From ca6acb9921b46446ba40c31687173f4726ee7c57 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Wed, 7 Dec 2016 10:23:13 -0700 Subject: [PATCH] fix a few memory safety issues The main issue was that offsets for GC roots on the stack were being miscalculated because invokedynamic bootstrap methods are invoked as static methods but were not being flagged as such. Also, I forgot to initialize MyThread::dynamicTable in the constructor (and why the hell doesn't `gcc -Wall` warn me about stuff like that?) --- src/compile.cpp | 24 +++++++++++++++++------- src/machine.cpp | 9 +++++++-- test/InvokeDynamic.java | 6 ++++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/compile.cpp b/src/compile.cpp index 6a36649181..725033ab0c 100644 --- a/src/compile.cpp +++ b/src/compile.cpp @@ -268,6 +268,7 @@ class MyThread : public Thread { heapImage(0), codeImage(0), thunkTable(0), + dynamicTable(0), trace(0), reference(0), arch(parent ? parent->arch : avian::codegen::makeArchitectureNative( @@ -1310,6 +1311,10 @@ Allocator* allocator(MyThread* t); unsigned addDynamic(MyThread* t, GcInvocation* invocation) { + if (t->dynamicTable == nullptr) { + t->dynamicTable = dynamicTable(t); + } + ACQUIRE(t, t->m->classLock); int index = invocation->index(); @@ -5177,13 +5182,18 @@ loop: jclass lmfClass = e->vtable->FindClass( e, "java/lang/invoke/LambdaMetafactory"); - jmethodID makeLambda = e->vtable->GetStaticMethodID( - e, - lmfClass, - "makeLambda", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/" - "String;Ljava/" - "lang/String;Ljava/lang/String;Ljava/lang/String;I)[B"); + jmethodID makeLambda + = e->vtable->GetStaticMethodID(e, + lmfClass, + "makeLambda", + "(Ljava/lang/String;" + "Ljava/lang/String;" + "Ljava/lang/String;" + "Ljava/lang/String;" + "Ljava/lang/String;" + "Ljava/lang/String;" + "I" + ")[B"); GcReference* reference = cast( t, diff --git a/src/machine.cpp b/src/machine.cpp index 3bf4aa9dfb..c2d43a503c 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -1075,7 +1075,7 @@ unsigned parsePoolEntry(Thread* t, returnCode, parameterCount, parameterFootprint, - 0, + ACC_STATIC, 0, 0, 0, @@ -6076,6 +6076,8 @@ GcCallSite* resolveDynamic(Thread* t, GcInvocation* invocation) array->setBodyElement(t, argument++, name); array->setBodyElement(t, argument++, type); + THREAD_RUNTIME_ARRAY(t, char, specBuffer, bootstrap->spec()->length()); + const char* spec; GcArray* argArray = array; PROTECT(t, argArray); @@ -6101,7 +6103,10 @@ GcCallSite* resolveDynamic(Thread* t, GcInvocation* invocation) "[Ljava/lang/invoke/MethodType;" ")Ljava/lang/invoke/CallSite;"; } else if (bootstrap->parameterCount() == 2 + bootstrapArray->length()) { - spec = reinterpret_cast(bootstrap->spec()->body().begin()); + memcpy(RUNTIME_ARRAY_BODY(specBuffer), + bootstrap->spec()->body().begin(), + bootstrap->spec()->length()); + spec = RUNTIME_ARRAY_BODY(specBuffer); } else { abort(t); } diff --git a/test/InvokeDynamic.java b/test/InvokeDynamic.java index 05a2876c12..e312e78d82 100644 --- a/test/InvokeDynamic.java +++ b/test/InvokeDynamic.java @@ -56,5 +56,11 @@ public class InvokeDynamic { expect(s.get().first == 42L); expect(s.get().second == 77.1D); } + + { double[] a = new double[] { 3.14D }; + Supplier> s = () -> new Pair(42L, a[0]); + expect(s.get().first == 42L); + expect(s.get().second == 3.14D); + } } }