summaryrefslogtreecommitdiffstats
path: root/V8Binding
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-12-18 12:28:23 +0000
committerSteve Block <steveblock@google.com>2010-01-08 16:22:49 +0000
commit88d4517612dafdcaff7a98f2a68ff071e2734ea6 (patch)
tree6bf4ebf254be2f5726d1d42fb7b5868969047cb9 /V8Binding
parent621d19b254dc27a490101dcc947c9a29517af899 (diff)
downloadexternal_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.cpp29
-rw-r--r--V8Binding/jni/jni_instance.h38
-rw-r--r--V8Binding/jni/jni_npobject.cpp12
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);