[vmkit-commits] [PATCH] Various patches

Nicolas Geoffray nicolas.geoffray at gmail.com
Sun Oct 23 23:10:47 PDT 2011


Again, nice work fixing the code that soon.

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.

Nicolas

On Mon, Oct 24, 2011 at 12:22 AM, Will Dietz <willdtz at gmail.com> wrote:

> Done, updated patch attached.  Seems to work fine!
>
> Also, pasted below for reference/reviewing.
>
> Thanks!
>
> ~Will
>
>
>
>
> From 117cf54d43ae0a475f100e8f2f0183d1325df6e8 Mon Sep 17 00:00:00 2001
> From: Will Dietz <w at wdtz.org>
> Date: Fri, 14 Oct 2011 05:34:37 -0500
> Subject: [PATCH] Implement basic registerNatives support.
>
> Store the registred native function pointer in the class's classloader.
> ---
>  lib/J3/Compiler/JavaLLVMCompiler.cpp |    2 +-
>  lib/J3/VMCore/JavaClass.h            |    5 +++-
>  lib/J3/VMCore/Jni.cpp                |   39
> ++++++++++++++++++++++++++++++---
>  lib/J3/VMCore/JnjvmClassLoader.cpp   |    8 +++++++
>  lib/J3/VMCore/JnjvmClassLoader.h     |   18 +++++++++++++++
>  lib/J3/VMCore/Precompiled.cpp        |    1 +
>  6 files changed, 67 insertions(+), 6 deletions(-)
>
> diff --git a/lib/J3/Compiler/JavaLLVMCompiler.cpp
> b/lib/J3/Compiler/JavaLLVMCompiler.cpp
> index 95d93ae..781f445 100644
> --- a/lib/J3/Compiler/JavaLLVMCompiler.cpp
> +++ b/lib/J3/Compiler/JavaLLVMCompiler.cpp
> @@ -62,7 +62,7 @@ Function*
> JavaLLVMCompiler::parseFunction(JavaMethod* meth, Class* customizeFor)
>   if (func->getLinkage() == GlobalValue::ExternalWeakLinkage) {
>     JavaJIT jit(this, meth, func, customizeFor);
>     if (isNative(meth->access)) {
> -      jit.nativeCompile();
> +      jit.nativeCompile(meth->getNativePointer());
>        mvm::MvmModule::runPasses(func, JavaNativeFunctionPasses);
>       mvm::MvmModule::runPasses(func, J3FunctionPasses);
>     } else {
> diff --git a/lib/J3/VMCore/JavaClass.h b/lib/J3/VMCore/JavaClass.h
> index 1fa9b77..5b4fb30 100644
> --- a/lib/J3/VMCore/JavaClass.h
> +++ b/lib/J3/VMCore/JavaClass.h
> @@ -961,7 +961,10 @@ public:
>    /// with the given class loader.
>   ///
>   JavaObject* getReturnType(JnjvmClassLoader* loader);
> -
> +
> +  word_t getNativePointer() const {
> +    return classDef->classLoader->getRegisteredNative(this);
> +  }
>
>
>  //===----------------------------------------------------------------------===//
>  //
> diff --git a/lib/J3/VMCore/Jni.cpp b/lib/J3/VMCore/Jni.cpp
> index e64b5c3..356187b 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..1bb7aaa 100644
> --- a/lib/J3/VMCore/JnjvmClassLoader.cpp
> +++ b/lib/J3/VMCore/JnjvmClassLoader.cpp
> @@ -1031,3 +1031,11 @@ JavaString**
> StringList::addString(JnjvmClassLoader* JCL, JavaString* obj) {
>     return res;
>   }
>  }
> +
> +void JnjvmClassLoader::registerNative(JavaMethod * meth, word_t fnPtr)
> +{
> +  // Don't support multiple levels of registerNatives
> +  assert(registeredNatives.find(meth) == registeredNatives.end());
> +
> +  registeredNatives[meth] = fnPtr;
>

Should we think about concurrent updates and lookups on registeredNatives?
Unfortunately, I think we should :(


> +}
> diff --git a/lib/J3/VMCore/JnjvmClassLoader.h
> b/lib/J3/VMCore/JnjvmClassLoader.h
> index 8e15d65..def954f 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,19 @@ 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) const {
> +    std::map<const JavaMethod*,word_t>::const_iterator I =
> +      registeredNatives.find(meth);
> +    if (I == registeredNatives.end()) return 0;
> +    return I->second;
>

Could that be replaced with registeredNatives[meth]?


> +  }
> +
>   friend class Class;
>   friend class CommonClass;
>   friend class StringList;
> diff --git a/lib/J3/VMCore/Precompiled.cpp b/lib/J3/VMCore/Precompiled.cpp
> index e469eaf..9a85e99 100644
> --- a/lib/J3/VMCore/Precompiled.cpp
> +++ b/lib/J3/VMCore/Precompiled.cpp
> @@ -102,6 +102,7 @@ extern "C" word_t vmjcNativeLoader(JavaMethod* meth) {
>   char* buf = (char*)threadAllocator.Allocate(
>       3 + JNI_NAME_PRE_LEN + 1 + ((mnlen + clen + mtlen) << 3));
>   word_t res = meth->classDef->classLoader->nativeLookup(meth, j3, buf);
>

Could you please add a comment on what's happening here? It might get tricky
to understand.


> +  if (!res) res = meth->getNativePointer();
>    assert(res && "Could not find required native method");
>   return res;
>  }
> --
> 1.7.5.1
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/vmkit-commits/attachments/20111024/3c3343e1/attachment.html>


More information about the vmkit-commits mailing list