Commit c652a6b4 authored by ggaren's avatar ggaren

RS by Brady Eidson.

        
        Rolling back in r18786 with leaks fixed, and these renames slightly reworked:

        Because they can return 0:
        rootObjectForImp => findRootObject (overloaded for JSObject* and Interpreter*)
        rootObjectForInterpreter => findRootObject (ditto)
        findReferenceSet => findProtectCountSet



git-svn-id: svn://svn.chromium.org/blink/trunk@18811 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 0ae841b5
2007-01-12 Geoffrey Garen <ggaren@apple.com>
RS by Brady Eidson.
Rolling back in r18786 with leaks fixed, and these renames slightly reworked:
Because they can return 0:
rootObjectForImp => findRootObject (overloaded for JSObject* and Interpreter*)
rootObjectForInterpreter => findRootObject (ditto)
findReferenceSet => findProtectCountSet
2007-01-11 Geoffrey Garen <ggaren@apple.com> 2007-01-11 Geoffrey Garen <ggaren@apple.com>
RS by Brady Eidson. RS by Brady Eidson.
......
...@@ -126,7 +126,7 @@ void convertValueToNPVariant(ExecState *exec, JSValue *value, NPVariant *result) ...@@ -126,7 +126,7 @@ void convertValueToNPVariant(ExecState *exec, JSValue *value, NPVariant *result)
OBJECT_TO_NPVARIANT(obj, *result); OBJECT_TO_NPVARIANT(obj, *result);
} else { } else {
Interpreter *originInterpreter = exec->dynamicInterpreter(); Interpreter *originInterpreter = exec->dynamicInterpreter();
const Bindings::RootObject* originRootObject = rootObjectForInterpreter(originInterpreter); const Bindings::RootObject* originRootObject = findRootObject(originInterpreter);
Interpreter *interpreter = 0; Interpreter *interpreter = 0;
if (originInterpreter->isGlobalObject(value)) { if (originInterpreter->isGlobalObject(value)) {
...@@ -136,7 +136,7 @@ void convertValueToNPVariant(ExecState *exec, JSValue *value, NPVariant *result) ...@@ -136,7 +136,7 @@ void convertValueToNPVariant(ExecState *exec, JSValue *value, NPVariant *result)
if (!interpreter) if (!interpreter)
interpreter = originInterpreter; interpreter = originInterpreter;
const RootObject* rootObject = rootObjectForInterpreter(interpreter); const RootObject* rootObject = findRootObject(interpreter);
if (!rootObject) { if (!rootObject) {
RootObject* newRootObject = new RootObject(0, interpreter); RootObject* newRootObject = new RootObject(0, interpreter);
rootObject = newRootObject; rootObject = newRootObject;
......
...@@ -79,7 +79,7 @@ jvalue JavaJSObject::invoke (JSObjectCallContext *context) ...@@ -79,7 +79,7 @@ jvalue JavaJSObject::invoke (JSObjectCallContext *context)
} }
else { else {
JSObject *imp = jlong_to_impptr(nativeHandle); JSObject *imp = jlong_to_impptr(nativeHandle);
if (!rootObjectForImp(imp)) { if (!findRootObject(imp)) {
fprintf (stderr, "%s:%d: Attempt to access JavaScript from destroyed applet, type %d.\n", __FILE__, __LINE__, context->type); fprintf (stderr, "%s:%d: Attempt to access JavaScript from destroyed applet, type %d.\n", __FILE__, __LINE__, context->type);
return result; return result;
} }
...@@ -127,14 +127,10 @@ jvalue JavaJSObject::invoke (JSObjectCallContext *context) ...@@ -127,14 +127,10 @@ jvalue JavaJSObject::invoke (JSObjectCallContext *context)
case Finalize: { case Finalize: {
JSObject *imp = jlong_to_impptr(nativeHandle); JSObject *imp = jlong_to_impptr(nativeHandle);
if (findReferenceSet(imp) == 0) { // We may have received a finalize method call from the VM
// We may have received a finalize method call from the VM // AFTER removing our last reference to the Java instance.
// AFTER removing our last reference to the Java instance. if (findProtectCountSet(imp))
JS_LOG ("finalize called on instance we have already removed.\n");
}
else {
JavaJSObject(nativeHandle).finalize(); JavaJSObject(nativeHandle).finalize();
}
break; break;
} }
...@@ -158,7 +154,7 @@ JavaJSObject::JavaJSObject(jlong nativeJSObject) ...@@ -158,7 +154,7 @@ JavaJSObject::JavaJSObject(jlong nativeJSObject)
// terribly wrong. // terribly wrong.
assert (_imp != 0); assert (_imp != 0);
_rootObject = rootObjectForImp(_imp); _rootObject = findRootObject(_imp);
// If we can't find the root for the object something is terribly wrong. // If we can't find the root for the object something is terribly wrong.
assert (_rootObject != 0); assert (_rootObject != 0);
...@@ -300,7 +296,7 @@ jlong JavaJSObject::createNative(jlong nativeHandle) ...@@ -300,7 +296,7 @@ jlong JavaJSObject::createNative(jlong nativeHandle)
if (nativeHandle == UndefinedHandle) if (nativeHandle == UndefinedHandle)
return nativeHandle; return nativeHandle;
if (rootObjectForImp(jlong_to_impptr(nativeHandle))) if (findRootObject(jlong_to_impptr(nativeHandle)))
return nativeHandle; return nativeHandle;
CreateRootObjectFunction createRootObject = RootObject::createRootObject(); CreateRootObjectFunction createRootObject = RootObject::createRootObject();
......
...@@ -141,7 +141,7 @@ JSValue* ObjcField::valueFromInstance(ExecState* exec, const Instance* instance) ...@@ -141,7 +141,7 @@ JSValue* ObjcField::valueFromInstance(ExecState* exec, const Instance* instance)
static id convertValueToObjcObject(ExecState* exec, JSValue* value) static id convertValueToObjcObject(ExecState* exec, JSValue* value)
{ {
const RootObject* rootObject = rootObjectForInterpreter(exec->dynamicInterpreter()); const RootObject* rootObject = findRootObject(exec->dynamicInterpreter());
if (!rootObject) { if (!rootObject) {
RootObject* newRootObject = new RootObject(0, exec->dynamicInterpreter()); RootObject* newRootObject = new RootObject(0, exec->dynamicInterpreter());
rootObject = newRootObject; rootObject = newRootObject;
......
...@@ -136,7 +136,7 @@ ObjcValue convertValueToObjcValue(ExecState *exec, JSValue *value, ObjcValueType ...@@ -136,7 +136,7 @@ ObjcValue convertValueToObjcValue(ExecState *exec, JSValue *value, ObjcValueType
switch (type) { switch (type) {
case ObjcObjectType: { case ObjcObjectType: {
Interpreter *originInterpreter = exec->dynamicInterpreter(); Interpreter *originInterpreter = exec->dynamicInterpreter();
const RootObject* originRootObject = rootObjectForInterpreter(originInterpreter); const RootObject* originRootObject = findRootObject(originInterpreter);
Interpreter *interpreter = 0; Interpreter *interpreter = 0;
if (originInterpreter->isGlobalObject(value)) if (originInterpreter->isGlobalObject(value))
...@@ -145,7 +145,7 @@ ObjcValue convertValueToObjcValue(ExecState *exec, JSValue *value, ObjcValueType ...@@ -145,7 +145,7 @@ ObjcValue convertValueToObjcValue(ExecState *exec, JSValue *value, ObjcValueType
if (!interpreter) if (!interpreter)
interpreter = originInterpreter; interpreter = originInterpreter;
const RootObject* rootObject = rootObjectForInterpreter(interpreter); const RootObject* rootObject = findRootObject(interpreter);
if (!rootObject) { if (!rootObject) {
RootObject* newRootObject = new RootObject(0, interpreter); RootObject* newRootObject = new RootObject(0, interpreter);
rootObject = newRootObject; rootObject = newRootObject;
......
...@@ -44,119 +44,93 @@ namespace KJS { namespace Bindings { ...@@ -44,119 +44,93 @@ namespace KJS { namespace Bindings {
// 1 OR the applet is shutdown we deref the JavaScript instance. Applet instances // 1 OR the applet is shutdown we deref the JavaScript instance. Applet instances
// are represented by a jlong. // are represented by a jlong.
typedef HashMap<const RootObject*, ReferencesSet*> ReferencesByRootMap; typedef HashMap<const RootObject*, ProtectCountSet*> RootObjectMap;
static ReferencesByRootMap* getReferencesByRootMap() static RootObjectMap* rootObjectMap()
{ {
static ReferencesByRootMap* referencesByRootMap = 0; static RootObjectMap staticRootObjectMap;
return &staticRootObjectMap;
if (!referencesByRootMap)
referencesByRootMap = new ReferencesByRootMap;
return referencesByRootMap;
} }
static ReferencesSet* getReferencesSet(const RootObject* rootObject) static ProtectCountSet* getProtectCountSet(const RootObject* rootObject)
{ {
ReferencesByRootMap* refsByRoot = getReferencesByRootMap(); ProtectCountSet* protectCountSet = rootObjectMap()->get(rootObject);
ReferencesSet* referencesSet = 0;
if (!protectCountSet) {
referencesSet = refsByRoot->get(rootObject); protectCountSet = new ProtectCountSet;
if (!referencesSet) { rootObjectMap()->add(rootObject, protectCountSet);
referencesSet = new ReferencesSet;
refsByRoot->add(rootObject, referencesSet);
} }
return referencesSet; return protectCountSet;
} }
// Scan all the dictionary for all the roots to see if any have a static void destroyProtectCountSet(const RootObject* rootObject, ProtectCountSet* protectCountSet)
// reference to the imp, and if so, return it's reference count
// dictionary.
// FIXME: This is a potential performance bottleneck with many applets. We could fix be adding a
// imp to root dictionary.
ReferencesSet* findReferenceSet(JSObject* imp)
{ {
ReferencesByRootMap* refsByRoot = getReferencesByRootMap (); rootObjectMap()->remove(rootObject);
if (refsByRoot) { delete protectCountSet;
ReferencesByRootMap::const_iterator end = refsByRoot->end();
for (ReferencesByRootMap::const_iterator it = refsByRoot->begin(); it != end; ++it) {
ReferencesSet* set = it->second;
if (set->contains(imp))
return set;
}
}
return 0;
} }
// FIXME: This is a potential performance bottleneck with many applets. We could fix be adding a // FIXME: These two functions are a potential performance problem. We could
// imp to root dictionary. // fix them by adding a JSObject to RootObject dictionary.
const RootObject* rootObjectForImp (JSObject* imp)
ProtectCountSet* findProtectCountSet(JSObject* jsObject)
{ {
ReferencesByRootMap* refsByRoot = getReferencesByRootMap (); const RootObject* rootObject = findRootObject(jsObject);
const RootObject* rootObject = 0; return rootObject ? getProtectCountSet(rootObject) : 0;
}
if (refsByRoot) {
ReferencesByRootMap::const_iterator end = refsByRoot->end(); const RootObject* findRootObject(JSObject* jsObject)
for (ReferencesByRootMap::const_iterator it = refsByRoot->begin(); it != end; ++it) { {
ReferencesSet* set = it->second; RootObjectMap::const_iterator end = rootObjectMap()->end();
if (set->contains(imp)) { for (RootObjectMap::const_iterator it = rootObjectMap()->begin(); it != end; ++it) {
rootObject = it->first; ProtectCountSet* set = it->second;
break; if (set->contains(jsObject))
} return it->first;
}
} }
return rootObject; return 0;
} }
const RootObject* rootObjectForInterpreter(Interpreter* interpreter) const RootObject* findRootObject(Interpreter* interpreter)
{ {
ReferencesByRootMap* refsByRoot = getReferencesByRootMap (); RootObjectMap::const_iterator end = rootObjectMap()->end();
for (RootObjectMap::const_iterator it = rootObjectMap()->begin(); it != end; ++it) {
if (refsByRoot) { const RootObject* aRootObject = it->first;
ReferencesByRootMap::const_iterator end = refsByRoot->end();
for (ReferencesByRootMap::const_iterator it = refsByRoot->begin(); it != end; ++it) { if (aRootObject->interpreter() == interpreter)
const RootObject* aRootObject = it->first; return aRootObject;
if (aRootObject->interpreter() == interpreter)
return aRootObject;
}
} }
return 0; return 0;
} }
void addNativeReference(const RootObject* rootObject, JSObject* imp) void addNativeReference(const RootObject* rootObject, JSObject* jsObject)
{ {
if (rootObject) { if (!rootObject)
ReferencesSet* referenceMap = getReferencesSet(rootObject); return;
unsigned numReferences = referenceMap->count(imp); ProtectCountSet* protectCountSet = getProtectCountSet(rootObject);
if (numReferences == 0) { if (!protectCountSet->contains(jsObject)) {
JSLock lock; JSLock lock;
gcProtect(imp); gcProtect(jsObject);
}
referenceMap->add(imp);
} }
protectCountSet->add(jsObject);
} }
void removeNativeReference(JSObject* imp) void removeNativeReference(JSObject* jsObject)
{ {
if (!imp) if (!jsObject)
return; return;
ReferencesSet *referencesSet = findReferenceSet(imp); // We might have manually detroyed the root object and its protect set already
if (referencesSet) { ProtectCountSet* protectCountSet = findProtectCountSet(jsObject);
unsigned numReferences = referencesSet->count(imp); if (!protectCountSet)
return;
if (numReferences == 1) {
JSLock lock; if (protectCountSet->count(jsObject) == 1) {
gcUnprotect(imp); JSLock lock;
} gcUnprotect(jsObject);
referencesSet->remove(imp);
} }
protectCountSet->remove(jsObject);
} }
#if PLATFORM(MAC) #if PLATFORM(MAC)
...@@ -286,18 +260,16 @@ void RootObject::setCreateRootObject(CreateRootObjectFunction createRootObject) ...@@ -286,18 +260,16 @@ void RootObject::setCreateRootObject(CreateRootObjectFunction createRootObject)
// Destroys the RootObject and unprotects all JSObjects associated with it. // Destroys the RootObject and unprotects all JSObjects associated with it.
void RootObject::destroy() void RootObject::destroy()
{ {
ReferencesSet* referencesSet = getReferencesSet(this); ProtectCountSet* protectCountSet = getProtectCountSet(this);
if (referencesSet) { if (protectCountSet) {
ReferencesSet::iterator end = referencesSet->end(); ProtectCountSet::iterator end = protectCountSet->end();
for (ReferencesSet::iterator it = referencesSet->begin(); it != end; ++it) { for (ProtectCountSet::iterator it = protectCountSet->begin(); it != end; ++it) {
JSLock lock; JSLock lock;
gcUnprotect(it->first); gcUnprotect(it->first);
} }
referencesSet->clear();
ReferencesByRootMap* refsByRoot = getReferencesByRootMap(); destroyProtectCountSet(this, protectCountSet);
refsByRoot->remove(this);
delete referencesSet;
} }
delete this; delete this;
......
...@@ -39,13 +39,13 @@ namespace Bindings { ...@@ -39,13 +39,13 @@ namespace Bindings {
class RootObject; class RootObject;
typedef RootObject* (*CreateRootObjectFunction)(void* nativeHandle); typedef RootObject* (*CreateRootObjectFunction)(void* nativeHandle);
typedef HashCountedSet<JSObject*> ReferencesSet; typedef HashCountedSet<JSObject*> ProtectCountSet;
extern ReferencesSet* findReferenceSet(JSObject *imp); extern ProtectCountSet* findProtectCountSet(JSObject*);
extern const RootObject* rootObjectForImp(JSObject*); extern const RootObject* findRootObject(JSObject*);
extern const RootObject* rootObjectForInterpreter(Interpreter*); extern const RootObject* findRootObject(Interpreter*);
extern void addNativeReference (const RootObject *root, JSObject *imp); extern void addNativeReference(const RootObject*, JSObject*);
extern void removeNativeReference (JSObject *imp); extern void removeNativeReference(JSObject*);
class RootObject class RootObject
{ {
......
...@@ -417,12 +417,12 @@ void Collector::markStackObjectsConservatively() ...@@ -417,12 +417,12 @@ void Collector::markStackObjectsConservatively()
#endif #endif
} }
typedef HashCountedSet<JSCell *> ProtectCounts; typedef HashCountedSet<JSCell*> ProtectCountSet;
static ProtectCounts& protectedValues() static ProtectCountSet& protectedValues()
{ {
static ProtectCounts pv; static ProtectCountSet staticProtectCountSet;
return pv; return staticProtectCountSet;
} }
void Collector::protect(JSValue *k) void Collector::protect(JSValue *k)
...@@ -449,9 +449,9 @@ void Collector::unprotect(JSValue *k) ...@@ -449,9 +449,9 @@ void Collector::unprotect(JSValue *k)
void Collector::markProtectedObjects() void Collector::markProtectedObjects()
{ {
ProtectCounts& pv = protectedValues(); ProtectCountSet& protectedValues = KJS::protectedValues();
ProtectCounts::iterator end = pv.end(); ProtectCountSet::iterator end = protectedValues.end();
for (ProtectCounts::iterator it = pv.begin(); it != end; ++it) { for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it) {
JSCell *val = it->first; JSCell *val = it->first;
if (!val->marked()) if (!val->marked())
val->mark(); val->mark();
...@@ -669,9 +669,9 @@ HashCountedSet<const char*>* Collector::rootObjectTypeCounts() ...@@ -669,9 +669,9 @@ HashCountedSet<const char*>* Collector::rootObjectTypeCounts()
{ {
HashCountedSet<const char*>* counts = new HashCountedSet<const char*>; HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
ProtectCounts& pv = protectedValues(); ProtectCountSet& protectedValues = KJS::protectedValues();
ProtectCounts::iterator end = pv.end(); ProtectCountSet::iterator end = protectedValues.end();
for (ProtectCounts::iterator it = pv.begin(); it != end; ++it) for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it)
counts->add(typeName(it->first)); counts->add(typeName(it->first));
return counts; return counts;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment