[vmkit-commits] [PATCH] registerNatives

Will Dietz wdietz2 at illinois.edu
Mon Oct 24 13:38:28 PDT 2011


(Fixing my failure to cc the list originally)

Updated patch below, addressing the mentioned concerns (thanks!).

Also, dropped the 'getNativePointer' accessor on JavaMethod since
that's confusing and forces one to know which "type" of native method
they have.

Instead put the logic into nativeLookup, so existing code that wants
the native function pointer (and are used to doing so via
nativeLookup) now get it with any fuss.

Inlined below.

~Will
---
 lib/J3/VMCore/JavaClass.h          |    1 -
 lib/J3/VMCore/Jni.cpp              |   39 ++++++++++++++++++++++++++++++++---
 lib/J3/VMCore/JnjvmClassLoader.cpp |   28 ++++++++++++++++++++++++-
 lib/J3/VMCore/JnjvmClassLoader.h   |   13 ++++++++++++
 4 files changed, 75 insertions(+), 6 deletions(-)

diff --git a/lib/J3/VMCore/JavaClass.h b/lib/J3/VMCore/JavaClass.h
index 1fa9b77..5da5571 100644
--- a/lib/J3/VMCore/JavaClass.h
+++ b/lib/J3/VMCore/JavaClass.h
@@ -961,7 +961,6 @@ public:
  /// with the given class loader.
  ///
  JavaObject* getReturnType(JnjvmClassLoader* loader);
-

 //===----------------------------------------------------------------------===//
 //
diff --git a/lib/J3/VMCore/Jni.cpp b/lib/J3/VMCore/Jni.cpp
index 9f7d612..82d2719 100644
--- a/lib/J3/VMCore/Jni.cpp
+++ b/lib/J3/VMCore/Jni.cpp
@@ -3755,11 +3755,42 @@ void SetDoubleArrayRegion(JNIEnv *env,
jdoubleArray array, jsize start,
 }


-jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
+jint RegisterNatives(JNIEnv *env, jclass _clazz, const
JNINativeMethod *methods,
                    jint nMethods) {
-  NYI();
-  abort();
-  return 0;
+  BEGIN_JNI_EXCEPTION
+
+  JavaObject * clazz = 0;
+  llvm_gcroot(clazz, 0);
+  clazz = *(JavaObject**)_clazz;
+
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  UserCommonClass * Cl = UserCommonClass::resolvedImplClass(vm, clazz, false);
+  // TODO: Don't assert, throw exceptions!
+  assert(Cl);
+  UserClass * cl = Cl->asClass();
+
+  for(int i = 0; i < nMethods; ++i)
+  {
+    const UTF8* name =
cl->classLoader->hashUTF8->lookupAsciiz(methods[i].name);
+    const UTF8* sign =
cl->classLoader->hashUTF8->lookupAsciiz(methods[i].signature);
+    assert(name);
+    assert(sign);
+
+    JavaMethod * meth = cl->lookupMethodDontThrow(name, sign, true, true, 0);
+    if (!meth) meth = cl->lookupMethodDontThrow(name, sign, false, true, 0);
+
+    // TODO: Don't assert, throw exceptions!
+    assert(meth);
+    assert(isNative(meth->access));
+
+    cl->classLoader->registerNative(meth,(word_t)methods[i].fnPtr);
+  }
+
+  RETURN_FROM_JNI(0)
+
+  END_JNI_EXCEPTION
+
+  RETURN_FROM_JNI(0)
 }


diff --git a/lib/J3/VMCore/JnjvmClassLoader.cpp
b/lib/J3/VMCore/JnjvmClassLoader.cpp
index 55d3cfb..fe83593 100644
--- a/lib/J3/VMCore/JnjvmClassLoader.cpp
+++ b/lib/J3/VMCore/JnjvmClassLoader.cpp
@@ -1005,9 +1005,19 @@ word_t JnjvmClassLoader::loadInLib(const char*
name, void* handle) {
 word_t JnjvmClassLoader::nativeLookup(JavaMethod* meth, bool& j3,
                                        char* buf) {

+  word_t res;
+
+  // Is this method defined via registerNatives()?
+  // If so, use that definition.
+  if (res = getRegisteredNative(meth))
+    return res;
+
+  // Otherwise, try to resolve the method with a symbol lookup
+  // First as the base method
  meth->jniConsFromMeth(buf);
-  word_t res = loadInLib(buf, j3);
+  res = loadInLib(buf, j3);
  if (!res) {
+    // Failing that, try the overloaded symbol name
    meth->jniConsFromMethOverloaded(buf);
    res = loadInLib(buf, j3);
  }
@@ -1031,3 +1041,19 @@ JavaString**
StringList::addString(JnjvmClassLoader* JCL, JavaString* obj) {
    return res;
  }
 }
+
+void JnjvmClassLoader::registerNative(JavaMethod * meth, word_t fnPtr) {
+  // Don't support multiple levels of registerNatives
+  lock.lock();
+  assert(registeredNatives.find(meth) == registeredNatives.end());
+
+  registeredNatives[meth] = fnPtr;
+  lock.unlock();
+}
+
+word_t JnjvmClassLoader::getRegisteredNative(const JavaMethod * meth) {
+  lock.lock();
+  word_t res = registeredNatives[meth];
+  lock.unlock();
+  return res;
+}
diff --git a/lib/J3/VMCore/JnjvmClassLoader.h b/lib/J3/VMCore/JnjvmClassLoader.h
index 8e15d65..f5891b0 100644
--- a/lib/J3/VMCore/JnjvmClassLoader.h
+++ b/lib/J3/VMCore/JnjvmClassLoader.h
@@ -108,6 +108,11 @@ protected:
  ///
  mvm::LockRecursive lock;

+  /// registeredNatives - Stores the native function pointers corresponding
+  /// to methods that were defined through JNI's RegisterNatives mechanism.
+  ///
+  std::map<const JavaMethod*,word_t> registeredNatives;
+
 public:

  /// allocator - Reference to the memory allocator, which will allocate UTF8s,
@@ -301,6 +306,14 @@ public:
  ///
  Class* loadClassFromSelf(Jnjvm* vm, const char* name);

+  /// registerNative - Record the native function pointer of a method.
+  ///
+  void registerNative(JavaMethod * meth, word_t fnPtr);
+
+  /// getRegisteredNative - Return the native pointer, if exists.
+  ///
+  word_t getRegisteredNative(const JavaMethod * meth);
+
  friend class Class;
  friend class CommonClass;
  friend class StringList;
--
1.7.5.1




More information about the vmkit-commits mailing list