Fix garbage cycle collection for kotlin.Array

This commit is contained in:
Svyatoslav Scherbina
2018-06-04 15:34:35 +03:00
committed by SvyatoslavScherbina
parent b31590f545
commit 2934588bbe
5 changed files with 38 additions and 8 deletions
@@ -165,6 +165,12 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
val objOffsetsPtr = staticData.placeGlobalConstArray("krefs:$className", int32Type,
objOffsets.map { Int32(it.toInt()) })
val objOffsetsCount = if (classDesc.descriptor == context.builtIns.array) {
1 // To mark it as non-leaf.
} else {
objOffsets.size
}
val fields = llvmDeclarations.fields.mapIndexed { index, field ->
// Note: using FQ name because a class may have multiple fields with the same name due to property overriding
val nameSignature = field.fqNameSafe.localHash // FIXME: add signature
@@ -191,7 +197,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
name,
size,
superType,
objOffsetsPtr, objOffsets.size,
objOffsetsPtr, objOffsetsCount,
interfacesPtr, interfaces.size,
methodsPtr, methods.size,
fieldsPtr, if (classDesc.isInterface) -1 else fields.size,
+4
View File
@@ -2117,6 +2117,10 @@ task memory_cycles0(type: RunKonanTest) {
source = "runtime/memory/cycles0.kt"
}
task memory_cycles1(type: RunKonanTest) {
source = "runtime/memory/cycles1.kt"
}
task memory_basic0(type: RunKonanTest) {
source = "runtime/memory/basic0.kt"
}
@@ -0,0 +1,17 @@
package runtime.memory.cycles1
import kotlin.test.*
import konan.ref.*
@Test fun runTest() {
val weakRefToTrashCycle = createLoop()
konan.internal.GC.collect()
assertNull(weakRefToTrashCycle.get())
}
private fun createLoop(): WeakReference<Any> {
val loop = Array<Any?>(1, { null })
loop[0] = loop
return WeakReference(loop)
}
+7 -6
View File
@@ -442,12 +442,13 @@ inline void traverseContainerObjectFields(ContainerHeader* container, func proce
ObjHeader* obj = reinterpret_cast<ObjHeader*>(container + 1);
for (int object = 0; object < container->objectCount(); object++) {
const TypeInfo* typeInfo = obj->type_info();
for (int index = 0; index < typeInfo->objOffsetsCount_; index++) {
ObjHeader** location = reinterpret_cast<ObjHeader**>(
reinterpret_cast<uintptr_t>(obj + 1) + typeInfo->objOffsets_[index]);
process(location);
}
if (typeInfo == theArrayTypeInfo) {
if (typeInfo != theArrayTypeInfo) {
for (int index = 0; index < typeInfo->objOffsetsCount_; index++) {
ObjHeader** location = reinterpret_cast<ObjHeader**>(
reinterpret_cast<uintptr_t>(obj + 1) + typeInfo->objOffsets_[index]);
process(location);
}
} else {
ArrayHeader* array = obj->array();
for (int index = 0; index < array->count_; index++) {
process(ArrayAddressOfElementAt(array, index));
+3 -1
View File
@@ -81,8 +81,10 @@ struct TypeInfo {
int32_t instanceSize_;
// Must be pointer to Any for array classes, and null for Any.
const TypeInfo* superType_;
// All object references inside this object.
// All object reference fields inside this object.
const int32_t* objOffsets_;
// Count of object reference fields inside this object.
// 1 for kotlin.Array to mark it as non-leaf.
int32_t objOffsetsCount_;
const TypeInfo* const* implementedInterfaces_;
int32_t implementedInterfacesCount_;