diff --git a/core/src/main/java/org/teavm/runtime/GC.java b/core/src/main/java/org/teavm/runtime/GC.java index f33172cd9..0d670f589 100644 --- a/core/src/main/java/org/teavm/runtime/GC.java +++ b/core/src/main/java/org/teavm/runtime/GC.java @@ -438,7 +438,9 @@ public final class GC { hasObjectsFromYoungGen |= enqueueMark(object.object); } } - if (object.next == null && object.object != null) { + if (object.next != null) { + hasObjectsFromYoungGen |= enqueueMark(object.next); + } else if (object.object != null) { object.next = firstWeakReference; firstWeakReference = object; } @@ -448,9 +450,8 @@ public final class GC { private static boolean markReferenceQueue(RuntimeReferenceQueue object) { RuntimeReference reference = object.first; boolean hasObjectsFromYoungGen = false; - while (reference != null) { + if (reference != null) { hasObjectsFromYoungGen |= enqueueMark(reference); - reference = reference.next; } return hasObjectsFromYoungGen; } @@ -519,14 +520,22 @@ public final class GC { queue.first = reference; } else { queue.last.next = reference; + makeInvalid(queue.last); } queue.last = reference; + makeInvalid(queue); } } reference = next; } } + private static void makeInvalid(RuntimeObject object) { + long offset = object.toAddress().toLong() - heapAddress().toLong(); + Address cardTableItem = cardTable().add(offset / regionSize()); + cardTableItem.putByte((byte) (cardTableItem.getByte() & ~CARD_VALID)); + } + private static void sweep() { MemoryTrace.sweepStarted(); diff --git a/core/src/main/resources/org/teavm/backend/c/heaptrace.c b/core/src/main/resources/org/teavm/backend/c/heaptrace.c index fcf8107d9..6037870dc 100644 --- a/core/src/main/resources/org/teavm/backend/c/heaptrace.c +++ b/core/src/main/resources/org/teavm/backend/c/heaptrace.c @@ -4,6 +4,7 @@ #include "definitions.h" #include "memory.h" #include "time.h" +#include "references.h" #include #include #include @@ -363,9 +364,14 @@ FILE* teavm_gc_openDumpFile(wchar_t* name) { while (cls != NULL) { int32_t kind = (cls->flags >> 7) & 7; if (kind == 1) { - + TeaVM_Reference* reference = (TeaVM_Reference*) obj; + teavm_verify(reference->next); + teavm_verify(reference->object); + teavm_verify(reference->queue); } else if (kind == 2) { - + TeaVM_ReferenceQueue* queue = (TeaVM_ReferenceQueue*) obj; + teavm_verify(queue->first); + teavm_verify(queue->last); } else { int16_t* layout = cls->layout; if (layout != NULL) {