From 19d36cc463fb7c3a28936dee89a26b1067838ed7 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 5 Nov 2007 08:29:43 -0700 Subject: [PATCH] implement impdep1 instruction for lazily loading bootstrap classes --- makefile | 2 +- src/interpret.cpp | 37 +++++++++++++++++++++++++++++++++---- src/machine.cpp | 1 + src/machine.h | 2 +- test/Misc.java | 2 ++ 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/makefile b/makefile index a8e418a08e..21d1eb6c97 100644 --- a/makefile +++ b/makefile @@ -28,7 +28,7 @@ src = src classpath = classpath test = test -input = $(test-build)/Reflection.class +input = $(test-build)/References.class build-cxx = g++ build-cc = gcc diff --git a/src/interpret.cpp b/src/interpret.cpp index 28901b357a..7b54c10b5e 100644 --- a/src/interpret.cpp +++ b/src/interpret.cpp @@ -1082,8 +1082,9 @@ interpret(Thread* t) (t, className(t, objectClass(t, peekObject(t, sp - 1))), 0), &byteArrayBody(t, className(t, class_), 0)); exception = makeClassCastException(t, message); - goto throw_; } + + if (UNLIKELY(exception)) goto throw_; } } goto loop; @@ -1784,6 +1785,8 @@ interpret(Thread* t) } else { pushInt(t, 0); } + + if (UNLIKELY(exception)) goto throw_; } else { popObject(t); pushInt(t, 0); @@ -1851,6 +1854,10 @@ interpret(Thread* t) object method = resolveMethod(t, codePool(t, code), index - 1); if (UNLIKELY(exception)) goto throw_; + + fprintf(stderr, "invokevirtual %s.%s\n", + &byteArrayBody(t, className(t, methodClass(t, method)), 0), + &byteArrayBody(t, methodName(t, method), 0)); unsigned parameterFootprint = methodParameterFootprint(t, method); if (LIKELY(peekObject(t, sp - parameterFootprint))) { @@ -2571,9 +2578,27 @@ interpret(Thread* t) case impdep1: { // this means we're invoking a virtual method on an instance of a - // bootstrap class, so we need to load the real class. - abort(t); - } break; + // bootstrap class, so we need to load the real class to get the + // real method and call it. + + assert(t, frameNext(t, frame) >= base); + popFrame(t); + + assert(t, codeBody(t, code, ip - 3) == invokevirtual); + ip -= 2; + + uint16_t index = codeReadInt16(t, code, ip); + object method = resolveMethod(t, codePool(t, code), index - 1); + + unsigned parameterFootprint = methodParameterFootprint(t, method); + object class_ = objectClass(t, peekObject(t, sp - parameterFootprint)); + assert(t, classVmFlags(t, class_) & BootstrapFlag); + + resolveClass(t, className(t, class_)); + if (UNLIKELY(exception)) goto throw_; + + ip -= 3; + } goto loop; default: abort(t); } @@ -2738,6 +2763,10 @@ invoke(Thread* t, object method) unsigned parameterFootprint = methodParameterFootprint(t, method); class_ = objectClass(t, peekObject(t, t->sp - parameterFootprint)); + if (classVmFlags(t, class_) & BootstrapFlag) { + resolveClass(t, className(t, class_)); + } + if (classFlags(t, methodClass(t, method)) & ACC_INTERFACE) { method = findInterfaceMethod(t, method, class_); } else { diff --git a/src/machine.cpp b/src/machine.cpp index 5b8dd4fe9d..2ffe5e217f 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -2131,6 +2131,7 @@ isAssignableFrom(Thread* t, object a, object b) if (classFlags(t, a) & ACC_INTERFACE) { if (classVmFlags(t, b) & BootstrapFlag) { resolveClass(t, className(t, b)); + if (UNLIKELY(t->exception)) return false; } for (; b; b = classSuper(t, b)) { diff --git a/src/machine.h b/src/machine.h index f6bbb6181a..7c8aa1a8f1 100644 --- a/src/machine.h +++ b/src/machine.h @@ -29,7 +29,7 @@ const bool Verbose = false; const bool DebugRun = false; const bool DebugStack = false; const bool DebugMonitors = false; -const bool DebugReferences = false; +const bool DebugReferences = true; const uintptr_t HashTakenMark = 1; const uintptr_t ExtendedMark = 2; diff --git a/test/Misc.java b/test/Misc.java index 3321647f20..59b7d88d55 100644 --- a/test/Misc.java +++ b/test/Misc.java @@ -17,6 +17,8 @@ public class Misc { public static void main(String[] args) { boolean v = Boolean.valueOf("true"); + ClassLoader.getSystemClassLoader().toString(); + int a = 2; int b = 2; int c = a + b;