<div>Again, nice work fixing the code that soon.</div><div><br></div><div>And indeed, putting overridePtr in 'code' is not possible. And that's unfortunate because we now have to think about concurrent updates on the registersNatives field on the classloader (see attached comments). But I think you can just use the classloader's existing lock.</div>
<div><br></div><div>Nicolas</div><div><br></div>On Mon, Oct 24, 2011 at 12:22 AM, Will Dietz <span dir="ltr"><<a href="mailto:willdtz@gmail.com">willdtz@gmail.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Done, updated patch attached.  Seems to work fine!<br>
<br>
Also, pasted below for reference/reviewing.<br>
<br>
Thanks!<br>
<br>
~Will<br>
<br>
<br>
<br>
<br>
>From 117cf54d43ae0a475f100e8f2f0183d1325df6e8 Mon Sep 17 00:00:00 2001<br>
<div class="im">From: Will Dietz <<a href="mailto:w@wdtz.org">w@wdtz.org</a>><br>
Date: Fri, 14 Oct 2011 05:34:37 -0500<br>
</div>Subject: [PATCH] Implement basic registerNatives support.<br>
<br>
Store the registred native function pointer in the class's classloader.<br>
---<br>
 lib/J3/Compiler/JavaLLVMCompiler.cpp |    2 +-<br>
 lib/J3/VMCore/JavaClass.h            |    5 +++-<br>
 lib/J3/VMCore/Jni.cpp                |   39 ++++++++++++++++++++++++++++++---<br>
 lib/J3/VMCore/JnjvmClassLoader.cpp   |    8 +++++++<br>
 lib/J3/VMCore/JnjvmClassLoader.h     |   18 +++++++++++++++<br>
 lib/J3/VMCore/Precompiled.cpp        |    1 +<br>
 6 files changed, 67 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/lib/J3/Compiler/JavaLLVMCompiler.cpp<br>
b/lib/J3/Compiler/JavaLLVMCompiler.cpp<br>
index 95d93ae..781f445 100644<br>
<div class="im">--- a/lib/J3/Compiler/JavaLLVMCompiler.cpp<br>
+++ b/lib/J3/Compiler/JavaLLVMCompiler.cpp<br>
@@ -62,7 +62,7 @@ Function*<br>
JavaLLVMCompiler::parseFunction(JavaMethod* meth, Class* customizeFor)<br>
   if (func->getLinkage() == GlobalValue::ExternalWeakLinkage) {<br>
     JavaJIT jit(this, meth, func, customizeFor);<br>
     if (isNative(meth->access)) {<br>
-      jit.nativeCompile();<br>
</div>+      jit.nativeCompile(meth->getNativePointer());<br>
<div class="im">       mvm::MvmModule::runPasses(func, JavaNativeFunctionPasses);<br>
       mvm::MvmModule::runPasses(func, J3FunctionPasses);<br>
     } else {<br>
</div>diff --git a/lib/J3/VMCore/JavaClass.h b/lib/J3/VMCore/JavaClass.h<br>
index 1fa9b77..5b4fb30 100644<br>
--- a/lib/J3/VMCore/JavaClass.h<br>
+++ b/lib/J3/VMCore/JavaClass.h<br>
@@ -961,7 +961,10 @@ public:<br>
<div class="im">   /// with the given class loader.<br>
   ///<br>
   JavaObject* getReturnType(JnjvmClassLoader* loader);<br>
-<br>
+<br>
</div>+  word_t getNativePointer() const {<br>
+    return classDef->classLoader->getRegisteredNative(this);<br>
+  }<br>
<div class="im"><br>
 //===----------------------------------------------------------------------===//<br>
 //<br>
diff --git a/lib/J3/VMCore/Jni.cpp b/lib/J3/VMCore/Jni.cpp<br>
</div>index e64b5c3..356187b 100644<br>
--- a/lib/J3/VMCore/Jni.cpp<br>
+++ b/lib/J3/VMCore/Jni.cpp<br>
@@ -3755,11 +3755,42 @@ void SetDoubleArrayRegion(JNIEnv *env,<br>
jdoubleArray array, jsize start,<br>
 }<br>
<br>
<br>
-jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,<br>
+jint RegisterNatives(JNIEnv *env, jclass _clazz, const<br>
<div class="im">JNINativeMethod *methods,<br>
                     jint nMethods) {<br>
-  NYI();<br>
-  abort();<br>
-  return 0;<br>
+  BEGIN_JNI_EXCEPTION<br>
+<br>
</div>+  JavaObject * clazz = 0;<br>
+  llvm_gcroot(clazz, 0);<br>
+  clazz = *(JavaObject**)_clazz;<br>
+<br>
+  Jnjvm* vm = JavaThread::get()->getJVM();<br>
+  UserCommonClass * Cl = UserCommonClass::resolvedImplClass(vm, clazz, false);<br>
+  // TODO: Don't assert, throw exceptions!<br>
+  assert(Cl);<br>
+  UserClass * cl = Cl->asClass();<br>
<div class="im">+<br>
+  for(int i = 0; i < nMethods; ++i)<br>
+  {<br>
</div><div class="im">+    const UTF8* name =<br>
cl->classLoader->hashUTF8->lookupAsciiz(methods[i].name);<br>
+    const UTF8* sign =<br>
cl->classLoader->hashUTF8->lookupAsciiz(methods[i].signature);<br>
+    assert(name);<br>
+    assert(sign);<br>
+<br>
+    JavaMethod * meth = cl->lookupMethodDontThrow(name, sign, true, true, 0);<br>
+    if (!meth) meth = cl->lookupMethodDontThrow(name, sign, false, true, 0);<br>
+<br>
</div>+    // TODO: Don't assert, throw exceptions!<br>
<div class="im">+    assert(meth);<br>
+    assert(isNative(meth->access));<br>
+<br>
</div>+    cl->classLoader->registerNative(meth,(word_t)methods[i].fnPtr);<br>
<div class="im">+  }<br>
+<br>
+  RETURN_FROM_JNI(0)<br>
+<br>
+  END_JNI_EXCEPTION<br>
+<br>
+  RETURN_FROM_JNI(0)<br>
 }<br>
<br>
<br>
</div>diff --git a/lib/J3/VMCore/JnjvmClassLoader.cpp<br>
b/lib/J3/VMCore/JnjvmClassLoader.cpp<br>
index 55d3cfb..1bb7aaa 100644<br>
--- a/lib/J3/VMCore/JnjvmClassLoader.cpp<br>
+++ b/lib/J3/VMCore/JnjvmClassLoader.cpp<br>
@@ -1031,3 +1031,11 @@ JavaString**<br>
StringList::addString(JnjvmClassLoader* JCL, JavaString* obj) {<br>
     return res;<br>
   }<br>
 }<br>
+<br>
+void JnjvmClassLoader::registerNative(JavaMethod * meth, word_t fnPtr)<br>
+{<br>
+  // Don't support multiple levels of registerNatives<br>
+  assert(registeredNatives.find(meth) == registeredNatives.end());<br>
+<br>
+  registeredNatives[meth] = fnPtr;<br></blockquote><div><br></div><div>Should we think about concurrent updates and lookups on registeredNatives? Unfortunately, I think we should :(</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

+}<br>
diff --git a/lib/J3/VMCore/JnjvmClassLoader.h b/lib/J3/VMCore/JnjvmClassLoader.h<br>
index 8e15d65..def954f 100644<br>
--- a/lib/J3/VMCore/JnjvmClassLoader.h<br>
+++ b/lib/J3/VMCore/JnjvmClassLoader.h<br>
@@ -108,6 +108,11 @@ protected:<br>
   ///<br>
   mvm::LockRecursive lock;<br>
<br>
+  /// registeredNatives - Stores the native function pointers corresponding<br>
+  /// to methods that were defined through JNI's RegisterNatives mechanism.<br>
+  ///<br>
+  std::map<const JavaMethod*,word_t> registeredNatives;<br>
+<br>
 public:<br>
<br>
   /// allocator - Reference to the memory allocator, which will allocate UTF8s,<br>
@@ -301,6 +306,19 @@ public:<br>
   ///<br>
   Class* loadClassFromSelf(Jnjvm* vm, const char* name);<br>
<br>
+  /// registerNative - Record the native function pointer of a method.<br>
+  ///<br>
+  void registerNative(JavaMethod * meth, word_t fnPtr);<br>
+<br>
+  /// getRegisteredNative - Return the native pointer, if exists.<br>
+  ///<br>
+  word_t getRegisteredNative(const JavaMethod * meth) const {<br>
+    std::map<const JavaMethod*,word_t>::const_iterator I =<br>
+      registeredNatives.find(meth);<br>
+    if (I == registeredNatives.end()) return 0;<br>
+    return I->second;<br></blockquote><div><br></div><div>Could that be replaced with registeredNatives[meth]?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

+  }<br>
+<br>
   friend class Class;<br>
   friend class CommonClass;<br>
   friend class StringList;<br>
diff --git a/lib/J3/VMCore/Precompiled.cpp b/lib/J3/VMCore/Precompiled.cpp<br>
index e469eaf..9a85e99 100644<br>
<div class="im">--- a/lib/J3/VMCore/Precompiled.cpp<br>
+++ b/lib/J3/VMCore/Precompiled.cpp<br>
@@ -102,6 +102,7 @@ extern "C" word_t vmjcNativeLoader(JavaMethod* meth) {<br>
   char* buf = (char*)threadAllocator.Allocate(<br>
       3 + JNI_NAME_PRE_LEN + 1 + ((mnlen + clen + mtlen) << 3));<br>
   word_t res = meth->classDef->classLoader->nativeLookup(meth, j3, buf);<br></div></blockquote><div><br></div><div>Could you please add a comment on what's happening here? It might get tricky to understand.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im">
</div>+  if (!res) res = meth->getNativePointer();<br>
<div><div></div><div class="h5">   assert(res && "Could not find required native method");<br>
   return res;<br>
 }<br>
--<br>
1.7.5.1<br>
</div></div></blockquote></div><br>