java_wrapper->u.hash_code = hash_code;
jsj_WrapJavaObject(JSContext *cx,                   JNIEnv *jEnv,                   jobject java_obj,                   jclass java_class){    JSJHashNumber hash_code;    JSClass *js_class;    JSObject *js_wrapper_obj;    JavaObjectWrapper *java_wrapper;    JavaClassDescriptor *class_descriptor;    JSJHashEntry *he, **hep;#ifdef JSJ_THREADSAFE    int mutation_count;#endif    js_wrapper_obj = NULL;    hash_code = jsj_HashJavaObject((void*)java_obj, (void*)jEnv);#ifdef JSJ_THREADSAFE    PR_EnterMonitor(java_obj_reflections_monitor);#endif        hep = JSJ_HashTableRawLookup(java_obj_reflections,                                 hash_code, java_obj, (void*)jEnv);    he = *hep;#ifdef JSJ_THREADSAFE    /* Track mutations to hash table */    mutation_count = java_obj_reflections_mutation_count;    /* We must temporarily release this monitor so as to avoid       deadlocks with the JS GC.  See Bugsplat #354852 */    PR_ExitMonitor(java_obj_reflections_monitor);#endif    if (he) {        js_wrapper_obj = (JSObject *)he->value;        if (js_wrapper_obj)            return js_wrapper_obj;    }    /* No existing reflection found.  Construct a new one */    class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);    if (!class_descriptor)        return NULL;    if (class_descriptor->type == JAVA_SIGNATURE_ARRAY) {        js_class = &JavaArray_class;    } else {        JS_ASSERT(IS_OBJECT_TYPE(class_descriptor->type));        js_class = &JavaObject_class;    }        /* Create new JS object to reflect Java object */    js_wrapper_obj = JS_NewObject(cx, js_class, NULL, NULL);    if (!js_wrapper_obj)        return NULL;    /* Create private, native portion of JavaObject */    java_wrapper =        (JavaObjectWrapper *)JS_malloc(cx, sizeof(JavaObjectWrapper));    if (!java_wrapper) {        jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);        return NULL;    }    JS_SetPrivate(cx, js_wrapper_obj, java_wrapper);    java_wrapper->class_descriptor = class_descriptor;    java_wrapper->java_obj = NULL;#ifdef JSJ_THREADSAFE    PR_EnterMonitor(java_obj_reflections_monitor);    /* We may need to do the hash table lookup again, since some other       thread may have updated it while the lock wasn't being held. */    if (mutation_count != java_obj_reflections_mutation_count) {        hep = JSJ_HashTableRawLookup(java_obj_reflections,                                     hash_code, java_obj, (void*)jEnv);        he = *hep;        if (he) {            js_wrapper_obj = (JSObject *)he->value;            if (js_wrapper_obj) {                PR_ExitMonitor(java_obj_reflections_monitor);                return js_wrapper_obj;            }        }    }    java_obj_reflections_mutation_count++;#endif    java_obj = (*jEnv)->NewGlobalRef(jEnv, java_obj);    java_wrapper->java_obj = java_obj;    if (!java_obj)        goto out_of_memory;    /* Add the JavaObject to the hash table */    he = JSJ_HashTableRawAdd(java_obj_reflections, hep, hash_code,                             java_obj, js_wrapper_obj, (void*)jEnv);#ifdef JSJ_THREADSAFE    PR_ExitMonitor(java_obj_reflections_monitor);#endif    if (!he) {        (*jEnv)->DeleteGlobalRef(jEnv, java_obj);        goto out_of_memory;    }     return js_wrapper_obj;out_of_memory:    /* No need to free js_wrapper_obj, as it will be finalized by GC. */    JS_ReportOutOfMemory(cx);    return NULL;}