Add tests cases for, and fix, #513 #524
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This patch addresses both leaks discussed in #513.
First leak
The changes in d1d6ca4 made several
Geometry2DTests
fail.The actual unbalanced retain causing the leak in
VariantRepresentable.swift
:The
variant.toType
function calls into Godot to copy out the built-in type stored invariant
. If that built-in type has an internal reference count, Godot increments it. Then, the call toself.init(content: content)
increments the count again. The retain performed byvariant.toType
is never balanced.This patch fixes the bug by generating a new
init(alreadyOwnedContent:)
initializer for each Godot builtin class type. This needs to be on the builtin wrappers (likeGDictionary
,GArray
, etc.), rather than onVariant
which is where d1d6ca4 put it.This patch also adds a test case to check for the leak by looking at Godot's
MEMORY_STATIC
performance counter, which is only enabled if Godot was built withDEBUG_ENABLED
.Second leak
This patch adds a test for the second leak described in #513, and fixes the leak.
Without this patch, the leak happens because
Variant.asObject
has an unneeded call torc.reference()
which increments theRefCounted
object's reference count. As far as I can tell, nothing balances this increment.Variant.asObject
callslookupObject(nativeHandle:)
, which returns a Swift wrapper for an object whose reference count has already been incremented (if the object isRefCounted
). The Swift wrapper balances that increment with a decrement in itsdeinit
.