Commit ee9b4368 authored by barraclough@apple.com's avatar barraclough@apple.com
Browse files

https://bugs.webkit.org/show_bug.cgi?id=33236

Remove m_identifierTable pointer from UString

Reviewed by Sam Weinig.

JavaScriptCore: 

Currently every string holds a pointer so that during destruction,
if a string has been used as an identifier, it can remove itself
from the table.  By instead accessing the identifierTable via a
thread specific tracking the table associated with the current
globaldata, we can save the memory cost of this pointer.

* API/APIShims.h:
(JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
(JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
(JSC::APICallbackShim::APICallbackShim):
(JSC::APICallbackShim::~APICallbackShim):

    - change the API shims to track the identifierTable of the current JSGlobalData.

* API/JSContextRef.cpp:
(JSContextGroupCreate):

    - update creation of JSGlobalData for API usage to use new create method.
    - fix shim instanciation bug in JSGlobalContextCreateInGroup.

* JavaScriptCore.exp:
* runtime/Completion.cpp:
(JSC::checkSyntax):
(JSC::evaluate):

    - add asserts to check the identifierTable is being tracked correctly.

* runtime/Identifier.cpp:
(JSC::IdentifierTable::~IdentifierTable):
(JSC::IdentifierTable::add):
(JSC::Identifier::remove):
(JSC::Identifier::checkSameIdentifierTable):
(JSC::createIdentifierTableSpecificCallback):
(JSC::createIdentifierTableSpecific):
(JSC::createDefaultDataSpecific):

    - Use currentIdentifierTable() instead of UStringImpl::m_identifierTable.
    - Define methods to access the thread specific identifier tables.

* runtime/Identifier.h:
(JSC::ThreadIdentifierTableData::ThreadIdentifierTableData):
(JSC::defaultIdentifierTable):
(JSC::setDefaultIdentifierTable):
(JSC::currentIdentifierTable):
(JSC::setCurrentIdentifierTable):
(JSC::resetCurrentIdentifierTable):

    - Declare methods to access the thread specific identifier tables.

* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::createNonDefault):
(JSC::JSGlobalData::create):
(JSC::JSGlobalData::sharedInstance):

    - creation of JSGlobalData objects, other than for API usage, associate themselves with the current thread.

* runtime/JSGlobalData.h:
* runtime/UStringImpl.cpp:
(JSC::UStringImpl::destroy):

    - destroy() method should be using isIdentifier().

* runtime/UStringImpl.h:
(JSC::UStringImpl::isIdentifier):
(JSC::UStringImpl::setIsIdentifier):
(JSC::UStringImpl::checkConsistency):
(JSC::UStringImpl::UStringImpl):

    - replace m_identifierTable with a single m_isIdentifier bit.

* wtf/StringHashFunctions.h:
(WTF::stringHash):

    - change string hash result from 32-bit to 31-bit, to free a bit in UStringImpl for m_isIdentifier.

JavaScriptGlue: 

Add API shims similar to those used in the JSC API to track the current identifierTable.

* JSBase.cpp:
(JSBase::Release):
* JSUtils.cpp:
(JSObjectKJSValue):
(KJSValueToCFTypeInternal):
(unprotectGlobalObject):
(JSGlueAPIEntry::JSGlueAPIEntry):
(JSGlueAPIEntry::~JSGlueAPIEntry):
(JSGlueAPICallback::JSGlueAPICallback):
(JSGlueAPICallback::~JSGlueAPICallback):
* JSUtils.h:
* JSValueWrapper.cpp:
(JSValueWrapper::JSObjectCopyPropertyNames):
(JSValueWrapper::JSObjectCopyProperty):
(JSValueWrapper::JSObjectSetProperty):
(JSValueWrapper::JSObjectCallFunction):
(JSValueWrapper::JSObjectCopyCFValue):
* JavaScriptGlue.cpp:
(JSRunCreate):
(JSRunEvaluate):
(JSRunCheckSyntax):
(JSCollect):
* JavaScriptGlue.xcodeproj/project.pbxproj:
* UserObjectImp.cpp:
(UserObjectImp::callAsFunction):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52856 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 401150b9
......@@ -34,6 +34,7 @@ namespace JSC {
class APIEntryShimWithoutLock {
protected:
APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread)
: m_entryIdentifierTable(setCurrentIdentifierTable(globalData->identifierTable))
{
if (registerThread)
globalData->heap.registerThread();
......@@ -41,7 +42,11 @@ protected:
~APIEntryShimWithoutLock()
{
setCurrentIdentifierTable(m_entryIdentifierTable);
}
private:
IdentifierTable* m_entryIdentifierTable;
};
class APIEntryShim : public APIEntryShimWithoutLock {
......@@ -68,17 +73,21 @@ class APICallbackShim {
public:
APICallbackShim(ExecState* exec)
: m_dropAllLocks(exec)
, m_globalData(&exec->globalData())
{
resetCurrentIdentifierTable();
}
~APICallbackShim()
{
setCurrentIdentifierTable(m_globalData->identifierTable);
}
private:
JSLock::DropAllLocks m_dropAllLocks;
JSGlobalData* m_globalData;
};
}
#endif // APIShims_h
#endif
......@@ -46,7 +46,7 @@ using namespace JSC;
JSContextGroupRef JSContextGroupCreate()
{
initializeThreading();
return toRef(JSGlobalData::create().releaseRef());
return toRef(JSGlobalData::createNonDefault().releaseRef());
}
JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
......@@ -84,8 +84,9 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
initializeThreading();
JSLock lock(LockForReal);
RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::create();
APIEntryShim(globalData.get(), false);
RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createNonDefault();
APIEntryShim entryShim(globalData.get(), false);
#if ENABLE(JSC_MULTIPLE_THREADS)
globalData->makeUsableFromMultipleThreads();
......
2010-01-05 Gavin Barraclough <barraclough@apple.com>
Reviewed by Sam Weinig.
https://bugs.webkit.org/show_bug.cgi?id=33236
Remove m_identifierTable pointer from UString
Currently every string holds a pointer so that during destruction,
if a string has been used as an identifier, it can remove itself
from the table. By instead accessing the identifierTable via a
thread specific tracking the table associated with the current
globaldata, we can save the memory cost of this pointer.
* API/APIShims.h:
(JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
(JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
(JSC::APICallbackShim::APICallbackShim):
(JSC::APICallbackShim::~APICallbackShim):
- change the API shims to track the identifierTable of the current JSGlobalData.
* API/JSContextRef.cpp:
(JSContextGroupCreate):
- update creation of JSGlobalData for API usage to use new create method.
- fix shim instanciation bug in JSGlobalContextCreateInGroup.
* JavaScriptCore.exp:
* runtime/Completion.cpp:
(JSC::checkSyntax):
(JSC::evaluate):
- add asserts to check the identifierTable is being tracked correctly.
* runtime/Identifier.cpp:
(JSC::IdentifierTable::~IdentifierTable):
(JSC::IdentifierTable::add):
(JSC::Identifier::remove):
(JSC::Identifier::checkSameIdentifierTable):
(JSC::createIdentifierTableSpecificCallback):
(JSC::createIdentifierTableSpecific):
(JSC::createDefaultDataSpecific):
- Use currentIdentifierTable() instead of UStringImpl::m_identifierTable.
- Define methods to access the thread specific identifier tables.
* runtime/Identifier.h:
(JSC::ThreadIdentifierTableData::ThreadIdentifierTableData):
(JSC::defaultIdentifierTable):
(JSC::setDefaultIdentifierTable):
(JSC::currentIdentifierTable):
(JSC::setCurrentIdentifierTable):
(JSC::resetCurrentIdentifierTable):
- Declare methods to access the thread specific identifier tables.
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::createNonDefault):
(JSC::JSGlobalData::create):
(JSC::JSGlobalData::sharedInstance):
- creation of JSGlobalData objects, other than for API usage, associate themselves with the current thread.
* runtime/JSGlobalData.h:
* runtime/UStringImpl.cpp:
(JSC::UStringImpl::destroy):
- destroy() method should be using isIdentifier().
* runtime/UStringImpl.h:
(JSC::UStringImpl::isIdentifier):
(JSC::UStringImpl::setIsIdentifier):
(JSC::UStringImpl::checkConsistency):
(JSC::UStringImpl::UStringImpl):
- replace m_identifierTable with a single m_isIdentifier bit.
* wtf/StringHashFunctions.h:
(WTF::stringHash):
- change string hash result from 32-bit to 31-bit, to free a bit in UStringImpl for m_isIdentifier.
2009-12-25 Patrick Gansterer <paroga@paroga.com>
Reviewed by Eric Seidel.
......
......@@ -116,7 +116,7 @@ __ZN3JSC12JSGlobalData13startSamplingEv
__ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE
__ZN3JSC12JSGlobalData14resetDateCacheEv
__ZN3JSC12JSGlobalData14sharedInstanceEv
__ZN3JSC12JSGlobalData6createEb
__ZN3JSC12JSGlobalData6createEv
__ZN3JSC12JSGlobalDataD1Ev
__ZN3JSC12SamplingTool5setupEv
__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
......@@ -181,6 +181,8 @@ __ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_
__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
__ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE
__ZN3JSC25g_identifierTableSpecificE
__ZN3JSC29createIdentifierTableSpecificEv
__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
__ZN3JSC3NaNE
__ZN3JSC4Heap14primaryHeapEndEv
......
......@@ -36,6 +36,7 @@ namespace JSC {
Completion checkSyntax(ExecState* exec, const SourceCode& source)
{
JSLock lock(exec);
ASSERT(exec->globalData().identifierTable == currentIdentifierTable());
RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
JSObject* error = program->checkSyntax(exec);
......@@ -48,6 +49,7 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source)
Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue thisValue)
{
JSLock lock(exec);
ASSERT(exec->globalData().identifierTable == currentIdentifierTable());
RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
JSObject* error = program->compile(exec, scopeChain.node());
......
......@@ -28,6 +28,8 @@
#include <wtf/FastMalloc.h>
#include <wtf/HashSet.h>
using WTF::ThreadSpecific;
namespace JSC {
typedef HashMap<const char*, RefPtr<UString::Rep>, PtrHash<const char*> > LiteralIdentifierTable;
......@@ -38,13 +40,13 @@ public:
{
HashSet<UString::Rep*>::iterator end = m_table.end();
for (HashSet<UString::Rep*>::iterator iter = m_table.begin(); iter != end; ++iter)
(*iter)->setIdentifierTable(0);
(*iter)->setIsIdentifier(false);
}
std::pair<HashSet<UString::Rep*>::iterator, bool> add(UString::Rep* value)
{
std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add(value);
(*result.first)->setIdentifierTable(this);
(*result.first)->setIsIdentifier(true);
return result;
}
......@@ -52,7 +54,7 @@ public:
std::pair<HashSet<UString::Rep*>::iterator, bool> add(U value)
{
std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add<U, V>(value);
(*result.first)->setIdentifierTable(this);
(*result.first)->setIsIdentifier(true);
return result;
}
......@@ -238,19 +240,19 @@ PassRefPtr<UString::Rep> Identifier::addSlowCase(ExecState* exec, UString::Rep*
void Identifier::remove(UString::Rep* r)
{
r->identifierTable()->remove(r);
currentIdentifierTable()->remove(r);
}
#ifndef NDEBUG
void Identifier::checkSameIdentifierTable(ExecState* exec, UString::Rep* rep)
void Identifier::checkSameIdentifierTable(ExecState* exec, UString::Rep*)
{
ASSERT(rep->identifierTable() == exec->globalData().identifierTable);
ASSERT(exec->globalData().identifierTable == currentIdentifierTable());
}
void Identifier::checkSameIdentifierTable(JSGlobalData* globalData, UString::Rep* rep)
void Identifier::checkSameIdentifierTable(JSGlobalData* globalData, UString::Rep*)
{
ASSERT(rep->identifierTable() == globalData->identifierTable);
ASSERT(globalData->identifierTable == currentIdentifierTable());
}
#else
......@@ -265,4 +267,30 @@ void Identifier::checkSameIdentifierTable(JSGlobalData*, UString::Rep*)
#endif
ThreadSpecific<ThreadIdentifierTableData>* g_identifierTableSpecific = 0;
#if ENABLE(JSC_MULTIPLE_THREADS)
pthread_once_t createIdentifierTableSpecificOnce = PTHREAD_ONCE_INIT;
void createIdentifierTableSpecificCallback()
{
ASSERT(!g_identifierTableSpecific);
g_identifierTableSpecific = new ThreadSpecific<ThreadIdentifierTableData>();
}
void createIdentifierTableSpecific()
{
pthread_once(&createIdentifierTableSpecificOnce, createIdentifierTableSpecificCallback);
ASSERT(g_identifierTableSpecific);
}
#else
void createDefaultDataSpecific()
{
ASSERT(!g_identifierTableSpecific);
g_identifierTableSpecific = new ThreadSpecific<ThreadIdentifierTableData>();
}
#endif
} // namespace JSC
......@@ -22,6 +22,7 @@
#define Identifier_h
#include "JSGlobalData.h"
#include "ThreadSpecific.h"
#include "UString.h"
namespace JSC {
......@@ -141,6 +142,67 @@ namespace JSC {
IdentifierTable* createIdentifierTable();
void deleteIdentifierTable(IdentifierTable*);
struct ThreadIdentifierTableData {
ThreadIdentifierTableData()
: defaultIdentifierTable(0)
, currentIdentifierTable(0)
{
}
IdentifierTable* defaultIdentifierTable;
IdentifierTable* currentIdentifierTable;
};
extern WTF::ThreadSpecific<ThreadIdentifierTableData>* g_identifierTableSpecific;
void createIdentifierTableSpecific();
inline IdentifierTable* defaultIdentifierTable()
{
if (!g_identifierTableSpecific)
createIdentifierTableSpecific();
ThreadIdentifierTableData& data = **g_identifierTableSpecific;
return data.defaultIdentifierTable;
}
inline void setDefaultIdentifierTable(IdentifierTable* identifierTable)
{
if (!g_identifierTableSpecific)
createIdentifierTableSpecific();
ThreadIdentifierTableData& data = **g_identifierTableSpecific;
data.defaultIdentifierTable = identifierTable;
}
inline IdentifierTable* currentIdentifierTable()
{
if (!g_identifierTableSpecific)
createIdentifierTableSpecific();
ThreadIdentifierTableData& data = **g_identifierTableSpecific;
return data.currentIdentifierTable;
}
inline IdentifierTable* setCurrentIdentifierTable(IdentifierTable* identifierTable)
{
if (!g_identifierTableSpecific)
createIdentifierTableSpecific();
ThreadIdentifierTableData& data = **g_identifierTableSpecific;
IdentifierTable* oldIdentifierTable = data.currentIdentifierTable;
data.currentIdentifierTable = identifierTable;
return oldIdentifierTable;
}
inline void resetCurrentIdentifierTable()
{
if (!g_identifierTableSpecific)
createIdentifierTableSpecific();
ThreadIdentifierTableData& data = **g_identifierTableSpecific;
data.currentIdentifierTable = data.defaultIdentifierTable;
}
} // namespace JSC
#endif // Identifier_h
......@@ -45,10 +45,10 @@
#include "JSNotAnObject.h"
#include "JSPropertyNameIterator.h"
#include "JSStaticScopeObject.h"
#include "Parser.h"
#include "Lexer.h"
#include "Lookup.h"
#include "Nodes.h"
#include "Parser.h"
#if ENABLE(JSC_MULTIPLE_THREADS)
#include <wtf/Threading.h>
......@@ -202,9 +202,17 @@ JSGlobalData::~JSGlobalData()
delete clientData;
}
PassRefPtr<JSGlobalData> JSGlobalData::create(bool isShared)
PassRefPtr<JSGlobalData> JSGlobalData::createNonDefault()
{
return adoptRef(new JSGlobalData(false, VPtrSet()));
}
PassRefPtr<JSGlobalData> JSGlobalData::create()
{
return adoptRef(new JSGlobalData(isShared, VPtrSet()));
JSGlobalData* globalData = new JSGlobalData(false, VPtrSet());
setDefaultIdentifierTable(globalData->identifierTable);
setCurrentIdentifierTable(globalData->identifierTable);
return adoptRef(globalData);
}
PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
......@@ -224,7 +232,7 @@ JSGlobalData& JSGlobalData::sharedInstance()
{
JSGlobalData*& instance = sharedInstanceInternal();
if (!instance) {
instance = create(true).releaseRef();
instance = new JSGlobalData(true, VPtrSet());
#if ENABLE(JSC_MULTIPLE_THREADS)
instance->makeUsableFromMultipleThreads();
#endif
......
......@@ -93,8 +93,9 @@ namespace JSC {
static bool sharedInstanceExists();
static JSGlobalData& sharedInstance();
static PassRefPtr<JSGlobalData> create(bool isShared = false);
static PassRefPtr<JSGlobalData> create();
static PassRefPtr<JSGlobalData> createLeaked();
static PassRefPtr<JSGlobalData> createNonDefault();
~JSGlobalData();
#if ENABLE(JSC_MULTIPLE_THREADS)
......
......@@ -64,7 +64,7 @@ void UStringImpl::destroy()
ASSERT(!isStatic());
checkConsistency();
if (identifierTable())
if (isIdentifier())
Identifier::remove(this);
if (bufferOwnership() != BufferInternal) {
......
......@@ -137,9 +137,8 @@ public:
unsigned hash() const { if (!m_hash) m_hash = computeHash(data(), m_length); return m_hash; }
unsigned computedHash() const { ASSERT(m_hash); return m_hash; } // fast path for Identifiers
void setHash(unsigned hash) { ASSERT(hash == computeHash(data(), m_length)); m_hash = hash; } // fast path for Identifiers
bool isIdentifier() const { return m_identifierTable; }
IdentifierTable* identifierTable() const { return m_identifierTable; }
void setIdentifierTable(IdentifierTable* table) { ASSERT(!isStatic()); m_identifierTable = table; }
bool isIdentifier() const { return m_isIdentifier; }
void setIsIdentifier(bool isIdentifier) { m_isIdentifier = isIdentifier; }
UStringImpl* ref() { m_refCount += s_refCountIncrement; return this; }
ALWAYS_INLINE void deref() { if (!(m_refCount -= s_refCountIncrement)) destroy(); }
......@@ -173,7 +172,7 @@ public:
// There is no recursion of substrings.
ASSERT(bufferOwnerString()->bufferOwnership() != BufferSubstring);
// Static strings cannot be put in identifier tables, because they are globally shared.
ASSERT(!isStatic() || !identifierTable());
ASSERT(!isStatic() || !isIdentifier());
}
private:
......@@ -193,7 +192,7 @@ private:
, m_length(length)
, m_refCount(s_refCountIncrement)
, m_hash(0)
, m_identifierTable(0)
, m_isIdentifier(false)
, m_dataBuffer(0, ownership)
{
ASSERT((ownership == BufferInternal) || (ownership == BufferOwned));
......@@ -209,7 +208,7 @@ private:
, m_length(length)
, m_refCount(s_staticRefCountInitialValue)
, m_hash(0)
, m_identifierTable(0)
, m_isIdentifier(false)
, m_dataBuffer(0, BufferOwned)
{
checkConsistency();
......@@ -221,7 +220,7 @@ private:
, m_length(length)
, m_refCount(s_refCountIncrement)
, m_hash(0)
, m_identifierTable(0)
, m_isIdentifier(false)
, m_dataBuffer(base.releaseRef(), BufferSubstring)
{
// Do use static strings as a base for substrings; UntypedPtrAndBitfield assumes
......@@ -238,7 +237,7 @@ private:
, m_length(length)
, m_refCount(s_refCountIncrement)
, m_hash(0)
, m_identifierTable(0)
, m_isIdentifier(false)
, m_dataBuffer(sharedBuffer.releaseRef(), BufferShared)
{
checkConsistency();
......@@ -268,8 +267,8 @@ private:
UChar* m_data;
int m_length;
unsigned m_refCount;
mutable unsigned m_hash;
IdentifierTable* m_identifierTable;
mutable unsigned m_hash : 31;
mutable unsigned m_isIdentifier : 1;
UntypedPtrAndBitfield m_dataBuffer;
JS_EXPORTDATA static UStringImpl* s_null;
......
......@@ -60,11 +60,13 @@ inline unsigned stringHash(const UChar* data, unsigned length)
hash += hash >> 15;
hash ^= hash << 10;
hash &= 0x7fffffff;
// this avoids ever returning a hash code of 0, since that is used to
// signal "hash not computed yet", using a value that is likely to be
// effectively the same as 0 when the low bits are masked
if (hash == 0)
hash = 0x80000000;
hash = 0x40000000;
return hash;
}
......@@ -98,11 +100,13 @@ inline unsigned stringHash(const char* data, unsigned length)
hash += hash >> 15;
hash ^= hash << 10;
hash &= 0x7fffffff;
// this avoids ever returning a hash code of 0, since that is used to
// signal "hash not computed yet", using a value that is likely to be
// effectively the same as 0 when the low bits are masked
if (hash == 0)
hash = 0x80000000;
hash = 0x40000000;
return hash;
}
......@@ -137,11 +141,13 @@ inline unsigned stringHash(const char* data)
hash += hash >> 15;
hash ^= hash << 10;
hash &= 0x7fffffff;
// This avoids ever returning a hash code of 0, since that is used to
// signal "hash not computed yet", using a value that is likely to be
// effectively the same as 0 when the low bits are masked.
if (hash == 0)
hash = 0x80000000;
hash = 0x40000000;
return hash;
}
......
2010-01-05 Gavin Barraclough <barraclough@apple.com>
Reviewed by Sam Weinig.
https://bugs.webkit.org/show_bug.cgi?id=33236
Remove m_identifierTable pointer from UString
Add API shims similar to those used in the JSC API to track the current identifierTable.
* JSBase.cpp:
(JSBase::Release):
* JSUtils.cpp:
(JSObjectKJSValue):
(KJSValueToCFTypeInternal):
(unprotectGlobalObject):
(JSGlueAPIEntry::JSGlueAPIEntry):
(JSGlueAPIEntry::~JSGlueAPIEntry):
(JSGlueAPICallback::JSGlueAPICallback):
(JSGlueAPICallback::~JSGlueAPICallback):
* JSUtils.h:
* JSValueWrapper.cpp:
(JSValueWrapper::JSObjectCopyPropertyNames):
(JSValueWrapper::JSObjectCopyProperty):
(JSValueWrapper::JSObjectSetProperty):
(JSValueWrapper::JSObjectCallFunction):
(JSValueWrapper::JSObjectCopyCFValue):
* JavaScriptGlue.cpp:
(JSRunCreate):
(JSRunEvaluate):
(JSRunCheckSyntax):
(JSCollect):
* JavaScriptGlue.xcodeproj/project.pbxproj:
* UserObjectImp.cpp:
(UserObjectImp::callAsFunction):
2010-01-04 Gavin Barraclough <barraclough@apple.com>
Reviewed by Sam Weinig.
......
......@@ -46,7 +46,7 @@ void JSBase::Release()
{
if (--fRetainCount == 0)
{
JSLock lock(LockForReal);
JSGlueAPIEntry entry;
delete this;
}
}
......
......@@ -128,7 +128,7 @@ JSUserObject* KJSValueToJSObject(JSValue inValue, ExecState *exec)
//--------------------------------------------------------------------------
JSValue JSObjectKJSValue(JSUserObject* ptr)
{
JSLock lock(LockForReal);
JSGlueAPIEntry entry;
JSValue result = jsUndefined();
if (ptr)
......@@ -203,7 +203,7 @@ CFTypeRef KJSValueToCFTypeInternal(JSValue inValue, ExecState *exec, ObjectImpLi
CFTypeRef result = 0;
JSLock lock(LockForReal);
JSGlueAPIEntry entry;
if (inValue.isBoolean())
{
......@@ -394,7 +394,7 @@ static pthread_once_t globalObjectKeyOnce = PTHREAD_ONCE_INIT;
static void unprotectGlobalObject(void* data)
{
JSLock lock(LockForReal);
JSGlueAPIEntry entry;
gcUnprotect(static_cast<JSGlueGlobalObject*>(data));
}
......@@ -424,3 +424,26 @@ ExecState* getThreadGlobalExecState()
exec->clearException();
return exec;
}
JSGlueAPIEntry::JSGlueAPIEntry()
: m_lock(LockForReal)
, m_storedIdentifierTable(currentIdentifierTable())
{
setCurrentIdentifierTable(getThreadGlobalObject()->globalExec()->globalData().identifierTable);
}
JSGlueAPIEntry::~JSGlueAPIEntry()
{
setCurrentIdentifierTable(m_storedIdentifierTable);
}
JSGlueAPICallback::JSGlueAPICallback(ExecState* exec)
: m_dropLocks(exec)