diff options
Diffstat (limited to 'JavaScriptCore/API/JSContextRef.cpp')
-rw-r--r-- | JavaScriptCore/API/JSContextRef.cpp | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/JavaScriptCore/API/JSContextRef.cpp b/JavaScriptCore/API/JSContextRef.cpp index 2c76338..06f9274 100644 --- a/JavaScriptCore/API/JSContextRef.cpp +++ b/JavaScriptCore/API/JSContextRef.cpp @@ -33,7 +33,7 @@ #include "JSClassRef.h" #include "JSGlobalObject.h" #include "JSObject.h" -#include <wtf/Platform.h> +#include <wtf/text/StringHash.h> #if OS(DARWIN) #include <mach-o/dyld.h> @@ -46,7 +46,7 @@ using namespace JSC; JSContextGroupRef JSContextGroupCreate() { initializeThreading(); - return toRef(JSGlobalData::createNonDefault().releaseRef()); + return toRef(JSGlobalData::createNonDefault(ThreadStackTypeSmall).releaseRef()); } JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) @@ -84,7 +84,7 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass initializeThreading(); JSLock lock(LockForReal); - RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createNonDefault(); + RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createNonDefault(ThreadStackTypeSmall); APIEntryShim entryShim(globalData.get(), false); @@ -123,19 +123,32 @@ void JSGlobalContextRelease(JSGlobalContextRef ctx) JSLock lock(exec); JSGlobalData& globalData = exec->globalData(); - IdentifierTable* savedIdentifierTable = setCurrentIdentifierTable(globalData.identifierTable); - - gcUnprotect(exec->dynamicGlobalObject()); - - if (globalData.refCount() == 2) { // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain(). - // The last reference was released, this is our last chance to collect. + JSGlobalObject* dgo = exec->dynamicGlobalObject(); + IdentifierTable* savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable); + + // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain(). + bool releasingContextGroup = globalData.refCount() == 2; + bool releasingGlobalObject = Heap::heap(dgo)->unprotect(dgo); + // If this is the last reference to a global data, it should also + // be the only remaining reference to the global object too! + ASSERT(!releasingContextGroup || releasingGlobalObject); + + // An API 'JSGlobalContextRef' retains two things - a global object and a + // global data (or context group, in API terminology). + // * If this is the last reference to any contexts in the given context group, + // call destroy on the heap (the global data is being freed). + // * If this was the last reference to the global object, then unprotecting + // it may release a lot of GC memory - run the garbage collector now. + // * If there are more references remaining the the global object, then do nothing + // (specifically that is more protects, which we assume come from other JSGlobalContextRefs). + if (releasingContextGroup) globalData.heap.destroy(); - } else + else if (releasingGlobalObject) globalData.heap.collectAllGarbage(); globalData.deref(); - setCurrentIdentifierTable(savedIdentifierTable); + wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable); } JSObjectRef JSContextGetGlobalObject(JSContextRef ctx) |