From de6a1ded922abc9e921d5fdb0cc194dca02d95ca Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 28 Jan 2008 08:12:06 -0700 Subject: [PATCH] ensure that we populate the interface vtables of a class which does not declare any new virtual methods but does implement new interfaces relative to its superclass --- src/machine.cpp | 47 ++++++++++++++++++++++++++++------------------- src/machine.h | 3 +++ 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/machine.cpp b/src/machine.cpp index 509af2d023..3edbf8700f 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1344,6 +1344,8 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool) set(t, class_, ClassMethodTable, methodTable); } + bool populateInterfaceVtables = false; + if (declaredVirtualCount == 0 and (classFlags(t, class_) & ACC_INTERFACE) == 0) { @@ -1358,10 +1360,12 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool) // inherit interface table from superclass set(t, class_, ClassInterfaceTable, classInterfaceTable(t, classSuper(t, class_))); - } + } else { + populateInterfaceVtables = true; + } } else { - // apparently Object does not have any virtual methods. We give - // it a vtable anyway so code doesn't break elsewhere. + // apparently, Object does not have any virtual methods. We + // give it a vtable anyway so code doesn't break elsewhere. object vtable = makeArray(t, 0, false); set(t, class_, ClassVirtualTable, vtable); } @@ -1404,25 +1408,28 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool) set(t, class_, ClassVirtualTable, vtable); if ((classFlags(t, class_) & ACC_INTERFACE) == 0) { - // generate interface vtables - - object itable = classInterfaceTable(t, class_); - if (itable) { - PROTECT(t, itable); + populateInterfaceVtables = true; + } + } - for (unsigned i = 0; i < arrayLength(t, itable); i += 2) { - object ivtable = classVirtualTable(t, arrayBody(t, itable, i)); - if (ivtable) { - object vtable = arrayBody(t, itable, i + 1); + if (populateInterfaceVtables) { + // generate interface vtables + object itable = classInterfaceTable(t, class_); + if (itable) { + PROTECT(t, itable); + + for (unsigned i = 0; i < arrayLength(t, itable); i += 2) { + object ivtable = classVirtualTable(t, arrayBody(t, itable, i)); + if (ivtable) { + object vtable = arrayBody(t, itable, i + 1); - for (unsigned j = 0; j < arrayLength(t, ivtable); ++j) { - object method = arrayBody(t, ivtable, j); - method = hashMapFind - (t, virtualMap, method, methodHash, methodEqual); - assert(t, method); + for (unsigned j = 0; j < arrayLength(t, ivtable); ++j) { + object method = arrayBody(t, ivtable, j); + method = hashMapFind + (t, virtualMap, method, methodHash, methodEqual); + assert(t, method); - set(t, vtable, ArrayBody + (j * BytesPerWord), method); - } + set(t, vtable, ArrayBody + (j * BytesPerWord), method); } } } @@ -2199,6 +2206,8 @@ allocate3(Thread* t, Allocator* allocator, Machine::AllocationType type, if (t->heap == 0) { ENTER(t, Thread::ExclusiveState); +// fprintf(stderr, "gc"); +// vmPrintTrace(t); collect(t, Heap::MinorCollection); } diff --git a/src/machine.h b/src/machine.h index 7862cd6fbd..2c125ba2c3 100644 --- a/src/machine.h +++ b/src/machine.h @@ -2230,4 +2230,7 @@ makeSingleton(Thread* t, unsigned count) } // namespace vm +void +vmPrintTrace(vm::Thread* t); + #endif//MACHINE_H