зеркало из https://github.com/mozilla/gecko-dev.git
Fix several memory leaks. Also, use monitors around sensetive structures.
Original committer: pedemont%us.ibm.com Original revision: 1.23 Original date: 2005/02/24 23:17:36
This commit is contained in:
Родитель
9099d9e10a
Коммит
7a5c700888
|
@ -374,27 +374,22 @@ SetupParams(JNIEnv *env, const jobject aParam, const nsXPTParamInfo &aParamInfo,
|
|||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
NS_RELEASE(xpcom_obj);
|
||||
xpcom_obj = weakref;
|
||||
NS_ADDREF(xpcom_obj);
|
||||
aVariant.SetValIsAllocated();
|
||||
} else { // if is native XPCOM object
|
||||
nsCOMPtr<nsISupportsWeakReference> supportsweak =
|
||||
do_QueryInterface(xpcom_obj);
|
||||
if (supportsweak) {
|
||||
nsWeakPtr weakref;
|
||||
supportsweak->GetWeakReference(getter_AddRefs(weakref));
|
||||
NS_RELEASE(xpcom_obj);
|
||||
xpcom_obj = weakref;
|
||||
NS_ADDREF(xpcom_obj);
|
||||
} else {
|
||||
xpcom_obj = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (isXPTCStub) {
|
||||
aVariant.SetValIsAllocated();
|
||||
|
||||
} else { // if is native XPCOM object
|
||||
xpcom_obj->Release();
|
||||
}
|
||||
} else {
|
||||
xpcom_obj = nsnull;
|
||||
|
@ -618,7 +613,6 @@ FinalizeParams(JNIEnv *env, const jobject aParam,
|
|||
PRUint32 length = nsCRT::strlen((const PRUnichar*) aVariant.val.p);
|
||||
str = env->NewString((const jchar*) aVariant.val.p, length);
|
||||
}
|
||||
nsMemory::Free(aVariant.val.p);
|
||||
if (!str) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
|
@ -693,11 +687,7 @@ FinalizeParams(JNIEnv *env, const jobject aParam,
|
|||
env->SetObjectArrayElement((jobjectArray) aParam, 0, java_obj);
|
||||
}
|
||||
|
||||
// If VAL_IS_ALLOCD is set, that means that an XPCOM object was created
|
||||
// is SetupParams that now needs to be released.
|
||||
if (xpcom_obj && aVariant.IsValAllocated()) {
|
||||
NS_RELEASE(xpcom_obj);
|
||||
}
|
||||
NS_IF_RELEASE(xpcom_obj);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -770,6 +760,9 @@ FinalizeParams(JNIEnv *env, const jobject aParam,
|
|||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles 'retval' and 'dipper' params.
|
||||
*/
|
||||
nsresult
|
||||
SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
||||
const nsXPTMethodInfo* aMethodInfo, nsIInterfaceInfo* aIInfo,
|
||||
|
@ -901,12 +894,13 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
|||
case nsXPTType::T_DOMSTRING:
|
||||
{
|
||||
if (aVariant.ptr) {
|
||||
nsString* str = (nsString*) aVariant.ptr;
|
||||
nsString* str = NS_STATIC_CAST(nsString*, aVariant.ptr);
|
||||
*result = env->NewString(str->get(), str->Length());
|
||||
if (*result == nsnull) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
delete str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -915,12 +909,13 @@ SetRetval(JNIEnv *env, const nsXPTParamInfo &aParamInfo,
|
|||
case nsXPTType::T_CSTRING:
|
||||
{
|
||||
if (aVariant.ptr) {
|
||||
nsCString* str = (nsCString*) aVariant.ptr;
|
||||
nsCString* str = NS_STATIC_CAST(nsCString*, aVariant.ptr);
|
||||
*result = env->NewStringUTF(str->get());
|
||||
if (*result == nsnull) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
delete str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1094,7 +1089,7 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
|
|||
rv = SetupParams(env, env->GetObjectArrayElement(aParams, i), paramInfo,
|
||||
methodInfo, iinfo, methodIndex, params, params[i]);
|
||||
} else if (paramInfo.IsDipper()) {
|
||||
LOG(("dipper"));
|
||||
LOG(("dipper\n"));
|
||||
const nsXPTType &type = paramInfo.GetType();
|
||||
switch (type.TagPart())
|
||||
{
|
||||
|
@ -1173,7 +1168,7 @@ JAVAPROXY_NATIVE(callXPCOMMethod) (JNIEnv *env, jclass that, jobject aJavaProxy,
|
|||
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(j);
|
||||
const nsXPTType &type = paramInfo.GetType();
|
||||
if (type.TagPart() == nsXPTType::T_IID) {
|
||||
nsID* iid = (nsID*) params[j].ptr;
|
||||
nsID* iid = (nsID*) params[j].val.p;
|
||||
delete iid;
|
||||
}
|
||||
}
|
||||
|
@ -1243,8 +1238,8 @@ CreateJavaProxy(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
|
|||
#ifdef DEBUG_JAVAXPCOM
|
||||
char* iid_str = aIID.ToString();
|
||||
LOG(("+ CreateJavaProxy (Java=%08x | XPCOM=%08x | IID=%s)\n",
|
||||
env->CallIntMethod(java_obj, hashCodeMID),
|
||||
(int) aXPCOMObject, iid_str));
|
||||
(PRUint32) env->CallIntMethod(java_obj, hashCodeMID),
|
||||
(PRUint32) aXPCOMObject, iid_str));
|
||||
PR_Free(iid_str);
|
||||
#endif
|
||||
|
||||
|
@ -1285,8 +1280,8 @@ GetXPCOMInstFromProxy(JNIEnv* env, jobject aJavaObject, void** aResult)
|
|||
inst->InterfaceInfo()->GetInterfaceIID(&iid);
|
||||
char* iid_str = iid->ToString();
|
||||
LOG(("< GetXPCOMInstFromProxy (Java=%08x | XPCOM=%08x | IID=%s)\n",
|
||||
env->CallIntMethod(aJavaObject, hashCodeMID),
|
||||
(int) inst->GetInstance(), iid_str));
|
||||
(PRUint32) env->CallIntMethod(aJavaObject, hashCodeMID),
|
||||
(PRUint32) inst->GetInstance(), iid_str));
|
||||
PR_Free(iid_str);
|
||||
nsMemory::Free(iid);
|
||||
#endif
|
||||
|
@ -1299,33 +1294,38 @@ GetXPCOMInstFromProxy(JNIEnv* env, jobject aJavaObject, void** aResult)
|
|||
extern "C" JX_EXPORT void JNICALL
|
||||
JAVAPROXY_NATIVE(finalizeProxy) (JNIEnv *env, jclass that, jobject aJavaProxy)
|
||||
{
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
PRUint32 xpcom_addr = 0;
|
||||
#endif
|
||||
|
||||
// Due to Java's garbage collection, this finalize statement may get called
|
||||
// after FreeJavaGlobals(). So check to make sure that everything is still
|
||||
// initialized.
|
||||
if (gJavaXPCOMLock) {
|
||||
nsAutoLock lock(gJavaXPCOMLock);
|
||||
if (gJavaXPCOMMonitor) {
|
||||
nsAutoMonitor mon(gJavaXPCOMMonitor);
|
||||
|
||||
// Get native XPCOM instance
|
||||
void* xpcom_obj;
|
||||
nsresult rv = GetXPCOMInstFromProxy(env, aJavaProxy, &xpcom_obj);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj);
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
xpcom_addr = NS_REINTERPRET_CAST(PRUint32, inst->GetInstance());
|
||||
#endif
|
||||
nsIID* iid;
|
||||
rv = inst->InterfaceInfo()->GetInterfaceIID(&iid);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = gNativeToJavaProxyMap->Remove(env, inst->GetInstance(), *iid);
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
char* iid_str = iid->ToString();
|
||||
LOG(("- Finalize (Java=%08x | XPCOM=%08x | IID=%s)\n",
|
||||
env->CallIntMethod(aJavaProxy, hashCodeMID),
|
||||
(int) inst->GetInstance(), iid_str));
|
||||
PR_Free(iid_str);
|
||||
#endif
|
||||
nsMemory::Free(iid);
|
||||
}
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to RemoveJavaProxy");
|
||||
delete inst;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_JAVAXPCOM
|
||||
LOG(("- Finalize (Java=%08x | XPCOM=%08x)\n",
|
||||
(PRUint32) env->CallIntMethod(aJavaProxy, hashCodeMID), xpcom_addr));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -110,7 +110,10 @@ extern NativeToJavaProxyMap* gNativeToJavaProxyMap;
|
|||
class JavaToXPTCStubMap;
|
||||
extern JavaToXPTCStubMap* gJavaToXPTCStubMap;
|
||||
|
||||
extern PRLock* gJavaXPCOMLock;
|
||||
// The Java garbage collector runs in a separate thread. Since it calls the
|
||||
// finalizeProxy() function in nsJavaWrapper.cpp, we need to make sure that
|
||||
// all the structures touched by finalizeProxy() are multithread aware.
|
||||
extern PRMonitor* gJavaXPCOMMonitor;
|
||||
|
||||
/**
|
||||
* Initialize global structures used by Javaconnect.
|
||||
|
@ -154,6 +157,11 @@ private:
|
|||
*/
|
||||
class NativeToJavaProxyMap
|
||||
{
|
||||
friend PLDHashOperator DestroyJavaProxyMappingEnum(PLDHashTable* aTable,
|
||||
PLDHashEntryHdr* aHeader,
|
||||
PRUint32 aNumber,
|
||||
void* aData);
|
||||
|
||||
protected:
|
||||
struct ProxyList
|
||||
{
|
||||
|
@ -179,10 +187,16 @@ public:
|
|||
: mHashTable(nsnull)
|
||||
{ }
|
||||
|
||||
~NativeToJavaProxyMap();
|
||||
~NativeToJavaProxyMap()
|
||||
{
|
||||
NS_ASSERTION(mHashTable == nsnull,
|
||||
"MUST call Destroy() before deleting object");
|
||||
}
|
||||
|
||||
nsresult Init();
|
||||
|
||||
nsresult Destroy(JNIEnv* env);
|
||||
|
||||
nsresult Add(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID,
|
||||
jobject aProxy);
|
||||
|
||||
|
@ -200,11 +214,15 @@ protected:
|
|||
*/
|
||||
class JavaToXPTCStubMap
|
||||
{
|
||||
friend PLDHashOperator DestroyXPTCMappingEnum(PLDHashTable* aTable,
|
||||
PLDHashEntryHdr* aHeader,
|
||||
PRUint32 aNumber, void* aData);
|
||||
|
||||
protected:
|
||||
struct Entry : public PLDHashEntryHdr
|
||||
{
|
||||
jint key;
|
||||
nsJavaXPTCStub* xptcstub;
|
||||
jint key;
|
||||
nsJavaXPTCStub* xptcstub;
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -212,10 +230,16 @@ public:
|
|||
: mHashTable(nsnull)
|
||||
{ }
|
||||
|
||||
~JavaToXPTCStubMap();
|
||||
~JavaToXPTCStubMap()
|
||||
{
|
||||
NS_ASSERTION(mHashTable == nsnull,
|
||||
"MUST call Destroy() before deleting object");
|
||||
}
|
||||
|
||||
nsresult Init();
|
||||
|
||||
nsresult Destroy();
|
||||
|
||||
nsresult Add(JNIEnv* env, jobject aJavaObject, nsJavaXPTCStub* aProxy);
|
||||
|
||||
nsresult Find(JNIEnv* env, jobject aJavaObject, const nsIID& aIID,
|
||||
|
@ -300,7 +324,7 @@ void ThrowException(JNIEnv* env, const nsresult aErrorCode,
|
|||
|
||||
/**
|
||||
* Helper functions for converting from java.lang.String to
|
||||
* nsAString/nsACstring.
|
||||
* nsAString/nsACstring. Caller must delete nsAString/nsACString.
|
||||
*
|
||||
* @param env Java environment pointer
|
||||
* @param aString Java string to convert
|
||||
|
|
Загрузка…
Ссылка в новой задаче