diff options
author | Steve Block <steveblock@google.com> | 2009-12-18 12:28:23 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-01-08 16:22:49 +0000 |
commit | 88d4517612dafdcaff7a98f2a68ff071e2734ea6 (patch) | |
tree | 6bf4ebf254be2f5726d1d42fb7b5868969047cb9 /V8Binding | |
parent | 621d19b254dc27a490101dcc947c9a29517af899 (diff) | |
download | external_webkit-88d4517612dafdcaff7a98f2a68ff071e2734ea6.zip external_webkit-88d4517612dafdcaff7a98f2a68ff071e2734ea6.tar.gz external_webkit-88d4517612dafdcaff7a98f2a68ff071e2734ea6.tar.bz2 |
Updates the use of weak references in the script-to-Java bridge for V8.
Currently, V8 uses weak references to the Java object owned by JObjectWrapper.
This is in contrast to JSC, which uses strong references in JObjectWrapper.
However, for the special-case where JObjectWrapper is used in JavaInstance in
WebCoreFrameBridge, JSC uses WeakJavaInstance to swap the strong references for
weak references.
This change updates the V8 version of JObjectWrapper to use strong references
to match the JSC version. To maintain the weak reference behavior where
JObjectWrapper is used in JavaInstance in WebCoreFrameBridge, V8 now make use of
WeakJavaInstance too. This requires changes to jni_npobject to call the
necessary methods on JavaInstance to swap the references when the object is
accessed.
Change-Id: I3724d7e6437588feb0268a2670b02a93b52e54f0
Diffstat (limited to 'V8Binding')
-rw-r--r-- | V8Binding/jni/jni_instance.cpp | 29 | ||||
-rw-r--r-- | V8Binding/jni/jni_instance.h | 38 | ||||
-rw-r--r-- | V8Binding/jni/jni_npobject.cpp | 12 |
3 files changed, 35 insertions, 44 deletions
diff --git a/V8Binding/jni/jni_instance.cpp b/V8Binding/jni/jni_instance.cpp index 657b8c4..70da861 100644 --- a/V8Binding/jni/jni_instance.cpp +++ b/V8Binding/jni/jni_instance.cpp @@ -53,14 +53,12 @@ JavaInstance::~JavaInstance () JavaClass* JavaInstance::getClass() const { if (_class == 0) { - jobject local_ref = getLocalRef(); - _class = new JavaClass(local_ref); - getJNIEnv()->DeleteLocalRef(local_ref); + _class = new JavaClass(javaInstance()); } return _class; } -bool JavaInstance::invokeMethod(const char* methodName, const NPVariant* args, uint32_t count, NPVariant* resultValue) +bool JavaInstance::invokeMethod(const char* methodName, const NPVariant* args, int count, NPVariant* resultValue) { int i; jvalue *jArgs; @@ -108,7 +106,7 @@ bool JavaInstance::invokeMethod(const char* methodName, const NPVariant* args, u // The following code can be conditionally removed once we have a Tiger update that // contains the new Java plugin. It is needed for builds prior to Tiger. { - jobject obj = getLocalRef(); + jobject obj = javaInstance(); switch (jMethod->JNIReturnType()){ case void_type: callJNIMethodIDA<void>(obj, jMethod->methodID(obj), jArgs); @@ -145,7 +143,6 @@ bool JavaInstance::invokeMethod(const char* methodName, const NPVariant* args, u default: break; } - getJNIEnv()->DeleteLocalRef(obj); } convertJValueToNPVariant(result, jMethod->JNIReturnType(), jMethod->returnType(), resultValue); @@ -163,34 +160,16 @@ JObjectWrapper::JObjectWrapper(jobject instance) // It'll be used to delete the reference. _env = getJNIEnv(); - jclass localClsRef = _env->FindClass("java/lang/ref/WeakReference"); - jmethodID weakRefInit = _env->GetMethodID(localClsRef, "<init>", - "(Ljava/lang/Object;)V"); - mWeakRefGet = _env->GetMethodID(localClsRef, "get", - "()Ljava/lang/Object;"); + _instance = _env->NewGlobalRef(instance); - jobject weakRef = _env->NewObject(localClsRef, weakRefInit, instance); - - _instance = _env->NewGlobalRef(weakRef); - LOGV("new global ref %p for %p\n", _instance, instance); if (_instance == NULL) { fprintf (stderr, "%s: could not get GlobalRef for %p\n", __PRETTY_FUNCTION__, instance); } - - _env->DeleteLocalRef(weakRef); - _env->DeleteLocalRef(localClsRef); } JObjectWrapper::~JObjectWrapper() { LOGV("deleting global ref %p\n", _instance); _env->DeleteGlobalRef(_instance); } - -jobject JObjectWrapper::getLocalRef() const { - jobject real = _env->CallObjectMethod(_instance, mWeakRefGet); - if (!real) - LOGE("The real object has been deleted"); - return _env->NewLocalRef(real); -} diff --git a/V8Binding/jni/jni_instance.h b/V8Binding/jni/jni_instance.h index f8b0d65..608b461 100644 --- a/V8Binding/jni/jni_instance.h +++ b/V8Binding/jni/jni_instance.h @@ -33,10 +33,6 @@ #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> -namespace android { -class WeakJavaInstance; -} - using namespace WTF; namespace JSC { @@ -47,7 +43,15 @@ class JavaClass; class JObjectWrapper { +friend class RefPtr<JObjectWrapper>; +friend class JavaField; +friend class JavaInstance; + public: + jobject instance() const { return _instance; } + void setInstance(jobject instance) { _instance = instance; } + +protected: JObjectWrapper(jobject instance); ~JObjectWrapper(); @@ -58,35 +62,37 @@ public: delete this; } - jobject getLocalRef() const; + jobject _instance; private: JNIEnv *_env; unsigned int _refCount; - jobject _instance; // it is a global weak reference. - - jmethodID mWeakRefGet; // cache WeakReference::Get method id }; class JavaInstance : public RefCounted<JavaInstance> { public: JavaInstance(jobject instance); - ~JavaInstance(); + virtual ~JavaInstance(); JavaClass* getClass() const; - bool invokeMethod(const char* name, const NPVariant* args, uint32_t argsCount, NPVariant* result); + bool invokeMethod(const char* name, const NPVariant* args, int argsCount, NPVariant* result); - // Returns a local reference, and the caller must delete - // the returned reference after use. - jobject getLocalRef() const { - return _instance->getLocalRef(); - } + jobject javaInstance() const { return _instance->_instance; } -private: + // These functions are called before and after the main entry points into + // the native implementations. They can be used to establish and cleanup + // any needed state. + void begin() { virtualBegin(); } + void end() { virtualEnd(); } + +protected: RefPtr<JObjectWrapper> _instance; mutable JavaClass* _class; + + virtual void virtualBegin() {} + virtual void virtualEnd() {} }; } // namespace Bindings diff --git a/V8Binding/jni/jni_npobject.cpp b/V8Binding/jni/jni_npobject.cpp index 3480ac5..8a49a19 100644 --- a/V8Binding/jni/jni_npobject.cpp +++ b/V8Binding/jni/jni_npobject.cpp @@ -93,7 +93,9 @@ bool JavaNPObject_HasMethod(NPObject* obj, NPIdentifier identifier) { if (name == 0) return false; + instance->begin(); bool result = (instance->getClass()->methodsNamed(name).size() > 0); + instance->end(); // TODO: use NPN_MemFree free(name); @@ -110,7 +112,9 @@ bool JavaNPObject_Invoke(NPObject* obj, NPIdentifier identifier, if (name == 0) return false; + instance->begin(); bool r = instance->invokeMethod(name, args, argCount, result); + instance->end(); // TODO: use NPN_MemFree free(name); @@ -125,7 +129,9 @@ bool JavaNPObject_HasProperty(NPObject* obj, NPIdentifier identifier) { NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); if (name == 0) return false; + instance->begin(); bool result = instance->getClass()->fieldNamed(name) != 0; + instance->end(); free(name); return result; } @@ -139,19 +145,19 @@ bool JavaNPObject_GetProperty(NPObject* obj, NPIdentifier identifier, NPVariant* if (name == 0) return false; + instance->begin(); JavaField* field = instance->getClass()->fieldNamed(name); + instance->end(); free(name); // TODO: use NPN_MemFree if (field == 0) { return false; } - jobject local_ref = instance->getLocalRef(); - jvalue value = getJNIField(local_ref, + jvalue value = getJNIField(instance->javaInstance(), field->getJNIType(), field->name(), field->type()); - getJNIEnv()->DeleteLocalRef(local_ref); convertJValueToNPVariant(value, field->getJNIType(), field->type(), result); |