diff options
Diffstat (limited to 'JavaScriptCore')
269 files changed, 11849 insertions, 4487 deletions
diff --git a/JavaScriptCore/API/APIShims.h b/JavaScriptCore/API/APIShims.h new file mode 100644 index 0000000..d7276ec --- /dev/null +++ b/JavaScriptCore/API/APIShims.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APIShims_h +#define APIShims_h + +#include "CallFrame.h" +#include "JSLock.h" + +namespace JSC { + +class APIEntryShimWithoutLock { +protected: + APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread) + : m_globalData(globalData) + , m_entryIdentifierTable(setCurrentIdentifierTable(globalData->identifierTable)) + { + if (registerThread) + globalData->heap.registerThread(); + m_globalData->timeoutChecker.start(); + } + + ~APIEntryShimWithoutLock() + { + m_globalData->timeoutChecker.stop(); + setCurrentIdentifierTable(m_entryIdentifierTable); + } + +private: + JSGlobalData* m_globalData; + IdentifierTable* m_entryIdentifierTable; +}; + +class APIEntryShim : public APIEntryShimWithoutLock { +public: + // Normal API entry + APIEntryShim(ExecState* exec, bool registerThread = true) + : APIEntryShimWithoutLock(&exec->globalData(), registerThread) + , m_lock(exec) + { + } + + // JSPropertyNameAccumulator only has a globalData. + APIEntryShim(JSGlobalData* globalData, bool registerThread = true) + : APIEntryShimWithoutLock(globalData, registerThread) + , m_lock(globalData->isSharedInstance ? LockForReal : SilenceAssertionsOnly) + { + } + +private: + JSLock m_lock; +}; + +class APICallbackShim { +public: + APICallbackShim(ExecState* exec) + : m_dropAllLocks(exec) + , m_globalData(&exec->globalData()) + { + resetCurrentIdentifierTable(); + m_globalData->timeoutChecker.start(); + } + + ~APICallbackShim() + { + m_globalData->timeoutChecker.stop(); + setCurrentIdentifierTable(m_globalData->identifierTable); + } + +private: + JSLock::DropAllLocks m_dropAllLocks; + JSGlobalData* m_globalData; +}; + +} + +#endif diff --git a/JavaScriptCore/API/JSBase.cpp b/JavaScriptCore/API/JSBase.cpp index 4a32d35..ebfeafa 100644 --- a/JavaScriptCore/API/JSBase.cpp +++ b/JavaScriptCore/API/JSBase.cpp @@ -28,6 +28,7 @@ #include "JSBasePrivate.h" #include "APICast.h" +#include "APIShims.h" #include "Completion.h" #include "OpaqueJSString.h" #include "SourceCode.h" @@ -43,8 +44,7 @@ using namespace JSC; JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsThisObject = toJS(thisObject); @@ -69,8 +69,7 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), startingLineNumber); Completion completion = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source); @@ -94,12 +93,11 @@ void JSGarbageCollect(JSContextRef ctx) return; ExecState* exec = toJS(ctx); - JSGlobalData& globalData = exec->globalData(); - - JSLock lock(globalData.isSharedInstance ? LockForReal : SilenceAssertionsOnly); + APIEntryShim entryShim(exec, false); + JSGlobalData& globalData = exec->globalData(); if (!globalData.heap.isBusy()) - globalData.heap.collect(); + globalData.heap.collectAllGarbage(); // FIXME: Perhaps we should trigger a second mark and sweep // once the garbage collector is done if this is called when @@ -109,8 +107,6 @@ void JSGarbageCollect(JSContextRef ctx) void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); - + APIEntryShim entryShim(exec); exec->globalData().heap.reportExtraMemoryCost(size); } diff --git a/JavaScriptCore/API/JSBase.h b/JavaScriptCore/API/JSBase.h index d1ce9b3..2e16720 100644 --- a/JavaScriptCore/API/JSBase.h +++ b/JavaScriptCore/API/JSBase.h @@ -65,27 +65,15 @@ typedef struct OpaqueJSValue* JSObjectRef; /* JavaScript symbol exports */ #undef JS_EXPORT -#if defined(BUILDING_WX__) +#if defined(JS_NO_EXPORT) #define JS_EXPORT #elif defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC__) #define JS_EXPORT __attribute__((visibility("default"))) -#elif defined(_WIN32_WCE) - #if defined(JS_BUILDING_JS) - #define JS_EXPORT __declspec(dllexport) - #elif defined(JS_IMPORT_JS) - #define JS_EXPORT __declspec(dllimport) - #else - #define JS_EXPORT - #endif -#elif defined(WIN32) || defined(_WIN32) - /* - * TODO: Export symbols with JS_EXPORT when using MSVC. - * See http://bugs.webkit.org/show_bug.cgi?id=16227 - */ +#elif defined(WIN32) || defined(_WIN32) || defined(_WIN32_WCE) #if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF) - #define JS_EXPORT __declspec(dllexport) + #define JS_EXPORT __declspec(dllexport) #else - #define JS_EXPORT __declspec(dllimport) + #define JS_EXPORT __declspec(dllimport) #endif #else #define JS_EXPORT diff --git a/JavaScriptCore/API/JSCallbackConstructor.cpp b/JavaScriptCore/API/JSCallbackConstructor.cpp index 1c33962..9c5f6d7 100644 --- a/JavaScriptCore/API/JSCallbackConstructor.cpp +++ b/JavaScriptCore/API/JSCallbackConstructor.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "JSCallbackConstructor.h" +#include "APIShims.h" #include "APICast.h" #include <runtime/JSGlobalObject.h> #include <runtime/JSLock.h> @@ -66,7 +67,7 @@ static JSObject* constructJSCallback(ExecState* exec, JSObject* constructor, con JSValueRef exception = 0; JSObjectRef result; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception); } if (exception) diff --git a/JavaScriptCore/API/JSCallbackConstructor.h b/JavaScriptCore/API/JSCallbackConstructor.h index c4bd7ad..e529947 100644 --- a/JavaScriptCore/API/JSCallbackConstructor.h +++ b/JavaScriptCore/API/JSCallbackConstructor.h @@ -41,7 +41,7 @@ public: static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/API/JSCallbackFunction.cpp b/JavaScriptCore/API/JSCallbackFunction.cpp index b7dd768..0e434d9 100644 --- a/JavaScriptCore/API/JSCallbackFunction.cpp +++ b/JavaScriptCore/API/JSCallbackFunction.cpp @@ -27,6 +27,7 @@ #include <wtf/Platform.h> #include "JSCallbackFunction.h" +#include "APIShims.h" #include "APICast.h" #include "CodeBlock.h" #include "JSFunction.h" @@ -61,7 +62,7 @@ JSValue JSCallbackFunction::call(ExecState* exec, JSObject* functionObject, JSVa JSValueRef exception = 0; JSValueRef result; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); result = static_cast<JSCallbackFunction*>(functionObject)->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception); } if (exception) diff --git a/JavaScriptCore/API/JSCallbackFunction.h b/JavaScriptCore/API/JSCallbackFunction.h index 0cf25c4..10dae6b 100644 --- a/JavaScriptCore/API/JSCallbackFunction.h +++ b/JavaScriptCore/API/JSCallbackFunction.h @@ -41,7 +41,7 @@ public: // refactor the code so this override isn't necessary static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } private: diff --git a/JavaScriptCore/API/JSCallbackObject.h b/JavaScriptCore/API/JSCallbackObject.h index d19890a..adb5b60 100644 --- a/JavaScriptCore/API/JSCallbackObject.h +++ b/JavaScriptCore/API/JSCallbackObject.h @@ -50,7 +50,7 @@ public: static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), Base::AnonymousSlotCount); } protected: @@ -61,6 +61,7 @@ private: virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&); + virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); @@ -69,7 +70,7 @@ private: virtual bool hasInstance(ExecState* exec, JSValue value, JSValue proto); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); virtual double toNumber(ExecState*) const; virtual UString toString(ExecState*) const; diff --git a/JavaScriptCore/API/JSCallbackObjectFunctions.h b/JavaScriptCore/API/JSCallbackObjectFunctions.h index ed86a00..4b28a99 100644 --- a/JavaScriptCore/API/JSCallbackObjectFunctions.h +++ b/JavaScriptCore/API/JSCallbackObjectFunctions.h @@ -24,6 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "APIShims.h" #include "APICast.h" #include "Error.h" #include "JSCallbackFunction.h" @@ -79,7 +80,7 @@ void JSCallbackObject<Base>::init(ExecState* exec) // initialize from base to derived for (int i = static_cast<int>(initRoutines.size()) - 1; i >= 0; i--) { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); JSObjectInitializeCallback initialize = initRoutines[i]; initialize(toRef(exec), toRef(this)); } @@ -117,7 +118,7 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) { if (!propertyNameRef) propertyNameRef = OpaqueJSString::create(propertyName.ustring()); - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); if (hasProperty(ctx, thisRef, propertyNameRef.get())) { slot.setCustom(this, callbackGetter); return true; @@ -128,7 +129,7 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie JSValueRef exception = 0; JSValueRef value; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception); } if (exception) { @@ -167,6 +168,25 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, unsigned proper } template <class Base> +bool JSCallbackObject<Base>::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +{ + PropertySlot slot; + if (getOwnPropertySlot(exec, propertyName, slot)) { + // Ideally we should return an access descriptor, but returning a value descriptor is better than nothing. + JSValue value = slot.getValue(exec, propertyName); + if (!exec->hadException()) + descriptor.setValue(value); + // We don't know whether the property is configurable, but assume it is. + descriptor.setConfigurable(true); + // We don't know whether the property is enumerable (we could call getOwnPropertyNames() to find out), but assume it isn't. + descriptor.setEnumerable(false); + return true; + } + + return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); +} + +template <class Base> void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { JSContextRef ctx = toRef(exec); @@ -181,7 +201,7 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName JSValueRef exception = 0; bool result; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception); } if (exception) @@ -200,7 +220,7 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName JSValueRef exception = 0; bool result; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception); } if (exception) @@ -239,7 +259,7 @@ bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& p JSValueRef exception = 0; bool result; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception); } if (exception) @@ -301,7 +321,7 @@ JSObject* JSCallbackObject<Base>::construct(ExecState* exec, JSObject* construct JSValueRef exception = 0; JSObject* result; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception)); } if (exception) @@ -326,7 +346,7 @@ bool JSCallbackObject<Base>::hasInstance(ExecState* exec, JSValue value, JSValue JSValueRef exception = 0; bool result; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); result = hasInstance(execRef, thisRef, valueRef, &exception); } if (exception) @@ -365,7 +385,7 @@ JSValue JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject, JSValueRef exception = 0; JSValue result; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); result = toJS(exec, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception)); } if (exception) @@ -379,14 +399,14 @@ JSValue JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject, } template <class Base> -void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { JSContextRef execRef = toRef(exec); JSObjectRef thisRef = toRef(this); for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); getPropertyNames(execRef, thisRef, toRef(&propertyNames)); } @@ -396,7 +416,7 @@ void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameAr for (iterator it = staticValues->begin(); it != end; ++it) { UString::Rep* name = it->first.get(); StaticValueEntry* entry = it->second; - if (entry->getProperty && !(entry->attributes & kJSPropertyAttributeDontEnum)) + if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))) propertyNames.add(Identifier(exec, name)); } } @@ -407,13 +427,13 @@ void JSCallbackObject<Base>::getOwnPropertyNames(ExecState* exec, PropertyNameAr for (iterator it = staticFunctions->begin(); it != end; ++it) { UString::Rep* name = it->first.get(); StaticFunctionEntry* entry = it->second; - if (!(entry->attributes & kJSPropertyAttributeDontEnum)) + if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)) propertyNames.add(Identifier(exec, name)); } } } - Base::getOwnPropertyNames(exec, propertyNames); + Base::getOwnPropertyNames(exec, propertyNames, mode); } template <class Base> @@ -432,7 +452,7 @@ double JSCallbackObject<Base>::toNumber(ExecState* exec) const JSValueRef exception = 0; JSValueRef value; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); value = convertToType(ctx, thisRef, kJSTypeNumber, &exception); } if (exception) { @@ -459,7 +479,7 @@ UString JSCallbackObject<Base>::toString(ExecState* exec) const JSValueRef exception = 0; JSValueRef value; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); value = convertToType(ctx, thisRef, kJSTypeString, &exception); } if (exception) { @@ -512,7 +532,7 @@ JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identif JSValueRef exception = 0; JSValueRef value; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception); } if (exception) { @@ -566,7 +586,7 @@ JSValue JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifier JSValueRef exception = 0; JSValueRef value; { - JSLock::DropAllLocks dropAllLocks(exec); + APICallbackShim callbackShim(exec); value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception); } if (exception) { diff --git a/JavaScriptCore/API/JSClassRef.cpp b/JavaScriptCore/API/JSClassRef.cpp index afde7ce..c6685bf 100644 --- a/JavaScriptCore/API/JSClassRef.cpp +++ b/JavaScriptCore/API/JSClassRef.cpp @@ -34,6 +34,7 @@ #include <runtime/ObjectPrototype.h> #include <runtime/Identifier.h> +using namespace std; using namespace JSC; const JSClassDefinition kJSClassDefinitionEmpty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -52,7 +53,7 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* , callAsConstructor(definition->callAsConstructor) , hasInstance(definition->hasInstance) , convertToType(definition->convertToType) - , m_className(UString::Rep::createFromUTF8(definition->className)) + , m_className(UString::createFromUTF8(definition->className).rep()->ref()) , m_staticValues(0) , m_staticFunctions(0) { @@ -61,8 +62,9 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* if (const JSStaticValue* staticValue = definition->staticValues) { m_staticValues = new OpaqueJSClassStaticValuesTable(); while (staticValue->name) { - m_staticValues->add(UString::Rep::createFromUTF8(staticValue->name), - new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes)); + // Use a local variable here to sidestep an RVCT compiler bug. + StaticValueEntry* entry = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes); + m_staticValues->add(UString::createFromUTF8(staticValue->name).rep()->ref(), entry); ++staticValue; } } @@ -70,8 +72,9 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* if (const JSStaticFunction* staticFunction = definition->staticFunctions) { m_staticFunctions = new OpaqueJSClassStaticFunctionsTable(); while (staticFunction->name) { - m_staticFunctions->add(UString::Rep::createFromUTF8(staticFunction->name), - new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes)); + // Use a local variable here to sidestep an RVCT compiler bug. + StaticFunctionEntry* entry = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes); + m_staticFunctions->add(UString::createFromUTF8(staticFunction->name).rep()->ref(), entry); ++staticFunction; } } @@ -82,12 +85,12 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* OpaqueJSClass::~OpaqueJSClass() { - ASSERT(!m_className.rep()->identifierTable()); + ASSERT(!m_className.rep()->isIdentifier()); if (m_staticValues) { OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end(); for (OpaqueJSClassStaticValuesTable::const_iterator it = m_staticValues->begin(); it != end; ++it) { - ASSERT(!it->first->identifierTable()); + ASSERT(!it->first->isIdentifier()); delete it->second; } delete m_staticValues; @@ -96,7 +99,7 @@ OpaqueJSClass::~OpaqueJSClass() if (m_staticFunctions) { OpaqueJSClassStaticFunctionsTable::const_iterator end = m_staticFunctions->end(); for (OpaqueJSClassStaticFunctionsTable::const_iterator it = m_staticFunctions->begin(); it != end; ++it) { - ASSERT(!it->first->identifierTable()); + ASSERT(!it->first->isIdentifier()); delete it->second; } delete m_staticFunctions; @@ -118,39 +121,32 @@ static void clearReferenceToPrototype(JSObjectRef prototype) jsClassData->cachedPrototype = 0; } -PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* definition) +PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientDefinition) { - if (const JSStaticFunction* staticFunctions = definition->staticFunctions) { - // copy functions into a prototype class - JSClassDefinition protoDefinition = kJSClassDefinitionEmpty; - protoDefinition.staticFunctions = staticFunctions; - protoDefinition.finalize = clearReferenceToPrototype; - - // We are supposed to use JSClassRetain/Release but since we know that we currently have - // the only reference to this class object we cheat and use a RefPtr instead. - RefPtr<OpaqueJSClass> protoClass = adoptRef(new OpaqueJSClass(&protoDefinition, 0)); - - // remove functions from the original class - JSClassDefinition objectDefinition = *definition; - objectDefinition.staticFunctions = 0; - - return adoptRef(new OpaqueJSClass(&objectDefinition, protoClass.get())); - } + JSClassDefinition definition = *clientDefinition; // Avoid modifying client copy. - return adoptRef(new OpaqueJSClass(definition, 0)); + JSClassDefinition protoDefinition = kJSClassDefinitionEmpty; + protoDefinition.finalize = clearReferenceToPrototype; + swap(definition.staticFunctions, protoDefinition.staticFunctions); // Move static functions to the prototype. + + // We are supposed to use JSClassRetain/Release but since we know that we currently have + // the only reference to this class object we cheat and use a RefPtr instead. + RefPtr<OpaqueJSClass> protoClass = adoptRef(new OpaqueJSClass(&protoDefinition, 0)); + return adoptRef(new OpaqueJSClass(&definition, protoClass.get())); } OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) : m_class(jsClass) - , cachedPrototype(0) { if (jsClass->m_staticValues) { staticValues = new OpaqueJSClassStaticValuesTable; OpaqueJSClassStaticValuesTable::const_iterator end = jsClass->m_staticValues->end(); for (OpaqueJSClassStaticValuesTable::const_iterator it = jsClass->m_staticValues->begin(); it != end; ++it) { - ASSERT(!it->first->identifierTable()); - staticValues->add(UString::Rep::createCopying(it->first->data(), it->first->size()), - new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes)); + ASSERT(!it->first->isIdentifier()); + // Use a local variable here to sidestep an RVCT compiler bug. + StaticValueEntry* entry = new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes); + staticValues->add(UString::Rep::create(it->first->data(), it->first->size()), entry); + } } else @@ -161,9 +157,10 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass) staticFunctions = new OpaqueJSClassStaticFunctionsTable; OpaqueJSClassStaticFunctionsTable::const_iterator end = jsClass->m_staticFunctions->end(); for (OpaqueJSClassStaticFunctionsTable::const_iterator it = jsClass->m_staticFunctions->begin(); it != end; ++it) { - ASSERT(!it->first->identifierTable()); - staticFunctions->add(UString::Rep::createCopying(it->first->data(), it->first->size()), - new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes)); + ASSERT(!it->first->isIdentifier()); + // Use a local variable here to sidestep an RVCT compiler bug. + StaticFunctionEntry* entry = new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes); + staticFunctions->add(UString::Rep::create(it->first->data(), it->first->size()), entry); } } else @@ -240,5 +237,5 @@ JSObject* OpaqueJSClass::prototype(ExecState* exec) jsClassData.cachedPrototype->setPrototype(prototype); } } - return jsClassData.cachedPrototype; + return jsClassData.cachedPrototype.get(); } diff --git a/JavaScriptCore/API/JSClassRef.h b/JavaScriptCore/API/JSClassRef.h index c4777dd..ae60aad 100644 --- a/JavaScriptCore/API/JSClassRef.h +++ b/JavaScriptCore/API/JSClassRef.h @@ -31,6 +31,7 @@ #include <runtime/JSObject.h> #include <runtime/Protect.h> #include <runtime/UString.h> +#include <runtime/WeakGCPtr.h> #include <wtf/HashMap.h> #include <wtf/RefCounted.h> @@ -76,7 +77,7 @@ struct OpaqueJSClassContextData : Noncopyable { OpaqueJSClassStaticValuesTable* staticValues; OpaqueJSClassStaticFunctionsTable* staticFunctions; - JSC::JSObject* cachedPrototype; + JSC::WeakGCPtr<JSC::JSObject> cachedPrototype; }; struct OpaqueJSClass : public ThreadSafeShared<OpaqueJSClass> { diff --git a/JavaScriptCore/API/JSContextRef.cpp b/JavaScriptCore/API/JSContextRef.cpp index e6626b7..6bdc3c8 100644 --- a/JavaScriptCore/API/JSContextRef.cpp +++ b/JavaScriptCore/API/JSContextRef.cpp @@ -35,7 +35,7 @@ #include "JSObject.h" #include <wtf/Platform.h> -#if PLATFORM(DARWIN) +#if OS(DARWIN) #include <mach-o/dyld.h> static const int32_t webkitFirstVersionWithConcurrentGlobalContexts = 0x2100500; // 528.5.0 @@ -46,7 +46,7 @@ using namespace JSC; JSContextGroupRef JSContextGroupCreate() { initializeThreading(); - return toRef(JSGlobalData::create().releaseRef()); + return toRef(JSGlobalData::createNonDefault().releaseRef()); } JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) @@ -63,7 +63,7 @@ void JSContextGroupRelease(JSContextGroupRef group) JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) { initializeThreading(); -#if PLATFORM(DARWIN) +#if OS(DARWIN) // When running on Tiger or Leopard, or if the application was linked before JSGlobalContextCreate was changed // to use a unique JSGlobalData, we use a shared one for compatibility. #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) @@ -74,7 +74,7 @@ JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) JSLock lock(LockForReal); return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass); } -#endif // PLATFORM(DARWIN) +#endif // OS(DARWIN) return JSGlobalContextCreateInGroup(0, globalObjectClass); } @@ -84,8 +84,9 @@ 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::create(); + APIEntryShim entryShim(globalData.get(), false); #if ENABLE(JSC_MULTIPLE_THREADS) globalData->makeUsableFromMultipleThreads(); @@ -108,12 +109,9 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx) { ExecState* exec = toJS(ctx); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSGlobalData& globalData = exec->globalData(); - - globalData.heap.registerThread(); - gcProtect(exec->dynamicGlobalObject()); globalData.ref(); return ctx; @@ -122,18 +120,16 @@ JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx) void JSGlobalContextRelease(JSGlobalContextRef ctx) { ExecState* exec = toJS(ctx); - JSLock lock(exec); + APIEntryShim entryShim(exec, false); gcUnprotect(exec->dynamicGlobalObject()); JSGlobalData& globalData = exec->globalData(); 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. - ASSERT(!globalData.heap.protectedObjectCount()); - ASSERT(!globalData.heap.isBusy()); globalData.heap.destroy(); } else - globalData.heap.collect(); + globalData.heap.collectAllGarbage(); globalData.deref(); } @@ -141,8 +137,7 @@ void JSGlobalContextRelease(JSGlobalContextRef ctx) JSObjectRef JSContextGetGlobalObject(JSContextRef ctx) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); // It is necessary to call toThisObject to get the wrapper object when used with WebCore. return toRef(exec->lexicalGlobalObject()->toThisObject(exec)); @@ -157,8 +152,7 @@ JSContextGroupRef JSContextGetGroup(JSContextRef ctx) JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); return toGlobalRef(exec->lexicalGlobalObject()->globalExec()); } diff --git a/JavaScriptCore/API/JSObjectRef.cpp b/JavaScriptCore/API/JSObjectRef.cpp index 06ef578..faaa4eb 100644 --- a/JavaScriptCore/API/JSObjectRef.cpp +++ b/JavaScriptCore/API/JSObjectRef.cpp @@ -76,8 +76,7 @@ void JSClassRelease(JSClassRef jsClass) JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); if (!jsClass) return toRef(new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure())); // slightly more efficient @@ -92,8 +91,7 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data) JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous"); @@ -103,8 +101,7 @@ JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsPrototype = jsClass ? jsClass->prototype(exec) : 0; if (!jsPrototype) @@ -118,8 +115,7 @@ JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObje JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous"); @@ -141,8 +137,7 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* result; if (argumentCount) { @@ -167,8 +162,7 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); MarkedArgumentBuffer argList; for (size_t i = 0; i < argumentCount; ++i) @@ -188,8 +182,7 @@ JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSVal JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); MarkedArgumentBuffer argList; for (size_t i = 0; i < argumentCount; ++i) @@ -209,8 +202,7 @@ JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSVa JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); MarkedArgumentBuffer argList; for (size_t i = 0; i < argumentCount; ++i) @@ -230,8 +222,7 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); return toRef(exec, jsObject->prototype()); @@ -240,8 +231,7 @@ JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object) void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); JSValue jsValue = toJS(exec, value); @@ -252,8 +242,7 @@ void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); @@ -263,8 +252,7 @@ bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); @@ -280,8 +268,7 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); Identifier name(propertyName->identifier(&exec->globalData())); @@ -304,8 +291,7 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); @@ -322,8 +308,7 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsi void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned propertyIndex, JSValueRef value, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); JSValue jsValue = toJS(exec, value); @@ -339,8 +324,7 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); @@ -389,8 +373,7 @@ bool JSObjectIsFunction(JSContextRef, JSObjectRef object) JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); JSObject* jsThisObject = toJS(thisObject); @@ -427,8 +410,7 @@ bool JSObjectIsConstructor(JSContextRef, JSObjectRef object) JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSObject* jsObject = toJS(object); @@ -466,8 +448,7 @@ JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef o { JSObject* jsObject = toJS(object); ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSGlobalData* globalData = &exec->globalData(); @@ -492,7 +473,7 @@ JSPropertyNameArrayRef JSPropertyNameArrayRetain(JSPropertyNameArrayRef array) void JSPropertyNameArrayRelease(JSPropertyNameArrayRef array) { if (--array->refCount == 0) { - JSLock lock(array->globalData->isSharedInstance ? LockForReal : SilenceAssertionsOnly); + APIEntryShim entryShim(array->globalData, false); delete array; } } @@ -510,9 +491,6 @@ JSStringRef JSPropertyNameArrayGetNameAtIndex(JSPropertyNameArrayRef array, size void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStringRef propertyName) { PropertyNameArray* propertyNames = toJS(array); - - propertyNames->globalData()->heap.registerThread(); - JSLock lock(propertyNames->globalData()->isSharedInstance ? LockForReal : SilenceAssertionsOnly); - + APIEntryShim entryShim(propertyNames->globalData()); propertyNames->add(propertyName->identifier(propertyNames->globalData())); } diff --git a/JavaScriptCore/API/JSValueRef.cpp b/JavaScriptCore/API/JSValueRef.cpp index 31859d6..a12cc34 100644 --- a/JavaScriptCore/API/JSValueRef.cpp +++ b/JavaScriptCore/API/JSValueRef.cpp @@ -28,6 +28,7 @@ #include <wtf/Platform.h> #include "APICast.h" +#include "APIShims.h" #include "JSCallbackObject.h" #include <runtime/JSGlobalObject.h> @@ -41,13 +42,14 @@ #include <algorithm> // for std::min -JSType JSValueGetType(JSContextRef ctx, JSValueRef value) +using namespace JSC; + +::JSType JSValueGetType(JSContextRef ctx, JSValueRef value) { - JSC::ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSC::JSLock lock(exec); + ExecState* exec = toJS(ctx); + APIEntryShim entryShim(exec); - JSC::JSValue jsValue = toJS(exec, value); + JSValue jsValue = toJS(exec, value); if (jsValue.isUndefined()) return kJSTypeUndefined; @@ -63,13 +65,10 @@ JSType JSValueGetType(JSContextRef ctx, JSValueRef value) return kJSTypeObject; } -using namespace JSC; // placed here to avoid conflict between JSC::JSType and JSType, above. - bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); return jsValue.isUndefined(); @@ -78,8 +77,7 @@ bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value) bool JSValueIsNull(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); return jsValue.isNull(); @@ -88,8 +86,7 @@ bool JSValueIsNull(JSContextRef ctx, JSValueRef value) bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); return jsValue.isBoolean(); @@ -98,8 +95,7 @@ bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value) bool JSValueIsNumber(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); return jsValue.isNumber(); @@ -108,8 +104,7 @@ bool JSValueIsNumber(JSContextRef ctx, JSValueRef value) bool JSValueIsString(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); return jsValue.isString(); @@ -118,8 +113,7 @@ bool JSValueIsString(JSContextRef ctx, JSValueRef value) bool JSValueIsObject(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); return jsValue.isObject(); @@ -128,8 +122,7 @@ bool JSValueIsObject(JSContextRef ctx, JSValueRef value) bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); @@ -145,8 +138,7 @@ bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsCla bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsA = toJS(exec, a); JSValue jsB = toJS(exec, b); @@ -163,8 +155,7 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsA = toJS(exec, a); JSValue jsB = toJS(exec, b); @@ -175,8 +166,7 @@ bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b) bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); @@ -195,8 +185,7 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject JSValueRef JSValueMakeUndefined(JSContextRef ctx) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); return toRef(exec, jsUndefined()); } @@ -204,8 +193,7 @@ JSValueRef JSValueMakeUndefined(JSContextRef ctx) JSValueRef JSValueMakeNull(JSContextRef ctx) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); return toRef(exec, jsNull()); } @@ -213,8 +201,7 @@ JSValueRef JSValueMakeNull(JSContextRef ctx) JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); return toRef(exec, jsBoolean(value)); } @@ -222,8 +209,7 @@ JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value) JSValueRef JSValueMakeNumber(JSContextRef ctx, double value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); return toRef(exec, jsNumber(exec, value)); } @@ -231,8 +217,7 @@ JSValueRef JSValueMakeNumber(JSContextRef ctx, double value) JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); return toRef(exec, jsString(exec, string->ustring())); } @@ -240,8 +225,7 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string) bool JSValueToBoolean(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); return jsValue.toBoolean(exec); @@ -250,8 +234,7 @@ bool JSValueToBoolean(JSContextRef ctx, JSValueRef value) double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); @@ -268,8 +251,7 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); @@ -286,8 +268,7 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJS(exec, value); @@ -304,8 +285,7 @@ JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exce void JSValueProtect(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJSForGC(exec, value); gcProtect(jsValue); @@ -314,8 +294,7 @@ void JSValueProtect(JSContextRef ctx, JSValueRef value) void JSValueUnprotect(JSContextRef ctx, JSValueRef value) { ExecState* exec = toJS(ctx); - exec->globalData().heap.registerThread(); - JSLock lock(exec); + APIEntryShim entryShim(exec); JSValue jsValue = toJSForGC(exec, value); gcUnprotect(jsValue); diff --git a/JavaScriptCore/API/OpaqueJSString.cpp b/JavaScriptCore/API/OpaqueJSString.cpp index 7c7b1af..f740abe 100644 --- a/JavaScriptCore/API/OpaqueJSString.cpp +++ b/JavaScriptCore/API/OpaqueJSString.cpp @@ -42,7 +42,7 @@ PassRefPtr<OpaqueJSString> OpaqueJSString::create(const UString& ustring) UString OpaqueJSString::ustring() const { if (this && m_characters) - return UString(m_characters, m_length, true); + return UString(m_characters, m_length); return UString::null(); } diff --git a/JavaScriptCore/API/tests/testapi.c b/JavaScriptCore/API/tests/testapi.c index e7aba0f..ebc0cfb 100644 --- a/JavaScriptCore/API/tests/testapi.c +++ b/JavaScriptCore/API/tests/testapi.c @@ -623,6 +623,17 @@ static JSClassRef Derived_class(JSContextRef context) return jsClass; } +static JSClassRef Derived2_class(JSContextRef context) +{ + static JSClassRef jsClass; + if (!jsClass) { + JSClassDefinition definition = kJSClassDefinitionEmpty; + definition.parentClass = Derived_class(context); + jsClass = JSClassCreate(&definition); + } + return jsClass; +} + static JSValueRef print_callAsFunction(JSContextRef ctx, JSObjectRef functionObject, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { UNUSED_PARAM(functionObject); @@ -1070,11 +1081,21 @@ int main(int argc, char* argv[]) ASSERT(!JSObjectSetPrivate(myConstructor, (void*)1)); ASSERT(!JSObjectGetPrivate(myConstructor)); + string = JSStringCreateWithUTF8CString("Base"); + JSObjectRef baseConstructor = JSObjectMakeConstructor(context, Base_class(context), NULL); + JSObjectSetProperty(context, globalObject, string, baseConstructor, kJSPropertyAttributeNone, NULL); + JSStringRelease(string); + string = JSStringCreateWithUTF8CString("Derived"); JSObjectRef derivedConstructor = JSObjectMakeConstructor(context, Derived_class(context), NULL); JSObjectSetProperty(context, globalObject, string, derivedConstructor, kJSPropertyAttributeNone, NULL); JSStringRelease(string); + string = JSStringCreateWithUTF8CString("Derived2"); + JSObjectRef derived2Constructor = JSObjectMakeConstructor(context, Derived2_class(context), NULL); + JSObjectSetProperty(context, globalObject, string, derived2Constructor, kJSPropertyAttributeNone, NULL); + JSStringRelease(string); + o = JSObjectMake(context, NULL, NULL); JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL); JSObjectSetProperty(context, o, jsCFIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeDontEnum, NULL); @@ -1173,7 +1194,7 @@ int main(int argc, char* argv[]) } else { script = JSStringCreateWithUTF8CString(scriptUTF8); result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception); - if (JSValueIsUndefined(context, result)) + if (result && JSValueIsUndefined(context, result)) printf("PASS: Test script executed successfully.\n"); else { printf("FAIL: Test script returned unexpected value:\n"); diff --git a/JavaScriptCore/API/tests/testapi.js b/JavaScriptCore/API/tests/testapi.js index 82756b5..15c9e50 100644 --- a/JavaScriptCore/API/tests/testapi.js +++ b/JavaScriptCore/API/tests/testapi.js @@ -113,6 +113,35 @@ if (foundRegularType) else fail("MyObject.regularType was not enumerated"); +var alwaysOneDescriptor = Object.getOwnPropertyDescriptor(MyObject, "alwaysOne"); +shouldBe('typeof alwaysOneDescriptor', "object"); +shouldBe('alwaysOneDescriptor.value', MyObject.alwaysOne); +shouldBe('alwaysOneDescriptor.configurable', true); +shouldBe('alwaysOneDescriptor.enumerable', false); // Actually it is. +var cantFindDescriptor = Object.getOwnPropertyDescriptor(MyObject, "cantFind"); +shouldBe('typeof cantFindDescriptor', "object"); +shouldBe('cantFindDescriptor.value', MyObject.cantFind); +shouldBe('cantFindDescriptor.configurable', true); +shouldBe('cantFindDescriptor.enumerable', false); +try { + // If getOwnPropertyDescriptor() returned an access descriptor, this wouldn't throw. + Object.getOwnPropertyDescriptor(MyObject, "throwOnGet"); +} catch (e) { + pass("getting property descriptor of throwOnGet threw exception"); +} +var myPropertyNameDescriptor = Object.getOwnPropertyDescriptor(MyObject, "myPropertyName"); +shouldBe('typeof myPropertyNameDescriptor', "object"); +shouldBe('myPropertyNameDescriptor.value', MyObject.myPropertyName); +shouldBe('myPropertyNameDescriptor.configurable', true); +shouldBe('myPropertyNameDescriptor.enumerable', false); // Actually it is. +try { + // if getOwnPropertyDescriptor() returned an access descriptor, this wouldn't throw. + Object.getOwnPropertyDescriptor(MyObject, "hasPropertyLie"); +} catch (e) { + pass("getting property descriptor of hasPropertyLie threw exception"); +} +shouldBe('Object.getOwnPropertyDescriptor(MyObject, "doesNotExist")', undefined); + myObject = new MyObject(); shouldBe("delete MyObject.regularType", true); @@ -140,6 +169,9 @@ shouldThrow("MyObject.hasPropertyLie"); derived = new Derived(); +shouldBe("derived instanceof Derived", true); +shouldBe("derived instanceof Base", true); + // base properties and functions return 1 when called/gotten; derived, 2 shouldBe("derived.baseProtoDup()", 2); shouldBe("derived.baseProto()", 1); @@ -155,6 +187,51 @@ shouldBe("derived.baseOnly = 0", 1); shouldBe("derived.derivedOnly = 0", 2) shouldBe("derived.protoDup = 0", 2); +derived2 = new Derived2(); + +shouldBe("derived2 instanceof Derived2", true); +shouldBe("derived2 instanceof Derived", true); +shouldBe("derived2 instanceof Base", true); + +// base properties and functions return 1 when called/gotten; derived, 2 +shouldBe("derived2.baseProtoDup()", 2); +shouldBe("derived2.baseProto()", 1); +shouldBe("derived2.baseDup", 2); +shouldBe("derived2.baseOnly", 1); +shouldBe("derived2.protoOnly()", 2); +shouldBe("derived2.protoDup", 2); +shouldBe("derived2.derivedOnly", 2) + +// base properties throw 1 when set; derived, 2 +shouldBe("derived2.baseDup = 0", 2); +shouldBe("derived2.baseOnly = 0", 1); +shouldBe("derived2.derivedOnly = 0", 2) +shouldBe("derived2.protoDup = 0", 2); + +shouldBe('Object.getOwnPropertyDescriptor(derived, "baseProto")', undefined); +shouldBe('Object.getOwnPropertyDescriptor(derived, "baseProtoDup")', undefined); +var baseDupDescriptor = Object.getOwnPropertyDescriptor(derived, "baseDup"); +shouldBe('typeof baseDupDescriptor', "object"); +shouldBe('baseDupDescriptor.value', derived.baseDup); +shouldBe('baseDupDescriptor.configurable', true); +shouldBe('baseDupDescriptor.enumerable', false); +var baseOnlyDescriptor = Object.getOwnPropertyDescriptor(derived, "baseOnly"); +shouldBe('typeof baseOnlyDescriptor', "object"); +shouldBe('baseOnlyDescriptor.value', derived.baseOnly); +shouldBe('baseOnlyDescriptor.configurable', true); +shouldBe('baseOnlyDescriptor.enumerable', false); +shouldBe('Object.getOwnPropertyDescriptor(derived, "protoOnly")', undefined); +var protoDupDescriptor = Object.getOwnPropertyDescriptor(derived, "protoDup"); +shouldBe('typeof protoDupDescriptor', "object"); +shouldBe('protoDupDescriptor.value', derived.protoDup); +shouldBe('protoDupDescriptor.configurable', true); +shouldBe('protoDupDescriptor.enumerable', false); +var derivedOnlyDescriptor = Object.getOwnPropertyDescriptor(derived, "derivedOnly"); +shouldBe('typeof derivedOnlyDescriptor', "object"); +shouldBe('derivedOnlyDescriptor.value', derived.derivedOnly); +shouldBe('derivedOnlyDescriptor.configurable', true); +shouldBe('derivedOnlyDescriptor.enumerable', false); + shouldBe("undefined instanceof MyObject", false); EvilExceptionObject.hasInstance = function f() { return f(); }; EvilExceptionObject.__proto__ = undefined; diff --git a/JavaScriptCore/Android.mk b/JavaScriptCore/Android.mk index 425d69c..e76da32 100644 --- a/JavaScriptCore/Android.mk +++ b/JavaScriptCore/Android.mk @@ -56,12 +56,10 @@ LOCAL_SRC_FILES := \ pcre/pcre_ucp_searchfuncs.cpp \ pcre/pcre_xclass.cpp \ \ - profiler/HeavyProfile.cpp \ profiler/Profile.cpp \ profiler/ProfileGenerator.cpp \ profiler/ProfileNode.cpp \ profiler/Profiler.cpp \ - profiler/TreeProfile.cpp \ \ runtime/ArgList.cpp \ runtime/Arguments.cpp \ @@ -161,6 +159,7 @@ LOCAL_SRC_FILES := \ wtf/RandomNumber.cpp \ wtf/RefCountedLeakCounter.cpp \ wtf/TCSystemAlloc.cpp \ + wtf/ThreadIdentifierDataPthreads.cpp \ wtf/Threading.cpp \ wtf/ThreadingPthreads.cpp \ \ diff --git a/JavaScriptCore/Android.v8.wtf.mk b/JavaScriptCore/Android.v8.wtf.mk index 53a50d9..69128d6 100644 --- a/JavaScriptCore/Android.v8.wtf.mk +++ b/JavaScriptCore/Android.v8.wtf.mk @@ -42,6 +42,7 @@ LOCAL_SRC_FILES := \ wtf/RandomNumber.cpp \ wtf/RefCountedLeakCounter.cpp \ wtf/TCSystemAlloc.cpp \ + wtf/ThreadIdentifierDataPthreads.cpp \ wtf/Threading.cpp \ wtf/ThreadingPthreads.cpp \ \ diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog index 829cc98..01ba8ea 100644 --- a/JavaScriptCore/ChangeLog +++ b/JavaScriptCore/ChangeLog @@ -1,3 +1,3746 @@ +<<<<<<< HEAD +======= +2010-01-31 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Darin Adler. + + Buildfix for WinCE + style fixes (TLS_OUT_OF_INDEXES is not defined). + https://bugs.webkit.org/show_bug.cgi?id=34380 + + * wtf/ThreadSpecific.h: + +2010-01-31 Kent Tamura <tkent@chromium.org> + + Reviewed by Darin Adler. + + [Windows] Fix a bug of round() with huge integral numbers + https://bugs.webkit.org/show_bug.cgi?id=34297 + + Fix a bug that round() for huge integral numbers returns incorrect + results. For example, round(8639999913600001) returns + 8639999913600002 without this change though the double type can + represent 8639999913600001 precisely. + + Math.round() of JavaScript has a similar problem. But this change + doesn't fix it because Math.round() doesn't use round() of + MathExtra.h. + + * wtf/MathExtras.h: + (round): Avoid to do "num + 0.5" or "num - 0.5". + (roundf): Fixed similarly. + (llround): Calls round(). + (llroundf): Calls roundf(). + (lround): Calls round(). + (lroundf): Calls roundf(). + +2010-01-29 Mark Rowe <mrowe@apple.com> + + Sort Xcode projects. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2010-01-29 Mark Rowe <mrowe@apple.com> + + Fix the Mac build. + + Disable ENABLE_INDEXED_DATABASE since it is "completely non-functional". + + As the comment in FeatureDefines.xcconfig notes, the list of feature defines + needs to be kept in sync across the various files. The default values also + need to be kept in sync between these files and build-webkit. + + * Configurations/FeatureDefines.xcconfig: + +2010-01-29 Simon Hausmann <simon.hausmann@nokia.com> + + Rubber-stamped by Maciej Stachowiak. + + Fix the ARM build. + + * runtime/JSNumberCell.h: + (JSC::JSNumberCell::createStructure): Call the right Structure::create overload. + +2010-01-28 Kevin Ollivier <kevino@theolliviers.com> + + [wx] Build fix for MSW, use ThreadingWin.cpp as the Windows pthreads implementation + implements pthread_t in a way that makes it impossible to check its validity, + which is needed by ThreadingPthreads.cpp. + + * wscript: + +2010-01-28 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + DOM Objects shouldn't all require custom mark functions + https://bugs.webkit.org/show_bug.cgi?id=34291 + + Make getAnonymousValue const-friendly + + * runtime/JSObject.h: + (JSC::JSObject::getAnonymousValue): + +2010-01-28 Oliver Hunt <oliver@apple.com> + + Reviewed by Gavin Barraclough. + + Simplify anonymous slot implementation + https://bugs.webkit.org/show_bug.cgi?id=34282 + + A class must now specify the number of slots it needs at construction time + rather than later on with a transition. This makes many things simpler, + we no longer need to need an additional transition on object creation to + add the anonymous slots, and we remove the need for a number of transition + type checks. + + * API/JSCallbackConstructor.h: + (JSC::JSCallbackConstructor::createStructure): + * API/JSCallbackFunction.h: + (JSC::JSCallbackFunction::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::createStructure): + * JavaScriptCore.exp: + * debugger/DebuggerActivation.h: + (JSC::DebuggerActivation::createStructure): + * runtime/Arguments.h: + (JSC::Arguments::createStructure): + * runtime/BooleanObject.h: + (JSC::BooleanObject::createStructure): + * runtime/DateInstance.h: + (JSC::DateInstance::createStructure): + * runtime/DatePrototype.h: + (JSC::DatePrototype::createStructure): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::createStructure): + * runtime/GetterSetter.h: + (JSC::GetterSetter::createStructure): + * runtime/GlobalEvalFunction.h: + (JSC::GlobalEvalFunction::createStructure): + * runtime/InternalFunction.h: + (JSC::InternalFunction::createStructure): + * runtime/JSAPIValueWrapper.h: + (JSC::JSAPIValueWrapper::createStructure): + * runtime/JSActivation.h: + (JSC::JSActivation::createStructure): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::createStructure): + * runtime/JSCell.h: + (JSC::JSCell::createDummyStructure): + * runtime/JSFunction.h: + (JSC::JSFunction::createStructure): + * runtime/JSGlobalObject.h: + (JSC::JSGlobalObject::createStructure): + * runtime/JSNotAnObject.h: + (JSC::JSNotAnObject::createStructure): + * runtime/JSONObject.h: + (JSC::JSONObject::createStructure): + * runtime/JSObject.h: + (JSC::JSObject::createStructure): + (JSC::JSObject::putAnonymousValue): + (JSC::JSObject::getAnonymousValue): + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::createStructure): + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::createStructure): + * runtime/JSString.h: + (JSC::Fiber::createStructure): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::createStructure): + * runtime/JSWrapperObject.h: + (JSC::JSWrapperObject::createStructure): + (JSC::JSWrapperObject::JSWrapperObject): + * runtime/MathObject.h: + (JSC::MathObject::createStructure): + * runtime/NumberConstructor.h: + (JSC::NumberConstructor::createStructure): + * runtime/NumberObject.h: + (JSC::NumberObject::createStructure): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::createStructure): + * runtime/RegExpObject.h: + (JSC::RegExpObject::createStructure): + * runtime/StringObject.h: + (JSC::StringObject::createStructure): + * runtime/StringObjectThatMasqueradesAsUndefined.h: + (JSC::StringObjectThatMasqueradesAsUndefined::createStructure): + * runtime/Structure.cpp: + (JSC::Structure::~Structure): + (JSC::Structure::materializePropertyMap): + * runtime/Structure.h: + (JSC::Structure::create): + (JSC::Structure::anonymousSlotCount): + * runtime/StructureTransitionTable.h: + +2010-01-27 Oliver Hunt <oliver@apple.com> + + Windows build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2010-01-27 Oliver Hunt <oliver@apple.com> + + Reviewed by Maciej Stachowiak. + + MessageEvent.data should deserialize in the context of the MessageEvent's global object + https://bugs.webkit.org/show_bug.cgi?id=34227 + + Add logic to allow us to create an Object, Array, or Date instance + so we can create them in the context of a specific global object, + rather than just using the current lexical global object. + + * JavaScriptCore.exp: + * runtime/DateInstance.cpp: + (JSC::DateInstance::DateInstance): + * runtime/DateInstance.h: + * runtime/JSGlobalObject.h: + (JSC::constructEmptyObject): + (JSC::constructEmptyArray): + +2010-01-27 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=34150 + WebKit needs a mechanism to catch stale HashMap entries + + It is very difficult to catch stale pointers that are HashMap keys - since a pointer's hash + is just its value, it is very unlikely that any observable problem is reproducible. + + This extends hash table consistency checks to check that pointers are referencing allocated + memory blocks, and makes it possible to invoke the checks explicitly (it is not feasible + to enable CHECK_HASHTABLE_CONSISTENCY by default, because that affects performance too much). + + * wtf/HashMap.h: (WTF::::checkConsistency): Call through to HashTable implementation. We can + add similar calls to HashSet and HashCountedSet, but I haven't seen hard to debug problems + with those yet. + + * wtf/HashSet.h: (WTF::::remove): The version of checkTableConsistency that's guarded by + CHECK_HASHTABLE_CONSISTENCY is now called internalCheckTableConsistency(). + + * wtf/HashTable.h: + (WTF::HashTable::internalCheckTableConsistency): + (WTF::HashTable::internalCheckTableConsistencyExceptSize): + (WTF::HashTable::checkTableConsistencyExceptSize): + Expose checkTableConsistency() even if CHECK_HASHTABLE_CONSISTENCY is off. + (WTF::::add): Updated for checkTableConsistency renaming. + (WTF::::addPassingHashCode): Ditto. + (WTF::::removeAndInvalidate): Ditto. + (WTF::::remove): Ditto. + (WTF::::rehash): Ditto. + (WTF::::checkTableConsistency): The assertion for !shouldExpand() was not correct - this + function returns true for tables with m_table == 0. + (WTF::::checkTableConsistencyExceptSize): Call checkValueConsistency for key. Potentially, + we could do the same for values. + + * wtf/HashTraits.h: + (WTF::GenericHashTraits::checkValueConsistency): An empty function that can be overridden + to add checks. Currently, the only override is for pointer hashes. + + * wtf/RefPtrHashMap.h: (WTF::::remove): Updated for checkTableConsistency renaming. + +2010-01-27 Anton Muhin <antonm@chromium.org> + + Reviewed by Darin Adler. + + Remove trailing \ from inline function code + https://bugs.webkit.org/show_bug.cgi?id=34223 + + * assembler/ARMv7Assembler.h: + (JSC::ARMThumbImmediate::countLeadingZerosPartial): + +2010-01-27 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Eric Seidel. + + [BREWMP] Port WTF's randomNumber + https://bugs.webkit.org/show_bug.cgi?id=33566 + + Use GETRAND to generate 4 byte random byte sequence to implement + weakRandomNumber. Create a secure random number generator with + AEECLSID_RANDOM to implement randomNumber. + + * wtf/RandomNumber.cpp: + (WTF::weakRandomNumber): + (WTF::randomNumber): + +2010-01-27 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Eric Seidel. + + [BREWMP] Port getCPUTime + https://bugs.webkit.org/show_bug.cgi?id=33572 + + Use GETUPTIMEMS which returns a continuously and + linearly increasing millisecond timer from the time the device + was powered on. This function is enough to implement getCPUTime. + + * runtime/TimeoutChecker.cpp: + (JSC::getCPUTime): + +2010-01-27 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Oliver Hunt. + + [BREWMP] Add MarkStack fastMalloc implementation for platforms without VirtualAlloc or mmap. + https://bugs.webkit.org/show_bug.cgi?id=33582 + + Use fastMalloc and fastFree to implement MarkStack::allocateStack and + MarkStack::releaseStack for platforms without page level allocation. + + * runtime/MarkStack.h: + (JSC::MarkStack::MarkStackArray::shrinkAllocation): + * runtime/MarkStackNone.cpp: Added. + (JSC::MarkStack::initializePagesize): + (JSC::MarkStack::allocateStack): + (JSC::MarkStack::releaseStack): + +2010-01-27 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Eric Seidel. + + [BREWMP] Don't use time function + https://bugs.webkit.org/show_bug.cgi?id=33577 + + Calling time(0) in BREW devices causes a crash because time + is not properly ported in most devices. Cast currentTime() to + time_t to get the same result as time(0). + + * wtf/DateMath.cpp: + (WTF::calculateUTCOffset): + +2010-01-27 Alexey Proskuryakov <ap@apple.com> + + Revert r53899 (HashMap<AtomicStringImpl*, Value> key checks) and subsequent build fixes, + because they make SVG tests crash in release builds. + + * wtf/HashMap.h: + (WTF::::remove): + * wtf/HashSet.h: + (WTF::::remove): + * wtf/HashTable.h: + (WTF::::add): + (WTF::::addPassingHashCode): + (WTF::::removeAndInvalidate): + (WTF::::remove): + (WTF::::rehash): + (WTF::::checkTableConsistency): + (WTF::::checkTableConsistencyExceptSize): + * wtf/HashTraits.h: + (WTF::GenericHashTraits::emptyValue): + (WTF::): + * wtf/RefPtrHashMap.h: + (WTF::::remove): + +2010-01-26 Alexey Proskuryakov <ap@apple.com> + + More Windows build fixing. + + * wtf/HashTraits.h: _msize takes void*, remove const qualifier from type. + +2010-01-26 Alexey Proskuryakov <ap@apple.com> + + Windows build fix. + + * wtf/HashTraits.h: Include malloc.h for _msize(). + +2010-01-26 Alexey Proskuryakov <ap@apple.com> + + Build fix. + + * wtf/HashTable.h: (WTF::HashTable::checkTableConsistencyExceptSize): Remove const from a + static (empty) version of this function. + +2010-01-26 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=34150 + WebKit needs a mechanism to catch stale HashMap entries + + It is very difficult to catch stale pointers that are HashMap keys - since a pointer's hash + is just its value, it is very unlikely that any observable problem is reproducible. + + This extends hash table consistency checks to check that pointers are referencing allocated + memory blocks, and makes it possible to invoke the checks explicitly (it is not feasible + to enable CHECK_HASHTABLE_CONSISTENCY by default, because that affects performance too much). + + * wtf/HashMap.h: (WTF::::checkConsistency): Call through to HashTable implementation. We can + add similar calls to HashSet and HashCountedSet, but I haven't seen hard to debug problems + with those yet. + + * wtf/HashSet.h: (WTF::::remove): The version of checkTableConsistency that's guarded by + CHECK_HASHTABLE_CONSISTENCY is now called internalCheckTableConsistency(). + + * wtf/HashTable.h: + (WTF::HashTable::internalCheckTableConsistency): + (WTF::HashTable::internalCheckTableConsistencyExceptSize): + (WTF::HashTable::checkTableConsistencyExceptSize): + Expose checkTableConsistency() even if CHECK_HASHTABLE_CONSISTENCY is off. + (WTF::::add): Updated for checkTableConsistency renaming. + (WTF::::addPassingHashCode): Ditto. + (WTF::::removeAndInvalidate): Ditto. + (WTF::::remove): Ditto. + (WTF::::rehash): Ditto. + (WTF::::checkTableConsistency): The assertion for !shouldExpand() was not correct - this + function returns true for tables with m_table == 0. + (WTF::::checkTableConsistencyExceptSize): Call checkValueConsistency for key. Potentially, + we could do the same for values. + + * wtf/HashTraits.h: + (WTF::GenericHashTraits::checkValueConsistency): An empty function that can be overridden + to add checks. Currently, the only override is for pointer hashes. + + * wtf/RefPtrHashMap.h: (WTF::::remove): Updated for checkTableConsistency renaming. + +2010-01-26 Lyon Chen <liachen@rim.com> + + Reviewed by Maciej Stachowiak. + + Opcode.h use const void* for Opcode cause error #1211 for RVCT compiler + https://bugs.webkit.org/show_bug.cgi?id=33902 + + * bytecode/Opcode.h: + +2010-01-26 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Oliver Hunt. + + Windows build references non-existent include paths + https://bugs.webkit.org/show_bug.cgi?id=34175 + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops: + * JavaScriptCore.vcproj/WTF/WTFCommon.vsprops: + * JavaScriptCore.vcproj/jsc/jscCommon.vsprops: + * JavaScriptCore.vcproj/testapi/testapi.vcproj: + * JavaScriptCore.vcproj/testapi/testapiCommon.vsprops: + +2010-01-26 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoffrey Garen. + + Using JavaScriptCore API with a webkit vended context can result in slow script dialog + https://bugs.webkit.org/show_bug.cgi?id=34172 + + Make the APIShim correctly increment and decrement the timeout + entry counter. + + * API/APIShims.h: + (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): + (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock): + (JSC::APICallbackShim::APICallbackShim): + (JSC::APICallbackShim::~APICallbackShim): + +2010-01-26 Simon Hausmann <simon.hausmann@nokia.com> + + [Qt] Fix compilation of QtScript with non-gcc compilers + + Variable length stack arrays are a gcc extension. Use QVarLengthArray + as a more portable solution that still tries to allocate on the stack + first. + + * qt/api/qscriptvalue_p.h: + (QScriptValuePrivate::call): + +2010-01-26 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Fix the build on platforms without JIT support. + + The JIT support should be determined at compile-time via wtf/Platform.h + + * qt/api/QtScript.pro: + +2010-01-26 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> + + Reviewed by Simon Hausmann. + + First steps of the QtScript API. + + Two new classes were created; QScriptEngine and QScriptValue. + The first should encapsulate a javascript context and the second a script + value. + + This API is still in development, so it isn't compiled by default. + To trigger compilation, pass --qmakearg="CONFIG+=build-qtscript" to + build-webkit. + + https://bugs.webkit.org/show_bug.cgi?id=32565 + + * qt/api/QtScript.pro: Added. + * qt/api/qscriptconverter_p.h: Added. + (QScriptConverter::toString): + * qt/api/qscriptengine.cpp: Added. + (QScriptEngine::QScriptEngine): + (QScriptEngine::~QScriptEngine): + (QScriptEngine::evaluate): + (QScriptEngine::collectGarbage): + * qt/api/qscriptengine.h: Added. + * qt/api/qscriptengine_p.cpp: Added. + (QScriptEnginePrivate::QScriptEnginePrivate): + (QScriptEnginePrivate::~QScriptEnginePrivate): + (QScriptEnginePrivate::evaluate): + * qt/api/qscriptengine_p.h: Added. + (QScriptEnginePrivate::get): + (QScriptEnginePrivate::collectGarbage): + (QScriptEnginePrivate::makeJSValue): + (QScriptEnginePrivate::context): + * qt/api/qscriptvalue.cpp: Added. + (QScriptValue::QScriptValue): + (QScriptValue::~QScriptValue): + (QScriptValue::isValid): + (QScriptValue::isBool): + (QScriptValue::isBoolean): + (QScriptValue::isNumber): + (QScriptValue::isNull): + (QScriptValue::isString): + (QScriptValue::isUndefined): + (QScriptValue::isError): + (QScriptValue::isObject): + (QScriptValue::isFunction): + (QScriptValue::toString): + (QScriptValue::toNumber): + (QScriptValue::toBool): + (QScriptValue::toBoolean): + (QScriptValue::toInteger): + (QScriptValue::toInt32): + (QScriptValue::toUInt32): + (QScriptValue::toUInt16): + (QScriptValue::call): + (QScriptValue::engine): + (QScriptValue::operator=): + (QScriptValue::equals): + (QScriptValue::strictlyEquals): + * qt/api/qscriptvalue.h: Added. + (QScriptValue::): + * qt/api/qscriptvalue_p.h: Added. + (QScriptValuePrivate::): + (QScriptValuePrivate::get): + (QScriptValuePrivate::QScriptValuePrivate): + (QScriptValuePrivate::isValid): + (QScriptValuePrivate::isBool): + (QScriptValuePrivate::isNumber): + (QScriptValuePrivate::isNull): + (QScriptValuePrivate::isString): + (QScriptValuePrivate::isUndefined): + (QScriptValuePrivate::isError): + (QScriptValuePrivate::isObject): + (QScriptValuePrivate::isFunction): + (QScriptValuePrivate::toString): + (QScriptValuePrivate::toNumber): + (QScriptValuePrivate::toBool): + (QScriptValuePrivate::toInteger): + (QScriptValuePrivate::toInt32): + (QScriptValuePrivate::toUInt32): + (QScriptValuePrivate::toUInt16): + (QScriptValuePrivate::equals): + (QScriptValuePrivate::strictlyEquals): + (QScriptValuePrivate::assignEngine): + (QScriptValuePrivate::call): + (QScriptValuePrivate::engine): + (QScriptValuePrivate::context): + (QScriptValuePrivate::value): + (QScriptValuePrivate::object): + (QScriptValuePrivate::inherits): + (QScriptValuePrivate::isJSBased): + (QScriptValuePrivate::isNumberBased): + (QScriptValuePrivate::isStringBased): + * qt/api/qtscriptglobal.h: Added. + * qt/tests/qscriptengine/qscriptengine.pro: Added. + * qt/tests/qscriptengine/tst_qscriptengine.cpp: Added. + (tst_QScriptEngine::tst_QScriptEngine): + (tst_QScriptEngine::~tst_QScriptEngine): + (tst_QScriptEngine::init): + (tst_QScriptEngine::cleanup): + (tst_QScriptEngine::collectGarbage): + (tst_QScriptEngine::evaluate): + * qt/tests/qscriptvalue/qscriptvalue.pro: Added. + * qt/tests/qscriptvalue/tst_qscriptvalue.cpp: Added. + (tst_QScriptValue::tst_QScriptValue): + (tst_QScriptValue::~tst_QScriptValue): + (tst_QScriptValue::init): + (tst_QScriptValue::cleanup): + (tst_QScriptValue::ctor): + (tst_QScriptValue::toString_data): + (tst_QScriptValue::toString): + (tst_QScriptValue::copyConstructor_data): + (tst_QScriptValue::copyConstructor): + (tst_QScriptValue::assignOperator_data): + (tst_QScriptValue::assignOperator): + (tst_QScriptValue::dataSharing): + (tst_QScriptValue::constructors_data): + (tst_QScriptValue::constructors): + (tst_QScriptValue::call): + * qt/tests/tests.pri: Added. + * qt/tests/tests.pro: Added. + +2010-01-25 Dmitry Titov <dimich@chromium.org> + + Reviewed by David Levin. + + Fix Chromium Linux tests: the pthread functions on Linux produce segfault if they receive 0 thread handle. + After r53714, we can have 0 thread handles passed to pthread_join and pthread_detach if corresponding threads + were already terminated and their threadMap entries cleared. + Add a 0 check. + + * wtf/ThreadingPthreads.cpp: + (WTF::waitForThreadCompletion): + (WTF::detachThread): + +2010-01-24 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Maciej Stachowiak. + + Refactor JITStubs.cpp so that DEFINE_STUB_FUNCTION is only used once for each function + https://bugs.webkit.org/show_bug.cgi?id=33866 + + Place the guard USE(JSVALUE32_64) inside the body of the DEFINE_STUB_FUNCTION + macro for those functions that are always present. + + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + +2010-01-22 Kevin Watters <kevinwatters@gmail.com> + + Reviewed by Kevin Ollivier. + + [wx] Remove the Bakefile build system, which is no longer being used. + + https://bugs.webkit.org/show_bug.cgi?id=34022 + + * JavaScriptCoreSources.bkl: Removed. + * jscore.bkl: Removed. + +2010-01-22 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=34025 + Enable client-based Geolocation abstraction for Mac, Windows AppleWebKit targets. + + * Configurations/FeatureDefines.xcconfig: + +2010-01-22 Dmitry Titov <dimich@chromium.org> + + Not reviewed, attempted Snow Leopard build fix. + + * wtf/ThreadingPthreads.cpp: Add a forward declaration of a function which is not 'static'. + +2009-01-22 Dmitry Titov <dimich@chromium.org> + + Reviewed by Maciej Stachowiak. + + Fix the leak of ThreadIdentifiers in threadMap across threads. + https://bugs.webkit.org/show_bug.cgi?id=32689 + + Test is added to DumpRenderTree.mm. + + * Android.mk: Added file ThreadIdentifierDataPthreads.(h|cpp) to build. + * Android.v8.wtf.mk: Ditto. + * GNUmakefile.am: Ditto. + * JavaScriptCore.gyp/JavaScriptCore.gyp: Ditto. + * JavaScriptCore.gypi: Ditto. + * JavaScriptCore.xcodeproj/project.pbxproj: Ditto. + + * wtf/ThreadIdentifierDataPthreads.cpp: Added. Contains custom implementation of thread-specific data that uses custom destructor. + (WTF::ThreadIdentifierData::~ThreadIdentifierData): Removes the ThreadIdentifier from the threadMap. + (WTF::ThreadIdentifierData::identifier): + (WTF::ThreadIdentifierData::initialize): + (WTF::ThreadIdentifierData::destruct): Custom thread-specific destructor. Resets the value for the key again to cause second invoke. + (WTF::ThreadIdentifierData::initializeKeyOnceHelper): + (WTF::ThreadIdentifierData::initializeKeyOnce): Need to use pthread_once since initialization may come on any thread(s). + * wtf/ThreadIdentifierDataPthreads.h: Added. + (WTF::ThreadIdentifierData::ThreadIdentifierData): + + * wtf/Threading.cpp: + (WTF::threadEntryPoint): Move initializeCurrentThreadInternal to after the lock to make + sure it is invoked when ThreadIdentifier is already established. + + * wtf/Threading.h: Rename setThreadNameInternal -> initializeCurrentThreadInternal since it does more then only set the name now. + * wtf/ThreadingNone.cpp: + (WTF::initializeCurrentThreadInternal): Ditto. + * wtf/ThreadingWin.cpp: + (WTF::initializeCurrentThreadInternal): Ditto. + (WTF::initializeThreading): Ditto. + * wtf/gtk/ThreadingGtk.cpp: + (WTF::initializeCurrentThreadInternal): Ditto. + * wtf/qt/ThreadingQt.cpp: + (WTF::initializeCurrentThreadInternal): Ditto. + + * wtf/ThreadingPthreads.cpp: + (WTF::establishIdentifierForPthreadHandle): + (WTF::clearPthreadHandleForIdentifier): Make it not 'static' so the ~ThreadIdentifierData() in another file can call it. + (WTF::initializeCurrentThreadInternal): Set the thread-specific data. The ThreadIdentifier is already established by creating thread. + (WTF::waitForThreadCompletion): Remove call to clearPthreadHandleForIdentifier(threadID) since it is now done in ~ThreadIdentifierData(). + (WTF::detachThread): Ditto. + (WTF::currentThread): Use the thread-specific data to get the ThreadIdentifier. It's many times faster then Mutex-protected iteration through the map. + Also, set the thread-specific data if called first time on the thread. + +2010-01-21 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Alexey Proskuryakov. + + Add ThreadSpecific for ENABLE(SINGLE_THREADED) + https://bugs.webkit.org/show_bug.cgi?id=33878 + + Implement ThreadSpecific with a simple getter/setter + when ENABLE(SINGLE_THREADED) is true. + + Due to the change in https://bugs.webkit.org/show_bug.cgi?id=33236, + an implementation of ThreadSpecific must be available to build WebKit. + This causes a build failure for platforms without a proper + ThreadSpecific implementation. + + * wtf/ThreadSpecific.h: + (WTF::::ThreadSpecific): + (WTF::::~ThreadSpecific): + (WTF::::get): + (WTF::::set): + (WTF::::destroy): + +2010-01-21 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Maciej Stachowiak. + + Add fastStrDup to FastMalloc + https://bugs.webkit.org/show_bug.cgi?id=33937 + + The new string returned by fastStrDup is obtained with fastMalloc, + and can be freed with fastFree. This makes the memory management + more consistent because we don't need to keep strdup allocated pointers + and free them with free(). Instead we can use fastFree everywhere. + + * wtf/FastMalloc.cpp: + (WTF::fastStrDup): + * wtf/FastMalloc.h: + +2010-01-21 Brady Eidson <beidson@apple.com> + + Reviewed by Maciej Stachowiak. + + history.back() for same-document history traversals isn't synchronous as the specification states. + <rdar://problem/7535011> and https://bugs.webkit.org/show_bug.cgi?id=33538 + + * wtf/Platform.h: Add a "HISTORY_ALWAYS_ASYNC" enable and turn it on for Chromium. + +2010-01-21 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Always create a prototype for automatically managed classes. + + This fixes some errors where prototype chains were not correctly hooked + up, and also ensures that API classes work correctly with features like + instanceof. + + * API/JSClassRef.cpp: + (OpaqueJSClass::create): Cleaned up some of this code. Also changed it + to always create a prototype class. + + * API/tests/testapi.c: + (Derived2_class): + (main): Fixed a null value crash in the exception checking code. + * API/tests/testapi.js: Added some tests for the case where a prototype + chain would not be hooked up correctly. + +2010-01-21 Oliver Hunt <oliver@apple.com> + + Reviewed by Geoff Garen. + + Force JSC to create a prototype chain for API classes with a + parent class but no static functions. + + * API/JSClassRef.cpp: + (OpaqueJSClass::create): + +2010-01-21 Kent Hansen <kent.hansen@nokia.com> + + Reviewed by Geoffrey Garen. + + Object.getOwnPropertyDescriptor always returns undefined for JS API objects + https://bugs.webkit.org/show_bug.cgi?id=33946 + + Ideally the getOwnPropertyDescriptor() reimplementation should return an + access descriptor that wraps the property getter and setter callbacks, but + that approach is much more involved than returning a value descriptor. + Keep it simple for now. + + * API/JSCallbackObject.h: + * API/JSCallbackObjectFunctions.h: + (JSC::::getOwnPropertyDescriptor): + * API/tests/testapi.js: + +2010-01-20 Mark Rowe <mrowe@apple.com> + + Build fix. + + * wtf/FastMalloc.cpp: + (WTF::TCMalloc_PageHeap::initializeScavenger): Remove unnecessary function call. + +2010-01-20 Mark Rowe <mrowe@apple.com> + + Reviewed by Oliver Hunt. + + Use the inline i386 assembly for x86_64 as well rather than falling back to using pthread mutexes. + + * wtf/TCSpinLock.h: + (TCMalloc_SpinLock::Lock): + (TCMalloc_SpinLock::Unlock): + (TCMalloc_SlowLock): + +2010-01-20 Mark Rowe <mrowe@apple.com> + + Reviewed by Oliver Hunt. + + <rdar://problem/7215063> Use GCD instead of an extra thread for FastMalloc scavenging on platforms where it is supported + + Abstract the background scavenging slightly so that an alternate implementation that uses GCD can be used on platforms + where it is supported. + + * wtf/FastMalloc.cpp: + (WTF::TCMalloc_PageHeap::init): + (WTF::TCMalloc_PageHeap::initializeScavenger): + (WTF::TCMalloc_PageHeap::signalScavenger): + (WTF::TCMalloc_PageHeap::shouldContinueScavenging): + (WTF::TCMalloc_PageHeap::Delete): + (WTF::TCMalloc_PageHeap::periodicScavenge): + * wtf/Platform.h: + +2010-01-20 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + <rdar://problem/7562708> REGRESSION(53460): Heap::destroy may not run + all destructors + + * runtime/Collector.cpp: + (JSC::Heap::freeBlocks): Instead of fully marking protected objects, + just set their mark bits. This prevents protected objects from keeping + unprotected objects alive. Destructor order is not guaranteed, so it's + OK to destroy objects pointed to by protected objects before destroying + protected objects. + +2010-01-19 David Levin <levin@chromium.org> + + Reviewed by Oliver Hunt. + + CrossThreadCopier needs to support ThreadSafeShared better. + https://bugs.webkit.org/show_bug.cgi?id=33698 + + * wtf/TypeTraits.cpp: Added tests for the new type traits. + * wtf/TypeTraits.h: + (WTF::IsSubclass): Determines if a class is a derived from another class. + (WTF::IsSubclassOfTemplate): Determines if a class is a derived from a + template class (with one parameter that is unknown). + (WTF::RemoveTemplate): Reveals the type for a template parameter. + +2010-01-20 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Darin Adler and Adam Roben. + + Feature defines are difficult to maintain on Windows builds + https://bugs.webkit.org/show_bug.cgi?id=33883 + + FeatureDefines.vsprops are now maintained in a way similar to + Configurations/FeatureDefines.xcconfig, with the added advantage + of having a single FeatureDefines file across all projects. + + * Configurations/FeatureDefines.xcconfig: Add comments about keeping feature definitions in sync. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add FeatureDefines.vsprops inherited property sheet. + * JavaScriptCore.vcproj/WTF/WTF.vcproj: Add FeatureDefines.vsprops inherited property sheet. + +2010-01-20 Csaba Osztrogonác <ossy@webkit.org> + + [Qt] Unreviewed buildfix for r53547. + + * DerivedSources.pro: + +2010-01-20 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Make extraCompilers for generated sources depend on their scripts + + * DerivedSources.pro: + +2010-01-19 Brian Weinstein <bweinstein@apple.com> + + Reviewed by Tim Hatcher. + + When JavaScriptCore calls Debugger::Exception, have it pass a + hasHandler variable that represents if exception is being handled + in the same function (not in a parent on the call stack). + + This just adds a new parameter, no behavior is changed. + + * debugger/Debugger.h: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::throwException): + +2010-01-18 Maciej Stachowiak <mjs@apple.com> + + Reviewed by Adam Barth. + + Inline functions that are hot in DOM manipulation + https://bugs.webkit.org/show_bug.cgi?id=33820 + + (3% speedup on Dromaeo DOM Core tests) + + * runtime/WeakGCMap.h: + (JSC::::get): inline + +2010-01-19 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Unreviewed build fix for JIT with RVCT. + + Remove IMPORT statement; cti_vm_throw is already defined in JITStubs.h. + Remove extra ')'. + + * jit/JITStubs.cpp: + (JSC::ctiVMThrowTrampoline): + +2010-01-19 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + REGRESSION (52082): Crash on worker thread when reloading http://radnan.public.iastate.edu/procedural/ + https://bugs.webkit.org/show_bug.cgi?id=33826 + + This bug was caused by a GC-protected object being destroyed early by + Heap::destroy. Clients of the GC protect APIs (reasonably) expect pointers + to GC-protected memory to be valid. + + The solution is to do two passes of tear-down in Heap::destroy. The first + pass tears down all unprotected objects. The second pass ASSERTs that all + previously protected objects are now unprotected, and then tears down + all perviously protected objects. These two passes simulate the two passes + that would have been required to free a protected object during normal GC. + + * API/JSContextRef.cpp: Removed some ASSERTs that have moved into Heap. + + * runtime/Collector.cpp: + (JSC::Heap::destroy): Moved ASSERTs to here. + (JSC::Heap::freeBlock): Tidied up the use of didShrink by moving its + setter to the function that does the shrinking. + (JSC::Heap::freeBlocks): Implemented above algorithm. + (JSC::Heap::shrinkBlocks): Tidied up the use of didShrink. + +2010-01-19 Gavin Barraclough <barraclough@apple.com> + + Reviewed by NOBODY (build fix). + + Reverting r53455, breaks 2 javascriptcore tests. + + * API/JSContextRef.cpp: + * runtime/Collector.cpp: + (JSC::Heap::destroy): + (JSC::Heap::freeBlock): + (JSC::Heap::freeBlocks): + (JSC::Heap::shrinkBlocks): + +2010-01-18 Gavin Barraclough <barraclough@apple.com> + + Reviewed by NOBODY (build fix). + + Revert r53454, since it causes much sadness in this world. + + * runtime/UString.cpp: + (JSC::UString::spliceSubstringsWithSeparators): + (JSC::UString::replaceRange): + * runtime/UStringImpl.cpp: + (JSC::UStringImpl::baseSharedBuffer): + (JSC::UStringImpl::sharedBuffer): + (JSC::UStringImpl::~UStringImpl): + * runtime/UStringImpl.h: + (JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield): + (JSC::UntypedPtrAndBitfield::asPtr): + (JSC::UntypedPtrAndBitfield::operator&=): + (JSC::UntypedPtrAndBitfield::operator|=): + (JSC::UntypedPtrAndBitfield::operator&): + (JSC::UStringImpl::create): + (JSC::UStringImpl::cost): + (JSC::UStringImpl::isIdentifier): + (JSC::UStringImpl::setIsIdentifier): + (JSC::UStringImpl::ref): + (JSC::UStringImpl::deref): + (JSC::UStringImpl::checkConsistency): + (JSC::UStringImpl::UStringImpl): + (JSC::UStringImpl::bufferOwnerString): + (JSC::UStringImpl::bufferOwnership): + (JSC::UStringImpl::isStatic): + * wtf/StringHashFunctions.h: + (WTF::stringHash): + +2010-01-18 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + REGRESSION (52082): Crash on worker thread when reloading http://radnan.public.iastate.edu/procedural/ + https://bugs.webkit.org/show_bug.cgi?id=33826 + + This bug was caused by a GC-protected object being destroyed early by + Heap::destroy. Clients of the GC protect APIs (reasonably) expect pointers + to GC-protected memory to be valid. + + The solution is to do two passes of tear-down in Heap::destroy. The first + pass tears down all unprotected objects. The second pass ASSERTs that all + previously protected objects are now unprotected, and then tears down + all perviously protected objects. These two passes simulate the two passes + that would have been required to free a protected object during normal GC. + + * API/JSContextRef.cpp: Removed some ASSERTs that have moved into Heap. + + * runtime/Collector.cpp: + (JSC::Heap::destroy): Moved ASSERTs to here. + (JSC::Heap::freeBlock): Tidied up the use of didShrink by moving its + setter to the function that does the shrinking. + (JSC::Heap::freeBlocks): Implemented above algorithm. + (JSC::Heap::shrinkBlocks): Tidied up the use of didShrink. + +2010-01-18 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=33731 + Remove UntypedPtrAndBitfield from UStringImpl (akin to PtrAndFlags). + + This break the OS X Leaks tool. Instead, free up some more bits from the refCount. + + * runtime/UStringImpl.cpp: + (JSC::UStringImpl::sharedBuffer): + (JSC::UStringImpl::~UStringImpl): + * runtime/UStringImpl.h: + (JSC::UStringImpl::cost): + (JSC::UStringImpl::checkConsistency): + (JSC::UStringImpl::UStringImpl): + (JSC::UStringImpl::bufferOwnerString): + (JSC::UStringImpl::): + * wtf/StringHashFunctions.h: + (WTF::stringHash): + +2010-01-18 Kent Tamura <tkent@chromium.org> + + Reviewed by Darin Adler. + + HTMLInputElement::valueAsDate setter support for type=month. + https://bugs.webkit.org/show_bug.cgi?id=33021 + + Expose the following functions to be used by WebCore: + - WTF::msToyear() + - WTF::dayInYear() + - WTF::monthFromDayInYear() + - WTF::dayInMonthFromDayInYear() + + * JavaScriptCore.exp: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * wtf/DateMath.cpp: + (WTF::msToYear): Remove "static inline". + (WTF::dayInYear): Remove "static inline". + (WTF::monthFromDayInYear): Remove "static inline". + (WTF::dayInMonthFromDayInYear): Remove "static inline". + * wtf/DateMath.h: Declare the above functions. + +2010-01-18 Darin Adler <darin@apple.com> + + Fix build by reverting the previous change. + + * runtime/UString.h: Rolled out the FastAllocBase base class. + It was making UString larger, and therefore JSString larger, + and too big for a garbage collection cell. + + This raises the unpleasant possibility that many classes became + larger because we added the FastAllocBase base class. I am + worried about this, and it needs to be investigated. + +2010-01-18 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Darin Adler. + + Allow custom memory allocation control for UString class + https://bugs.webkit.org/show_bug.cgi?id=27831 + + Inherits the following class from FastAllocBase because it is + instantiated by 'new' and no need to be copyable: + + class name - instantiated at: + classs UString - JavaScriptCore/runtime/UString.cpp:160 + + * runtime/UString.h: + +2010-01-18 Evan Cheng <evan.cheng@apple.com> + + Reviewed by Darin Adler. + + Add some ALWAYS_INLINE for key functions not inlined by some versions of GCC. + rdar://problem/7553780 + + * runtime/JSObject.h: + (JSC::JSObject::getPropertySlot): ALWAYS_INLINE both overloads. + * runtime/JSString.h: + (JSC::JSString::JSString): ALWAYS_INLINE the version that takes a UString. + * runtime/UString.h: + (JSC::operator==): ALWAYS_INLINE the version that compares two UString objects. + +2010-01-18 Csaba Osztrogonác <ossy@webkit.org> + + Reviewed by Darin Adler. + + Delete dftables-xxxxxxxx.in files automatically. + https://bugs.webkit.org/show_bug.cgi?id=33796 + + * pcre/dftables: unlink unnecessary temporary file. + +2010-01-18 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Force qmake to generate a single makefile for DerivedSources.pro + + * DerivedSources.pro: + +2010-01-18 Csaba Osztrogonác <ossy@webkit.org> + + Rubber-stamped by Gustavo Noronha Silva. + + Rolling out r53391 and r53392 because of random crashes on buildbots. + https://bugs.webkit.org/show_bug.cgi?id=33731 + + * bytecode/CodeBlock.h: + (JSC::CallLinkInfo::seenOnce): + (JSC::CallLinkInfo::setSeen): + (JSC::MethodCallLinkInfo::MethodCallLinkInfo): + (JSC::MethodCallLinkInfo::seenOnce): + (JSC::MethodCallLinkInfo::setSeen): + * jit/JIT.cpp: + (JSC::JIT::unlinkCall): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::patchMethodCallProto): + * runtime/UString.cpp: + (JSC::UString::spliceSubstringsWithSeparators): + (JSC::UString::replaceRange): + * runtime/UString.h: + * runtime/UStringImpl.cpp: + (JSC::UStringImpl::baseSharedBuffer): + (JSC::UStringImpl::sharedBuffer): + (JSC::UStringImpl::~UStringImpl): + * runtime/UStringImpl.h: + (JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield): + (JSC::UntypedPtrAndBitfield::asPtr): + (JSC::UntypedPtrAndBitfield::operator&=): + (JSC::UntypedPtrAndBitfield::operator|=): + (JSC::UntypedPtrAndBitfield::operator&): + (JSC::UStringImpl::create): + (JSC::UStringImpl::cost): + (JSC::UStringImpl::isIdentifier): + (JSC::UStringImpl::setIsIdentifier): + (JSC::UStringImpl::ref): + (JSC::UStringImpl::deref): + (JSC::UStringImpl::checkConsistency): + (JSC::UStringImpl::UStringImpl): + (JSC::UStringImpl::bufferOwnerString): + (JSC::UStringImpl::bufferOwnership): + (JSC::UStringImpl::isStatic): + * wtf/StringHashFunctions.h: + (WTF::stringHash): + +2010-01-18 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Fix the build with strict gcc and RVCT versions: It's not legal to cast a + pointer to a function to a void* without an intermediate cast to a non-pointer + type. A cast to a ptrdiff_t inbetween fixes it. + + * runtime/JSString.h: + (JSC::Fiber::JSString): + +2010-01-15 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=33731 + Remove UntypedPtrAndBitfield from UStringImpl (akin to PtrAndFlags). + + This break the OS X Leaks tool. Instead, free up some more bits from the refCount. + + * runtime/UStringImpl.cpp: + (JSC::UStringImpl::sharedBuffer): + (JSC::UStringImpl::~UStringImpl): + * runtime/UStringImpl.h: + (JSC::UStringImpl::cost): + (JSC::UStringImpl::checkConsistency): + (JSC::UStringImpl::UStringImpl): + (JSC::UStringImpl::bufferOwnerString): + (JSC::UStringImpl::): + * wtf/StringHashFunctions.h: + (WTF::stringHash): + +2010-01-15 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=33731 + Remove uses of PtrAndFlags from JIT data stuctures. + + These break the OS X Leaks tool. Free up a bit in CallLinkInfo, and invalid + permutation of pointer states in MethodCallLinkInfo to represent the removed bits. + + * bytecode/CodeBlock.h: + (JSC::CallLinkInfo::seenOnce): + (JSC::CallLinkInfo::setSeen): + (JSC::MethodCallLinkInfo::MethodCallLinkInfo): + (JSC::MethodCallLinkInfo::seenOnce): + (JSC::MethodCallLinkInfo::setSeen): + * jit/JIT.cpp: + (JSC::JIT::unlinkCall): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::patchMethodCallProto): + * runtime/UString.h: + +2010-01-16 Maciej Stachowiak <mjs@apple.com> + + Reviewed by Oliver Hunt. + + Cache JS string values made from DOM strings (Dromaeo speedup) + https://bugs.webkit.org/show_bug.cgi?id=33768 + <rdar://problem/7353576> + + * runtime/JSString.h: + (JSC::jsStringWithFinalizer): Added new mechanism for a string to have an optional + finalizer callback, for the benefit of weak-referencing caches. + (JSC::): + (JSC::Fiber::JSString): + (JSC::Fiber::~JSString): + * runtime/JSString.cpp: + (JSC::JSString::resolveRope): Clear fibers so this doesn't look like a string with a finalizer. + * runtime/WeakGCMap.h: Include "Collector.h" to make this header includable by itself. + +2010-01-15 Sam Weinig <sam@webkit.org> + + Reviewed by Maciej Stachowiak. + + Fix for <rdar://problem/7548432> + Add ALWAYS_INLINE to jsLess for a 1% speedup on llvm-gcc. + + * runtime/Operations.h: + (JSC::jsLess): + +2010-01-14 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + REGRESISON: Google maps buttons not working properly + https://bugs.webkit.org/show_bug.cgi?id=31871 + + REGRESSION(r52948): JavaScript exceptions thrown on Google Maps when + getting directions for a second time + https://bugs.webkit.org/show_bug.cgi?id=33446 + + SunSpider and v8 report no change. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::tryCacheGetByID): Update our cached offset in case + flattening the dictionary changed any of its offsets. + + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCacheGetByID): + (JSC::DEFINE_STUB_FUNCTION): + * runtime/Operations.h: + (JSC::normalizePrototypeChain): ditto + +2010-01-14 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=33705 + UStringImpl::create() should use internal storage + + When creating a UStringImpl copying of a UChar*, we can use an internal buffer, + by calling UStringImpl::tryCreateUninitialized(). + + Also, remove duplicate of copyChars from JSString, call UStringImpl's version. + + Small (max 0.5%) progression on Sunspidey. + + * runtime/JSString.cpp: + (JSC::JSString::resolveRope): + * runtime/UStringImpl.h: + (JSC::UStringImpl::create): + +2010-01-14 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + Make naming & behaviour of UString[Impl] methods more consistent. + https://bugs.webkit.org/show_bug.cgi?id=33702 + + UString::create() creates a copy of the UChar* passed, but UStringImpl::create() assumes + that it should assume ownership of the provided buffer (with UString::createNonCopying() + and UStringImpl::createCopying() providing the alternate behaviours). Unify on create() + taking a copy of the provided buffer. For non-copying cases, use the name 'adopt', and + make this method take a Vector<UChar>&. For cases where non-copying construction was being + used, other than from a Vector<UChar>, change the code to allocate the storage along with + the UStringImpl using UStringImpl::createUninitialized(). (The adopt() method also more + closely matches that of WebCore::StringImpl). + + Also, UString::createUninitialized() and UStringImpl::createUninitialized() have incompatible + behaviours, in that the UString form sets the provided UChar* to a null or non-null value to + indicate success or failure, but UStringImpl uses the returned PassRefPtr<UStringImpl> to + indicate when allocation has failed (potentially leaving the output Char* uninitialized). + This is also incompatible with WebCore::StringImpl's behaviour, in that + StringImpl::createUninitialized() will CRASH() if unable to allocate. Some uses of + createUninitialized() in JSC are unsafe, since they do not test the result for null. + UStringImpl's indication is preferable, since we may want a successful call to set the result + buffer to 0 (specifically, StringImpl returns 0 for the buffer where createUninitialized() + returns the empty string, which seems reasonable to catch bugs early). UString's method + cannot support UStringImpl's behaviour directly, since it returns an object rather than a + pointer. + - remove UString::createUninitialized(), replace with calls to UStringImpl::createUninitialized() + - create a UStringImpl::tryCreateUninitialized() form UStringImpl::createUninitialized(), + with current behaviour, make createUninitialized() crash on failure to allocate. + - make cases in JSC that do not check the result call createUninitialized(), and cases that do + check call tryCreateUninitialized(). + + Rename computedHash() to existingHash(), to bring this in line wih WebCore::StringImpl. + + * API/JSClassRef.cpp: + (OpaqueJSClassContextData::OpaqueJSClassContextData): + * JavaScriptCore.exp: + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncToString): + * runtime/Identifier.cpp: + (JSC::CStringTranslator::translate): + (JSC::UCharBufferTranslator::translate): + * runtime/JSString.cpp: + (JSC::JSString::resolveRope): + * runtime/Lookup.cpp: + (JSC::HashTable::createTable): + * runtime/Lookup.h: + (JSC::HashTable::entry): + * runtime/StringBuilder.h: + (JSC::StringBuilder::release): + * runtime/StringConstructor.cpp: + (JSC::stringFromCharCodeSlowCase): + * runtime/StringPrototype.cpp: + (JSC::substituteBackreferencesSlow): + (JSC::stringProtoFuncToLowerCase): + (JSC::stringProtoFuncToUpperCase): + (JSC::stringProtoFuncFontsize): + (JSC::stringProtoFuncLink): + * runtime/Structure.cpp: + (JSC::Structure::despecifyDictionaryFunction): + (JSC::Structure::get): + (JSC::Structure::despecifyFunction): + (JSC::Structure::put): + (JSC::Structure::remove): + (JSC::Structure::insertIntoPropertyMapHashTable): + (JSC::Structure::checkConsistency): + * runtime/Structure.h: + (JSC::Structure::get): + * runtime/StructureTransitionTable.h: + (JSC::StructureTransitionTableHash::hash): + * runtime/UString.cpp: + (JSC::createRep): + (JSC::UString::UString): + (JSC::UString::spliceSubstringsWithSeparators): + (JSC::UString::replaceRange): + (JSC::UString::operator=): + * runtime/UString.h: + (JSC::UString::adopt): + (JSC::IdentifierRepHash::hash): + (JSC::makeString): + * runtime/UStringImpl.h: + (JSC::UStringImpl::adopt): + (JSC::UStringImpl::create): + (JSC::UStringImpl::createUninitialized): + (JSC::UStringImpl::tryCreateUninitialized): + (JSC::UStringImpl::existingHash): + +2010-01-13 Kent Hansen <kent.hansen@nokia.com> + + Reviewed by Oliver Hunt. + + JSON.stringify and JSON.parse needlessly process properties in the prototype chain + https://bugs.webkit.org/show_bug.cgi?id=33053 + + * runtime/JSONObject.cpp: + (JSC::Stringifier::Holder::appendNextProperty): + (JSC::Walker::walk): + +2010-01-13 Gavin Barraclough <barraclough@apple.com> + + Reviewed by NOBODY (buildfix). + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2010-01-13 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=33641 + Assertion failure in Lexer.cpp if input stream ends while in string escape + + Test: fast/js/end-in-string-escape.html + + * parser/Lexer.cpp: (JSC::Lexer::lex): Bail out quickly on end of stream, not giving the + assertion a chance to fire. + +2010-01-13 Gavin Barraclough <barraclough@apple.com> + + Reviewed by NOBODY (buildfix). + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2010-01-13 Gavin Barraclough <barraclough@apple.com> + + Rubber stamped by Sam Weinig & Darin Adler. + + Three quick fixes to UStringImpl. + - The destroy() method can be switched back to a normal destructor; since we've switched + the way we protect static strings to be using an odd ref-count the destroy() won't abort. + - The cost() calculation logic was wrong. If you have multiple JSStrings wrapping substrings + of a base string, they would each report the full cost of the base string to the heap. + Instead we should only be reporting once for the base string. + - Remove the overloaded new operator calling fastMalloc, replace this with a 'using' to pick + up the implementation from the parent class. + + * JavaScriptCore.exp: + * runtime/UStringImpl.cpp: + (JSC::UStringImpl::~UStringImpl): + * runtime/UStringImpl.h: + (JSC::UStringImpl::cost): + (JSC::UStringImpl::deref): + +2010-01-13 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Split the build process in two different .pro files. + This allows qmake to be run once all source files are available. + + * DerivedSources.pro: Added. + * JavaScriptCore.pri: Moved source generation to DerivedSources.pro + * pcre/pcre.pri: Moved source generation to DerivedSources.pro + +2010-01-12 Kent Hansen <kent.hansen@nokia.com> + + Reviewed by Geoffrey Garen. + + [ES5] Implement Object.getOwnPropertyNames + https://bugs.webkit.org/show_bug.cgi?id=32242 + + Add an extra argument to getPropertyNames() and getOwnPropertyNames() + (and all reimplementations thereof) that indicates whether non-enumerable + properties should be added. + + * API/JSCallbackObject.h: + * API/JSCallbackObjectFunctions.h: + (JSC::::getOwnPropertyNames): + * JavaScriptCore.exp: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * debugger/DebuggerActivation.cpp: + (JSC::DebuggerActivation::getOwnPropertyNames): + * debugger/DebuggerActivation.h: + * runtime/Arguments.cpp: + (JSC::Arguments::getOwnPropertyNames): + * runtime/Arguments.h: + * runtime/CommonIdentifiers.h: + * runtime/JSArray.cpp: + (JSC::JSArray::getOwnPropertyNames): + * runtime/JSArray.h: + * runtime/JSByteArray.cpp: + (JSC::JSByteArray::getOwnPropertyNames): + * runtime/JSByteArray.h: + * runtime/JSFunction.cpp: + (JSC::JSFunction::getOwnPropertyNames): + * runtime/JSFunction.h: + * runtime/JSNotAnObject.cpp: + (JSC::JSNotAnObject::getOwnPropertyNames): + * runtime/JSNotAnObject.h: + * runtime/JSObject.cpp: + (JSC::getClassPropertyNames): + (JSC::JSObject::getPropertyNames): + (JSC::JSObject::getOwnPropertyNames): + * runtime/JSObject.h: + * runtime/JSVariableObject.cpp: + (JSC::JSVariableObject::getOwnPropertyNames): + * runtime/JSVariableObject.h: + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::ObjectConstructor): + (JSC::objectConstructorGetOwnPropertyNames): + * runtime/RegExpMatchesArray.h: + (JSC::RegExpMatchesArray::getOwnPropertyNames): + * runtime/StringObject.cpp: + (JSC::StringObject::getOwnPropertyNames): + * runtime/StringObject.h: + * runtime/Structure.cpp: Rename getEnumerablePropertyNames() to getPropertyNames(), which takes an extra argument. + (JSC::Structure::getPropertyNames): + * runtime/Structure.h: + (JSC::): + +2010-01-12 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=33540 + Make it possible to build in debug mode with assertions disabled + + * jit/JITStubs.cpp: (JSC::DEFINE_STUB_FUNCTION): + * runtime/Identifier.cpp: (JSC::Identifier::checkSameIdentifierTable): + * wtf/FastMalloc.cpp: + * wtf/HashTable.h: (WTF::HashTableConstIterator::checkValidity): + * yarr/RegexCompiler.cpp: (JSC::Yarr::compileRegex): + +2009-11-23 Yong Li <yoli@rim.com> + + Reviewed by Adam Treat. + + Make GIF decoder support down-sampling + https://bugs.webkit.org/show_bug.cgi?id=31806 + + * platform/image-decoders/ImageDecoder.cpp: + (WebCore::ImageDecoder::upperBoundScaledY): + (WebCore::ImageDecoder::lowerBoundScaledY): + * platform/image-decoders/ImageDecoder.h: + (WebCore::RGBA32Buffer::scaledRect): + (WebCore::RGBA32Buffer::setScaledRect): + (WebCore::ImageDecoder::scaledSize): + * platform/image-decoders/gif/GIFImageDecoder.cpp: + (WebCore::GIFImageDecoder::sizeNowAvailable): + (WebCore::GIFImageDecoder::initFrameBuffer): + (WebCore::copyOnePixel): + (WebCore::GIFImageDecoder::haveDecodedRow): + (WebCore::GIFImageDecoder::frameComplete): + +2010-01-12 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + ecma/Date/15.9.5.12-1.js fails every night at midnight + https://bugs.webkit.org/show_bug.cgi?id=28041 + + Change the test to use a concrete time instead of "now". + + * tests/mozilla/ecma/Date/15.9.5.10-1.js: + * tests/mozilla/ecma/Date/15.9.5.12-1.js: + +2010-01-11 Csaba Osztrogonác <ossy@webkit.org> + + Reviewed by Ariya Hidayat. + + [Qt] Enable JIT and YARR_JIT if (CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100) + + * wtf/Platform.h: + +2010-01-11 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Alexey Proskuryakov. + + https://bugs.webkit.org/show_bug.cgi?id=33481 + Uninitialized data members in ArrayStorage + + SunSpider reports no change. + + * runtime/JSArray.cpp: + (JSC::JSArray::JSArray): Initialize missing data members in the two cases + where we don't use fastZeroedMalloc, so it doesn't happen automatically. + +2010-01-11 Steve Falkenburg <sfalken@apple.com> + + Reviewed by Sam Weinig. + + https://bugs.webkit.org/show_bug.cgi?id=33480 + + Improve debugging reliability for WTF on Windows. + Store WTF static library's PDB file into a better location. + + * JavaScriptCore.vcproj/WTF/WTF.vcproj: + +2010-01-11 Steve Falkenburg <sfalken@apple.com> + + Windows build fix. + Remove extraneous entries from def file causing build warning. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2010-01-10 Kent Hansen <kent.hansen@nokia.com> + + Reviewed by Darin Adler. + + RegExp.prototype.toString returns "//" for empty regular expressions + https://bugs.webkit.org/show_bug.cgi?id=33319 + + "//" starts a single-line comment, hence "/(?:)/" should be used, according to ECMA. + + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncToString): + + * tests/mozilla/ecma_2/RegExp/properties-001.js: + (AddRegExpCases): + * tests/mozilla/js1_2/regexp/toString.js: + Update relevant Mozilla tests (Mozilla has had this behavior since November 2003). + +2010-01-10 Darin Adler <darin@apple.com> + + * tests/mozilla/ecma/Array/15.4.1.1.js: Added property allow-tabs. + * tests/mozilla/ecma/Array/15.4.1.2.js: Added property allow-tabs. + * tests/mozilla/ecma/Array/15.4.2.1-1.js: Added property allow-tabs. + * tests/mozilla/ecma/Array/15.4.2.2-1.js: Added property allow-tabs. + * tests/mozilla/ecma/Array/15.4.2.2-2.js: Added property allow-tabs. + * tests/mozilla/ecma/Array/15.4.2.3.js: Added property allow-tabs. + * tests/mozilla/ecma/Array/15.4.3.2.js: Added property allow-tabs. + * tests/mozilla/ecma/Array/15.4.3.js: Added property allow-tabs. + * tests/mozilla/ecma/Array/15.4.4.1.js: Added property allow-tabs. + * tests/mozilla/ecma/Array/15.4.4.js: Added property allow-tabs. + * tests/mozilla/ecma/LexicalConventions/7.7.4.js: Added property allow-tabs. + * tests/mozilla/ecma/Math/15.8.2.13.js: Added property allow-tabs. + * tests/mozilla/ecma/Math/15.8.2.16.js: Added property allow-tabs. + * tests/mozilla/ecma/Math/15.8.2.18.js: Added property allow-tabs. + * tests/mozilla/ecma/Math/15.8.2.2.js: Added property allow-tabs. + * tests/mozilla/ecma/Math/15.8.2.4.js: Added property allow-tabs. + * tests/mozilla/ecma/Math/15.8.2.5.js: Added property allow-tabs. + * tests/mozilla/ecma/Math/15.8.2.7.js: Added property allow-tabs. + * tests/mozilla/ecma/String/15.5.1.js: Added property allow-tabs. + * tests/mozilla/ecma/String/15.5.2.js: Added property allow-tabs. + * tests/mozilla/ecma/String/15.5.3.1-3.js: Added property allow-tabs. + * tests/mozilla/ecma/String/15.5.3.1-4.js: Added property allow-tabs. + * tests/mozilla/ecma/String/15.5.3.js: Added property allow-tabs. + * tests/mozilla/ecma/TypeConversion/9.5-2.js: Added property allow-tabs. + * tests/mozilla/ecma/jsref.js: Modified property allow-tabs. + * tests/mozilla/ecma/shell.js: Modified property allow-tabs. + * tests/mozilla/ecma_2/LexicalConventions/keywords-001.js: Added property allow-tabs. + * tests/mozilla/ecma_2/RegExp/exec-001.js: Added property allow-tabs. + * tests/mozilla/ecma_2/String/match-004.js: Added property allow-tabs. + * tests/mozilla/ecma_2/String/replace-001.js: Added property allow-tabs. + * tests/mozilla/ecma_2/String/split-002.js: Added property allow-tabs. + * tests/mozilla/ecma_2/jsref.js: Modified property allow-tabs. + * tests/mozilla/ecma_2/shell.js: Added property allow-tabs. + * tests/mozilla/ecma_3/Date/shell.js: Modified property allow-tabs. + * tests/mozilla/ecma_3/Exceptions/regress-181654.js: Added property allow-tabs. + * tests/mozilla/ecma_3/RegExp/regress-209067.js: Added property allow-tabs. + * tests/mozilla/ecma_3/RegExp/regress-85721.js: Added property allow-tabs. + * tests/mozilla/importList.html: Added property allow-tabs. + * tests/mozilla/js1_1/shell.js: Added property allow-tabs. + * tests/mozilla/js1_2/Array/general1.js: Added property allow-tabs. + * tests/mozilla/js1_2/Array/general2.js: Added property allow-tabs. + * tests/mozilla/js1_2/Array/slice.js: Added property allow-tabs. + * tests/mozilla/js1_2/Array/splice1.js: Added property allow-tabs. + * tests/mozilla/js1_2/Array/splice2.js: Added property allow-tabs. + * tests/mozilla/js1_2/Objects/toString-001.js: Added property allow-tabs. + * tests/mozilla/js1_2/String/charCodeAt.js: Added property allow-tabs. + * tests/mozilla/js1_2/String/concat.js: Modified property allow-tabs. + * tests/mozilla/js1_2/String/match.js: Added property allow-tabs. + * tests/mozilla/js1_2/String/slice.js: Added property allow-tabs. + * tests/mozilla/js1_2/function/Function_object.js: Added property allow-tabs. + * tests/mozilla/js1_2/function/Number.js: Modified property allow-tabs. + * tests/mozilla/js1_2/function/String.js: Modified property allow-tabs. + * tests/mozilla/js1_2/function/nesting.js: Added property allow-tabs. + * tests/mozilla/js1_2/function/regexparg-1.js: Added property allow-tabs. + * tests/mozilla/js1_2/function/regexparg-2-n.js: Added property allow-tabs. + * tests/mozilla/js1_2/jsref.js: Added property allow-tabs. + * tests/mozilla/js1_2/operator/equality.js: Added property allow-tabs. + * tests/mozilla/js1_2/operator/strictEquality.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_dollar_number.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_input.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_input_as_array.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_lastIndex.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_lastMatch.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_lastMatch_as_array.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_lastParen.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_lastParen_as_array.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_leftContext.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_leftContext_as_array.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_multiline.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_multiline_as_array.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_object.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_rightContext.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/RegExp_rightContext_as_array.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/alphanumeric.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/asterisk.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/backslash.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/backspace.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/beginLine.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/character_class.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/compile.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/control_characters.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/digit.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/dot.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/endLine.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/everything.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/exec.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/flags.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/global.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/hexadecimal.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/ignoreCase.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/interval.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/octal.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/parentheses.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/plus.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/question_mark.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/simple_form.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/source.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/special_characters.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/string_replace.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/string_search.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/string_split.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/test.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/toString.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/vertical_bar.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/whitespace.js: Added property allow-tabs. + * tests/mozilla/js1_2/regexp/word_boundary.js: Added property allow-tabs. + * tests/mozilla/js1_2/shell.js: Added property allow-tabs. + * tests/mozilla/js1_2/statements/break.js: Added property allow-tabs. + * tests/mozilla/js1_2/statements/continue.js: Added property allow-tabs. + * tests/mozilla/js1_2/statements/do_while.js: Added property allow-tabs. + * tests/mozilla/js1_2/statements/switch.js: Added property allow-tabs. + * tests/mozilla/js1_2/statements/switch2.js: Added property allow-tabs. + * tests/mozilla/js1_3/shell.js: Added property allow-tabs. + * tests/mozilla/js1_4/shell.js: Added property allow-tabs. + * tests/mozilla/js1_5/Regress/regress-111557.js: Added property allow-tabs. + * tests/mozilla/js1_5/Regress/regress-216320.js: Added property allow-tabs. + * tests/mozilla/menuhead.html: Added property allow-tabs. + * tests/mozilla/mklistpage.pl: Added property allow-tabs. + * tests/mozilla/runtests.pl: Added property allow-tabs. + +2010-01-08 Daniel Bates <dbates@webkit.org> + + Reviewed by Adam Barth. + + https://bugs.webkit.org/show_bug.cgi?id=33417 + + Cleans up style errors exposed by the patch for bug #33198. + Moreover, fixes all "Weird number of spaces at line-start. Are you using a 4-space indent?" + errors reported by check-webkit-style. + + No functionality was changed. So, no new tests. + + * wtf/Platform.h: + +2010-01-08 Kent Hansen <kent.hansen@nokia.com> + + Reviewed by Eric Seidel. + + Don't store RegExp flags string representation + https://bugs.webkit.org/show_bug.cgi?id=33321 + + It's unused; the string representation is reconstructed from flags. + + * runtime/RegExp.cpp: + (JSC::RegExp::RegExp): + * runtime/RegExp.h: + +2010-01-08 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Memory use grows grows possibly unbounded in this JavaScript Array test case + https://bugs.webkit.org/show_bug.cgi?id=31675 + + This fixes one observed bug in this test case, which is that + arrays don't report extra cost for the sparse value maps. + + SunSpider reports a small speedup. + + * runtime/JSArray.cpp: + (JSC::JSArray::putSlowCase): Report extra memory cost for + the sparse value map. + * runtime/JSArray.h: + +2010-01-08 Yong Li <yoli@rim.com> + + Reviewed by Darin Adler. + + Remove unnecessary #include from FastMalloc.cpp + https://bugs.webkit.org/show_bug.cgi?id=33393 + + * wtf/FastMalloc.cpp: + +2010-01-08 Eric Seidel <eric@webkit.org> + + No review, rolling out r52983. + http://trac.webkit.org/changeset/52983 + https://bugs.webkit.org/show_bug.cgi?id=33321 + + Broke 59 JavaScriptCore tests. I don't think Kent knew about + run-javascriptcore-tests. Sadly neither does the commit-bot, + yet. + + * runtime/RegExp.cpp: + (JSC::RegExp::RegExp): + * runtime/RegExp.h: + (JSC::RegExp::flags): + +2010-01-08 Eric Seidel <eric@webkit.org> + + No review, rolling out r52981. + http://trac.webkit.org/changeset/52981 + https://bugs.webkit.org/show_bug.cgi?id=33319 + + Caused two JS tests to start failing: + ecma_2/RegExp/properties-001.js and js1_2/regexp/toString.js + + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncToString): + +2010-01-08 Kent Hansen <kent.hansen@nokia.com> + + Reviewed by Darin Adler. + + Don't store RegExp flags string representation + https://bugs.webkit.org/show_bug.cgi?id=33321 + + It's unused; the string representation is reconstructed from flags. + + * runtime/RegExp.cpp: + (JSC::RegExp::RegExp): + * runtime/RegExp.h: + +2010-01-08 Kent Hansen <kent.hansen@nokia.com> + + Reviewed by Darin Adler. + + RegExp.prototype.toString returns "//" for empty regular expressions + https://bugs.webkit.org/show_bug.cgi?id=33319 + + "//" starts a single-line comment, hence "/(?:)/" should be used, according to ECMA. + + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncToString): + +2010-01-08 Norbert Leser <norbert.leser@nokia.com> + + Reviewed by Darin Adler. + + RVCT compiler with "-Otime -O3" optimization tries to optimize out + inline new'ed pointers that are passed as arguments. + Proposed patch assigns new'ed pointer explicitly outside function call. + + https://bugs.webkit.org/show_bug.cgi?id=33084 + + * API/JSClassRef.cpp: + (OpaqueJSClass::OpaqueJSClass): + (OpaqueJSClassContextData::OpaqueJSClassContextData): + +2010-01-08 Gabor Loki <loki@webkit.org> + + Reviewed by Gavin Barraclough. + + Remove an unnecessary cacheFlush from ARM_TRADITIONAL JIT + https://bugs.webkit.org/show_bug.cgi?id=33203 + + * assembler/ARMAssembler.cpp: Remove obsolete linkBranch function. + (JSC::ARMAssembler::executableCopy): Inline a clean linkBranch code. + * assembler/ARMAssembler.h: + (JSC::ARMAssembler::getLdrImmAddress): Use inline function. + (JSC::ARMAssembler::getLdrImmAddressOnPool): Ditto. + (JSC::ARMAssembler::patchPointerInternal): Remove an unnecessary cacheFlush. + (JSC::ARMAssembler::linkJump): Use patchPointerInternal instead of linkBranch. + (JSC::ARMAssembler::linkCall): Ditto. + (JSC::ARMAssembler::relinkCall): Ditto. + +2010-01-07 Gabor Loki <loki@webkit.org> + + Reviewed by Gavin Barraclough. + + Build fix for JSVALUE32 when ENABLE_JIT_OPTIMIZE* are disabled + https://bugs.webkit.org/show_bug.cgi?id=33311 + + Move compileGetDirectOffset function to common part of JSVALUE32 + + * jit/JITPropertyAccess.cpp: + (JSC::JIT::compileGetDirectOffset): + +2010-01-07 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Maciej Stachowiak. + + Allow call sites to determine if ASSERT_* and LOG_* macros are operational + https://bugs.webkit.org/show_bug.cgi?id=33020 + + * wtf/Assertions.h: Set ASSERT_MSG_DISABLED, FATAL_DISABLED, + ERROR_DISABLED, LOG_DISABLED to 1 if the compiler does not support + variadic macros. Refactor for better readibility. + +2010-01-07 Daniel Bates <dbates@rim.com> + + Reviewed by Eric Seidel. + + https://bugs.webkit.org/show_bug.cgi?id=32987 + + Added ENABLE_XHTMLMP flag. Disabled by default. + + * Configurations/FeatureDefines.xcconfig: + +2010-01-07 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Gavin Barraclough. + + [Symbian] Port ARM traditional JIT Trampolines to RVCT + https://bugs.webkit.org/show_bug.cgi?id=30552 + + Take the GCC implementation and mechanically convert + it to RVCT syntax. + + Use 'bx rX' instead of 'mov pc, rX' when it is available. + + Developed in cooperation with Iain Campbell and Gabor Loki. + + * JavaScriptCore.pri: Extra step to generate RVCT stubs. The + script generation intentionally executed all the time not just + for RVCT targets. + + * create_rvct_stubs: Added. Perl script to expand precompiler macros + for RVCT assembler - the template is defined in JITStubs.cpp. + + * jit/JITStubs.cpp: + (JSC::ctiTrampoline): + (JSC::ctiVMThrowTrampoline): + (JSC::ctiOpThrowNotCaught): + +2010-01-07 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Fix a crash seen on the buildbots. + + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::init): Disable specific function tracking here, + instead of in WebCore, to ensure that the disabling happens before a + specific function can be registered. + +2010-01-07 Alexey Proskuryakov <ap@apple.com> + + Mac build fix. + + * JavaScriptCore.exp: Export new JSGlobalData static data members. + +2010-01-07 Alexey Proskuryakov <ap@apple.com> + + Reviewed by Geoffrey Garen. + + https://bugs.webkit.org/show_bug.cgi?id=33057 + REGRESSION(r49365): typeof(xhr.responseText) != "string" in Windows + + <rdar://problem/7296920> REGRESSION: WebKit fails to start PeaceKeeper benchmark + + Test: fast/js/webcore-string-comparison.html + + In r49365, some code was moved from JSString.cpp to JSString.h, and as a result, WebCore + got a way to directly instantiate JSStrings over DLL borders. Since vftable for JSString was + not exported, objects created from WebCore got a different vptr, and JavaScriptCore + optimizations that relied on vptr of all JSString objects being equal failed. + + * config.h: Added a JS_EXPORTCLASS macro for exporting classes. It's currently the same as + JS_EXPORTDATA, but it clearly needed a new name. + + * runtime/InitializeThreading.cpp: + (JSC::initializeThreadingOnce): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::storeVPtrs): + (JSC::JSGlobalData::JSGlobalData): + (JSC::JSGlobalData::createNonDefault): + (JSC::JSGlobalData::create): + (JSC::JSGlobalData::sharedInstance): + * runtime/JSGlobalData.h: + Store vptrs just once, no need to repeatedly pick and copy them. This makes it possible to + assert vptr correctness in object destructors (which don't have access to JSGlobalData, + and even Heap::heap(this) will fail for fake objects created from storeVPtrs()). + + * runtime/JSArray.cpp: (JSC::JSArray::~JSArray): Assert that vptr is what we expect it to be. + It's important to assert in destructor, because MSVC changes the vptr after constructor + is invoked. + * runtime/JSByteArray.cpp: (JSC::JSByteArray::~JSByteArray): Ditto. + * runtime/JSByteArray.h: Ditto. + * runtime/JSFunction.h: Ditto. + * runtime/JSFunction.cpp: (JSC::JSFunction::~JSFunction): Ditto. + + * runtime/JSCell.h: (JSC::JSCell::setVPtr): Added a method to substitute vptr for another + one. + + * runtime/JSString.h: Export JSString class together with its vftable, and tell other + libraries tp import it. This is needed on platforms that have a separate JavaScriptCore + dynamic library - and on Mac, we already did the export via JavaScriptCore.exp. + (JSC::JSString::~JSString): Assert tha vptr is what we expect it to be. + (JSC::fixupVPtr): Store a previously saved primary vftable pointer (do nothing if building + JavaScriptCore itself). + (JSC::jsSingleCharacterString): Call fixupVPtr in case this is call across DLL boundary. + (JSC::jsSingleCharacterSubstring): Ditto. + (JSC::jsNontrivialString): Ditto. + (JSC::jsString): Ditto. + (JSC::jsSubstring): Ditto. + (JSC::jsOwnedString): Ditto. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Export the new static + JSGlobalData members that are used in WebCore via inline functions. + +2010-01-07 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Safari memory usage skyrockets using new Google AdWords interface + https://bugs.webkit.org/show_bug.cgi?id=33343 + + The memory use was caused by the global object creating too many structures + as it thrashed between different specific functions. + + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC::Structure::addPropertyTransition): + (JSC::Structure::changePrototypeTransition): + (JSC::Structure::despecifyFunctionTransition): + (JSC::Structure::addAnonymousSlotsTransition): + (JSC::Structure::getterSetterTransition): + (JSC::Structure::toDictionaryTransition): + (JSC::Structure::addPropertyWithoutTransition): + (JSC::Structure::despecifyAllFunctions): + * runtime/Structure.h: + (JSC::Structure::disableSpecificFunctionTracking): Track a thrash count + for specific functions. Disable specific function tracking once the + thrash count has been hit. + +2010-01-07 Csaba Osztrogonác <ossy@webkit.org> + + Reviewed by Simon Hausmann. + + [Qt] Enable JIT in debug mode on win32 after r51141 fixed the crashes. + + * JavaScriptCore.pri: + +2010-01-07 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Holger Freyther. + + [Mac] Build fix when FAST_MALLOC_MATCH_VALIDATION=1 + https://bugs.webkit.org/show_bug.cgi?id=33312 + + Using of operator += cause compile error on Mac, so it is changed to + "= static_cast<AllocAlignmentInteger*>(old_ptr) + 1". + + * wtf/FastMalloc.cpp: + (WTF::TCMallocStats::realloc): + +2010-01-07 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Holger Freyther. + + [Qt] Build fix when FAST_MALLOC_MATCH_VALIDATION=1 + https://bugs.webkit.org/show_bug.cgi?id=33312 + + Remove pByte (committed in r42344 from #20422), because pByte doesn't + exist and it is unnecessary. + + * wtf/FastMalloc.cpp: + (WTF::TCMallocStats::realloc): + +2010-01-06 Gavin Barraclough <barraclough@apple.com> + + QT build fix. + + * runtime/Identifier.cpp: + (JSC::createIdentifierTableSpecific): + +2010-01-06 Gavin Barraclough <barraclough@apple.com> + + Windows build fix part I. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2010-01-06 Dan Bernstein <mitz@apple.com> + + Build fix + + * runtime/Identifier.cpp: + (JSC::createIdentifierTableSpecificCallback): + +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. + + Buildfix for WinCE + style fixes. + https://bugs.webkit.org/show_bug.cgi?id=32939 + + * jsc.cpp: + (functionPrint): + (functionQuit): + (parseArguments): + (fillBufferWithContentsOfFile): + +2010-01-05 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Eric Seidel. + + WinCE buildfix after r52791 (renamed PLATFORM(WINCE) to OS(WINCE)). + https://bugs.webkit.org/show_bug.cgi?id=33205 + + * jit/ExecutableAllocator.h: + +2010-01-05 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Darin Adler. + + Added compiler error for unsupported platforms. + https://bugs.webkit.org/show_bug.cgi?id=33112 + + * jit/JITStubs.cpp: + +2010-01-05 Gabor Loki <loki@webkit.org> + + Reviewed by Maciej Stachowiak. + + Follow r52729 in ARMAssembler. + https://bugs.webkit.org/show_bug.cgi?id=33208 + + Use WTF_ARM_ARCH_AT_LEAST instead of ARM_ARCH_VERSION + + * assembler/ARMAssembler.cpp: + (JSC::ARMAssembler::encodeComplexImm): Move tmp declaration to ARMv7 + * assembler/ARMAssembler.h: + (JSC::ARMAssembler::): + (JSC::ARMAssembler::bkpt): + +2010-01-05 Maciej Stachowiak <mjs@apple.com> + + Unreviewed build fix for Gtk+ + + Don't use // comments in Platform.h, at least some of them seem to make the version of GCC + used on the Gtk buildbot unhappy. + + * wtf/Platform.h: + +2010-01-04 Maciej Stachowiak <mjs@apple.com> + + Reviewed by Darin Fisher. + + Reorganize, document and rename OS() platform macros. + https://bugs.webkit.org/show_bug.cgi?id=33198 + + * wtf/Platform.h: Rename, reorganize and document OS() macros. + + Adapt to name changes. Also fixed a few incorrect OS checks. + + * API/JSContextRef.cpp: + * assembler/MacroAssemblerARM.cpp: + (JSC::isVFPPresent): + * assembler/MacroAssemblerX86Common.h: + * bytecode/SamplingTool.cpp: + * config.h: + * interpreter/RegisterFile.cpp: + (JSC::RegisterFile::~RegisterFile): + * interpreter/RegisterFile.h: + (JSC::RegisterFile::RegisterFile): + (JSC::RegisterFile::grow): + * jit/ExecutableAllocator.h: + * jit/ExecutableAllocatorFixedVMPool.cpp: + * jit/ExecutableAllocatorPosix.cpp: + * jit/ExecutableAllocatorSymbian.cpp: + * jit/ExecutableAllocatorWin.cpp: + * jit/JITOpcodes.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + * jit/JITStubs.cpp: + * jsc.cpp: + (main): + * parser/Grammar.y: + * profiler/ProfileNode.cpp: + (JSC::getCount): + * runtime/Collector.cpp: + (JSC::Heap::Heap): + (JSC::Heap::allocateBlock): + (JSC::Heap::freeBlockPtr): + (JSC::currentThreadStackBase): + (JSC::getCurrentPlatformThread): + (JSC::suspendThread): + (JSC::resumeThread): + (JSC::getPlatformThreadRegisters): + (JSC::otherThreadStackPointer): + * runtime/Collector.h: + * runtime/DateConstructor.cpp: + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + * runtime/InitializeThreading.cpp: + (JSC::initializeThreading): + * runtime/MarkStack.h: + (JSC::MarkStack::MarkStackArray::shrinkAllocation): + * runtime/MarkStackPosix.cpp: + * runtime/MarkStackSymbian.cpp: + * runtime/MarkStackWin.cpp: + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncLastIndexOf): + * runtime/TimeoutChecker.cpp: + (JSC::getCPUTime): + * runtime/UString.cpp: + (JSC::UString::from): + * wtf/Assertions.cpp: + * wtf/Assertions.h: + * wtf/CurrentTime.cpp: + (WTF::lowResUTCTime): + * wtf/CurrentTime.h: + (WTF::getLocalTime): + * wtf/DateMath.cpp: + * wtf/FastMalloc.cpp: + (WTF::TCMalloc_ThreadCache::InitModule): + (WTF::TCMallocStats::): + * wtf/FastMalloc.h: + * wtf/MathExtras.h: + * wtf/RandomNumber.cpp: + (WTF::randomNumber): + * wtf/RandomNumberSeed.h: + (WTF::initializeRandomNumberGenerator): + * wtf/StringExtras.h: + * wtf/TCSpinLock.h: + (TCMalloc_SpinLock::Unlock): + (TCMalloc_SlowLock): + * wtf/TCSystemAlloc.cpp: + * wtf/ThreadSpecific.h: + (WTF::::destroy): + * wtf/Threading.h: + * wtf/ThreadingPthreads.cpp: + (WTF::initializeThreading): + (WTF::isMainThread): + * wtf/ThreadingWin.cpp: + (WTF::wtfThreadEntryPoint): + (WTF::createThreadInternal): + * wtf/VMTags.h: + * wtf/unicode/icu/CollatorICU.cpp: + (WTF::Collator::userDefault): + * wtf/win/MainThreadWin.cpp: + (WTF::initializeMainThreadPlatform): + +2010-01-04 Gustavo Noronha Silva <gns@gnome.org> + + Add missing files to the build system - make distcheck build fix. + + * GNUmakefile.am: + +2010-01-04 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig, additional coding by Mark Rowe. + + https://bugs.webkit.org/show_bug.cgi?id=33163 + Add string hashing functions to WTF. + Use WTF's string hashing functions from UStringImpl. + + * GNUmakefile.am: + * JavaScriptCore.exp: + * JavaScriptCore.gypi: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/UStringImpl.cpp: + * runtime/UStringImpl.h: + (JSC::UStringImpl::computeHash): + * wtf/HashFunctions.h: + * wtf/StringHashFunctions.h: Added. + (WTF::stringHash): + +2010-01-04 Dmitry Titov <dimich@chromium.org> + + Not reviewed, attempt to fix ARM bulid. + + * wtf/Platform.h: + +2010-01-04 Gavin Barraclough <barraclough@apple.com> + + Rubber stamped by Geoff Garen. + + Add an 'isIdentifier' to UStringImpl, use this where appropriate + (where previously 'identifierTable' was being tested). + + * API/JSClassRef.cpp: + (OpaqueJSClass::~OpaqueJSClass): + (OpaqueJSClassContextData::OpaqueJSClassContextData): + * runtime/Identifier.cpp: + (JSC::Identifier::addSlowCase): + * runtime/Identifier.h: + (JSC::Identifier::add): + * runtime/PropertyNameArray.cpp: + (JSC::PropertyNameArray::add): + * runtime/UStringImpl.h: + (JSC::UStringImpl::isIdentifier): + +2010-01-04 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam "Shimmey Shimmey" Weinig. + + https://bugs.webkit.org/show_bug.cgi?id=33158 + Refactor JSC API entry/exit to use RAII instead of copy/pasting code. + Make it easier to change set of actions taken when passing across the API boundary. + + * API/APIShims.h: Added. + (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): + (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock): + (JSC::APIEntryShim::APIEntryShim): + (JSC::APICallbackShim::APICallbackShim): + (JSC::APICallbackShim::~APICallbackShim): + * API/JSBase.cpp: + (JSEvaluateScript): + (JSCheckScriptSyntax): + (JSGarbageCollect): + (JSReportExtraMemoryCost): + * API/JSCallbackConstructor.cpp: + (JSC::constructJSCallback): + * API/JSCallbackFunction.cpp: + (JSC::JSCallbackFunction::call): + * API/JSCallbackObjectFunctions.h: + (JSC::::init): + (JSC::::getOwnPropertySlot): + (JSC::::put): + (JSC::::deleteProperty): + (JSC::::construct): + (JSC::::hasInstance): + (JSC::::call): + (JSC::::getOwnPropertyNames): + (JSC::::toNumber): + (JSC::::toString): + (JSC::::staticValueGetter): + (JSC::::callbackGetter): + * API/JSContextRef.cpp: + * API/JSObjectRef.cpp: + (JSObjectMake): + (JSObjectMakeFunctionWithCallback): + (JSObjectMakeConstructor): + (JSObjectMakeFunction): + (JSObjectMakeArray): + (JSObjectMakeDate): + (JSObjectMakeError): + (JSObjectMakeRegExp): + (JSObjectGetPrototype): + (JSObjectSetPrototype): + (JSObjectHasProperty): + (JSObjectGetProperty): + (JSObjectSetProperty): + (JSObjectGetPropertyAtIndex): + (JSObjectSetPropertyAtIndex): + (JSObjectDeleteProperty): + (JSObjectCallAsFunction): + (JSObjectCallAsConstructor): + (JSObjectCopyPropertyNames): + (JSPropertyNameArrayRelease): + (JSPropertyNameAccumulatorAddName): + * API/JSValueRef.cpp: + (JSValueGetType): + (JSValueIsUndefined): + (JSValueIsNull): + (JSValueIsBoolean): + (JSValueIsNumber): + (JSValueIsString): + (JSValueIsObject): + (JSValueIsObjectOfClass): + (JSValueIsEqual): + (JSValueIsStrictEqual): + (JSValueIsInstanceOfConstructor): + (JSValueMakeUndefined): + (JSValueMakeNull): + (JSValueMakeBoolean): + (JSValueMakeNumber): + (JSValueMakeString): + (JSValueToBoolean): + (JSValueToNumber): + (JSValueToStringCopy): + (JSValueToObject): + (JSValueProtect): + (JSValueUnprotect): + * JavaScriptCore.xcodeproj/project.pbxproj: + +2010-01-04 Dan Bernstein <mitz@apple.com> + + Reviewed by Ada Chan and Mark Rowe. + + Updated copyright string + + * Info.plist: + * JavaScriptCore.vcproj/JavaScriptCore.resources/Info.plist: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc: + +2010-01-04 Adam Roben <aroben@apple.com> + + No review, rolling out r52741. + http://trac.webkit.org/changeset/52741 + https://bugs.webkit.org/show_bug.cgi?id=33056 + + * wtf/AlwaysInline.h: + +2010-01-04 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Darin Adler. + + Add cacheFlush support for WinCE + https://bugs.webkit.org/show_bug.cgi?id=33110 + + * jit/ExecutableAllocator.h: + (JSC::ExecutableAllocator::cacheFlush): + +2010-01-04 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Adam Roben. + + Implement NO_RETURN for COMPILER(MSVC). + https://bugs.webkit.org/show_bug.cgi?id=33056 + + * wtf/AlwaysInline.h: + +2010-01-04 Maciej Stachowiak <mjs@apple.com> + + Reviewed by Simon Hausmann. + + Fix some PLATFORM(*_ENDIAN) uses to CPU() + https://bugs.webkit.org/show_bug.cgi?id=33148 + + * runtime/JSCell.cpp: + (JSC::): + * runtime/JSValue.h: + (JSC::JSValue::): + +2010-01-04 Maciej Stachowiak <mjs@apple.com> + + Reviewed by Adam Barth. + + Document CPU() macros in comments. + https://bugs.webkit.org/show_bug.cgi?id=33147 + + * wtf/Platform.h: + +2010-01-04 Maciej Stachowiak <mjs@apple.com> + + Reviewed by Adam Barth. + + Reorganize, document and rename CPU() platform macros. + https://bugs.webkit.org/show_bug.cgi?id=33145 + ExecutableAllocatorSymbian appears to have buggy ARM version check + https://bugs.webkit.org/show_bug.cgi?id=33138 + + * wtf/Platform.h: + Rename all macros related to detection of particular CPUs or + classes of CPUs to CPU(), reorganize and document them. + + All remaining changes are adapting to the renames, plus fixing the + second bug cited above. + + * assembler/ARMAssembler.cpp: + * assembler/ARMAssembler.h: + * assembler/ARMv7Assembler.h: + * assembler/AbstractMacroAssembler.h: + (JSC::AbstractMacroAssembler::Imm32::Imm32): + * assembler/MacroAssembler.h: + * assembler/MacroAssemblerARM.cpp: + * assembler/MacroAssemblerARM.h: + * assembler/MacroAssemblerCodeRef.h: + (JSC::MacroAssemblerCodePtr::MacroAssemblerCodePtr): + * assembler/MacroAssemblerX86.h: + * assembler/MacroAssemblerX86Common.h: + * assembler/MacroAssemblerX86_64.h: + * assembler/X86Assembler.h: + (JSC::X86Registers::): + (JSC::X86Assembler::): + (JSC::X86Assembler::movl_mEAX): + (JSC::X86Assembler::movl_EAXm): + (JSC::X86Assembler::repatchLoadPtrToLEA): + (JSC::X86Assembler::X86InstructionFormatter::memoryModRM): + * jit/ExecutableAllocator.h: + * jit/ExecutableAllocatorFixedVMPool.cpp: + * jit/ExecutableAllocatorPosix.cpp: + * jit/ExecutableAllocatorSymbian.cpp: + (JSC::ExecutableAllocator::intializePageSize): + * jit/JIT.cpp: + * jit/JIT.h: + * jit/JITArithmetic.cpp: + * jit/JITInlineMethods.h: + (JSC::JIT::beginUninterruptedSequence): + (JSC::JIT::restoreArgumentReferenceForTrampoline): + (JSC::JIT::emitCount): + * jit/JITOpcodes.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::privateCompileGetByIdProto): + (JSC::JIT::privateCompileGetByIdProtoList): + (JSC::JIT::privateCompileGetByIdChainList): + (JSC::JIT::privateCompileGetByIdChain): + * jit/JITStubs.cpp: + (JSC::JITThunks::JITThunks): + * jit/JITStubs.h: + * runtime/Collector.cpp: + (JSC::currentThreadStackBase): + (JSC::getPlatformThreadRegisters): + (JSC::otherThreadStackPointer): + * wrec/WREC.h: + * wrec/WRECGenerator.cpp: + (JSC::WREC::Generator::generateEnter): + (JSC::WREC::Generator::generateReturnSuccess): + (JSC::WREC::Generator::generateReturnFailure): + * wrec/WRECGenerator.h: + * wtf/FastMalloc.cpp: + * wtf/TCSpinLock.h: + (TCMalloc_SpinLock::Lock): + (TCMalloc_SpinLock::Unlock): + (TCMalloc_SlowLock): + * wtf/Threading.h: + * wtf/dtoa.cpp: + * yarr/RegexJIT.cpp: + (JSC::Yarr::RegexGenerator::generateEnter): + (JSC::Yarr::RegexGenerator::generateReturn): + * yarr/RegexJIT.h: + +2010-01-04 Maciej Stachowiak <mjs@apple.com> + + Reviewed by Adam Barth. + + Clean up COMPILER macros and remove unused ones. + https://bugs.webkit.org/show_bug.cgi?id=33132 + + Removed values are COMPILER(BORLAND) and COMPILER(CYGWIN) - they were + not used anywhere. + + * wtf/Platform.h: + +2010-01-03 Maciej Stachowiak <mjs@apple.com> + + Reviewed by Eric Seidel. + + Update wtf/Platform.h to document the new system for porting macros. + https://bugs.webkit.org/show_bug.cgi?id=33130 + + * wtf/Platform.h: + +2009-12-29 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Maciej Stachowiak. + + PLATFORM(CAIRO) should be defined by WIN_CAIRO define + https://bugs.webkit.org/show_bug.cgi?id=22250 + + * wtf/Platform.h: Define WTF_PLATFORM_CAIRO for GTK port only + For the WinCairo port WTF_PLATFORM_CAIRO is already defined in config.h + +2009-12-28 Shu Chang <Chang.Shu@nokia.com> + + Reviewed by Laszlo Gombos. + + [Qt] Delete ThreadPrivate instance after it is finished. + https://bugs.webkit.org/show_bug.cgi?id=32614 + + * wtf/qt/ThreadingQt.cpp: + (WTF::ThreadMonitor::instance): + (WTF::ThreadMonitor::threadFinished): + (WTF::createThreadInternal): + (WTF::detachThread): + +2009-12-28 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Maciej Stachowiak. + + Cleanup of #define JS_EXPORT. + + * API/JSBase.h: + +2009-12-27 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Adam Barth. + + WinCE buildfix (HWND_MESSAGE isn't supported there) + + * wtf/win/MainThreadWin.cpp: + (WTF::initializeMainThreadPlatform): + +2009-12-27 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Adam Barth. + + Added a file with WinMain function to link agains in WinCE. + + * os-win32/WinMain.cpp: Added. + (convertToUtf8): + (WinMain): + +2009-12-24 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Unreviewed; revert of r52550. + + The change regressed the following LayoutTests for QtWebKit. + + fast/workers/worker-call.html -> crashed + fast/workers/worker-close.html -> crashed + + * wtf/qt/ThreadingQt.cpp: + (WTF::waitForThreadCompletion): + (WTF::detachThread): + +2009-12-24 Shu Chang <Chang.Shu@nokia.com> + + Reviewed by Laszlo Gombos. + + [Qt] Fix memory leak by deleting instance of ThreadPrivate + in function waitForThreadCompletion(), synchronously, or in + detachThread(), asynchronously. + https://bugs.webkit.org/show_bug.cgi?id=32614 + + * wtf/qt/ThreadingQt.cpp: + (WTF::waitForThreadCompletion): + (WTF::detachThread): + +2009-12-23 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Laszlo Gombos. + + Include stddef.h for ptrdiff_t + https://bugs.webkit.org/show_bug.cgi?id=32891 + + ptrdiff_t is typedef-ed in stddef.h. + Include stddef.h in jit/ExecutableAllocator.h. + + * jit/ExecutableAllocator.h: + +2009-12-23 Patrick Gansterer <paroga@paroga.com> + + Reviewed by Eric Seidel. + + Buildfix after r47092. + + * wtf/wince/MemoryManager.cpp: + (WTF::tryFastMalloc): + (WTF::tryFastZeroedMalloc): + (WTF::tryFastCalloc): + (WTF::tryFastRealloc): + +2009-12-23 Kent Tamura <tkent@chromium.org> + + Reviewed by Darin Adler. + + HTMLInputElement::valueAsDate getter support. + https://bugs.webkit.org/show_bug.cgi?id=32876 + + Expose dateToDaysFrom1970(). + + * JavaScriptCore.exp: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * wtf/DateMath.cpp: + (WTF::dateToDaysFrom1970): + * wtf/DateMath.h: + +2009-12-22 Darin Adler <darin@apple.com> + + Reviewed by Mark Rowe. + + Turn off datagrid by default, at least for all platforms Apple ships. + The datagrid implementation isn't ready for general web use yet. + + * Configurations/FeatureDefines.xcconfig: Turn off datagrid by default. + +2009-12-22 Steve Block <steveblock@google.com> + + Reviewed by David Levin. + + Updates Android's scheduleDispatchFunctionsOnMainThread() to use new + AndroidThreading class, rather than using JavaSharedClient directly. + This fixes the current layering violation. + https://bugs.webkit.org/show_bug.cgi?id=32651 + + The pattern is copied from Chromium, which uses the ChromiumThreading + class. This patch also fixes the style in ChromiumThreading.h. + + * wtf/android/AndroidThreading.h: Added. Declares AndroidThreading. + * wtf/android/MainThreadAndroid.cpp: Modified + (WTF::scheduleDispatchFunctionsOnMainThread): Uses AndroidThreading. + * wtf/chromium/ChromiumThreading.h: Modified. Fixes style. + +2009-12-22 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + Fix a couple of problems with UntypedPtrAndBitfield. + + Add a m_leaksPtr to reduce false positives from leaks in debug builds + (this isn't perfect because we'd like a solution for release builds, + but this is now at least as good as a PtrAndFlags would be). + + Switch SmallStringsto use a regular string for the base, rather than + a static one. UntypedPtrAndBitfield assumes all strings are at least + 8 byte aligned; this migt not be true of static strings. Shared buffers + are heap allocated, as are all UStringImpls other than static strings. + Static strings cannot end up being the owner string of substrings, + since the only static strings are length 0. + + * runtime/SmallStrings.cpp: + (JSC::SmallStringsStorage::SmallStringsStorage): + * runtime/UStringImpl.h: + (JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield): + (JSC::UStringImpl::UStringImpl): + +2009-12-22 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Darin Adler. + + RVCT (__ARMCC_VERSION < 400000) does not provide strcasecmp and strncasecmp + https://bugs.webkit.org/show_bug.cgi?id=32857 + + Add implementation of strcasecmp and strncasecmp for RVCT < 4.0 + because earlier versions of RVCT 4.0 does not provide these functions. + + * wtf/StringExtras.cpp: Added. + (strcasecmp): + (strncasecmp): + * wtf/StringExtras.h: + +2009-12-22 Kwang Yul Seo <skyul@company100.net> + + Reviewed by Darin Adler. + + Define ALWAYS_INLINE and WTF_PRIVATE_INLINE to __forceinline for RVCT + https://bugs.webkit.org/show_bug.cgi?id=32853 + + Use __forceinline forces RVCT to compile a C or C++ function + inline. The compiler attempts to inline the function, regardless of + the characteristics of the function. + + * wtf/AlwaysInline.h: + * wtf/FastMalloc.h: + +2009-12-21 Simon Hausmann <simon.hausmann@nokia.com> + + Prospective GTK build fix: Add UStringImpl.cpp/h to the build. + + * GNUmakefile.am: + +2009-12-21 Simon Hausmann <simon.hausmann@nokia.com> + + Fix the Qt build, add UStringImpl.cpp to the build. + + * JavaScriptCore.pri: + +2009-12-21 Gavin Barraclough <barraclough@apple.com> + + Windows Build fix part 5. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + +2009-12-21 Gavin Barraclough <barraclough@apple.com> + + Reviewed by NOBODY (build fix). + Fix breakage of world introduced in build fix to r52463. + + * runtime/UStringImpl.h: + +2009-12-21 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Darin Adler. + + https://bugs.webkit.org/show_bug.cgi?id=32831 + Replace UString::Rep implementation, following introduction of ropes to JSC. + + * Remove redundant overcapacity mechanisms. + * Reduce memory cost of Rep's. + * Add an inline storage mechanism akin to that in WebCore's StringImpl. + + ~1% Sunspider progression. + + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/JSString.cpp: + (JSC::JSString::resolveRope): + * runtime/SmallStrings.cpp: + (JSC::SmallStringsStorage::SmallStringsStorage): + * runtime/UString.cpp: + (JSC::initializeUString): + (JSC::createRep): + (JSC::UString::createFromUTF8): + (JSC::UString::createUninitialized): + (JSC::UString::spliceSubstringsWithSeparators): + (JSC::UString::replaceRange): + (JSC::UString::ascii): + (JSC::UString::operator=): + (JSC::UString::toStrictUInt32): + (JSC::equal): + * runtime/UString.h: + (JSC::UString::isEmpty): + (JSC::UString::cost): + (JSC::makeString): + * runtime/UStringImpl.cpp: Added. + (JSC::UStringImpl::baseSharedBuffer): + (JSC::UStringImpl::sharedBuffer): + (JSC::UStringImpl::destroy): + (JSC::UStringImpl::computeHash): + * runtime/UStringImpl.h: Added. + (JSC::UntypedPtrAndBitfield::UntypedPtrAndBitfield): + (JSC::UntypedPtrAndBitfield::asPtr): + (JSC::UntypedPtrAndBitfield::operator&=): + (JSC::UntypedPtrAndBitfield::operator|=): + (JSC::UntypedPtrAndBitfield::operator&): + (JSC::UStringImpl::create): + (JSC::UStringImpl::createCopying): + (JSC::UStringImpl::createUninitialized): + (JSC::UStringImpl::data): + (JSC::UStringImpl::size): + (JSC::UStringImpl::cost): + (JSC::UStringImpl::hash): + (JSC::UStringImpl::computedHash): + (JSC::UStringImpl::setHash): + (JSC::UStringImpl::identifierTable): + (JSC::UStringImpl::setIdentifierTable): + (JSC::UStringImpl::ref): + (JSC::UStringImpl::deref): + (JSC::UStringImpl::allocChars): + (JSC::UStringImpl::copyChars): + (JSC::UStringImpl::computeHash): + (JSC::UStringImpl::null): + (JSC::UStringImpl::empty): + (JSC::UStringImpl::checkConsistency): + (JSC::UStringImpl::): + (JSC::UStringImpl::UStringImpl): + (JSC::UStringImpl::operator new): + (JSC::UStringImpl::bufferOwnerString): + (JSC::UStringImpl::bufferOwnership): + (JSC::UStringImpl::isStatic): + +2009-12-18 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Move some build decisions from Qt build system into source files + https://bugs.webkit.org/show_bug.cgi?id=31956 + + * JavaScriptCore.pri: Compile files unconditionally + * jit/ExecutableAllocatorPosix.cpp: Guard with PLATFORM(UNIX) && !PLATFORM(SYMBIAN) + * jit/ExecutableAllocatorWin.cpp: Guard with PLATFORM(WIN_OS) + * runtime/MarkStackPosix.cpp: Guard with PLATFORM(UNIX) && !PLATFORM(SYMBIAN) + * runtime/MarkStackSymbian.cpp: Guard with PLATFORM(SYMBIAN) + * runtime/MarkStackWin.cpp: Guard with PLATFORM(WIN_OS) + * wtf/Platform.h: Guard ENABLE_JSC_MULTIPLE_THREADS with ENABLE_SINGLE_THREADED for the Qt port + * wtf/ThreadingNone.cpp: Guard with ENABLE(SINGLE_THREADED) + * wtf/qt/ThreadingQt.cpp: Guard with !ENABLE(SINGLE_THREADED) + +2009-12-18 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + Add createNonCopying method to UString to make replace constructor passed bool, + to make behaviour more explicit. Add createFromUTF8 to UString (wrapping method + on UString::Rep), since other cases of transliteration (e.g. from ascii) are + performed in UString constructors. Add/use setHash & size() accessors on Rep, + rather than accessing _hash/len directly. + + * API/JSClassRef.cpp: + (OpaqueJSClass::OpaqueJSClass): + * API/OpaqueJSString.cpp: + (OpaqueJSString::ustring): + * JavaScriptCore.exp: + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncToString): + * runtime/Identifier.cpp: + (JSC::Identifier::equal): + (JSC::CStringTranslator::translate): + (JSC::UCharBufferTranslator::translate): + (JSC::Identifier::addSlowCase): + * runtime/JSString.cpp: + (JSC::JSString::resolveRope): + * runtime/JSString.h: + (JSC::JSString::Rope::Fiber::refAndGetLength): + (JSC::JSString::Rope::append): + * runtime/StringBuilder.h: + (JSC::StringBuilder::release): + * runtime/StringConstructor.cpp: + (JSC::stringFromCharCodeSlowCase): + * runtime/StringPrototype.cpp: + (JSC::substituteBackreferencesSlow): + (JSC::stringProtoFuncToLowerCase): + (JSC::stringProtoFuncToUpperCase): + (JSC::stringProtoFuncFontsize): + (JSC::stringProtoFuncLink): + * runtime/UString.cpp: + (JSC::UString::UString): + (JSC::UString::createNonCopying): + (JSC::UString::createFromUTF8): + * runtime/UString.h: + (JSC::UString::Rep::setHash): + (JSC::UString::~UString): + (JSC::makeString): + +2009-12-18 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Cameron Zwarich and Gavin Barraclough. + + Changed Register constructors to assignment operators, to streamline + moving values into registers. (In theory, there's no difference between + the two, since the constructor should just inline away, but there seems + to be a big difference in the addled mind of the GCC optimizer.) + + In the interpreter, this is a 3.5% SunSpider speedup and a 1K-2K + reduction in stack usage per privateExecute stack frame. + + * interpreter/CallFrame.h: + (JSC::ExecState::setCalleeArguments): + (JSC::ExecState::setCallerFrame): + (JSC::ExecState::setScopeChain): + (JSC::ExecState::init): + (JSC::ExecState::setArgumentCount): + (JSC::ExecState::setCallee): + (JSC::ExecState::setCodeBlock): Added a little bit of casting so these + functions could use the new Register assignment operators. + + * interpreter/Register.h: + (JSC::Register::withInt): + (JSC::Register::Register): + (JSC::Register::operator=): Swapped in assignment operators for constructors. + +2009-12-18 Yongjun Zhang <yongjun.zhang@nokia.com> + + Reviewed by Simon Hausmann. + + https://bugs.webkit.org/show_bug.cgi?id=32713 + [Qt] make wtf/Assertions.h compile in winscw compiler. + + Add string arg before ellipsis to help winscw compiler resolve variadic + macro definitions in wtf/Assertions.h. + + * wtf/Assertions.h: + +2009-12-18 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Adam Roben. + + Fixed intermittent failure seen on Windows buildbot, and in other JSC + API clients. + + Added a WeakGCPtr class and changed OpaqueJSClass::cachedPrototype to + use it, to avoid vending a stale object as a prototype. + + * API/JSClassRef.cpp: + (OpaqueJSClassContextData::OpaqueJSClassContextData): + (OpaqueJSClass::prototype): + * API/JSClassRef.h: Use WeakGCPtr. + + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/WeakGCPtr.h: Added. + (JSC::WeakGCPtr::WeakGCPtr): + (JSC::WeakGCPtr::get): + (JSC::WeakGCPtr::clear): + (JSC::WeakGCPtr::operator*): + (JSC::WeakGCPtr::operator->): + (JSC::WeakGCPtr::operator!): + (JSC::WeakGCPtr::operator bool): + (JSC::WeakGCPtr::operator UnspecifiedBoolType): + (JSC::WeakGCPtr::assign): + (JSC::::operator): + (JSC::operator==): + (JSC::operator!=): + (JSC::static_pointer_cast): + (JSC::const_pointer_cast): + (JSC::getPtr): Added WeakGCPtr to the project. + +2009-12-18 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + https://bugs.webkit.org/show_bug.cgi?id=32720 + + * JavaScriptCore.exp: + - Remove exports for UString::append + * JavaScriptCore.xcodeproj/project.pbxproj: + - Make StringBuilder a private header (was project). + +2009-12-18 Martin Robinson <martin.james.robinson@gmail.com> + + Reviewed by Gustavo Noronha Silva. + + [GTK] GRefPtr does not take a reference when assigned a raw pointer + https://bugs.webkit.org/show_bug.cgi?id=32709 + + Ensure that when assigning a raw pointer to a GRefPtr, the reference + count is incremented. Also remove the GRefPtr conversion overload as + GRefPtr types have necessarily incompatible reference counting. + + * wtf/gtk/GRefPtr.h: + (WTF::GRefPtr::operator=): + +2009-12-18 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Clean up the qmake build system to distinguish between trunk builds and package builds + + https://bugs.webkit.org/show_bug.cgi?id=32716 + + * pcre/pcre.pri: Use standalone_package instead of QTDIR_build + +2009-12-18 Martin Robinson <martin.james.robinson@gmail.com> + + Reviewed by Gustavo Noronha Silva. + + [GTK] Compile warning from line 29 of GRefPtr.cpp + https://bugs.webkit.org/show_bug.cgi?id=32703 + + Fix memory leak and compiler warning in GRefPtr GHashTable template + specialization. + + * wtf/gtk/GRefPtr.cpp: + (WTF::refGPtr): + +2009-12-17 Sam Weinig <sam@webkit.org> + + Reviewed by Mark Rowe. + + Add BUILDING_ON_SNOW_LEOPARD and TARGETING_SNOW_LEOPARD #defines. + + * wtf/Platform.h: + +2009-12-17 Adam Roben <aroben@apple.com> + + Sync JavaScriptCore.vcproj with JavaScriptCore.xcodeproj and the + source tree + + Fixes <http://webkit.org/b/32665>. + + Reviewed by Ada Chan. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Moved + around files and filters so that the structure matches + JavaScriptCore.xcodeproj and the source tree. A few headers that were + previously omitted have been added, as well as JSZombie.{cpp,h}. + +2009-12-17 Adam Roben <aroben@apple.com> + + Remove HeavyProfile and TreeProfile completely + + These were mostly removed in r42808, but the empty files were left in + place. + + Fixes <http://webkit.org/b/32664>. + + Reviewed by John Sullivan. + + * Android.mk: + * GNUmakefile.am: + * JavaScriptCore.gypi: + * JavaScriptCore.pri: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCoreSources.bkl: + Removed HeavyProfile/TreeProfile source files. + + * profiler/HeavyProfile.cpp: Removed. + * profiler/HeavyProfile.h: Removed. + * profiler/TreeProfile.cpp: Removed. + * profiler/TreeProfile.h: Removed. + +2009-12-17 Martin Robinson <martin.james.robinson@gmail.com> + + Reviewed by Gustavo Noronha Silva. + + [GTK] WebKit GTK needs a wrapper for ref counted glib/gobject structs + https://bugs.webkit.org/show_bug.cgi?id=21599 + + Implement GRefPtr, a smart pointer for reference counted GObject types. + + * GNUmakefile.am: + * wtf/gtk/GOwnPtr.cpp: + (WTF::GDir): + * wtf/gtk/GRefPtr.h: Added. + (WTF::): + (WTF::GRefPtr::GRefPtr): + (WTF::GRefPtr::~GRefPtr): + (WTF::GRefPtr::clear): + (WTF::GRefPtr::get): + (WTF::GRefPtr::operator*): + (WTF::GRefPtr::operator->): + (WTF::GRefPtr::operator!): + (WTF::GRefPtr::operator UnspecifiedBoolType): + (WTF::GRefPtr::hashTableDeletedValue): + (WTF::::operator): + (WTF::::swap): + (WTF::swap): + (WTF::operator==): + (WTF::operator!=): + (WTF::static_pointer_cast): + (WTF::const_pointer_cast): + (WTF::getPtr): + (WTF::adoptGRef): + (WTF::refGPtr): + (WTF::derefGPtr): + +2009-12-17 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> + + Unreviewed. Build fixes for make distcheck. + + * GNUmakefile.am: + +2009-12-16 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Fixed <rdar://problem/7355025> Interpreter::privateExecute macro generates + bloated code + + This patch cuts Interpreter stack use by about a third. + + * bytecode/Opcode.h: Changed Opcode to const void* to work with the + const static initiliazation we want to do in Interpreter::privateExecute. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::Interpreter): Moved hashtable initialization here to + avoid polluting Interpreter::privateExecute's stack, and changed it from a + series of add() calls to one add() call in a loop, to cut down on code size. + + (JSC::Interpreter::privateExecute): Changed a series of label computations + to a copy of a compile-time constant array to cut down on code size. + +2009-12-16 Mark Rowe <mrowe@apple.com> + + Build fix. Disable debug variants of WebKit frameworks. + + * JavaScriptCore.xcodeproj/project.pbxproj: + +2009-12-15 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam "r=me" Weinig. + + https://bugs.webkit.org/show_bug.cgi?id=32498 + <rdar://problem/7471495> + REGRESSION(r51978-r52039): AJAX "Mark This Forum Read" function no longer + works + + Fixed a tyop. + + * runtime/Operations.h: + (JSC::jsAdd): Use the '&&' operator, not the ',' operator. + +2009-12-15 Geoffrey Garen <ggaren@apple.com> + + Try to fix the windows build: don't export this inlined function. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2009-12-15 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Beth Dakin. + + Inlined JSCell's operator new. + + 3.7% speedup on bench-allocate-nonretained.js. + + * JavaScriptCore.exp: + * runtime/JSCell.cpp: + * runtime/JSCell.h: + (JSC::JSCell::operator new): + +2009-12-15 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Oliver Hunt. + + Removed the number heap, replacing it with a one-item free list for + numbers, taking advantage of the fact that two number cells fit inside + the space for one regular cell, and number cells don't require destruction. + + SunSpider says 1.6% faster in JSVALUE32 mode (the only mode that + heap-allocates numbers). + + SunSpider says 1.1% faster in JSVALUE32_64 mode. v8 says 0.8% faster + in JSVALUE32_64 mode. 10% speedup on bench-alloc-nonretained.js. 6% + speedup on bench-alloc-retained.js. + + There's a lot of formulaic change in this patch, but not much substance. + + * JavaScriptCore.exp: + * debugger/Debugger.cpp: + (JSC::Debugger::recompileAllJSFunctions): + * runtime/Collector.cpp: + (JSC::Heap::Heap): + (JSC::Heap::destroy): + (JSC::Heap::allocateBlock): + (JSC::Heap::freeBlock): + (JSC::Heap::freeBlockPtr): + (JSC::Heap::freeBlocks): + (JSC::Heap::recordExtraCost): + (JSC::Heap::allocate): + (JSC::Heap::resizeBlocks): + (JSC::Heap::growBlocks): + (JSC::Heap::shrinkBlocks): + (JSC::Heap::markConservatively): + (JSC::Heap::clearMarkBits): + (JSC::Heap::markedCells): + (JSC::Heap::sweep): + (JSC::Heap::markRoots): + (JSC::Heap::objectCount): + (JSC::Heap::addToStatistics): + (JSC::Heap::statistics): + (JSC::Heap::isBusy): + (JSC::Heap::reset): + (JSC::Heap::collectAllGarbage): + (JSC::Heap::primaryHeapBegin): + (JSC::Heap::primaryHeapEnd): + * runtime/Collector.h: + (JSC::): Removed all code pertaining to the number heap, and changed all + heap template functions and classes to non-template functions and classes. + + (JSC::Heap::allocateNumber): A new optimization to replace the number + heap: allocate half-sized number cells in pairs, returning the first + cell and caching the second cell for the next allocation. + + * runtime/CollectorHeapIterator.h: + (JSC::LiveObjectIterator::LiveObjectIterator): + (JSC::LiveObjectIterator::operator++): + (JSC::DeadObjectIterator::DeadObjectIterator): + (JSC::DeadObjectIterator::operator++): + (JSC::ObjectIterator::ObjectIterator): + (JSC::ObjectIterator::operator++): + * runtime/JSCell.h: + (JSC::JSCell::isNumber): Removed all code pertaining to the number heap, + and changed all heap template functions and classes to non-template functions + and classes. + +2009-12-15 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Darin Adler. + + Allow custom memory allocation control for WeakGCMap class + https://bugs.webkit.org/show_bug.cgi?id=32547 + + Inherits WeakGCMap from FastAllocBase because it is instantiated by + 'new' at: WebCore/dom/Document.cpp:512. + + * runtime/WeakGCMap.h: + +2009-12-15 Zoltan Horvath <zoltan@webkit.org> + + Reviewed by Darin Adler. + + Allow custom memory allocation control for dtoa's P5Node struct + https://bugs.webkit.org/show_bug.cgi?id=32544 + + Inherits P5Node struct from Noncopyable because it is instantiated by + 'new' at wtf/dtoa.cpp:588 and don't need to be copyable. + + * wtf/dtoa.cpp: + +2009-12-14 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Simon Fraser. + + https://bugs.webkit.org/show_bug.cgi?id=32524 + REGRESSION(52084): fast/dom/prototypes.html failing two CSS tests + + * wtf/StdLibExtras.h: + (WTF::bitCount): The original patch put the parentheses in the wrong + place, completely changing the calculation and making it almost always + wrong. Moved the parentheses around the '+' operation, like the original + compiler warning suggested. + +2009-12-14 Gabor Loki <loki@inf.u-szeged.hu> + + Unreviewed trivial buildfix. + + Fix crosses initialization of usedPrimaryBlocks for JSValue32 + + * runtime/Collector.cpp: + (JSC::Heap::markConservatively): + +2009-12-14 Csaba Osztrogonác <ossy@webkit.org> + + Reviewed by Simon Hausmann. + + GCC 4.3.x warning fixed. Suggested parantheses added. + warning: ../../../JavaScriptCore/wtf/StdLibExtras.h:77: warning: suggest parentheses around + or - in operand of & + + * wtf/StdLibExtras.h: + (WTF::bitCount): + +2009-12-13 Geoffrey Garen <ggaren@apple.com> + + Reviewed by Sam Weinig. + + Changed GC from mark-sweep to mark-allocate. + + Added WeakGCMap to keep WebCore blissfully ignorant about objects that + have become garbage but haven't run their destructors yet. + + 1% SunSpider speedup. + 7.6% v8 speedup (37% splay speedup). + 17% speedup on bench-alloc-nonretained.js. + 18% speedup on bench-alloc-retained.js. + + * API/JSBase.cpp: + (JSGarbageCollect): + * API/JSContextRef.cpp: + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: Updated for renames and new + files. + + * debugger/Debugger.cpp: + (JSC::Debugger::recompileAllJSFunctions): Updated to use the Collector + iterator abstraction. + + * jsc.cpp: + (functionGC): Updated for rename. + + * runtime/Collector.cpp: Slightly reduced the number of allocations per + collection, so that small workloads only allocate on collector block, + rather than two. + + (JSC::Heap::Heap): Updated to use the new allocateBlock function. + + (JSC::Heap::destroy): Updated to use the new freeBlocks function. + + (JSC::Heap::allocateBlock): New function to initialize a block when + allocating it. + + (JSC::Heap::freeBlock): Consolidated the responsibility for running + destructors into this function. + + (JSC::Heap::freeBlocks): Updated to use freeBlock. + + (JSC::Heap::recordExtraCost): Sweep the heap in this reporting function, + so that allocation, which is more common, doesn't have to check extraCost. + + (JSC::Heap::heapAllocate): Run destructors right before recycling a + garbage cell. This has better cache utilization than a separate sweep phase. + + (JSC::Heap::resizeBlocks): + (JSC::Heap::growBlocks): + (JSC::Heap::shrinkBlocks): New set of functions for managing the size of + the heap, now that the heap doesn't maintain any information about its + size. + + (JSC::isPointerAligned): + (JSC::isHalfCellAligned): + (JSC::isPossibleCell): + (JSC::isCellAligned): + (JSC::Heap::markConservatively): Cleaned up this code a bit. + + (JSC::Heap::clearMarkBits): + (JSC::Heap::markedCells): Some helper functions for examining the the mark + bitmap. + + (JSC::Heap::sweep): Simplified this function by using a DeadObjectIterator. + + (JSC::Heap::markRoots): Reordered some operations for clarity. + + (JSC::Heap::objectCount): + (JSC::Heap::addToStatistics): + (JSC::Heap::statistics): Rewrote these functions to calculate an object + count on demand, since the heap doesn't maintain this information by + itself. + + (JSC::Heap::reset): New function for resetting the heap once we've + exhausted heap space. + + (JSC::Heap::collectAllGarbage): This function matches the old collect() + behavior, but it's now an uncommon function used only by API. + + * runtime/Collector.h: + (JSC::CollectorBitmap::count): + (JSC::CollectorBitmap::isEmpty): Added some helper functions for managing + the collector mark bitmap. + + (JSC::Heap::reportExtraMemoryCost): Changed reporting from cell equivalents + to bytes, so it's easier to understand. + + * runtime/CollectorHeapIterator.h: + (JSC::CollectorHeapIterator::CollectorHeapIterator): + (JSC::CollectorHeapIterator::operator!=): + (JSC::CollectorHeapIterator::operator*): + (JSC::CollectorHeapIterator::advance): + (JSC::::LiveObjectIterator): + (JSC::::operator): + (JSC::::DeadObjectIterator): + (JSC::::ObjectIterator): New iterators for encapsulating details about + heap layout, and what's live and dead on the heap. + + * runtime/JSArray.cpp: + (JSC::JSArray::putSlowCase): + (JSC::JSArray::increaseVectorLength): Delay reporting extra cost until + we're fully constructed, so the heap mark phase won't visit us in an + invalid state. + + * runtime/JSCell.h: + (JSC::JSCell::): + (JSC::JSCell::createDummyStructure): + (JSC::JSCell::JSCell): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: Added a dummy cell to simplify allocation logic. + + * runtime/JSString.h: + (JSC::jsSubstring): Don't report extra cost for substrings, since they + share a buffer that's already reported extra cost. + + * runtime/Tracing.d: + * runtime/Tracing.h: Changed these dtrace hooks not to report object + counts, since they're no longer cheap to compute. + + * runtime/UString.h: Updated for renames. + + * runtime/WeakGCMap.h: Added. + (JSC::WeakGCMap::isEmpty): + (JSC::WeakGCMap::uncheckedGet): + (JSC::WeakGCMap::uncheckedBegin): + (JSC::WeakGCMap::uncheckedEnd): + (JSC::::get): + (JSC::::take): + (JSC::::set): + (JSC::::uncheckedRemove): Mentioned above. + + * wtf/StdLibExtras.h: + (WTF::bitCount): Added a bit population count function, so the heap can + count live objects to fulfill statistics questions. + +The very last cell in the block is not allocated -- should not be marked. + +2009-12-13 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: Export some new symbols. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2009-12-13 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: Removed some old exports. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2009-12-13 Geoffrey Garen <ggaren@apple.com> + + Windows build fix: Use unsigned instead of uint32_t to avoid dependencies. + + * wtf/StdLibExtras.h: + (WTF::bitCount): + +2009-12-13 Gavin Barraclough <barraclough@apple.com> + + Reviewed by NOBODY (speculative Windows build fix). + + * runtime/JSGlobalObjectFunctions.cpp: + +2009-12-13 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Sam Weinig. + + https://bugs.webkit.org/show_bug.cgi?id=32496 + Switch remaining cases of string construction to use StringBuilder. + Builds strings using a vector rather than using string append / addition. + + * JavaScriptCore.exp: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/Executable.cpp: + (JSC::FunctionExecutable::paramString): + * runtime/FunctionConstructor.cpp: + (JSC::constructFunction): + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::encode): + (JSC::decode): + (JSC::globalFuncEscape): + (JSC::globalFuncUnescape): + * runtime/JSONObject.cpp: + (JSC::Stringifier::stringify): + (JSC::Stringifier::indent): + * runtime/JSString.h: + * runtime/LiteralParser.cpp: + (JSC::LiteralParser::Lexer::lexString): + * runtime/NumberPrototype.cpp: + (JSC::integerPartNoExp): + (JSC::numberProtoFuncToFixed): + (JSC::numberProtoFuncToPrecision): + * runtime/Operations.h: + (JSC::jsString): + * runtime/StringPrototype.cpp: + (JSC::substituteBackreferencesSlow): + (JSC::substituteBackreferences): + (JSC::stringProtoFuncConcat): + +2009-12-08 Jeremy Moskovich <jeremy@chromium.org> + + Reviewed by Eric Seidel. + + Add code to allow toggling ATSUI/Core Text rendering at runtime in ComplexTextController. + https://bugs.webkit.org/show_bug.cgi?id=31802 + + The goal here is to allow for a zero runtime hit for ports that decide to select + the API at compile time. + When both USE(ATSUI) and USE(CORE_TEXT) are true, the API is toggled + at runtime. Core Text is used for OS Versions >= 10.6. + + * wtf/Platform.h: #define USE_CORE_TEXT and USE_ATSUI on Chrome/Mac. + +2009-12-11 Maciej Stachowiak <mjs@apple.com> + + Reviewed by Oliver Hunt. + + Unify codegen for forward and backward variants of branches + https://bugs.webkit.org/show_bug.cgi?id=32463 + + * jit/JIT.h: + (JSC::JIT::emit_op_loop): Implemented in terms of forward variant. + (JSC::JIT::emit_op_loop_if_true): ditto + (JSC::JIT::emitSlow_op_loop_if_true): ditto + (JSC::JIT::emit_op_loop_if_false): ditto + (JSC::JIT::emitSlow_op_loop_if_false): ditto + (JSC::JIT::emit_op_loop_if_less): ditto + (JSC::JIT::emitSlow_op_loop_if_less): ditto + * jit/JITOpcodes.cpp: + +2009-12-11 Sam Weinig <sam@webkit.org> + + Reviewed by Anders Carlsson. + + Allow WTFs concept of the main thread to differ from pthreads when necessary. + + * wtf/ThreadingPthreads.cpp: + (WTF::initializeThreading): + (WTF::isMainThread): + * wtf/mac/MainThreadMac.mm: + (WTF::initializeMainThreadPlatform): + (WTF::scheduleDispatchFunctionsOnMainThread): + +2009-12-11 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=32454 + Refactor construction of simple strings to avoid string concatenation. + + Building strings through concatenation has a memory and performance cost - + a memory cost since we must over-allocate the buffer to leave space to append + into, and performance in that the string may still require reallocation (and + thus copying during construction). Instead move the full construction to + within a single function call (makeString), so that the arguments' lengths + can be calculated and an appropriate sized buffer allocated before copying + any characters. + + ~No performance change (~2% progression on date tests). + + * bytecode/CodeBlock.cpp: + (JSC::escapeQuotes): + (JSC::valueToSourceString): + (JSC::constantName): + (JSC::idName): + (JSC::CodeBlock::registerName): + (JSC::regexpToSourceString): + (JSC::regexpName): + * bytecompiler/NodesCodegen.cpp: + (JSC::substitute): + * profiler/Profiler.cpp: + (JSC::Profiler::createCallIdentifier): + * runtime/DateConstructor.cpp: + (JSC::callDate): + * runtime/DateConversion.cpp: + (JSC::formatDate): + (JSC::formatDateUTCVariant): + (JSC::formatTime): + (JSC::formatTimeUTC): + * runtime/DateConversion.h: + (JSC::): + * runtime/DatePrototype.cpp: + (JSC::dateProtoFuncToString): + (JSC::dateProtoFuncToUTCString): + (JSC::dateProtoFuncToDateString): + (JSC::dateProtoFuncToTimeString): + (JSC::dateProtoFuncToGMTString): + * runtime/ErrorPrototype.cpp: + (JSC::errorProtoFuncToString): + * runtime/ExceptionHelpers.cpp: + (JSC::createUndefinedVariableError): + (JSC::createErrorMessage): + (JSC::createInvalidParamError): + * runtime/FunctionPrototype.cpp: + (JSC::insertSemicolonIfNeeded): + (JSC::functionProtoFuncToString): + * runtime/ObjectPrototype.cpp: + (JSC::objectProtoFuncToString): + * runtime/RegExpConstructor.cpp: + (JSC::constructRegExp): + * runtime/RegExpObject.cpp: + (JSC::RegExpObject::match): + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncCompile): + (JSC::regExpProtoFuncToString): + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncBig): + (JSC::stringProtoFuncSmall): + (JSC::stringProtoFuncBlink): + (JSC::stringProtoFuncBold): + (JSC::stringProtoFuncFixed): + (JSC::stringProtoFuncItalics): + (JSC::stringProtoFuncStrike): + (JSC::stringProtoFuncSub): + (JSC::stringProtoFuncSup): + (JSC::stringProtoFuncFontcolor): + (JSC::stringProtoFuncFontsize): + (JSC::stringProtoFuncAnchor): + * runtime/UString.h: + (JSC::): + (JSC::makeString): + +2009-12-10 Gavin Barraclough <barraclough@apple.com> + + Reviewed by Oliver Hunt. + + https://bugs.webkit.org/show_bug.cgi?id=32400 + Switch remaining cases of string addition to use ropes. + + Re-landing r51975 - added toPrimitiveString method, + performs toPrimitive then subsequent toString operations. + + ~1% progression on Sunspidey. + + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/JSString.h: + (JSC::JSString::JSString): + (JSC::JSString::appendStringInConstruct): + * runtime/Operations.cpp: + (JSC::jsAddSlowCase): + * runtime/Operations.h: + (JSC::jsString): + (JSC::jsAdd): + +2009-12-11 Adam Roben <aroben@apple.com> + + Windows build fix + + * JavaScriptCore.vcproj/jsc/jscCommon.vsprops: Added + $(WebKitOutputDir)/include/private to the include path. + +2009-12-11 Adam Roben <aroben@apple.com> + + Move QuartzCorePresent.h to include/private + + This fixes other projects that use wtf/Platform.h + + Rubber-stamped by Steve Falkenburg. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Let VS do its thang. + * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh: Write + QuartzCorePresent.h to $(WebKitOutputDir)/include/private. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops: + * JavaScriptCore.vcproj/WTF/WTFCommon.vsprops: + Added $(WebKitOutputDir)/include/private to the include path. + +2009-12-11 Adam Roben <aroben@apple.com> + + Fix clean builds and everything rebuilding on every build + + Reviewed by Sam Weinig. + + * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh: Don't + write out QuartzCorePresent.h if it exists but is older than + QuartzCore.h. Also, create the directory we write QuartzCorePresent.h + into first. + +2009-12-11 Adam Roben <aroben@apple.com> + + Windows build fix for systems with spaces in their paths + + * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh: Quote some paths. + +2009-12-11 Chris Marrin <cmarrin@apple.com> + + Reviewed by Adam Roben. + + Add check for presence of QuartzCore headers + https://bugs.webkit.org/show_bug.cgi?id=31856 + + The script now checks for the presence of QuartzCore.h. If present + it will turn on ACCELERATED_COMPOSITING and 3D_RENDERING to enable + HW compositing on Windows. The script writes QuartzCorePresent.h to + the build directory which has a define telling whether QuartzCore is + present. + + * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh: + * wtf/Platform.h: + +2009-12-11 Kent Tamura <tkent@chromium.org> + + Reviewed by Darin Adler. + + Fix a problem that JSC::gregorianDateTimeToMS() returns a negative + value for a huge year value. + https://bugs.webkit.org/show_bug.cgi?id=32304 + + * wtf/DateMath.cpp: + (WTF::dateToDaysFrom1970): Renamed from dateToDayInYear, and changed the return type to double. + (WTF::calculateDSTOffset): Follow the dateToDaysFrom1970() change. + (WTF::timeClip): Use maxECMAScriptTime. + (JSC::gregorianDateTimeToMS): Follow the dateToDaysFrom1970() change. + +>>>>>>> webkit.org at r54127 2009-12-10 Adam Barth <abarth@webkit.org> No review, rolling out r51975. diff --git a/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/JavaScriptCore/Configurations/FeatureDefines.xcconfig index cd462d6..24589c7 100644 --- a/JavaScriptCore/Configurations/FeatureDefines.xcconfig +++ b/JavaScriptCore/Configurations/FeatureDefines.xcconfig @@ -26,6 +26,9 @@ // WebCore and WebKit. Also the default values of the ENABLE_FEATURE_NAME macros in build-webkit // should match the values below, but they do not need to be in the same order. +// Keep this list of features (not enabled/disabled state) in sync with FeatureDefines.vsprops +// and FeatureDefinesCairo.vsprops in WebKitLibraries/win/tools/vsprops. + // Set any ENABLE_FEATURE_NAME macro to an empty string to disable that feature. ENABLE_3D_CANVAS = $(ENABLE_3D_CANVAS_$(MAC_OS_X_VERSION_MAJOR)); @@ -39,14 +42,16 @@ ENABLE_3D_RENDERING_1060 = ENABLE_3D_RENDERING; ENABLE_3D_RENDERING_1070 = ENABLE_3D_RENDERING; ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING; +ENABLE_CLIENT_BASED_GEOLOCATION = ENABLE_CLIENT_BASED_GEOLOCATION; ENABLE_DATABASE = ENABLE_DATABASE; -ENABLE_DATAGRID = ENABLE_DATAGRID; +ENABLE_DATAGRID = ; ENABLE_DATALIST = ENABLE_DATALIST; ENABLE_DOM_STORAGE = ENABLE_DOM_STORAGE; ENABLE_EVENTSOURCE = ENABLE_EVENTSOURCE; ENABLE_FILTERS = ENABLE_FILTERS; -ENABLE_GEOLOCATION = ; +ENABLE_GEOLOCATION = ENABLE_GEOLOCATION; ENABLE_ICONDATABASE = ENABLE_ICONDATABASE; +ENABLE_INDEXED_DATABASE = ; ENABLE_JAVASCRIPT_DEBUGGER = ENABLE_JAVASCRIPT_DEBUGGER; ENABLE_MATHML = ; ENABLE_NOTIFICATIONS = ; @@ -63,7 +68,8 @@ ENABLE_VIDEO = ENABLE_VIDEO; ENABLE_WEB_SOCKETS = ENABLE_WEB_SOCKETS; ENABLE_WML = ; ENABLE_WORKERS = ENABLE_WORKERS; +ENABLE_XHTMLMP = ; ENABLE_XPATH = ENABLE_XPATH; ENABLE_XSLT = ENABLE_XSLT; -FEATURE_DEFINES = $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XPATH) $(ENABLE_XSLT); +FEATURE_DEFINES = $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT); diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig index b3bf41d..75f9bd4 100644 --- a/JavaScriptCore/Configurations/Version.xcconfig +++ b/JavaScriptCore/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 532; -MINOR_VERSION = 6; +MINOR_VERSION = 9; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/JavaScriptCore/DerivedSources.pro b/JavaScriptCore/DerivedSources.pro new file mode 100644 index 0000000..bd9f6ab --- /dev/null +++ b/JavaScriptCore/DerivedSources.pro @@ -0,0 +1,95 @@ +# DerivedSources - qmake build info + +CONFIG -= debug_and_release + +TEMPLATE = lib +TARGET = dummy + +QMAKE_EXTRA_TARGETS += generated_files + +CONFIG(standalone_package) { + isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = $$PWD/generated +} else { + isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = generated +} + +LUT_FILES += \ + runtime/ArrayPrototype.cpp \ + runtime/DatePrototype.cpp \ + runtime/JSONObject.cpp \ + runtime/MathObject.cpp \ + runtime/NumberConstructor.cpp \ + runtime/RegExpConstructor.cpp \ + runtime/RegExpObject.cpp \ + runtime/StringPrototype.cpp + +KEYWORDLUT_FILES += \ + parser/Keywords.table + +JSCBISON += \ + parser/Grammar.y + +RVCT_STUB_FILES += \ + jit/JITStubs.cpp + +defineTest(addExtraCompiler) { + eval($${1}.CONFIG = target_predeps no_link) + eval($${1}.variable_out =) + eval($${1}.dependency_type = TYPE_C) + + wkScript = $$eval($${1}.wkScript) + eval($${1}.depends += $$wkScript) + + export($${1}.CONFIG) + export($${1}.variable_out) + export($${1}.dependency_type) + export($${1}.depends) + + QMAKE_EXTRA_COMPILERS += $$1 + generated_files.depends += compiler_$${1}_make_all + export(QMAKE_EXTRA_COMPILERS) + export(generated_files.depends) + return(true) +} + +# GENERATOR 1-A: LUT creator +lut.output = $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.lut.h +lut.input = LUT_FILES +lut.wkScript = $$PWD/create_hash_table +lut.commands = perl $$lut.wkScript ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT} +lut.depends = ${QMAKE_FILE_NAME} +addExtraCompiler(lut) + +# GENERATOR 1-B: particular LUT creator (for 1 file only) +keywordlut.output = $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}Lexer.lut.h +keywordlut.input = KEYWORDLUT_FILES +keywordlut.wkScript = $$PWD/create_hash_table +keywordlut.commands = perl $$keywordlut.wkScript ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT} +keywordlut.depends = ${QMAKE_FILE_NAME} +addExtraCompiler(keywordlut) + +# GENERATOR 2: bison grammar +jscbison.output = $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.cpp +jscbison.input = JSCBISON +jscbison.commands = bison -d -p jscyy ${QMAKE_FILE_NAME} -o $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.c && $(MOVE) $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.c ${QMAKE_FILE_OUT} && $(MOVE) $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.h $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.h +jscbison.depends = ${QMAKE_FILE_NAME} +addExtraCompiler(jscbison) + +# GENERATOR 3: JIT Stub functions for RVCT +rvctstubs.output = $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}Generated${QMAKE_FILE_BASE}_RVCT.h +rvctstubs.wkScript = $$PWD/create_rvct_stubs +rvctstubs.commands = perl $$rvctstubs.wkScript ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT} +rvctstubs.depends = ${QMAKE_FILE_NAME} +rvctstubs.input = RVCT_STUB_FILES +rvctstubs.CONFIG += no_link +addExtraCompiler(rvctstubs) + +# GENERATOR: "chartables.c": compile and execute the chartables generator (and add it to sources) +win32-msvc*|wince*: PREPROCESSOR = "--preprocessor=\"$$QMAKE_CC /E\"" +ctgen.output = $$JSC_GENERATED_SOURCES_DIR/chartables.c +ctgen.wkScript = $$PWD/pcre/dftables +ctgen.input = ctgen.wkScript +ctgen.commands = perl $$ctgen.wkScript ${QMAKE_FILE_OUT} $$PREPROCESSOR +ctgen.clean = ${QMAKE_FILE_OUT} ${QMAKE_VAR_JSC_GENERATED_SOURCES_DIR}${QMAKE_FILE_BASE} +addExtraCompiler(ctgen) + diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am index dba305a..7ac6a8c 100644 --- a/JavaScriptCore/GNUmakefile.am +++ b/JavaScriptCore/GNUmakefile.am @@ -45,6 +45,7 @@ javascriptcore_built_nosources += \ javascriptcore_sources += \ JavaScriptCore/API/APICast.h \ + JavaScriptCore/API/APIShims.h \ JavaScriptCore/API/JSBase.cpp \ JavaScriptCore/API/JSBasePrivate.h \ JavaScriptCore/API/JSCallbackConstructor.cpp \ @@ -161,8 +162,6 @@ javascriptcore_sources += \ JavaScriptCore/pcre/pcre_xclass.cpp \ JavaScriptCore/pcre/ucpinternal.h \ JavaScriptCore/profiler/CallIdentifier.h \ - JavaScriptCore/profiler/HeavyProfile.cpp \ - JavaScriptCore/profiler/HeavyProfile.h \ JavaScriptCore/profiler/Profile.cpp \ JavaScriptCore/profiler/Profile.h \ JavaScriptCore/profiler/ProfileGenerator.cpp \ @@ -171,8 +170,6 @@ javascriptcore_sources += \ JavaScriptCore/profiler/ProfileNode.h \ JavaScriptCore/profiler/Profiler.cpp \ JavaScriptCore/profiler/Profiler.h \ - JavaScriptCore/profiler/TreeProfile.cpp \ - JavaScriptCore/profiler/TreeProfile.h \ JavaScriptCore/interpreter/CachedCall.h \ JavaScriptCore/interpreter/CallFrame.cpp \ JavaScriptCore/interpreter/CallFrame.h \ @@ -195,6 +192,7 @@ javascriptcore_sources += \ JavaScriptCore/runtime/JSONObject.h \ JavaScriptCore/runtime/JSPropertyNameIterator.cpp \ JavaScriptCore/runtime/JSPropertyNameIterator.h \ + JavaScriptCore/runtime/JSZombie.h \ JavaScriptCore/runtime/LiteralParser.cpp \ JavaScriptCore/runtime/LiteralParser.h \ JavaScriptCore/runtime/MarkStack.cpp \ @@ -204,6 +202,7 @@ javascriptcore_sources += \ JavaScriptCore/runtime/PropertyDescriptor.cpp \ JavaScriptCore/runtime/SmallStrings.cpp \ JavaScriptCore/runtime/SmallStrings.h \ + JavaScriptCore/runtime/StringBuilder.h \ JavaScriptCore/runtime/Structure.cpp \ JavaScriptCore/runtime/Structure.h \ JavaScriptCore/runtime/StructureChain.cpp \ @@ -212,6 +211,8 @@ javascriptcore_sources += \ JavaScriptCore/runtime/TimeoutChecker.cpp \ JavaScriptCore/runtime/TimeoutChecker.h \ JavaScriptCore/runtime/JSTypeInfo.h \ + JavaScriptCore/runtime/WeakGCMap.h \ + JavaScriptCore/runtime/WeakGCPtr.h \ JavaScriptCore/wrec/CharacterClass.h \ JavaScriptCore/wrec/CharacterClassConstructor.h \ JavaScriptCore/wrec/Escapes.h \ @@ -228,7 +229,6 @@ javascriptcore_sources += \ JavaScriptCore/wtf/ByteArray.cpp \ JavaScriptCore/wtf/ByteArray.h \ JavaScriptCore/wtf/CrossThreadRefCounted.h \ - JavaScriptCore/wtf/OwnFastMallocPtr.h \ JavaScriptCore/wtf/CurrentTime.cpp \ JavaScriptCore/wtf/CurrentTime.h \ JavaScriptCore/wtf/DateMath.cpp \ @@ -255,6 +255,7 @@ javascriptcore_sources += \ JavaScriptCore/wtf/Noncopyable.h \ JavaScriptCore/wtf/NotFound.h \ JavaScriptCore/wtf/OwnArrayPtr.h \ + JavaScriptCore/wtf/OwnFastMallocPtr.h \ JavaScriptCore/wtf/OwnPtr.h \ JavaScriptCore/wtf/OwnPtrCommon.h \ JavaScriptCore/wtf/PassOwnPtr.h \ @@ -274,13 +275,16 @@ javascriptcore_sources += \ JavaScriptCore/wtf/SegmentedVector.h \ JavaScriptCore/wtf/StdLibExtras.h \ JavaScriptCore/wtf/StringExtras.h \ + JavaScriptCore/wtf/StringHashFunctions.h \ JavaScriptCore/wtf/TCPackedCache.h \ JavaScriptCore/wtf/TCPageMap.h \ JavaScriptCore/wtf/TCSpinLock.h \ - JavaScriptCore/wtf/ThreadSpecific.h \ - JavaScriptCore/wtf/Threading.h \ + JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp \ + JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h \ JavaScriptCore/wtf/Threading.cpp \ + JavaScriptCore/wtf/Threading.h \ JavaScriptCore/wtf/ThreadingPthreads.cpp \ + JavaScriptCore/wtf/ThreadSpecific.h \ JavaScriptCore/wtf/TypeTraits.cpp \ JavaScriptCore/wtf/TypeTraits.h \ JavaScriptCore/wtf/UnusedParam.h \ @@ -288,6 +292,8 @@ javascriptcore_sources += \ JavaScriptCore/wtf/VectorTraits.h \ JavaScriptCore/wtf/gtk/GOwnPtr.cpp \ JavaScriptCore/wtf/gtk/GOwnPtr.h \ + JavaScriptCore/wtf/gtk/GRefPtr.cpp \ + JavaScriptCore/wtf/gtk/GRefPtr.h \ JavaScriptCore/wtf/gtk/MainThreadGtk.cpp \ JavaScriptCore/wtf/gtk/ThreadingGtk.cpp \ JavaScriptCore/wtf/unicode/Collator.h \ @@ -499,6 +505,8 @@ javascriptcore_sources += \ JavaScriptCore/runtime/Tracing.h \ JavaScriptCore/runtime/UString.cpp \ JavaScriptCore/runtime/UString.h \ + JavaScriptCore/runtime/UStringImpl.cpp \ + JavaScriptCore/runtime/UStringImpl.h \ JavaScriptCore/runtime/WeakRandom.h \ JavaScriptCore/wtf/FastAllocBase.h \ JavaScriptCore/wtf/FastMalloc.cpp \ diff --git a/JavaScriptCore/Info.plist b/JavaScriptCore/Info.plist index 17949b0..77c9eb8 100644 --- a/JavaScriptCore/Info.plist +++ b/JavaScriptCore/Info.plist @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> @@ -7,7 +7,7 @@ <key>CFBundleExecutable</key> <string>${PRODUCT_NAME}</string> <key>CFBundleGetInfoString</key> - <string>${BUNDLE_VERSION}, Copyright 2003-2009 Apple Inc.; Copyright 1999-2001 Harri Porten <porten@kde.org>; Copyright 2001 Peter Kelly <pmk@post.com>; Copyright 1997-2005 University of Cambridge; Copyright 1991, 2000, 2001 by Lucent Technologies.</string> + <string>${BUNDLE_VERSION}, Copyright 2003-2010 Apple Inc.; Copyright 1999-2001 Harri Porten <porten@kde.org>; Copyright 2001 Peter Kelly <pmk@post.com>; Copyright 1997-2005 University of Cambridge; Copyright 1991, 2000, 2001 by Lucent Technologies.</string> <key>CFBundleIdentifier</key> <string>com.apple.${PRODUCT_NAME}</string> <key>CFBundleInfoDictionaryVersion</key> diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp index 1c91d36..3821992 100644 --- a/JavaScriptCore/JavaScriptCore.exp +++ b/JavaScriptCore/JavaScriptCore.exp @@ -90,12 +90,12 @@ __Z12jsRegExpFreeP8JSRegExp __Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc __Z15jsRegExpExecutePK8JSRegExpPKtiiPii __ZN14OpaqueJSString6createERKN3JSC7UStringE -__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPNS_7UString3RepE -__ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPNS_7UString3RepE -__ZN3JSC10Identifier24checkSameIdentifierTableEPNS_12JSGlobalDataEPNS_7UString3RepE -__ZN3JSC10Identifier24checkSameIdentifierTableEPNS_9ExecStateEPNS_7UString3RepE +__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPNS_11UStringImplE +__ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPNS_11UStringImplE +__ZN3JSC10Identifier24checkSameIdentifierTableEPNS_12JSGlobalDataEPNS_11UStringImplE +__ZN3JSC10Identifier24checkSameIdentifierTableEPNS_9ExecStateEPNS_11UStringImplE __ZN3JSC10Identifier3addEPNS_9ExecStateEPKc -__ZN3JSC10Identifier5equalEPKNS_7UString3RepEPKc +__ZN3JSC10Identifier5equalEPKNS_11UStringImplEPKc __ZN3JSC10JSFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc @@ -103,17 +103,24 @@ __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringE __ZN3JSC11JSByteArray15createStructureENS_7JSValueE __ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE __ZN3JSC11ParserArena5resetEv +__ZN3JSC11UStringImpl12sharedBufferEv +__ZN3JSC11UStringImpl6s_nullE +__ZN3JSC11UStringImpl7s_emptyE +__ZN3JSC11UStringImplD1Ev __ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE __ZN3JSC12DateInstance4infoE +__ZN3JSC12DateInstanceC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEd __ZN3JSC12DateInstanceC1EPNS_9ExecStateEd __ZN3JSC12JSGlobalData10ClientDataD2Ev +__ZN3JSC12JSGlobalData11jsArrayVPtrE __ZN3JSC12JSGlobalData12createLeakedEv +__ZN3JSC12JSGlobalData12jsStringVPtrE __ZN3JSC12JSGlobalData12stopSamplingEv __ZN3JSC12JSGlobalData13startSamplingEv __ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE __ZN3JSC12JSGlobalData14resetDateCacheEv __ZN3JSC12JSGlobalData14sharedInstanceEv -__ZN3JSC12JSGlobalData6createEb +__ZN3JSC12JSGlobalData6createEv __ZN3JSC12JSGlobalDataD1Ev __ZN3JSC12SamplingTool5setupEv __ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE @@ -121,7 +128,7 @@ __ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh __ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE -__ZN3JSC12StringObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE +__ZN3JSC12StringObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE __ZN3JSC12StringObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE __ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE __ZN3JSC12StringObject4infoE @@ -154,10 +161,10 @@ __ZN3JSC16InternalFunction4nameEPNS_9ExecStateE __ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_10IdentifierE __ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE __ZN3JSC16JSVariableObject14symbolTableGetERKNS_10IdentifierERNS_18PropertyDescriptorE -__ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE +__ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE __ZN3JSC16toUInt32SlowCaseEdRb __ZN3JSC17BytecodeGenerator21setDumpsGeneratedCodeEb -__ZN3JSC17PropertyNameArray3addEPNS_7UString3RepE +__ZN3JSC17PropertyNameArray3addEPNS_11UStringImplE __ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE __ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectES6_RKNS_7ArgListEE __ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi @@ -178,24 +185,25 @@ __ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_ __ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE __ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE __ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE +__ZN3JSC25g_identifierTableSpecificE +__ZN3JSC29createIdentifierTableSpecificEv __ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE __ZN3JSC3NaNE -__ZN3JSC4Heap11objectCountEv __ZN3JSC4Heap14primaryHeapEndEv __ZN3JSC4Heap15recordExtraCostEm __ZN3JSC4Heap16primaryHeapBeginEv +__ZN3JSC4Heap17collectAllGarbageEv __ZN3JSC4Heap17globalObjectCountEv __ZN3JSC4Heap20protectedObjectCountEv __ZN3JSC4Heap25protectedObjectTypeCountsEv __ZN3JSC4Heap26protectedGlobalObjectCountEv __ZN3JSC4Heap6isBusyEv -__ZN3JSC4Heap7collectEv __ZN3JSC4Heap7destroyEv __ZN3JSC4Heap7protectENS_7JSValueE __ZN3JSC4Heap8allocateEm __ZN3JSC4Heap9unprotectENS_7JSValueE __ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE -__ZN3JSC5equalEPKNS_7UString3RepES3_ +__ZN3JSC5equalEPKNS_11UStringImplES2_ __ZN3JSC6JSCell11getCallDataERNS_8CallDataE __ZN3JSC6JSCell11getJSNumberEv __ZN3JSC6JSCell14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE @@ -208,7 +216,6 @@ __ZN3JSC6JSCell18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE __ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE __ZN3JSC6JSCell3putEPNS_9ExecStateEjNS_7JSValueE __ZN3JSC6JSCell9getObjectEv -__ZN3JSC6JSCellnwEmPNS_9ExecStateE __ZN3JSC6JSLock12DropAllLocksC1ENS_14JSLockBehaviorE __ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE __ZN3JSC6JSLock12DropAllLocksD1Ev @@ -227,19 +234,10 @@ __ZN3JSC7Profile10restoreAllEv __ZN3JSC7Profile5focusEPKNS_11ProfileNodeE __ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE __ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE -__ZN3JSC7UString3Rep11computeHashEPKci -__ZN3JSC7UString3Rep11computeHashEPKti -__ZN3JSC7UString3Rep12sharedBufferEv -__ZN3JSC7UString3Rep14createFromUTF8EPKc -__ZN3JSC7UString3Rep14nullBaseStringE -__ZN3JSC7UString3Rep6createEPtiN3WTF10PassRefPtrINS3_21CrossThreadRefCountedINS3_16OwnFastMallocPtrItEEEEEE -__ZN3JSC7UString3Rep7destroyEv __ZN3JSC7UString4fromEd __ZN3JSC7UString4fromEi __ZN3JSC7UString4fromEj __ZN3JSC7UString4fromEl -__ZN3JSC7UString6appendEPKc -__ZN3JSC7UString6appendERKS0_ __ZN3JSC7UStringC1EPKc __ZN3JSC7UStringC1EPKti __ZN3JSC7UStringaSEPKc @@ -256,7 +254,7 @@ __ZN3JSC8JSObject12markChildrenERNS_9MarkStackE __ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE __ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj __ZN3JSC8JSObject15unwrappedObjectEv -__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE +__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE __ZN3JSC8JSObject17createInheritorIDEv __ZN3JSC8JSObject17defineOwnPropertyEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorEb __ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj @@ -265,7 +263,7 @@ __ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValu __ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateEjNS_7JSValueEj __ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE __ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE -__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE +__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE __ZN3JSC8JSObject21getPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE __ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_7JSValueE __ZN3JSC8JSObject23allocatePropertyStorageEmm @@ -283,17 +281,16 @@ __ZN3JSC9MarkStack10s_pageSizeE __ZN3JSC9MarkStack12releaseStackEPvm __ZN3JSC9MarkStack13allocateStackEm __ZN3JSC9MarkStack18initializePagesizeEv -__ZN3JSC9Structure13hasTransitionEPNS_7UString3RepEj +__ZN3JSC9Structure13hasTransitionEPNS_11UStringImplEj __ZN3JSC9Structure17stopIgnoringLeaksEv __ZN3JSC9Structure18startIgnoringLeaksEv __ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjPNS_6JSCellERm __ZN3JSC9Structure22materializePropertyMapEv __ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_7JSValueE -__ZN3JSC9Structure27addAnonymousSlotsTransitionEPS0_j __ZN3JSC9Structure27despecifyDictionaryFunctionERKNS_10IdentifierE __ZN3JSC9Structure27despecifyFunctionTransitionEPS0_RKNS_10IdentifierE __ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEjPNS_6JSCellE -__ZN3JSC9Structure3getEPKNS_7UString3RepERjRPNS_6JSCellE +__ZN3JSC9Structure3getEPKNS_11UStringImplERjRPNS_6JSCellE __ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm __ZN3JSC9StructureC1ENS_7JSValueERKNS_8TypeInfoE __ZN3JSC9StructureD1Ev @@ -321,6 +318,8 @@ __ZN3WTF15ThreadConditionC1Ev __ZN3WTF15ThreadConditionD1Ev __ZN3WTF16callOnMainThreadEPFvPvES0_ __ZN3WTF16fastZeroedMallocEm +__ZN3WTF18dateToDaysFrom1970Eiii +__ZN3WTF18monthFromDayInYearEib __ZN3WTF19initializeThreadingEv __ZN3WTF20fastMallocStatisticsEv __ZN3WTF21RefCountedLeakCounter16suppressMessagesEPKc @@ -330,6 +329,7 @@ __ZN3WTF21RefCountedLeakCounter9incrementEv __ZN3WTF21RefCountedLeakCounterC1EPKc __ZN3WTF21RefCountedLeakCounterD1Ev __ZN3WTF23callOnMainThreadAndWaitEPFvPvES0_ +__ZN3WTF23dayInMonthFromDayInYearEib __ZN3WTF23waitForThreadCompletionEjPPv __ZN3WTF27releaseFastMallocFreeMemoryEv __ZN3WTF28setMainThreadCallbacksPausedEb @@ -348,10 +348,12 @@ __ZN3WTF8Collator18setOrderLowerFirstEb __ZN3WTF8CollatorC1EPKc __ZN3WTF8CollatorD1Ev __ZN3WTF8fastFreeEPv +__ZN3WTF8msToYearEd +__ZN3WTF9dayInYearEdi __ZN3WTF9ByteArray6createEm __ZNK3JSC10JSFunction23isHostFunctionNonInlineEv __ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE -__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE +__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE __ZNK3JSC14JSGlobalObject14isDynamicScopeEv __ZNK3JSC16InternalFunction9classInfoEv __ZNK3JSC16JSVariableObject16isVariableObjectEv @@ -368,6 +370,7 @@ __ZNK3JSC18PropertyDescriptor6getterEv __ZNK3JSC18PropertyDescriptor6setterEv __ZNK3JSC18PropertyDescriptor8writableEv __ZNK3JSC4Heap10statisticsEv +__ZNK3JSC4Heap11objectCountEv __ZNK3JSC6JSCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE __ZNK3JSC6JSCell12toThisObjectEPNS_9ExecStateE __ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE @@ -376,9 +379,9 @@ __ZNK3JSC6JSCell8toNumberEPNS_9ExecStateE __ZNK3JSC6JSCell8toObjectEPNS_9ExecStateE __ZNK3JSC6JSCell8toStringEPNS_9ExecStateE __ZNK3JSC6JSCell9classInfoEv -__ZNK3JSC6JSCell9getUInt32ERj __ZNK3JSC6JSCell9getStringEPNS_9ExecStateE __ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE +__ZNK3JSC6JSCell9getUInt32ERj __ZNK3JSC6JSCell9toBooleanEPNS_9ExecStateE __ZNK3JSC7ArgList8getSliceEiRS0_ __ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE diff --git a/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp b/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp index 64e20a2..66f40e9 100644 --- a/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp +++ b/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp @@ -134,6 +134,7 @@ 'conditions': [ ['OS=="win"', { 'sources/': [ + ['exclude', 'ThreadIdentifierDataPthreads\\.(h|cpp)$'], ['exclude', 'ThreadingPthreads\\.cpp$'], ['include', 'Thread(ing|Specific)Win\\.cpp$'] ], diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi index b4495b2..24577da 100644 --- a/JavaScriptCore/JavaScriptCore.gypi +++ b/JavaScriptCore/JavaScriptCore.gypi @@ -149,8 +149,6 @@ 'pcre/ucpinternal.h', 'pcre/ucptable.cpp', 'profiler/CallIdentifier.h', - 'profiler/HeavyProfile.cpp', - 'profiler/HeavyProfile.h', 'profiler/Profile.cpp', 'profiler/Profile.h', 'profiler/ProfileGenerator.cpp', @@ -160,8 +158,6 @@ 'profiler/Profiler.cpp', 'profiler/Profiler.h', 'profiler/ProfilerServer.h', - 'profiler/TreeProfile.cpp', - 'profiler/TreeProfile.h', 'runtime/ArgList.cpp', 'runtime/ArgList.h', 'runtime/Arguments.cpp', @@ -402,8 +398,6 @@ 'wtf/PassRefPtr.h', 'wtf/Platform.h', 'wtf/PtrAndFlags.h', - 'wtf/qt/MainThreadQt.cpp', - 'wtf/qt/ThreadingQt.cpp', 'wtf/RandomNumber.cpp', 'wtf/RandomNumber.h', 'wtf/RandomNumberSeed.h', @@ -416,11 +410,16 @@ 'wtf/SegmentedVector.h', 'wtf/StdLibExtras.h', 'wtf/StringExtras.h', + 'wtf/StringHashFunctions.h', 'wtf/TCPackedCache.h', + 'wtf/qt/MainThreadQt.cpp', + 'wtf/qt/ThreadingQt.cpp', 'wtf/TCPageMap.h', 'wtf/TCSpinLock.h', 'wtf/TCSystemAlloc.cpp', 'wtf/TCSystemAlloc.h', + 'wtf/ThreadIdentifierDataPthreads.cpp', + 'wtf/ThreadIdentifierDataPthreads.h', 'wtf/Threading.cpp', 'wtf/Threading.h', 'wtf/ThreadingNone.cpp', diff --git a/JavaScriptCore/JavaScriptCore.pri b/JavaScriptCore/JavaScriptCore.pri index aecf01c..75737ae 100644 --- a/JavaScriptCore/JavaScriptCore.pri +++ b/JavaScriptCore/JavaScriptCore.pri @@ -1,11 +1,15 @@ # JavaScriptCore - Qt4 build info VPATH += $$PWD +CONFIG(standalone_package) { + isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = $$PWD/generated +} else { + isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = generated +} + CONFIG(debug, debug|release) { - isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = generated$${QMAKE_DIR_SEP}debug OBJECTS_DIR = obj/debug } else { # Release - isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = generated$${QMAKE_DIR_SEP}release OBJECTS_DIR = obj/release } @@ -24,6 +28,7 @@ INCLUDEPATH = \ $$PWD/interpreter \ $$PWD/jit \ $$PWD/parser \ + $$PWD/pcre \ $$PWD/profiler \ $$PWD/runtime \ $$PWD/wrec \ @@ -32,12 +37,11 @@ INCLUDEPATH = \ $$PWD/yarr \ $$PWD/API \ $$PWD/ForwardingHeaders \ - $$GENERATED_SOURCES_DIR \ + $$JSC_GENERATED_SOURCES_DIR \ $$INCLUDEPATH DEFINES += BUILDING_QT__ BUILDING_JavaScriptCore BUILDING_WTF -GENERATED_SOURCES_DIR_SLASH = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP} win32-* { LIBS += -lwinmm } @@ -52,11 +56,6 @@ contains(JAVASCRIPTCORE_JIT,no) { DEFINES+=ENABLE_YARR=0 } -# In debug mode JIT disabled until crash fixed -win32-* { - CONFIG(debug):!contains(DEFINES, ENABLE_JIT=1): DEFINES+=ENABLE_JIT=0 -} - # Rules when JIT enabled (not disabled) !contains(DEFINES, ENABLE_JIT=0) { linux*-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,0) { @@ -73,22 +72,6 @@ wince* { include(pcre/pcre.pri) -LUT_FILES += \ - runtime/ArrayPrototype.cpp \ - runtime/DatePrototype.cpp \ - runtime/JSONObject.cpp \ - runtime/MathObject.cpp \ - runtime/NumberConstructor.cpp \ - runtime/RegExpConstructor.cpp \ - runtime/RegExpObject.cpp \ - runtime/StringPrototype.cpp - -KEYWORDLUT_FILES += \ - parser/Keywords.table - -JSCBISON += \ - parser/Grammar.y - SOURCES += \ API/JSBase.cpp \ API/JSCallbackConstructor.cpp \ @@ -115,6 +98,9 @@ SOURCES += \ interpreter/CallFrame.cpp \ interpreter/Interpreter.cpp \ interpreter/RegisterFile.cpp \ + jit/ExecutableAllocatorPosix.cpp \ + jit/ExecutableAllocatorSymbian.cpp \ + jit/ExecutableAllocatorWin.cpp \ jit/ExecutableAllocator.cpp \ jit/JITArithmetic.cpp \ jit/JITCall.cpp \ @@ -126,12 +112,10 @@ SOURCES += \ parser/Nodes.cpp \ parser/ParserArena.cpp \ parser/Parser.cpp \ - profiler/HeavyProfile.cpp \ profiler/Profile.cpp \ profiler/ProfileGenerator.cpp \ profiler/ProfileNode.cpp \ profiler/Profiler.cpp \ - profiler/TreeProfile.cpp \ runtime/ArgList.cpp \ runtime/Arguments.cpp \ runtime/ArrayConstructor.cpp \ @@ -184,6 +168,9 @@ SOURCES += \ runtime/JSWrapperObject.cpp \ runtime/LiteralParser.cpp \ runtime/Lookup.cpp \ + runtime/MarkStackPosix.cpp \ + runtime/MarkStackSymbian.cpp \ + runtime/MarkStackWin.cpp \ runtime/MarkStack.cpp \ runtime/MathObject.cpp \ runtime/NativeErrorConstructor.cpp \ @@ -211,6 +198,7 @@ SOURCES += \ runtime/Structure.cpp \ runtime/TimeoutChecker.cpp \ runtime/UString.cpp \ + runtime/UStringImpl.cpp \ wtf/Assertions.cpp \ wtf/ByteArray.cpp \ wtf/CurrentTime.cpp \ @@ -220,8 +208,10 @@ SOURCES += \ wtf/HashTable.cpp \ wtf/MainThread.cpp \ wtf/qt/MainThreadQt.cpp \ + wtf/qt/ThreadingQt.cpp \ wtf/RandomNumber.cpp \ wtf/RefCountedLeakCounter.cpp \ + wtf/ThreadingNone.cpp \ wtf/Threading.cpp \ wtf/TypeTraits.cpp \ wtf/unicode/CollatorDefault.cpp \ @@ -231,53 +221,11 @@ SOURCES += \ yarr/RegexInterpreter.cpp \ yarr/RegexJIT.cpp -symbian { - SOURCES += jit/ExecutableAllocatorSymbian.cpp \ - runtime/MarkStackSymbian.cpp -} else { - win32-*|wince* { - SOURCES += jit/ExecutableAllocatorWin.cpp \ - runtime/MarkStackWin.cpp - } else { - SOURCES += jit/ExecutableAllocatorPosix.cpp \ - runtime/MarkStackPosix.cpp - } -} +# Generated files, simply list them for JavaScriptCore +SOURCES += \ + $${JSC_GENERATED_SOURCES_DIR}/Grammar.cpp !contains(DEFINES, USE_SYSTEM_MALLOC) { SOURCES += wtf/TCSystemAlloc.cpp } -!contains(DEFINES, ENABLE_SINGLE_THREADED=1) { - SOURCES += wtf/qt/ThreadingQt.cpp -} else { - DEFINES += ENABLE_JSC_MULTIPLE_THREADS=0 - SOURCES += wtf/ThreadingNone.cpp -} - -# GENERATOR 1-A: LUT creator -lut.output = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.lut.h -lut.commands = perl $$PWD/create_hash_table ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT} -lut.depend = ${QMAKE_FILE_NAME} -lut.input = LUT_FILES -lut.CONFIG += no_link -addExtraCompiler(lut) - -# GENERATOR 1-B: particular LUT creator (for 1 file only) -keywordlut.output = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}Lexer.lut.h -keywordlut.commands = perl $$PWD/create_hash_table ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT} -keywordlut.depend = ${QMAKE_FILE_NAME} -keywordlut.input = KEYWORDLUT_FILES -keywordlut.CONFIG += no_link -addExtraCompiler(keywordlut) - -# GENERATOR 2: bison grammar -jscbison.output = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.cpp -jscbison.commands = bison -d -p jscyy ${QMAKE_FILE_NAME} -o $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.c && $(MOVE) $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.c ${QMAKE_FILE_OUT} && $(MOVE) $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.h $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.h -jscbison.depend = ${QMAKE_FILE_NAME} -jscbison.input = JSCBISON -jscbison.variable_out = GENERATED_SOURCES -jscbison.dependency_type = TYPE_C -jscbison.CONFIG = target_predeps -addExtraCompilerWithHeader(jscbison) - diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.resources/Info.plist b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.resources/Info.plist index bccf2b5..7de8638 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.resources/Info.plist +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore.resources/Info.plist @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleDevelopmentRegion</key> @@ -7,7 +7,7 @@ <key>CFBundleExecutable</key> <string>JavaScriptCore</string> <key>CFBundleGetInfoString</key> - <string>530, Copyright 2003-2009 Apple Inc.</string> + <string>530, Copyright 2003-2010 Apple Inc.</string> <key>CFBundleIdentifier</key> <string>com.apple.JavaScriptCore</string> <key>CFBundleInfoDictionaryVersion</key> diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def index aae8118..65ba684 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def @@ -2,6 +2,7 @@ EXPORTS ??0Collator@WTF@@QAE@PBD@Z ??0DateInstance@JSC@@QAE@PAVExecState@1@N@Z + ??0DateInstance@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@N@Z ??0DropAllLocks@JSLock@JSC@@QAE@W4JSLockBehavior@2@@Z ??0InternalFunction@JSC@@IAE@PAVJSGlobalData@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@ABVIdentifier@1@@Z ??0JSArray@JSC@@QAE@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@@Z @@ -29,24 +30,22 @@ EXPORTS ??1Rope@JSString@JSC@@QAE@XZ ??1Structure@JSC@@QAE@XZ ??1ThreadCondition@WTF@@QAE@XZ - ??2JSCell@JSC@@SAPAXIPAVExecState@1@@Z + ??1UStringImpl@JSC@@AAE@XZ ??2JSGlobalObject@JSC@@SAPAXIPAVJSGlobalData@1@@Z ??4UString@JSC@@QAEAAV01@PBD@Z ??8JSC@@YA_NABVUString@0@0@Z ?NaN@JSC@@3NB ?UTF8String@UString@JSC@@QBE?AVCString@2@_N@Z - ?add@Identifier@JSC@@SA?AV?$PassRefPtr@URep@UString@JSC@@@WTF@@PAVExecState@2@PBD@Z - ?add@PropertyNameArray@JSC@@QAEXPAURep@UString@2@@Z ?addPropertyTransition@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@IPAVJSCell@2@AAI@Z ?addPropertyTransitionToExistingStructure@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@IPAVJSCell@2@AAI@Z ?addPropertyWithoutTransition@Structure@JSC@@QAEIABVIdentifier@2@IPAVJSCell@2@@Z - ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@URep@UString@JSC@@@WTF@@PAVExecState@2@PAURep@UString@2@@Z - ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@URep@UString@JSC@@@WTF@@PAVJSGlobalData@2@PAURep@UString@2@@Z + ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VUStringImpl@JSC@@@WTF@@PAVExecState@2@PAVUStringImpl@2@@Z + ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VUStringImpl@JSC@@@WTF@@PAVJSGlobalData@2@PAVUStringImpl@2@@Z + ?add@Identifier@JSC@@SA?AV?$PassRefPtr@VUStringImpl@JSC@@@WTF@@PAVExecState@2@PBD@Z + ?add@PropertyNameArray@JSC@@QAEXPAVUStringImpl@2@@Z ?allocate@Heap@JSC@@QAEPAXI@Z ?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z ?allocateStack@MarkStack@JSC@@CAPAXI@Z - ?append@UString@JSC@@QAEAAV12@ABV12@@Z - ?append@UString@JSC@@QAEAAV12@PBD@Z ?ascii@UString@JSC@@QBEPADXZ ?attach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z ?broadcast@ThreadCondition@WTF@@QAEXXZ @@ -55,16 +54,15 @@ EXPORTS ?callOnMainThread@WTF@@YAXP6AXPAX@Z0@Z ?callOnMainThreadAndWait@WTF@@YAXP6AXPAX@Z0@Z ?changePrototypeTransition@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@VJSValue@2@@Z - ?checkSameIdentifierTable@Identifier@JSC@@CAXPAVExecState@2@PAURep@UString@2@@Z - ?checkSameIdentifierTable@Identifier@JSC@@CAXPAVJSGlobalData@2@PAURep@UString@2@@Z + ?checkSameIdentifierTable@Identifier@JSC@@CAXPAVExecState@2@PAVUStringImpl@2@@Z + ?checkSameIdentifierTable@Identifier@JSC@@CAXPAVJSGlobalData@2@PAVUStringImpl@2@@Z ?checkSyntax@JSC@@YA?AVCompletion@1@PAVExecState@1@ABVSourceCode@1@@Z ?classInfo@InternalFunction@JSC@@UBEPBUClassInfo@2@XZ ?classInfo@JSCell@JSC@@UBEPBUClassInfo@2@XZ ?className@JSObject@JSC@@UBE?AVUString@2@XZ ?collate@Collator@WTF@@QBE?AW4Result@12@PB_WI0I@Z - ?collect@Heap@JSC@@QAE_NXZ - ?computeHash@Rep@UString@JSC@@SAIPBDH@Z - ?computeHash@Rep@UString@JSC@@SAIPB_WH@Z + ?collectAllGarbage@Heap@JSC@@QAEXXZ + ?computeHash@UStringImpl@JSC@@SAIPB_WH@Z ?configurable@PropertyDescriptor@JSC@@QBE_NXZ ?construct@JSC@@YAPAVJSObject@1@PAVExecState@1@VJSValue@1@W4ConstructType@1@ABTConstructData@1@ABVArgList@1@@Z ?constructArray@JSC@@YAPAVJSArray@1@PAVExecState@1@ABVArgList@1@@Z @@ -73,9 +71,8 @@ EXPORTS ?constructFunction@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVArgList@1@ABVIdentifier@1@ABVUString@1@H@Z ?convertUTF16ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPB_WPB_WPAPADPAD_N@Z ?create@ByteArray@WTF@@SA?AV?$PassRefPtr@VByteArray@WTF@@@2@I@Z - ?create@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@_N@Z + ?create@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@XZ ?create@OpaqueJSString@@SA?AV?$PassRefPtr@UOpaqueJSString@@@WTF@@ABVUString@JSC@@@Z - ?create@Rep@UString@JSC@@SA?AV?$PassRefPtr@URep@UString@JSC@@@WTF@@PA_WHV?$PassRefPtr@V?$CrossThreadRefCounted@V?$OwnFastMallocPtr@_W@WTF@@@WTF@@@5@@Z ?createEmptyString@SmallStrings@JSC@@AAEXPAVJSGlobalData@2@@Z ?createInheritorID@JSObject@JSC@@AAEPAVStructure@2@XZ ?createInterruptedExecutionException@JSC@@YA?AVJSValue@1@PAVJSGlobalData@1@@Z @@ -89,6 +86,9 @@ EXPORTS ?createTypeError@JSC@@YA?AVJSValue@1@PAVExecState@1@PBD@Z ?currentThread@WTF@@YAIXZ ?currentTime@WTF@@YANXZ + ?dateToDaysFrom1970@WTF@@YANHHH@Z + ?dayInMonthFromDayInYear@WTF@@YAHH_N@Z + ?dayInYear@WTF@@YAHNH@Z ?decrement@RefCountedLeakCounter@WTF@@QAEXXZ ?defaultAttributes@PropertyDescriptor@JSC@@0IA ?defaultValue@JSObject@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z @@ -110,16 +110,15 @@ EXPORTS ?despecifyDictionaryFunction@Structure@JSC@@QAEXABVIdentifier@2@@Z ?despecifyFunctionTransition@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@@Z ?destroy@Heap@JSC@@QAEXXZ - ?destroy@Rep@UString@JSC@@QAEXXZ ?destroyJSGlobalObjectData@JSGlobalObject@JSC@@CAXPAX@Z ?detach@Debugger@JSC@@UAEXPAVJSGlobalObject@2@@Z ?detachThread@WTF@@YAXI@Z ?didTimeOut@TimeoutChecker@JSC@@QAE_NPAVExecState@2@@Z - ?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z ?doubleToStringInJavaScriptFormat@WTF@@YAXNQADPAI@Z + ?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z ?enumerable@PropertyDescriptor@JSC@@QBE_NXZ - ?equal@Identifier@JSC@@SA_NPBURep@UString@2@PBD@Z - ?equal@JSC@@YA_NPBURep@UString@1@0@Z + ?equal@Identifier@JSC@@SA_NPBVUStringImpl@2@PBD@Z + ?equal@JSC@@YA_NPBVUStringImpl@1@0@Z ?evaluate@DebuggerCallFrame@JSC@@QBE?AVJSValue@2@ABVUString@2@AAV32@@Z ?evaluate@JSC@@YA?AVCompletion@1@PAVExecState@1@AAVScopeChain@1@ABVSourceCode@1@VJSValue@1@@Z ?exclude@Profile@JSC@@QAEXPBVProfileNode@2@@Z @@ -134,7 +133,6 @@ EXPORTS ?from@UString@JSC@@SA?AV12@I@Z ?from@UString@JSC@@SA?AV12@N@Z ?functionName@DebuggerCallFrame@JSC@@QBEPBVUString@2@XZ - ?get@Structure@JSC@@QAEIPBURep@UString@2@AAIAAPAVJSCell@2@@Z ?getCallData@JSCell@JSC@@UAE?AW4CallType@2@AATCallData@2@@Z ?getConstructData@JSCell@JSC@@UAE?AW4ConstructType@2@AATConstructData@2@@Z ?getJSNumber@JSCell@JSC@@UAE?AVJSValue@2@XZ @@ -142,9 +140,9 @@ EXPORTS ?getOwnPropertyDescriptor@JSObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z ?getOwnPropertyDescriptor@JSString@JSC@@EAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z ?getOwnPropertyDescriptor@StringObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z - ?getOwnPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z - ?getOwnPropertyNames@JSVariableObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z - ?getOwnPropertyNames@StringObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z + ?getOwnPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z + ?getOwnPropertyNames@JSVariableObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z + ?getOwnPropertyNames@StringObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z ?getOwnPropertySlot@JSCell@JSC@@EAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertySlot@2@@Z ?getOwnPropertySlot@JSCell@JSC@@EAE_NPAVExecState@2@IAAVPropertySlot@2@@Z ?getOwnPropertySlot@JSObject@JSC@@UAE_NPAVExecState@2@IAAVPropertySlot@2@@Z @@ -156,18 +154,19 @@ EXPORTS ?getPrimitiveNumber@JSObject@JSC@@UAE_NPAVExecState@2@AANAAVJSValue@2@@Z ?getPrimitiveNumber@JSString@JSC@@EAE_NPAVExecState@2@AANAAVJSValue@2@@Z ?getPropertyDescriptor@JSObject@JSC@@QAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@@Z - ?getPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@@Z + ?getPropertyNames@JSObject@JSC@@UAEXPAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z ?getSlice@ArgList@JSC@@QBEXHAAV12@@Z ?getString@JSCell@JSC@@QBE?AVUString@2@PAVExecState@2@@Z ?getString@JSCell@JSC@@QBE_NPAVExecState@2@AAVUString@2@@Z ?getUInt32@JSCell@JSC@@UBE_NAAI@Z + ?get@Structure@JSC@@QAEIPBVUStringImpl@2@AAIAAPAVJSCell@2@@Z ?getter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ ?globalExec@JSGlobalObject@JSC@@UAEPAVExecState@2@XZ ?globalObjectCount@Heap@JSC@@QAEIXZ ?hasInstance@JSObject@JSC@@UAE_NPAVExecState@2@VJSValue@2@1@Z ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@ABVIdentifier@2@@Z ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@I@Z - ?hasTransition@Structure@JSC@@QAE_NPAURep@UString@2@I@Z + ?hasTransition@Structure@JSC@@QAE_NPAVUStringImpl@2@I@Z ?heap@Heap@JSC@@SAPAV12@VJSValue@2@@Z ?increment@RefCountedLeakCounter@WTF@@QAEXXZ ?init@JSGlobalObject@JSC@@AAEXPAVJSObject@2@@Z @@ -198,14 +197,14 @@ EXPORTS ?markChildren@JSObject@JSC@@UAEXAAVMarkStack@2@@Z ?markChildren@JSWrapperObject@JSC@@EAEXAAVMarkStack@2@@Z ?materializePropertyMap@Structure@JSC@@AAEXXZ + ?monthFromDayInYear@WTF@@YAHH_N@Z + ?msToYear@WTF@@YAHN@Z ?name@InternalFunction@JSC@@QAEABVUString@2@PAVExecState@2@@Z ?nonInlineNaN@JSC@@YANXZ - ?objectCount@Heap@JSC@@QAEIXZ + ?objectCount@Heap@JSC@@QBEIXZ ?objectProtoFuncToString@JSC@@YI?AVJSValue@1@PAVExecState@1@PAVJSObject@1@V21@ABVArgList@1@@Z ?parse@Parser@JSC@@AAEXPAVJSGlobalData@2@PAHPAVUString@2@@Z ?parseDateFromNullTerminatedCharacters@WTF@@YANPBD@Z - ?primaryHeapBegin@Heap@JSC@@QAE?AV?$CollectorHeapIterator@$0A@@2@XZ - ?primaryHeapEnd@Heap@JSC@@QAE?AV?$CollectorHeapIterator@$0A@@2@XZ ?profiler@Profiler@JSC@@SAPAV12@XZ ?protect@Heap@JSC@@QAEXVJSValue@2@@Z ?protectedGlobalObjectCount@Heap@JSC@@QAEIXZ @@ -248,7 +247,7 @@ EXPORTS ?setUpStaticFunctionSlot@JSC@@YAXPAVExecState@1@PBVHashEntry@1@PAVJSObject@1@ABVIdentifier@1@AAVPropertySlot@1@@Z ?setWritable@PropertyDescriptor@JSC@@QAEX_N@Z ?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ - ?sharedBuffer@Rep@UString@JSC@@QAEPAV?$CrossThreadRefCounted@V?$OwnFastMallocPtr@_W@WTF@@@WTF@@XZ + ?sharedBuffer@UStringImpl@JSC@@QAEPAV?$CrossThreadRefCounted@V?$OwnFastMallocPtr@_W@WTF@@@WTF@@XZ ?signal@ThreadCondition@WTF@@QAEXXZ ?slowAppend@MarkedArgumentBuffer@JSC@@AAEXVJSValue@2@@Z ?startIgnoringLeaks@Structure@JSC@@SAXXZ diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc index ba59bb8..861fa3a 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.rc @@ -34,7 +34,7 @@ BEGIN VALUE "FileVersion", __VERSION_TEXT__ VALUE "CompanyName", "Apple Inc." VALUE "InternalName", "JavaScriptCore" - VALUE "LegalCopyright", "Copyright Apple Inc. 2003-2009" + VALUE "LegalCopyright", "Copyright Apple Inc. 2003-2010" VALUE "OriginalFilename", "JavaScriptCore.dll" VALUE "ProductName", " JavaScriptCore" VALUE "ProductVersion", __VERSION_TEXT__ diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj index 5b7f9ad..9c20af9 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj @@ -18,7 +18,7 @@ <Configuration
Name="Debug|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
CharacterSet="1"
>
<Tool
@@ -79,7 +79,7 @@ <Configuration
Name="Release|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
@@ -141,7 +141,7 @@ <Configuration
Name="Debug_Internal|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
CharacterSet="1"
>
<Tool
@@ -203,7 +203,7 @@ Name="Release_PGOInstrument|Win32"
IntermediateDirectory="$(WebKitOutputDir)\obj\$(ProjectName)\Release"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
CharacterSet="1"
WholeProgramOptimization="2"
>
@@ -266,7 +266,7 @@ Name="Release_PGOOptimize|Win32"
IntermediateDirectory="$(WebKitOutputDir)\obj\$(ProjectName)\Release"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops"
CharacterSet="1"
WholeProgramOptimization="4"
>
@@ -328,7 +328,7 @@ <Configuration
Name="Debug_CFLite|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCFLite.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefinesCairo.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_wincairo.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCFLite.vsprops"
CharacterSet="1"
>
<Tool
@@ -389,7 +389,7 @@ <Configuration
Name="Release_CFLite|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCFLite.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefinesCairo.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCFLite.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
@@ -451,7 +451,7 @@ <Configuration
Name="Debug_All|Win32"
ConfigurationType="2"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\JavaScriptCoreCommon.vsprops;.\JavaScriptCoreCF.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops"
CharacterSet="1"
>
<Tool
@@ -514,7 +514,7 @@ </References>
<Files>
<Filter
- Name="JavaScriptCore"
+ Name="runtime"
>
<File
RelativePath="..\..\runtime\ArgList.cpp"
@@ -549,6 +549,10 @@ >
</File>
<File
+ RelativePath="..\..\runtime\BatchedTransitionOptimizer.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\BooleanConstructor.cpp"
>
</File>
@@ -573,10 +577,6 @@ >
</File>
<File
- RelativePath="..\..\interpreter\CachedCall.h"
- >
- </File>
- <File
RelativePath="..\..\runtime\CallData.cpp"
>
</File>
@@ -585,18 +585,6 @@ >
</File>
<File
- RelativePath="..\..\interpreter\CallFrame.cpp"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\CallFrame.h"
- >
- </File>
- <File
- RelativePath="..\..\interpreter\CallFrameClosure.h"
- >
- </File>
- <File
RelativePath="..\..\runtime\ClassInfo.h"
>
</File>
@@ -629,10 +617,6 @@ >
</File>
<File
- RelativePath="..\..\config.h"
- >
- </File>
- <File
RelativePath="..\..\runtime\ConstructData.cpp"
>
</File>
@@ -668,14 +652,14 @@ RelativePath="..\..\runtime\DateInstanceCache.h"
>
</File>
- <File
- RelativePath="..\..\wtf\DateMath.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wtf\DateMath.h"
- >
- </File>
+ <File
+ RelativePath="..\..\wtf\DateMath.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\DateMath.h"
+ >
+ </File>
<File
RelativePath="..\..\runtime\DatePrototype.cpp"
>
@@ -717,10 +701,22 @@ >
</File>
<File
+ RelativePath="..\..\runtime\ExceptionHelpers.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\interpreter\ExceptionHelpers.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\Executable.cpp"
>
</File>
<File
+ RelativePath="..\..\runtime\Executable.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\FunctionConstructor.cpp"
>
</File>
@@ -785,14 +781,6 @@ >
</File>
<File
- RelativePath="..\..\runtime\JSAPIValueWrapper.cpp"
- >
- </File>
- <File
- RelativePath="..\..\runtime\JSAPIValueWrapper.h"
- >
- </File>
- <File
RelativePath="..\..\runtime\JSArray.cpp"
>
</File>
@@ -897,6 +885,14 @@ >
</File>
<File
+ RelativePath="..\..\runtime\JSPropertyNameIterator.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\JSPropertyNameIterator.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\JSStaticScopeObject.cpp"
>
</File>
@@ -917,6 +913,10 @@ >
</File>
<File
+ RelativePath="..\..\runtime\JSTypeInfo.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\JSValue.cpp"
>
</File>
@@ -941,7 +941,11 @@ >
</File>
<File
- RelativePath="..\..\bytecompiler\LabelScope.h"
+ RelativePath="..\..\runtime\JSZombie.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\JSZombie.h"
>
</File>
<File
@@ -1109,6 +1113,10 @@ >
</File>
<File
+ RelativePath="..\..\runtime\RegExpMatchesArray.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\RegExpObject.cpp"
>
</File>
@@ -1145,14 +1153,6 @@ >
</File>
<File
- RelativePath="..\..\parser\SourceCode.h"
- >
- </File>
- <File
- RelativePath="..\..\parser\SourceProvider.h"
- >
- </File>
- <File
RelativePath="..\..\runtime\StringConstructor.cpp"
>
</File>
@@ -1205,6 +1205,14 @@ >
</File>
<File
+ RelativePath="..\..\runtime\TimeoutChecker.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\TimeoutChecker.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\UString.cpp"
>
</File>
@@ -1213,120 +1221,28 @@ >
</File>
<File
- RelativePath="..\..\runtime\WeakRandom.h"
+ RelativePath="..\..\runtime\UStringImpl.cpp"
>
</File>
- <Filter
- Name="DerivedSources"
+ <File
+ RelativePath="..\..\runtime\UStringImpl.h"
>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\ArrayPrototype.lut.h"
- >
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\DatePrototype.lut.h"
- >
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\Grammar.cpp"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_Internal|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_PGOInstrument|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_PGOOptimize|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_CFLite|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release_CFLite|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Debug_All|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- DisableSpecificWarnings="4701"
- />
- </FileConfiguration>
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\Grammar.h"
- >
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\lexer.lut.h"
- >
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\MathObject.lut.h"
- >
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\NumberConstructor.lut.h"
- >
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\RegExpConstructor.lut.h"
- >
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\RegExpObject.lut.h"
- >
- </File>
- <File
- RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\StringPrototype.lut.h"
- >
- </File>
- </Filter>
+ </File>
+ <File
+ RelativePath="..\..\runtime\WeakGCMap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\WeakGCPtr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\WeakRandom.h"
+ >
+ </File>
</Filter>
<Filter
- Name="PCRE"
+ Name="pcre"
>
<File
RelativePath="..\..\pcre\pcre.h"
@@ -1377,6 +1293,14 @@ >
</File>
<File
+ RelativePath="..\..\runtime\JSAPIValueWrapper.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\JSAPIValueWrapper.h"
+ >
+ </File>
+ <File
RelativePath="..\..\API\JSBase.cpp"
>
</File>
@@ -1385,6 +1309,10 @@ >
</File>
<File
+ RelativePath="..\..\API\JSBasePrivate.h"
+ >
+ </File>
+ <File
RelativePath="..\..\API\JSCallbackConstructor.cpp"
>
</File>
@@ -1409,6 +1337,10 @@ >
</File>
<File
+ RelativePath="..\..\API\JSCallbackObjectFunctions.h"
+ >
+ </File>
+ <File
RelativePath="..\..\API\JSClassRef.cpp"
>
</File>
@@ -1486,14 +1418,10 @@ </File>
</Filter>
<Filter
- Name="Profiler"
+ Name="profiler"
>
<File
- RelativePath="..\..\profiler\HeavyProfile.cpp"
- >
- </File>
- <File
- RelativePath="..\..\profiler\HeavyProfile.h"
+ RelativePath="..\..\profiler\CallIdentifier.h"
>
</File>
<File
@@ -1528,396 +1456,528 @@ RelativePath="..\..\profiler\Profiler.h"
>
</File>
+ </Filter>
+ <Filter
+ Name="bytecode"
+ >
<File
- RelativePath="..\..\profiler\TreeProfile.cpp"
+ RelativePath="..\..\bytecode\CodeBlock.cpp"
>
</File>
<File
- RelativePath="..\..\profiler\TreeProfile.h"
+ RelativePath="..\..\bytecode\CodeBlock.h"
>
</File>
- </Filter>
- <Filter
- Name="Compiler"
- >
<File
- RelativePath="..\..\bytecompiler\BytecodeGenerator.cpp"
+ RelativePath="..\..\bytecode\EvalCodeCache.h"
>
</File>
<File
- RelativePath="..\..\bytecompiler\BytecodeGenerator.h"
+ RelativePath="..\..\bytecode\Instruction.h"
>
</File>
<File
- RelativePath="..\..\bytecompiler\NodesCodegen.cpp"
+ RelativePath="..\..\bytecode\JumpTable.cpp"
>
</File>
<File
- RelativePath="..\..\bytecompiler\Label.h"
+ RelativePath="..\..\bytecode\JumpTable.h"
>
</File>
<File
- RelativePath="..\..\parser\Lexer.cpp"
+ RelativePath="..\..\bytecode\Opcode.cpp"
>
</File>
<File
- RelativePath="..\..\parser\Lexer.h"
+ RelativePath="..\..\bytecode\Opcode.h"
>
</File>
<File
- RelativePath="..\..\parser\NodeConstructors.h"
+ RelativePath="..\..\bytecode\SamplingTool.cpp"
>
</File>
<File
- RelativePath="..\..\parser\NodeInfo.h"
+ RelativePath="..\..\bytecode\SamplingTool.h"
>
</File>
<File
- RelativePath="..\..\parser\Nodes.cpp"
+ RelativePath="..\..\bytecode\StructureStubInfo.cpp"
>
</File>
<File
- RelativePath="..\..\parser\Nodes.h"
+ RelativePath="..\..\bytecode\StructureStubInfo.h"
>
</File>
+ </Filter>
+ <Filter
+ Name="debugger"
+ >
<File
- RelativePath="..\..\parser\Parser.cpp"
+ RelativePath="..\..\debugger\Debugger.cpp"
>
</File>
<File
- RelativePath="..\..\parser\Parser.h"
+ RelativePath="..\..\debugger\Debugger.h"
>
</File>
<File
- RelativePath="..\..\parser\ParserArena.cpp"
+ RelativePath="..\..\debugger\DebuggerActivation.cpp"
>
</File>
<File
- RelativePath="..\..\parser\ParserArena.h"
+ RelativePath="..\..\debugger\DebuggerActivation.h"
>
</File>
<File
- RelativePath="..\..\bytecompiler\RegisterID.h"
+ RelativePath="..\..\debugger\DebuggerCallFrame.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\debugger\DebuggerCallFrame.h"
>
</File>
</Filter>
<Filter
- Name="bytecode"
+ Name="assembler"
>
<File
- RelativePath="..\..\bytecode\CodeBlock.cpp"
+ RelativePath="..\..\assembler\AbstractMacroAssembler.h"
>
</File>
<File
- RelativePath="..\..\bytecode\CodeBlock.h"
+ RelativePath="..\..\assembler\AssemblerBuffer.h"
>
</File>
<File
- RelativePath="..\..\bytecode\EvalCodeCache.h"
+ RelativePath="..\..\assembler\CodeLocation.h"
>
</File>
<File
- RelativePath="..\..\runtime\ExceptionHelpers.cpp"
+ RelativePath="..\..\assembler\LinkBuffer.h"
>
</File>
<File
- RelativePath="..\..\interpreter\ExceptionHelpers.h"
+ RelativePath="..\..\assembler\MacroAssembler.h"
>
</File>
<File
- RelativePath="..\..\bytecode\Instruction.h"
+ RelativePath="..\..\assembler\MacroAssemblerX86.h"
>
</File>
<File
- RelativePath="..\..\interpreter\Interpreter.cpp"
+ RelativePath="..\..\assembler\MacroAssemblerX86Common.h"
>
</File>
<File
- RelativePath="..\..\interpreter\Interpreter.h"
+ RelativePath="..\..\assembler\RepatchBuffer.h"
>
</File>
<File
- RelativePath="..\..\jit\JITStubs.cpp"
+ RelativePath="..\..\assembler\X86Assembler.h"
>
</File>
+ </Filter>
+ <Filter
+ Name="wrec"
+ >
<File
- RelativePath="..\..\jit\JITStubs.h"
+ RelativePath="..\..\wrec\CharacterClass.cpp"
>
</File>
<File
- RelativePath="..\..\runtime\JSPropertyNameIterator.cpp"
+ RelativePath="..\..\wrec\CharacterClass.h"
>
</File>
<File
- RelativePath="..\..\runtime\JSPropertyNameIterator.h"
+ RelativePath="..\..\wrec\CharacterClassConstructor.cpp"
>
</File>
<File
- RelativePath="..\..\bytecode\JumpTable.cpp"
+ RelativePath="..\..\wrec\CharacterClassConstructor.h"
>
</File>
<File
- RelativePath="..\..\bytecode\JumpTable.h"
+ RelativePath="..\..\wrec\Escapes.h"
>
</File>
<File
- RelativePath="..\..\bytecode\Opcode.cpp"
+ RelativePath="..\..\wrec\Quantifier.h"
>
</File>
<File
- RelativePath="..\..\bytecode\Opcode.h"
+ RelativePath="..\..\wrec\WREC.cpp"
>
</File>
<File
- RelativePath="..\..\interpreter\Register.h"
+ RelativePath="..\..\wrec\WREC.h"
>
</File>
<File
- RelativePath="..\..\interpreter\RegisterFile.cpp"
+ RelativePath="..\..\wrec\WRECFunctors.cpp"
>
</File>
<File
- RelativePath="..\..\interpreter\RegisterFile.h"
+ RelativePath="..\..\wrec\WRECFunctors.h"
>
</File>
<File
- RelativePath="..\..\bytecode\SamplingTool.cpp"
+ RelativePath="..\..\wrec\WRECGenerator.cpp"
>
</File>
<File
- RelativePath="..\..\bytecode\SamplingTool.h"
+ RelativePath="..\..\wrec\WRECGenerator.h"
>
</File>
<File
- RelativePath="..\..\bytecode\StructureStubInfo.cpp"
+ RelativePath="..\..\wrec\WRECParser.cpp"
>
</File>
<File
- RelativePath="..\..\bytecode\StructureStubInfo.h"
+ RelativePath="..\..\wrec\WRECParser.h"
>
</File>
+ </Filter>
+ <Filter
+ Name="yarr"
+ >
<File
- RelativePath="..\..\runtime\TimeoutChecker.cpp"
+ RelativePath="..\..\yarr\RegexCompiler.cpp"
>
</File>
<File
- RelativePath="..\..\runtime\TimeoutChecker.h"
+ RelativePath="..\..\yarr\RegexCompiler.h"
>
</File>
- </Filter>
- <Filter
- Name="Debugger"
- >
<File
- RelativePath="..\..\debugger\Debugger.cpp"
+ RelativePath="..\..\yarr\RegexInterpreter.cpp"
>
</File>
<File
- RelativePath="..\..\debugger\Debugger.h"
+ RelativePath="..\..\yarr\RegexInterpreter.h"
>
</File>
<File
- RelativePath="..\..\debugger\DebuggerActivation.cpp"
+ RelativePath="..\..\yarr\RegexJIT.cpp"
>
</File>
<File
- RelativePath="..\..\debugger\DebuggerActivation.h"
+ RelativePath="..\..\yarr\RegexJIT.h"
>
</File>
<File
- RelativePath="..\..\debugger\DebuggerCallFrame.cpp"
+ RelativePath="..\..\yarr\RegexParser.h"
>
</File>
<File
- RelativePath="..\..\debugger\DebuggerCallFrame.h"
+ RelativePath="..\..\yarr\RegexPattern.h"
>
</File>
</Filter>
<Filter
- Name="assembler"
+ Name="jit"
>
<File
- RelativePath="..\..\assembler\AbstractMacroAssembler.h"
+ RelativePath="..\..\jit\ExecutableAllocator.cpp"
>
</File>
<File
- RelativePath="..\..\assembler\AssemblerBuffer.h"
+ RelativePath="..\..\jit\ExecutableAllocator.h"
>
</File>
<File
- RelativePath="..\..\assembler\LinkBuffer.h"
+ RelativePath="..\..\jit\ExecutableAllocatorWin.cpp"
>
</File>
<File
- RelativePath="..\..\assembler\MacroAssembler.h"
+ RelativePath="..\..\jit\JIT.cpp"
>
</File>
<File
- RelativePath="..\..\assembler\MacroAssemblerX86.h"
+ RelativePath="..\..\jit\JIT.h"
>
</File>
<File
- RelativePath="..\..\assembler\MacroAssemblerX86Common.h"
+ RelativePath="..\..\jit\JITArithmetic.cpp"
>
</File>
<File
- RelativePath="..\..\assembler\RepatchBuffer.h"
+ RelativePath="..\..\jit\JITCall.cpp"
>
</File>
<File
- RelativePath="..\..\assembler\X86Assembler.h"
+ RelativePath="..\..\jit\JITCode.h"
>
</File>
- </Filter>
- <Filter
- Name="wrec"
- >
<File
- RelativePath="..\..\wrec\CharacterClass.cpp"
+ RelativePath="..\..\jit\JITInlineMethods.h"
>
</File>
<File
- RelativePath="..\..\wrec\CharacterClass.h"
+ RelativePath="..\..\jit\JITOpcodes.cpp"
>
</File>
<File
- RelativePath="..\..\wrec\CharacterClassConstructor.cpp"
+ RelativePath="..\..\jit\JITPropertyAccess.cpp"
>
</File>
<File
- RelativePath="..\..\wrec\CharacterClassConstructor.h"
+ RelativePath="..\..\jit\JITStubCall.h"
>
</File>
<File
- RelativePath="..\..\wrec\Quantifier.h"
+ RelativePath="..\..\jit\JITStubs.cpp"
>
</File>
<File
- RelativePath="..\..\wrec\WREC.cpp"
+ RelativePath="..\..\jit\JITStubs.h"
>
</File>
+ </Filter>
+ <Filter
+ Name="Resources"
+ >
<File
- RelativePath="..\..\wrec\WREC.h"
+ RelativePath=".\JavaScriptCore.rc"
>
</File>
+ </Filter>
+ <Filter
+ Name="interpreter"
+ >
<File
- RelativePath="..\..\wrec\WRECFunctors.cpp"
+ RelativePath="..\..\interpreter\CachedCall.h"
>
</File>
<File
- RelativePath="..\..\wrec\WRECFunctors.h"
+ RelativePath="..\..\interpreter\CallFrame.cpp"
>
</File>
<File
- RelativePath="..\..\wrec\WRECGenerator.cpp"
+ RelativePath="..\..\interpreter\CallFrame.h"
>
</File>
<File
- RelativePath="..\..\wrec\WRECGenerator.h"
+ RelativePath="..\..\interpreter\CallFrameClosure.h"
>
</File>
<File
- RelativePath="..\..\wrec\WRECParser.cpp"
+ RelativePath="..\..\interpreter\Interpreter.cpp"
>
</File>
<File
- RelativePath="..\..\wrec\WRECParser.h"
+ RelativePath="..\..\interpreter\Interpreter.h"
>
</File>
- </Filter>
- <Filter
- Name="yarr"
- >
<File
- RelativePath="..\..\yarr\RegexCompiler.cpp"
+ RelativePath="..\..\interpreter\Register.h"
>
</File>
<File
- RelativePath="..\..\yarr\RegexCompiler.h"
+ RelativePath="..\..\interpreter\RegisterFile.cpp"
>
</File>
<File
- RelativePath="..\..\yarr\RegexInterpreter.cpp"
+ RelativePath="..\..\interpreter\RegisterFile.h"
>
</File>
+ </Filter>
+ <Filter
+ Name="bytecompiler"
+ >
<File
- RelativePath="..\..\yarr\RegexInterpreter.h"
+ RelativePath="..\..\bytecompiler\BytecodeGenerator.cpp"
>
</File>
<File
- RelativePath="..\..\yarr\RegexJIT.cpp"
+ RelativePath="..\..\bytecompiler\BytecodeGenerator.h"
>
</File>
<File
- RelativePath="..\..\yarr\RegexJIT.h"
+ RelativePath="..\..\bytecompiler\Label.h"
>
</File>
<File
- RelativePath="..\..\yarr\RegexParser.h"
+ RelativePath="..\..\bytecompiler\LabelScope.h"
>
</File>
<File
- RelativePath="..\..\yarr\RegexPattern.h"
+ RelativePath="..\..\bytecompiler\NodesCodegen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\bytecompiler\RegisterID.h"
>
</File>
</Filter>
<Filter
- Name="jit"
+ Name="parser"
>
<File
- RelativePath="..\..\jit\ExecutableAllocator.cpp"
+ RelativePath="..\..\parser\Lexer.cpp"
>
</File>
<File
- RelativePath="..\..\jit\ExecutableAllocator.h"
+ RelativePath="..\..\parser\Lexer.h"
>
</File>
<File
- RelativePath="..\..\jit\ExecutableAllocatorWin.cpp"
+ RelativePath="..\..\parser\NodeConstructors.h"
>
</File>
<File
- RelativePath="..\..\jit\JIT.cpp"
+ RelativePath="..\..\parser\NodeInfo.h"
>
</File>
<File
- RelativePath="..\..\jit\JIT.h"
+ RelativePath="..\..\parser\Nodes.cpp"
>
</File>
<File
- RelativePath="..\..\jit\JITArithmetic.cpp"
+ RelativePath="..\..\parser\Nodes.h"
>
</File>
<File
- RelativePath="..\..\jit\JITCall.cpp"
+ RelativePath="..\..\parser\Parser.cpp"
>
</File>
<File
- RelativePath="..\..\jit\JITInlineMethods.h"
+ RelativePath="..\..\parser\Parser.h"
>
</File>
<File
- RelativePath="..\..\jit\JITOpcodes.cpp"
+ RelativePath="..\..\parser\ParserArena.cpp"
>
</File>
<File
- RelativePath="..\..\jit\JITPropertyAccess.cpp"
+ RelativePath="..\..\parser\ParserArena.h"
>
</File>
<File
- RelativePath="..\..\jit\JITStubCall.h"
+ RelativePath="..\..\parser\ResultType.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\parser\SourceCode.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\parser\SourceProvider.h"
>
</File>
</Filter>
<Filter
- Name="Resources"
+ Name="Derived Sources"
>
<File
- RelativePath=".\JavaScriptCore.rc"
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\ArrayPrototype.lut.h"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\DatePrototype.lut.h"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\Grammar.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableSpecificWarnings="4701"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableSpecificWarnings="4701"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_Internal|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableSpecificWarnings="4701"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_PGOInstrument|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableSpecificWarnings="4701"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_PGOOptimize|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableSpecificWarnings="4701"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_CFLite|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableSpecificWarnings="4701"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release_CFLite|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableSpecificWarnings="4701"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug_All|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ DisableSpecificWarnings="4701"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\Grammar.h"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\lexer.lut.h"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\MathObject.lut.h"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\NumberConstructor.lut.h"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\RegExpConstructor.lut.h"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\RegExpObject.lut.h"
+ >
+ </File>
+ <File
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\StringPrototype.lut.h"
>
</File>
</Filter>
<File
+ RelativePath="..\..\config.h"
+ >
+ </File>
+ <File
RelativePath=".\JavaScriptCore.def"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops index 682e01e..f489e79 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops @@ -6,7 +6,7 @@ >
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(WebKitOutputDir)\obj\JavaScriptCore\DerivedSources\";../../;../../API/;../../pcre/;../../parser/;../../bytecompiler/;../../jit/;../../runtime/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;../../wrec/;"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\icu";"$(WebKitLibrariesDir)\include\private";../../../icu/include;"$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\JavaScriptCore";"$(WebKitLibrariesDir)\include\pthreads";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility""
+ AdditionalIncludeDirectories=""$(WebKitOutputDir)\obj\JavaScriptCore\DerivedSources\";../../;../../API/;../../pcre/;../../parser/;../../bytecompiler/;../../jit/;../../runtime/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;../../wrec/;"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private";"$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\JavaScriptCore";"$(WebKitOutputDir)\include\private";"$(WebKitLibrariesDir)\include\pthreads""
PreprocessorDefinitions="__STD_C"
/>
<Tool
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh index 6d6b588..5955365 100755 --- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh +++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh @@ -1,5 +1,15 @@ #!/usr/bin/bash +# Determine if we have QuartzCore so we can turn on +QUARTZCORE_H_PATH=$(cygpath -u "${WEBKITLIBRARIESDIR}/include/QuartzCore/QuartzCore.h") +QUARTZCOREPRESENT_H_PATH=$(cygpath -u "${WEBKITOUTPUTDIR}/include/private/QuartzCorePresent.h") +if test \( ! -f "${QUARTZCOREPRESENT_H_PATH}" \) -o \( -f "${QUARTZCORE_H_PATH}" -a \( "${QUARTZCORE_H_PATH}" -nt "${QUARTZCOREPRESENT_H_PATH}" \) \) +then + mkdir -p "$(dirname "${QUARTZCOREPRESENT_H_PATH}")" + test ! -f "${QUARTZCORE_H_PATH}" + echo "#define QUARTZCORE_PRESENT $?" > "${QUARTZCOREPRESENT_H_PATH}" +fi + NUMCPUS=`../../../WebKitTools/Scripts/num-cpus` XSRCROOT="`pwd`/../.." diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj index 78f507a..7a93632 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj +++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj @@ -18,7 +18,7 @@ <Configuration
Name="Debug|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;.\WTFCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;.\WTFCommon.vsprops"
CharacterSet="1"
>
<Tool
@@ -38,6 +38,7 @@ />
<Tool
Name="VCCLCompilerTool"
+ ProgramDataBaseFileName="$(OutDir)\$(TargetName).vc80.pdb"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -70,7 +71,7 @@ <Configuration
Name="Release|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\WTFCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\release.vsprops;.\WTFCommon.vsprops"
CharacterSet="1"
WholeProgramOptimization="1"
>
@@ -91,6 +92,7 @@ />
<Tool
Name="VCCLCompilerTool"
+ ProgramDataBaseFileName="$(OutDir)\$(TargetName).vc80.pdb"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -123,7 +125,7 @@ <Configuration
Name="Debug_Internal|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\WTFCommon.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\WTFCommon.vsprops"
CharacterSet="1"
>
<Tool
@@ -143,6 +145,7 @@ />
<Tool
Name="VCCLCompilerTool"
+ ProgramDataBaseFileName="$(OutDir)\$(TargetName).vc80.pdb"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -175,7 +178,7 @@ <Configuration
Name="Debug_All|Win32"
ConfigurationType="4"
- InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\WTFCommon.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops"
+ InheritedPropertySheets="$(WebKitLibrariesDir)\tools\vsprops\FeatureDefines.vsprops;$(WebKitLibrariesDir)\tools\vsprops\common.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_internal.vsprops;.\WTFCommon.vsprops;$(WebKitLibrariesDir)\tools\vsprops\debug_all.vsprops"
CharacterSet="1"
>
<Tool
@@ -195,6 +198,7 @@ />
<Tool
Name="VCCLCompilerTool"
+ ProgramDataBaseFileName="$(OutDir)\$(TargetName).vc80.pdb"
/>
<Tool
Name="VCManagedResourceCompilerTool"
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFCommon.vsprops b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFCommon.vsprops index d78ff43..b41682f 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFCommon.vsprops +++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTFCommon.vsprops @@ -7,7 +7,7 @@ >
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\";../../;"../../os-win32/";../../pcre/;../../parser/;../../wtf/;../../wtf/unicode/;"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\icu";../../../icu/include;../../bindings;../../bindings/c;../../bindings/jni;"$(WebKitOutputDir)\include\JavaScriptCore";"$(WebKitLibrariesDir)\include\pthreads""
+ AdditionalIncludeDirectories=""$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\";../../;"../../os-win32/";../../pcre/;../../parser/;../../wtf/;../../wtf/unicode/;"$(WebKitOutputDir)\include\private";"$(WebKitLibrariesDir)\include";../../../icu/include;../../bindings;../../bindings/c;../../bindings/jni;"$(WebKitOutputDir)\include\JavaScriptCore";"$(WebKitLibrariesDir)\include\pthreads""
PreprocessorDefinitions="__STD_C"
/>
<Tool
@@ -21,6 +21,6 @@ />
<Tool
Name="VCPreBuildEventTool"
- CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c"
+ CommandLine="%SystemDrive%\cygwin\bin\which.exe bash
if errorlevel 1 set PATH=%SystemDrive%\cygwin\bin;%PATH%
cmd /c
"
/>
</VisualStudioPropertySheet>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops index 1a8f8b6..61594e1 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops +++ b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops @@ -6,7 +6,7 @@ >
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""$(WebKitOutputDir)\include";"$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\";../../;"../../os-win32/";../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;../../profiler;"$(WebKitLibrariesDir)\include\icu";"$(WebKitLibrariesDir)\include\pthreads";../../../icu/include;"$(WebKitLibrariesDir)\include";../../jit/"
+ AdditionalIncludeDirectories=""$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\";../../;"../../os-win32/";../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;../../profiler;../../jit/;"$(WebKitLibrariesDir)\include\pthreads";"$(WebKitLibrariesDir)\include""
PreprocessorDefinitions="__STD_C"
/>
<Tool
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiCommon.vsprops b/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiCommon.vsprops index 7c6d126..161f571 100644 --- a/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiCommon.vsprops +++ b/JavaScriptCore/JavaScriptCore.vcproj/testapi/testapiCommon.vsprops @@ -6,7 +6,7 @@ > <Tool Name="VCCLCompilerTool" - AdditionalIncludeDirectories=""$(ProjectDir)\..\..\API";"$(WebKitOutputDir)\include\WebCore\ForwardingHeaders";"$(WebKitOutputDir)\include\JavaScriptCore";"$(WebKitOutputDir)\include\private\JavaScriptCore";"$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\nclude\private";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility"" + AdditionalIncludeDirectories=""$(ProjectDir)\..\..\API";"$(WebKitOutputDir)\include\WebCore\ForwardingHeaders";"$(WebKitOutputDir)\include\JavaScriptCore";"$(WebKitOutputDir)\include\private\JavaScriptCore";"$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\private";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private"" WarningLevel="4" Detect64BitPortabilityProblems="true" /> diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj index e766243..58016d0 100644 --- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj @@ -44,6 +44,7 @@ 0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B4D7E620F319AC800AD7E58 /* TypeTraits.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0BDFFAE00FC6192900D69EF4 /* CrossThreadRefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 14035DB110DBFB2A00FFFFE7 /* WeakGCPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */; }; 140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; }; 140566D1107EC267005DBC8D /* JSStaticScopeObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E42C190E3938830065A544 /* JSStaticScopeObject.cpp */; }; 140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A85E0255597D01FF60F7 /* JSFunction.cpp */; }; @@ -167,6 +168,7 @@ 14BD59C50A3E8F9F00BAF59C /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; }; 14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */; }; 14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */; }; + 14BFCE6910CDB1FC00364CCE /* WeakGCMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14C5242B0F5355E900BA3D04 /* JITStubs.h in Headers */ = {isa = PBXBuildFile; fileRef = 14A6581A0F4E36F4000150FD /* JITStubs.h */; settings = {ATTRIBUTES = (Private, ); }; }; 14E9D17B107EC469004DDA21 /* JSGlobalObjectFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */; }; 14F3488F0E95EF8A003648BC /* CollectorHeapIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F3488E0E95EF8A003648BC /* CollectorHeapIterator.h */; settings = {ATTRIBUTES = (); }; }; @@ -175,6 +177,8 @@ 14F8BA4F107EC899009892DC /* Collector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8520255597D01FF60F7 /* Collector.cpp */; }; 180B9B080F16D94F009BDBC5 /* CurrentTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 180B9AF00F16C569009BDBC5 /* CurrentTime.h */; settings = {ATTRIBUTES = (Private, ); }; }; 180B9BFE0F16E94D009BDBC5 /* CurrentTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */; }; + 18BAB55310DAE054000D945B /* ThreadIdentifierDataPthreads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 18BAB52710DADFCD000D945B /* ThreadIdentifierDataPthreads.cpp */; }; + 18BAB55410DAE066000D945B /* ThreadIdentifierDataPthreads.h in Headers */ = {isa = PBXBuildFile; fileRef = 18BAB52810DADFCD000D945B /* ThreadIdentifierDataPthreads.h */; }; 1C61516C0EBAC7A00031376F /* ProfilerServer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C61516A0EBAC7A00031376F /* ProfilerServer.mm */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; }; 1C61516D0EBAC7A00031376F /* ProfilerServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C61516B0EBAC7A00031376F /* ProfilerServer.h */; }; 41359CF30FDD89AD00206180 /* DateConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = D21202290AD4310C00ED79B6 /* DateConversion.h */; }; @@ -185,6 +189,7 @@ 5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; }; 5D5D8AB60E0D0A7200F9C692 /* jsc in Copy Into Framework */ = {isa = PBXBuildFile; fileRef = 932F5BE10822A1C700736975 /* jsc */; }; 5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; }; + 5D63E9AD10F2BD6E00FC8AE9 /* StringHashFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D63E9AC10F2BD6E00FC8AE9 /* StringHashFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5D6A566B0F05995500266145 /* Threading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5D6A566A0F05995500266145 /* Threading.cpp */; }; 5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */ = {isa = PBXBuildFile; fileRef = F692A8540255597D01FF60F7 /* create_hash_table */; settings = {ATTRIBUTES = (); }; }; 6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 6507D2970E871E4A00D7D896 /* JSTypeInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -202,8 +207,12 @@ 860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */; }; 860161E60F3A83C100F84710 /* MacroAssemblerX86Common.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */; }; 863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 865F408810E7D56300947361 /* APIShims.h in Headers */ = {isa = PBXBuildFile; fileRef = 865F408710E7D56300947361 /* APIShims.h */; }; 869083150E6518D7000D36ED /* WREC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 869083130E6518D7000D36ED /* WREC.cpp */; }; 869083160E6518D7000D36ED /* WREC.h in Headers */ = {isa = PBXBuildFile; fileRef = 869083140E6518D7000D36ED /* WREC.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698B86810D44D9400D8D01B /* StringBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 8698BB3910D86BAF00D8D01B /* UStringImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698BB3710D86BAF00D8D01B /* UStringImpl.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 8698BB3A10D86BAF00D8D01B /* UStringImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8698BB3810D86BAF00D8D01B /* UStringImpl.cpp */; }; 869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; }; 86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; }; 86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */; }; @@ -559,6 +568,7 @@ 0B4D7E620F319AC800AD7E58 /* TypeTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeTraits.h; sourceTree = "<group>"; }; 0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnFastMallocPtr.h; sourceTree = "<group>"; }; 0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrossThreadRefCounted.h; sourceTree = "<group>"; }; + 14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCPtr.h; sourceTree = "<group>"; }; 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBasePrivate.h; sourceTree = "<group>"; }; 141211020A48780900480255 /* minidom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = minidom.c; path = tests/minidom.c; sourceTree = "<group>"; }; 1412110D0A48788700480255 /* minidom.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = minidom.js; path = tests/minidom.js; sourceTree = "<group>"; }; @@ -636,6 +646,7 @@ 14BD5A2A0A3E91F600BAF59C /* JSContextRef.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSContextRef.h; sourceTree = "<group>"; }; 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSValueRef.cpp; sourceTree = "<group>"; }; 14BD5A2D0A3E91F600BAF59C /* testapi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testapi.c; path = API/tests/testapi.c; sourceTree = "<group>"; }; + 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMap.h; sourceTree = "<group>"; }; 14D792640DAA03FB001A9F05 /* RegisterFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterFile.h; sourceTree = "<group>"; }; 14D857740A4696C80032146C /* testapi.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = testapi.js; path = API/tests/testapi.js; sourceTree = "<group>"; }; 14DA818E0D99FD2000B0A4FB /* JSActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSActivation.h; sourceTree = "<group>"; }; @@ -645,6 +656,8 @@ 14F3488E0E95EF8A003648BC /* CollectorHeapIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectorHeapIterator.h; sourceTree = "<group>"; }; 180B9AEF0F16C569009BDBC5 /* CurrentTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CurrentTime.cpp; sourceTree = "<group>"; }; 180B9AF00F16C569009BDBC5 /* CurrentTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CurrentTime.h; sourceTree = "<group>"; }; + 18BAB52710DADFCD000D945B /* ThreadIdentifierDataPthreads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadIdentifierDataPthreads.cpp; sourceTree = "<group>"; }; + 18BAB52810DADFCD000D945B /* ThreadIdentifierDataPthreads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadIdentifierDataPthreads.h; sourceTree = "<group>"; }; 1C61516A0EBAC7A00031376F /* ProfilerServer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ProfilerServer.mm; path = profiler/ProfilerServer.mm; sourceTree = "<group>"; }; 1C61516B0EBAC7A00031376F /* ProfilerServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerServer.h; path = profiler/ProfilerServer.h; sourceTree = "<group>"; }; 1C9051420BA9E8A70081E9D0 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; }; @@ -667,6 +680,7 @@ 5D53726E0E1C54880021E549 /* Tracing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tracing.h; sourceTree = "<group>"; }; 5D53727D0E1C55EC0021E549 /* TracingDtrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TracingDtrace.h; sourceTree = "<group>"; }; 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libedit.dylib; path = /usr/lib/libedit.dylib; sourceTree = "<absolute>"; }; + 5D63E9AC10F2BD6E00FC8AE9 /* StringHashFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringHashFunctions.h; sourceTree = "<group>"; }; 5D6A566A0F05995500266145 /* Threading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Threading.cpp; sourceTree = "<group>"; }; 5DA479650CFBCF56009328A0 /* TCPackedCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCPackedCache.h; sourceTree = "<group>"; }; 5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MallocZoneSupport.h; sourceTree = "<group>"; }; @@ -726,8 +740,12 @@ 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86_64.h; sourceTree = "<group>"; }; 860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86Common.h; sourceTree = "<group>"; }; 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerCodeRef.h; sourceTree = "<group>"; }; + 865F408710E7D56300947361 /* APIShims.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIShims.h; sourceTree = "<group>"; }; 869083130E6518D7000D36ED /* WREC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WREC.cpp; sourceTree = "<group>"; }; 869083140E6518D7000D36ED /* WREC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WREC.h; sourceTree = "<group>"; }; + 8698B86810D44D9400D8D01B /* StringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringBuilder.h; sourceTree = "<group>"; }; + 8698BB3710D86BAF00D8D01B /* UStringImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UStringImpl.h; sourceTree = "<group>"; }; + 8698BB3810D86BAF00D8D01B /* UStringImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UStringImpl.cpp; sourceTree = "<group>"; }; 869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; }; 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; }; 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; }; @@ -1178,6 +1196,7 @@ isa = PBXGroup; children = ( 1482B78A0A4305AB00517CFC /* APICast.h */, + 865F408710E7D56300947361 /* APIShims.h */, 1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */, 1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */, BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */, @@ -1350,11 +1369,14 @@ 969A07290ED1CE6900F1F681 /* SegmentedVector.h */, FE1B44790ECCD73B004F4DD1 /* StdLibExtras.h */, E11D51750B2E798D0056C188 /* StringExtras.h */, + 5D63E9AC10F2BD6E00FC8AE9 /* StringHashFunctions.h */, 5DA479650CFBCF56009328A0 /* TCPackedCache.h */, 6541BD6E08E80A17002CBEE7 /* TCPageMap.h */, 6541BD6F08E80A17002CBEE7 /* TCSpinLock.h */, 6541BD7008E80A17002CBEE7 /* TCSystemAlloc.cpp */, 6541BD7108E80A17002CBEE7 /* TCSystemAlloc.h */, + 18BAB52710DADFCD000D945B /* ThreadIdentifierDataPthreads.cpp */, + 18BAB52810DADFCD000D945B /* ThreadIdentifierDataPthreads.h */, 5D6A566A0F05995500266145 /* Threading.cpp */, E1EE79220D6C95CD00FEA3BA /* Threading.h */, E1EE793C0D6C9B9200FEA3BA /* ThreadingPthreads.cpp */, @@ -1392,10 +1414,10 @@ isa = PBXGroup; children = ( 969A07200ED1CE3300F1F681 /* BytecodeGenerator.cpp */, - 655EB29A10CE2581001A990E /* NodesCodegen.cpp */, 969A07210ED1CE3300F1F681 /* BytecodeGenerator.h */, 969A07270ED1CE6900F1F681 /* Label.h */, 960097A50EBABB58007A7297 /* LabelScope.h */, + 655EB29A10CE2581001A990E /* NodesCodegen.cpp */, 969A07280ED1CE6900F1F681 /* RegisterID.h */, ); path = bytecompiler; @@ -1530,6 +1552,10 @@ 14F252560D08DD8D004ECFFF /* JSVariableObject.h */, 65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */, 65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */, + A7C2216B10C7469C00F97913 /* JSZombie.cpp */, + A7C2216B10C7469C00F97913 /* JSZombie.cpp */, + A7C2216810C745E000F97913 /* JSZombie.h */, + A7C2216810C745E000F97913 /* JSZombie.h */, A7E2EA6A0FB460CF00601F06 /* LiteralParser.cpp */, A7E2EA690FB460CF00601F06 /* LiteralParser.h */, F692A8680255597D01FF60F7 /* Lookup.cpp */, @@ -1582,6 +1608,7 @@ 7E2C6C980D31C6B6002D44E2 /* ScopeChainMark.h */, 93303FE80E6A72B500786E6A /* SmallStrings.cpp */, 93303FEA0E6A72C000786E6A /* SmallStrings.h */, + 8698B86810D44D9400D8D01B /* StringBuilder.h */, BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */, BC18C3C10E16EE3300B34460 /* StringConstructor.h */, BC18C3C20E16EE3300B34460 /* StringObject.cpp */, @@ -1601,9 +1628,11 @@ 5D53726E0E1C54880021E549 /* Tracing.h */, F692A8850255597D01FF60F7 /* UString.cpp */, F692A8860255597D01FF60F7 /* UString.h */, + 8698BB3810D86BAF00D8D01B /* UStringImpl.cpp */, + 8698BB3710D86BAF00D8D01B /* UStringImpl.h */, + 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */, + 14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */, 1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */, - A7C2216810C745E000F97913 /* JSZombie.h */, - A7C2216B10C7469C00F97913 /* JSZombie.cpp */, ); path = runtime; sourceTree = "<group>"; @@ -1760,6 +1789,7 @@ 860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */, BC18C3E40E16F5CD00B34460 /* AlwaysInline.h in Headers */, BC18C3E50E16F5CD00B34460 /* APICast.h in Headers */, + 865F408810E7D56300947361 /* APIShims.h in Headers */, BCF605140E203EF800B9A64D /* ArgList.h in Headers */, BC257DE80E1F51C50016B6C9 /* Arguments.h in Headers */, 86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */, @@ -1797,6 +1827,7 @@ BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */, 41359CF30FDD89AD00206180 /* DateConversion.h in Headers */, BC1166020E1997B4008066DD /* DateInstance.h in Headers */, + 14A1563210966365006FA260 /* DateInstanceCache.h in Headers */, 41359CF70FDD89CB00206180 /* DateMath.h in Headers */, BCD2034C0E17135E002C7E82 /* DatePrototype.h in Headers */, BCD203E80E1718F4002C7E82 /* DatePrototype.lut.h in Headers */, @@ -1813,6 +1844,7 @@ 96A746410EDDF70600904779 /* Escapes.h in Headers */, 969A07980ED1D3AE00F1F681 /* EvalCodeCache.h in Headers */, BC18C4000E16F5CD00B34460 /* ExceptionHelpers.h in Headers */, + 86CAFEE31035DDE60028A609 /* Executable.h in Headers */, A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */, E48E0F2D0F82151700A8CA37 /* FastAllocBase.h in Headers */, BC18C4020E16F5CD00B34460 /* FastMalloc.h in Headers */, @@ -1855,6 +1887,7 @@ BC1167DA0E19BCC9008066DD /* JSCell.h in Headers */, BC18C41D0E16F5CD00B34460 /* JSClassRef.h in Headers */, BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */, + 148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */, BC18C41F0E16F5CD00B34460 /* JSFunction.h in Headers */, BC18C4200E16F5CD00B34460 /* JSGlobalData.h in Headers */, BC18C4210E16F5CD00B34460 /* JSGlobalObject.h in Headers */, @@ -1865,12 +1898,14 @@ BC18C4240E16F5CD00B34460 /* JSObject.h in Headers */, BC18C4250E16F5CD00B34460 /* JSObjectRef.h in Headers */, A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */, + BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */, 9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */, BC18C4260E16F5CD00B34460 /* JSRetainPtr.h in Headers */, BC18C4270E16F5CD00B34460 /* JSString.h in Headers */, BC18C4280E16F5CD00B34460 /* JSStringRef.h in Headers */, BC18C4290E16F5CD00B34460 /* JSStringRefCF.h in Headers */, BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */, + 6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */, BC18C42B0E16F5CD00B34460 /* JSValue.h in Headers */, BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */, BC18C42D0E16F5CD00B34460 /* JSVariableObject.h in Headers */, @@ -1895,6 +1930,7 @@ 860161E60F3A83C100F84710 /* MacroAssemblerX86Common.h in Headers */, BC18C4390E16F5CD00B34460 /* MainThread.h in Headers */, BC18C43A0E16F5CD00B34460 /* MallocZoneSupport.h in Headers */, + A7795590101A74D500114E55 /* MarkStack.h in Headers */, BC18C43B0E16F5CD00B34460 /* MathExtras.h in Headers */, BC18C43C0E16F5CD00B34460 /* MathObject.h in Headers */, BC18C52A0E16FCC200B34460 /* MathObject.lut.h in Headers */, @@ -1910,6 +1946,7 @@ BC18C4420E16F5CD00B34460 /* NumberConstructor.lut.h in Headers */, BC18C4430E16F5CD00B34460 /* NumberObject.h in Headers */, BC18C4440E16F5CD00B34460 /* NumberPrototype.h in Headers */, + 142D3939103E4560007DCB52 /* NumericStrings.h in Headers */, BC18C4450E16F5CD00B34460 /* ObjectConstructor.h in Headers */, BC18C4460E16F5CD00B34460 /* ObjectPrototype.h in Headers */, E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */, @@ -1926,11 +1963,13 @@ BC18C44D0E16F5CD00B34460 /* pcre.h in Headers */, BC18C44E0E16F5CD00B34460 /* pcre_internal.h in Headers */, BC18C44F0E16F5CD00B34460 /* Platform.h in Headers */, + A7D649AA1015224E009B2E1B /* PossiblyNull.h in Headers */, BC18C4500E16F5CD00B34460 /* Profile.h in Headers */, 95CD45770E1C4FDD0085358E /* ProfileGenerator.h in Headers */, BC18C4510E16F5CD00B34460 /* ProfileNode.h in Headers */, BC18C4520E16F5CD00B34460 /* Profiler.h in Headers */, 1C61516D0EBAC7A00031376F /* ProfilerServer.h in Headers */, + A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */, BC95437D0EBA70FD0072B6D3 /* PropertyMapHashTable.h in Headers */, BC18C4540E16F5CD00B34460 /* PropertyNameArray.h in Headers */, BC18C4550E16F5CD00B34460 /* PropertySlot.h in Headers */, @@ -1969,8 +2008,10 @@ BC18C4640E16F5CD00B34460 /* SourceCode.h in Headers */, BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */, FE1B447A0ECCD73B004F4DD1 /* StdLibExtras.h in Headers */, + 8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */, BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */, BC18C4670E16F5CD00B34460 /* StringExtras.h in Headers */, + 5D63E9AD10F2BD6E00FC8AE9 /* StringHashFunctions.h in Headers */, BC18C4680E16F5CD00B34460 /* StringObject.h in Headers */, BC18C4690E16F5CD00B34460 /* StringObjectThatMasqueradesAsUndefined.h in Headers */, BC18C46A0E16F5CD00B34460 /* StringPrototype.h in Headers */, @@ -1984,36 +2025,31 @@ BC18C46D0E16F5CD00B34460 /* TCPageMap.h in Headers */, BC18C46E0E16F5CD00B34460 /* TCSpinLock.h in Headers */, BC18C46F0E16F5CD00B34460 /* TCSystemAlloc.h in Headers */, + 18BAB55410DAE066000D945B /* ThreadIdentifierDataPthreads.h in Headers */, BC18C4700E16F5CD00B34460 /* Threading.h in Headers */, BC18C4710E16F5CD00B34460 /* ThreadSpecific.h in Headers */, 14A42E400F4F60EE00599099 /* TimeoutChecker.h in Headers */, 5D53726F0E1C54880021E549 /* Tracing.h in Headers */, - 6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */, 0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */, BC18C4720E16F5CD00B34460 /* ucpinternal.h in Headers */, BC18C4730E16F5CD00B34460 /* Unicode.h in Headers */, BC18C4740E16F5CD00B34460 /* UnicodeIcu.h in Headers */, BC18C4750E16F5CD00B34460 /* UnusedParam.h in Headers */, BC18C4760E16F5CD00B34460 /* UString.h in Headers */, + 8698BB3910D86BAF00D8D01B /* UStringImpl.h in Headers */, BC18C4770E16F5CD00B34460 /* UTF8.h in Headers */, BC18C4780E16F5CD00B34460 /* Vector.h in Headers */, BC18C4790E16F5CD00B34460 /* VectorTraits.h in Headers */, 96DD73790F9DA3100027FBCC /* VMTags.h in Headers */, + 14BFCE6910CDB1FC00364CCE /* WeakGCMap.h in Headers */, + 14035DB110DBFB2A00FFFFE7 /* WeakGCPtr.h in Headers */, + 1420BE7B10AA6DDB00F455D2 /* WeakRandom.h in Headers */, BC18C47A0E16F5CD00B34460 /* WebKitAvailability.h in Headers */, 869083160E6518D7000D36ED /* WREC.h in Headers */, 1429DA830ED2482900B89619 /* WRECFunctors.h in Headers */, 1429DAE00ED2645B00B89619 /* WRECGenerator.h in Headers */, 1429DABF0ED263E700B89619 /* WRECParser.h in Headers */, 9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */, - A7795590101A74D500114E55 /* MarkStack.h in Headers */, - A7D649AA1015224E009B2E1B /* PossiblyNull.h in Headers */, - 86CAFEE31035DDE60028A609 /* Executable.h in Headers */, - 142D3939103E4560007DCB52 /* NumericStrings.h in Headers */, - A7FB61001040C38B0017A286 /* PropertyDescriptor.h in Headers */, - BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */, - 148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */, - 14A1563210966365006FA260 /* DateInstanceCache.h in Headers */, - 1420BE7B10AA6DDB00F455D2 /* WeakRandom.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2390,6 +2426,7 @@ 14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */, 147F39D7107EC37600427A48 /* JSVariableObject.cpp in Sources */, 14280870107EC1340013E7B2 /* JSWrapperObject.cpp in Sources */, + A7C2217810C7479400F97913 /* JSZombie.cpp in Sources */, BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */, 148F21B0107EC5410042EC2C /* Lexer.cpp in Sources */, A7E2EA6C0FB460CF00601F06 /* LiteralParser.cpp in Sources */, @@ -2402,6 +2439,7 @@ 14469DE0107EC7E700650446 /* NativeErrorConstructor.cpp in Sources */, 14469DE1107EC7E700650446 /* NativeErrorPrototype.cpp in Sources */, 148F21B7107EC5470042EC2C /* Nodes.cpp in Sources */, + 655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */, 14469DE2107EC7E700650446 /* NumberConstructor.cpp in Sources */, 14469DE3107EC7E700650446 /* NumberObject.cpp in Sources */, 14469DE4107EC7E700650446 /* NumberPrototype.cpp in Sources */, @@ -2446,18 +2484,18 @@ 7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */, BCCF0D0C0EF0B8A500413C8F /* StructureStubInfo.cpp in Sources */, 14F8BA43107EC88C009892DC /* TCSystemAlloc.cpp in Sources */, + 18BAB55310DAE054000D945B /* ThreadIdentifierDataPthreads.cpp in Sources */, 5D6A566B0F05995500266145 /* Threading.cpp in Sources */, E1EE793D0D6C9B9200FEA3BA /* ThreadingPthreads.cpp in Sources */, 14A42E3F0F4F60EE00599099 /* TimeoutChecker.cpp in Sources */, 0B330C270F38C62300692DE3 /* TypeTraits.cpp in Sources */, 14469DEE107EC7E700650446 /* UString.cpp in Sources */, + 8698BB3A10D86BAF00D8D01B /* UStringImpl.cpp in Sources */, E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */, 869083150E6518D7000D36ED /* WREC.cpp in Sources */, 1429DA820ED2482900B89619 /* WRECFunctors.cpp in Sources */, 1429DAE10ED2645B00B89619 /* WRECGenerator.cpp in Sources */, 1429DAC00ED263E700B89619 /* WRECParser.cpp in Sources */, - A7C2217810C7479400F97913 /* JSZombie.cpp in Sources */, - 655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2556,10 +2594,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; buildSettings = { - BUILD_VARIANTS = ( - normal, - debug, - ); + BUILD_VARIANTS = normal; }; name = Production; }; diff --git a/JavaScriptCore/JavaScriptCoreSources.bkl b/JavaScriptCore/JavaScriptCoreSources.bkl index 1f36c1c..e69de29 100644 --- a/JavaScriptCore/JavaScriptCoreSources.bkl +++ b/JavaScriptCore/JavaScriptCoreSources.bkl @@ -1,193 +0,0 @@ -<?xml version="1.0" ?> -<!-- -Copyright (C) 2006, 2007 Kevin Ollivier. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - its contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Source files for JSCore. ---> -<makefile> - <set append="1" var="JSCORE_API_SOURCES"> - API/JSBase.cpp - API/JSCallbackConstructor.cpp - API/JSCallbackFunction.cpp - API/JSCallbackObject.cpp - API/JSClassRef.cpp - API/JSContextRef.cpp - API/JSObjectRef.cpp - API/JSStringRef.cpp - API/JSValueRef.cpp - API/OpaqueJSString.cpp - </set> - <set append="1" var="JSCORE_BYTECOMPILER_SOURCES"> - bytecompiler/BytecodeGenerator.cpp - bytecompiler/NodesCodegen.cpp - </set> - <set append="1" var="JSCORE_DEBUGGER_SOURCES"> - debugger/Debugger.cpp - debugger/DebuggerActivation.cpp - debugger/DebuggerCallFrame.cpp - </set> - <set append="1" var="JSCORE_JSC_SOURCES"> - DerivedSources/JavaScriptCore/Grammar.cpp - wtf/dtoa.cpp - </set> - <set append="1" var="JSCORE_PCRE_SOURCES"> - pcre/pcre_compile.cpp - pcre/pcre_exec.cpp - pcre/pcre_tables.cpp - pcre/pcre_ucp_searchfuncs.cpp - pcre/pcre_xclass.cpp - </set> - <set append="1" var="JSCORE_PARSER_SOURCES"> - parser/Lexer.cpp - parser/Nodes.cpp - parser/Parser.cpp - parser/ParserArena.cpp - </set> - <set append="1" var="JSCORE_PROFILER_SOURCES"> - profiler/HeavyProfile.cpp - profiler/ProfileGenerator.cpp - profiler/ProfileNode.cpp - profiler/Profile.cpp - profiler/Profiler.cpp - profiler/TreeProfile.cpp - </set> - <set append="1" var="JSCORE_RUNTIME_SOURCES"> - runtime/ArgList.cpp - runtime/Arguments.cpp - runtime/ArrayConstructor.cpp - runtime/ArrayPrototype.cpp - runtime/BooleanConstructor.cpp - runtime/BooleanObject.cpp - runtime/BooleanPrototype.cpp - runtime/CallData.cpp - runtime/Collector.cpp - runtime/CommonIdentifiers.cpp - runtime/ConstructData.cpp - runtime/DateConstructor.cpp - runtime/DateConversion.cpp - runtime/DateInstance.cpp - wtf/DateMath.cpp - runtime/DatePrototype.cpp - runtime/Error.cpp - runtime/ErrorConstructor.cpp - runtime/ErrorInstance.cpp - runtime/ErrorPrototype.cpp - interpreter/CallFrame.cpp - runtime/FunctionConstructor.cpp - runtime/FunctionPrototype.cpp - runtime/GetterSetter.cpp - runtime/GlobalEvalFunction.cpp - runtime/Identifier.cpp - runtime/InitializeThreading.cpp - runtime/InternalFunction.cpp - runtime/Completion.cpp - runtime/JSActivation.cpp - runtime/JSArray.cpp - runtime/JSByteArray.cpp - runtime/JSCell.cpp - runtime/JSFunction.cpp - runtime/JSGlobalData.cpp - runtime/JSGlobalObject.cpp - runtime/JSGlobalObjectFunctions.cpp - runtime/JSImmediate.cpp - runtime/JSLock.cpp - runtime/JSNotAnObject.cpp - runtime/JSNumberCell.cpp - runtime/JSObject.cpp - runtime/JSONObject.cpp - runtime/JSPropertyNameIterator.cpp - runtime/JSStaticScopeObject.cpp - runtime/JSString.cpp - runtime/JSValue.cpp - runtime/JSVariableObject.cpp - runtime/JSWrapperObject.cpp - runtime/LiteralParser.cpp - runtime/Lookup.cpp - runtime/MathObject.cpp - runtime/NativeErrorConstructor.cpp - runtime/NativeErrorPrototype.cpp - runtime/NumberConstructor.cpp - runtime/NumberObject.cpp - runtime/NumberPrototype.cpp - runtime/ObjectConstructor.cpp - runtime/ObjectPrototype.cpp - runtime/Operations.cpp - runtime/PropertyDescriptor.cpp - runtime/PropertyNameArray.cpp - runtime/PropertySlot.cpp - runtime/PrototypeFunction.cpp - runtime/RegExp.cpp - runtime/RegExpConstructor.cpp - runtime/RegExpObject.cpp - runtime/RegExpPrototype.cpp - runtime/ScopeChain.cpp - runtime/SmallStrings.cpp - runtime/StringConstructor.cpp - runtime/StringObject.cpp - runtime/StringPrototype.cpp - runtime/Structure.cpp - runtime/StructureChain.cpp - runtime/UString.cpp - </set> - <set append="1" var="JSCORE_VM_SOURCES"> - bytecode/CodeBlock.cpp - bytecode/StructureStubInfo.cpp - bytecode/JumpTable.cpp - runtime/ExceptionHelpers.cpp - runtime/TimeoutChecker.cpp - interpreter/Interpreter.cpp - bytecode/Opcode.cpp - bytecode/SamplingTool.cpp - interpreter/RegisterFile.cpp - jit/ExecutableAllocator.cpp - </set> - <set append="1" var="JSCORE_VM_SOURCES_WIN"> - jit/ExecutableAllocatorWin.cpp - </set> - <set append="1" var="JSCORE_VM_SOURCES_POSIX"> - jit/ExecutableAllocatorPosix.cpp - </set> - <set append="1" var="JSCORE_WTF_SOURCES"> - wtf/Assertions.cpp - wtf/ByteArray.cpp - wtf/CurrentTime.cpp - wtf/FastMalloc.cpp - wtf/HashTable.cpp - wtf/MainThread.cpp - wtf/RandomNumber.cpp - wtf/RefCountedLeakCounter.cpp - wtf/TCSystemAlloc.cpp - wtf/Threading.cpp - wtf/ThreadingNone.cpp - wtf/TypeTraits.cpp - wtf/wx/MainThreadWx.cpp - wtf/unicode/CollatorDefault.cpp - wtf/unicode/icu/CollatorICU.cpp - wtf/unicode/UTF8.cpp - </set> - -</makefile> diff --git a/JavaScriptCore/assembler/ARMAssembler.cpp b/JavaScriptCore/assembler/ARMAssembler.cpp index 81c3222..6dd2b87 100644 --- a/JavaScriptCore/assembler/ARMAssembler.cpp +++ b/JavaScriptCore/assembler/ARMAssembler.cpp @@ -26,7 +26,7 @@ #include "config.h" -#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) +#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) #include "ARMAssembler.h" @@ -34,39 +34,6 @@ namespace JSC { // Patching helpers -ARMWord* ARMAssembler::getLdrImmAddress(ARMWord* insn, uint32_t* constPool) -{ - // Must be an ldr ..., [pc +/- imm] - ASSERT((*insn & 0x0f7f0000) == 0x051f0000); - - if (constPool && (*insn & 0x1)) - return reinterpret_cast<ARMWord*>(constPool + ((*insn & SDT_OFFSET_MASK) >> 1)); - - ARMWord addr = reinterpret_cast<ARMWord>(insn) + 2 * sizeof(ARMWord); - if (*insn & DT_UP) - return reinterpret_cast<ARMWord*>(addr + (*insn & SDT_OFFSET_MASK)); - else - return reinterpret_cast<ARMWord*>(addr - (*insn & SDT_OFFSET_MASK)); -} - -void ARMAssembler::linkBranch(void* code, JmpSrc from, void* to, int useConstantPool) -{ - ARMWord* insn = reinterpret_cast<ARMWord*>(code) + (from.m_offset / sizeof(ARMWord)); - - if (!useConstantPool) { - int diff = reinterpret_cast<ARMWord*>(to) - reinterpret_cast<ARMWord*>(insn + 2); - - if ((diff <= BOFFSET_MAX && diff >= BOFFSET_MIN)) { - *insn = B | getConditionalField(*insn) | (diff & BRANCH_MASK); - ExecutableAllocator::cacheFlush(insn, sizeof(ARMWord)); - return; - } - } - ARMWord* addr = getLdrImmAddress(insn); - *addr = reinterpret_cast<ARMWord>(to); - ExecutableAllocator::cacheFlush(addr, sizeof(ARMWord)); -} - void ARMAssembler::patchConstantPoolLoad(void* loadAddr, void* constPoolAddr) { ARMWord *ldr = reinterpret_cast<ARMWord*>(loadAddr); @@ -272,10 +239,8 @@ void ARMAssembler::moveImm(ARMWord imm, int dest) ARMWord ARMAssembler::encodeComplexImm(ARMWord imm, int dest) { - ARMWord tmp; - -#if ARM_ARCH_VERSION >= 7 - tmp = getImm16Op2(imm); +#if WTF_ARM_ARCH_AT_LEAST(7) + ARMWord tmp = getImm16Op2(imm); if (tmp != INVALID_IMM) { movw_r(dest, tmp); return dest; @@ -390,10 +355,17 @@ void* ARMAssembler::executableCopy(ExecutablePool* allocator) // The last bit is set if the constant must be placed on constant pool. int pos = (*iter) & (~0x1); ARMWord* ldrAddr = reinterpret_cast<ARMWord*>(data + pos); - ARMWord offset = *getLdrImmAddress(ldrAddr); - if (offset != 0xffffffff) { - JmpSrc jmpSrc(pos); - linkBranch(data, jmpSrc, data + offset, ((*iter) & 1)); + ARMWord* addr = getLdrImmAddress(ldrAddr); + if (*addr != 0xffffffff) { + if (!(*iter & 1)) { + int diff = reinterpret_cast<ARMWord*>(data + *addr) - (ldrAddr + DefaultPrefetching); + + if ((diff <= BOFFSET_MAX && diff >= BOFFSET_MIN)) { + *ldrAddr = B | getConditionalField(*ldrAddr) | (diff & BRANCH_MASK); + continue; + } + } + *addr = reinterpret_cast<ARMWord>(data + *addr); } } @@ -402,4 +374,4 @@ void* ARMAssembler::executableCopy(ExecutablePool* allocator) } // namespace JSC -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) +#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) diff --git a/JavaScriptCore/assembler/ARMAssembler.h b/JavaScriptCore/assembler/ARMAssembler.h index 712473e..6967b37 100644 --- a/JavaScriptCore/assembler/ARMAssembler.h +++ b/JavaScriptCore/assembler/ARMAssembler.h @@ -29,7 +29,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) +#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) #include "AssemblerBufferWithConstantPool.h" #include <wtf/Assertions.h> @@ -138,11 +138,11 @@ namespace JSC { FSITOD = 0x0eb80bc0, FTOSID = 0x0ebd0b40, FMSTAT = 0x0ef1fa10, -#if ARM_ARCH_VERSION >= 5 +#if WTF_ARM_ARCH_AT_LEAST(5) CLZ = 0x016f0f10, BKPT = 0xe120070, #endif -#if ARM_ARCH_VERSION >= 7 +#if WTF_ARM_ARCH_AT_LEAST(7) MOVW = 0x03000000, MOVT = 0x03400000, #endif @@ -183,6 +183,7 @@ namespace JSC { }; static const ARMWord INVALID_IMM = 0xf0000000; + static const int DefaultPrefetching = 2; class JmpSrc { friend class ARMAssembler; @@ -342,7 +343,7 @@ namespace JSC { emitInst(static_cast<ARMWord>(cc) | MOV, rd, ARMRegisters::r0, op2); } -#if ARM_ARCH_VERSION >= 7 +#if WTF_ARM_ARCH_AT_LEAST(7) void movw_r(int rd, ARMWord op2, Condition cc = AL) { ASSERT((op2 | 0xf0fff) == 0xf0fff); @@ -530,7 +531,7 @@ namespace JSC { m_buffer.putInt(static_cast<ARMWord>(cc) | FMSTAT); } -#if ARM_ARCH_VERSION >= 5 +#if WTF_ARM_ARCH_AT_LEAST(5) void clz_r(int rd, int rm, Condition cc = AL) { m_buffer.putInt(static_cast<ARMWord>(cc) | CLZ | RD(rd) | RM(rm)); @@ -539,7 +540,7 @@ namespace JSC { void bkpt(ARMWord value) { -#if ARM_ARCH_VERSION >= 5 +#if WTF_ARM_ARCH_AT_LEAST(5) m_buffer.putInt(BKPT | ((value & 0xff0) << 4) | (value & 0xf)); #else // Cannot access to Zero memory address @@ -632,15 +633,32 @@ namespace JSC { // Patching helpers - static ARMWord* getLdrImmAddress(ARMWord* insn, uint32_t* constPool = 0); - static void linkBranch(void* code, JmpSrc from, void* to, int useConstantPool = 0); + static ARMWord* getLdrImmAddress(ARMWord* insn) + { + // Must be an ldr ..., [pc +/- imm] + ASSERT((*insn & 0x0f7f0000) == 0x051f0000); + + ARMWord addr = reinterpret_cast<ARMWord>(insn) + DefaultPrefetching * sizeof(ARMWord); + if (*insn & DT_UP) + return reinterpret_cast<ARMWord*>(addr + (*insn & SDT_OFFSET_MASK)); + return reinterpret_cast<ARMWord*>(addr - (*insn & SDT_OFFSET_MASK)); + } + + static ARMWord* getLdrImmAddressOnPool(ARMWord* insn, uint32_t* constPool) + { + // Must be an ldr ..., [pc +/- imm] + ASSERT((*insn & 0x0f7f0000) == 0x051f0000); + + if (*insn & 0x1) + return reinterpret_cast<ARMWord*>(constPool + ((*insn & SDT_OFFSET_MASK) >> 1)); + return getLdrImmAddress(insn); + } static void patchPointerInternal(intptr_t from, void* to) { ARMWord* insn = reinterpret_cast<ARMWord*>(from); ARMWord* addr = getLdrImmAddress(insn); *addr = reinterpret_cast<ARMWord>(to); - ExecutableAllocator::cacheFlush(addr, sizeof(ARMWord)); } static ARMWord patchConstantPoolLoad(ARMWord load, ARMWord value) @@ -685,12 +703,13 @@ namespace JSC { void linkJump(JmpSrc from, JmpDst to) { ARMWord* insn = reinterpret_cast<ARMWord*>(m_buffer.data()) + (from.m_offset / sizeof(ARMWord)); - *getLdrImmAddress(insn, m_buffer.poolAddress()) = static_cast<ARMWord>(to.m_offset); + ARMWord* addr = getLdrImmAddressOnPool(insn, m_buffer.poolAddress()); + *addr = static_cast<ARMWord>(to.m_offset); } static void linkJump(void* code, JmpSrc from, void* to) { - linkBranch(code, from, to); + patchPointerInternal(reinterpret_cast<intptr_t>(code) + from.m_offset, to); } static void relinkJump(void* from, void* to) @@ -700,12 +719,12 @@ namespace JSC { static void linkCall(void* code, JmpSrc from, void* to) { - linkBranch(code, from, to, true); + patchPointerInternal(reinterpret_cast<intptr_t>(code) + from.m_offset, to); } static void relinkCall(void* from, void* to) { - relinkJump(from, to); + patchPointerInternal(reinterpret_cast<intptr_t>(from) - sizeof(ARMWord), to); } // Address operations @@ -747,7 +766,7 @@ namespace JSC { static ARMWord getOp2(ARMWord imm); -#if ARM_ARCH_VERSION >= 7 +#if WTF_ARM_ARCH_AT_LEAST(7) static ARMWord getImm16Op2(ARMWord imm) { if (imm <= 0xffff) @@ -812,6 +831,6 @@ namespace JSC { } // namespace JSC -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) +#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) #endif // ARMAssembler_h diff --git a/JavaScriptCore/assembler/ARMv7Assembler.h b/JavaScriptCore/assembler/ARMv7Assembler.h index e253a53..4e394b2 100644 --- a/JavaScriptCore/assembler/ARMv7Assembler.h +++ b/JavaScriptCore/assembler/ARMv7Assembler.h @@ -28,7 +28,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM(ARM_THUMB2) +#if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2) #include "AssemblerBuffer.h" #include <wtf/Assertions.h> @@ -201,10 +201,10 @@ class ARMThumbImmediate { ALWAYS_INLINE static void countLeadingZerosPartial(uint32_t& value, int32_t& zeros, const int N) { - if (value & ~((1<<N)-1)) /* check for any of the top N bits (of 2N bits) are set */ \ - value >>= N; /* if any were set, lose the bottom N */ \ - else /* if none of the top N bits are set, */ \ - zeros += N; /* then we have identified N leading zeros */ + if (value & ~((1 << N) - 1)) /* check for any of the top N bits (of 2N bits) are set */ + value >>= N; /* if any were set, lose the bottom N */ + else /* if none of the top N bits are set, */ + zeros += N; /* then we have identified N leading zeros */ } static int32_t countLeadingZeros(uint32_t value) @@ -1832,6 +1832,6 @@ private: } // namespace JSC -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_THUMB2) +#endif // ENABLE(ASSEMBLER) && CPU(ARM_THUMB2) #endif // ARMAssembler_h diff --git a/JavaScriptCore/assembler/AbstractMacroAssembler.h b/JavaScriptCore/assembler/AbstractMacroAssembler.h index 525fe98..198e8d1 100644 --- a/JavaScriptCore/assembler/AbstractMacroAssembler.h +++ b/JavaScriptCore/assembler/AbstractMacroAssembler.h @@ -173,16 +173,16 @@ public: struct Imm32 { explicit Imm32(int32_t value) : m_value(value) -#if PLATFORM(ARM) +#if CPU(ARM) , m_isPointer(false) #endif { } -#if !PLATFORM(X86_64) +#if !CPU(X86_64) explicit Imm32(ImmPtr ptr) : m_value(ptr.asIntptr()) -#if PLATFORM(ARM) +#if CPU(ARM) , m_isPointer(true) #endif { @@ -190,7 +190,7 @@ public: #endif int32_t m_value; -#if PLATFORM(ARM) +#if CPU(ARM) // We rely on being able to regenerate code to recover exception handling // information. Since ARMv7 supports 16-bit immediates there is a danger // that if pointer values change the layout of the generated code will change. diff --git a/JavaScriptCore/assembler/MacroAssembler.h b/JavaScriptCore/assembler/MacroAssembler.h index 858707d..76bd205 100644 --- a/JavaScriptCore/assembler/MacroAssembler.h +++ b/JavaScriptCore/assembler/MacroAssembler.h @@ -30,19 +30,19 @@ #if ENABLE(ASSEMBLER) -#if PLATFORM(ARM_THUMB2) +#if CPU(ARM_THUMB2) #include "MacroAssemblerARMv7.h" namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; }; -#elif PLATFORM(ARM_TRADITIONAL) +#elif CPU(ARM_TRADITIONAL) #include "MacroAssemblerARM.h" namespace JSC { typedef MacroAssemblerARM MacroAssemblerBase; }; -#elif PLATFORM(X86) +#elif CPU(X86) #include "MacroAssemblerX86.h" namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; }; -#elif PLATFORM(X86_64) +#elif CPU(X86_64) #include "MacroAssemblerX86_64.h" namespace JSC { typedef MacroAssemblerX86_64 MacroAssemblerBase; }; @@ -60,7 +60,7 @@ public: using MacroAssemblerBase::jump; using MacroAssemblerBase::branch32; using MacroAssemblerBase::branch16; -#if PLATFORM(X86_64) +#if CPU(X86_64) using MacroAssemblerBase::branchPtr; using MacroAssemblerBase::branchTestPtr; #endif @@ -133,7 +133,8 @@ public: // Ptr methods // On 32-bit platforms (i.e. x86), these methods directly map onto their 32-bit equivalents. -#if !PLATFORM(X86_64) + // FIXME: should this use a test for 32-bitness instead of this specific exception? +#if !CPU(X86_64) void addPtr(RegisterID src, RegisterID dest) { add32(src, dest); diff --git a/JavaScriptCore/assembler/MacroAssemblerARM.cpp b/JavaScriptCore/assembler/MacroAssemblerARM.cpp index d726ecd..b5b20fa 100644 --- a/JavaScriptCore/assembler/MacroAssemblerARM.cpp +++ b/JavaScriptCore/assembler/MacroAssemblerARM.cpp @@ -26,11 +26,11 @@ #include "config.h" -#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) +#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) #include "MacroAssemblerARM.h" -#if PLATFORM(LINUX) +#if OS(LINUX) #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -43,7 +43,7 @@ namespace JSC { static bool isVFPPresent() { -#if PLATFORM(LINUX) +#if OS(LINUX) int fd = open("/proc/self/auxv", O_RDONLY); if (fd > 0) { Elf32_auxv_t aux; @@ -62,7 +62,8 @@ static bool isVFPPresent() const bool MacroAssemblerARM::s_isVFPPresent = isVFPPresent(); -#if defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_REQUIRE_NATURAL_ALIGNMENT +#if CPU(ARMV5_OR_LOWER) +/* On ARMv5 and below, natural alignment is required. */ void MacroAssemblerARM::load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest) { ARMWord op2; @@ -91,4 +92,4 @@ void MacroAssemblerARM::load32WithUnalignedHalfWords(BaseIndex address, Register } -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) +#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) diff --git a/JavaScriptCore/assembler/MacroAssemblerARM.h b/JavaScriptCore/assembler/MacroAssemblerARM.h index 24e2e11..21b8de8 100644 --- a/JavaScriptCore/assembler/MacroAssemblerARM.h +++ b/JavaScriptCore/assembler/MacroAssemblerARM.h @@ -30,7 +30,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) +#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) #include "ARMAssembler.h" #include "AbstractMacroAssembler.h" @@ -224,7 +224,7 @@ public: m_assembler.baseIndexTransfer32(true, dest, address.base, address.index, static_cast<int>(address.scale), address.offset); } -#if defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_REQUIRE_NATURAL_ALIGNMENT +#if CPU(ARMV5_OR_LOWER) void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest); #else void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest) @@ -928,6 +928,6 @@ private: } -#endif // ENABLE(ASSEMBLER) && PLATFORM(ARM_TRADITIONAL) +#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) #endif // MacroAssemblerARM_h diff --git a/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/JavaScriptCore/assembler/MacroAssemblerCodeRef.h index 3681af8..cae8bf6 100644 --- a/JavaScriptCore/assembler/MacroAssemblerCodeRef.h +++ b/JavaScriptCore/assembler/MacroAssemblerCodeRef.h @@ -37,7 +37,7 @@ // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid // instruction address on the platform (for example, check any alignment requirements). -#if PLATFORM(ARM_THUMB2) +#if CPU(ARM_THUMB2) // ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded // into the processor are decorated with the bottom bit set, indicating that this is // thumb code (as oposed to 32-bit traditional ARM). The first test checks for both @@ -130,7 +130,7 @@ public: } explicit MacroAssemblerCodePtr(void* value) -#if PLATFORM(ARM_THUMB2) +#if CPU(ARM_THUMB2) // Decorate the pointer as a thumb code pointer. : m_value(reinterpret_cast<char*>(value) + 1) #else @@ -147,7 +147,7 @@ public: } void* executableAddress() const { return m_value; } -#if PLATFORM(ARM_THUMB2) +#if CPU(ARM_THUMB2) // To use this pointer as a data address remove the decoration. void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; } #else diff --git a/JavaScriptCore/assembler/MacroAssemblerX86.h b/JavaScriptCore/assembler/MacroAssemblerX86.h index 6e96240..ca7c31a 100644 --- a/JavaScriptCore/assembler/MacroAssemblerX86.h +++ b/JavaScriptCore/assembler/MacroAssemblerX86.h @@ -28,7 +28,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM(X86) +#if ENABLE(ASSEMBLER) && CPU(X86) #include "MacroAssemblerX86Common.h" diff --git a/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/JavaScriptCore/assembler/MacroAssemblerX86Common.h index 96d21f1..449df86 100644 --- a/JavaScriptCore/assembler/MacroAssemblerX86Common.h +++ b/JavaScriptCore/assembler/MacroAssemblerX86Common.h @@ -542,7 +542,7 @@ public: m_assembler.movl_i32r(imm.m_value, dest); } -#if PLATFORM(X86_64) +#if CPU(X86_64) void move(RegisterID src, RegisterID dest) { // Note: on 64-bit this is is a full register move; perhaps it would be @@ -944,8 +944,8 @@ private: // x86_64, and clients & subclasses of MacroAssembler should be using 'supportsFloatingPoint()'. friend class MacroAssemblerX86; -#if PLATFORM(X86) -#if PLATFORM(MAC) +#if CPU(X86) +#if OS(MAC_OS_X) // All X86 Macs are guaranteed to support at least SSE2, static bool isSSE2Present() @@ -953,7 +953,7 @@ private: return true; } -#else // PLATFORM(MAC) +#else // OS(MAC_OS_X) enum SSE2CheckState { NotCheckedSSE2, @@ -996,8 +996,8 @@ private: static SSE2CheckState s_sse2CheckState; -#endif // PLATFORM(MAC) -#elif !defined(NDEBUG) // PLATFORM(X86) +#endif // OS(MAC_OS_X) +#elif !defined(NDEBUG) // CPU(X86) // On x86-64 we should never be checking for SSE2 in a non-debug build, // but non debug add this method to keep the asserts above happy. diff --git a/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/JavaScriptCore/assembler/MacroAssemblerX86_64.h index 7828cf5..ec93f8c 100644 --- a/JavaScriptCore/assembler/MacroAssemblerX86_64.h +++ b/JavaScriptCore/assembler/MacroAssemblerX86_64.h @@ -28,7 +28,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && PLATFORM(X86_64) +#if ENABLE(ASSEMBLER) && CPU(X86_64) #include "MacroAssemblerX86Common.h" diff --git a/JavaScriptCore/assembler/X86Assembler.h b/JavaScriptCore/assembler/X86Assembler.h index cbbaaa5..ab3d05f 100644 --- a/JavaScriptCore/assembler/X86Assembler.h +++ b/JavaScriptCore/assembler/X86Assembler.h @@ -28,7 +28,7 @@ #include <wtf/Platform.h> -#if ENABLE(ASSEMBLER) && (PLATFORM(X86) || PLATFORM(X86_64)) +#if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64)) #include "AssemblerBuffer.h" #include <stdint.h> @@ -50,7 +50,7 @@ namespace X86Registers { esi, edi, -#if PLATFORM(X86_64) +#if CPU(X86_64) r8, r9, r10, @@ -118,12 +118,12 @@ private: OP_XOR_GvEv = 0x33, OP_CMP_EvGv = 0x39, OP_CMP_GvEv = 0x3B, -#if PLATFORM(X86_64) +#if CPU(X86_64) PRE_REX = 0x40, #endif OP_PUSH_EAX = 0x50, OP_POP_EAX = 0x58, -#if PLATFORM(X86_64) +#if CPU(X86_64) OP_MOVSXD_GvEv = 0x63, #endif PRE_OPERAND_SIZE = 0x66, @@ -296,7 +296,7 @@ public: // Arithmetic operations: -#if !PLATFORM(X86_64) +#if !CPU(X86_64) void adcl_im(int imm, void* addr) { if (CAN_SIGN_EXTEND_8_32(imm)) { @@ -346,7 +346,7 @@ public: } } -#if PLATFORM(X86_64) +#if CPU(X86_64) void addq_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst); @@ -423,7 +423,7 @@ public: } } -#if PLATFORM(X86_64) +#if CPU(X86_64) void andq_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_AND_EvGv, src, dst); @@ -509,7 +509,7 @@ public: } } -#if PLATFORM(X86_64) +#if CPU(X86_64) void orq_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_OR_EvGv, src, dst); @@ -575,7 +575,7 @@ public: } } -#if PLATFORM(X86_64) +#if CPU(X86_64) void subq_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst); @@ -641,7 +641,7 @@ public: } } -#if PLATFORM(X86_64) +#if CPU(X86_64) void xorq_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst); @@ -689,7 +689,7 @@ public: m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst); } -#if PLATFORM(X86_64) +#if CPU(X86_64) void sarq_CLr(RegisterID dst) { m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst); @@ -789,7 +789,7 @@ public: m_formatter.immediate32(imm); } -#if PLATFORM(X86_64) +#if CPU(X86_64) void cmpq_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst); @@ -897,7 +897,7 @@ public: m_formatter.immediate32(imm); } -#if PLATFORM(X86_64) +#if CPU(X86_64) void testq_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst); @@ -971,7 +971,7 @@ public: m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst); } -#if PLATFORM(X86_64) +#if CPU(X86_64) void xchgq_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst); @@ -1001,7 +1001,7 @@ public: void movl_mEAX(void* addr) { m_formatter.oneByteOp(OP_MOV_EAXOv); -#if PLATFORM(X86_64) +#if CPU(X86_64) m_formatter.immediate64(reinterpret_cast<int64_t>(addr)); #else m_formatter.immediate32(reinterpret_cast<int>(addr)); @@ -1038,14 +1038,14 @@ public: void movl_EAXm(void* addr) { m_formatter.oneByteOp(OP_MOV_OvEAX); -#if PLATFORM(X86_64) +#if CPU(X86_64) m_formatter.immediate64(reinterpret_cast<int64_t>(addr)); #else m_formatter.immediate32(reinterpret_cast<int>(addr)); #endif } -#if PLATFORM(X86_64) +#if CPU(X86_64) void movq_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst); @@ -1157,7 +1157,7 @@ public: { m_formatter.oneByteOp(OP_LEA, dst, base, offset); } -#if PLATFORM(X86_64) +#if CPU(X86_64) void leaq_mr(int offset, RegisterID base, RegisterID dst) { m_formatter.oneByteOp64(OP_LEA, dst, base, offset); @@ -1323,7 +1323,7 @@ public: m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset); } -#if !PLATFORM(X86_64) +#if !CPU(X86_64) void cvtsi2sd_mr(void* address, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); @@ -1343,7 +1343,7 @@ public: m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst); } -#if PLATFORM(X86_64) +#if CPU(X86_64) void movq_rr(XMMRegisterID src, RegisterID dst) { m_formatter.prefix(PRE_SSE_66); @@ -1369,7 +1369,7 @@ public: m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset); } -#if !PLATFORM(X86_64) +#if !CPU(X86_64) void movsd_mr(void* address, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); @@ -1535,7 +1535,7 @@ public: static void repatchLoadPtrToLEA(void* where) { -#if PLATFORM(X86_64) +#if CPU(X86_64) // On x86-64 pointer memory accesses require a 64-bit operand, and as such a REX prefix. // Skip over the prefix byte. where = reinterpret_cast<char*>(where) + 1; @@ -1679,7 +1679,7 @@ private: memoryModRM(reg, base, index, scale, offset); } -#if !PLATFORM(X86_64) +#if !CPU(X86_64) void oneByteOp(OneByteOpcodeID opcode, int reg, void* address) { m_buffer.ensureSpace(maxInstructionSize); @@ -1722,7 +1722,7 @@ private: memoryModRM(reg, base, index, scale, offset); } -#if !PLATFORM(X86_64) +#if !CPU(X86_64) void twoByteOp(TwoByteOpcodeID opcode, int reg, void* address) { m_buffer.ensureSpace(maxInstructionSize); @@ -1732,7 +1732,7 @@ private: } #endif -#if PLATFORM(X86_64) +#if CPU(X86_64) // Quad-word-sized operands: // // Used to format 64-bit operantions, planting a REX.w prefix. @@ -1891,7 +1891,7 @@ private: static const RegisterID noBase = X86Registers::ebp; static const RegisterID hasSib = X86Registers::esp; static const RegisterID noIndex = X86Registers::esp; -#if PLATFORM(X86_64) +#if CPU(X86_64) static const RegisterID noBase2 = X86Registers::r13; static const RegisterID hasSib2 = X86Registers::r12; @@ -1967,7 +1967,7 @@ private: void memoryModRM(int reg, RegisterID base, int offset) { // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there. -#if PLATFORM(X86_64) +#if CPU(X86_64) if ((base == hasSib) || (base == hasSib2)) { #else if (base == hasSib) { @@ -1982,7 +1982,7 @@ private: m_buffer.putIntUnchecked(offset); } } else { -#if PLATFORM(X86_64) +#if CPU(X86_64) if (!offset && (base != noBase) && (base != noBase2)) #else if (!offset && (base != noBase)) @@ -2001,7 +2001,7 @@ private: void memoryModRM_disp32(int reg, RegisterID base, int offset) { // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there. -#if PLATFORM(X86_64) +#if CPU(X86_64) if ((base == hasSib) || (base == hasSib2)) { #else if (base == hasSib) { @@ -2018,7 +2018,7 @@ private: { ASSERT(index != noIndex); -#if PLATFORM(X86_64) +#if CPU(X86_64) if (!offset && (base != noBase) && (base != noBase2)) #else if (!offset && (base != noBase)) @@ -2033,7 +2033,7 @@ private: } } -#if !PLATFORM(X86_64) +#if !CPU(X86_64) void memoryModRM(int reg, void* address) { // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32! @@ -2048,6 +2048,6 @@ private: } // namespace JSC -#endif // ENABLE(ASSEMBLER) && PLATFORM(X86) +#endif // ENABLE(ASSEMBLER) && CPU(X86) #endif // X86Assembler_h diff --git a/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp index 13bed8c..fd56ece 100644 --- a/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/JavaScriptCore/bytecode/CodeBlock.cpp @@ -51,7 +51,7 @@ static UString escapeQuotes(const UString& str) UString result = str; int pos = 0; while ((pos = result.find('\"', pos)) >= 0) { - result = result.substr(0, pos) + "\"\\\"\"" + result.substr(pos + 1); + result = makeString(result.substr(0, pos), "\"\\\"\"", result.substr(pos + 1)); pos += 4; } return result; @@ -62,23 +62,20 @@ static UString valueToSourceString(ExecState* exec, JSValue val) if (!val) return "0"; - if (val.isString()) { - UString result("\""); - result += escapeQuotes(val.toString(exec)) + "\""; - return result; - } + if (val.isString()) + return makeString("\"", escapeQuotes(val.toString(exec)), "\""); return val.toString(exec); } static CString constantName(ExecState* exec, int k, JSValue value) { - return (valueToSourceString(exec, value) + "(@k" + UString::from(k - FirstConstantRegisterIndex) + ")").UTF8String(); + return makeString(valueToSourceString(exec, value), "(@k", UString::from(k - FirstConstantRegisterIndex), ")").UTF8String(); } static CString idName(int id0, const Identifier& ident) { - return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String(); + return makeString(ident.ustring(), "(@id", UString::from(id0), ")").UTF8String(); } CString CodeBlock::registerName(ExecState* exec, int r) const @@ -89,25 +86,26 @@ CString CodeBlock::registerName(ExecState* exec, int r) const if (isConstantRegisterIndex(r)) return constantName(exec, r, getConstant(r)); - return (UString("r") + UString::from(r)).UTF8String(); + return makeString("r", UString::from(r)).UTF8String(); } static UString regexpToSourceString(RegExp* regExp) { - UString pattern = UString("/") + regExp->pattern() + "/"; + char postfix[5] = { '/', 0, 0, 0, 0 }; + int index = 1; if (regExp->global()) - pattern += "g"; + postfix[index++] = 'g'; if (regExp->ignoreCase()) - pattern += "i"; + postfix[index++] = 'i'; if (regExp->multiline()) - pattern += "m"; + postfix[index] = 'm'; - return pattern; + return makeString("/", regExp->pattern(), postfix); } static CString regexpName(int re, RegExp* regexp) { - return (regexpToSourceString(regexp) + "(@re" + UString::from(re) + ")").UTF8String(); + return makeString(regexpToSourceString(regexp), "(@re", UString::from(re), ")").UTF8String(); } static UString pointerToSourceString(void* p) diff --git a/JavaScriptCore/bytecode/Opcode.h b/JavaScriptCore/bytecode/Opcode.h index e88f051..d9b2153 100644 --- a/JavaScriptCore/bytecode/Opcode.h +++ b/JavaScriptCore/bytecode/Opcode.h @@ -196,8 +196,12 @@ namespace JSC { #undef VERIFY_OPCODE_ID #if HAVE(COMPUTED_GOTO) +#if COMPILER(RVCT) typedef void* Opcode; #else + typedef const void* Opcode; +#endif +#else typedef OpcodeID Opcode; #endif diff --git a/JavaScriptCore/bytecode/SamplingTool.cpp b/JavaScriptCore/bytecode/SamplingTool.cpp index 865c919..3f0babc 100644 --- a/JavaScriptCore/bytecode/SamplingTool.cpp +++ b/JavaScriptCore/bytecode/SamplingTool.cpp @@ -33,7 +33,7 @@ #include "Interpreter.h" #include "Opcode.h" -#if !PLATFORM(WIN_OS) +#if !OS(WINDOWS) #include <unistd.h> #endif @@ -91,7 +91,7 @@ void SamplingFlags::stop() {} uint32_t SamplingFlags::s_flags = 1 << 15; -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) static void sleepForMicroseconds(unsigned us) { diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp index 80a7a2f..b66c50d 100644 --- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp +++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp @@ -78,10 +78,7 @@ static void substitute(UString& string, const UString& substring) { int position = string.find("%s"); ASSERT(position != -1); - UString newString = string.substr(0, position); - newString.append(substring); - newString.append(string.substr(position + 2)); - string = newString; + string = makeString(string.substr(0, position), substring, string.substr(position + 2)); } RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message) diff --git a/JavaScriptCore/config.h b/JavaScriptCore/config.h index 30757db..d5fdfe9 100644 --- a/JavaScriptCore/config.h +++ b/JavaScriptCore/config.h @@ -25,24 +25,26 @@ #include <wtf/Platform.h> -#if PLATFORM(WIN_OS) && !defined(BUILDING_WX__) && !COMPILER(GCC) +#if OS(WINDOWS) && !defined(BUILDING_WX__) && !COMPILER(GCC) #if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF) #define JS_EXPORTDATA __declspec(dllexport) #else #define JS_EXPORTDATA __declspec(dllimport) #endif +#define JS_EXPORTCLASS JS_EXPORTDATA #else #define JS_EXPORTDATA +#define JS_EXPORTCLASS #endif -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) // If we don't define these, they get defined in windef.h. // We want to use std::min and std::max #define max max #define min min -#if !COMPILER(MSVC7) && !PLATFORM(WINCE) +#if !COMPILER(MSVC7) && !OS(WINCE) // We need to define this before the first #include of stdlib.h or it won't contain rand_s. #ifndef _CRT_RAND_S #define _CRT_RAND_S @@ -51,7 +53,7 @@ #endif -#if PLATFORM(FREEBSD) || PLATFORM(OPENBSD) +#if OS(FREEBSD) || OS(OPENBSD) #define HAVE_PTHREAD_NP_H 1 #endif diff --git a/JavaScriptCore/create_rvct_stubs b/JavaScriptCore/create_rvct_stubs new file mode 100644 index 0000000..0c49c4f --- /dev/null +++ b/JavaScriptCore/create_rvct_stubs @@ -0,0 +1,52 @@ +#! /usr/bin/perl -w +# +# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public License +# along with this library; see the file COPYING.LIB. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +use strict; + +my $file = $ARGV[0]; +shift; + +my $stub_template = ""; +my $stub = ""; + +my $rtype = ""; +my $op = ""; + +my $rtype_template = quotemeta("#rtype#"); +my $op_template = quotemeta("#op#"); + +print STDERR "Creating RVCT stubs for $file \n"; +open(IN, $file) or die "No such file $file"; + +while ( $_ = <IN> ) { + if ( /^RVCT\((.*)\)/ ) { + $stub_template .= $1 . "\n"; + } + if ( /^DEFINE_STUB_FUNCTION\((.*), (.*)\)/ ) { + $stub = $stub_template; + $rtype = quotemeta($1); + $op = quotemeta($2); + $stub =~ s/$rtype_template/$rtype/g; + $stub =~ s/$op_template/$op/g; + $stub =~ s/\\\*/\*/g; + print $stub; + } +} + +close(IN); diff --git a/JavaScriptCore/debugger/Debugger.cpp b/JavaScriptCore/debugger/Debugger.cpp index 902a802..1d2e4fb 100644 --- a/JavaScriptCore/debugger/Debugger.cpp +++ b/JavaScriptCore/debugger/Debugger.cpp @@ -67,8 +67,9 @@ void Debugger::recompileAllJSFunctions(JSGlobalData* globalData) FunctionExecutableSet functionExecutables; SourceProviderMap sourceProviders; - Heap::iterator heapEnd = globalData->heap.primaryHeapEnd(); - for (Heap::iterator it = globalData->heap.primaryHeapBegin(); it != heapEnd; ++it) { + LiveObjectIterator it = globalData->heap.primaryHeapBegin(); + LiveObjectIterator heapEnd = globalData->heap.primaryHeapEnd(); + for ( ; it != heapEnd; ++it) { if (!(*it)->inherits(&JSFunction::info)) continue; diff --git a/JavaScriptCore/debugger/Debugger.h b/JavaScriptCore/debugger/Debugger.h index 3ee9767..3b9bec4 100644 --- a/JavaScriptCore/debugger/Debugger.h +++ b/JavaScriptCore/debugger/Debugger.h @@ -42,7 +42,7 @@ namespace JSC { virtual void detach(JSGlobalObject*); virtual void sourceParsed(ExecState*, const SourceCode&, int errorLineNumber, const UString& errorMessage) = 0; - virtual void exception(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0; + virtual void exception(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber, bool hasHandler) = 0; virtual void atStatement(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0; virtual void callEvent(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0; virtual void returnEvent(const DebuggerCallFrame&, intptr_t sourceID, int lineNumber) = 0; diff --git a/JavaScriptCore/debugger/DebuggerActivation.cpp b/JavaScriptCore/debugger/DebuggerActivation.cpp index d47db5b..0444d23 100644 --- a/JavaScriptCore/debugger/DebuggerActivation.cpp +++ b/JavaScriptCore/debugger/DebuggerActivation.cpp @@ -71,9 +71,9 @@ bool DebuggerActivation::deleteProperty(ExecState* exec, const Identifier& prope return m_activation->deleteProperty(exec, propertyName); } -void DebuggerActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void DebuggerActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { - m_activation->getPropertyNames(exec, propertyNames); + m_activation->getPropertyNames(exec, propertyNames, mode); } bool DebuggerActivation::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) diff --git a/JavaScriptCore/debugger/DebuggerActivation.h b/JavaScriptCore/debugger/DebuggerActivation.h index 373e62d..3927017 100644 --- a/JavaScriptCore/debugger/DebuggerActivation.h +++ b/JavaScriptCore/debugger/DebuggerActivation.h @@ -42,7 +42,7 @@ namespace JSC { virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue, unsigned attributes); virtual bool deleteProperty(ExecState*, const Identifier& propertyName); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction, unsigned attributes); virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction, unsigned attributes); @@ -51,7 +51,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/interpreter/CallFrame.h b/JavaScriptCore/interpreter/CallFrame.h index fff4c9b..e3ea689 100644 --- a/JavaScriptCore/interpreter/CallFrame.h +++ b/JavaScriptCore/interpreter/CallFrame.h @@ -110,9 +110,9 @@ namespace JSC { Arguments* optionalCalleeArguments() const { return this[RegisterFile::OptionalCalleeArguments].arguments(); } Instruction* returnPC() const { return this[RegisterFile::ReturnPC].vPC(); } - void setCalleeArguments(JSValue arguments) { this[RegisterFile::OptionalCalleeArguments] = arguments; } - void setCallerFrame(CallFrame* callerFrame) { this[RegisterFile::CallerFrame] = callerFrame; } - void setScopeChain(ScopeChainNode* scopeChain) { this[RegisterFile::ScopeChain] = scopeChain; } + void setCalleeArguments(JSValue arguments) { static_cast<Register*>(this)[RegisterFile::OptionalCalleeArguments] = arguments; } + void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; } + void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; } ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, CallFrame* callerFrame, int returnValueRegister, int argc, JSFunction* function) @@ -122,8 +122,8 @@ namespace JSC { setCodeBlock(codeBlock); setScopeChain(scopeChain); setCallerFrame(callerFrame); - this[RegisterFile::ReturnPC] = vPC; // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*. - this[RegisterFile::ReturnValueRegister] = Register::withInt(returnValueRegister); + static_cast<Register*>(this)[RegisterFile::ReturnPC] = vPC; // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*. + static_cast<Register*>(this)[RegisterFile::ReturnValueRegister] = Register::withInt(returnValueRegister); setArgumentCount(argc); // original argument count (for the sake of the "arguments" object) setCallee(function); setCalleeArguments(JSValue()); @@ -140,9 +140,9 @@ namespace JSC { CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); } private: - void setArgumentCount(int count) { this[RegisterFile::ArgumentCount] = Register::withInt(count); } - void setCallee(JSFunction* callee) { this[RegisterFile::Callee] = callee; } - void setCodeBlock(CodeBlock* codeBlock) { this[RegisterFile::CodeBlock] = codeBlock; } + void setArgumentCount(int count) { static_cast<Register*>(this)[RegisterFile::ArgumentCount] = Register::withInt(count); } + void setCallee(JSFunction* callee) { static_cast<Register*>(this)[RegisterFile::Callee] = callee; } + void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[RegisterFile::CodeBlock] = codeBlock; } static const intptr_t HostCallFrameFlag = 1; diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp index ed8bf5b..2498d69 100644 --- a/JavaScriptCore/interpreter/Interpreter.cpp +++ b/JavaScriptCore/interpreter/Interpreter.cpp @@ -321,7 +321,13 @@ Interpreter::Interpreter() : m_sampleEntryDepth(0) , m_reentryDepth(0) { +#if HAVE(COMPUTED_GOTO) privateExecute(InitializeAndReturn, 0, 0, 0); + + for (int i = 0; i < numOpcodeIDs; ++i) + m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i)); +#endif // HAVE(COMPUTED_GOTO) + #if ENABLE(OPCODE_SAMPLING) enableSampler(); #endif @@ -527,7 +533,8 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) { DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue); - debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset)); + bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset); + debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset), hasHandler); } // If we throw in the middle of a call instruction, we need to notify @@ -1038,23 +1045,27 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* ASSERT(slot.slotBase().isObject()); JSObject* baseObject = asObject(slot.slotBase()); + size_t offset = slot.cachedOffset(); // Since we're accessing a prototype in a loop, it's a good bet that it // should not be treated as a dictionary. - if (baseObject->structure()->isDictionary()) + if (baseObject->structure()->isDictionary()) { baseObject->flattenDictionaryObject(); + offset = baseObject->structure()->get(propertyName); + } ASSERT(!baseObject->structure()->isUncacheableDictionary()); vPC[0] = getOpcode(op_get_by_id_proto); vPC[5] = baseObject->structure(); - vPC[6] = slot.cachedOffset(); + vPC[6] = offset; codeBlock->refStructures(vPC); return; } - size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase()); + size_t offset = slot.cachedOffset(); + size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset); if (!count) { vPC[0] = getOpcode(op_get_by_id_generic); return; @@ -1064,7 +1075,7 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* vPC[4] = structure; vPC[5] = structure->prototypeChain(callFrame); vPC[6] = count; - vPC[7] = slot.cachedOffset(); + vPC[7] = offset; codeBlock->refStructures(vPC); } @@ -1081,16 +1092,13 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi { // One-time initialization of our address tables. We have to put this code // here because our labels are only in scope inside this function. - if (flag == InitializeAndReturn) { + if (UNLIKELY(flag == InitializeAndReturn)) { #if HAVE(COMPUTED_GOTO) - #define ADD_BYTECODE(id, length) m_opcodeTable[id] = &&id; - FOR_EACH_OPCODE_ID(ADD_BYTECODE); - #undef ADD_BYTECODE - - #define ADD_OPCODE_ID(id, length) m_opcodeIDTable.add(&&id, id); - FOR_EACH_OPCODE_ID(ADD_OPCODE_ID); - #undef ADD_OPCODE_ID - ASSERT(m_opcodeIDTable.size() == numOpcodeIDs); + #define LIST_OPCODE_LABEL(id, length) &&id, + static Opcode labels[] = { FOR_EACH_OPCODE_ID(LIST_OPCODE_LABEL) }; + for (size_t i = 0; i < sizeof(labels) / sizeof(Opcode); ++i) + m_opcodeTable[i] = labels[i]; + #undef LIST_OPCODE_LABEL #endif // HAVE(COMPUTED_GOTO) return JSValue(); } diff --git a/JavaScriptCore/interpreter/Register.h b/JavaScriptCore/interpreter/Register.h index d0b0568..ecd7403 100644 --- a/JavaScriptCore/interpreter/Register.h +++ b/JavaScriptCore/interpreter/Register.h @@ -51,17 +51,18 @@ namespace JSC { class Register : public WTF::FastAllocBase { public: Register(); - Register(JSValue); + Register(const JSValue&); + Register& operator=(const JSValue&); JSValue jsValue() const; - Register(JSActivation*); - Register(CallFrame*); - Register(CodeBlock*); - Register(JSFunction*); - Register(JSPropertyNameIterator*); - Register(ScopeChainNode*); - Register(Instruction*); + Register& operator=(JSActivation*); + Register& operator=(CallFrame*); + Register& operator=(CodeBlock*); + Register& operator=(JSFunction*); + Register& operator=(JSPropertyNameIterator*); + Register& operator=(ScopeChainNode*); + Register& operator=(Instruction*); int32_t i() const; JSActivation* activation() const; @@ -75,12 +76,12 @@ namespace JSC { static Register withInt(int32_t i) { - return Register(i); + Register r; + r.u.i = i; + return r; } private: - Register(int32_t); - union { int32_t i; EncodedJSValue value; @@ -98,11 +99,11 @@ namespace JSC { ALWAYS_INLINE Register::Register() { #ifndef NDEBUG - u.value = JSValue::encode(JSValue()); + *this = JSValue(); #endif } - ALWAYS_INLINE Register::Register(JSValue v) + ALWAYS_INLINE Register::Register(const JSValue& v) { #if ENABLE(JSC_ZOMBIES) ASSERT(!v.isZombie()); @@ -110,6 +111,15 @@ namespace JSC { u.value = JSValue::encode(v); } + ALWAYS_INLINE Register& Register::operator=(const JSValue& v) + { +#if ENABLE(JSC_ZOMBIES) + ASSERT(!v.isZombie()); +#endif + u.value = JSValue::encode(v); + return *this; + } + ALWAYS_INLINE JSValue Register::jsValue() const { return JSValue::decode(u.value); @@ -117,44 +127,46 @@ namespace JSC { // Interpreter functions - ALWAYS_INLINE Register::Register(JSActivation* activation) + ALWAYS_INLINE Register& Register::operator=(JSActivation* activation) { u.activation = activation; + return *this; } - ALWAYS_INLINE Register::Register(CallFrame* callFrame) + ALWAYS_INLINE Register& Register::operator=(CallFrame* callFrame) { u.callFrame = callFrame; + return *this; } - ALWAYS_INLINE Register::Register(CodeBlock* codeBlock) + ALWAYS_INLINE Register& Register::operator=(CodeBlock* codeBlock) { u.codeBlock = codeBlock; + return *this; } - ALWAYS_INLINE Register::Register(JSFunction* function) + ALWAYS_INLINE Register& Register::operator=(JSFunction* function) { u.function = function; + return *this; } - ALWAYS_INLINE Register::Register(Instruction* vPC) + ALWAYS_INLINE Register& Register::operator=(Instruction* vPC) { u.vPC = vPC; + return *this; } - ALWAYS_INLINE Register::Register(ScopeChainNode* scopeChain) + ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain) { u.scopeChain = scopeChain; + return *this; } - ALWAYS_INLINE Register::Register(JSPropertyNameIterator* propertyNameIterator) + ALWAYS_INLINE Register& Register::operator=(JSPropertyNameIterator* propertyNameIterator) { u.propertyNameIterator = propertyNameIterator; - } - - ALWAYS_INLINE Register::Register(int32_t i) - { - u.i = i; + return *this; } ALWAYS_INLINE int32_t Register::i() const diff --git a/JavaScriptCore/interpreter/RegisterFile.cpp b/JavaScriptCore/interpreter/RegisterFile.cpp index 5424199..510effe 100644 --- a/JavaScriptCore/interpreter/RegisterFile.cpp +++ b/JavaScriptCore/interpreter/RegisterFile.cpp @@ -36,7 +36,7 @@ RegisterFile::~RegisterFile() #if HAVE(MMAP) munmap(m_buffer, ((m_max - m_start) + m_maxGlobals) * sizeof(Register)); #elif HAVE(VIRTUALALLOC) -#if PLATFORM(WINCE) +#if OS(WINCE) VirtualFree(m_buffer, DWORD(m_commitEnd) - DWORD(m_buffer), MEM_DECOMMIT); #endif VirtualFree(m_buffer, 0, MEM_RELEASE); diff --git a/JavaScriptCore/interpreter/RegisterFile.h b/JavaScriptCore/interpreter/RegisterFile.h index 953c70f..1fc4f82 100644 --- a/JavaScriptCore/interpreter/RegisterFile.h +++ b/JavaScriptCore/interpreter/RegisterFile.h @@ -176,7 +176,7 @@ namespace JSC { #if HAVE(MMAP) m_buffer = static_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, VM_TAG_FOR_REGISTERFILE_MEMORY, 0)); if (m_buffer == MAP_FAILED) { -#if PLATFORM(WINCE) +#if OS(WINCE) fprintf(stderr, "Could not allocate register file: %d\n", GetLastError()); #else fprintf(stderr, "Could not allocate register file: %d\n", errno); @@ -186,7 +186,7 @@ namespace JSC { #elif HAVE(VIRTUALALLOC) m_buffer = static_cast<Register*>(VirtualAlloc(0, roundUpAllocationSize(bufferLength, commitSize), MEM_RESERVE, PAGE_READWRITE)); if (!m_buffer) { -#if PLATFORM(WINCE) +#if OS(WINCE) fprintf(stderr, "Could not allocate register file: %d\n", GetLastError()); #else fprintf(stderr, "Could not allocate register file: %d\n", errno); @@ -196,7 +196,7 @@ namespace JSC { size_t committedSize = roundUpAllocationSize(maxGlobals * sizeof(Register), commitSize); void* commitCheck = VirtualAlloc(m_buffer, committedSize, MEM_COMMIT, PAGE_READWRITE); if (commitCheck != m_buffer) { -#if PLATFORM(WINCE) +#if OS(WINCE) fprintf(stderr, "Could not allocate register file: %d\n", GetLastError()); #else fprintf(stderr, "Could not allocate register file: %d\n", errno); @@ -242,7 +242,7 @@ namespace JSC { if (newEnd > m_commitEnd) { size_t size = roundUpAllocationSize(reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_commitEnd), commitSize); if (!VirtualAlloc(m_commitEnd, size, MEM_COMMIT, PAGE_READWRITE)) { -#if PLATFORM(WINCE) +#if OS(WINCE) fprintf(stderr, "Could not allocate register file: %d\n", GetLastError()); #else fprintf(stderr, "Could not allocate register file: %d\n", errno); diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h index 9ca62c8..1fb8ff7 100644 --- a/JavaScriptCore/jit/ExecutableAllocator.h +++ b/JavaScriptCore/jit/ExecutableAllocator.h @@ -26,6 +26,7 @@ #ifndef ExecutableAllocator_h #define ExecutableAllocator_h +#include <stddef.h> // for ptrdiff_t #include <limits> #include <wtf/Assertions.h> #include <wtf/PassRefPtr.h> @@ -33,15 +34,21 @@ #include <wtf/UnusedParam.h> #include <wtf/Vector.h> -#if PLATFORM(IPHONE) +#if OS(IPHONE_OS) #include <libkern/OSCacheControl.h> #include <sys/mman.h> #endif -#if PLATFORM(SYMBIAN) +#if OS(SYMBIAN) #include <e32std.h> #endif +#if OS(WINCE) +// From pkfuncs.h (private header file from the Platform Builder) +#define CACHE_SYNC_ALL 0x07F +extern "C" __declspec(dllimport) void CacheRangeFlush(LPVOID pAddr, DWORD dwLength, DWORD dwFlags); +#endif + #define JIT_ALLOCATOR_PAGE_SIZE (ExecutableAllocator::pageSize) #define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (ExecutableAllocator::pageSize * 4) @@ -78,7 +85,7 @@ private: struct Allocation { char* pages; size_t size; -#if PLATFORM(SYMBIAN) +#if OS(SYMBIAN) RChunk* chunk; #endif }; @@ -179,17 +186,17 @@ public: #endif -#if PLATFORM(X86) || PLATFORM(X86_64) +#if CPU(X86) || CPU(X86_64) static void cacheFlush(void*, size_t) { } -#elif PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) +#elif CPU(ARM_THUMB2) && OS(IPHONE_OS) static void cacheFlush(void* code, size_t size) { sys_dcache_flush(code, size); sys_icache_invalidate(code, size); } -#elif PLATFORM(ARM_THUMB2) && PLATFORM(LINUX) +#elif CPU(ARM_THUMB2) && OS(LINUX) static void cacheFlush(void* code, size_t size) { asm volatile ( @@ -205,12 +212,12 @@ public: : "r" (code), "r" (reinterpret_cast<char*>(code) + size) : "r0", "r1", "r2"); } -#elif PLATFORM(SYMBIAN) +#elif OS(SYMBIAN) static void cacheFlush(void* code, size_t size) { User::IMB_Range(code, static_cast<char*>(code) + size); } -#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX) +#elif CPU(ARM_TRADITIONAL) && OS(LINUX) static void cacheFlush(void* code, size_t size) { asm volatile ( @@ -226,6 +233,11 @@ public: : "r" (code), "r" (reinterpret_cast<char*>(code) + size) : "r0", "r1", "r2"); } +#elif OS(WINCE) + static void cacheFlush(void* code, size_t size) + { + CacheRangeFlush(code, size, CACHE_SYNC_ALL); + } #else #error "The cacheFlush support is missing on this platform." #endif diff --git a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp index 7682b9c..dd1db4e 100644 --- a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp +++ b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp @@ -29,7 +29,7 @@ #include <errno.h> -#if ENABLE(ASSEMBLER) && PLATFORM(MAC) && PLATFORM(X86_64) +#if ENABLE(ASSEMBLER) && OS(DARWIN) && CPU(X86_64) #include "TCSpinLock.h" #include <mach/mach_init.h> diff --git a/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp b/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp index 13a8626..06375ad 100644 --- a/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp +++ b/JavaScriptCore/jit/ExecutableAllocatorPosix.cpp @@ -27,7 +27,7 @@ #include "ExecutableAllocator.h" -#if ENABLE(ASSEMBLER) +#if ENABLE(ASSEMBLER) && OS(UNIX) && !OS(SYMBIAN) #include <sys/mman.h> #include <unistd.h> @@ -35,7 +35,7 @@ namespace JSC { -#if !(PLATFORM(MAC) && PLATFORM(X86_64)) +#if !(OS(DARWIN) && CPU(X86_64)) void ExecutableAllocator::intializePageSize() { @@ -57,7 +57,7 @@ void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc) ASSERT_UNUSED(result, !result); } -#endif // !(PLATFORM(MAC) && PLATFORM(X86_64)) +#endif // !(OS(DARWIN) && CPU(X86_64)) #if ENABLE(ASSEMBLER_WX_EXCLUSIVE) void ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSeting setting) diff --git a/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp b/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp index c96ecae..e82975c 100644 --- a/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp +++ b/JavaScriptCore/jit/ExecutableAllocatorSymbian.cpp @@ -22,7 +22,7 @@ #include "ExecutableAllocator.h" -#if ENABLE(ASSEMBLER) && PLATFORM(SYMBIAN) +#if ENABLE(ASSEMBLER) && OS(SYMBIAN) #include <e32hal.h> #include <e32std.h> @@ -34,7 +34,7 @@ namespace JSC { void ExecutableAllocator::intializePageSize() { -#if PLATFORM_ARM_ARCH(5) +#if CPU(ARMV5_OR_LOWER) // The moving memory model (as used in ARMv5 and earlier platforms) // on Symbian OS limits the number of chunks for each process to 16. // To mitigate this limitation increase the pagesize to diff --git a/JavaScriptCore/jit/ExecutableAllocatorWin.cpp b/JavaScriptCore/jit/ExecutableAllocatorWin.cpp index e6ac855..e38323c 100644 --- a/JavaScriptCore/jit/ExecutableAllocatorWin.cpp +++ b/JavaScriptCore/jit/ExecutableAllocatorWin.cpp @@ -27,7 +27,7 @@ #include "ExecutableAllocator.h" -#if ENABLE(ASSEMBLER) +#if ENABLE(ASSEMBLER) && OS(WINDOWS) #include "windows.h" diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp index 585486f..c0da66d 100644 --- a/JavaScriptCore/jit/JIT.cpp +++ b/JavaScriptCore/jit/JIT.cpp @@ -27,7 +27,7 @@ #include "JIT.h" // This probably does not belong here; adding here for now as a quick Windows build fix. -#if ENABLE(ASSEMBLER) && PLATFORM(X86) && !PLATFORM(MAC) +#if ENABLE(ASSEMBLER) && CPU(X86) && !OS(MAC_OS_X) #include "MacroAssembler.h" JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse2CheckState = NotCheckedSSE2; #endif diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h index 0b902b9..8e0c9ac 100644 --- a/JavaScriptCore/jit/JIT.h +++ b/JavaScriptCore/jit/JIT.h @@ -192,7 +192,7 @@ namespace JSC { // on x86/x86-64 it is ecx for performance reasons, since the // MacroAssembler will need to plant register swaps if it is not - // however the code will still function correctly. -#if PLATFORM(X86_64) +#if CPU(X86_64) static const RegisterID returnValueRegister = X86Registers::eax; static const RegisterID cachedResultRegister = X86Registers::eax; static const RegisterID firstArgumentRegister = X86Registers::edi; @@ -210,7 +210,7 @@ namespace JSC { static const FPRegisterID fpRegT0 = X86Registers::xmm0; static const FPRegisterID fpRegT1 = X86Registers::xmm1; static const FPRegisterID fpRegT2 = X86Registers::xmm2; -#elif PLATFORM(X86) +#elif CPU(X86) static const RegisterID returnValueRegister = X86Registers::eax; static const RegisterID cachedResultRegister = X86Registers::eax; // On x86 we always use fastcall conventions = but on @@ -228,7 +228,7 @@ namespace JSC { static const FPRegisterID fpRegT0 = X86Registers::xmm0; static const FPRegisterID fpRegT1 = X86Registers::xmm1; static const FPRegisterID fpRegT2 = X86Registers::xmm2; -#elif PLATFORM(ARM_THUMB2) +#elif CPU(ARM_THUMB2) static const RegisterID returnValueRegister = ARMRegisters::r0; static const RegisterID cachedResultRegister = ARMRegisters::r0; static const RegisterID firstArgumentRegister = ARMRegisters::r0; @@ -244,7 +244,7 @@ namespace JSC { static const FPRegisterID fpRegT0 = ARMRegisters::d0; static const FPRegisterID fpRegT1 = ARMRegisters::d1; static const FPRegisterID fpRegT2 = ARMRegisters::d2; -#elif PLATFORM(ARM_TRADITIONAL) +#elif CPU(ARM_TRADITIONAL) static const RegisterID returnValueRegister = ARMRegisters::r0; static const RegisterID cachedResultRegister = ARMRegisters::r0; static const RegisterID firstArgumentRegister = ARMRegisters::r0; @@ -436,7 +436,7 @@ namespace JSC { void emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType); void emitBinaryDoubleOp(OpcodeID, unsigned dst, unsigned op1, unsigned op2, OperandTypes, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters = true, bool op2IsInRegisters = true); -#if PLATFORM(X86) +#if CPU(X86) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 7; static const int patchOffsetPutByIdExternalLoad = 13; @@ -465,7 +465,7 @@ namespace JSC { static const int patchOffsetMethodCheckProtoObj = 11; static const int patchOffsetMethodCheckProtoStruct = 18; static const int patchOffsetMethodCheckPutFunction = 29; -#elif PLATFORM(ARM_TRADITIONAL) +#elif CPU(ARM_TRADITIONAL) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 4; static const int patchOffsetPutByIdExternalLoad = 16; @@ -574,7 +574,7 @@ namespace JSC { void compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch); void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset); -#if PLATFORM(X86_64) +#if CPU(X86_64) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 10; static const int patchOffsetPutByIdExternalLoad = 20; @@ -597,7 +597,7 @@ namespace JSC { static const int patchOffsetMethodCheckProtoObj = 20; static const int patchOffsetMethodCheckProtoStruct = 30; static const int patchOffsetMethodCheckPutFunction = 50; -#elif PLATFORM(X86) +#elif CPU(X86) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 7; static const int patchOffsetPutByIdExternalLoad = 13; @@ -624,7 +624,7 @@ namespace JSC { static const int patchOffsetMethodCheckProtoObj = 11; static const int patchOffsetMethodCheckProtoStruct = 18; static const int patchOffsetMethodCheckPutFunction = 29; -#elif PLATFORM(ARM_THUMB2) +#elif CPU(ARM_THUMB2) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 10; static const int patchOffsetPutByIdExternalLoad = 26; @@ -647,7 +647,7 @@ namespace JSC { static const int patchOffsetMethodCheckProtoObj = 24; static const int patchOffsetMethodCheckProtoStruct = 34; static const int patchOffsetMethodCheckPutFunction = 58; -#elif PLATFORM(ARM_TRADITIONAL) +#elif CPU(ARM_TRADITIONAL) // These architecture specific value are used to enable patching - see comment on op_put_by_id. static const int patchOffsetPutByIdStructure = 4; static const int patchOffsetPutByIdExternalLoad = 16; @@ -954,6 +954,46 @@ namespace JSC { #endif #endif } JIT_CLASS_ALIGNMENT; + + inline void JIT::emit_op_loop(Instruction* currentInstruction) + { + emitTimeoutCheck(); + emit_op_jmp(currentInstruction); + } + + inline void JIT::emit_op_loop_if_true(Instruction* currentInstruction) + { + emitTimeoutCheck(); + emit_op_jtrue(currentInstruction); + } + + inline void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) + { + emitSlow_op_jtrue(currentInstruction, iter); + } + + inline void JIT::emit_op_loop_if_false(Instruction* currentInstruction) + { + emitTimeoutCheck(); + emit_op_jfalse(currentInstruction); + } + + inline void JIT::emitSlow_op_loop_if_false(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) + { + emitSlow_op_jfalse(currentInstruction, iter); + } + + inline void JIT::emit_op_loop_if_less(Instruction* currentInstruction) + { + emitTimeoutCheck(); + emit_op_jless(currentInstruction); + } + + inline void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) + { + emitSlow_op_jless(currentInstruction, iter); + } + } // namespace JSC #endif // ENABLE(JIT) diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp index 70f7564..feee8d2 100644 --- a/JavaScriptCore/jit/JITArithmetic.cpp +++ b/JavaScriptCore/jit/JITArithmetic.cpp @@ -1116,7 +1116,7 @@ void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry> /* ------------------------------ BEGIN: OP_MOD ------------------------------ */ -#if PLATFORM(X86) || PLATFORM(X86_64) +#if CPU(X86) || CPU(X86_64) void JIT::emit_op_mod(Instruction* currentInstruction) { @@ -1178,7 +1178,7 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry> stubCall.call(dst); } -#else // PLATFORM(X86) || PLATFORM(X86_64) +#else // CPU(X86) || CPU(X86_64) void JIT::emit_op_mod(Instruction* currentInstruction) { @@ -1196,7 +1196,7 @@ void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&) { } -#endif // PLATFORM(X86) || PLATFORM(X86_64) +#endif // CPU(X86) || CPU(X86_64) /* ------------------------------ END: OP_MOD ------------------------------ */ @@ -2081,7 +2081,7 @@ void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEn /* ------------------------------ BEGIN: OP_MOD ------------------------------ */ -#if PLATFORM(X86) || PLATFORM(X86_64) +#if CPU(X86) || CPU(X86_64) void JIT::emit_op_mod(Instruction* currentInstruction) { @@ -2130,7 +2130,7 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry> stubCall.call(result); } -#else // PLATFORM(X86) || PLATFORM(X86_64) +#else // CPU(X86) || CPU(X86_64) void JIT::emit_op_mod(Instruction* currentInstruction) { @@ -2149,7 +2149,7 @@ void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&) ASSERT_NOT_REACHED(); } -#endif // PLATFORM(X86) || PLATFORM(X86_64) +#endif // CPU(X86) || CPU(X86_64) /* ------------------------------ END: OP_MOD ------------------------------ */ diff --git a/JavaScriptCore/jit/JITInlineMethods.h b/JavaScriptCore/jit/JITInlineMethods.h index 1ce6889..5af7565 100644 --- a/JavaScriptCore/jit/JITInlineMethods.h +++ b/JavaScriptCore/jit/JITInlineMethods.h @@ -115,7 +115,7 @@ ALWAYS_INLINE JIT::Call JIT::emitNakedCall(CodePtr function) ALWAYS_INLINE void JIT::beginUninterruptedSequence(int insnSpace, int constSpace) { -#if PLATFORM(ARM_TRADITIONAL) +#if CPU(ARM_TRADITIONAL) #ifndef NDEBUG // Ensure the label after the sequence can also fit insnSpace += sizeof(ARMWord); @@ -144,7 +144,7 @@ ALWAYS_INLINE void JIT::endUninterruptedSequence(int insnSpace, int constSpace) #endif -#if PLATFORM(ARM) +#if CPU(ARM) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { @@ -161,7 +161,7 @@ ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address) loadPtr(address, linkRegister); } -#else // PLATFORM(X86) || PLATFORM(X86_64) +#else // CPU(X86) || CPU(X86_64) ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg) { @@ -194,10 +194,10 @@ ALWAYS_INLINE void JIT::restoreArgumentReference() } ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() { -#if PLATFORM(X86) +#if CPU(X86) // Within a trampoline the return address will be on the stack at this point. addPtr(Imm32(sizeof(void*)), stackPointerRegister, firstArgumentRegister); -#elif PLATFORM(ARM) +#elif CPU(ARM) move(stackPointerRegister, firstArgumentRegister); #endif // In the trampoline on x86-64, the first argument register is not overwritten. @@ -265,9 +265,9 @@ ALWAYS_INLINE void JIT::clearSamplingFlag(int32_t flag) #if ENABLE(SAMPLING_COUNTERS) ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, uint32_t count) { -#if PLATFORM(X86_64) // Or any other 64-bit plattform. +#if CPU(X86_64) // Or any other 64-bit plattform. addPtr(Imm32(count), AbsoluteAddress(&counter.m_counter)); -#elif PLATFORM(X86) // Or any other little-endian 32-bit plattform. +#elif CPU(X86) // Or any other little-endian 32-bit plattform. intptr_t hiWord = reinterpret_cast<intptr_t>(&counter.m_counter) + sizeof(int32_t); add32(Imm32(count), AbsoluteAddress(&counter.m_counter)); addWithCarry32(Imm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord))); @@ -278,7 +278,7 @@ ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, uint32_t cou #endif #if ENABLE(OPCODE_SAMPLING) -#if PLATFORM(X86_64) +#if CPU(X86_64) ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction) { move(ImmPtr(m_interpreter->sampler()->sampleSlot()), X86Registers::ecx); @@ -293,7 +293,7 @@ ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostF #endif #if ENABLE(CODEBLOCK_SAMPLING) -#if PLATFORM(X86_64) +#if CPU(X86_64) ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock) { move(ImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86Registers::ecx); diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp index 77fec28..d9a32d9 100644 --- a/JavaScriptCore/jit/JITOpcodes.cpp +++ b/JavaScriptCore/jit/JITOpcodes.cpp @@ -137,7 +137,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0); jump(regT0); -#if PLATFORM(X86) || PLATFORM(ARM_TRADITIONAL) +#if CPU(X86) || CPU(ARM_TRADITIONAL) Label nativeCallThunk = align(); preserveReturnAddressAfterCall(regT0); emitPutToCallFrameHeader(regT0, RegisterFile::ReturnPC); // Push return address @@ -148,7 +148,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT1); emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain); -#if PLATFORM(X86) +#if CPU(X86) emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); /* We have two structs that we use to describe the stackframe we set up for our @@ -160,7 +160,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable * stack pointer by the right amount after the call. */ -#if COMPILER(MSVC) || PLATFORM(LINUX) +#if COMPILER(MSVC) || OS(LINUX) #if COMPILER(MSVC) #pragma pack(push) #pragma pack(4) @@ -223,7 +223,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable storePtr(regT2, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue) + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); storePtr(regT3, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); -#if COMPILER(MSVC) || PLATFORM(LINUX) +#if COMPILER(MSVC) || OS(LINUX) // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register) addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86Registers::ecx); @@ -248,7 +248,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable // so pull them off now addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister); -#elif PLATFORM(ARM_TRADITIONAL) +#elif CPU(ARM_TRADITIONAL) emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); // Allocate stack space for our arglist @@ -409,58 +409,6 @@ void JIT::emit_op_jmp(Instruction* currentInstruction) addJump(jump(), target); } -void JIT::emit_op_loop(Instruction* currentInstruction) -{ - unsigned target = currentInstruction[1].u.operand; - emitTimeoutCheck(); - addJump(jump(), target); -} - -void JIT::emit_op_loop_if_less(Instruction* currentInstruction) -{ - unsigned op1 = currentInstruction[1].u.operand; - unsigned op2 = currentInstruction[2].u.operand; - unsigned target = currentInstruction[3].u.operand; - - emitTimeoutCheck(); - - if (isOperandConstantImmediateInt(op1)) { - emitLoad(op2, regT1, regT0); - addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op1).asInt32())), target); - return; - } - - if (isOperandConstantImmediateInt(op2)) { - emitLoad(op1, regT1, regT0); - addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target); - return; - } - - emitLoad2(op1, regT1, regT0, op2, regT3, regT2); - addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); - addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); - addJump(branch32(LessThan, regT0, regT2), target); -} - -void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) -{ - unsigned op1 = currentInstruction[1].u.operand; - unsigned op2 = currentInstruction[2].u.operand; - unsigned target = currentInstruction[3].u.operand; - - if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) - linkSlowCase(iter); // int32 check - linkSlowCase(iter); // int32 check - - JITStubCall stubCall(this, cti_op_jless); - stubCall.addArgument(op1); - stubCall.addArgument(op2); - stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target); -} - void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) { unsigned op1 = currentInstruction[1].u.operand; @@ -709,84 +657,6 @@ void JIT::emit_op_strcat(Instruction* currentInstruction) stubCall.call(currentInstruction[1].u.operand); } -void JIT::emit_op_loop_if_true(Instruction* currentInstruction) -{ - unsigned cond = currentInstruction[1].u.operand; - unsigned target = currentInstruction[2].u.operand; - - emitTimeoutCheck(); - - emitLoad(cond, regT1, regT0); - - Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); - addJump(branch32(NotEqual, regT0, Imm32(0)), target); - Jump isNotZero = jump(); - - isNotInteger.link(this); - - addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target); - addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::FalseTag))); - - isNotZero.link(this); -} - -void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) -{ - unsigned cond = currentInstruction[1].u.operand; - unsigned target = currentInstruction[2].u.operand; - - linkSlowCase(iter); - - JITStubCall stubCall(this, cti_op_jtrue); - stubCall.addArgument(cond); - stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target); -} - -void JIT::emit_op_loop_if_false(Instruction* currentInstruction) -{ - unsigned cond = currentInstruction[1].u.operand; - unsigned target = currentInstruction[2].u.operand; - - emitTimeoutCheck(); - - emitLoad(cond, regT1, regT0); - - Jump isTrue = branch32(Equal, regT1, Imm32(JSValue::TrueTag)); - addJump(branch32(Equal, regT1, Imm32(JSValue::FalseTag)), target); - - Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)); - Jump isTrue2 = branch32(NotEqual, regT0, Imm32(0)); - addJump(jump(), target); - - if (supportsFloatingPoint()) { - isNotInteger.link(this); - - addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag))); - - zeroDouble(fpRegT0); - emitLoadDouble(cond, fpRegT1); - addJump(branchDouble(DoubleEqualOrUnordered, fpRegT0, fpRegT1), target); - } else - addSlowCase(isNotInteger); - - isTrue.link(this); - isTrue2.link(this); -} - -void JIT::emitSlow_op_loop_if_false(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) -{ - unsigned cond = currentInstruction[1].u.operand; - unsigned target = currentInstruction[2].u.operand; - - linkSlowCase(iter); - - JITStubCall stubCall(this, cti_op_jtrue); - stubCall.addArgument(cond); - stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), target); -} - void JIT::emit_op_resolve_base(Instruction* currentInstruction) { JITStubCall stubCall(this, cti_op_resolve_base); @@ -1731,7 +1601,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain); -#if PLATFORM(X86_64) +#if CPU(X86_64) emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, X86Registers::ecx); // Allocate stack space for our arglist @@ -1767,7 +1637,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable call(Address(X86Registers::esi, OBJECT_OFFSETOF(JSFunction, m_data))); addPtr(Imm32(sizeof(ArgList)), stackPointerRegister); -#elif PLATFORM(X86) +#elif CPU(X86) emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); /* We have two structs that we use to describe the stackframe we set up for our @@ -1778,7 +1648,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable * not the rest of the callframe so we need a nice way to ensure we increment the * stack pointer by the right amount after the call. */ -#if COMPILER(MSVC) || PLATFORM(LINUX) +#if COMPILER(MSVC) || OS(LINUX) struct NativeCallFrameStructure { // CallFrame* callFrame; // passed in EDX JSObject* callee; @@ -1831,7 +1701,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable loadPtr(Address(regT1, -(int)sizeof(Register)), regT1); storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue))); -#if COMPILER(MSVC) || PLATFORM(LINUX) +#if COMPILER(MSVC) || OS(LINUX) // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register) addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86Registers::ecx); @@ -1859,7 +1729,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable // so pull them off now addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister); -#elif PLATFORM(ARM) +#elif CPU(ARM) emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); // Allocate stack space for our arglist @@ -2005,47 +1875,6 @@ void JIT::emit_op_jmp(Instruction* currentInstruction) RECORD_JUMP_TARGET(target); } -void JIT::emit_op_loop(Instruction* currentInstruction) -{ - emitTimeoutCheck(); - - unsigned target = currentInstruction[1].u.operand; - addJump(jump(), target); -} - -void JIT::emit_op_loop_if_less(Instruction* currentInstruction) -{ - emitTimeoutCheck(); - - unsigned op1 = currentInstruction[1].u.operand; - unsigned op2 = currentInstruction[2].u.operand; - unsigned target = currentInstruction[3].u.operand; - if (isOperandConstantImmediateInt(op2)) { - emitGetVirtualRegister(op1, regT0); - emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(JSVALUE64) - int32_t op2imm = getConstantOperandImmediateInt(op2); -#else - int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); -#endif - addJump(branch32(LessThan, regT0, Imm32(op2imm)), target); - } else if (isOperandConstantImmediateInt(op1)) { - emitGetVirtualRegister(op2, regT0); - emitJumpSlowCaseIfNotImmediateInteger(regT0); -#if USE(JSVALUE64) - int32_t op1imm = getConstantOperandImmediateInt(op1); -#else - int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1))); -#endif - addJump(branch32(GreaterThan, regT0, Imm32(op1imm)), target); - } else { - emitGetVirtualRegisters(op1, regT0, op2, regT1); - emitJumpSlowCaseIfNotImmediateInteger(regT0); - emitJumpSlowCaseIfNotImmediateInteger(regT1); - addJump(branch32(LessThan, regT0, regT1), target); - } -} - void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) { emitTimeoutCheck(); @@ -2284,40 +2113,6 @@ void JIT::emit_op_strcat(Instruction* currentInstruction) stubCall.call(currentInstruction[1].u.operand); } -void JIT::emit_op_loop_if_true(Instruction* currentInstruction) -{ - emitTimeoutCheck(); - - unsigned target = currentInstruction[2].u.operand; - emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); - - Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))); - addJump(emitJumpIfImmediateInteger(regT0), target); - - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target); - addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false))))); - - isZero.link(this); -}; - -void JIT::emit_op_loop_if_false(Instruction* currentInstruction) -{ - emitTimeoutCheck(); - - - unsigned target = currentInstruction[2].u.operand; - emitGetVirtualRegister(currentInstruction[1].u.operand, regT0); - - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target); - Jump isNonZero = emitJumpIfImmediateInteger(regT0); - - addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target); - addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(true))))); - - isNonZero.link(this); - RECORD_JUMP_TARGET(target); -}; - void JIT::emit_op_resolve_base(Instruction* currentInstruction) { JITStubCall stubCall(this, cti_op_resolve_base); @@ -2997,36 +2792,6 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas stubCall.call(dst); } -void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) -{ - unsigned op1 = currentInstruction[1].u.operand; - unsigned op2 = currentInstruction[2].u.operand; - unsigned target = currentInstruction[3].u.operand; - if (isOperandConstantImmediateInt(op2)) { - linkSlowCase(iter); - JITStubCall stubCall(this, cti_op_jless); - stubCall.addArgument(regT0); - stubCall.addArgument(op2, regT2); - stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target); - } else if (isOperandConstantImmediateInt(op1)) { - linkSlowCase(iter); - JITStubCall stubCall(this, cti_op_jless); - stubCall.addArgument(op1, regT2); - stubCall.addArgument(regT0); - stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target); - } else { - linkSlowCase(iter); - linkSlowCase(iter); - JITStubCall stubCall(this, cti_op_jless); - stubCall.addArgument(regT0); - stubCall.addArgument(regT1); - stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), target); - } -} - void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { unsigned op2 = currentInstruction[2].u.operand; @@ -3067,24 +2832,6 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas stubPutByValCall.call(); } -void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) -{ - linkSlowCase(iter); - JITStubCall stubCall(this, cti_op_jtrue); - stubCall.addArgument(regT0); - stubCall.call(); - emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand); -} - -void JIT::emitSlow_op_loop_if_false(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) -{ - linkSlowCase(iter); - JITStubCall stubCall(this, cti_op_jtrue); - stubCall.addArgument(regT0); - stubCall.call(); - emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand); // inverted! -} - void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp index e2995a1..ef95f99 100644 --- a/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -730,7 +730,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure); -#if PLATFORM(X86_64) +#if CPU(X86_64) move(ImmPtr(prototypeStructure), regT3); Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3); #else @@ -810,7 +810,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure); -#if PLATFORM(X86_64) +#if CPU(X86_64) move(ImmPtr(prototypeStructure), regT3); Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3); #else @@ -863,7 +863,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure); -#if PLATFORM(X86_64) +#if CPU(X86_64) move(ImmPtr(currStructure), regT3); bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3)); #else @@ -918,7 +918,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure); -#if PLATFORM(X86_64) +#if CPU(X86_64) move(ImmPtr(currStructure), regT3); bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3)); #else @@ -1051,6 +1051,20 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) emitPutVirtualRegister(dst); } +void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch) +{ + ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); + ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); + + Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); + loadPtr(BaseIndex(base, offset, ScalePtr, OBJECT_OFFSETOF(JSObject, m_inlineStorage)), result); + Jump finishedLoad = jump(); + notUsingInlineStorage.link(this); + loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), scratch); + loadPtr(BaseIndex(scratch, offset, ScalePtr, 0), result); + finishedLoad.link(this); +} + void JIT::emit_op_get_by_pname(Instruction* currentInstruction) { unsigned dst = currentInstruction[1].u.operand; @@ -1477,20 +1491,6 @@ void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID res } } -void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch) -{ - ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t)); - ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t)); - - Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity)); - loadPtr(BaseIndex(base, offset, ScalePtr, OBJECT_OFFSETOF(JSObject, m_inlineStorage)), result); - Jump finishedLoad = jump(); - notUsingInlineStorage.link(this); - loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), scratch); - loadPtr(BaseIndex(scratch, offset, ScalePtr, 0), result); - finishedLoad.link(this); -} - void JIT::testPrototype(Structure* structure, JumpList& failureCases) { if (structure->m_prototype.isNull()) @@ -1676,7 +1676,7 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure); -#if PLATFORM(X86_64) +#if CPU(X86_64) move(ImmPtr(prototypeStructure), regT3); Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3); #else @@ -1751,7 +1751,7 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure); -#if PLATFORM(X86_64) +#if CPU(X86_64) move(ImmPtr(prototypeStructure), regT3); Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3); #else @@ -1804,7 +1804,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure); -#if PLATFORM(X86_64) +#if CPU(X86_64) move(ImmPtr(currStructure), regT3); bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3)); #else @@ -1857,7 +1857,7 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str // Check the prototype object's Structure had not changed. Structure** prototypeStructureAddress = &(protoObject->m_structure); -#if PLATFORM(X86_64) +#if CPU(X86_64) move(ImmPtr(currStructure), regT3); bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3)); #else diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp index cace8b2..9191907 100644 --- a/JavaScriptCore/jit/JITStubs.cpp +++ b/JavaScriptCore/jit/JITStubs.cpp @@ -64,31 +64,37 @@ using namespace std; namespace JSC { -#if PLATFORM(DARWIN) || PLATFORM(WIN_OS) +#if OS(DARWIN) || OS(WINDOWS) #define SYMBOL_STRING(name) "_" #name #else #define SYMBOL_STRING(name) #name #endif -#if PLATFORM(IPHONE) +#if OS(IPHONE_OS) #define THUMB_FUNC_PARAM(name) SYMBOL_STRING(name) #else #define THUMB_FUNC_PARAM(name) #endif -#if PLATFORM(LINUX) && PLATFORM(X86_64) +#if OS(LINUX) && CPU(X86_64) #define SYMBOL_STRING_RELOCATION(name) #name "@plt" #else #define SYMBOL_STRING_RELOCATION(name) SYMBOL_STRING(name) #endif -#if PLATFORM(DARWIN) +#if OS(DARWIN) // Mach-O platform #define HIDE_SYMBOL(name) ".private_extern _" #name -#elif PLATFORM(AIX) +#elif OS(AIX) // IBM's own file format #define HIDE_SYMBOL(name) ".lglobl " #name -#elif PLATFORM(LINUX) || PLATFORM(FREEBSD) || PLATFORM(OPENBSD) || PLATFORM(SOLARIS) || (PLATFORM(HPUX) && PLATFORM(IA64)) || PLATFORM(SYMBIAN) || PLATFORM(NETBSD) +#elif OS(LINUX) \ + || OS(FREEBSD) \ + || OS(OPENBSD) \ + || OS(SOLARIS) \ + || (OS(HPUX) && CPU(IA64)) \ + || OS(SYMBIAN) \ + || OS(NETBSD) // ELF platform #define HIDE_SYMBOL(name) ".hidden " #name #else @@ -97,7 +103,7 @@ namespace JSC { #if USE(JSVALUE32_64) -#if COMPILER(GCC) && PLATFORM(X86) +#if COMPILER(GCC) && CPU(X86) // These ASSERTs remind you that, if you change the layout of JITStackFrame, you // need to change the assembly trampolines below to match. @@ -156,7 +162,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ret" "\n" ); -#elif COMPILER(GCC) && PLATFORM(X86_64) +#elif COMPILER(GCC) && CPU(X86_64) #if USE(JIT_STUB_ARGUMENT_VA_LIST) #error "JIT_STUB_ARGUMENT_VA_LIST not supported on x86-64." @@ -226,7 +232,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ret" "\n" ); -#elif COMPILER(GCC) && PLATFORM(ARM_THUMB2) +#elif COMPILER(GCC) && CPU(ARM_THUMB2) #if USE(JIT_STUB_ARGUMENT_VA_LIST) #error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7." @@ -292,7 +298,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "bx lr" "\n" ); -#elif COMPILER(GCC) && PLATFORM(ARM_TRADITIONAL) +#elif COMPILER(GCC) && CPU(ARM_TRADITIONAL) asm volatile ( ".globl " SYMBOL_STRING(ctiTrampoline) "\n" @@ -326,7 +332,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "mov pc, lr" "\n" ); -#elif COMPILER(MSVC) +#elif COMPILER(MSVC) && CPU(X86) #if USE(JIT_STUB_ARGUMENT_VA_LIST) #error "JIT_STUB_ARGUMENT_VA_LIST configuration not supported on MSVC." @@ -390,11 +396,13 @@ extern "C" { } } -#endif // COMPILER(GCC) && PLATFORM(X86) +#else + #error "JIT not supported on this platform." +#endif #else // USE(JSVALUE32_64) -#if COMPILER(GCC) && PLATFORM(X86) +#if COMPILER(GCC) && CPU(X86) // These ASSERTs remind you that, if you change the layout of JITStackFrame, you // need to change the assembly trampolines below to match. @@ -452,7 +460,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ret" "\n" ); -#elif COMPILER(GCC) && PLATFORM(X86_64) +#elif COMPILER(GCC) && CPU(X86_64) #if USE(JIT_STUB_ARGUMENT_VA_LIST) #error "JIT_STUB_ARGUMENT_VA_LIST not supported on x86-64." @@ -529,7 +537,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "ret" "\n" ); -#elif COMPILER(GCC) && PLATFORM(ARM_THUMB2) +#elif COMPILER(GCC) && CPU(ARM_THUMB2) #if USE(JIT_STUB_ARGUMENT_VA_LIST) #error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7." @@ -596,7 +604,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "bx lr" "\n" ); -#elif COMPILER(GCC) && PLATFORM(ARM_TRADITIONAL) +#elif COMPILER(GCC) && CPU(ARM_TRADITIONAL) asm volatile ( ".text\n" @@ -633,7 +641,46 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" "mov pc, lr" "\n" ); -#elif COMPILER(MSVC) +#elif COMPILER(RVCT) && CPU(ARM_TRADITIONAL) + +__asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, JSValue*, Profiler**, JSGlobalData*) +{ + ARM + stmdb sp!, {r1-r3} + stmdb sp!, {r4-r8, lr} + sub sp, sp, #36 + mov r4, r2 + mov r5, #512 + mov lr, pc + bx r0 + add sp, sp, #36 + ldmia sp!, {r4-r8, lr} + add sp, sp, #12 + bx lr +} + +__asm void ctiVMThrowTrampoline() +{ + ARM + PRESERVE8 + mov r0, sp + bl cti_vm_throw + add sp, sp, #36 + ldmia sp!, {r4-r8, lr} + add sp, sp, #12 + bx lr +} + +__asm void ctiOpThrowNotCaught() +{ + ARM + add sp, sp, #36 + ldmia sp!, {r4-r8, lr} + add sp, sp, #12 + bx lr +} + +#elif COMPILER(MSVC) && CPU(X86) #if USE(JIT_STUB_ARGUMENT_VA_LIST) #error "JIT_STUB_ARGUMENT_VA_LIST configuration not supported on MSVC." @@ -696,7 +743,9 @@ extern "C" { } } -#endif // COMPILER(GCC) && PLATFORM(X86) +#else + #error "JIT not supported on this platform." +#endif #endif // USE(JSVALUE32_64) @@ -710,7 +759,7 @@ JITThunks::JITThunks(JSGlobalData* globalData) { JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk); -#if PLATFORM(ARM_THUMB2) +#if CPU(ARM_THUMB2) // Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types), // and the OBJECT_OFFSETOF macro does not appear constantish enough for it to be happy with its use in COMPILE_ASSERT // macros. @@ -839,21 +888,25 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co ASSERT(slot.slotBase().isObject()); JSObject* slotBaseObject = asObject(slot.slotBase()); - + size_t offset = slot.cachedOffset(); + // Since we're accessing a prototype in a loop, it's a good bet that it // should not be treated as a dictionary. - if (slotBaseObject->structure()->isDictionary()) + if (slotBaseObject->structure()->isDictionary()) { slotBaseObject->flattenDictionaryObject(); + offset = slotBaseObject->structure()->get(propertyName); + } stubInfo->initGetByIdProto(structure, slotBaseObject->structure()); ASSERT(!structure->isDictionary()); ASSERT(!slotBaseObject->structure()->isDictionary()); - JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), slot.cachedOffset(), returnAddress); + JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), offset, returnAddress); return; } - size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase()); + size_t offset = slot.cachedOffset(); + size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset); if (!count) { stubInfo->accessType = access_get_by_id_generic; return; @@ -861,7 +914,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co StructureChain* prototypeChain = structure->prototypeChain(callFrame); stubInfo->initGetByIdChain(structure, prototypeChain); - JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, slot.cachedOffset(), returnAddress); + JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, offset, returnAddress); } #endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) @@ -957,7 +1010,7 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD } \ } while (0) -#if PLATFORM(ARM_THUMB2) +#if CPU(ARM_THUMB2) #define DEFINE_STUB_FUNCTION(rtype, op) \ extern "C" { \ @@ -978,7 +1031,7 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD ); \ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) \ -#elif PLATFORM(ARM_TRADITIONAL) && COMPILER(GCC) +#elif CPU(ARM_TRADITIONAL) && COMPILER(GCC) #if USE(JSVALUE32_64) #define THUNK_RETURN_ADDRESS_OFFSET 64 @@ -1002,6 +1055,32 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, thunkReturnAddress) == THUNK_RETUR ); \ rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) +#elif CPU(ARM_TRADITIONAL) && COMPILER(RVCT) + +#define DEFINE_STUB_FUNCTION(rtype, op) rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) + +/* The following is a workaround for RVCT toolchain; precompiler macros are not expanded before the code is passed to the assembler */ + +/* The following section is a template to generate code for GeneratedJITStubs_RVCT.h */ +/* The pattern "#xxx#" will be replaced with "xxx" */ + +/* +RVCT(extern "C" #rtype# JITStubThunked_#op#(STUB_ARGS_DECLARATION);) +RVCT(__asm #rtype# cti_#op#(STUB_ARGS_DECLARATION)) +RVCT({) +RVCT( ARM) +RVCT( IMPORT JITStubThunked_#op#) +RVCT( str lr, [sp, #32]) +RVCT( bl JITStubThunked_#op#) +RVCT( ldr lr, [sp, #32]) +RVCT( bx lr) +RVCT(}) +RVCT() +*/ + +/* Include the generated file */ +#include "GeneratedJITStubs_RVCT.h" + #else #define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION) #endif @@ -1043,9 +1122,16 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_add) CallFrame* callFrame = stackFrame.callFrame; +<<<<<<< HEAD bool leftIsString = v1.isString(); if (leftIsString && v2.isString()) { JSValue result = jsString(callFrame, asString(v1), asString(v2)); +======= + if (v1.isString()) { + JSValue result = v2.isString() + ? jsString(callFrame, asString(v1), asString(v2)) + : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame)); +>>>>>>> webkit.org at r54127 CHECK_FOR_EXCEPTION_AT_END(); return JSValue::encode(result); } @@ -1375,10 +1461,11 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) STUB_INIT_STACK_FRAME(stackFrame); CallFrame* callFrame = stackFrame.callFrame; + const Identifier& propertyName = stackFrame.args[1].identifier(); JSValue baseValue = stackFrame.args[0].jsValue(); PropertySlot slot(baseValue); - JSValue result = baseValue.get(callFrame, stackFrame.args[1].identifier(), slot); + JSValue result = baseValue.get(callFrame, propertyName, slot); CHECK_FOR_EXCEPTION(); @@ -1393,6 +1480,8 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) ASSERT(slot.slotBase().isObject()); JSObject* slotBaseObject = asObject(slot.slotBase()); + + size_t offset = slot.cachedOffset(); if (slot.slotBase() == baseValue) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); @@ -1400,23 +1489,25 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) ASSERT(!asCell(baseValue)->structure()->isDictionary()); // Since we're accessing a prototype in a loop, it's a good bet that it // should not be treated as a dictionary. - if (slotBaseObject->structure()->isDictionary()) + if (slotBaseObject->structure()->isDictionary()) { slotBaseObject->flattenDictionaryObject(); + offset = slotBaseObject->structure()->get(propertyName); + } int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); - JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), slot.cachedOffset()); + JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), offset); if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); - } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase())) { + } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) { ASSERT(!asCell(baseValue)->structure()->isDictionary()); int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); StructureChain* protoChain = structure->prototypeChain(callFrame); - JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, slot.cachedOffset()); + JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, offset); if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); @@ -1561,7 +1652,7 @@ DEFINE_STUB_FUNCTION(void*, op_call_JSFunction) { STUB_INIT_STACK_FRAME(stackFrame); -#ifndef NDEBUG +#if !ASSERT_DISABLED CallData callData; ASSERT(stackFrame.args[0].jsValue().getCallData(callData) == CallTypeJS); #endif @@ -1810,7 +1901,7 @@ DEFINE_STUB_FUNCTION(JSObject*, op_construct_JSConstruct) VM_THROW_EXCEPTION(); } -#ifndef NDEBUG +#if !ASSERT_DISABLED ConstructData constructData; ASSERT(constructor->getConstructData(constructData) == ConstructTypeJS); #endif @@ -2350,8 +2441,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_inc) return JSValue::encode(number); } -#if USE(JSVALUE32_64) - DEFINE_STUB_FUNCTION(int, op_eq) { STUB_INIT_STACK_FRAME(stackFrame); @@ -2359,6 +2448,7 @@ DEFINE_STUB_FUNCTION(int, op_eq) JSValue src1 = stackFrame.args[0].jsValue(); JSValue src2 = stackFrame.args[1].jsValue(); +#if USE(JSVALUE32_64) start: if (src2.isUndefined()) { return src1.isNull() || @@ -2439,8 +2529,18 @@ DEFINE_STUB_FUNCTION(int, op_eq) src1 = asObject(cell1)->toPrimitive(stackFrame.callFrame); CHECK_FOR_EXCEPTION(); goto start; + +#else // USE(JSVALUE32_64) + CallFrame* callFrame = stackFrame.callFrame; + + bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2); + CHECK_FOR_EXCEPTION_AT_END(); + return result; +#endif // USE(JSVALUE32_64) } +#if USE(JSVALUE32_64) + DEFINE_STUB_FUNCTION(int, op_eq_strings) { STUB_INIT_STACK_FRAME(stackFrame); @@ -2453,23 +2553,7 @@ DEFINE_STUB_FUNCTION(int, op_eq_strings) return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame); } -#else // USE(JSVALUE32_64) - -DEFINE_STUB_FUNCTION(int, op_eq) -{ - STUB_INIT_STACK_FRAME(stackFrame); - - JSValue src1 = stackFrame.args[0].jsValue(); - JSValue src2 = stackFrame.args[1].jsValue(); - - CallFrame* callFrame = stackFrame.callFrame; - - bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2); - CHECK_FOR_EXCEPTION_AT_END(); - return result; -} - -#endif // USE(JSVALUE32_64) +#endif DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift) { diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h index f71dc9a..99c2dd2 100644 --- a/JavaScriptCore/jit/JITStubs.h +++ b/JavaScriptCore/jit/JITStubs.h @@ -75,7 +75,7 @@ namespace JSC { ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); } }; -#if PLATFORM(X86_64) +#if CPU(X86_64) struct JITStackFrame { void* reserved; // Unused JITStubArg args[6]; @@ -99,7 +99,7 @@ namespace JSC { // When JIT code makes a call, it pushes its return address just below the rest of the stack. ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; } }; -#elif PLATFORM(X86) +#elif CPU(X86) #if COMPILER(MSVC) #pragma pack(push) #pragma pack(4) @@ -130,7 +130,7 @@ namespace JSC { #if COMPILER(MSVC) #pragma pack(pop) #endif // COMPILER(MSVC) -#elif PLATFORM(ARM_THUMB2) +#elif CPU(ARM_THUMB2) struct JITStackFrame { void* reserved; // Unused JITStubArg args[6]; @@ -158,7 +158,7 @@ namespace JSC { ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; } }; -#elif PLATFORM(ARM_TRADITIONAL) +#elif CPU(ARM_TRADITIONAL) struct JITStackFrame { JITStubArg padding; // Unused JITStubArg args[7]; @@ -202,16 +202,16 @@ namespace JSC { #define STUB_ARGS_DECLARATION void** args #define STUB_ARGS (args) - #if PLATFORM(X86) && COMPILER(MSVC) + #if CPU(X86) && COMPILER(MSVC) #define JIT_STUB __fastcall - #elif PLATFORM(X86) && COMPILER(GCC) + #elif CPU(X86) && COMPILER(GCC) #define JIT_STUB __attribute__ ((fastcall)) #else #define JIT_STUB #endif #endif -#if PLATFORM(X86_64) +#if CPU(X86_64) struct VoidPtrPair { void* first; void* second; diff --git a/JavaScriptCore/jsc.cpp b/JavaScriptCore/jsc.cpp index b6bc0aa..252fb96 100644 --- a/JavaScriptCore/jsc.cpp +++ b/JavaScriptCore/jsc.cpp @@ -37,7 +37,7 @@ #include <stdlib.h> #include <string.h> -#if !PLATFORM(WIN_OS) +#if !OS(WINDOWS) #include <unistd.h> #endif @@ -54,10 +54,10 @@ #include <signal.h> #endif -#if COMPILER(MSVC) && !PLATFORM(WINCE) +#if COMPILER(MSVC) && !OS(WINCE) #include <crtdbg.h> -#include <windows.h> #include <mmsystem.h> +#include <windows.h> #endif #if PLATFORM(QT) @@ -88,8 +88,8 @@ static JSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState*, JSObject*, J struct Script { bool isFile; - char *argument; - + char* argument; + Script(bool isFile, char *argument) : isFile(isFile) , argument(argument) @@ -174,12 +174,12 @@ GlobalObject::GlobalObject(const Vector<UString>& arguments) JSValue JSC_HOST_CALL functionPrint(ExecState* exec, JSObject*, JSValue, const ArgList& args) { for (unsigned i = 0; i < args.size(); ++i) { - if (i != 0) + if (i) putchar(' '); - + printf("%s", args.at(i).toString(exec).UTF8String().c_str()); } - + putchar('\n'); fflush(stdout); return jsUndefined(); @@ -194,7 +194,7 @@ JSValue JSC_HOST_CALL functionDebug(ExecState* exec, JSObject*, JSValue, const A JSValue JSC_HOST_CALL functionGC(ExecState* exec, JSObject*, JSValue, const ArgList&) { JSLock lock(SilenceAssertionsOnly); - exec->heap()->collect(); + exec->heap()->collectAllGarbage(); return jsUndefined(); } @@ -292,8 +292,18 @@ JSValue JSC_HOST_CALL functionReadline(ExecState* exec, JSObject*, JSValue, cons JSValue JSC_HOST_CALL functionQuit(ExecState* exec, JSObject*, JSValue, const ArgList&) { + // Technically, destroying the heap in the middle of JS execution is a no-no, + // but we want to maintain compatibility with the Mozilla test suite, so + // we pretend that execution has terminated to avoid ASSERTs, then tear down the heap. + exec->globalData().dynamicGlobalObject = 0; + cleanupGlobalData(&exec->globalData()); exit(EXIT_SUCCESS); + +#if COMPILER(MSVC) && OS(WINCE) + // Without this, Visual Studio will complain that this method does not return a value. + return jsUndefined(); +#endif } // Use SEH for Release builds only to get rid of the crash report dialog @@ -313,7 +323,7 @@ int jscmain(int argc, char** argv, JSGlobalData*); int main(int argc, char** argv) { -#if defined(_DEBUG) && PLATFORM(WIN_OS) +#if defined(_DEBUG) && OS(WINDOWS) _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); @@ -322,7 +332,7 @@ int main(int argc, char** argv) _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); #endif -#if COMPILER(MSVC) && !PLATFORM(WINCE) +#if COMPILER(MSVC) && !OS(WINCE) timeBeginPeriod(1); #endif @@ -463,30 +473,27 @@ static void parseArguments(int argc, char** argv, Options& options, JSGlobalData int i = 1; for (; i < argc; ++i) { const char* arg = argv[i]; - if (strcmp(arg, "-f") == 0) { + if (!strcmp(arg, "-f")) { if (++i == argc) printUsageStatement(globalData); options.scripts.append(Script(true, argv[i])); continue; } - if (strcmp(arg, "-e") == 0) { + if (!strcmp(arg, "-e")) { if (++i == argc) printUsageStatement(globalData); options.scripts.append(Script(false, argv[i])); continue; } - if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) { - printUsageStatement(globalData, true); - } - if (strcmp(arg, "-i") == 0) { + if (!strcmp(arg, "-i")) { options.interactive = true; continue; } - if (strcmp(arg, "-d") == 0) { + if (!strcmp(arg, "-d")) { options.dump = true; continue; } - if (strcmp(arg, "-s") == 0) { + if (!strcmp(arg, "-s")) { #if HAVE(SIGNAL_H) signal(SIGILL, _exit); signal(SIGFPE, _exit); @@ -495,16 +502,18 @@ static void parseArguments(int argc, char** argv, Options& options, JSGlobalData #endif continue; } - if (strcmp(arg, "--") == 0) { + if (!strcmp(arg, "--")) { ++i; break; } + if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) + printUsageStatement(globalData, true); options.scripts.append(Script(true, argv[i])); } - + if (options.scripts.isEmpty()) options.interactive = true; - + for (; i < argc; ++i) options.arguments.append(argv[i]); } @@ -532,20 +541,20 @@ static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& return false; } - size_t buffer_size = 0; - size_t buffer_capacity = 1024; + size_t bufferSize = 0; + size_t bufferCapacity = 1024; - buffer.resize(buffer_capacity); + buffer.resize(bufferCapacity); while (!feof(f) && !ferror(f)) { - buffer_size += fread(buffer.data() + buffer_size, 1, buffer_capacity - buffer_size, f); - if (buffer_size == buffer_capacity) { // guarantees space for trailing '\0' - buffer_capacity *= 2; - buffer.resize(buffer_capacity); + bufferSize += fread(buffer.data() + bufferSize, 1, bufferCapacity - bufferSize, f); + if (bufferSize == bufferCapacity) { // guarantees space for trailing '\0' + bufferCapacity *= 2; + buffer.resize(bufferCapacity); } } fclose(f); - buffer[buffer_size] = '\0'; + buffer[bufferSize] = '\0'; return true; } diff --git a/JavaScriptCore/jscore.bkl b/JavaScriptCore/jscore.bkl index 25e17d7..e69de29 100644 --- a/JavaScriptCore/jscore.bkl +++ b/JavaScriptCore/jscore.bkl @@ -1,150 +0,0 @@ -<?xml version="1.0" ?> -<!-- -Copyright (C) 2007 Kevin Ollivier. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - its contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -JavaScriptCore Bakefile project file. ---> - -<makefile> - <set var="SRCDIR">.</set> - - <include file="../WebKit/wx/wxwk-settings.bkl"/> - <include file="JavaScriptCoreSources.bkl"/> - - <template id="jscore_base" template="icu,pthreads,wxwk_build_settings"> - <sources> - $(JSCORE_API_SOURCES) - $(JSCORE_BYTECOMPILER_SOURCES) - $(JSCORE_DEBUGGER_SOURCES) - $(JSCORE_JSC_SOURCES) - $(JSCORE_PCRE_SOURCES) - $(JSCORE_PARSER_SOURCES) - $(JSCORE_PROFILER_SOURCES) - $(JSCORE_RUNTIME_SOURCES) - $(JSCORE_VM_SOURCES) - $(JSCORE_WTF_SOURCES) - </sources> - - <set var="ASSEMBLER_SOURCES"> - <if cond="WX_PORT=='gtk2'"> - $(JSCORE_VM_SOURCES_POSIX) - </if> - <if cond="PLATFORM_OS=='mac'"> - $(JSCORE_VM_SOURCES_POSIX) - </if> - <if cond="WX_PORT=='msw'"> - $(JSCORE_VM_SOURCES_WIN) - </if> - </set> - - <sources> - $(ASSEMBLER_SOURCES) - </sources> - <install-to>$(WKOUTPUTDIR)</install-to> - <pic>on</pic> - <threading>multi</threading> - - <include>$(SRCDIR)</include> - <include>$(SRCDIR)/..</include> - <include>$(SRCDIR)/API</include> - <include>$(SRCDIR)/assembler</include> - <include>$(SRCDIR)/bytecompiler</include> - <include>$(SRCDIR)/DerivedSources/JavaScriptCore</include> - <include>$(SRCDIR)/ForwardingHeaders</include> - <include>$(SRCDIR)/debugger</include> - <include>$(SRCDIR)/parser</include> - <include>$(SRCDIR)/pcre</include> - <include>$(SRCDIR)/profiler</include> - <include>$(SRCDIR)/runtime</include> - <include>$(SRCDIR)/interpreter</include> - <include>$(SRCDIR)/bytecode</include> - <include>$(SRCDIR)/wrec</include> - <include>$(SRCDIR)/jit</include> - <include>$(SRCDIR)/wtf</include> - <include>$(SRCDIR)/wtf/unicode</include> - - <define>ENABLE_XSLT=1</define> - - <if cond="FORMAT=='gnu'"> - <!-- FIXME: we need proper configure checks --> - <define>HAVE_FUNC_ISNAN</define> - <!-- check for undefined symbols for debugging reasons --> - <ldflags>-Wl</ldflags> - </if> - - <if cond="PLATFORM_WIN32=='1'"> - <include>$(SRCDIR)/os-win32</include> - <define>HAVE_SYS_TIMEB_H=1</define> - <define>HAVE_FLOAT_H=1</define> - <define>HAVE_FUNC__FINITE=1</define> - </if> - - </template> - - <exe id="jsc" template="icu,jscore,pthreads,wxwk"> - <cxx-rtti>off</cxx-rtti> - <cxx-exceptions>off</cxx-exceptions> - <debug-info>on</debug-info> - <depends>jscore</depends> - <include>$(SRCDIR)</include> - <include>$(WK_ROOT)/JavaScriptCore</include> - <include>$(WK_ROOT)/JavaScriptCore/assembler</include> - <include>$(WK_ROOT)/JavaScriptCore/bytecompiler</include> - <include>$(WK_ROOT)/JavaScriptCore/debugger</include> - <include>$(WK_ROOT)/JavaScriptCore/parser</include> - <include>$(WK_ROOT)/JavaScriptCore/pcre</include> - <include>$(WK_ROOT)/JavaScriptCore/profiler</include> - <include>$(WK_ROOT)/JavaScriptCore/runtime</include> - <include>$(WK_ROOT)/JavaScriptCore/interpreter</include> - <include>$(WK_ROOT)/JavaScriptCore/bytecode</include> - <include>$(WK_ROOT)/JavaScriptCore/jit</include> - <include>$(WK_ROOT)/JavaScriptCore/wrec</include> - <include>$(WK_ROOT)/JavaScriptCore/wtf</include> - <dirname>$(WKOUTPUTDIR)</dirname> - <sources>$(SRCDIR)/jsc.cpp</sources> - <set var="READLINE_LIB"> - <if cond="WX_PORT=='mac'">edit</if> - </set> - <sys-lib>$(READLINE_LIB)</sys-lib> - <if cond="FORMAT in ['msvc','msvs2005prj']"> - <include>$(WK_ROOT)/WebKitLibraries/win/include</include> - <sys-lib>winmm</sys-lib> <!-- for timeGetTime --> - <lib-path>$(WKOUTPUTDIR)</lib-path> - <lib-path>$(WK_ROOT)/WebKitLibraries/win/lib</lib-path> - </if> - - </exe> - - <action id="DerivedSources"> - <is-phony /> - <command>bash make-generated-sources.sh</command> - </action> - - <lib id="jscore" template="jscore_base,wx-lib"> - - </lib> -</makefile> diff --git a/JavaScriptCore/os-win32/WinMain.cpp b/JavaScriptCore/os-win32/WinMain.cpp new file mode 100644 index 0000000..17800d0 --- /dev/null +++ b/JavaScriptCore/os-win32/WinMain.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 Patrick Gansterer (paroga@paroga.com) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" +#include "Vector.h" +#include <winbase.h> +#include <winnls.h> +#include <wtf/UnusedParam.h> + +int main(int argc, char** argv); + +static inline char* convertToUtf8(LPCWSTR widecharString, int length) +{ + int requiredSize = WideCharToMultiByte(CP_UTF8, 0, widecharString, length, 0, 0, 0, 0); + char* multibyteString = new char[requiredSize + 1]; + + WideCharToMultiByte(CP_UTF8, 0, widecharString, length, multibyteString, requiredSize, 0, 0); + multibyteString[requiredSize] = '\0'; + + return multibyteString; +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) +{ + UNUSED_PARAM(hInstance); + UNUSED_PARAM(hPrevInstance); + UNUSED_PARAM(nCmdShow); + + Vector<char*> arguments; + TCHAR buffer[MAX_PATH]; + + int length = GetModuleFileNameW(0, buffer, MAX_PATH); + arguments.append(convertToUtf8(buffer, length)); + + WCHAR* commandLine = lpCmdLine; + while (commandLine[0] != '\0') { + int commandLineLength = 1; + WCHAR endChar = ' '; + + while (commandLine[0] == ' ') + ++commandLine; + + if (commandLine[0] == '\"') { + ++commandLine; + endChar = '\"'; + } + + while (commandLine[commandLineLength] != endChar && commandLine[commandLineLength] != '\0') + ++commandLineLength; + + arguments.append(convertToUtf8(commandLine, commandLineLength)); + + commandLine += commandLineLength; + if (endChar != ' ' && commandLine[0] != '\0') + ++commandLine; + } + + int res = main(arguments.size(), arguments.data()); + + for (size_t i = 0; i < arguments.size(); i++) + delete arguments[i]; + + return res; +} diff --git a/JavaScriptCore/parser/Grammar.y b/JavaScriptCore/parser/Grammar.y index 6d953df..717a266 100644 --- a/JavaScriptCore/parser/Grammar.y +++ b/JavaScriptCore/parser/Grammar.y @@ -43,7 +43,7 @@ // Default values for bison. #define YYDEBUG 0 // Set to 1 to debug a parse error. #define jscyydebug 0 // Set to 1 to debug a parse error. -#if !PLATFORM(DARWIN) +#if !OS(DARWIN) // Avoid triggering warnings in older bison by not setting this on the Darwin platform. // FIXME: Is this still needed? #define YYERROR_VERBOSE diff --git a/JavaScriptCore/parser/Lexer.cpp b/JavaScriptCore/parser/Lexer.cpp index 9148230..83f56bd 100644 --- a/JavaScriptCore/parser/Lexer.cpp +++ b/JavaScriptCore/parser/Lexer.cpp @@ -639,6 +639,8 @@ inStringEscapeSequence: shiftLineTerminator(); goto inString; } + if (m_current == -1) + goto returnError; record16(singleEscape(m_current)); shift1(); goto inString; diff --git a/JavaScriptCore/pcre/dftables b/JavaScriptCore/pcre/dftables index 1f0ea01..669b948 100755 --- a/JavaScriptCore/pcre/dftables +++ b/JavaScriptCore/pcre/dftables @@ -269,4 +269,5 @@ sub readHeaderValues() eval $content; die "$@" if $@; + unlink $tempFile; } diff --git a/JavaScriptCore/pcre/pcre.pri b/JavaScriptCore/pcre/pcre.pri index c33c67c..4f59e17 100644 --- a/JavaScriptCore/pcre/pcre.pri +++ b/JavaScriptCore/pcre/pcre.pri @@ -3,8 +3,6 @@ VPATH += $$PWD INCLUDEPATH += $$PWD $$OUTPUT_DIR/JavaScriptCore/tmp DEPENDPATH += $$PWD -isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = tmp - SOURCES += \ pcre_compile.cpp \ pcre_exec.cpp \ @@ -12,24 +10,3 @@ SOURCES += \ pcre_ucp_searchfuncs.cpp \ pcre_xclass.cpp -!CONFIG(QTDIR_build) { - defineTest(addExtraCompiler) { - QMAKE_EXTRA_COMPILERS += $$1 - generated_files.depends += compiler_$${1}_make_all - export(QMAKE_EXTRA_COMPILERS) - export(generated_files.depends) - return(true) - } -} - -# GENERATOR: "chartables.c": compile and execute the chartables generator (and add it to sources) -win32-msvc*|wince*: PREPROCESSOR = "--preprocessor=\"$$QMAKE_CC /E\"" -DFTABLES = $$PWD/dftables -ctgen.input = DFTABLES -ctgen.output = $$GENERATED_SOURCES_DIR/chartables.c -ctgen.commands = perl $$DFTABLES ${QMAKE_FILE_OUT} $$PREPROCESSOR -ctgen.CONFIG += target_predeps no_link -ctgen.variable_out = GENERATED_SOURCES -ctgen.dependency_type = TYPE_C -ctgen.clean = ${QMAKE_FILE_OUT} ${QMAKE_VAR_GENERATED_SOURCES_DIR}${QMAKE_FILE_BASE} -addExtraCompiler(ctgen) diff --git a/JavaScriptCore/profiler/HeavyProfile.cpp b/JavaScriptCore/profiler/HeavyProfile.cpp deleted file mode 100644 index e69de29..0000000 --- a/JavaScriptCore/profiler/HeavyProfile.cpp +++ /dev/null diff --git a/JavaScriptCore/profiler/HeavyProfile.h b/JavaScriptCore/profiler/HeavyProfile.h deleted file mode 100644 index e69de29..0000000 --- a/JavaScriptCore/profiler/HeavyProfile.h +++ /dev/null diff --git a/JavaScriptCore/profiler/ProfileNode.cpp b/JavaScriptCore/profiler/ProfileNode.cpp index 02fb7c9..fb126b3 100644 --- a/JavaScriptCore/profiler/ProfileNode.cpp +++ b/JavaScriptCore/profiler/ProfileNode.cpp @@ -33,7 +33,7 @@ #include <stdio.h> #include <wtf/DateMath.h> -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) #include <windows.h> #endif @@ -43,7 +43,7 @@ namespace JSC { static double getCount() { -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) static LARGE_INTEGER frequency = {0}; if (!frequency.QuadPart) QueryPerformanceFrequency(&frequency); diff --git a/JavaScriptCore/profiler/Profiler.cpp b/JavaScriptCore/profiler/Profiler.cpp index 5585d2e..fe8727a 100644 --- a/JavaScriptCore/profiler/Profiler.cpp +++ b/JavaScriptCore/profiler/Profiler.cpp @@ -148,7 +148,7 @@ CallIdentifier Profiler::createCallIdentifier(ExecState* exec, JSValue functionV } if (asObject(functionValue)->inherits(&InternalFunction::info)) return CallIdentifier(static_cast<InternalFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber); - return CallIdentifier("(" + asObject(functionValue)->className() + " object)", defaultSourceURL, defaultLineNumber); + return CallIdentifier(makeString("(", asObject(functionValue)->className(), " object)"), defaultSourceURL, defaultLineNumber); } CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSFunction* function) diff --git a/JavaScriptCore/profiler/TreeProfile.cpp b/JavaScriptCore/profiler/TreeProfile.cpp deleted file mode 100644 index e69de29..0000000 --- a/JavaScriptCore/profiler/TreeProfile.cpp +++ /dev/null diff --git a/JavaScriptCore/profiler/TreeProfile.h b/JavaScriptCore/profiler/TreeProfile.h deleted file mode 100644 index e69de29..0000000 --- a/JavaScriptCore/profiler/TreeProfile.h +++ /dev/null diff --git a/JavaScriptCore/qt/api/QtScript.pro b/JavaScriptCore/qt/api/QtScript.pro new file mode 100644 index 0000000..c87eaf4 --- /dev/null +++ b/JavaScriptCore/qt/api/QtScript.pro @@ -0,0 +1,36 @@ +TARGET = QtScript +TEMPLATE = lib +QT = core + +INCLUDEPATH += $$PWD + +CONFIG += building-libs + +isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = ../../generated +CONFIG(debug, debug|release) { + OBJECTS_DIR = obj/debug +} else { # Release + OBJECTS_DIR = obj/release +} + +include($$PWD/../../../WebKit.pri) +include($$PWD/../../JavaScriptCore.pri) + +INCLUDEPATH += $$PWD/../../API + +SOURCES += $$PWD/qscriptengine.cpp \ + $$PWD/qscriptengine_p.cpp \ + $$PWD/qscriptvalue.cpp \ + +HEADERS += $$PWD/qtscriptglobal.h \ + $$PWD/qscriptengine.h \ + $$PWD/qscriptengine_p.h \ + $$PWD/qscriptvalue.h \ + $$PWD/qscriptvalue_p.h \ + $$PWD/qscriptconverter_p.h \ + + +!static: DEFINES += QT_MAKEDLL + +DESTDIR = $$OUTPUT_DIR/lib + diff --git a/JavaScriptCore/qt/api/qscriptconverter_p.h b/JavaScriptCore/qt/api/qscriptconverter_p.h new file mode 100644 index 0000000..c3ca41f --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptconverter_p.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptconverter_p_h +#define qscriptconverter_p_h + +#include <JavaScriptCore/JavaScript.h> +#include <QtCore/qstring.h> + +/* + \internal + \class QScriptConverter + QScriptValue and QScriptEngine helper class. This class's responsibility is to convert values + between JS values and Qt/C++ values. + + This is a nice way to inline these functions in both QScriptValue and QScriptEngine. +*/ +class QScriptConverter { +public: + static QString toString(const JSStringRef str) + { + return QString(reinterpret_cast<const QChar*>(JSStringGetCharactersPtr(str)), JSStringGetLength(str)); + } + static JSStringRef toString(const QString& str) + { + return JSStringCreateWithUTF8CString(str.toUtf8().constData()); + } + static JSStringRef toString(const char* str) + { + return JSStringCreateWithUTF8CString(str); + } +}; + +#endif // qscriptconverter_p_h diff --git a/JavaScriptCore/qt/api/qscriptengine.cpp b/JavaScriptCore/qt/api/qscriptengine.cpp new file mode 100644 index 0000000..f12f410 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptengine.cpp @@ -0,0 +1,88 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptengine.h" + +#include "qscriptengine_p.h" +#include "qscriptvalue_p.h" + +/*! + Constructs a QScriptEngine object. + + The globalObject() is initialized to have properties as described in ECMA-262, Section 15.1. +*/ +QScriptEngine::QScriptEngine() + : d_ptr(new QScriptEnginePrivate(this)) +{ +} + +/*! + Destroys this QScriptEngine. +*/ +QScriptEngine::~QScriptEngine() +{ +} + +/*! + Evaluates \a program, using \a lineNumber as the base line number, + and returns the result of the evaluation. + + The script code will be evaluated in the current context. + + The evaluation of \a program can cause an exception in the + engine; in this case the return value will be the exception + that was thrown (typically an \c{Error} object). You can call + hasUncaughtException() to determine if an exception occurred in + the last call to evaluate(). + + \a lineNumber is used to specify a starting line number for \a + program; line number information reported by the engine that pertain + to this evaluation (e.g. uncaughtExceptionLineNumber()) will be + based on this argument. For example, if \a program consists of two + lines of code, and the statement on the second line causes a script + exception, uncaughtExceptionLineNumber() would return the given \a + lineNumber plus one. When no starting line number is specified, line + numbers will be 1-based. + + \a fileName is used for error reporting. For example in error objects + the file name is accessible through the "fileName" property if it's + provided with this function. +*/ +QScriptValue QScriptEngine::evaluate(const QString& program, const QString& fileName, int lineNumber) +{ + return QScriptValuePrivate::get(d_ptr->evaluate(program, fileName, lineNumber)); +} + +/*! + Runs the garbage collector. + + The garbage collector will attempt to reclaim memory by locating and disposing of objects that are + no longer reachable in the script environment. + + Normally you don't need to call this function; the garbage collector will automatically be invoked + when the QScriptEngine decides that it's wise to do so (i.e. when a certain number of new objects + have been created). However, you can call this function to explicitly request that garbage + collection should be performed as soon as possible. +*/ +void QScriptEngine::collectGarbage() +{ + d_ptr->collectGarbage(); +} diff --git a/JavaScriptCore/qt/api/qscriptengine.h b/JavaScriptCore/qt/api/qscriptengine.h new file mode 100644 index 0000000..cf61d35 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptengine.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptengine_h +#define qscriptengine_h + +#include <QtCore/qobject.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> + +class QScriptValue; +class QScriptEnginePrivate; + +// Internal typedef +typedef QExplicitlySharedDataPointer<QScriptEnginePrivate> QScriptEnginePtr; + +class QScriptEngine : public QObject { +public: + QScriptEngine(); + ~QScriptEngine(); + + QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1); + void collectGarbage(); + +private: + friend class QScriptEnginePrivate; + + QScriptEnginePtr d_ptr; +}; + +#endif diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp new file mode 100644 index 0000000..de8a355 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp @@ -0,0 +1,54 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptengine_p.h" + +#include "qscriptvalue_p.h" + +/*! + Constructs a default QScriptEnginePrivate object, a new global context will be created. + \internal +*/ +QScriptEnginePrivate::QScriptEnginePrivate(const QScriptEngine* engine) + : q_ptr(const_cast<QScriptEngine*>(engine)) + , m_context(JSGlobalContextCreate(0)) +{ +} + +QScriptEnginePrivate::~QScriptEnginePrivate() +{ + JSGlobalContextRelease(m_context); +} + +/*! + Evaluates program and returns the result of the evaluation. + \internal +*/ +QScriptValuePrivate* QScriptEnginePrivate::evaluate(const QString& program, const QString& fileName, int lineNumber) +{ + JSStringRef script = QScriptConverter::toString(program); + JSStringRef file = QScriptConverter::toString(fileName); + JSValueRef exception; + JSValueRef result = JSEvaluateScript(m_context, script, /* Global Object */ 0, file, lineNumber, &exception); + if (!result) + return new QScriptValuePrivate(this, exception); // returns an exception + return new QScriptValuePrivate(this, result); +} diff --git a/JavaScriptCore/qt/api/qscriptengine_p.h b/JavaScriptCore/qt/api/qscriptengine_p.h new file mode 100644 index 0000000..8e27c42 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptengine_p.h @@ -0,0 +1,98 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptengine_p_h +#define qscriptengine_p_h + +#include "qscriptconverter_p.h" +#include "qscriptengine.h" +#include "qscriptvalue.h" +#include <JavaScriptCore/JavaScript.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> + +class QScriptEngine; + +class QScriptEnginePrivate : public QSharedData { +public: + static QScriptEnginePtr get(const QScriptEngine* q) { Q_ASSERT(q); return q->d_ptr; } + static QScriptEngine* get(const QScriptEnginePrivate* d) { Q_ASSERT(d); return d->q_ptr; } + + QScriptEnginePrivate(const QScriptEngine*); + ~QScriptEnginePrivate(); + + QScriptValuePrivate* evaluate(const QString& program, const QString& fileName, int lineNumber); + inline void collectGarbage(); + + inline JSValueRef makeJSValue(double number) const; + inline JSValueRef makeJSValue(int number) const; + inline JSValueRef makeJSValue(uint number) const; + inline JSValueRef makeJSValue(const QString& string) const; + inline JSValueRef makeJSValue(bool number) const; + inline JSValueRef makeJSValue(QScriptValue::SpecialValue value) const; + + inline JSGlobalContextRef context() const; +private: + QScriptEngine* q_ptr; + JSGlobalContextRef m_context; +}; + +void QScriptEnginePrivate::collectGarbage() +{ + JSGarbageCollect(m_context); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(double number) const +{ + return JSValueMakeNumber(m_context, number); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(int number) const +{ + return JSValueMakeNumber(m_context, number); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(uint number) const +{ + return JSValueMakeNumber(m_context, number); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(const QString& string) const +{ + return JSValueMakeString(m_context, QScriptConverter::toString(string)); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(bool value) const +{ + return JSValueMakeBoolean(m_context, value); +} + +JSValueRef QScriptEnginePrivate::makeJSValue(QScriptValue::SpecialValue value) const +{ + if (value == QScriptValue::NullValue) + return JSValueMakeNull(m_context); + return JSValueMakeUndefined(m_context); +} + +JSGlobalContextRef QScriptEnginePrivate::context() const +{ + return m_context; +} + +#endif diff --git a/JavaScriptCore/qt/api/qscriptvalue.cpp b/JavaScriptCore/qt/api/qscriptvalue.cpp new file mode 100644 index 0000000..127fe04 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptvalue.cpp @@ -0,0 +1,556 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "config.h" + +#include "qscriptvalue.h" + +#include "qscriptengine.h" +#include "qscriptengine_p.h" +#include "qscriptvalue_p.h" +#include <QtCore/qdebug.h> + +/*! + Constructs an invalid value. +*/ +QScriptValue::QScriptValue() + : d_ptr(new QScriptValuePrivate()) +{ +} + +/*! + Constructs a new QScriptValue with a boolean \a value. +*/ +QScriptValue::QScriptValue(bool value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a number \a value. +*/ +QScriptValue::QScriptValue(int value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a number \a value. +*/ +QScriptValue::QScriptValue(uint value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a number \a value. +*/ +QScriptValue::QScriptValue(qsreal value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a string \a value. +*/ +QScriptValue::QScriptValue(const QString& value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a special \a value. +*/ +QScriptValue::QScriptValue(SpecialValue value) + : d_ptr(new QScriptValuePrivate(value)) +{ +} + +/*! + Constructs a new QScriptValue with a string \a value. +*/ +QScriptValue::QScriptValue(const char* value) + : d_ptr(new QScriptValuePrivate(QString::fromUtf8(value))) +{ +} + +/*! + Block automatic convertion to bool + \internal +*/ +QScriptValue::QScriptValue(void* d) +{ + Q_ASSERT(false); +} + +/*! + Constructs a new QScriptValue from private + \internal +*/ +QScriptValue::QScriptValue(QScriptValuePrivate* d) + : d_ptr(d) +{ +} + +/*! + \obsolete + + Constructs a new QScriptValue with the boolean \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, bool value) + : d_ptr(new QScriptValuePrivate(engine, value)) +{ +} + +/*! + \obsolete + + Constructs a new QScriptValue with the integer \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, int value) + : d_ptr(new QScriptValuePrivate(engine, value)) +{ +} + +/*! + \obsolete + + Constructs a new QScriptValue with the unsigned integer \a value and + registers it with the script \a engine. + */ +QScriptValue::QScriptValue(QScriptEngine* engine, uint value) + : d_ptr(new QScriptValuePrivate(engine, value)) +{ +} + +/*! + \obsolete + + Constructs a new QScriptValue with the qsreal \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, qsreal value) + : d_ptr(new QScriptValuePrivate(engine, value)) +{ +} + +/*! + \obsolete + + Constructs a new QScriptValue with the string \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, const QString& value) + : d_ptr(new QScriptValuePrivate(engine, value)) +{ +} + +/*! + \obsolete + + Constructs a new QScriptValue with the string \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, const char* value) + : d_ptr(new QScriptValuePrivate(engine, QString::fromUtf8(value))) +{ +} + +/*! + \obsolete + + Constructs a new QScriptValue with the special \a value and + registers it with the script \a engine. +*/ +QScriptValue::QScriptValue(QScriptEngine* engine, SpecialValue value) + : d_ptr(new QScriptValuePrivate(engine, value)) +{ +} + +/*! + Constructs a new QScriptValue that is a copy of \a other. + + Note that if \a other is an object (i.e., isObject() would return + true), then only a reference to the underlying object is copied into + the new script value (i.e., the object itself is not copied). +*/ +QScriptValue::QScriptValue(const QScriptValue& other) + : d_ptr(other.d_ptr) +{ +} + +/*! + Destroys this QScriptValue. +*/ +QScriptValue::~QScriptValue() +{ +} + +/*! + Returns true if this QScriptValue is valid; otherwise returns + false. +*/ +bool QScriptValue::isValid() const +{ + return d_ptr->isValid(); +} + +/*! + Returns true if this QScriptValue is of the primitive type Boolean; + otherwise returns false. + + \sa toBool() +*/ +bool QScriptValue::isBool() const +{ + return d_ptr->isBool(); +} + +/*! + \obsolete + + Use isBool() instead. + Returns true if this QScriptValue is of the primitive type Boolean; + otherwise returns false. +*/ +bool QScriptValue::isBoolean() const +{ + return d_ptr->isBool(); +} + +/*! + Returns true if this QScriptValue is of the primitive type Number; + otherwise returns false. + + \sa toNumber() +*/ +bool QScriptValue::isNumber() const +{ + return d_ptr->isNumber(); +} + +/*! + Returns true if this QScriptValue is of the primitive type Null; + otherwise returns false. + + \sa QScriptEngine::nullValue() +*/ +bool QScriptValue::isNull() const +{ + return d_ptr->isNull(); +} + +/*! + Returns true if this QScriptValue is of the primitive type String; + otherwise returns false. + + \sa toString() +*/ +bool QScriptValue::isString() const +{ + return d_ptr->isString(); +} + +/*! + Returns true if this QScriptValue is of the primitive type Undefined; + otherwise returns false. + + \sa QScriptEngine::undefinedValue() +*/ +bool QScriptValue::isUndefined() const +{ + return d_ptr->isUndefined(); +} + +/*! + Returns true if this QScriptValue is an object of the Error class; + otherwise returns false. + + \sa QScriptContext::throwError() +*/ +bool QScriptValue::isError() const +{ + return d_ptr->isError(); +} + +/*! + Returns true if this QScriptValue is of the Object type; otherwise + returns false. + + Note that function values, variant values, and QObject values are + objects, so this function returns true for such values. + + \sa toObject(), QScriptEngine::newObject() +*/ +bool QScriptValue::isObject() const +{ + return d_ptr->isObject(); +} + +/*! + Returns true if this QScriptValue is a function; otherwise returns + false. + + \sa call() +*/ +bool QScriptValue::isFunction() const +{ + return d_ptr->isFunction(); +} + +/*! + Returns the string value of this QScriptValue, as defined in + \l{ECMA-262} section 9.8, "ToString". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's toString() function (and possibly valueOf()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa isString() +*/ +QString QScriptValue::toString() const +{ + return d_ptr->toString(); +} + +/*! + Returns the number value of this QScriptValue, as defined in + \l{ECMA-262} section 9.3, "ToNumber". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa isNumber(), toInteger(), toInt32(), toUInt32(), toUInt16() +*/ +qsreal QScriptValue::toNumber() const +{ + return d_ptr->toNumber(); +} + +/*! + Returns the boolean value of this QScriptValue, using the conversion + rules described in \l{ECMA-262} section 9.2, "ToBoolean". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa isBool() +*/ +bool QScriptValue::toBool() const +{ + return d_ptr->toBool(); +} + +/*! + \obsolete + + Use toBool() instead. +*/ +bool QScriptValue::toBoolean() const +{ + return d_ptr->toBool(); +} + +/*! + Returns the integer value of this QScriptValue, using the conversion + rules described in \l{ECMA-262} section 9.4, "ToInteger". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber() +*/ +qsreal QScriptValue::toInteger() const +{ + return d_ptr->toInteger(); +} + +/*! + Returns the signed 32-bit integer value of this QScriptValue, using + the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber(), toUInt32() +*/ +qint32 QScriptValue::toInt32() const +{ + return d_ptr->toInt32(); +} + +/*! + Returns the unsigned 32-bit integer value of this QScriptValue, using + the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber(), toInt32() +*/ +quint32 QScriptValue::toUInt32() const +{ + return d_ptr->toUInt32(); +} + +/*! + Returns the unsigned 16-bit integer value of this QScriptValue, using + the conversion rules described in \l{ECMA-262} section 9.7, "ToUint16". + + Note that if this QScriptValue is an object, calling this function + has side effects on the script engine, since the engine will call + the object's valueOf() function (and possibly toString()) in an + attempt to convert the object to a primitive value (possibly + resulting in an uncaught script exception). + + \sa toNumber() +*/ +quint16 QScriptValue::toUInt16() const +{ + return d_ptr->toUInt16(); +} + +/*! + Calls this QScriptValue as a function, using \a thisObject as + the `this' object in the function call, and passing \a args + as arguments to the function. Returns the value returned from + the function. + + If this QScriptValue is not a function, call() does nothing + and returns an invalid QScriptValue. + + Note that if \a thisObject is not an object, the global object + (see \l{QScriptEngine::globalObject()}) will be used as the + `this' object. + + Calling call() can cause an exception to occur in the script engine; + in that case, call() returns the value that was thrown (typically an + \c{Error} object). You can call + QScriptEngine::hasUncaughtException() to determine if an exception + occurred. + + \snippet doc/src/snippets/code/src_script_qscriptvalue.cpp 2 + + \sa construct() +*/ +QScriptValue QScriptValue::call(const QScriptValue& thisObject, const QScriptValueList& args) +{ + return d_ptr->call(thisObject.d_ptr.data(), args); +} + +/*! + Returns the QScriptEngine that created this QScriptValue, + or 0 if this QScriptValue is invalid or the value is not + associated with a particular engine. +*/ +QScriptEngine* QScriptValue::engine() const +{ + QScriptEnginePrivate* engine = d_ptr->engine(); + if (engine) + return QScriptEnginePrivate::get(engine); + return 0; +} + +/*! + Assigns the \a other value to this QScriptValue. + + Note that if \a other is an object (isObject() returns true), + only a reference to the underlying object will be assigned; + the object itself will not be copied. +*/ +QScriptValue& QScriptValue::operator=(const QScriptValue& other) +{ + d_ptr = other.d_ptr; + return *this; +} + +/*! + Returns true if this QScriptValue is equal to \a other, otherwise + returns false. The comparison follows the behavior described in + \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison + Algorithm". + + This function can return true even if the type of this QScriptValue + is different from the type of the \a other value; i.e. the + comparison is not strict. For example, comparing the number 9 to + the string "9" returns true; comparing an undefined value to a null + value returns true; comparing a \c{Number} object whose primitive + value is 6 to a \c{String} object whose primitive value is "6" + returns true; and comparing the number 1 to the boolean value + \c{true} returns true. If you want to perform a comparison + without such implicit value conversion, use strictlyEquals(). + + Note that if this QScriptValue or the \a other value are objects, + calling this function has side effects on the script engine, since + the engine will call the object's valueOf() function (and possibly + toString()) in an attempt to convert the object to a primitive value + (possibly resulting in an uncaught script exception). + + \sa strictlyEquals(), lessThan() +*/ +bool QScriptValue::equals(const QScriptValue& other) const +{ + return d_ptr == other.d_ptr || d_ptr->equals(QScriptValuePrivate::get(other)); +} + +/*! + Returns true if this QScriptValue is equal to \a other using strict + comparison (no conversion), otherwise returns false. The comparison + follows the behavior described in \l{ECMA-262} section 11.9.6, "The + Strict Equality Comparison Algorithm". + + If the type of this QScriptValue is different from the type of the + \a other value, this function returns false. If the types are equal, + the result depends on the type, as shown in the following table: + + \table + \header \o Type \o Result + \row \o Undefined \o true + \row \o Null \o true + \row \o Boolean \o true if both values are true, false otherwise + \row \o Number \o false if either value is NaN (Not-a-Number); true if values are equal, false otherwise + \row \o String \o true if both values are exactly the same sequence of characters, false otherwise + \row \o Object \o true if both values refer to the same object, false otherwise + \endtable + + \sa equals() +*/ +bool QScriptValue::strictlyEquals(const QScriptValue& other) const +{ + return d_ptr == other.d_ptr || d_ptr->strictlyEquals(QScriptValuePrivate::get(other)); +} diff --git a/JavaScriptCore/qt/api/qscriptvalue.h b/JavaScriptCore/qt/api/qscriptvalue.h new file mode 100644 index 0000000..d45aed3 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptvalue.h @@ -0,0 +1,99 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptvalue_h +#define qscriptvalue_h + +#include <QtCore/qlist.h> +#include <QtCore/qshareddata.h> + +class QScriptEngine; +class QScriptValuePrivate; + +class QScriptValue; +typedef QList<QScriptValue> QScriptValueList; + +typedef double qsreal; + +class QScriptValue { +public: + enum SpecialValue { + NullValue, + UndefinedValue + }; + + QScriptValue(); + QScriptValue(bool value); + QScriptValue(int value); + QScriptValue(uint value); + QScriptValue(qsreal value); + QScriptValue(const QString& value); + QScriptValue(const char* value); + QScriptValue(SpecialValue value); + QScriptValue(const QScriptValue& other); + + QScriptValue(QScriptEngine* engine, bool value); + QScriptValue(QScriptEngine* engine, int value); + QScriptValue(QScriptEngine* engine, uint value); + QScriptValue(QScriptEngine* engine, qsreal value); + QScriptValue(QScriptEngine* engine, const QString& value); + QScriptValue(QScriptEngine* engine, const char* value); + QScriptValue(QScriptEngine* engine, SpecialValue value); + + ~QScriptValue(); + + QScriptValue& operator=(const QScriptValue& other); + bool equals(const QScriptValue& other) const; + bool strictlyEquals(const QScriptValue& other) const; + + QScriptEngine* engine() const; + + bool isValid() const; + bool isBool() const; + bool isBoolean() const; + bool isNumber() const; + bool isFunction() const; + bool isNull() const; + bool isString() const; + bool isUndefined() const; + bool isObject() const; + bool isError() const; + + QString toString() const; + qsreal toNumber() const; + bool toBool() const; + bool toBoolean() const; + qsreal toInteger() const; + qint32 toInt32() const; + quint32 toUInt32() const; + quint16 toUInt16() const; + + QScriptValue call(const QScriptValue& thisObject = QScriptValue(), + const QScriptValueList& args = QScriptValueList()); + +private: + QScriptValue(void*); + QScriptValue(QScriptValuePrivate*); + + QExplicitlySharedDataPointer<QScriptValuePrivate> d_ptr; + + friend class QScriptValuePrivate; +}; + +#endif // qscriptvalue_h diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h new file mode 100644 index 0000000..6a5b388 --- /dev/null +++ b/JavaScriptCore/qt/api/qscriptvalue_p.h @@ -0,0 +1,719 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qscriptvalue_p_h +#define qscriptvalue_p_h + +#include "qscriptconverter_p.h" +#include "qscriptengine_p.h" +#include "qscriptvalue.h" +#include <JavaScriptCore/JavaScript.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qvarlengtharray.h> + +class QScriptEngine; +class QScriptValue; + +/* + \internal + \class QScriptValuePrivate + + Implementation of QScriptValue. + The implementation is based on a state machine. The states names are included in + QScriptValuePrivate::States. Each method should check for the current state and then perform a + correct action. + + States: + Invalid -> QSVP is invalid, no assumptions should be made about class members (apart from m_value). + CString -> QSVP is created from QString or const char* and no JSC engine has been associated yet. + Current value is kept in m_string, + CNumber -> QSVP is created from int, uint, double... and no JSC engine has been bind yet. Current + value is kept in m_number + CBool -> QSVP is created from bool and no JSC engine has been associated yet. Current value is kept + in m_number + CSpecial -> QSVP is Undefined or Null, but a JSC engine hasn't been associated yet, current value + is kept in m_number (cast of QScriptValue::SpecialValue) + JSValue -> QSVP is associated with engine, but there is no information about real type, the state + have really short live cycle. Normally it is created as a function call result. + JSNative -> QSVP is associated with engine, and it is sure that it isn't a JavaScript object. + JSObject -> QSVP is associated with engine, and it is sure that it is a JavaScript object. + + Each state keep all necessary information to invoke all methods, if not it should be changed to + a proper state. Changed state shouldn't be reverted. +*/ + +class QScriptValuePrivate : public QSharedData { +public: + inline static QScriptValuePrivate* get(const QScriptValue& q); + inline static QScriptValue get(const QScriptValuePrivate* d); + inline static QScriptValue get(QScriptValuePrivate* d); + + inline ~QScriptValuePrivate(); + + inline QScriptValuePrivate(); + inline QScriptValuePrivate(const QString& string); + inline QScriptValuePrivate(bool value); + inline QScriptValuePrivate(int number); + inline QScriptValuePrivate(uint number); + inline QScriptValuePrivate(qsreal number); + inline QScriptValuePrivate(QScriptValue::SpecialValue value); + + inline QScriptValuePrivate(const QScriptEngine* engine, bool value); + inline QScriptValuePrivate(const QScriptEngine* engine, int value); + inline QScriptValuePrivate(const QScriptEngine* engine, uint value); + inline QScriptValuePrivate(const QScriptEngine* engine, qsreal value); + inline QScriptValuePrivate(const QScriptEngine* engine, const QString& value); + inline QScriptValuePrivate(const QScriptEngine* engine, QScriptValue::SpecialValue value); + + inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value); + inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value, JSObjectRef object); + + inline bool isValid() const; + inline bool isBool(); + inline bool isNumber(); + inline bool isNull(); + inline bool isString(); + inline bool isUndefined(); + inline bool isError(); + inline bool isObject(); + inline bool isFunction(); + + inline QString toString() const; + inline qsreal toNumber() const; + inline bool toBool() const; + inline qsreal toInteger() const; + inline qint32 toInt32() const; + inline quint32 toUInt32() const; + inline quint16 toUInt16() const; + + inline bool equals(QScriptValuePrivate* other); + inline bool strictlyEquals(const QScriptValuePrivate* other) const; + inline bool assignEngine(QScriptEnginePrivate* engine); + + inline QScriptValuePrivate* call(const QScriptValuePrivate* , const QScriptValueList& args); + + inline JSGlobalContextRef context() const; + inline JSValueRef value() const; + inline JSObjectRef object() const; + inline QScriptEnginePrivate* engine() const; + +private: + // Please, update class documentation when you change the enum. + enum States { + Invalid = 0, + CString = 0x1000, + CNumber, + CBool, + CSpecial, + JSValue = 0x2000, // JS values are equal or higher then this value. + JSNative, + JSObject + } m_state; + QScriptEnginePtr m_engine; + QString m_string; + qsreal m_number; + JSValueRef m_value; + JSObjectRef m_object; + + inline void setValue(JSValueRef); + + inline bool inherits(const char*); + + inline bool isJSBased() const; + inline bool isNumberBased() const; + inline bool isStringBased() const; +}; + +QScriptValuePrivate* QScriptValuePrivate::get(const QScriptValue& q) { return q.d_ptr.data(); } + +QScriptValue QScriptValuePrivate::get(const QScriptValuePrivate* d) +{ + return QScriptValue(const_cast<QScriptValuePrivate*>(d)); +} + +QScriptValue QScriptValuePrivate::get(QScriptValuePrivate* d) +{ + return QScriptValue(d); +} + +QScriptValuePrivate::~QScriptValuePrivate() +{ + if (m_value) + JSValueUnprotect(context(), m_value); +} + +QScriptValuePrivate::QScriptValuePrivate() + : m_state(Invalid) + , m_value(0) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(const QString& string) + : m_state(CString) + , m_string(string) + , m_value(0) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(bool value) + : m_state(CBool) + , m_number(value) + , m_value(0) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(int number) + : m_state(CNumber) + , m_number(number) + , m_value(0) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(uint number) + : m_state(CNumber) + , m_number(number) + , m_value(0) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(qsreal number) + : m_state(CNumber) + , m_number(number) + , m_value(0) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(QScriptValue::SpecialValue value) + : m_state(CSpecial) + , m_number(value) + , m_value(0) +{ +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, bool value) + : m_state(JSNative) +{ + if (!engine) { + // slower path reinitialization + m_state = CBool; + m_number = value; + m_value = 0; + } else { + m_engine = QScriptEnginePrivate::get(engine); + m_value = m_engine->makeJSValue(value); + JSValueProtect(context(), m_value); + } +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, int value) + : m_state(JSNative) +{ + if (!engine) { + // slower path reinitialization + m_state = CNumber; + m_number = value; + m_value = 0; + } else { + m_engine = QScriptEnginePrivate::get(engine); + m_value = m_engine->makeJSValue(value); + JSValueProtect(context(), m_value); + } +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, uint value) + : m_state(JSNative) +{ + if (!engine) { + // slower path reinitialization + m_state = CNumber; + m_number = value; + m_value = 0; + } else { + m_engine = QScriptEnginePrivate::get(engine); + m_value = m_engine->makeJSValue(value); + JSValueProtect(context(), m_value); + } +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, qsreal value) + : m_state(JSNative) +{ + if (!engine) { + // slower path reinitialization + m_state = CNumber; + m_number = value; + m_value = 0; + } else { + m_engine = QScriptEnginePrivate::get(engine); + m_value = m_engine->makeJSValue(value); + JSValueProtect(context(), m_value); + } +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, const QString& value) + : m_state(JSNative) +{ + if (!engine) { + // slower path reinitialization + m_state = CString; + m_string = value; + m_value = 0; + } else { + m_engine = QScriptEnginePrivate::get(engine); + m_value = m_engine->makeJSValue(value); + JSValueProtect(context(), m_value); + } +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, QScriptValue::SpecialValue value) + : m_state(JSNative) +{ + if (!engine) { + // slower path reinitialization + m_state = CSpecial; + m_number = value; + m_value = 0; + } else { + m_engine = QScriptEnginePrivate::get(engine); + m_value = m_engine->makeJSValue(value); + JSValueProtect(context(), m_value); + } +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value) + : m_state(JSValue) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) + , m_value(value) +{ + Q_ASSERT(engine); + JSValueProtect(context(), m_value); +} + +QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value, JSObjectRef object) + : m_state(JSObject) + , m_engine(const_cast<QScriptEnginePrivate*>(engine)) + , m_value(value) + , m_object(object) +{ + Q_ASSERT(engine); + JSValueProtect(context(), m_value); +} + +bool QScriptValuePrivate::isValid() const { return m_state != Invalid; } + +bool QScriptValuePrivate::isBool() +{ + switch (m_state) { + case CBool: + return true; + case JSValue: + if (isObject()) + return false; + // Fall-through. + case JSNative: + return JSValueIsBoolean(context(), value()); + default: + return false; + } +} + +bool QScriptValuePrivate::isNumber() +{ + switch (m_state) { + case CNumber: + return m_number; + case JSValue: + if (isObject()) + return false; + // Fall-through. + case JSNative: + return JSValueIsNumber(context(), value()); + default: + return false; + } +} + +bool QScriptValuePrivate::isNull() +{ + switch (m_state) { + case CSpecial: + return m_number == static_cast<int>(QScriptValue::NullValue); + case JSValue: + if (isObject()) + return false; + // Fall-through. + case JSNative: + return JSValueIsNull(context(), value()); + default: + return false; + } +} + +bool QScriptValuePrivate::isString() +{ + switch (m_state) { + case CString: + return true; + case JSValue: + if (isObject()) + return false; + // Fall-through. + case JSNative: + return JSValueIsString(context(), value()); + default: + return false; + } +} + +bool QScriptValuePrivate::isUndefined() +{ + switch (m_state) { + case CSpecial: + return m_number == static_cast<int>(QScriptValue::UndefinedValue); + case JSValue: + if (isObject()) + return false; + // Fall-through. + case JSNative: + return JSValueIsUndefined(context(), value()); + default: + return false; + } +} + +bool QScriptValuePrivate::isError() +{ + switch (m_state) { + case JSValue: + if (!isObject()) + return false; + // Fall-through. + case JSObject: + return inherits("Error"); + default: + return false; + } +} + +bool QScriptValuePrivate::isObject() +{ + switch (m_state) { + case JSObject: + return true; + case JSValue: + m_object = JSValueToObject(context(), value(), /* exception */ 0); + if (!m_object) + return false; + m_state = JSObject; + return true; + default: + return false; + } +} + +bool QScriptValuePrivate::isFunction() +{ + switch (m_state) { + case JSValue: + m_object = JSValueToObject(context(), value(), /* exception */ 0); + if (!m_object) + return false; + m_state = JSObject; + // Fall-through. + case JSObject: + return JSObjectIsFunction(context(), object()); + default: + return false; + } +} + +QString QScriptValuePrivate::toString() const +{ + switch (m_state) { + case Invalid: + return QString(); + case CBool: + return m_number ? QString::fromLatin1("true") : QString::fromLatin1("false"); + case CString: + return m_string; + case CNumber: + return QString::number(m_number); + case CSpecial: + return m_number == QScriptValue::NullValue ? QString::fromLatin1("null") : QString::fromLatin1("undefined"); + case JSValue: + case JSNative: + case JSObject: + return QScriptConverter::toString(JSValueToStringCopy(context(), value(), /* exception */ 0)); + } + + Q_ASSERT_X(false, "toString()", "Not all states are included in the previous switch statement."); + return QString(); // Avoid compiler warning. +} + +qsreal QScriptValuePrivate::toNumber() const +{ + // TODO Check it. + switch (m_state) { + case JSValue: + case JSNative: + case JSObject: + return JSValueToNumber(context(), value(), /* exception */ 0); + case CNumber: + case CBool: + return m_number; + case Invalid: + case CSpecial: + return false; + case CString: + return m_string.isEmpty(); + } + + Q_ASSERT_X(false, "toNumber()", "Not all states are included in the previous switch statement."); + return 0; // Avoid compiler warning. +} + +bool QScriptValuePrivate::toBool() const +{ + switch (m_state) { + case JSValue: + case JSNative: + case JSObject: + return JSValueToBoolean(context(), value()); + case CNumber: + case CBool: + return m_number; + case Invalid: + case CSpecial: + return false; + case CString: + return m_string.isEmpty(); + } + + Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement."); + return false; // Avoid compiler warning. +} + +qsreal QScriptValuePrivate::toInteger() const +{ + // TODO it is not true implementation! + return toNumber(); +} + +qint32 QScriptValuePrivate::toInt32() const +{ + // TODO it is not true implementation! + return toNumber(); +} + +quint32 QScriptValuePrivate::toUInt32() const +{ + // TODO it is not true implementation! + return toNumber(); +} + +quint16 QScriptValuePrivate::toUInt16() const +{ + // TODO it is not true implementation! + return toNumber(); +} + + +bool QScriptValuePrivate::equals(QScriptValuePrivate* other) +{ + if (!isValid() || !other->isValid()) + return false; + + if ((m_state == other->m_state) && !isJSBased()) { + if (isNumberBased()) + return m_number == other->m_number; + return m_string == other->m_string; + } + + if (isJSBased() && !other->isJSBased()) { + if (!other->assignEngine(engine())) { + qWarning("equals(): Cannot compare to a value created in a different engine"); + return false; + } + } else if (!isJSBased() && other->isJSBased()) { + if (!other->assignEngine(other->engine())) { + qWarning("equals(): Cannot compare to a value created in a different engine"); + return false; + } + } + + return JSValueIsEqual(context(), value(), other->value(), /* exception */ 0); +} + +bool QScriptValuePrivate::strictlyEquals(const QScriptValuePrivate* other) const +{ + if (m_state != other->m_state) + return false; + if (isJSBased()) { + if (other->engine() != engine()) { + qWarning("strictlyEquals(): Cannot compare to a value created in a different engine"); + return false; + } + return JSValueIsStrictEqual(context(), value(), other->value()); + } + if (isStringBased()) + return m_string == other->m_string; + if (isNumberBased()) + return m_number == other->m_number; + + return false; // Invalid state. +} + +/*! + Tries to assign \a engine to this value. Returns true on success; otherwise returns false. +*/ +bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine) +{ + JSValueRef value; + switch (m_state) { + case CBool: + value = engine->makeJSValue(static_cast<bool>(m_number)); + break; + case CString: + value = engine->makeJSValue(m_string); + break; + case CNumber: + value = engine->makeJSValue(m_number); + break; + case CSpecial: + value = engine->makeJSValue(static_cast<QScriptValue::SpecialValue>(m_number)); + break; + default: + if (!isJSBased()) + Q_ASSERT_X(!isJSBased(), "assignEngine()", "Not all states are included in the previous switch statement."); + else + qWarning("JSValue can't be rassigned to an another engine."); + return false; + } + m_engine = engine; + m_state = JSNative; + setValue(value); + return true; +} + +QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const QScriptValueList& args) +{ + switch (m_state) { + case JSValue: + m_object = JSValueToObject(context(), value(), /* exception */ 0); + if (!object()) { + m_state = JSValue; + return new QScriptValuePrivate; + } + m_state = JSObject; + // Fall-through. + case JSObject: + { + // Convert all arguments and bind to the engine. + int argc = args.size(); + QVarLengthArray<JSValueRef, 8> argv(argc); + QScriptValueList::const_iterator i = args.constBegin(); + for (int j = 0; i != args.constEnd(); j++, i++) { + QScriptValuePrivate* value = QScriptValuePrivate::get(*i); + if (!value->assignEngine(engine())) { + qWarning("QScriptValue::call() failed: cannot call function with values created in a different engine"); + return new QScriptValuePrivate; + } + argv[j] = value->value(); + } + + // Make the call + JSValueRef exception = 0; + JSValueRef result = JSObjectCallAsFunction(context(), object(), /* thisObject */ 0, argc, argv.constData(), &exception); + if (!result && exception) + return new QScriptValuePrivate(engine(), exception); + if (result && !exception) + return new QScriptValuePrivate(engine(), result); + } + // this QSV is not a function <-- !result && !exception. Fall-through. + default: + return new QScriptValuePrivate; + } +} + +QScriptEnginePrivate* QScriptValuePrivate::engine() const +{ + // As long as m_engine is an autoinitializated pointer we can safely return it without + // checking current state. + return m_engine.data(); +} + +JSGlobalContextRef QScriptValuePrivate::context() const +{ + Q_ASSERT(isJSBased()); + return m_engine->context(); +} + +JSValueRef QScriptValuePrivate::value() const +{ + Q_ASSERT(isJSBased()); + return m_value; +} + +JSObjectRef QScriptValuePrivate::object() const +{ + Q_ASSERT(m_state == JSObject); + return m_object; +} + +void QScriptValuePrivate::setValue(JSValueRef value) +{ + if (m_value) + JSValueUnprotect(context(), m_value); + if (value) + JSValueProtect(context(), value); + m_value = value; +} + +/*! + \internal + Returns true if QSV is created from constructor with the given \a name, it has to be a + built-in type. +*/ +bool QScriptValuePrivate::inherits(const char* name) +{ + Q_ASSERT(isJSBased()); + JSObjectRef globalObject = JSContextGetGlobalObject(context()); + JSValueRef error = JSObjectGetProperty(context(), globalObject, QScriptConverter::toString(name), 0); + return JSValueIsInstanceOfConstructor(context(), value(), JSValueToObject(context(), error, /* exception */ 0), /* exception */ 0); +} + +/*! + \internal + Returns true if QSV have an engine associated. +*/ +bool QScriptValuePrivate::isJSBased() const { return m_state >= JSValue; } + +/*! + \internal + Returns true if current value of QSV is placed in m_number. +*/ +bool QScriptValuePrivate::isNumberBased() const { return !isJSBased() && !isStringBased() && m_state != Invalid; } + +/*! + \internal + Returns true if current value of QSV is placed in m_string. +*/ +bool QScriptValuePrivate::isStringBased() const { return m_state == CString; } + +#endif // qscriptvalue_p_h diff --git a/JavaScriptCore/qt/api/qtscriptglobal.h b/JavaScriptCore/qt/api/qtscriptglobal.h new file mode 100644 index 0000000..29749c0 --- /dev/null +++ b/JavaScriptCore/qt/api/qtscriptglobal.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef qtscriptglobal_h +#define qtscriptglobal_h + +#include <QtCore/qglobal.h> + +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) +# if defined(QT_NODLL) +# elif defined(QT_MAKEDLL) /* create a Qt DLL library */ +# if defined(QT_BUILD_JAVASCRIPT_LIB) +# define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT +# else +# define Q_JAVASCRIPT_EXPORT Q_DECL_IMPORT +# endif +# elif defined(QT_DLL) /* use a Qt DLL library */ +# define Q_JAVASCRIPT_EXPORT +# endif +#endif + +#if defined(QT_SHARED) +# define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT +#else +# define Q_JAVASCRIPT_EXPORT +#endif + +#endif diff --git a/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro b/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro new file mode 100644 index 0000000..0dc0902 --- /dev/null +++ b/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = tst_qscriptengine +QT += testlib +include(../tests.pri) + +SOURCES += tst_qscriptengine.cpp + diff --git a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp new file mode 100644 index 0000000..37f3d11 --- /dev/null +++ b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp @@ -0,0 +1,58 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "qscriptengine.h" +#include "qscriptvalue.h" +#include <QtTest/qtest.h> + +class tst_QScriptEngine : public QObject { + Q_OBJECT + +public: + tst_QScriptEngine() {} + virtual ~tst_QScriptEngine() {} + +public slots: + void init() {} + void cleanup() {} + +private slots: + void evaluate(); + void collectGarbage(); +}; + +/* Evaluating a script that throw an unhandled exception should return an invalid value. */ +void tst_QScriptEngine::evaluate() +{ + QScriptEngine engine; + QVERIFY2(engine.evaluate("1+1").isValid(), "the expression should be evaluated and an valid result should be returned"); + QVERIFY2(engine.evaluate("ping").isValid(), "Script throwing an unhandled exception should return an exception value"); +} + +/* Test garbage collection, at least try to not crash. */ +void tst_QScriptEngine::collectGarbage() +{ + QScriptEngine engine; + QScriptValue foo = engine.evaluate("( function foo() {return 'pong';} )"); + QVERIFY(foo.isFunction()); + engine.collectGarbage(); + QCOMPARE(foo.call().toString(), QString::fromAscii("pong")); +} +QTEST_MAIN(tst_QScriptEngine) +#include "tst_qscriptengine.moc" diff --git a/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro b/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro new file mode 100644 index 0000000..1ce5bc3 --- /dev/null +++ b/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +TARGET = tst_qscriptvalue +QT += testlib +include(../tests.pri) + +SOURCES += tst_qscriptvalue.cpp + diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp new file mode 100644 index 0000000..336a1a6 --- /dev/null +++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp @@ -0,0 +1,427 @@ +/* + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "qscriptengine.h" +#include "qscriptvalue.h" +#include <QtTest/qtest.h> + +Q_DECLARE_METATYPE(QScriptValue*); +Q_DECLARE_METATYPE(QScriptValue); + +class tst_QScriptValue : public QObject { + Q_OBJECT + +public: + tst_QScriptValue() {} + virtual ~tst_QScriptValue() {} + +private slots: + void toString_data(); + void toString(); + void copyConstructor_data(); + void copyConstructor(); + void assignOperator_data(); + void assignOperator(); + void dataSharing(); + void constructors_data(); + void constructors(); + void call(); + + // copied from Qt's QtScript. + void ctor(); +}; + +void tst_QScriptValue::ctor() +{ + QScriptEngine eng; + { + QScriptValue v; + QCOMPARE(v.isValid(), false); + QCOMPARE(v.engine(), (QScriptEngine *)0); + } + { + QScriptValue v(&eng, QScriptValue::UndefinedValue); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isUndefined(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(&eng, QScriptValue::NullValue); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNull(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(&eng, false); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isBoolean(), true); + QCOMPARE(v.isBool(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toBoolean(), false); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(&eng, int(1)); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(int(0x43211234)); + QVERIFY(v.isNumber()); + QCOMPARE(v.toInt32(), 0x43211234); + } + { + QScriptValue v(&eng, uint(1)); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(uint(0x43211234)); + QVERIFY(v.isNumber()); + QCOMPARE(v.toUInt32(), uint(0x43211234)); + } + { + QScriptValue v(&eng, 1.0); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(12345678910.5); + QVERIFY(v.isNumber()); + QCOMPARE(v.toNumber(), 12345678910.5); + } + { + QScriptValue v(&eng, "ciao"); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isString(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toString(), QLatin1String("ciao")); + QCOMPARE(v.engine(), &eng); + } + { + QScriptValue v(&eng, QString("ciao")); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isString(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toString(), QLatin1String("ciao")); + QCOMPARE(v.engine(), &eng); + } + // copy constructor, operator= + { + QScriptValue v(&eng, 1.0); + QScriptValue v2(v); + QCOMPARE(v2.strictlyEquals(v), true); + QCOMPARE(v2.engine(), &eng); + + QScriptValue v3(v); + QCOMPARE(v3.strictlyEquals(v), true); + QCOMPARE(v3.strictlyEquals(v2), true); + QCOMPARE(v3.engine(), &eng); + + QScriptValue v4(&eng, 2.0); + QCOMPARE(v4.strictlyEquals(v), false); + v3 = v4; + QCOMPARE(v3.strictlyEquals(v), false); + QCOMPARE(v3.strictlyEquals(v4), true); + + v2 = QScriptValue(); + QCOMPARE(v2.strictlyEquals(v), false); + QCOMPARE(v.toNumber(), 1.0); + + QScriptValue v5(v); + QCOMPARE(v5.strictlyEquals(v), true); + v = QScriptValue(); + QCOMPARE(v5.strictlyEquals(v), false); + QCOMPARE(v5.toNumber(), 1.0); + } + + // constructors that take no engine argument + { + QScriptValue v(QScriptValue::UndefinedValue); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isUndefined(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.engine(), (QScriptEngine *)0); + } + { + QScriptValue v(QScriptValue::NullValue); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNull(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.engine(), (QScriptEngine *)0); + } + { + QScriptValue v(false); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isBoolean(), true); + QCOMPARE(v.isBool(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toBoolean(), false); + QCOMPARE(v.engine(), (QScriptEngine *)0); + } + { + QScriptValue v(int(1)); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), (QScriptEngine *)0); + } + { + QScriptValue v(uint(1)); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), (QScriptEngine *)0); + } + { + QScriptValue v(1.0); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isNumber(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toNumber(), 1.0); + QCOMPARE(v.engine(), (QScriptEngine *)0); + } + { + QScriptValue v("ciao"); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isString(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toString(), QLatin1String("ciao")); + QCOMPARE(v.engine(), (QScriptEngine *)0); + } + { + QScriptValue v(QString("ciao")); + QCOMPARE(v.isValid(), true); + QCOMPARE(v.isString(), true); + QCOMPARE(v.isObject(), false); + QCOMPARE(v.toString(), QLatin1String("ciao")); + QCOMPARE(v.engine(), (QScriptEngine *)0); + } + // copy constructor, operator= + { + QScriptValue v(1.0); + QScriptValue v2(v); + QCOMPARE(v2.strictlyEquals(v), true); + QCOMPARE(v2.engine(), (QScriptEngine *)0); + + QScriptValue v3(v); + QCOMPARE(v3.strictlyEquals(v), true); + QCOMPARE(v3.strictlyEquals(v2), true); + QCOMPARE(v3.engine(), (QScriptEngine *)0); + + QScriptValue v4(2.0); + QCOMPARE(v4.strictlyEquals(v), false); + v3 = v4; + QCOMPARE(v3.strictlyEquals(v), false); + QCOMPARE(v3.strictlyEquals(v4), true); + + v2 = QScriptValue(); + QCOMPARE(v2.strictlyEquals(v), false); + QCOMPARE(v.toNumber(), 1.0); + + QScriptValue v5(v); + QCOMPARE(v5.strictlyEquals(v), true); + v = QScriptValue(); + QCOMPARE(v5.strictlyEquals(v), false); + QCOMPARE(v5.toNumber(), 1.0); + } + + // 0 engine + QVERIFY(QScriptValue(0, QScriptValue::UndefinedValue).isUndefined()); + QVERIFY(QScriptValue(0, QScriptValue::NullValue).isNull()); + QVERIFY(QScriptValue(0, false).isBool()); + QVERIFY(QScriptValue(0, int(1)).isNumber()); + QVERIFY(QScriptValue(0, uint(1)).isNumber()); + QVERIFY(QScriptValue(0, 1.0).isNumber()); + QVERIFY(QScriptValue(0, "ciao").isString()); + QVERIFY(QScriptValue(0, QString("ciao")).isString()); +} + +void tst_QScriptValue::toString_data() +{ + QTest::addColumn<QString>("code"); + QTest::addColumn<QString>("result"); + + QTest::newRow("string") << QString::fromAscii("'hello'") << QString::fromAscii("hello"); + QTest::newRow("string utf") << QString::fromUtf8("'ąśćżźółńę'") << QString::fromUtf8("ąśćżźółńę"); + QTest::newRow("expression") << QString::fromAscii("1 + 4") << QString::fromAscii("5"); + QTest::newRow("null") << QString::fromAscii("null") << QString::fromAscii("null"); + QTest::newRow("boolean") << QString::fromAscii("false") << QString::fromAscii("false"); + QTest::newRow("undefined") << QString::fromAscii("undefined") << QString::fromAscii("undefined"); + QTest::newRow("object") << QString::fromAscii("new Object") << QString::fromAscii("[object Object]"); +} + +/* Test conversion to string from different JSC types */ +void tst_QScriptValue::toString() +{ + QFETCH(QString, code); + QFETCH(QString, result); + + QScriptEngine engine; + QCOMPARE(engine.evaluate(code).toString(), result); +} + +void tst_QScriptValue::copyConstructor_data() +{ + QScriptEngine engine; + QScriptValue nnumber(123); + QScriptValue nstring("ping"); + QScriptValue number(engine.evaluate("1")); + QScriptValue string(engine.evaluate("'foo'")); + QScriptValue object(engine.evaluate("new Object")); + QScriptValue undefined(engine.evaluate("undefined")); + QScriptValue null(engine.evaluate("null")); + + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QString>("result"); + + QTest::newRow("native number") << nnumber << QString::number(123); + QTest::newRow("native string") << nstring << QString("ping"); + QTest::newRow("number") << number << QString::fromAscii("1"); + QTest::newRow("string") << string << QString::fromAscii("foo"); + QTest::newRow("object") << object << QString::fromAscii("[object Object]"); + QTest::newRow("undefined") << undefined << QString::fromAscii("undefined"); + QTest::newRow("null") << null << QString::fromAscii("null"); +} + +void tst_QScriptValue::copyConstructor() +{ + QFETCH(QScriptValue, value); + QFETCH(QString, result); + + QVERIFY(value.isValid()); + QScriptValue tmp(value); + QVERIFY(tmp.isValid()); + QCOMPARE(tmp.toString(), result); +} + +void tst_QScriptValue::assignOperator_data() +{ + copyConstructor_data(); +} + +void tst_QScriptValue::assignOperator() +{ + QFETCH(QScriptValue, value); + QFETCH(QString, result); + + QScriptValue tmp; + tmp = value; + QVERIFY(tmp.isValid()); + QCOMPARE(tmp.toString(), result); +} + +/* Test internal data sharing between a diffrenet QScriptValue. */ +void tst_QScriptValue::dataSharing() +{ + QScriptEngine engine; + QScriptValue v1; + QScriptValue v2(v1); + + v1 = engine.evaluate("1"); // v1 == 1 ; v2 invalid. + QVERIFY(v1.isValid()); + QVERIFY(!v2.isValid()); + + v2 = v1; // v1 == 1; v2 == 1. + QVERIFY(v1.isValid()); + QVERIFY(v2.isValid()); + + v1 = engine.evaluate("obj = new Date"); // v1 == [object Date] ; v2 == 1. + QVERIFY(v1.isValid()); + QVERIFY(v2.isValid()); + QVERIFY(v2.toString() != v1.toString()); + + // TODO add object manipulation (v1 and v2 point to the same object). +} + +void tst_QScriptValue::constructors_data() +{ + QScriptEngine engine; + + QTest::addColumn<QScriptValue>("value"); + QTest::addColumn<QString>("string"); + QTest::addColumn<bool>("valid"); + QTest::addColumn<bool>("object"); + + QTest::newRow("invalid") << QScriptValue() << QString() << false << false; + QTest::newRow("number") << QScriptValue(-21) << QString::number(-21) << true << false; + QTest::newRow("bool") << QScriptValue(true) << QString::fromAscii("true") << true << false; + QTest::newRow("double") << QScriptValue(21.12) << QString::number(21.12) << true << false; + QTest::newRow("string") << QScriptValue("AlaMaKota") << QString::fromAscii("AlaMaKota") << true << false; + QTest::newRow("object") << engine.evaluate("new Object") << QString::fromAscii("[object Object]") << true << true; + QTest::newRow("null") << QScriptValue(QScriptValue::NullValue)<< QString::fromAscii("null") << true << false; + QTest::newRow("undef") << QScriptValue(QScriptValue::UndefinedValue)<< QString::fromAscii("undefined") << true << false; +} + +void tst_QScriptValue::constructors() +{ + QFETCH(QScriptValue, value); + QFETCH(QString, string); + QFETCH(bool, valid); + QFETCH(bool, object); + + QCOMPARE(value.isValid(), valid); + QCOMPARE(value.toString(), string); + QCOMPARE(value.isObject(), object); +} + +void tst_QScriptValue::call() +{ + QScriptEngine engine; + QScriptValue ping = engine.evaluate("( function() {return 'ping';} )"); + QScriptValue incr = engine.evaluate("( function(i) {return i + 1;} )"); + QScriptValue one(1); + QScriptValue five(5); + QScriptValue result; + + QVERIFY(one.isValid()); + QVERIFY(five.isValid()); + + QVERIFY(ping.isValid()); + QVERIFY(ping.isFunction()); + result = ping.call(); + QVERIFY(result.isValid()); + QCOMPARE(result.toString(), QString::fromUtf8("ping")); + + QVERIFY(incr.isValid()); + QVERIFY(incr.isFunction()); + result = incr.call(QScriptValue(), QScriptValueList() << one); + QVERIFY(result.isValid()); + QCOMPARE(result.toString(), QString("2")); + + QCOMPARE(incr.call(QScriptValue(), QScriptValueList() << five).toString(), QString::fromAscii("6")); + + QVERIFY(incr.call().isValid()); // Exception. +} + +QTEST_MAIN(tst_QScriptValue) +#include "tst_qscriptvalue.moc" diff --git a/JavaScriptCore/qt/tests/tests.pri b/JavaScriptCore/qt/tests/tests.pri new file mode 100644 index 0000000..1ce238f --- /dev/null +++ b/JavaScriptCore/qt/tests/tests.pri @@ -0,0 +1,28 @@ +isEmpty(OUTPUT_DIR) { + CONFIG(debug, debug|release) { + OUTPUT_DIR=$$PWD/WebKitBuild/Debug + } else { # Release + OUTPUT_DIR=$$PWD/WebKitBuild/Release + } +} + + +QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +QMAKE_LIBDIR = $$OUTPUT_DIR/lib $$QMAKE_LIBDIR +mac:!static:contains(QT_CONFIG, qt_framework):!CONFIG(webkit_no_framework) { + LIBS += -framework QtScript + QMAKE_FRAMEWORKPATH = $$OUTPUT_DIR/lib $$QMAKE_FRAMEWORKPATH +} else { + win32-*|wince* { + LIBS += -lQtScript$${QT_MAJOR_VERSION} + } else { + LIBS += -lQtScript + } +} + +CONFIG(release, debug|release) { + DEFINES += NDEBUG +} + +INCLUDEPATH += $$PWD/../api + diff --git a/JavaScriptCore/qt/tests/tests.pro b/JavaScriptCore/qt/tests/tests.pro new file mode 100644 index 0000000..6e5edb1 --- /dev/null +++ b/JavaScriptCore/qt/tests/tests.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = qscriptengine \ + qscriptvalue diff --git a/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp index 86a8f0a..bb30e3b 100644 --- a/JavaScriptCore/runtime/Arguments.cpp +++ b/JavaScriptCore/runtime/Arguments.cpp @@ -204,6 +204,19 @@ bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& prop return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); } +void Arguments::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) +{ + if (mode == IncludeDontEnumProperties) { + for (unsigned i = 0; i < d->numArguments; ++i) { + if (!d->deletedArguments || !d->deletedArguments[i]) + propertyNames.add(Identifier(exec, UString::from(i))); + } + propertyNames.add(exec->propertyNames().callee); + propertyNames.add(exec->propertyNames().length); + } + JSObject::getOwnPropertyNames(exec, propertyNames, mode); +} + void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& slot) { if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { diff --git a/JavaScriptCore/runtime/Arguments.h b/JavaScriptCore/runtime/Arguments.h index 9b674a2..9797e08 100644 --- a/JavaScriptCore/runtime/Arguments.h +++ b/JavaScriptCore/runtime/Arguments.h @@ -85,7 +85,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: @@ -96,6 +96,7 @@ namespace JSC { virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName); diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp index 5b359e7..ce814b2 100644 --- a/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -204,8 +204,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue buffer.append(rep->data(), rep->size()); } ASSERT(buffer.size() == totalSize); - unsigned finalSize = buffer.size(); - return jsString(exec, UString(buffer.releaseBuffer(), finalSize, false)); + return jsString(exec, UString::adopt(buffer)); } JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) diff --git a/JavaScriptCore/runtime/BooleanObject.h b/JavaScriptCore/runtime/BooleanObject.h index 69c2e51..4b02acb 100644 --- a/JavaScriptCore/runtime/BooleanObject.h +++ b/JavaScriptCore/runtime/BooleanObject.h @@ -34,7 +34,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } }; diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp index 1630a58..63139a2 100644 --- a/JavaScriptCore/runtime/Collector.cpp +++ b/JavaScriptCore/runtime/Collector.cpp @@ -45,7 +45,7 @@ #include <wtf/UnusedParam.h> #include <wtf/VMTags.h> -#if PLATFORM(DARWIN) +#if OS(DARWIN) #include <mach/mach_init.h> #include <mach/mach_port.h> @@ -53,29 +53,29 @@ #include <mach/thread_act.h> #include <mach/vm_map.h> -#elif PLATFORM(SYMBIAN) +#elif OS(SYMBIAN) #include <e32std.h> #include <e32cmn.h> #include <unistd.h> -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) #include <windows.h> #include <malloc.h> -#elif PLATFORM(HAIKU) +#elif OS(HAIKU) #include <OS.h> -#elif PLATFORM(UNIX) +#elif OS(UNIX) #include <stdlib.h> -#if !PLATFORM(HAIKU) +#if !OS(HAIKU) #include <sys/mman.h> #endif #include <unistd.h> -#if PLATFORM(SOLARIS) +#if OS(SOLARIS) #include <thread.h> #else #include <pthread.h> @@ -85,7 +85,7 @@ #include <pthread_np.h> #endif -#if PLATFORM(QNX) +#if OS(QNX) #include <fcntl.h> #include <sys/procfs.h> #include <stdio.h> @@ -104,21 +104,21 @@ namespace JSC { const size_t GROWTH_FACTOR = 2; const size_t LOW_WATER_FACTOR = 4; -const size_t ALLOCATIONS_PER_COLLECTION = 4000; +const size_t ALLOCATIONS_PER_COLLECTION = 3600; // This value has to be a macro to be used in max() without introducing // a PIC branch in Mach-O binaries, see <rdar://problem/5971391>. #define MIN_ARRAY_SIZE (static_cast<size_t>(14)) -#if PLATFORM(SYMBIAN) +#if OS(SYMBIAN) const size_t MAX_NUM_BLOCKS = 256; // Max size of collector heap set to 16 MB static RHeap* userChunk = 0; #endif #if ENABLE(JSC_MULTIPLE_THREADS) -#if PLATFORM(DARWIN) +#if OS(DARWIN) typedef mach_port_t PlatformThread; -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) typedef HANDLE PlatformThread; #endif @@ -148,8 +148,8 @@ Heap::Heap(JSGlobalData* globalData) , m_globalData(globalData) { ASSERT(globalData); - -#if PLATFORM(SYMBIAN) + +#if OS(SYMBIAN) // Symbian OpenC supports mmap but currently not the MAP_ANON flag. // Using fastMalloc() does not properly align blocks on 64k boundaries // and previous implementation was flawed/incomplete. @@ -167,10 +167,10 @@ Heap::Heap(JSGlobalData* globalData) if (!userChunk) CRASH(); } -#endif // PLATFORM(SYMBIAN) +#endif // OS(SYMBIAN) - memset(&primaryHeap, 0, sizeof(CollectorHeap)); - memset(&numberHeap, 0, sizeof(CollectorHeap)); + memset(&m_heap, 0, sizeof(CollectorHeap)); + allocateBlock(); } Heap::~Heap() @@ -186,6 +186,9 @@ void Heap::destroy() if (!m_globalData) return; + ASSERT(!m_globalData->dynamicGlobalObject); + ASSERT(!isBusy()); + // The global object is not GC protected at this point, so sweeping may delete it // (and thus the global data) before other objects that may use the global data. RefPtr<JSGlobalData> protect(m_globalData); @@ -193,15 +196,7 @@ void Heap::destroy() delete m_markListSet; m_markListSet = 0; - sweep<PrimaryHeap>(); - // No need to sweep number heap, because the JSNumber destructor doesn't do anything. -#if ENABLE(JSC_ZOMBIES) - ASSERT(primaryHeap.numLiveObjects == primaryHeap.numZombies); -#else - ASSERT(!primaryHeap.numLiveObjects); -#endif - freeBlocks(&primaryHeap); - freeBlocks(&numberHeap); + freeBlocks(); #if ENABLE(JSC_MULTIPLE_THREADS) if (m_currentThreadRegistrar) { @@ -220,24 +215,20 @@ void Heap::destroy() m_globalData = 0; } -template <HeapType heapType> NEVER_INLINE CollectorBlock* Heap::allocateBlock() { -#if PLATFORM(DARWIN) +#if OS(DARWIN) vm_address_t address = 0; - // FIXME: tag the region as a JavaScriptCore heap when we get a registered VM tag: <rdar://problem/6054788>. vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE | VM_TAG_FOR_COLLECTOR_MEMORY, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT); -#elif PLATFORM(SYMBIAN) +#elif OS(SYMBIAN) // Allocate a 64 kb aligned CollectorBlock unsigned char* mask = reinterpret_cast<unsigned char*>(userChunk->Alloc(BLOCK_SIZE)); if (!mask) CRASH(); uintptr_t address = reinterpret_cast<uintptr_t>(mask); - - memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE); -#elif PLATFORM(WINCE) +#elif OS(WINCE) void* address = VirtualAlloc(NULL, BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) #if COMPILER(MINGW) void* address = __mingw_aligned_malloc(BLOCK_SIZE, BLOCK_SIZE); #else @@ -247,7 +238,6 @@ NEVER_INLINE CollectorBlock* Heap::allocateBlock() #elif HAVE(POSIX_MEMALIGN) void* address; posix_memalign(&address, BLOCK_SIZE, BLOCK_SIZE); - memset(address, 0, BLOCK_SIZE); #else #if ENABLE(JSC_MULTIPLE_THREADS) @@ -273,55 +263,63 @@ NEVER_INLINE CollectorBlock* Heap::allocateBlock() munmap(reinterpret_cast<char*>(address + adjust + BLOCK_SIZE), extra - adjust); address += adjust; - memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE); #endif + // Initialize block. + CollectorBlock* block = reinterpret_cast<CollectorBlock*>(address); - block->freeList = block->cells; block->heap = this; - block->type = heapType; + clearMarkBits(block); - CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap; - size_t numBlocks = heap.numBlocks; - if (heap.usedBlocks == numBlocks) { + Structure* dummyMarkableCellStructure = m_globalData->dummyMarkableCellStructure.get(); + for (size_t i = 0; i < HeapConstants::cellsPerBlock; ++i) + new (block->cells + i) JSCell(dummyMarkableCellStructure); + + // Add block to blocks vector. + + size_t numBlocks = m_heap.numBlocks; + if (m_heap.usedBlocks == numBlocks) { static const size_t maxNumBlocks = ULONG_MAX / sizeof(CollectorBlock*) / GROWTH_FACTOR; if (numBlocks > maxNumBlocks) CRASH(); numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR); - heap.numBlocks = numBlocks; - heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, numBlocks * sizeof(CollectorBlock*))); + m_heap.numBlocks = numBlocks; + m_heap.blocks = static_cast<CollectorBlock**>(fastRealloc(m_heap.blocks, numBlocks * sizeof(CollectorBlock*))); } - heap.blocks[heap.usedBlocks++] = block; + m_heap.blocks[m_heap.usedBlocks++] = block; return block; } -template <HeapType heapType> NEVER_INLINE void Heap::freeBlock(size_t block) { - CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap; + m_heap.didShrink = true; - freeBlock(heap.blocks[block]); + ObjectIterator it(m_heap, block); + ObjectIterator end(m_heap, block + 1); + for ( ; it != end; ++it) + (*it)->~JSCell(); + freeBlockPtr(m_heap.blocks[block]); // swap with the last block so we compact as we go - heap.blocks[block] = heap.blocks[heap.usedBlocks - 1]; - heap.usedBlocks--; + m_heap.blocks[block] = m_heap.blocks[m_heap.usedBlocks - 1]; + m_heap.usedBlocks--; - if (heap.numBlocks > MIN_ARRAY_SIZE && heap.usedBlocks < heap.numBlocks / LOW_WATER_FACTOR) { - heap.numBlocks = heap.numBlocks / GROWTH_FACTOR; - heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, heap.numBlocks * sizeof(CollectorBlock*))); + if (m_heap.numBlocks > MIN_ARRAY_SIZE && m_heap.usedBlocks < m_heap.numBlocks / LOW_WATER_FACTOR) { + m_heap.numBlocks = m_heap.numBlocks / GROWTH_FACTOR; + m_heap.blocks = static_cast<CollectorBlock**>(fastRealloc(m_heap.blocks, m_heap.numBlocks * sizeof(CollectorBlock*))); } } -NEVER_INLINE void Heap::freeBlock(CollectorBlock* block) +NEVER_INLINE void Heap::freeBlockPtr(CollectorBlock* block) { -#if PLATFORM(DARWIN) +#if OS(DARWIN) vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(block), BLOCK_SIZE); -#elif PLATFORM(SYMBIAN) +#elif OS(SYMBIAN) userChunk->Free(reinterpret_cast<TAny*>(block)); -#elif PLATFORM(WINCE) +#elif OS(WINCE) VirtualFree(block, 0, MEM_RELEASE); -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) #if COMPILER(MINGW) __mingw_aligned_free(block); #else @@ -334,13 +332,34 @@ NEVER_INLINE void Heap::freeBlock(CollectorBlock* block) #endif } -void Heap::freeBlocks(CollectorHeap* heap) +void Heap::freeBlocks() { - for (size_t i = 0; i < heap->usedBlocks; ++i) - if (heap->blocks[i]) - freeBlock(heap->blocks[i]); - fastFree(heap->blocks); - memset(heap, 0, sizeof(CollectorHeap)); + ProtectCountSet protectedValuesCopy = m_protectedValues; + + clearMarkBits(); + ProtectCountSet::iterator protectedValuesEnd = protectedValuesCopy.end(); + for (ProtectCountSet::iterator it = protectedValuesCopy.begin(); it != protectedValuesEnd; ++it) + markCell(it->first); + + m_heap.nextCell = 0; + m_heap.nextBlock = 0; + DeadObjectIterator it(m_heap, m_heap.nextBlock, m_heap.nextCell); + DeadObjectIterator end(m_heap, m_heap.usedBlocks); + for ( ; it != end; ++it) + (*it)->~JSCell(); + + ASSERT(!protectedObjectCount()); + + protectedValuesEnd = protectedValuesCopy.end(); + for (ProtectCountSet::iterator it = protectedValuesCopy.begin(); it != protectedValuesEnd; ++it) + it->first->~JSCell(); + + for (size_t block = 0; block < m_heap.usedBlocks; ++block) + freeBlockPtr(m_heap.blocks[block]); + + fastFree(m_heap.blocks); + + memset(&m_heap, 0, sizeof(CollectorHeap)); } void Heap::recordExtraCost(size_t cost) @@ -355,123 +374,109 @@ void Heap::recordExtraCost(size_t cost) // are either very short lived temporaries, or have extremely long lifetimes. So // if a large value survives one garbage collection, there is not much point to // collecting more frequently as long as it stays alive. - // NOTE: we target the primaryHeap unconditionally as JSNumber doesn't modify cost - primaryHeap.extraCost += cost; + if (m_heap.extraCost > maxExtraCost && m_heap.extraCost > m_heap.usedBlocks * BLOCK_SIZE / 2) { + // If the last iteration through the heap deallocated blocks, we need + // to clean up remaining garbage before marking. Otherwise, the conservative + // marking mechanism might follow a pointer to unmapped memory. + if (m_heap.didShrink) + sweep(); + reset(); + } + m_heap.extraCost += cost; } -template <HeapType heapType> ALWAYS_INLINE void* Heap::heapAllocate(size_t s) +void* Heap::allocate(size_t s) { - typedef typename HeapConstants<heapType>::Block Block; - typedef typename HeapConstants<heapType>::Cell Cell; - - CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap; + typedef HeapConstants::Block Block; + typedef HeapConstants::Cell Cell; + ASSERT(JSLock::lockCount() > 0); ASSERT(JSLock::currentThreadIsHoldingLock()); - ASSERT_UNUSED(s, s <= HeapConstants<heapType>::cellSize); + ASSERT_UNUSED(s, s <= HeapConstants::cellSize); - ASSERT(heap.operationInProgress == NoOperation); - ASSERT(heapType == PrimaryHeap || heap.extraCost == 0); - // FIXME: If another global variable access here doesn't hurt performance - // too much, we could CRASH() in NDEBUG builds, which could help ensure we - // don't spend any time debugging cases where we allocate inside an object's - // deallocation code. + ASSERT(m_heap.operationInProgress == NoOperation); #if COLLECT_ON_EVERY_ALLOCATION - collect(); + collectAllGarbage(); + ASSERT(m_heap.operationInProgress == NoOperation); #endif - size_t numLiveObjects = heap.numLiveObjects; - size_t usedBlocks = heap.usedBlocks; - size_t i = heap.firstBlockWithPossibleSpace; - - // if we have a huge amount of extra cost, we'll try to collect even if we still have - // free cells left. - if (heapType == PrimaryHeap && heap.extraCost > ALLOCATIONS_PER_COLLECTION) { - size_t numLiveObjectsAtLastCollect = heap.numLiveObjectsAtLastCollect; - size_t numNewObjects = numLiveObjects - numLiveObjectsAtLastCollect; - const size_t newCost = numNewObjects + heap.extraCost; - if (newCost >= ALLOCATIONS_PER_COLLECTION && newCost >= numLiveObjectsAtLastCollect) - goto collect; - } +allocate: - ASSERT(heap.operationInProgress == NoOperation); -#ifndef NDEBUG - // FIXME: Consider doing this in NDEBUG builds too (see comment above). - heap.operationInProgress = Allocation; -#endif + // Fast case: find the next garbage cell and recycle it. -scan: - Block* targetBlock; - size_t targetBlockUsedCells; - if (i != usedBlocks) { - targetBlock = reinterpret_cast<Block*>(heap.blocks[i]); - targetBlockUsedCells = targetBlock->usedCells; - ASSERT(targetBlockUsedCells <= HeapConstants<heapType>::cellsPerBlock); - while (targetBlockUsedCells == HeapConstants<heapType>::cellsPerBlock) { - if (++i == usedBlocks) - goto collect; - targetBlock = reinterpret_cast<Block*>(heap.blocks[i]); - targetBlockUsedCells = targetBlock->usedCells; - ASSERT(targetBlockUsedCells <= HeapConstants<heapType>::cellsPerBlock); - } - heap.firstBlockWithPossibleSpace = i; - } else { + do { + ASSERT(m_heap.nextBlock < m_heap.usedBlocks); + Block* block = reinterpret_cast<Block*>(m_heap.blocks[m_heap.nextBlock]); + do { + ASSERT(m_heap.nextCell < HeapConstants::cellsPerBlock); + if (!block->marked.get(m_heap.nextCell)) { // Always false for the last cell in the block + Cell* cell = block->cells + m_heap.nextCell; -collect: - size_t numLiveObjectsAtLastCollect = heap.numLiveObjectsAtLastCollect; - size_t numNewObjects = numLiveObjects - numLiveObjectsAtLastCollect; - const size_t newCost = numNewObjects + heap.extraCost; + m_heap.operationInProgress = Allocation; + JSCell* imp = reinterpret_cast<JSCell*>(cell); + imp->~JSCell(); + m_heap.operationInProgress = NoOperation; - if (newCost >= ALLOCATIONS_PER_COLLECTION && newCost >= numLiveObjectsAtLastCollect) { -#ifndef NDEBUG - heap.operationInProgress = NoOperation; -#endif - bool foundGarbage = collect(); - numLiveObjects = heap.numLiveObjects; - usedBlocks = heap.usedBlocks; - i = heap.firstBlockWithPossibleSpace; -#ifndef NDEBUG - heap.operationInProgress = Allocation; -#endif - if (foundGarbage) - goto scan; - } + ++m_heap.nextCell; + return cell; + } + } while (++m_heap.nextCell != HeapConstants::cellsPerBlock); + m_heap.nextCell = 0; + } while (++m_heap.nextBlock != m_heap.usedBlocks); - // didn't find a block, and GC didn't reclaim anything, need to allocate a new block - targetBlock = reinterpret_cast<Block*>(allocateBlock<heapType>()); - heap.firstBlockWithPossibleSpace = heap.usedBlocks - 1; - targetBlockUsedCells = 0; - } + // Slow case: reached the end of the heap. Mark live objects and start over. - // find a free spot in the block and detach it from the free list - Cell* newCell = targetBlock->freeList; + reset(); + goto allocate; +} - // "next" field is a cell offset -- 0 means next cell, so a zeroed block is already initialized - targetBlock->freeList = (newCell + 1) + newCell->u.freeCell.next; +void Heap::resizeBlocks() +{ + m_heap.didShrink = false; - targetBlock->usedCells = static_cast<uint32_t>(targetBlockUsedCells + 1); - heap.numLiveObjects = numLiveObjects + 1; + size_t usedCellCount = markedCells(); + size_t minCellCount = usedCellCount + max(ALLOCATIONS_PER_COLLECTION, usedCellCount); + size_t minBlockCount = (minCellCount + HeapConstants::cellsPerBlock - 1) / HeapConstants::cellsPerBlock; -#ifndef NDEBUG - // FIXME: Consider doing this in NDEBUG builds too (see comment above). - heap.operationInProgress = NoOperation; -#endif + size_t maxCellCount = 1.25f * minCellCount; + size_t maxBlockCount = (maxCellCount + HeapConstants::cellsPerBlock - 1) / HeapConstants::cellsPerBlock; - return newCell; + if (m_heap.usedBlocks < minBlockCount) + growBlocks(minBlockCount); + else if (m_heap.usedBlocks > maxBlockCount) + shrinkBlocks(maxBlockCount); } -void* Heap::allocate(size_t s) +void Heap::growBlocks(size_t neededBlocks) { - return heapAllocate<PrimaryHeap>(s); + ASSERT(m_heap.usedBlocks < neededBlocks); + while (m_heap.usedBlocks < neededBlocks) + allocateBlock(); } -void* Heap::allocateNumber(size_t s) +void Heap::shrinkBlocks(size_t neededBlocks) { - return heapAllocate<NumberHeap>(s); + ASSERT(m_heap.usedBlocks > neededBlocks); + + // Clear the always-on last bit, so isEmpty() isn't fooled by it. + for (size_t i = 0; i < m_heap.usedBlocks; ++i) + m_heap.blocks[i]->marked.clear(HeapConstants::cellsPerBlock - 1); + + for (size_t i = 0; i != m_heap.usedBlocks && m_heap.usedBlocks != neededBlocks; ) { + if (m_heap.blocks[i]->marked.isEmpty()) { + freeBlock(i); + } else + ++i; + } + + // Reset the always-on last bit. + for (size_t i = 0; i < m_heap.usedBlocks; ++i) + m_heap.blocks[i]->marked.set(HeapConstants::cellsPerBlock - 1); } -#if PLATFORM(WINCE) +#if OS(WINCE) void* g_stackBase = 0; inline bool isPageWritable(void* page) @@ -528,7 +533,7 @@ static void* getStackBase(void* previousFrame) } #endif -#if PLATFORM(QNX) +#if OS(QNX) static inline void *currentThreadStackBaseQNX() { static void* stackBase = 0; @@ -557,10 +562,10 @@ static inline void *currentThreadStackBaseQNX() static inline void* currentThreadStackBase() { -#if PLATFORM(DARWIN) +#if OS(DARWIN) pthread_t thread = pthread_self(); return pthread_get_stackaddr_np(thread); -#elif PLATFORM(WIN_OS) && PLATFORM(X86) && COMPILER(MSVC) +#elif OS(WINDOWS) && CPU(X86) && COMPILER(MSVC) // offset 0x18 from the FS segment register gives a pointer to // the thread information block for the current thread NT_TIB* pTib; @@ -569,10 +574,11 @@ static inline void* currentThreadStackBase() MOV pTib, EAX } return static_cast<void*>(pTib->StackBase); -#elif PLATFORM(WIN_OS) && PLATFORM(X86_64) && COMPILER(MSVC) +#elif OS(WINDOWS) && CPU(X86_64) && COMPILER(MSVC) + // FIXME: why only for MSVC? PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb()); return reinterpret_cast<void*>(pTib->StackBase); -#elif PLATFORM(WIN_OS) && PLATFORM(X86) && COMPILER(GCC) +#elif OS(WINDOWS) && CPU(X86) && COMPILER(GCC) // offset 0x18 from the FS segment register gives a pointer to // the thread information block for the current thread NT_TIB* pTib; @@ -580,18 +586,18 @@ static inline void* currentThreadStackBase() : "=r" (pTib) ); return static_cast<void*>(pTib->StackBase); -#elif PLATFORM(QNX) +#elif OS(QNX) return currentThreadStackBaseQNX(); -#elif PLATFORM(SOLARIS) +#elif OS(SOLARIS) stack_t s; thr_stksegment(&s); return s.ss_sp; -#elif PLATFORM(OPENBSD) +#elif OS(OPENBSD) pthread_t thread = pthread_self(); stack_t stack; pthread_stackseg_np(thread, &stack); return stack.ss_sp; -#elif PLATFORM(SYMBIAN) +#elif OS(SYMBIAN) static void* stackBase = 0; if (stackBase == 0) { TThreadStackInfo info; @@ -600,11 +606,11 @@ static inline void* currentThreadStackBase() stackBase = (void*)info.iBase; } return (void*)stackBase; -#elif PLATFORM(HAIKU) +#elif OS(HAIKU) thread_info threadInfo; get_thread_info(find_thread(NULL), &threadInfo); return threadInfo.stack_end; -#elif PLATFORM(UNIX) +#elif OS(UNIX) static void* stackBase = 0; static size_t stackSize = 0; static pthread_t stackThread; @@ -612,7 +618,7 @@ static inline void* currentThreadStackBase() if (stackBase == 0 || thread != stackThread) { pthread_attr_t sattr; pthread_attr_init(&sattr); -#if HAVE(PTHREAD_NP_H) || PLATFORM(NETBSD) +#if HAVE(PTHREAD_NP_H) || OS(NETBSD) // e.g. on FreeBSD 5.4, neundorf@kde.org pthread_attr_get_np(thread, &sattr); #else @@ -626,7 +632,7 @@ static inline void* currentThreadStackBase() stackThread = thread; } return static_cast<char*>(stackBase) + stackSize; -#elif PLATFORM(WINCE) +#elif OS(WINCE) if (g_stackBase) return g_stackBase; else { @@ -642,9 +648,9 @@ static inline void* currentThreadStackBase() static inline PlatformThread getCurrentPlatformThread() { -#if PLATFORM(DARWIN) +#if OS(DARWIN) return pthread_mach_thread_np(pthread_self()); -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) return pthread_getw32threadhandle_np(pthread_self()); #endif } @@ -714,10 +720,37 @@ void Heap::registerThread() #endif -#define IS_POINTER_ALIGNED(p) (((intptr_t)(p) & (sizeof(char*) - 1)) == 0) +inline bool isPointerAligned(void* p) +{ + return (((intptr_t)(p) & (sizeof(char*) - 1)) == 0); +} + +// Cell size needs to be a power of two for isPossibleCell to be valid. +COMPILE_ASSERT(sizeof(CollectorCell) % 2 == 0, Collector_cell_size_is_power_of_two); + +#if USE(JSVALUE32) +static bool isHalfCellAligned(void *p) +{ + return (((intptr_t)(p) & (CELL_MASK >> 1)) == 0); +} + +static inline bool isPossibleCell(void* p) +{ + return isHalfCellAligned(p) && p; +} + +#else + +static inline bool isCellAligned(void *p) +{ + return (((intptr_t)(p) & CELL_MASK) == 0); +} -// cell size needs to be a power of two for this to be valid -#define IS_HALF_CELL_ALIGNED(p) (((intptr_t)(p) & (CELL_MASK >> 1)) == 0) +static inline bool isPossibleCell(void* p) +{ + return isCellAligned(p) && p; +} +#endif // USE(JSVALUE32) void Heap::markConservatively(MarkStack& markStack, void* start, void* end) { @@ -728,46 +761,33 @@ void Heap::markConservatively(MarkStack& markStack, void* start, void* end) } ASSERT((static_cast<char*>(end) - static_cast<char*>(start)) < 0x1000000); - ASSERT(IS_POINTER_ALIGNED(start)); - ASSERT(IS_POINTER_ALIGNED(end)); + ASSERT(isPointerAligned(start)); + ASSERT(isPointerAligned(end)); char** p = static_cast<char**>(start); char** e = static_cast<char**>(end); - size_t usedPrimaryBlocks = primaryHeap.usedBlocks; - size_t usedNumberBlocks = numberHeap.usedBlocks; - CollectorBlock** primaryBlocks = primaryHeap.blocks; - CollectorBlock** numberBlocks = numberHeap.blocks; - - const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1); - + CollectorBlock** blocks = m_heap.blocks; while (p != e) { char* x = *p++; - if (IS_HALF_CELL_ALIGNED(x) && x) { + if (isPossibleCell(x)) { + size_t usedBlocks; uintptr_t xAsBits = reinterpret_cast<uintptr_t>(x); xAsBits &= CELL_ALIGN_MASK; + uintptr_t offset = xAsBits & BLOCK_OFFSET_MASK; + const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1); + if (offset > lastCellOffset) + continue; + CollectorBlock* blockAddr = reinterpret_cast<CollectorBlock*>(xAsBits - offset); - // Mark the the number heap, we can mark these Cells directly to avoid the virtual call cost - for (size_t block = 0; block < usedNumberBlocks; block++) { - if ((numberBlocks[block] == blockAddr) & (offset <= lastCellOffset)) { - Heap::markCell(reinterpret_cast<JSCell*>(xAsBits)); - goto endMarkLoop; - } - } - - // Mark the primary heap - for (size_t block = 0; block < usedPrimaryBlocks; block++) { - if ((primaryBlocks[block] == blockAddr) & (offset <= lastCellOffset)) { - if (reinterpret_cast<CollectorCell*>(xAsBits)->u.freeCell.zeroIfFree) { - markStack.append(reinterpret_cast<JSCell*>(xAsBits)); - markStack.drain(); - } - break; - } + usedBlocks = m_heap.usedBlocks; + for (size_t block = 0; block < usedBlocks; block++) { + if (blocks[block] != blockAddr) + continue; + markStack.append(reinterpret_cast<JSCell*>(xAsBits)); + markStack.drain(); } - endMarkLoop: - ; } } } @@ -806,9 +826,9 @@ void Heap::markCurrentThreadConservatively(MarkStack& markStack) static inline void suspendThread(const PlatformThread& platformThread) { -#if PLATFORM(DARWIN) +#if OS(DARWIN) thread_suspend(platformThread); -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) SuspendThread(platformThread); #else #error Need a way to suspend threads on this platform @@ -817,9 +837,9 @@ static inline void suspendThread(const PlatformThread& platformThread) static inline void resumeThread(const PlatformThread& platformThread) { -#if PLATFORM(DARWIN) +#if OS(DARWIN) thread_resume(platformThread); -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) ResumeThread(platformThread); #else #error Need a way to resume threads on this platform @@ -828,23 +848,23 @@ static inline void resumeThread(const PlatformThread& platformThread) typedef unsigned long usword_t; // word size, assumed to be either 32 or 64 bit -#if PLATFORM(DARWIN) +#if OS(DARWIN) -#if PLATFORM(X86) +#if CPU(X86) typedef i386_thread_state_t PlatformThreadRegisters; -#elif PLATFORM(X86_64) +#elif CPU(X86_64) typedef x86_thread_state64_t PlatformThreadRegisters; -#elif PLATFORM(PPC) +#elif CPU(PPC) typedef ppc_thread_state_t PlatformThreadRegisters; -#elif PLATFORM(PPC64) +#elif CPU(PPC64) typedef ppc_thread_state64_t PlatformThreadRegisters; -#elif PLATFORM(ARM) +#elif CPU(ARM) typedef arm_thread_state_t PlatformThreadRegisters; #else #error Unknown Architecture #endif -#elif PLATFORM(WIN_OS)&& PLATFORM(X86) +#elif OS(WINDOWS) && CPU(X86) typedef CONTEXT PlatformThreadRegisters; #else #error Need a thread register struct for this platform @@ -852,21 +872,21 @@ typedef CONTEXT PlatformThreadRegisters; static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, PlatformThreadRegisters& regs) { -#if PLATFORM(DARWIN) +#if OS(DARWIN) -#if PLATFORM(X86) +#if CPU(X86) unsigned user_count = sizeof(regs)/sizeof(int); thread_state_flavor_t flavor = i386_THREAD_STATE; -#elif PLATFORM(X86_64) +#elif CPU(X86_64) unsigned user_count = x86_THREAD_STATE64_COUNT; thread_state_flavor_t flavor = x86_THREAD_STATE64; -#elif PLATFORM(PPC) +#elif CPU(PPC) unsigned user_count = PPC_THREAD_STATE_COUNT; thread_state_flavor_t flavor = PPC_THREAD_STATE; -#elif PLATFORM(PPC64) +#elif CPU(PPC64) unsigned user_count = PPC_THREAD_STATE64_COUNT; thread_state_flavor_t flavor = PPC_THREAD_STATE64; -#elif PLATFORM(ARM) +#elif CPU(ARM) unsigned user_count = ARM_THREAD_STATE_COUNT; thread_state_flavor_t flavor = ARM_THREAD_STATE; #else @@ -880,9 +900,9 @@ static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, P CRASH(); } return user_count * sizeof(usword_t); -// end PLATFORM(DARWIN) +// end OS(DARWIN) -#elif PLATFORM(WIN_OS) && PLATFORM(X86) +#elif OS(WINDOWS) && CPU(X86) regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL | CONTEXT_SEGMENTS; GetThreadContext(platformThread, ®s); return sizeof(CONTEXT); @@ -893,17 +913,17 @@ static size_t getPlatformThreadRegisters(const PlatformThread& platformThread, P static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs) { -#if PLATFORM(DARWIN) +#if OS(DARWIN) #if __DARWIN_UNIX03 -#if PLATFORM(X86) +#if CPU(X86) return reinterpret_cast<void*>(regs.__esp); -#elif PLATFORM(X86_64) +#elif CPU(X86_64) return reinterpret_cast<void*>(regs.__rsp); -#elif PLATFORM(PPC) || PLATFORM(PPC64) +#elif CPU(PPC) || CPU(PPC64) return reinterpret_cast<void*>(regs.__r1); -#elif PLATFORM(ARM) +#elif CPU(ARM) return reinterpret_cast<void*>(regs.__sp); #else #error Unknown Architecture @@ -911,11 +931,11 @@ static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs) #else // !__DARWIN_UNIX03 -#if PLATFORM(X86) +#if CPU(X86) return reinterpret_cast<void*>(regs.esp); -#elif PLATFORM(X86_64) +#elif CPU(X86_64) return reinterpret_cast<void*>(regs.rsp); -#elif (PLATFORM(PPC) || PLATFORM(PPC64)) +#elif CPU(PPC) || CPU(PPC64) return reinterpret_cast<void*>(regs.r1); #else #error Unknown Architecture @@ -923,8 +943,8 @@ static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs) #endif // __DARWIN_UNIX03 -// end PLATFORM(DARWIN) -#elif PLATFORM(X86) && PLATFORM(WIN_OS) +// end OS(DARWIN) +#elif CPU(X86) && OS(WINDOWS) return reinterpret_cast<void*>((uintptr_t) regs.Esp); #else #error Need a way to get the stack pointer for another thread on this platform @@ -1009,129 +1029,68 @@ void Heap::markProtectedObjects(MarkStack& markStack) } } -template <HeapType heapType> size_t Heap::sweep() +void Heap::clearMarkBits() { - typedef typename HeapConstants<heapType>::Block Block; - typedef typename HeapConstants<heapType>::Cell Cell; + for (size_t i = 0; i < m_heap.usedBlocks; ++i) + clearMarkBits(m_heap.blocks[i]); +} - // SWEEP: delete everything with a zero refcount (garbage) and unmark everything else - CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap; - - size_t emptyBlocks = 0; - size_t numLiveObjects = heap.numLiveObjects; +void Heap::clearMarkBits(CollectorBlock* block) +{ + // allocate assumes that the last cell in every block is marked. + block->marked.clearAll(); + block->marked.set(HeapConstants::cellsPerBlock - 1); +} + +size_t Heap::markedCells(size_t startBlock, size_t startCell) const +{ + ASSERT(startBlock <= m_heap.usedBlocks); + ASSERT(startCell < HeapConstants::cellsPerBlock); + + if (startBlock >= m_heap.usedBlocks) + return 0; + + size_t result = 0; + result += m_heap.blocks[startBlock]->marked.count(startCell); + for (size_t i = startBlock + 1; i < m_heap.usedBlocks; ++i) + result += m_heap.blocks[i]->marked.count(); + + return result; +} + +void Heap::sweep() +{ + ASSERT(m_heap.operationInProgress == NoOperation); + if (m_heap.operationInProgress != NoOperation) + CRASH(); + m_heap.operationInProgress = Collection; - for (size_t block = 0; block < heap.usedBlocks; block++) { - Block* curBlock = reinterpret_cast<Block*>(heap.blocks[block]); - - size_t usedCells = curBlock->usedCells; - Cell* freeList = curBlock->freeList; - - if (usedCells == HeapConstants<heapType>::cellsPerBlock) { - // special case with a block where all cells are used -- testing indicates this happens often - for (size_t i = 0; i < HeapConstants<heapType>::cellsPerBlock; i++) { - if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) { - Cell* cell = curBlock->cells + i; - - if (heapType != NumberHeap) { - JSCell* imp = reinterpret_cast<JSCell*>(cell); - // special case for allocated but uninitialized object - // (We don't need this check earlier because nothing prior this point - // assumes the object has a valid vptr.) - if (cell->u.freeCell.zeroIfFree == 0) - continue; -#if ENABLE(JSC_ZOMBIES) - if (!imp->isZombie()) { - const ClassInfo* info = imp->classInfo(); - imp->~JSCell(); - new (imp) JSZombie(info, JSZombie::leakedZombieStructure()); - heap.numZombies++; - } -#else - imp->~JSCell(); -#endif - } - --numLiveObjects; #if !ENABLE(JSC_ZOMBIES) - --usedCells; - - // put cell on the free list - cell->u.freeCell.zeroIfFree = 0; - cell->u.freeCell.next = freeList - (cell + 1); - freeList = cell; + Structure* dummyMarkableCellStructure = m_globalData->dummyMarkableCellStructure.get(); #endif - } - } - } else { - size_t minimumCellsToProcess = usedCells; - for (size_t i = 0; (i < minimumCellsToProcess) & (i < HeapConstants<heapType>::cellsPerBlock); i++) { - Cell* cell = curBlock->cells + i; - if (cell->u.freeCell.zeroIfFree == 0) { - ++minimumCellsToProcess; - } else { - if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) { - if (heapType != NumberHeap) { - JSCell* imp = reinterpret_cast<JSCell*>(cell); + + DeadObjectIterator it(m_heap, m_heap.nextBlock, m_heap.nextCell); + DeadObjectIterator end(m_heap, m_heap.usedBlocks); + for ( ; it != end; ++it) { + JSCell* cell = *it; #if ENABLE(JSC_ZOMBIES) - if (!imp->isZombie()) { - const ClassInfo* info = imp->classInfo(); - imp->~JSCell(); - new (imp) JSZombie(info, JSZombie::leakedZombieStructure()); - heap.numZombies++; - } + if (!cell->isZombie()) { + const ClassInfo* info = cell->classInfo(); + cell->~JSCell(); + new (cell) JSZombie(info, JSZombie::leakedZombieStructure()); + Heap::markCell(cell); + } #else - imp->~JSCell(); + cell->~JSCell(); + // Callers of sweep assume it's safe to mark any cell in the heap. + new (cell) JSCell(dummyMarkableCellStructure); #endif - } -#if !ENABLE(JSC_ZOMBIES) - --usedCells; - --numLiveObjects; - - // put cell on the free list - cell->u.freeCell.zeroIfFree = 0; - cell->u.freeCell.next = freeList - (cell + 1); - freeList = cell; -#endif - } - } - } - } - - curBlock->usedCells = static_cast<uint32_t>(usedCells); - curBlock->freeList = freeList; - curBlock->marked.clearAll(); - - if (!usedCells) - ++emptyBlocks; } - - if (heap.numLiveObjects != numLiveObjects) - heap.firstBlockWithPossibleSpace = 0; - - heap.numLiveObjects = numLiveObjects; - heap.numLiveObjectsAtLastCollect = numLiveObjects; - heap.extraCost = 0; - - if (!emptyBlocks) - return numLiveObjects; - - size_t neededCells = 1.25f * (numLiveObjects + max(ALLOCATIONS_PER_COLLECTION, numLiveObjects)); - size_t neededBlocks = (neededCells + HeapConstants<heapType>::cellsPerBlock - 1) / HeapConstants<heapType>::cellsPerBlock; - for (size_t block = 0; block < heap.usedBlocks; block++) { - if (heap.usedBlocks <= neededBlocks) - break; - Block* curBlock = reinterpret_cast<Block*>(heap.blocks[block]); - if (curBlock->usedCells) - continue; - - freeBlock<heapType>(block); - block--; // Don't move forward a step in this case - } - - return numLiveObjects; + m_heap.operationInProgress = NoOperation; } -bool Heap::collect() +void Heap::markRoots() { #ifndef NDEBUG if (m_globalData->isSharedInstance) { @@ -1140,23 +1099,29 @@ bool Heap::collect() } #endif - ASSERT((primaryHeap.operationInProgress == NoOperation) | (numberHeap.operationInProgress == NoOperation)); - if ((primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation)) + ASSERT(m_heap.operationInProgress == NoOperation); + if (m_heap.operationInProgress != NoOperation) CRASH(); - JAVASCRIPTCORE_GC_BEGIN(); - primaryHeap.operationInProgress = Collection; - numberHeap.operationInProgress = Collection; + m_heap.operationInProgress = Collection; - // MARK: first mark all referenced objects recursively starting out from the set of root objects MarkStack& markStack = m_globalData->markStack; + + // Reset mark bits. + clearMarkBits(); + + // Mark stack roots. markStackObjectsConservatively(markStack); + m_globalData->interpreter->registerFile().markCallFrames(markStack, this); + + // Mark explicitly registered roots. markProtectedObjects(markStack); + + // Mark misc. other roots. if (m_markListSet && m_markListSet->size()) MarkedArgumentBuffer::markLists(markStack, *m_markListSet); if (m_globalData->exception) markStack.append(m_globalData->exception); - m_globalData->interpreter->registerFile().markCallFrames(markStack, this); m_globalData->smallStrings.markChildren(markStack); if (m_globalData->functionCodeBlockBeingReparsed) m_globalData->functionCodeBlockBeingReparsed->markAggregate(markStack); @@ -1165,41 +1130,28 @@ bool Heap::collect() markStack.drain(); markStack.compact(); - JAVASCRIPTCORE_GC_MARKED(); - - size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects; - size_t numLiveObjects = sweep<PrimaryHeap>(); - numLiveObjects += sweep<NumberHeap>(); - primaryHeap.operationInProgress = NoOperation; - numberHeap.operationInProgress = NoOperation; - JAVASCRIPTCORE_GC_END(originalLiveObjects, numLiveObjects); - - return numLiveObjects < originalLiveObjects; + m_heap.operationInProgress = NoOperation; } -size_t Heap::objectCount() +size_t Heap::objectCount() const { - return primaryHeap.numLiveObjects + numberHeap.numLiveObjects - m_globalData->smallStrings.count(); + return m_heap.nextBlock * HeapConstants::cellsPerBlock // allocated full blocks + + m_heap.nextCell // allocated cells in current block + + markedCells(m_heap.nextBlock, m_heap.nextCell) // marked cells in remainder of m_heap + - m_heap.usedBlocks; // 1 cell per block is a dummy sentinel } -template <HeapType heapType> -static void addToStatistics(Heap::Statistics& statistics, const CollectorHeap& heap) +void Heap::addToStatistics(Heap::Statistics& statistics) const { - typedef HeapConstants<heapType> HC; - for (size_t i = 0; i < heap.usedBlocks; ++i) { - if (heap.blocks[i]) { - statistics.size += BLOCK_SIZE; - statistics.free += (HC::cellsPerBlock - heap.blocks[i]->usedCells) * HC::cellSize; - } - } + statistics.size += m_heap.usedBlocks * BLOCK_SIZE; + statistics.free += m_heap.usedBlocks * BLOCK_SIZE - (objectCount() * HeapConstants::cellSize); } Heap::Statistics Heap::statistics() const { Statistics statistics = { 0, 0 }; - JSC::addToStatistics<PrimaryHeap>(statistics, primaryHeap); - JSC::addToStatistics<NumberHeap>(statistics, numberHeap); + addToStatistics(statistics); return statistics; } @@ -1268,17 +1220,61 @@ HashCountedSet<const char*>* Heap::protectedObjectTypeCounts() bool Heap::isBusy() { - return (primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation); + return m_heap.operationInProgress != NoOperation; +} + +void Heap::reset() +{ + JAVASCRIPTCORE_GC_BEGIN(); + + markRoots(); + + JAVASCRIPTCORE_GC_MARKED(); + + m_heap.nextCell = 0; + m_heap.nextBlock = 0; + m_heap.nextNumber = 0; + m_heap.extraCost = 0; +#if ENABLE(JSC_ZOMBIES) + sweep(); +#endif + resizeBlocks(); + + JAVASCRIPTCORE_GC_END(); +} + +void Heap::collectAllGarbage() +{ + JAVASCRIPTCORE_GC_BEGIN(); + + // If the last iteration through the heap deallocated blocks, we need + // to clean up remaining garbage before marking. Otherwise, the conservative + // marking mechanism might follow a pointer to unmapped memory. + if (m_heap.didShrink) + sweep(); + + markRoots(); + + JAVASCRIPTCORE_GC_MARKED(); + + m_heap.nextCell = 0; + m_heap.nextBlock = 0; + m_heap.nextNumber = 0; + m_heap.extraCost = 0; + sweep(); + resizeBlocks(); + + JAVASCRIPTCORE_GC_END(); } -Heap::iterator Heap::primaryHeapBegin() +LiveObjectIterator Heap::primaryHeapBegin() { - return iterator(primaryHeap.blocks, primaryHeap.blocks + primaryHeap.usedBlocks); + return LiveObjectIterator(m_heap, 0); } -Heap::iterator Heap::primaryHeapEnd() +LiveObjectIterator Heap::primaryHeapEnd() { - return iterator(primaryHeap.blocks + primaryHeap.usedBlocks, primaryHeap.blocks + primaryHeap.usedBlocks); + return LiveObjectIterator(m_heap, m_heap.usedBlocks); } } // namespace JSC diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h index 9128701..7f7a679 100644 --- a/JavaScriptCore/runtime/Collector.h +++ b/JavaScriptCore/runtime/Collector.h @@ -28,9 +28,9 @@ #include <wtf/HashSet.h> #include <wtf/Noncopyable.h> #include <wtf/OwnPtr.h> +#include <wtf/StdLibExtras.h> #include <wtf/Threading.h> -// This is supremely lame that we require pthreads to build on windows. #if ENABLE(JSC_MULTIPLE_THREADS) #include <pthread.h> #endif @@ -47,22 +47,21 @@ namespace JSC { class MarkStack; enum OperationInProgress { NoOperation, Allocation, Collection }; - enum HeapType { PrimaryHeap, NumberHeap }; - template <HeapType> class CollectorHeapIterator; + class LiveObjectIterator; struct CollectorHeap { + size_t nextBlock; + size_t nextCell; CollectorBlock** blocks; + + void* nextNumber; + size_t numBlocks; size_t usedBlocks; - size_t firstBlockWithPossibleSpace; - size_t numLiveObjects; - size_t numLiveObjectsAtLastCollect; size_t extraCost; -#if ENABLE(JSC_ZOMBIES) - size_t numZombies; -#endif + bool didShrink; OperationInProgress operationInProgress; }; @@ -70,21 +69,21 @@ namespace JSC { class Heap : public Noncopyable { public: class Thread; - typedef CollectorHeapIterator<PrimaryHeap> iterator; void destroy(); void* allocateNumber(size_t); void* allocate(size_t); - bool collect(); bool isBusy(); // true if an allocation or collection is in progress + void collectAllGarbage(); - static const size_t minExtraCostSize = 256; + static const size_t minExtraCost = 256; + static const size_t maxExtraCost = 1024 * 1024; void reportExtraMemoryCost(size_t cost); - size_t objectCount(); + size_t objectCount() const; struct Statistics { size_t size; size_t free; @@ -114,13 +113,12 @@ namespace JSC { JSGlobalData* globalData() const { return m_globalData; } static bool isNumber(JSCell*); - // Iterators for the object heap. - iterator primaryHeapBegin(); - iterator primaryHeapEnd(); + LiveObjectIterator primaryHeapBegin(); + LiveObjectIterator primaryHeapEnd(); private: - template <HeapType heapType> void* heapAllocate(size_t); - template <HeapType heapType> size_t sweep(); + void reset(); + void sweep(); static CollectorBlock* cellBlock(const JSCell*); static size_t cellOffset(const JSCell*); @@ -128,12 +126,22 @@ namespace JSC { Heap(JSGlobalData*); ~Heap(); - template <HeapType heapType> NEVER_INLINE CollectorBlock* allocateBlock(); - template <HeapType heapType> NEVER_INLINE void freeBlock(size_t); - NEVER_INLINE void freeBlock(CollectorBlock*); - void freeBlocks(CollectorHeap*); + NEVER_INLINE CollectorBlock* allocateBlock(); + NEVER_INLINE void freeBlock(size_t); + NEVER_INLINE void freeBlockPtr(CollectorBlock*); + void freeBlocks(); + void resizeBlocks(); + void growBlocks(size_t neededBlocks); + void shrinkBlocks(size_t neededBlocks); + void clearMarkBits(); + void clearMarkBits(CollectorBlock*); + size_t markedCells(size_t startBlock = 0, size_t startCell = 0) const; void recordExtraCost(size_t); + + void addToStatistics(Statistics&) const; + + void markRoots(); void markProtectedObjects(MarkStack&); void markCurrentThreadConservatively(MarkStack&); void markCurrentThreadConservativelyInternal(MarkStack&); @@ -142,8 +150,7 @@ namespace JSC { typedef HashCountedSet<JSCell*> ProtectCountSet; - CollectorHeap primaryHeap; - CollectorHeap numberHeap; + CollectorHeap m_heap; ProtectCountSet m_protectedValues; @@ -174,7 +181,7 @@ namespace JSC { #endif template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; }; -#if PLATFORM(WINCE) || PLATFORM(SYMBIAN) +#if OS(WINCE) || OS(SYMBIAN) const size_t BLOCK_SIZE = 64 * 1024; // 64k #else const size_t BLOCK_SIZE = 64 * 4096; // 256k @@ -189,87 +196,60 @@ namespace JSC { const size_t SMALL_CELL_SIZE = CELL_SIZE / 2; const size_t CELL_MASK = CELL_SIZE - 1; const size_t CELL_ALIGN_MASK = ~CELL_MASK; - const size_t CELLS_PER_BLOCK = (BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof(void *) * 8 - 2 * (7 + 3 * 8)) / (CELL_SIZE * 8 + 2); - const size_t SMALL_CELLS_PER_BLOCK = 2 * CELLS_PER_BLOCK; + const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*)) * 8 * CELL_SIZE / (8 * CELL_SIZE + 1) / CELL_SIZE; // one bitmap byte can represent 8 cells. + const size_t BITMAP_SIZE = (CELLS_PER_BLOCK + 7) / 8; const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t); - + struct CollectorBitmap { uint32_t bits[BITMAP_WORDS]; bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); } void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); } void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); } void clearAll() { memset(bits, 0, sizeof(bits)); } + size_t count(size_t startCell = 0) + { + size_t result = 0; + for ( ; (startCell & 0x1F) != 0; ++startCell) { + if (get(startCell)) + ++result; + } + for (size_t i = startCell >> 5; i < BITMAP_WORDS; ++i) + result += WTF::bitCount(bits[i]); + return result; + } + size_t isEmpty() // Much more efficient than testing count() == 0. + { + for (size_t i = 0; i < BITMAP_WORDS; ++i) + if (bits[i] != 0) + return false; + return true; + } }; struct CollectorCell { - union { - double memory[CELL_ARRAY_LENGTH]; - struct { - void* zeroIfFree; - ptrdiff_t next; - } freeCell; - } u; - }; - - struct SmallCollectorCell { - union { - double memory[CELL_ARRAY_LENGTH / 2]; - struct { - void* zeroIfFree; - ptrdiff_t next; - } freeCell; - } u; + double memory[CELL_ARRAY_LENGTH]; }; class CollectorBlock { public: CollectorCell cells[CELLS_PER_BLOCK]; - uint32_t usedCells; - CollectorCell* freeList; - CollectorBitmap marked; - Heap* heap; - HeapType type; - }; - - class SmallCellCollectorBlock { - public: - SmallCollectorCell cells[SMALL_CELLS_PER_BLOCK]; - uint32_t usedCells; - SmallCollectorCell* freeList; CollectorBitmap marked; Heap* heap; - HeapType type; }; - - template <HeapType heapType> struct HeapConstants; - template <> struct HeapConstants<PrimaryHeap> { + struct HeapConstants { static const size_t cellSize = CELL_SIZE; static const size_t cellsPerBlock = CELLS_PER_BLOCK; - static const size_t bitmapShift = 0; typedef CollectorCell Cell; typedef CollectorBlock Block; }; - template <> struct HeapConstants<NumberHeap> { - static const size_t cellSize = SMALL_CELL_SIZE; - static const size_t cellsPerBlock = SMALL_CELLS_PER_BLOCK; - static const size_t bitmapShift = 1; - typedef SmallCollectorCell Cell; - typedef SmallCellCollectorBlock Block; - }; - inline CollectorBlock* Heap::cellBlock(const JSCell* cell) { return reinterpret_cast<CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK); } - inline bool Heap::isNumber(JSCell* cell) - { - return Heap::cellBlock(cell)->type == NumberHeap; - } - inline size_t Heap::cellOffset(const JSCell* cell) { return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE; @@ -287,8 +267,20 @@ namespace JSC { inline void Heap::reportExtraMemoryCost(size_t cost) { - if (cost > minExtraCostSize) - recordExtraCost(cost / (CELL_SIZE * 2)); + if (cost > minExtraCost) + recordExtraCost(cost); + } + + inline void* Heap::allocateNumber(size_t s) + { + if (void* result = m_heap.nextNumber) { + m_heap.nextNumber = 0; + return result; + } + + void* result = allocate(s); + m_heap.nextNumber = static_cast<char*>(result) + (CELL_SIZE / 2); + return result; } } // namespace JSC diff --git a/JavaScriptCore/runtime/CollectorHeapIterator.h b/JavaScriptCore/runtime/CollectorHeapIterator.h index e38a852..e4f2f91 100644 --- a/JavaScriptCore/runtime/CollectorHeapIterator.h +++ b/JavaScriptCore/runtime/CollectorHeapIterator.h @@ -31,58 +31,108 @@ namespace JSC { - template <HeapType heapType> class CollectorHeapIterator { + class CollectorHeapIterator { public: - CollectorHeapIterator(CollectorBlock** block, CollectorBlock** endBlock); - - bool operator!=(const CollectorHeapIterator<heapType>& other) { return m_block != other.m_block || m_cell != other.m_cell; } - CollectorHeapIterator<heapType>& operator++(); + bool operator!=(const CollectorHeapIterator& other); JSCell* operator*() const; - private: - typedef typename HeapConstants<heapType>::Block Block; - typedef typename HeapConstants<heapType>::Cell Cell; - - Block** m_block; - Block** m_endBlock; - Cell* m_cell; - Cell* m_endCell; + protected: + CollectorHeapIterator(CollectorHeap&, size_t startBlock, size_t startCell); + void advance(size_t cellsPerBlock); + + CollectorHeap& m_heap; + size_t m_block; + size_t m_cell; + }; + + class LiveObjectIterator : public CollectorHeapIterator { + public: + LiveObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0); + LiveObjectIterator& operator++(); + }; + + class DeadObjectIterator : public CollectorHeapIterator { + public: + DeadObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0); + DeadObjectIterator& operator++(); + }; + + class ObjectIterator : public CollectorHeapIterator { + public: + ObjectIterator(CollectorHeap&, size_t startBlock, size_t startCell = 0); + ObjectIterator& operator++(); }; - template <HeapType heapType> - CollectorHeapIterator<heapType>::CollectorHeapIterator(CollectorBlock** block, CollectorBlock** endBlock) - : m_block(reinterpret_cast<Block**>(block)) - , m_endBlock(reinterpret_cast<Block**>(endBlock)) - , m_cell(m_block == m_endBlock ? 0 : (*m_block)->cells) - , m_endCell(m_block == m_endBlock ? 0 : (*m_block)->cells + HeapConstants<heapType>::cellsPerBlock) + inline CollectorHeapIterator::CollectorHeapIterator(CollectorHeap& heap, size_t startBlock, size_t startCell) + : m_heap(heap) + , m_block(startBlock) + , m_cell(startCell) + { + } + + inline bool CollectorHeapIterator::operator!=(const CollectorHeapIterator& other) + { + return m_block != other.m_block || m_cell != other.m_cell; + } + + inline JSCell* CollectorHeapIterator::operator*() const + { + return reinterpret_cast<JSCell*>(m_heap.blocks[m_block]->cells + m_cell); + } + + inline void CollectorHeapIterator::advance(size_t cellsPerBlock) + { + ++m_cell; + if (m_cell == cellsPerBlock) { + m_cell = 0; + ++m_block; + } + } + + inline LiveObjectIterator::LiveObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell) + : CollectorHeapIterator(heap, startBlock, startCell - 1) + { + ++(*this); + } + + inline LiveObjectIterator& LiveObjectIterator::operator++() + { + if (m_block < m_heap.nextBlock || m_cell < m_heap.nextCell) { + advance(HeapConstants::cellsPerBlock); + return *this; + } + + do { + advance(HeapConstants::cellsPerBlock); + } while (m_block < m_heap.usedBlocks && !m_heap.blocks[m_block]->marked.get(m_cell)); + return *this; + } + + inline DeadObjectIterator::DeadObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell) + : CollectorHeapIterator(heap, startBlock, startCell - 1) { - if (m_cell && m_cell->u.freeCell.zeroIfFree == 0) - ++*this; + ++(*this); } - template <HeapType heapType> - CollectorHeapIterator<heapType>& CollectorHeapIterator<heapType>::operator++() + inline DeadObjectIterator& DeadObjectIterator::operator++() { do { - for (++m_cell; m_cell != m_endCell; ++m_cell) - if (m_cell->u.freeCell.zeroIfFree != 0) { - return *this; - } - - if (++m_block != m_endBlock) { - m_cell = (*m_block)->cells; - m_endCell = (*m_block)->cells + HeapConstants<heapType>::cellsPerBlock; - } - } while(m_block != m_endBlock); - - m_cell = 0; + advance(HeapConstants::cellsPerBlock); + ASSERT(m_block > m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell >= m_heap.nextCell)); + } while (m_block < m_heap.usedBlocks && m_heap.blocks[m_block]->marked.get(m_cell)); return *this; } - template <HeapType heapType> - JSCell* CollectorHeapIterator<heapType>::operator*() const + inline ObjectIterator::ObjectIterator(CollectorHeap& heap, size_t startBlock, size_t startCell) + : CollectorHeapIterator(heap, startBlock, startCell - 1) { - return reinterpret_cast<JSCell*>(m_cell); + ++(*this); + } + + inline ObjectIterator& ObjectIterator::operator++() + { + advance(HeapConstants::cellsPerBlock); + return *this; } } // namespace JSC diff --git a/JavaScriptCore/runtime/CommonIdentifiers.h b/JavaScriptCore/runtime/CommonIdentifiers.h index abe5038..de24f4a 100644 --- a/JavaScriptCore/runtime/CommonIdentifiers.h +++ b/JavaScriptCore/runtime/CommonIdentifiers.h @@ -50,6 +50,7 @@ macro(get) \ macro(getPrototypeOf) \ macro(getOwnPropertyDescriptor) \ + macro(getOwnPropertyNames) \ macro(hasOwnProperty) \ macro(ignoreCase) \ macro(index) \ diff --git a/JavaScriptCore/runtime/Completion.cpp b/JavaScriptCore/runtime/Completion.cpp index 2507698..2f88df9 100644 --- a/JavaScriptCore/runtime/Completion.cpp +++ b/JavaScriptCore/runtime/Completion.cpp @@ -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()); diff --git a/JavaScriptCore/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp index 61ec4c5..2e476b3 100644 --- a/JavaScriptCore/runtime/DateConstructor.cpp +++ b/JavaScriptCore/runtime/DateConstructor.cpp @@ -35,7 +35,7 @@ #include <wtf/DateMath.h> #include <wtf/MathExtras.h> -#if PLATFORM(WINCE) && !PLATFORM(QT) +#if OS(WINCE) && !PLATFORM(QT) extern "C" time_t time(time_t* timer); // Provided by libce. #endif @@ -133,7 +133,11 @@ static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const tm localTM; getLocalTime(&localTime, &localTM); GregorianDateTime ts(exec, localTM); - return jsNontrivialString(exec, formatDate(ts) + " " + formatTime(ts)); + DateConversionBuffer date; + DateConversionBuffer time; + formatDate(ts, date); + formatTime(ts, time); + return jsNontrivialString(exec, makeString(date, " ", time)); } CallType DateConstructor::getCallData(CallData& callData) diff --git a/JavaScriptCore/runtime/DateConversion.cpp b/JavaScriptCore/runtime/DateConversion.cpp index b9d0e02..f129407 100644 --- a/JavaScriptCore/runtime/DateConversion.cpp +++ b/JavaScriptCore/runtime/DateConversion.cpp @@ -62,49 +62,41 @@ double parseDate(ExecState* exec, const UString &date) return value; } -UString formatDate(const GregorianDateTime &t) +void formatDate(const GregorianDateTime &t, DateConversionBuffer& buffer) { - char buffer[100]; - snprintf(buffer, sizeof(buffer), "%s %s %02d %04d", + snprintf(buffer, DateConversionBufferSize, "%s %s %02d %04d", weekdayName[(t.weekDay + 6) % 7], monthName[t.month], t.monthDay, t.year + 1900); - return buffer; } -UString formatDateUTCVariant(const GregorianDateTime &t) +void formatDateUTCVariant(const GregorianDateTime &t, DateConversionBuffer& buffer) { - char buffer[100]; - snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d", + snprintf(buffer, DateConversionBufferSize, "%s, %02d %s %04d", weekdayName[(t.weekDay + 6) % 7], t.monthDay, monthName[t.month], t.year + 1900); - return buffer; } -UString formatTime(const GregorianDateTime &t) +void formatTime(const GregorianDateTime &t, DateConversionBuffer& buffer) { - char buffer[100]; int offset = abs(gmtoffset(t)); char timeZoneName[70]; struct tm gtm = t; strftime(timeZoneName, sizeof(timeZoneName), "%Z", >m); if (timeZoneName[0]) { - snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)", + snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d (%s)", t.hour, t.minute, t.second, gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName); } else { - snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d", + snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d", t.hour, t.minute, t.second, gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60); } - return UString(buffer); } -UString formatTimeUTC(const GregorianDateTime &t) +void formatTimeUTC(const GregorianDateTime &t, DateConversionBuffer& buffer) { - char buffer[100]; - snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second); - return UString(buffer); + snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT", t.hour, t.minute, t.second); } } // namespace JSC diff --git a/JavaScriptCore/runtime/DateConversion.h b/JavaScriptCore/runtime/DateConversion.h index dc980d3..ff32b50 100644 --- a/JavaScriptCore/runtime/DateConversion.h +++ b/JavaScriptCore/runtime/DateConversion.h @@ -42,17 +42,21 @@ #ifndef DateConversion_h #define DateConversion_h +#include "UString.h" + namespace JSC { class ExecState; -class UString; struct GregorianDateTime; +static const unsigned DateConversionBufferSize = 100; +typedef char DateConversionBuffer[DateConversionBufferSize]; + double parseDate(ExecState* exec, const UString&); -UString formatDate(const GregorianDateTime&); -UString formatDateUTCVariant(const GregorianDateTime&); -UString formatTime(const GregorianDateTime&); -UString formatTimeUTC(const GregorianDateTime&); +void formatDate(const GregorianDateTime&, DateConversionBuffer&); +void formatDateUTCVariant(const GregorianDateTime&, DateConversionBuffer&); +void formatTime(const GregorianDateTime&, DateConversionBuffer&); +void formatTimeUTC(const GregorianDateTime&, DateConversionBuffer&); } // namespace JSC diff --git a/JavaScriptCore/runtime/DateInstance.cpp b/JavaScriptCore/runtime/DateInstance.cpp index 77a92be..b43b183 100644 --- a/JavaScriptCore/runtime/DateInstance.cpp +++ b/JavaScriptCore/runtime/DateInstance.cpp @@ -40,6 +40,12 @@ DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structu setInternalValue(jsNaN(exec)); } +DateInstance::DateInstance(ExecState* exec, NonNullPassRefPtr<Structure> structure, double time) + : JSWrapperObject(structure) +{ + setInternalValue(jsNumber(exec, timeClip(time))); +} + DateInstance::DateInstance(ExecState* exec, double time) : JSWrapperObject(exec->lexicalGlobalObject()->dateStructure()) { diff --git a/JavaScriptCore/runtime/DateInstance.h b/JavaScriptCore/runtime/DateInstance.h index 44b7521..77d46de 100644 --- a/JavaScriptCore/runtime/DateInstance.h +++ b/JavaScriptCore/runtime/DateInstance.h @@ -32,6 +32,7 @@ namespace JSC { class DateInstance : public JSWrapperObject { public: DateInstance(ExecState*, double); + DateInstance(ExecState*, NonNullPassRefPtr<Structure>, double); explicit DateInstance(ExecState*, NonNullPassRefPtr<Structure>); double internalNumber() const { return internalValue().uncheckedGetNumber(); } @@ -54,7 +55,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp index 7a2e802..ca9d4ea 100644 --- a/JavaScriptCore/runtime/DatePrototype.cpp +++ b/JavaScriptCore/runtime/DatePrototype.cpp @@ -59,7 +59,7 @@ #include <CoreFoundation/CoreFoundation.h> #endif -#if PLATFORM(WINCE) && !PLATFORM(QT) +#if OS(WINCE) && !PLATFORM(QT) extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); //provided by libce #endif @@ -197,7 +197,7 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L { #if HAVE(LANGINFO_H) static const nl_item formats[] = { D_T_FMT, D_FMT, T_FMT }; -#elif (PLATFORM(WINCE) && !PLATFORM(QT)) || PLATFORM(SYMBIAN) +#elif (OS(WINCE) && !PLATFORM(QT)) || OS(SYMBIAN) // strftime() does not support '#' on WinCE or Symbian static const char* const formatStrings[] = { "%c", "%x", "%X" }; #else @@ -423,7 +423,11 @@ JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); if (!gregorianDateTime) return jsNontrivialString(exec, "Invalid Date"); - return jsNontrivialString(exec, formatDate(*gregorianDateTime) + " " + formatTime(*gregorianDateTime)); + DateConversionBuffer date; + DateConversionBuffer time; + formatDate(*gregorianDateTime, date); + formatTime(*gregorianDateTime, time); + return jsNontrivialString(exec, makeString(date, " ", time)); } JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -436,7 +440,11 @@ JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSVal const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); if (!gregorianDateTime) return jsNontrivialString(exec, "Invalid Date"); - return jsNontrivialString(exec, formatDateUTCVariant(*gregorianDateTime) + " " + formatTimeUTC(*gregorianDateTime)); + DateConversionBuffer date; + DateConversionBuffer time; + formatDateUTCVariant(*gregorianDateTime, date); + formatTimeUTC(*gregorianDateTime, time); + return jsNontrivialString(exec, makeString(date, " ", time)); } JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -467,7 +475,9 @@ JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSVa const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); if (!gregorianDateTime) return jsNontrivialString(exec, "Invalid Date"); - return jsNontrivialString(exec, formatDate(*gregorianDateTime)); + DateConversionBuffer date; + formatDate(*gregorianDateTime, date); + return jsNontrivialString(exec, date); } JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -480,7 +490,9 @@ JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSVa const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec); if (!gregorianDateTime) return jsNontrivialString(exec, "Invalid Date"); - return jsNontrivialString(exec, formatTime(*gregorianDateTime)); + DateConversionBuffer time; + formatTime(*gregorianDateTime, time); + return jsNontrivialString(exec, time); } JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -554,7 +566,11 @@ JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSVal const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); if (!gregorianDateTime) return jsNontrivialString(exec, "Invalid Date"); - return jsNontrivialString(exec, formatDateUTCVariant(*gregorianDateTime) + " " + formatTimeUTC(*gregorianDateTime)); + DateConversionBuffer date; + DateConversionBuffer time; + formatDateUTCVariant(*gregorianDateTime, date); + formatTimeUTC(*gregorianDateTime, time); + return jsNontrivialString(exec, makeString(date, " ", time)); } JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) diff --git a/JavaScriptCore/runtime/DatePrototype.h b/JavaScriptCore/runtime/DatePrototype.h index f565775..612ca06 100644 --- a/JavaScriptCore/runtime/DatePrototype.h +++ b/JavaScriptCore/runtime/DatePrototype.h @@ -39,7 +39,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/runtime/ErrorPrototype.cpp b/JavaScriptCore/runtime/ErrorPrototype.cpp index a9a7a43..be9e4b8 100644 --- a/JavaScriptCore/runtime/ErrorPrototype.cpp +++ b/JavaScriptCore/runtime/ErrorPrototype.cpp @@ -48,21 +48,19 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, NonNullPassRefPtr<Structure> str JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { JSObject* thisObj = thisValue.toThisObject(exec); + JSValue name = thisObj->get(exec, exec->propertyNames().name); + JSValue message = thisObj->get(exec, exec->propertyNames().message); - UString s = "Error"; + // Mozilla-compatible format. - JSValue v = thisObj->get(exec, exec->propertyNames().name); - if (!v.isUndefined()) - s = v.toString(exec); - - v = thisObj->get(exec, exec->propertyNames().message); - if (!v.isUndefined()) { - // Mozilla-compatible format. - s += ": "; - s += v.toString(exec); + if (!name.isUndefined()) { + if (!message.isUndefined()) + return jsNontrivialString(exec, makeString(name.toString(exec), ": ", message.toString(exec))); + return jsNontrivialString(exec, name.toString(exec)); } - - return jsNontrivialString(exec, s); + if (!message.isUndefined()) + return jsNontrivialString(exec, makeString("Error: ", message.toString(exec))); + return jsNontrivialString(exec, "Error"); } } // namespace JSC diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp index 5bead90..9bb740e 100644 --- a/JavaScriptCore/runtime/ExceptionHelpers.cpp +++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp @@ -77,9 +77,7 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u int endOffset = 0; int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); - UString message = "Can't find variable: "; - message.append(ident.ustring()); - JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); + JSObject* exception = Error::create(exec, ReferenceError, makeString("Can't find variable: ", ident.ustring()), line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete); @@ -88,59 +86,36 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValue value, UString error) { - if (!expressionStop || expressionStart > codeBlock->source()->length()) { - UString errorText = value.toString(exec); - errorText.append(" is "); - errorText.append(error); - return errorText; - } + if (!expressionStop || expressionStart > codeBlock->source()->length()) + return makeString(value.toString(exec), " is ", error); + if (expressionStart < expressionStop) + return makeString("Result of expression '", codeBlock->source()->getRange(expressionStart, expressionStop), "' [", value.toString(exec), "] is ", error, "."); - UString errorText = "Result of expression "; - - if (expressionStart < expressionStop) { - errorText.append('\''); - errorText.append(codeBlock->source()->getRange(expressionStart, expressionStop)); - errorText.append("' ["); - errorText.append(value.toString(exec)); - errorText.append("] is "); - } else { - // No range information, so give a few characters of context - const UChar* data = codeBlock->source()->data(); - int dataLength = codeBlock->source()->length(); - int start = expressionStart; - int stop = expressionStart; - // Get up to 20 characters of context to the left and right of the divot, clamping to the line. - // then strip whitespace. - while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n') - start--; - while (start < (expressionStart - 1) && isStrWhiteSpace(data[start])) - start++; - while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n') - stop++; - while (stop > expressionStart && isStrWhiteSpace(data[stop])) - stop--; - errorText.append("near '..."); - errorText.append(codeBlock->source()->getRange(start, stop)); - errorText.append("...' ["); - errorText.append(value.toString(exec)); - errorText.append("] is "); - } - errorText.append(error); - errorText.append("."); - return errorText; + // No range information, so give a few characters of context + const UChar* data = codeBlock->source()->data(); + int dataLength = codeBlock->source()->length(); + int start = expressionStart; + int stop = expressionStart; + // Get up to 20 characters of context to the left and right of the divot, clamping to the line. + // then strip whitespace. + while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n') + start--; + while (start < (expressionStart - 1) && isStrWhiteSpace(data[start])) + start++; + while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n') + stop++; + while (stop > expressionStart && isStrWhiteSpace(data[stop])) + stop--; + return makeString("Result of expression near '...", codeBlock->source()->getRange(start, stop), "...' [", value.toString(exec), "] is ", error, "."); } JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock) { - UString message = "not a valid argument for '"; - message.append(op); - message.append("'"); - int startOffset = 0; int endOffset = 0; int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); - UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, message); + UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, makeString("not a valid argument for '", op, "'")); JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL()); exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete); exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete); diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp index 7586746..bc18cc9 100644 --- a/JavaScriptCore/runtime/Executable.cpp +++ b/JavaScriptCore/runtime/Executable.cpp @@ -30,6 +30,7 @@ #include "CodeBlock.h" #include "JIT.h" #include "Parser.h" +#include "StringBuilder.h" #include "Vector.h" namespace JSC { @@ -265,14 +266,13 @@ PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifi UString FunctionExecutable::paramString() const { FunctionParameters& parameters = *m_parameters; - UString s(""); + StringBuilder builder; for (size_t pos = 0; pos < parameters.size(); ++pos) { - if (!s.isEmpty()) - s += ", "; - s += parameters[pos].ustring(); + if (!builder.isEmpty()) + builder.append(", "); + builder.append(parameters[pos].ustring()); } - - return s; + return builder.release(); } }; diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp index 9d88400..9d55dd1 100644 --- a/JavaScriptCore/runtime/FunctionConstructor.cpp +++ b/JavaScriptCore/runtime/FunctionConstructor.cpp @@ -21,14 +21,15 @@ #include "config.h" #include "FunctionConstructor.h" +#include "Debugger.h" #include "FunctionPrototype.h" #include "JSFunction.h" #include "JSGlobalObject.h" #include "JSString.h" -#include "Parser.h" -#include "Debugger.h" #include "Lexer.h" #include "Nodes.h" +#include "Parser.h" +#include "StringBuilder.h" namespace JSC { @@ -76,12 +77,19 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi if (args.isEmpty()) program = "(function() { \n})"; else if (args.size() == 1) - program = "(function() { " + args.at(0).toString(exec) + "\n})"; + program = makeString("(function() { ", args.at(0).toString(exec), "\n})"); else { - program = "(function(" + args.at(0).toString(exec); - for (size_t i = 1; i < args.size() - 1; i++) - program += "," + args.at(i).toString(exec); - program += ") { " + args.at(args.size() - 1).toString(exec) + "\n})"; + StringBuilder builder; + builder.append("(function("); + builder.append(args.at(0).toString(exec)); + for (size_t i = 1; i < args.size() - 1; i++) { + builder.append(","); + builder.append(args.at(i).toString(exec)); + } + builder.append(") { "); + builder.append(args.at(args.size() - 1).toString(exec)); + builder.append("\n})"); + program = builder.release(); } int errLine; diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp index a3a7479..f08bd5e 100644 --- a/JavaScriptCore/runtime/FunctionPrototype.cpp +++ b/JavaScriptCore/runtime/FunctionPrototype.cpp @@ -76,7 +76,7 @@ static inline void insertSemicolonIfNeeded(UString& functionBody) UChar ch = functionBody[i]; if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) { if (ch != ';' && ch != '}') - functionBody = functionBody.substr(0, i + 1) + ";" + functionBody.substr(i + 1, functionBody.size() - (i + 1)); + functionBody = makeString(functionBody.substr(0, i + 1), ";", functionBody.substr(i + 1, functionBody.size() - (i + 1))); return; } } @@ -90,13 +90,13 @@ JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSVa FunctionExecutable* executable = function->jsExecutable(); UString sourceString = executable->source().toString(); insertSemicolonIfNeeded(sourceString); - return jsString(exec, "function " + function->name(exec) + "(" + executable->paramString() + ") " + sourceString); + return jsString(exec, makeString("function ", function->name(exec), "(", executable->paramString(), ") ", sourceString)); } } if (thisValue.inherits(&InternalFunction::info)) { InternalFunction* function = asInternalFunction(thisValue); - return jsString(exec, "function " + function->name(exec) + "() {\n [native code]\n}"); + return jsString(exec, makeString("function ", function->name(exec), "() {\n [native code]\n}")); } return throwError(exec, TypeError); diff --git a/JavaScriptCore/runtime/FunctionPrototype.h b/JavaScriptCore/runtime/FunctionPrototype.h index d1d6a1d..af783f7 100644 --- a/JavaScriptCore/runtime/FunctionPrototype.h +++ b/JavaScriptCore/runtime/FunctionPrototype.h @@ -34,7 +34,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } private: diff --git a/JavaScriptCore/runtime/GetterSetter.h b/JavaScriptCore/runtime/GetterSetter.h index 68e9ea3..4e47361 100644 --- a/JavaScriptCore/runtime/GetterSetter.h +++ b/JavaScriptCore/runtime/GetterSetter.h @@ -50,7 +50,7 @@ namespace JSC { void setSetter(JSObject* setter) { m_setter = setter; } static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(GetterSetterType, OverridesMarkChildren)); + return Structure::create(prototype, TypeInfo(GetterSetterType, OverridesMarkChildren), AnonymousSlotCount); } private: virtual bool isGetterSetter() const; diff --git a/JavaScriptCore/runtime/GlobalEvalFunction.h b/JavaScriptCore/runtime/GlobalEvalFunction.h index 389b1c3..a14ce4d 100644 --- a/JavaScriptCore/runtime/GlobalEvalFunction.h +++ b/JavaScriptCore/runtime/GlobalEvalFunction.h @@ -37,7 +37,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/runtime/Identifier.cpp b/JavaScriptCore/runtime/Identifier.cpp index 7db723b..747c4ac 100644 --- a/JavaScriptCore/runtime/Identifier.cpp +++ b/JavaScriptCore/runtime/Identifier.cpp @@ -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; } @@ -77,7 +79,7 @@ void deleteIdentifierTable(IdentifierTable* table) bool Identifier::equal(const UString::Rep* r, const char* s) { - int length = r->len; + int length = r->size(); const UChar* d = r->data(); for (int i = 0; i != length; ++i) if (d[i] != (unsigned char)s[i]) @@ -87,7 +89,7 @@ bool Identifier::equal(const UString::Rep* r, const char* s) bool Identifier::equal(const UString::Rep* r, const UChar* s, int length) { - if (r->len != length) + if (r->size() != length) return false; const UChar* d = r->data(); for (int i = 0; i != length; ++i) @@ -110,13 +112,11 @@ struct CStringTranslator { static void translate(UString::Rep*& location, const char* c, unsigned hash) { size_t length = strlen(c); - UChar* d = static_cast<UChar*>(fastMalloc(sizeof(UChar) * length)); + UChar* d; + UString::Rep* r = UString::Rep::createUninitialized(length, d).releaseRef(); for (size_t i = 0; i != length; i++) d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend - - UString::Rep* r = UString::Rep::create(d, static_cast<int>(length)).releaseRef(); - r->_hash = hash; - + r->setHash(hash); location = r; } }; @@ -175,13 +175,11 @@ struct UCharBufferTranslator { static void translate(UString::Rep*& location, const UCharBuffer& buf, unsigned hash) { - UChar* d = static_cast<UChar*>(fastMalloc(sizeof(UChar) * buf.length)); + UChar* d; + UString::Rep* r = UString::Rep::createUninitialized(buf.length, d).releaseRef(); for (unsigned i = 0; i != buf.length; i++) d[i] = buf.s[i]; - - UString::Rep* r = UString::Rep::create(d, buf.length).releaseRef(); - r->_hash = hash; - + r->setHash(hash); location = r; } }; @@ -212,19 +210,19 @@ PassRefPtr<UString::Rep> Identifier::add(ExecState* exec, const UChar* s, int le PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UString::Rep* r) { - ASSERT(!r->identifierTable()); - if (r->len == 1) { + ASSERT(!r->isIdentifier()); + if (r->size() == 1) { UChar c = r->data()[0]; if (c <= 0xFF) r = globalData->smallStrings.singleCharacterStringRep(c); - if (r->identifierTable()) { + if (r->isIdentifier()) { #ifndef NDEBUG checkSameIdentifierTable(globalData, r); #endif return r; } } - if (!r->len) { + if (!r->size()) { UString::Rep::empty().hash(); return &UString::Rep::empty(); } @@ -238,19 +236,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_UNUSED(exec, 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_UNUSED(globalData, globalData->identifierTable == currentIdentifierTable()); } #else @@ -265,4 +263,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; +static void createIdentifierTableSpecificCallback() +{ + ASSERT(!g_identifierTableSpecific); + g_identifierTableSpecific = new ThreadSpecific<ThreadIdentifierTableData>(); +} +void createIdentifierTableSpecific() +{ + pthread_once(&createIdentifierTableSpecificOnce, createIdentifierTableSpecificCallback); + ASSERT(g_identifierTableSpecific); +} + +#else + +void createIdentifierTableSpecific() +{ + ASSERT(!g_identifierTableSpecific); + g_identifierTableSpecific = new ThreadSpecific<ThreadIdentifierTableData>(); +} + +#endif + } // namespace JSC diff --git a/JavaScriptCore/runtime/Identifier.h b/JavaScriptCore/runtime/Identifier.h index 2249179..1d1bd18 100644 --- a/JavaScriptCore/runtime/Identifier.h +++ b/JavaScriptCore/runtime/Identifier.h @@ -22,6 +22,7 @@ #define Identifier_h #include "JSGlobalData.h" +#include "ThreadSpecific.h" #include "UString.h" namespace JSC { @@ -92,7 +93,7 @@ namespace JSC { static PassRefPtr<UString::Rep> add(ExecState* exec, UString::Rep* r) { - if (r->identifierTable()) { + if (r->isIdentifier()) { #ifndef NDEBUG checkSameIdentifierTable(exec, r); #endif @@ -102,7 +103,7 @@ namespace JSC { } static PassRefPtr<UString::Rep> add(JSGlobalData* globalData, UString::Rep* r) { - if (r->identifierTable()) { + if (r->isIdentifier()) { #ifndef NDEBUG checkSameIdentifierTable(globalData, r); #endif @@ -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 diff --git a/JavaScriptCore/runtime/InitializeThreading.cpp b/JavaScriptCore/runtime/InitializeThreading.cpp index aad1af8..2605a9a 100644 --- a/JavaScriptCore/runtime/InitializeThreading.cpp +++ b/JavaScriptCore/runtime/InitializeThreading.cpp @@ -41,7 +41,7 @@ using namespace WTF; namespace JSC { -#if PLATFORM(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS) +#if OS(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS) static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT; #endif @@ -49,6 +49,7 @@ static void initializeThreadingOnce() { WTF::initializeThreading(); initializeUString(); + JSGlobalData::storeVPtrs(); #if ENABLE(JSC_MULTIPLE_THREADS) s_dtoaP5Mutex = new Mutex; initializeDates(); @@ -57,7 +58,7 @@ static void initializeThreadingOnce() void initializeThreading() { -#if PLATFORM(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS) +#if OS(DARWIN) && ENABLE(JSC_MULTIPLE_THREADS) pthread_once(&initializeThreadingKeyOnce, initializeThreadingOnce); #else static bool initializedThreading = false; diff --git a/JavaScriptCore/runtime/InternalFunction.h b/JavaScriptCore/runtime/InternalFunction.h index fa1e5aa..d19b82b 100644 --- a/JavaScriptCore/runtime/InternalFunction.h +++ b/JavaScriptCore/runtime/InternalFunction.h @@ -42,7 +42,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/runtime/JSAPIValueWrapper.h b/JavaScriptCore/runtime/JSAPIValueWrapper.h index aca550e..b5016c2 100644 --- a/JavaScriptCore/runtime/JSAPIValueWrapper.h +++ b/JavaScriptCore/runtime/JSAPIValueWrapper.h @@ -39,7 +39,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames)); + return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren | OverridesGetPropertyNames), AnonymousSlotCount); } diff --git a/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h index ee98191..761bee4 100644 --- a/JavaScriptCore/runtime/JSActivation.h +++ b/JavaScriptCore/runtime/JSActivation.h @@ -66,7 +66,7 @@ namespace JSC { virtual const ClassInfo* classInfo() const { return &info; } static const ClassInfo info; - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp index b16d3fa..2be7371 100644 --- a/JavaScriptCore/runtime/JSArray.cpp +++ b/JavaScriptCore/runtime/JSArray.cpp @@ -152,6 +152,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength) m_storage->m_numValuesInVector = 0; m_storage->m_sparseValueMap = 0; m_storage->lazyCreationData = 0; + m_storage->reportedMapCapacity = 0; JSValue* vector = m_storage->m_vector; for (size_t i = 0; i < initialCapacity; ++i) @@ -172,6 +173,8 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list) m_vectorLength = initialCapacity; m_storage->m_numValuesInVector = initialCapacity; m_storage->m_sparseValueMap = 0; + m_storage->lazyCreationData = 0; + m_storage->reportedMapCapacity = 0; size_t i = 0; ArgList::const_iterator end = list.end(); @@ -185,6 +188,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list) JSArray::~JSArray() { + ASSERT(vptr() == JSGlobalData::jsArrayVPtr); checkConsistency(DestructorConsistencyCheck); delete m_storage->m_sparseValueMap; @@ -328,13 +332,24 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu } // We miss some cases where we could compact the storage, such as a large array that is being filled from the end - // (which will only be compacted as we reach indices that are less than cutoff) - but this makes the check much faster. + // (which will only be compacted as we reach indices that are less than MIN_SPARSE_ARRAY_INDEX) - but this makes the check much faster. if ((i > MAX_STORAGE_VECTOR_INDEX) || !isDenseEnoughForVector(i + 1, storage->m_numValuesInVector + 1)) { if (!map) { map = new SparseArrayValueMap; storage->m_sparseValueMap = map; } - map->set(i, value); + + pair<SparseArrayValueMap::iterator, bool> result = map->add(i, value); + if (!result.second) { // pre-existing entry + result.first->second = value; + return; + } + + size_t capacity = map->capacity(); + if (capacity != storage->reportedMapCapacity) { + Heap::heap(this)->reportExtraMemoryCost((capacity - storage->reportedMapCapacity) * (sizeof(unsigned) + sizeof(JSValue))); + storage->reportedMapCapacity = capacity; + } return; } } @@ -380,8 +395,6 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu unsigned vectorLength = m_vectorLength; - Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); - if (newNumValuesInVector == storage->m_numValuesInVector + 1) { for (unsigned j = vectorLength; j < newVectorLength; ++j) storage->m_vector[j] = JSValue(); @@ -402,6 +415,8 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu m_storage = storage; checkConsistency(); + + Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); } bool JSArray::deleteProperty(ExecState* exec, const Identifier& propertyName) @@ -454,7 +469,7 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i) return false; } -void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { // FIXME: Filling PropertyNameArray with an identifier for every integer // is incredibly inefficient for large arrays. We need a different approach, @@ -474,7 +489,10 @@ void JSArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNa propertyNames.add(Identifier::from(exec, it->first)); } - JSObject::getOwnPropertyNames(exec, propertyNames); + if (mode == IncludeDontEnumProperties) + propertyNames.add(exec->propertyNames().length); + + JSObject::getOwnPropertyNames(exec, propertyNames, mode); } bool JSArray::increaseVectorLength(unsigned newLength) @@ -492,13 +510,15 @@ bool JSArray::increaseVectorLength(unsigned newLength) if (!tryFastRealloc(storage, storageSize(newVectorLength)).getValue(storage)) return false; - Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); m_vectorLength = newVectorLength; for (unsigned i = vectorLength; i < newVectorLength; ++i) storage->m_vector[i] = JSValue(); m_storage = storage; + + Heap::heap(this)->reportExtraMemoryCost(storageSize(newVectorLength) - storageSize(vectorLength)); + return true; } diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h index 8c22451..ad6ee88 100644 --- a/JavaScriptCore/runtime/JSArray.h +++ b/JavaScriptCore/runtime/JSArray.h @@ -32,6 +32,7 @@ namespace JSC { unsigned m_numValuesInVector; SparseArrayValueMap* m_sparseValueMap; void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily. + size_t reportedMapCapacity; JSValue m_vector[1]; }; @@ -87,7 +88,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } inline void markChildrenDirect(MarkStack& markStack); @@ -97,7 +98,7 @@ namespace JSC { virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName); virtual bool deleteProperty(ExecState*, unsigned propertyName); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); virtual void markChildren(MarkStack&); void* lazyCreationData(); diff --git a/JavaScriptCore/runtime/JSByteArray.cpp b/JavaScriptCore/runtime/JSByteArray.cpp index 5e5003b..803a08c 100644 --- a/JavaScriptCore/runtime/JSByteArray.cpp +++ b/JavaScriptCore/runtime/JSByteArray.cpp @@ -42,10 +42,18 @@ JSByteArray::JSByteArray(ExecState* exec, NonNullPassRefPtr<Structure> structure { putDirect(exec->globalData().propertyNames->length, jsNumber(exec, m_storage->length()), ReadOnly | DontDelete); } - + +#if !ASSERT_DISABLED +JSByteArray::~JSByteArray() +{ + ASSERT(vptr() == JSGlobalData::jsByteArrayVPtr); +} +#endif + + PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype) { - PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); return result; } @@ -96,12 +104,12 @@ void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValue value) setIndex(exec, propertyName, value); } -void JSByteArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSByteArray::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { unsigned length = m_storage->length(); for (unsigned i = 0; i < length; ++i) propertyNames.add(Identifier::from(exec, i)); - JSObject::getOwnPropertyNames(exec, propertyNames); + JSObject::getOwnPropertyNames(exec, propertyNames, mode); } } diff --git a/JavaScriptCore/runtime/JSByteArray.h b/JavaScriptCore/runtime/JSByteArray.h index fe6e124..5b7adcf 100644 --- a/JavaScriptCore/runtime/JSByteArray.h +++ b/JavaScriptCore/runtime/JSByteArray.h @@ -33,7 +33,7 @@ namespace JSC { class JSByteArray : public JSObject { - friend struct VPtrSet; + friend class JSGlobalData; public: bool canAccessIndex(unsigned i) { return i < m_storage->length(); } JSValue getIndex(ExecState* exec, unsigned i) @@ -82,7 +82,7 @@ namespace JSC { virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue); - virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&); + virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); virtual const ClassInfo* classInfo() const { return m_classInfo; } static const ClassInfo s_defaultInfo; @@ -91,6 +91,10 @@ namespace JSC { WTF::ByteArray* storage() const { return m_storage.get(); } +#if !ASSERT_DISABLED + virtual ~JSByteArray(); +#endif + protected: static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags; diff --git a/JavaScriptCore/runtime/JSCell.cpp b/JavaScriptCore/runtime/JSCell.cpp index 17410e2..869fbfc 100644 --- a/JavaScriptCore/runtime/JSCell.cpp +++ b/JavaScriptCore/runtime/JSCell.cpp @@ -59,10 +59,10 @@ static const union { } doubles; } NaNInf = { { -#if PLATFORM(BIG_ENDIAN) +#if CPU(BIG_ENDIAN) { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }, { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } -#elif PLATFORM(MIDDLE_ENDIAN) +#elif CPU(MIDDLE_ENDIAN) { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 }, { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 } #else @@ -76,11 +76,6 @@ extern const double Inf = NaNInf.doubles.Inf_Double; #endif // !(defined NAN && defined INFINITY) -void* JSCell::operator new(size_t size, ExecState* exec) -{ - return exec->heap()->allocate(size); -} - bool JSCell::getUInt32(uint32_t&) const { return false; diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h index c8ba2b8..3c8c829 100644 --- a/JavaScriptCore/runtime/JSCell.h +++ b/JavaScriptCore/runtime/JSCell.h @@ -43,14 +43,18 @@ namespace JSC { friend class JSValue; friend class JSAPIValueWrapper; friend class JSZombie; - friend struct VPtrSet; + friend class JSGlobalData; private: explicit JSCell(Structure*); - JSCell(); // Only used for initializing Collector blocks. virtual ~JSCell(); public: + static PassRefPtr<Structure> createDummyStructure() + { + return Structure::create(jsNull(), TypeInfo(UnspecifiedType), AnonymousSlotCount); + } + // Querying the type. #if USE(JSVALUE32) bool isNumber() const; @@ -107,6 +111,10 @@ namespace JSC { virtual JSString* toThisJSString(ExecState*); virtual JSValue getJSNumber(); void* vptr() { return *reinterpret_cast<void**>(this); } + void setVPtr(void* vptr) { *reinterpret_cast<void**>(this) = vptr; } + + protected: + static const unsigned AnonymousSlotCount = 0; private: // Base implementation; for non-object classes implements getPropertySlot. @@ -122,11 +130,6 @@ namespace JSC { { } - // Only used for initializing Collector blocks. - inline JSCell::JSCell() - { - } - inline JSCell::~JSCell() { } @@ -134,7 +137,7 @@ namespace JSC { #if USE(JSVALUE32) inline bool JSCell::isNumber() const { - return Heap::isNumber(const_cast<JSCell*>(this)); + return m_structure->typeInfo().type() == NumberType; } #endif @@ -162,6 +165,11 @@ namespace JSC { return globalData->heap.allocate(size); } + inline void* JSCell::operator new(size_t size, ExecState* exec) + { + return exec->heap()->allocate(size); + } + // --- JSValue inlines ---------------------------- inline bool JSValue::isString() const diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp index 024e586..d213b4a 100644 --- a/JavaScriptCore/runtime/JSFunction.cpp +++ b/JavaScriptCore/runtime/JSFunction.cpp @@ -81,6 +81,8 @@ JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> ex JSFunction::~JSFunction() { + ASSERT(vptr() == JSGlobalData::jsFunctionVPtr); + // JIT code for other functions may have had calls linked directly to the code for this function; these links // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once // this memory is freed and may be reused (potentially for another, different JSFunction). @@ -206,6 +208,17 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); } +void JSFunction::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) +{ + if (!isHostFunction() && (mode == IncludeDontEnumProperties)) { + propertyNames.add(exec->propertyNames().arguments); + propertyNames.add(exec->propertyNames().callee); + propertyNames.add(exec->propertyNames().caller); + propertyNames.add(exec->propertyNames().length); + } + Base::getOwnPropertyNames(exec, propertyNames, mode); +} + void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { if (isHostFunction()) { diff --git a/JavaScriptCore/runtime/JSFunction.h b/JavaScriptCore/runtime/JSFunction.h index fcac9aa..8cd4b51 100644 --- a/JavaScriptCore/runtime/JSFunction.h +++ b/JavaScriptCore/runtime/JSFunction.h @@ -36,7 +36,7 @@ namespace JSC { class JSFunction : public InternalFunction { friend class JIT; - friend struct VPtrSet; + friend class JSGlobalData; typedef InternalFunction Base; @@ -61,7 +61,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } NativeFunction nativeFunction() @@ -82,6 +82,7 @@ namespace JSC { virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName); diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp index 234449f..45abc86 100644 --- a/JavaScriptCore/runtime/JSGlobalData.cpp +++ b/JavaScriptCore/runtime/JSGlobalData.cpp @@ -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> @@ -71,42 +71,38 @@ extern JSC_CONST_HASHTABLE HashTable regExpTable; extern JSC_CONST_HASHTABLE HashTable regExpConstructorTable; extern JSC_CONST_HASHTABLE HashTable stringTable; -struct VPtrSet { - VPtrSet(); - - void* jsArrayVPtr; - void* jsByteArrayVPtr; - void* jsStringVPtr; - void* jsFunctionVPtr; -}; +void* JSGlobalData::jsArrayVPtr; +void* JSGlobalData::jsByteArrayVPtr; +void* JSGlobalData::jsStringVPtr; +void* JSGlobalData::jsFunctionVPtr; -VPtrSet::VPtrSet() +void JSGlobalData::storeVPtrs() { CollectorCell cell; void* storage = &cell; COMPILE_ASSERT(sizeof(JSArray) <= sizeof(CollectorCell), sizeof_JSArray_must_be_less_than_CollectorCell); JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull())); - jsArrayVPtr = jsArray->vptr(); + JSGlobalData::jsArrayVPtr = jsArray->vptr(); jsArray->~JSCell(); COMPILE_ASSERT(sizeof(JSByteArray) <= sizeof(CollectorCell), sizeof_JSByteArray_must_be_less_than_CollectorCell); JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack); - jsByteArrayVPtr = jsByteArray->vptr(); + JSGlobalData::jsByteArrayVPtr = jsByteArray->vptr(); jsByteArray->~JSCell(); COMPILE_ASSERT(sizeof(JSString) <= sizeof(CollectorCell), sizeof_JSString_must_be_less_than_CollectorCell); JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack); - jsStringVPtr = jsString->vptr(); + JSGlobalData::jsStringVPtr = jsString->vptr(); jsString->~JSCell(); COMPILE_ASSERT(sizeof(JSFunction) <= sizeof(CollectorCell), sizeof_JSFunction_must_be_less_than_CollectorCell); JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull())); - jsFunctionVPtr = jsFunction->vptr(); + JSGlobalData::jsFunctionVPtr = jsFunction->vptr(); jsFunction->~JSCell(); } -JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet) +JSGlobalData::JSGlobalData(bool isShared) : isSharedInstance(isShared) , clientData(0) , arrayTable(fastNew<HashTable>(JSC::arrayTable)) @@ -126,13 +122,10 @@ JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet) , propertyNameIteratorStructure(JSPropertyNameIterator::createStructure(jsNull())) , getterSetterStructure(GetterSetter::createStructure(jsNull())) , apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull())) + , dummyMarkableCellStructure(JSCell::createDummyStructure()) #if USE(JSVALUE32) , numberStructure(JSNumberCell::createStructure(jsNull())) #endif - , jsArrayVPtr(vptrSet.jsArrayVPtr) - , jsByteArrayVPtr(vptrSet.jsByteArrayVPtr) - , jsStringVPtr(vptrSet.jsStringVPtr) - , jsFunctionVPtr(vptrSet.jsFunctionVPtr) , identifierTable(createIdentifierTable()) , propertyNames(new CommonIdentifiers(this)) , emptyList(new MarkedArgumentBuffer) @@ -148,7 +141,7 @@ JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet) , dynamicGlobalObject(0) , functionCodeBlockBeingReparsed(0) , firstStringifierToMark(0) - , markStack(vptrSet.jsArrayVPtr) + , markStack(jsArrayVPtr) , cachedUTCOffset(NaN) , weakRandom(static_cast<int>(currentTime())) #ifndef NDEBUG @@ -201,9 +194,17 @@ JSGlobalData::~JSGlobalData() delete clientData; } -PassRefPtr<JSGlobalData> JSGlobalData::create(bool isShared) +PassRefPtr<JSGlobalData> JSGlobalData::createNonDefault() +{ + return adoptRef(new JSGlobalData(false)); +} + +PassRefPtr<JSGlobalData> JSGlobalData::create() { - return adoptRef(new JSGlobalData(isShared, VPtrSet())); + JSGlobalData* globalData = new JSGlobalData(false); + setDefaultIdentifierTable(globalData->identifierTable); + setCurrentIdentifierTable(globalData->identifierTable); + return adoptRef(globalData); } PassRefPtr<JSGlobalData> JSGlobalData::createLeaked() @@ -223,7 +224,7 @@ JSGlobalData& JSGlobalData::sharedInstance() { JSGlobalData*& instance = sharedInstanceInternal(); if (!instance) { - instance = create(true).releaseRef(); + instance = new JSGlobalData(true); #if ENABLE(JSC_MULTIPLE_THREADS) instance->makeUsableFromMultipleThreads(); #endif diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h index f0c1b5c..0f1f3c6 100644 --- a/JavaScriptCore/runtime/JSGlobalData.h +++ b/JavaScriptCore/runtime/JSGlobalData.h @@ -62,7 +62,6 @@ namespace JSC { struct HashTable; struct Instruction; - struct VPtrSet; struct DSTOffsetCache { DSTOffsetCache() @@ -93,8 +92,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) @@ -123,15 +123,17 @@ namespace JSC { RefPtr<Structure> propertyNameIteratorStructure; RefPtr<Structure> getterSetterStructure; RefPtr<Structure> apiWrapperStructure; + RefPtr<Structure> dummyMarkableCellStructure; #if USE(JSVALUE32) RefPtr<Structure> numberStructure; #endif - void* jsArrayVPtr; - void* jsByteArrayVPtr; - void* jsStringVPtr; - void* jsFunctionVPtr; + static void storeVPtrs(); + static JS_EXPORTDATA void* jsArrayVPtr; + static JS_EXPORTDATA void* jsByteArrayVPtr; + static JS_EXPORTDATA void* jsStringVPtr; + static JS_EXPORTDATA void* jsFunctionVPtr; IdentifierTable* identifierTable; CommonIdentifiers* propertyNames; @@ -192,7 +194,7 @@ namespace JSC { void stopSampling(); void dumpSampleData(ExecState* exec); private: - JSGlobalData(bool isShared, const VPtrSet&); + JSGlobalData(bool isShared); static JSGlobalData*& sharedInstanceInternal(); void createNativeThunk(); }; diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp index cf3f1d1..4bf0a69 100644 --- a/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -128,6 +128,8 @@ void JSGlobalObject::init(JSObject* thisValue) { ASSERT(JSLock::currentThreadIsHoldingLock()); + structure()->disableSpecificFunctionTracking(); + d()->globalData = Heap::heap(this)->globalData(); d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), this, thisValue); diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h index 9e4ef49..bbb6d5e 100644 --- a/JavaScriptCore/runtime/JSGlobalObject.h +++ b/JavaScriptCore/runtime/JSGlobalObject.h @@ -267,7 +267,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: @@ -413,11 +413,21 @@ namespace JSC { { return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure()); } + + inline JSObject* constructEmptyObject(ExecState* exec, JSGlobalObject* globalObject) + { + return new (exec) JSObject(globalObject->emptyObjectStructure()); + } inline JSArray* constructEmptyArray(ExecState* exec) { return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure()); } + + inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject) + { + return new (exec) JSArray(globalObject->arrayStructure()); + } inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength) { diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp index dc32718..0bc1274 100644 --- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp @@ -27,14 +27,16 @@ #include "CallFrame.h" #include "GlobalEvalFunction.h" +#include "Interpreter.h" #include "JSGlobalObject.h" -#include "LiteralParser.h" #include "JSString.h" -#include "Interpreter.h" -#include "Parser.h" -#include "dtoa.h" #include "Lexer.h" +#include "LiteralParser.h" #include "Nodes.h" +#include "Parser.h" +#include "StringBuilder.h" +#include "StringExtras.h" +#include "dtoa.h" #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -55,24 +57,24 @@ static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEsc if (!cstr.c_str()) return throwError(exec, URIError, "String contained an illegal UTF-16 sequence."); - UString result = ""; + StringBuilder builder; const char* p = cstr.c_str(); for (size_t k = 0; k < cstr.size(); k++, p++) { char c = *p; if (c && strchr(doNotEscape, c)) - result.append(c); + builder.append(c); else { char tmp[4]; - sprintf(tmp, "%%%02X", static_cast<unsigned char>(c)); - result += tmp; + snprintf(tmp, 4, "%%%02X", static_cast<unsigned char>(c)); + builder.append((const char*)tmp); } } - return jsString(exec, result); + return jsString(exec, builder.release()); } static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict) { - UString result = ""; + StringBuilder builder; UString str = args.at(0).toString(exec); int k = 0; int len = str.size(); @@ -106,7 +108,7 @@ static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUne charLen = 0; else if (character >= 0x10000) { // Convert to surrogate pair. - result.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10))); + builder.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10))); u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF)); } else u = static_cast<UChar>(character); @@ -131,9 +133,9 @@ static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUne } } k++; - result.append(c); + builder.append(c); } - return jsString(exec, result); + return jsString(exec, builder.release()); } bool isStrWhiteSpace(UChar c) @@ -376,7 +378,7 @@ JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, cons "0123456789" "*+-./@_"; - UString result = ""; + StringBuilder builder; UString s; UString str = args.at(0).toString(exec); const UChar* c = str.data(); @@ -393,15 +395,15 @@ JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, cons sprintf(tmp, "%%%02X", u); s = UString(tmp); } - result += s; + builder.append(s); } - return jsString(exec, result); + return jsString(exec, builder.release()); } JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args) { - UString result = ""; + StringBuilder builder; UString str = args.at(0).toString(exec); int k = 0; int len = str.size(); @@ -420,10 +422,10 @@ JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, co k += 2; } k++; - result.append(*c); + builder.append(*c); } - return jsString(exec, result); + return jsString(exec, builder.release()); } #ifndef NDEBUG diff --git a/JavaScriptCore/runtime/JSNotAnObject.cpp b/JavaScriptCore/runtime/JSNotAnObject.cpp index c36dc10..f4764e2 100644 --- a/JavaScriptCore/runtime/JSNotAnObject.cpp +++ b/JavaScriptCore/runtime/JSNotAnObject.cpp @@ -121,7 +121,7 @@ bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned) return false; } -void JSNotAnObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray&) +void JSNotAnObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray&, EnumerationMode) { ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception); } diff --git a/JavaScriptCore/runtime/JSNotAnObject.h b/JavaScriptCore/runtime/JSNotAnObject.h index a271c4e..339d41f 100644 --- a/JavaScriptCore/runtime/JSNotAnObject.h +++ b/JavaScriptCore/runtime/JSNotAnObject.h @@ -62,7 +62,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } private: @@ -91,7 +91,7 @@ namespace JSC { virtual bool deleteProperty(ExecState*, const Identifier& propertyName); virtual bool deleteProperty(ExecState*, unsigned propertyName); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); JSNotAnObjectErrorStub* m_exception; }; diff --git a/JavaScriptCore/runtime/JSNumberCell.h b/JavaScriptCore/runtime/JSNumberCell.h index e9e2470..bcb506b 100644 --- a/JavaScriptCore/runtime/JSNumberCell.h +++ b/JavaScriptCore/runtime/JSNumberCell.h @@ -76,7 +76,7 @@ namespace JSC { return globalData->heap.allocateNumber(size); } - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, OverridesGetOwnPropertySlot | NeedsThisConversion)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); } private: JSNumberCell(JSGlobalData* globalData, double value) diff --git a/JavaScriptCore/runtime/JSONObject.cpp b/JavaScriptCore/runtime/JSONObject.cpp index cc7f6d9..ce0dcff 100644 --- a/JavaScriptCore/runtime/JSONObject.cpp +++ b/JavaScriptCore/runtime/JSONObject.cpp @@ -32,6 +32,7 @@ #include "JSArray.h" #include "LiteralParser.h" #include "PropertyNameArray.h" +#include "StringBuilder.h" #include <wtf/MathExtras.h> namespace JSC { @@ -70,24 +71,6 @@ public: void markAggregate(MarkStack&); private: - class StringBuilder : public Vector<UChar> { - public: - using Vector<UChar>::append; - - inline void append(const char* str) - { - size_t len = strlen(str); - reserveCapacity(size() + len); - for (size_t i = 0; i < len; i++) - Vector<UChar>::append(str[i]); - } - - inline void append(const UString& str) - { - append(str.data(), str.size()); - } - }; - class Holder { public: Holder(JSObject*); @@ -285,9 +268,7 @@ JSValue Stringifier::stringify(JSValue value) if (m_exec->hadException()) return jsNull(); - result.shrinkToFit(); - size_t length = result.size(); - return jsString(m_exec, UString(result.releaseBuffer(), length, false)); + return jsString(m_exec, result.release()); } void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value) @@ -477,7 +458,7 @@ inline void Stringifier::indent() // Use a single shared string, m_repeatedGap, so we don't keep allocating new ones as we indent and unindent. int newSize = m_indent.size() + m_gap.size(); if (newSize > m_repeatedGap.size()) - m_repeatedGap.append(m_gap); + m_repeatedGap = makeString(m_repeatedGap, m_gap); ASSERT(newSize <= m_repeatedGap.size()); m_indent = m_repeatedGap.substr(0, newSize); } @@ -520,7 +501,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui m_propertyNames = stringifier.m_arrayReplacerPropertyNames.data(); else { PropertyNameArray objectPropertyNames(exec); - m_object->getPropertyNames(exec, objectPropertyNames); + m_object->getOwnPropertyNames(exec, objectPropertyNames); m_propertyNames = objectPropertyNames.releaseData(); } m_size = m_propertyNames->propertyNameVector().size(); @@ -765,7 +746,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) objectStack.append(object); indexStack.append(0); propertyStack.append(PropertyNameArray(m_exec)); - object->getPropertyNames(m_exec, propertyStack.last()); + object->getOwnPropertyNames(m_exec, propertyStack.last()); // fallthrough } objectStartVisitMember: diff --git a/JavaScriptCore/runtime/JSONObject.h b/JavaScriptCore/runtime/JSONObject.h index ec3fa40..905e4bc 100644 --- a/JavaScriptCore/runtime/JSONObject.h +++ b/JavaScriptCore/runtime/JSONObject.h @@ -41,7 +41,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } static void markStringifiers(MarkStack&, Stringifier*); diff --git a/JavaScriptCore/runtime/JSObject.cpp b/JavaScriptCore/runtime/JSObject.cpp index ed9fdc2..d9500aa 100644 --- a/JavaScriptCore/runtime/JSObject.cpp +++ b/JavaScriptCore/runtime/JSObject.cpp @@ -42,7 +42,7 @@ namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSObject); -static inline void getEnumerablePropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames) +static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode) { // Add properties from the static hashtables of properties for (; classInfo; classInfo = classInfo->parentClass) { @@ -55,7 +55,7 @@ static inline void getEnumerablePropertyNames(ExecState* exec, const ClassInfo* int hashSizeMask = table->compactSize - 1; const HashEntry* entry = table->table; for (int i = 0; i <= hashSizeMask; ++i, ++entry) { - if (entry->key() && !(entry->attributes() & DontEnum)) + if (entry->key() && (!(entry->attributes() & DontEnum) || (mode == IncludeDontEnumProperties))) propertyNames.add(entry->key()); } } @@ -425,9 +425,9 @@ bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyNa return false; } -void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { - getOwnPropertyNames(exec, propertyNames); + getOwnPropertyNames(exec, propertyNames, mode); if (prototype().isNull()) return; @@ -435,10 +435,10 @@ void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyName JSObject* prototype = asObject(this->prototype()); while(1) { if (prototype->structure()->typeInfo().overridesGetPropertyNames()) { - prototype->getPropertyNames(exec, propertyNames); + prototype->getPropertyNames(exec, propertyNames, mode); break; } - prototype->getOwnPropertyNames(exec, propertyNames); + prototype->getOwnPropertyNames(exec, propertyNames, mode); JSValue nextProto = prototype->prototype(); if (nextProto.isNull()) break; @@ -446,10 +446,10 @@ void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyName } } -void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { - m_structure->getEnumerablePropertyNames(propertyNames); - getEnumerablePropertyNames(exec, classInfo(), propertyNames); + m_structure->getPropertyNames(propertyNames, mode); + getClassPropertyNames(exec, classInfo(), propertyNames, mode); } bool JSObject::toBoolean(ExecState*) const diff --git a/JavaScriptCore/runtime/JSObject.h b/JavaScriptCore/runtime/JSObject.h index a5da267..2b31a65 100644 --- a/JavaScriptCore/runtime/JSObject.h +++ b/JavaScriptCore/runtime/JSObject.h @@ -122,8 +122,8 @@ namespace JSC { virtual bool hasInstance(ExecState*, JSValue, JSValue prototypeProperty); - virtual void getPropertyNames(ExecState*, PropertyNameArray&); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); + virtual void getPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const; virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value); @@ -206,7 +206,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } void flattenDictionaryObject() @@ -217,13 +217,14 @@ namespace JSC { protected: static const unsigned StructureFlags = 0; - void addAnonymousSlots(unsigned count); void putAnonymousValue(unsigned index, JSValue value) { + ASSERT(index < m_structure->anonymousSlotCount()); *locationForOffset(index) = value; } - JSValue getAnonymousValue(unsigned index) + JSValue getAnonymousValue(unsigned index) const { + ASSERT(index < m_structure->anonymousSlotCount()); return *locationForOffset(index); } @@ -381,7 +382,7 @@ ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, const Identif // It may seem crazy to inline a function this large but it makes a big difference // since this is function very hot in variable lookup -inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { JSObject* object = this; while (true) { @@ -394,7 +395,7 @@ inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propert } } -inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) +ALWAYS_INLINE bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot) { JSObject* object = this; while (true) { @@ -528,17 +529,6 @@ inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi putDirectInternal(propertyName, value, attributes, false, slot, getJSFunction(globalData, value)); } -inline void JSObject::addAnonymousSlots(unsigned count) -{ - size_t currentCapacity = m_structure->propertyStorageCapacity(); - RefPtr<Structure> structure = Structure::addAnonymousSlotsTransition(m_structure, count); - - if (currentCapacity != structure->propertyStorageCapacity()) - allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity()); - - setStructure(structure.release()); -} - inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot) { ASSERT(value); diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.h b/JavaScriptCore/runtime/JSPropertyNameIterator.h index 529ae8b..d18c2c5 100644 --- a/JavaScriptCore/runtime/JSPropertyNameIterator.h +++ b/JavaScriptCore/runtime/JSPropertyNameIterator.h @@ -47,7 +47,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren)); + return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren), AnonymousSlotCount); } virtual bool isPropertyNameIterator() const { return true; } diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.h b/JavaScriptCore/runtime/JSStaticScopeObject.h index 2542878..4d156d4 100644 --- a/JavaScriptCore/runtime/JSStaticScopeObject.h +++ b/JavaScriptCore/runtime/JSStaticScopeObject.h @@ -57,7 +57,7 @@ namespace JSC{ virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes); - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NeedsThisConversion | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; diff --git a/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp index 28ae6f7..1e23a15 100644 --- a/JavaScriptCore/runtime/JSString.cpp +++ b/JavaScriptCore/runtime/JSString.cpp @@ -66,20 +66,6 @@ JSString::Rope::~Rope() destructNonRecursive(); } -#define ROPE_COPY_CHARS_INLINE_CUTOFF 20 - -static inline void copyChars(UChar* destination, const UChar* source, unsigned numCharacters) -{ -#ifdef ROPE_COPY_CHARS_INLINE_CUTOFF - if (numCharacters <= ROPE_COPY_CHARS_INLINE_CUTOFF) { - for (unsigned i = 0; i < numCharacters; ++i) - destination[i] = source[i]; - return; - } -#endif - memcpy(destination, source, numCharacters * sizeof(UChar)); -} - // Overview: this methods converts a JSString from holding a string in rope form // down to a simple UString representation. It does so by building up the string // backwards, since we want to avoid recursion, we expect that the tree structure @@ -96,13 +82,16 @@ void JSString::resolveRope(ExecState* exec) const // Allocate the buffer to hold the final string, position initially points to the end. UChar* buffer; - if (!tryFastMalloc(m_stringLength * sizeof(UChar)).getValue(buffer)) { - for (unsigned i = 0; i < m_ropeLength; ++i) + if (PassRefPtr<UStringImpl> newImpl = UStringImpl::tryCreateUninitialized(m_stringLength, buffer)) + m_value = newImpl; + else { + for (unsigned i = 0; i < m_ropeLength; ++i) { m_fibers[i].deref(); + m_fibers[i] = static_cast<void*>(0); + } m_ropeLength = 0; ASSERT(!isRope()); ASSERT(m_value == UString()); - throwOutOfMemoryError(exec); return; } @@ -125,17 +114,18 @@ void JSString::resolveRope(ExecState* exec) const currentFiber = rope->fibers(ropeLengthMinusOne); } else { UString::Rep* string = currentFiber.string(); - unsigned length = string->len; + unsigned length = string->size(); position -= length; - copyChars(position, string->data(), length); + UStringImpl::copyChars(position, string->data(), length); // Was this the last item in the work queue? if (workQueue.isEmpty()) { // Create a string from the UChar buffer, clear the rope RefPtr. ASSERT(buffer == position); - m_value = UString::Rep::create(buffer, m_stringLength); - for (unsigned i = 0; i < m_ropeLength; ++i) + for (unsigned i = 0; i < m_ropeLength; ++i) { m_fibers[i].deref(); + m_fibers[i] = static_cast<void*>(0); + } m_ropeLength = 0; ASSERT(!isRope()); diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h index 93b11f1..7288b6f 100644 --- a/JavaScriptCore/runtime/JSString.h +++ b/JavaScriptCore/runtime/JSString.h @@ -59,10 +59,13 @@ namespace JSC { JSString* jsOwnedString(JSGlobalData*, const UString&); JSString* jsOwnedString(ExecState*, const UString&); - class JSString : public JSCell { + typedef void (*JSStringFinalizerCallback)(JSString*, void* context); + JSString* jsStringWithFinalizer(ExecState*, const UString&, JSStringFinalizerCallback callback, void* context); + + class JS_EXPORTCLASS JSString : public JSCell { public: friend class JIT; - friend struct VPtrSet; + friend class JSGlobalData; // A Rope is a string composed of a set of substrings. class Rope : public RefCounted<Rope> { @@ -71,10 +74,12 @@ namespace JSC { // Each Fiber in a rope is either UString::Rep or another Rope. class Fiber { public: - Fiber() {} + Fiber() : m_value(0) {} Fiber(UString::Rep* string) : m_value(reinterpret_cast<intptr_t>(string)) {} Fiber(Rope* rope) : m_value(reinterpret_cast<intptr_t>(rope) | 1) {} + Fiber(void* nonFiber) : m_value(reinterpret_cast<intptr_t>(nonFiber)) {} + void deref() { if (isRope()) @@ -96,7 +101,7 @@ namespace JSC { { if (isString()) { UString::Rep* rep = string(); - return rep->ref()->len; + return rep->ref()->size(); } else { Rope* r = rope(); r->ref(); @@ -109,6 +114,7 @@ namespace JSC { bool isString() { return !isRope(); } UString::Rep* string() { return reinterpret_cast<UString::Rep*>(m_value); } + void* nonFiber() { return reinterpret_cast<void*>(m_value); } private: intptr_t m_value; }; @@ -135,7 +141,7 @@ namespace JSC { { UString::Rep* rep = string.rep(); m_fibers[index++] = Fiber(rep); - m_stringLength += rep->ref()->len; + m_stringLength += rep->ref()->size(); } void append(unsigned& index, JSString* jsString) { @@ -159,7 +165,7 @@ namespace JSC { Fiber m_fibers[1]; }; - JSString(JSGlobalData* globalData, const UString& value) + ALWAYS_INLINE JSString(JSGlobalData* globalData, const UString& value) : JSCell(globalData->stringStructure.get()) , m_stringLength(value.size()) , m_value(value) @@ -219,10 +225,28 @@ namespace JSC { ASSERT(index == s_maxInternalRopeLength); } + JSString(JSGlobalData* globalData, const UString& value, JSStringFinalizerCallback finalizer, void* context) + : JSCell(globalData->stringStructure.get()) + , m_stringLength(value.size()) + , m_value(value) + , m_ropeLength(0) + { + // nasty hack because we can't union non-POD types + m_fibers[0] = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(finalizer)); + m_fibers[1] = context; + Heap::heap(this)->reportExtraMemoryCost(value.cost()); + } + ~JSString() { + ASSERT(vptr() == JSGlobalData::jsStringVPtr); for (unsigned i = 0; i < m_ropeLength; ++i) m_fibers[i].deref(); + + if (!m_ropeLength && m_fibers[0].nonFiber()) { + JSStringFinalizerCallback finalizer = reinterpret_cast<JSStringFinalizerCallback>(m_fibers[0].nonFiber()); + finalizer(this, m_fibers[1].nonFiber()); + } } const UString& value(ExecState* exec) const @@ -246,7 +270,7 @@ namespace JSC { bool canGetIndex(unsigned i) { return i < m_stringLength; } JSString* getIndex(ExecState*, unsigned); - static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion)); } + static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); } private: enum VPtrStealingHackType { VPtrStealingHack }; @@ -312,10 +336,22 @@ namespace JSC { friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2); friend JSValue jsString(ExecState* exec, Register* strings, unsigned count); + friend JSValue jsString(ExecState* exec, JSValue thisValue, const ArgList& args); + friend JSString* jsStringWithFinalizer(ExecState*, const UString&, JSStringFinalizerCallback callback, void* context); }; JSString* asString(JSValue); + // When an object is created from a different DLL, MSVC changes vptr to a "local" one right after invoking a constructor, + // see <http://groups.google.com/group/microsoft.public.vc.language/msg/55cdcefeaf770212>. + // This breaks isJSString(), and we don't need that hack anyway, so we change vptr back to primary one. + // The below function must be called by any inline function that invokes a JSString constructor. +#if COMPILER(MSVC) && !defined(BUILDING_JavaScriptCore) + inline JSString* fixupVPtr(JSGlobalData* globalData, JSString* string) { string->setVPtr(globalData->jsStringVPtr); return string; } +#else + inline JSString* fixupVPtr(JSGlobalData*, JSString* string) { return string; } +#endif + inline JSString* asString(JSValue value) { ASSERT(asCell(value)->isString()); @@ -331,7 +367,7 @@ namespace JSC { { if (c <= 0xFF) return globalData->smallStrings.singleCharacterString(globalData, c); - return new (globalData) JSString(globalData, UString(&c, 1)); + return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(&c, 1))); } inline JSString* jsSingleCharacterSubstring(JSGlobalData* globalData, const UString& s, unsigned offset) @@ -340,7 +376,7 @@ namespace JSC { UChar c = s.data()[offset]; if (c <= 0xFF) return globalData->smallStrings.singleCharacterString(globalData, c); - return new (globalData) JSString(globalData, UString(UString::Rep::create(s.rep(), offset, 1))); + return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UString::Rep::create(s.rep(), offset, 1)))); } inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s) @@ -348,13 +384,13 @@ namespace JSC { ASSERT(s); ASSERT(s[0]); ASSERT(s[1]); - return new (globalData) JSString(globalData, s); + return fixupVPtr(globalData, new (globalData) JSString(globalData, s)); } inline JSString* jsNontrivialString(JSGlobalData* globalData, const UString& s) { ASSERT(s.size() > 1); - return new (globalData) JSString(globalData, s); + return fixupVPtr(globalData, new (globalData) JSString(globalData, s)); } inline JSString* JSString::getIndex(ExecState* exec, unsigned i) @@ -373,7 +409,14 @@ namespace JSC { if (c <= 0xFF) return globalData->smallStrings.singleCharacterString(globalData, c); } - return new (globalData) JSString(globalData, s); + return fixupVPtr(globalData, new (globalData) JSString(globalData, s)); + } + + inline JSString* jsStringWithFinalizer(ExecState* exec, const UString& s, JSStringFinalizerCallback callback, void* context) + { + ASSERT(s.size() && (s.size() > 1 || s.data()[0] > 0xFF)); + JSGlobalData* globalData = &exec->globalData(); + return fixupVPtr(globalData, new (globalData) JSString(globalData, s, callback, context)); } inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) @@ -388,7 +431,7 @@ namespace JSC { if (c <= 0xFF) return globalData->smallStrings.singleCharacterString(globalData, c); } - return new (globalData) JSString(globalData, UString(UString::Rep::create(s.rep(), offset, length))); + return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UString::Rep::create(s.rep(), offset, length)), JSString::HasOtherOwner)); } inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s) @@ -401,7 +444,7 @@ namespace JSC { if (c <= 0xFF) return globalData->smallStrings.singleCharacterString(globalData, c); } - return new (globalData) JSString(globalData, s, JSString::HasOtherOwner); + return fixupVPtr(globalData, new (globalData) JSString(globalData, s, JSString::HasOtherOwner)); } inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); } @@ -469,6 +512,26 @@ namespace JSC { return asCell()->toString(exec); } + inline UString JSValue::toPrimitiveString(ExecState* exec) const + { + if (isString()) + return static_cast<JSString*>(asCell())->value(exec); + if (isInt32()) + return exec->globalData().numericStrings.add(asInt32()); + if (isDouble()) + return exec->globalData().numericStrings.add(asDouble()); + if (isTrue()) + return "true"; + if (isFalse()) + return "false"; + if (isNull()) + return "null"; + if (isUndefined()) + return "undefined"; + ASSERT(isCell()); + return asCell()->toPrimitive(exec, NoPreference).toString(exec); + } + } // namespace JSC #endif // JSString_h diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h index fa5b5c0..6da921f 100644 --- a/JavaScriptCore/runtime/JSValue.h +++ b/JavaScriptCore/runtime/JSValue.h @@ -158,6 +158,7 @@ namespace JSC { double toNumber(ExecState*) const; JSValue toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number. UString toString(ExecState*) const; + UString toPrimitiveString(ExecState*) const; JSObject* toObject(ExecState*) const; // Integer conversions. @@ -234,7 +235,7 @@ namespace JSC { union { EncodedJSValue asEncodedJSValue; double asDouble; -#if PLATFORM(BIG_ENDIAN) +#if CPU(BIG_ENDIAN) struct { int32_t tag; int32_t payload; diff --git a/JavaScriptCore/runtime/JSVariableObject.cpp b/JavaScriptCore/runtime/JSVariableObject.cpp index 3aa9e62..7365001 100644 --- a/JavaScriptCore/runtime/JSVariableObject.cpp +++ b/JavaScriptCore/runtime/JSVariableObject.cpp @@ -42,15 +42,15 @@ bool JSVariableObject::deleteProperty(ExecState* exec, const Identifier& propert return JSObject::deleteProperty(exec, propertyName); } -void JSVariableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void JSVariableObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { SymbolTable::const_iterator end = symbolTable().end(); for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) { - if (!(it->second.getAttributes() & DontEnum)) + if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties)) propertyNames.add(Identifier(exec, it->first.get())); } - JSObject::getOwnPropertyNames(exec, propertyNames); + JSObject::getOwnPropertyNames(exec, propertyNames, mode); } bool JSVariableObject::isVariableObject() const diff --git a/JavaScriptCore/runtime/JSVariableObject.h b/JavaScriptCore/runtime/JSVariableObject.h index 15d6ff5..6c679ce 100644 --- a/JavaScriptCore/runtime/JSVariableObject.h +++ b/JavaScriptCore/runtime/JSVariableObject.h @@ -49,7 +49,7 @@ namespace JSC { virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0; virtual bool deleteProperty(ExecState*, const Identifier&); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); virtual bool isVariableObject() const; virtual bool isDynamicScope() const = 0; @@ -58,7 +58,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/runtime/JSWrapperObject.h b/JavaScriptCore/runtime/JSWrapperObject.h index 191ff3b..f19cd30 100644 --- a/JavaScriptCore/runtime/JSWrapperObject.h +++ b/JavaScriptCore/runtime/JSWrapperObject.h @@ -38,9 +38,12 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } + protected: + static const unsigned AnonymousSlotCount = 1 + JSObject::AnonymousSlotCount; + private: virtual void markChildren(MarkStack&); @@ -50,7 +53,6 @@ namespace JSC { inline JSWrapperObject::JSWrapperObject(NonNullPassRefPtr<Structure> structure) : JSObject(structure) { - addAnonymousSlots(1); putAnonymousValue(0, jsNull()); } diff --git a/JavaScriptCore/runtime/LiteralParser.cpp b/JavaScriptCore/runtime/LiteralParser.cpp index d242282..aa1e5ed 100644 --- a/JavaScriptCore/runtime/LiteralParser.cpp +++ b/JavaScriptCore/runtime/LiteralParser.cpp @@ -29,6 +29,7 @@ #include "JSArray.h" #include "JSString.h" #include "Lexer.h" +#include "StringBuilder.h" #include <wtf/ASCIICType.h> #include <wtf/dtoa.h> @@ -134,48 +135,48 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera { ++m_ptr; const UChar* runStart; - token.stringToken = UString(); + StringBuilder builder; do { runStart = m_ptr; while (m_ptr < m_end && isSafeStringCharacter<mode>(*m_ptr)) ++m_ptr; if (runStart < m_ptr) - token.stringToken.append(runStart, m_ptr - runStart); + builder.append(runStart, m_ptr - runStart); if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') { ++m_ptr; if (m_ptr >= m_end) return TokError; switch (*m_ptr) { case '"': - token.stringToken.append('"'); + builder.append('"'); m_ptr++; break; case '\\': - token.stringToken.append('\\'); + builder.append('\\'); m_ptr++; break; case '/': - token.stringToken.append('/'); + builder.append('/'); m_ptr++; break; case 'b': - token.stringToken.append('\b'); + builder.append('\b'); m_ptr++; break; case 'f': - token.stringToken.append('\f'); + builder.append('\f'); m_ptr++; break; case 'n': - token.stringToken.append('\n'); + builder.append('\n'); m_ptr++; break; case 'r': - token.stringToken.append('\r'); + builder.append('\r'); m_ptr++; break; case 't': - token.stringToken.append('\t'); + builder.append('\t'); m_ptr++; break; @@ -186,7 +187,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera if (!isASCIIHexDigit(m_ptr[i])) return TokError; } - token.stringToken.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4])); + builder.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4])); m_ptr += 5; break; @@ -199,6 +200,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera if (m_ptr >= m_end || *m_ptr != '"') return TokError; + token.stringToken = builder.release(); token.type = TokString; token.end = ++m_ptr; return TokString; diff --git a/JavaScriptCore/runtime/Lookup.cpp b/JavaScriptCore/runtime/Lookup.cpp index 8359ff7..4e9e086 100644 --- a/JavaScriptCore/runtime/Lookup.cpp +++ b/JavaScriptCore/runtime/Lookup.cpp @@ -34,7 +34,7 @@ void HashTable::createTable(JSGlobalData* globalData) const entries[i].setKey(0); for (int i = 0; values[i].key; ++i) { UString::Rep* identifier = Identifier::add(globalData, values[i].key).releaseRef(); - int hashIndex = identifier->computedHash() & compactHashSizeMask; + int hashIndex = identifier->existingHash() & compactHashSizeMask; HashEntry* entry = &entries[hashIndex]; if (entry->key()) { diff --git a/JavaScriptCore/runtime/Lookup.h b/JavaScriptCore/runtime/Lookup.h index 4d70689..e673c09 100644 --- a/JavaScriptCore/runtime/Lookup.h +++ b/JavaScriptCore/runtime/Lookup.h @@ -144,7 +144,7 @@ namespace JSC { { ASSERT(table); - const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & compactHashSizeMask]; + const HashEntry* entry = &table[identifier.ustring().rep()->existingHash() & compactHashSizeMask]; if (!entry->key()) return 0; diff --git a/JavaScriptCore/runtime/MarkStack.h b/JavaScriptCore/runtime/MarkStack.h index a114ae0..c551bac 100644 --- a/JavaScriptCore/runtime/MarkStack.h +++ b/JavaScriptCore/runtime/MarkStack.h @@ -153,7 +153,7 @@ namespace JSC { ASSERT(0 == (size % MarkStack::pageSize())); if (size == m_allocated) return; -#if PLATFORM(WIN_OS) || PLATFORM(SYMBIAN) +#if OS(WINDOWS) || OS(SYMBIAN) || PLATFORM(BREWMP) // We cannot release a part of a region with VirtualFree. To get around this, // we'll release the entire region and reallocate the size that we want. releaseStack(m_data, m_allocated); diff --git a/JavaScriptCore/runtime/MarkStackNone.cpp b/JavaScriptCore/runtime/MarkStackNone.cpp new file mode 100644 index 0000000..b1ff48b --- /dev/null +++ b/JavaScriptCore/runtime/MarkStackNone.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009 Company 100, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "MarkStack.h" + +#include "FastMalloc.h" + +namespace JSC { + +void MarkStack::initializePagesize() +{ + MarkStack::s_pageSize = 4096; +} + +void* MarkStack::allocateStack(size_t size) +{ + return fastMalloc(size); +} + +void MarkStack::releaseStack(void* addr, size_t) +{ + return fastFree(addr); +} + +} diff --git a/JavaScriptCore/runtime/MarkStackPosix.cpp b/JavaScriptCore/runtime/MarkStackPosix.cpp index 8e78ff3..c28bc0d 100644 --- a/JavaScriptCore/runtime/MarkStackPosix.cpp +++ b/JavaScriptCore/runtime/MarkStackPosix.cpp @@ -24,10 +24,10 @@ */ #include "config.h" - - #include "MarkStack.h" +#if OS(UNIX) && !OS(SYMBIAN) + #include <unistd.h> #include <sys/mman.h> @@ -48,3 +48,5 @@ void MarkStack::releaseStack(void* addr, size_t size) } } + +#endif diff --git a/JavaScriptCore/runtime/MarkStackSymbian.cpp b/JavaScriptCore/runtime/MarkStackSymbian.cpp index a0ce8f6..bda14ac 100644 --- a/JavaScriptCore/runtime/MarkStackSymbian.cpp +++ b/JavaScriptCore/runtime/MarkStackSymbian.cpp @@ -20,6 +20,8 @@ #include "config.h" #include "MarkStack.h" +#if OS(SYMBIAN) + #include <e32hal.h> namespace JSC { @@ -42,3 +44,5 @@ void MarkStack::releaseStack(void* addr, size_t size) } } + +#endif diff --git a/JavaScriptCore/runtime/MarkStackWin.cpp b/JavaScriptCore/runtime/MarkStackWin.cpp index 1fdd06a..a171c78 100644 --- a/JavaScriptCore/runtime/MarkStackWin.cpp +++ b/JavaScriptCore/runtime/MarkStackWin.cpp @@ -24,10 +24,10 @@ */ #include "config.h" - - #include "MarkStack.h" +#if OS(WINDOWS) + #include "windows.h" namespace JSC { @@ -51,3 +51,5 @@ void MarkStack::releaseStack(void* addr, size_t) } } + +#endif diff --git a/JavaScriptCore/runtime/MathObject.h b/JavaScriptCore/runtime/MathObject.h index 7f474b8..a9f7031 100644 --- a/JavaScriptCore/runtime/MathObject.h +++ b/JavaScriptCore/runtime/MathObject.h @@ -37,7 +37,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/runtime/NumberConstructor.h b/JavaScriptCore/runtime/NumberConstructor.h index cf19b6f..723c4b2 100644 --- a/JavaScriptCore/runtime/NumberConstructor.h +++ b/JavaScriptCore/runtime/NumberConstructor.h @@ -39,7 +39,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; diff --git a/JavaScriptCore/runtime/NumberObject.h b/JavaScriptCore/runtime/NumberObject.h index 8223a90..6c18cdd 100644 --- a/JavaScriptCore/runtime/NumberObject.h +++ b/JavaScriptCore/runtime/NumberObject.h @@ -33,7 +33,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp index df31404..67210fa 100644 --- a/JavaScriptCore/runtime/NumberPrototype.cpp +++ b/JavaScriptCore/runtime/NumberPrototype.cpp @@ -25,9 +25,10 @@ #include "Error.h" #include "JSFunction.h" #include "JSString.h" +#include "Operations.h" #include "PrototypeFunction.h" +#include "StringBuilder.h" #include "dtoa.h" -#include "Operations.h" #include <wtf/Assertions.h> #include <wtf/MathExtras.h> #include <wtf/Vector.h> @@ -73,11 +74,12 @@ static UString integerPartNoExp(double d) bool resultIsInfOrNan = (decimalPoint == 9999); size_t length = strlen(result); - UString str = sign ? "-" : ""; + StringBuilder builder; + builder.append(sign ? "-" : ""); if (resultIsInfOrNan) - str += result; + builder.append((const char*)result); else if (decimalPoint <= 0) - str += "0"; + builder.append("0"); else { Vector<char, 1024> buf(decimalPoint + 1); @@ -89,10 +91,10 @@ static UString integerPartNoExp(double d) strncpy(buf.data(), result, decimalPoint); buf[decimalPoint] = '\0'; - str.append(buf.data()); + builder.append((const char*)(buf.data())); } - return str; + return builder.release(); } static UString charSequence(char c, int count) @@ -236,13 +238,16 @@ JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue UString s; if (x < 0) { - s.append('-'); + s = "-"; x = -x; - } else if (x == -0.0) - x = 0; + } else { + s = ""; + if (x == -0.0) + x = 0; + } if (x >= pow(10.0, 21.0)) - return jsString(exec, s + UString::from(x)); + return jsString(exec, makeString(s, UString::from(x))); const double tenToTheF = pow(10.0, f); double n = floor(x * tenToTheF); @@ -253,17 +258,19 @@ JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue int k = m.size(); if (k <= f) { - UString z; + StringBuilder z; for (int i = 0; i < f + 1 - k; i++) z.append('0'); - m = z + m; + z.append(m); + m = z.release(); k = f + 1; ASSERT(k == m.size()); } int kMinusf = k - f; + if (kMinusf < m.size()) - return jsString(exec, s + m.substr(0, kMinusf) + "." + m.substr(kMinusf)); - return jsString(exec, s + m.substr(0, kMinusf)); + return jsString(exec, makeString(s, m.substr(0, kMinusf), ".", m.substr(kMinusf))); + return jsString(exec, makeString(s, m.substr(0, kMinusf))); } static void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits) @@ -391,7 +398,8 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV if (x < 0) { s = "-"; x = -x; - } + } else + s = ""; if (!(doublePrecision >= 1 && doublePrecision <= 21)) // true for NaN return throwError(exec, RangeError, "toPrecision() argument must be between 1 and 21"); @@ -422,10 +430,10 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV m = integerPartNoExp(n); if (e < -6 || e >= precision) { if (m.size() > 1) - m = m.substr(0, 1) + "." + m.substr(1); + m = makeString(m.substr(0, 1), ".", m.substr(1)); if (e >= 0) - return jsNontrivialString(exec, s + m + "e+" + UString::from(e)); - return jsNontrivialString(exec, s + m + "e-" + UString::from(-e)); + return jsNontrivialString(exec, makeString(s, m, "e+", UString::from(e))); + return jsNontrivialString(exec, makeString(s, m, "e-", UString::from(-e))); } } else { m = charSequence('0', precision); @@ -433,13 +441,13 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV } if (e == precision - 1) - return jsString(exec, s + m); + return jsString(exec, makeString(s, m)); if (e >= 0) { if (e + 1 < m.size()) - return jsString(exec, s + m.substr(0, e + 1) + "." + m.substr(e + 1)); - return jsString(exec, s + m); + return jsString(exec, makeString(s, m.substr(0, e + 1), ".", m.substr(e + 1))); + return jsString(exec, makeString(s, m)); } - return jsNontrivialString(exec, s + "0." + charSequence('0', -(e + 1)) + m); + return jsNontrivialString(exec, makeString(s, "0.", charSequence('0', -(e + 1)), m)); } } // namespace JSC diff --git a/JavaScriptCore/runtime/ObjectConstructor.cpp b/JavaScriptCore/runtime/ObjectConstructor.cpp index 693efc3..0838eb4 100644 --- a/JavaScriptCore/runtime/ObjectConstructor.cpp +++ b/JavaScriptCore/runtime/ObjectConstructor.cpp @@ -36,6 +36,7 @@ ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor); static JSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*, JSObject*, JSValue, const ArgList&); static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*, JSObject*, JSValue, const ArgList&); +static JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*, JSObject*, JSValue, const ArgList&); static JSValue JSC_HOST_CALL objectConstructorKeys(ExecState*, JSObject*, JSValue, const ArgList&); static JSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState*, JSObject*, JSValue, const ArgList&); static JSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState*, JSObject*, JSValue, const ArgList&); @@ -52,6 +53,7 @@ ObjectConstructor::ObjectConstructor(ExecState* exec, NonNullPassRefPtr<Structur putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().getPrototypeOf, objectConstructorGetPrototypeOf), DontEnum); putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().getOwnPropertyDescriptor, objectConstructorGetOwnPropertyDescriptor), DontEnum); + putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().getOwnPropertyNames, objectConstructorGetOwnPropertyNames), DontEnum); putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().keys, objectConstructorKeys), DontEnum); putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 3, exec->propertyNames().defineProperty, objectConstructorDefineProperty), DontEnum); putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().defineProperties, objectConstructorDefineProperties), DontEnum); @@ -126,6 +128,20 @@ JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec, } // FIXME: Use the enumeration cache. +JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exec, JSObject*, JSValue, const ArgList& args) +{ + if (!args.at(0).isObject()) + return throwError(exec, TypeError, "Requested property names of a value that is not an object."); + PropertyNameArray properties(exec); + asObject(args.at(0))->getOwnPropertyNames(exec, properties, IncludeDontEnumProperties); + JSArray* names = constructEmptyArray(exec); + size_t numProperties = properties.size(); + for (size_t i = 0; i < numProperties; i++) + names->push(exec, jsOwnedString(exec, properties[i].ustring())); + return names; +} + +// FIXME: Use the enumeration cache. JSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec, JSObject*, JSValue, const ArgList& args) { if (!args.at(0).isObject()) diff --git a/JavaScriptCore/runtime/ObjectPrototype.cpp b/JavaScriptCore/runtime/ObjectPrototype.cpp index 0970b7c..3065c6d 100644 --- a/JavaScriptCore/runtime/ObjectPrototype.cpp +++ b/JavaScriptCore/runtime/ObjectPrototype.cpp @@ -148,7 +148,7 @@ JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { - return jsNontrivialString(exec, "[object " + thisValue.toThisObject(exec)->className() + "]"); + return jsNontrivialString(exec, makeString("[object ", thisValue.toThisObject(exec)->className(), "]")); } } // namespace JSC diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h index 1cab06d..5a905e3 100644 --- a/JavaScriptCore/runtime/Operations.h +++ b/JavaScriptCore/runtime/Operations.h @@ -87,6 +87,43 @@ namespace JSC { return new (globalData) JSString(globalData, rope.release()); } + ALWAYS_INLINE JSValue jsString(ExecState* exec, JSValue thisValue, const ArgList& args) + { + unsigned ropeLength = 0; + if (LIKELY(thisValue.isString())) + ropeLength += asString(thisValue)->ropeLength(); + else + ++ropeLength; + for (unsigned i = 0; i < args.size(); ++i) { + JSValue v = args.at(i); + if (LIKELY(v.isString())) + ropeLength += asString(v)->ropeLength(); + else + ++ropeLength; + } + + RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength); + if (UNLIKELY(!rope)) + return throwOutOfMemoryError(exec); + + unsigned index = 0; + if (LIKELY(thisValue.isString())) + rope->append(index, asString(thisValue)); + else + rope->append(index, thisValue.toString(exec)); + for (unsigned i = 0; i < args.size(); ++i) { + JSValue v = args.at(i); + if (LIKELY(v.isString())) + rope->append(index, asString(v)); + else + rope->append(index, v.toString(exec)); + } + ASSERT(index == ropeLength); + + JSGlobalData* globalData = &exec->globalData(); + return new (globalData) JSString(globalData, rope.release()); + } + // ECMA 11.9.3 inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2) { @@ -186,7 +223,7 @@ namespace JSC { return strictEqualSlowCaseInline(exec, v1, v2); } - inline bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2) + ALWAYS_INLINE bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2) { if (v1.isInt32() && v2.isInt32()) return v1.asInt32() < v2.asInt32(); @@ -247,6 +284,7 @@ namespace JSC { ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2) { +<<<<<<< HEAD double left; double right = 0.0; @@ -271,13 +309,23 @@ namespace JSC { if (!value) return throwOutOfMemoryError(callFrame); return jsString(callFrame, value.release()); +======= + double left = 0.0, right; + if (v1.getNumber(left) && v2.getNumber(right)) + return jsNumber(callFrame, left + right); + + if (v1.isString()) { + return v2.isString() + ? jsString(callFrame, asString(v1), asString(v2)) + : jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame)); +>>>>>>> webkit.org at r54127 } // All other cases are pretty uncommon return jsAddSlowCase(callFrame, v1, v2); } - inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase) + inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, size_t& slotOffset) { JSCell* cell = asCell(base); size_t count = 0; @@ -295,8 +343,11 @@ namespace JSC { // Since we're accessing a prototype in a loop, it's a good bet that it // should not be treated as a dictionary. - if (cell->structure()->isDictionary()) + if (cell->structure()->isDictionary()) { asObject(cell)->flattenDictionaryObject(); + if (slotBase == cell) + slotOffset = cell->structure()->get(propertyName); + } ++count; } diff --git a/JavaScriptCore/runtime/PropertyNameArray.cpp b/JavaScriptCore/runtime/PropertyNameArray.cpp index c28b6a4..5108272 100644 --- a/JavaScriptCore/runtime/PropertyNameArray.cpp +++ b/JavaScriptCore/runtime/PropertyNameArray.cpp @@ -30,7 +30,7 @@ static const size_t setThreshold = 20; void PropertyNameArray::add(UString::Rep* identifier) { - ASSERT(identifier == &UString::Rep::null() || identifier == &UString::Rep::empty() || identifier->identifierTable()); + ASSERT(identifier == &UString::Rep::null() || identifier == &UString::Rep::empty() || identifier->isIdentifier()); size_t size = m_data->propertyNameVector().size(); if (size < setThreshold) { diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp index 7dd4a8f..4e958f4 100644 --- a/JavaScriptCore/runtime/RegExp.cpp +++ b/JavaScriptCore/runtime/RegExp.cpp @@ -65,7 +65,6 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern) inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags) : m_pattern(pattern) - , m_flags(flags) , m_flagBits(0) , m_constructionError(0) , m_numSubpatterns(0) diff --git a/JavaScriptCore/runtime/RegExp.h b/JavaScriptCore/runtime/RegExp.h index 24d4199..61ab0bc 100644 --- a/JavaScriptCore/runtime/RegExp.h +++ b/JavaScriptCore/runtime/RegExp.h @@ -49,7 +49,6 @@ namespace JSC { bool multiline() const { return m_flagBits & Multiline; } const UString& pattern() const { return m_pattern; } - const UString& flags() const { return m_flags; } bool isValid() const { return !m_constructionError; } const char* errorMessage() const { return m_constructionError; } @@ -66,7 +65,6 @@ namespace JSC { enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 }; UString m_pattern; // FIXME: Just decompile m_regExp instead of storing this. - UString m_flags; // FIXME: Just decompile m_regExp instead of storing this. int m_flagBits; const char* m_constructionError; unsigned m_numSubpatterns; diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp index e5c6909..6f00142 100644 --- a/JavaScriptCore/runtime/RegExpConstructor.cpp +++ b/JavaScriptCore/runtime/RegExpConstructor.cpp @@ -302,7 +302,7 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args) RefPtr<RegExp> regExp = RegExp::create(&exec->globalData(), pattern, flags); if (!regExp->isValid()) - return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage())); + return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage())); return new (exec) RegExpObject(exec->lexicalGlobalObject()->regExpStructure(), regExp.release()); } diff --git a/JavaScriptCore/runtime/RegExpConstructor.h b/JavaScriptCore/runtime/RegExpConstructor.h index f9ca9cf..8f4be71 100644 --- a/JavaScriptCore/runtime/RegExpConstructor.h +++ b/JavaScriptCore/runtime/RegExpConstructor.h @@ -59,7 +59,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&); diff --git a/JavaScriptCore/runtime/RegExpMatchesArray.h b/JavaScriptCore/runtime/RegExpMatchesArray.h index 829f7cf..38d3cb4 100644 --- a/JavaScriptCore/runtime/RegExpMatchesArray.h +++ b/JavaScriptCore/runtime/RegExpMatchesArray.h @@ -79,11 +79,11 @@ namespace JSC { return JSArray::deleteProperty(exec, propertyName); } - virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr) + virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties) { if (lazyCreationData()) fillArrayInstance(exec); - JSArray::getOwnPropertyNames(exec, arr); + JSArray::getOwnPropertyNames(exec, arr, mode); } void fillArrayInstance(ExecState*); diff --git a/JavaScriptCore/runtime/RegExpObject.cpp b/JavaScriptCore/runtime/RegExpObject.cpp index 679d072..42bfcef 100644 --- a/JavaScriptCore/runtime/RegExpObject.cpp +++ b/JavaScriptCore/runtime/RegExpObject.cpp @@ -142,7 +142,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args) UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec); if (input.isNull()) { - throwError(exec, GeneralError, "No input to " + toString(exec) + "."); + throwError(exec, GeneralError, makeString("No input to ", toString(exec), ".")); return false; } diff --git a/JavaScriptCore/runtime/RegExpObject.h b/JavaScriptCore/runtime/RegExpObject.h index 3117c86..4ad11ef 100644 --- a/JavaScriptCore/runtime/RegExpObject.h +++ b/JavaScriptCore/runtime/RegExpObject.h @@ -49,7 +49,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/runtime/RegExpPrototype.cpp b/JavaScriptCore/runtime/RegExpPrototype.cpp index bbc9e85..5f9d357 100644 --- a/JavaScriptCore/runtime/RegExpPrototype.cpp +++ b/JavaScriptCore/runtime/RegExpPrototype.cpp @@ -91,7 +91,7 @@ JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue } if (!regExp->isValid()) - return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage())); + return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage())); asRegExpObject(thisValue)->setRegExp(regExp.release()); asRegExpObject(thisValue)->setLastIndex(0); @@ -106,15 +106,17 @@ JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValu return throwError(exec, TypeError); } - UString result = "/" + asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec); - result.append('/'); + char postfix[5] = { '/', 0, 0, 0, 0 }; + int index = 1; if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec)) - result.append('g'); + postfix[index++] = 'g'; if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec)) - result.append('i'); + postfix[index++] = 'i'; if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec)) - result.append('m'); - return jsNontrivialString(exec, result); + postfix[index] = 'm'; + UString source = asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec); + // If source is empty, use "/(?:)/" to avoid colliding with comment syntax + return jsNontrivialString(exec, makeString("/", source.size() ? source : UString("(?:)"), postfix)); } } // namespace JSC diff --git a/JavaScriptCore/runtime/SmallStrings.cpp b/JavaScriptCore/runtime/SmallStrings.cpp index 04701cb..ac71735 100644 --- a/JavaScriptCore/runtime/SmallStrings.cpp +++ b/JavaScriptCore/runtime/SmallStrings.cpp @@ -41,30 +41,16 @@ public: UString::Rep* rep(unsigned char character) { return &m_reps[character]; } private: - UChar m_characters[numCharactersToStore]; - UString::BaseString m_base; UString::Rep m_reps[numCharactersToStore]; }; SmallStringsStorage::SmallStringsStorage() - : m_base(m_characters, numCharactersToStore) { - m_base.rc = numCharactersToStore + 1; - // make sure UString doesn't try to reuse the buffer by pretending we have one more character in it - m_base.usedCapacity = numCharactersToStore + 1; - m_base.capacity = numCharactersToStore + 1; - m_base.checkConsistency(); - - for (unsigned i = 0; i < numCharactersToStore; ++i) - m_characters[i] = i; - - memset(&m_reps, 0, sizeof(m_reps)); + UChar* characterBuffer = 0; + RefPtr<UStringImpl> baseString = UStringImpl::createUninitialized(numCharactersToStore, characterBuffer); for (unsigned i = 0; i < numCharactersToStore; ++i) { - m_reps[i].offset = i; - m_reps[i].len = 1; - m_reps[i].rc = 1; - m_reps[i].setBaseString(&m_base); - m_reps[i].checkConsistency(); + characterBuffer[i] = i; + new (&m_reps[i]) UString::Rep(&characterBuffer[i], 1, PassRefPtr<UStringImpl>(baseString)); } } diff --git a/JavaScriptCore/runtime/StringBuilder.h b/JavaScriptCore/runtime/StringBuilder.h new file mode 100644 index 0000000..8e18d37 --- /dev/null +++ b/JavaScriptCore/runtime/StringBuilder.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef StringBuilder_h +#define StringBuilder_h + +#include <wtf/Vector.h> + +namespace JSC { + +class StringBuilder { +public: + void append(const UChar u) + { + buffer.append(u); + } + + void append(const char* str) + { + buffer.append(str, strlen(str)); + } + + void append(const char* str, size_t len) + { + buffer.reserveCapacity(buffer.size() + len); + for (size_t i = 0; i < len; i++) + buffer.append(static_cast<unsigned char>(str[i])); + } + + void append(const UChar* str, size_t len) + { + buffer.append(str, len); + } + + void append(const UString& str) + { + buffer.append(str.data(), str.size()); + } + + bool isEmpty() { return buffer.isEmpty(); } + void reserveCapacity(size_t newCapacity) { buffer.reserveCapacity(newCapacity); } + void resize(size_t size) { buffer.resize(size); } + size_t size() const { return buffer.size(); } + + UChar operator[](size_t i) const { return buffer.at(i); } + + UString release() + { + buffer.shrinkToFit(); + return UString::adopt(buffer); + } + +private: + Vector<UChar, 64> buffer; +}; + +} + +#endif diff --git a/JavaScriptCore/runtime/StringConstructor.cpp b/JavaScriptCore/runtime/StringConstructor.cpp index 2f3adbe..c7b62bf 100644 --- a/JavaScriptCore/runtime/StringConstructor.cpp +++ b/JavaScriptCore/runtime/StringConstructor.cpp @@ -30,12 +30,12 @@ namespace JSC { static NEVER_INLINE JSValue stringFromCharCodeSlowCase(ExecState* exec, const ArgList& args) { - UChar* buf = static_cast<UChar*>(fastMalloc(args.size() * sizeof(UChar))); - UChar* p = buf; - ArgList::const_iterator end = args.end(); - for (ArgList::const_iterator it = args.begin(); it != end; ++it) - *p++ = static_cast<UChar>((*it).toUInt32(exec)); - return jsString(exec, UString(buf, p - buf, false)); + unsigned length = args.size(); + UChar* buf; + PassRefPtr<UStringImpl> impl = UStringImpl::createUninitialized(length, buf); + for (unsigned i = 0; i < length; ++i) + buf[i] = static_cast<UChar>(args.at(i).toUInt32(exec)); + return jsString(exec, impl); } static JSValue JSC_HOST_CALL stringFromCharCode(ExecState* exec, JSObject*, JSValue, const ArgList& args) diff --git a/JavaScriptCore/runtime/StringObject.cpp b/JavaScriptCore/runtime/StringObject.cpp index f23a20d..f8e0e87 100644 --- a/JavaScriptCore/runtime/StringObject.cpp +++ b/JavaScriptCore/runtime/StringObject.cpp @@ -86,12 +86,14 @@ bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyNam return JSObject::deleteProperty(exec, propertyName); } -void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames) +void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { int size = internalValue()->length(); for (int i = 0; i < size; ++i) propertyNames.add(Identifier(exec, UString::from(i))); - return JSObject::getOwnPropertyNames(exec, propertyNames); + if (mode == IncludeDontEnumProperties) + propertyNames.add(exec->propertyNames().length); + return JSObject::getOwnPropertyNames(exec, propertyNames, mode); } } // namespace JSC diff --git a/JavaScriptCore/runtime/StringObject.h b/JavaScriptCore/runtime/StringObject.h index 84e1ad2..e3add77 100644 --- a/JavaScriptCore/runtime/StringObject.h +++ b/JavaScriptCore/runtime/StringObject.h @@ -39,7 +39,7 @@ namespace JSC { virtual void put(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&); virtual bool deleteProperty(ExecState*, const Identifier& propertyName); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&); + virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); virtual const ClassInfo* classInfo() const { return &info; } static const JS_EXPORTDATA ClassInfo info; @@ -48,7 +48,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue prototype) { - return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } protected: diff --git a/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h b/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h index 69e1939..43c3e38 100644 --- a/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h +++ b/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h @@ -44,7 +44,7 @@ namespace JSC { static PassRefPtr<Structure> createStructure(JSValue proto) { - return Structure::create(proto, TypeInfo(ObjectType, StructureFlags)); + return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount); } static const unsigned StructureFlags = OverridesGetOwnPropertySlot | MasqueradesAsUndefined | OverridesGetPropertyNames | StringObject::StructureFlags; diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp index 32f9e6b..d002e07 100644 --- a/JavaScriptCore/runtime/StringPrototype.cpp +++ b/JavaScriptCore/runtime/StringPrototype.cpp @@ -29,6 +29,7 @@ #include "JSArray.h" #include "JSFunction.h" #include "ObjectPrototype.h" +#include "Operations.h" #include "PropertyNameArray.h" #include "RegExpConstructor.h" #include "RegExpObject.h" @@ -148,12 +149,11 @@ bool StringPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier // ------------------------------ Functions -------------------------- -static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg) +static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, int i) { - UString substitutedReplacement; + Vector<UChar> substitutedReplacement; int offset = 0; - int i = -1; - while ((i = replacement.find('$', i + 1)) != -1) { + do { if (i + 1 == replacement.size()) break; @@ -205,15 +205,21 @@ static inline UString substituteBackreferences(const UString& replacement, const i += 1 + advance; offset = i + 1; substitutedReplacement.append(source.data() + backrefStart, backrefLength); - } - - if (!offset) - return replacement; + } while ((i = replacement.find('$', i + 1)) != -1); if (replacement.size() - offset) substitutedReplacement.append(replacement.data() + offset, replacement.size() - offset); - return substitutedReplacement; + substitutedReplacement.shrinkToFit(); + return UString::adopt(substitutedReplacement); +} + +static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg) +{ + int i = replacement.find('$', 0); + if (UNLIKELY(i != -1)) + return substituteBackreferencesSlow(replacement, source, ovector, reg, i); + return replacement; } static inline int localeCompare(const UString& a, const UString& b) @@ -423,12 +429,14 @@ JSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSVa JSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { - UString s = thisValue.toThisString(exec); + if (thisValue.isString() && (args.size() == 1)) { + JSValue v = args.at(0); + return v.isString() + ? jsString(exec, asString(thisValue), asString(v)) + : jsString(exec, asString(thisValue), v.toString(exec)); + } - ArgList::const_iterator end = args.end(); - for (ArgList::const_iterator it = args.begin(); it != end; ++it) - s += (*it).toString(exec); - return jsString(exec, s); + return jsString(exec, thisValue, args); } JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -470,7 +478,7 @@ JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSV dpos = 0; else if (!(dpos <= len)) // true for NaN dpos = len; -#if PLATFORM(SYMBIAN) +#if OS(SYMBIAN) // Work around for broken NaN compare operator else if (isnan(dpos)) dpos = len; @@ -713,7 +721,7 @@ JSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSV buffer[i] = toASCIILower(c); } if (!(ored & ~0x7f)) - return jsString(exec, UString(buffer.releaseBuffer(), sSize, false)); + return jsString(exec, UString::adopt(buffer)); bool error; int length = Unicode::toLower(buffer.data(), sSize, sData, sSize, &error); @@ -723,9 +731,12 @@ JSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSV if (error) return sVal; } - if (length == sSize && memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0) - return sVal; - return jsString(exec, UString(buffer.releaseBuffer(), length, false)); + if (length == sSize) { + if (memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0) + return sVal; + } else + buffer.resize(length); + return jsString(exec, UString::adopt(buffer)); } JSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) @@ -747,7 +758,7 @@ JSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSV buffer[i] = toASCIIUpper(c); } if (!(ored & ~0x7f)) - return jsString(exec, UString(buffer.releaseBuffer(), sSize, false)); + return jsString(exec, UString::adopt(buffer)); bool error; int length = Unicode::toUpper(buffer.data(), sSize, sData, sSize, &error); @@ -757,9 +768,12 @@ JSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSV if (error) return sVal; } - if (length == sSize && memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0) - return sVal; - return jsString(exec, UString(buffer.releaseBuffer(), length, false)); + if (length == sSize) { + if (memcmp(buffer.data(), sData, length * sizeof(UChar)) == 0) + return sVal; + } else + buffer.resize(length); + return jsString(exec, UString::adopt(buffer)); } JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -775,62 +789,62 @@ JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, J JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { UString s = thisValue.toThisString(exec); - return jsNontrivialString(exec, "<big>" + s + "</big>"); + return jsNontrivialString(exec, makeString("<big>", s, "</big>")); } JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { UString s = thisValue.toThisString(exec); - return jsNontrivialString(exec, "<small>" + s + "</small>"); + return jsNontrivialString(exec, makeString("<small>", s, "</small>")); } JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { UString s = thisValue.toThisString(exec); - return jsNontrivialString(exec, "<blink>" + s + "</blink>"); + return jsNontrivialString(exec, makeString("<blink>", s, "</blink>")); } JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { UString s = thisValue.toThisString(exec); - return jsNontrivialString(exec, "<b>" + s + "</b>"); + return jsNontrivialString(exec, makeString("<b>", s, "</b>")); } JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { UString s = thisValue.toThisString(exec); - return jsString(exec, "<tt>" + s + "</tt>"); + return jsString(exec, makeString("<tt>", s, "</tt>")); } JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { UString s = thisValue.toThisString(exec); - return jsNontrivialString(exec, "<i>" + s + "</i>"); + return jsNontrivialString(exec, makeString("<i>", s, "</i>")); } JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { UString s = thisValue.toThisString(exec); - return jsNontrivialString(exec, "<strike>" + s + "</strike>"); + return jsNontrivialString(exec, makeString("<strike>", s, "</strike>")); } JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { UString s = thisValue.toThisString(exec); - return jsNontrivialString(exec, "<sub>" + s + "</sub>"); + return jsNontrivialString(exec, makeString("<sub>", s, "</sub>")); } JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) { UString s = thisValue.toThisString(exec); - return jsNontrivialString(exec, "<sup>" + s + "</sup>"); + return jsNontrivialString(exec, makeString("<sup>", s, "</sup>")); } JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UString s = thisValue.toThisString(exec); JSValue a0 = args.at(0); - return jsNontrivialString(exec, "<font color=\"" + a0.toString(exec) + "\">" + s + "</font>"); + return jsNontrivialString(exec, makeString("<font color=\"", a0.toString(exec), "\">", s, "</font>")); } JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -843,7 +857,8 @@ JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValu unsigned stringSize = s.size(); unsigned bufferSize = 22 + stringSize; UChar* buffer; - if (!tryFastMalloc(bufferSize * sizeof(UChar)).getValue(buffer)) + PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(bufferSize, buffer); + if (!impl) return jsUndefined(); buffer[0] = '<'; buffer[1] = 'f'; @@ -868,17 +883,17 @@ JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValu buffer[19 + stringSize] = 'n'; buffer[20 + stringSize] = 't'; buffer[21 + stringSize] = '>'; - return jsNontrivialString(exec, UString(buffer, bufferSize, false)); + return jsNontrivialString(exec, impl); } - return jsNontrivialString(exec, "<font size=\"" + a0.toString(exec) + "\">" + s + "</font>"); + return jsNontrivialString(exec, makeString("<font size=\"", a0.toString(exec), "\">", s, "</font>")); } JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) { UString s = thisValue.toThisString(exec); JSValue a0 = args.at(0); - return jsNontrivialString(exec, "<a name=\"" + a0.toString(exec) + "\">" + s + "</a>"); + return jsNontrivialString(exec, makeString("<a name=\"", a0.toString(exec), "\">", s, "</a>")); } JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) @@ -891,7 +906,8 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th unsigned stringSize = s.size(); unsigned bufferSize = 15 + linkTextSize + stringSize; UChar* buffer; - if (!tryFastMalloc(bufferSize * sizeof(UChar)).getValue(buffer)) + PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(bufferSize, buffer); + if (!impl) return jsUndefined(); buffer[0] = '<'; buffer[1] = 'a'; @@ -910,7 +926,7 @@ JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue th buffer[12 + linkTextSize + stringSize] = '/'; buffer[13 + linkTextSize + stringSize] = 'a'; buffer[14 + linkTextSize + stringSize] = '>'; - return jsNontrivialString(exec, UString(buffer, bufferSize, false)); + return jsNontrivialString(exec, impl); } enum { diff --git a/JavaScriptCore/runtime/Structure.cpp b/JavaScriptCore/runtime/Structure.cpp index e4c9ac3..77330aa 100644 --- a/JavaScriptCore/runtime/Structure.cpp +++ b/JavaScriptCore/runtime/Structure.cpp @@ -134,6 +134,7 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo) , m_isPinnedPropertyTable(false) , m_hasGetterSetterProperties(false) , m_attributesInPrevious(0) + , m_specificFunctionThrashCount(0) { ASSERT(m_prototype); ASSERT(m_prototype.isObject() || m_prototype.isNull()); @@ -156,10 +157,8 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo) Structure::~Structure() { if (m_previous) { - if (m_nameInPrevious) - m_previous->table.remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious); - else - m_previous->table.removeAnonymousSlotTransition(m_anonymousSlotsInPrevious); + ASSERT(m_nameInPrevious); + m_previous->table.remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious); } @@ -275,10 +274,6 @@ void Structure::materializePropertyMap() for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) { structure = structures[i]; - if (!structure->m_nameInPrevious) { - m_propertyTable->anonymousSlotCount += structure->m_anonymousSlotsInPrevious; - continue; - } structure->m_nameInPrevious->ref(); PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious, ++m_propertyTable->lastIndexUsed); insertIntoPropertyMapHashTable(entry); @@ -302,7 +297,7 @@ void Structure::despecifyDictionaryFunction(const Identifier& propertyName) ASSERT(isDictionary()); ASSERT(m_propertyTable); - unsigned i = rep->computedHash(); + unsigned i = rep->existingHash(); #if DUMP_PROPERTYMAP_STATS ++numProbes; @@ -320,7 +315,7 @@ void Structure::despecifyDictionaryFunction(const Identifier& propertyName) ++numCollisions; #endif - unsigned k = 1 | doubleHash(rep->computedHash()); + unsigned k = 1 | doubleHash(rep->existingHash()); while (1) { i += k; @@ -358,6 +353,9 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con ASSERT(!structure->isDictionary()); ASSERT(structure->typeInfo().type() == ObjectType); ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset)); + + if (structure->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount) + specificValue = 0; if (structure->transitionCount() > s_maxTransitionLength) { RefPtr<Structure> transition = toCacheableDictionaryTransition(structure); @@ -378,6 +376,7 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; + transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount; if (structure->m_propertyTable) { if (structure->m_isPinnedPropertyTable) @@ -421,6 +420,7 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; + transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount; // Don't set m_offset, as one can not transition to this. @@ -433,11 +433,13 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structure, const Identifier& replaceFunction) { + ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount); RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo()); transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; + transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount + 1; // Don't set m_offset, as one can not transition to this. @@ -445,52 +447,14 @@ PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structur transition->m_propertyTable = structure->copyPropertyTable(); transition->m_isPinnedPropertyTable = true; - bool removed = transition->despecifyFunction(replaceFunction); - ASSERT_UNUSED(removed, removed); - - return transition.release(); -} - -PassRefPtr<Structure> Structure::addAnonymousSlotsTransition(Structure* structure, unsigned count) -{ - if (Structure* transition = structure->table.getAnonymousSlotTransition(count)) { - ASSERT(transition->storedPrototype() == structure->storedPrototype()); - return transition; - } - ASSERT(count); - ASSERT(count < ((1<<6) - 2)); - RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo()); - - transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain; - transition->m_previous = structure; - transition->m_nameInPrevious = 0; - transition->m_attributesInPrevious = 0; - transition->m_anonymousSlotsInPrevious = count; - transition->m_specificValueInPrevious = 0; - transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; - transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; - transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; - - if (structure->m_propertyTable) { - if (structure->m_isPinnedPropertyTable) - transition->m_propertyTable = structure->copyPropertyTable(); - else { - transition->m_propertyTable = structure->m_propertyTable; - structure->m_propertyTable = 0; - } - } else { - if (structure->m_previous) - transition->materializePropertyMap(); - else - transition->createPropertyMapHashTable(); + if (transition->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount) + transition->despecifyAllFunctions(); + else { + bool removed = transition->despecifyFunction(replaceFunction); + ASSERT_UNUSED(removed, removed); } - transition->addAnonymousSlots(count); - if (transition->propertyStorageSize() > transition->propertyStorageCapacity()) - transition->growPropertyStorageCapacity(); - - structure->table.addAnonymousSlotTransition(count, transition.get()); - return transition.release(); + return transition.release(); } PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure) @@ -499,6 +463,7 @@ PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure) transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties; transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; + transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount; // Don't set m_offset, as one can not transition to this. @@ -518,6 +483,7 @@ PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, Di transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity; transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties; transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties; + transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount; structure->materializePropertyMapIfNecessary(); transition->m_propertyTable = structure->copyPropertyTable(); @@ -582,6 +548,10 @@ PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSObject* object) size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) { ASSERT(!m_enumerationCache); + + if (m_specificFunctionThrashCount == maxSpecificFunctionThrashCount) + specificValue = 0; + materializePropertyMapIfNecessary(); m_isPinnedPropertyTable = true; @@ -667,7 +637,7 @@ size_t Structure::get(const UString::Rep* rep, unsigned& attributes, JSCell*& sp if (!m_propertyTable) return notFound; - unsigned i = rep->computedHash(); + unsigned i = rep->existingHash(); #if DUMP_PROPERTYMAP_STATS ++numProbes; @@ -687,7 +657,7 @@ size_t Structure::get(const UString::Rep* rep, unsigned& attributes, JSCell*& sp ++numCollisions; #endif - unsigned k = 1 | doubleHash(rep->computedHash()); + unsigned k = 1 | doubleHash(rep->existingHash()); while (1) { i += k; @@ -718,7 +688,7 @@ bool Structure::despecifyFunction(const Identifier& propertyName) UString::Rep* rep = propertyName._ustring.rep(); - unsigned i = rep->computedHash(); + unsigned i = rep->existingHash(); #if DUMP_PROPERTYMAP_STATS ++numProbes; @@ -738,7 +708,7 @@ bool Structure::despecifyFunction(const Identifier& propertyName) ++numCollisions; #endif - unsigned k = 1 | doubleHash(rep->computedHash()); + unsigned k = 1 | doubleHash(rep->existingHash()); while (1) { i += k; @@ -759,6 +729,17 @@ bool Structure::despecifyFunction(const Identifier& propertyName) } } +void Structure::despecifyAllFunctions() +{ + materializePropertyMapIfNecessary(); + if (!m_propertyTable) + return; + + unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; + for (unsigned i = 1; i <= entryCount; ++i) + m_propertyTable->entries()[i].specificValue = 0; +} + size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) { ASSERT(!propertyName.isNull()); @@ -776,7 +757,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel // FIXME: Consider a fast case for tables with no deleted sentinels. - unsigned i = rep->computedHash(); + unsigned i = rep->existingHash(); unsigned k = 0; bool foundDeletedElement = false; unsigned deletedElementIndex = 0; // initialize to make the compiler happy @@ -799,7 +780,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel } if (k == 0) { - k = 1 | doubleHash(rep->computedHash()); + k = 1 | doubleHash(rep->existingHash()); #if DUMP_PROPERTYMAP_STATS ++numCollisions; #endif @@ -852,11 +833,6 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel return newOffset; } -void Structure::addAnonymousSlots(unsigned count) -{ - m_propertyTable->anonymousSlotCount += count; -} - bool Structure::hasTransition(UString::Rep* rep, unsigned attributes) { return table.hasTransition(make_pair(rep, attributes)); @@ -879,7 +855,7 @@ size_t Structure::remove(const Identifier& propertyName) #endif // Find the thing to remove. - unsigned i = rep->computedHash(); + unsigned i = rep->existingHash(); unsigned k = 0; unsigned entryIndex; UString::Rep* key = 0; @@ -893,7 +869,7 @@ size_t Structure::remove(const Identifier& propertyName) break; if (k == 0) { - k = 1 | doubleHash(rep->computedHash()); + k = 1 | doubleHash(rep->existingHash()); #if DUMP_PROPERTYMAP_STATS ++numCollisions; #endif @@ -937,7 +913,7 @@ void Structure::insertIntoPropertyMapHashTable(const PropertyMapEntry& entry) { ASSERT(m_propertyTable); - unsigned i = entry.key->computedHash(); + unsigned i = entry.key->existingHash(); unsigned k = 0; #if DUMP_PROPERTYMAP_STATS @@ -950,7 +926,7 @@ void Structure::insertIntoPropertyMapHashTable(const PropertyMapEntry& entry) break; if (k == 0) { - k = 1 | doubleHash(entry.key->computedHash()); + k = 1 | doubleHash(entry.key->existingHash()); #if DUMP_PROPERTYMAP_STATS ++numCollisions; #endif @@ -1044,7 +1020,7 @@ int comparePropertyMapEntryIndices(const void* a, const void* b) return 0; } -void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames) +void Structure::getPropertyNames(PropertyNameArray& propertyNames, EnumerationMode mode) { materializePropertyMapIfNecessary(); if (!m_propertyTable) @@ -1056,7 +1032,7 @@ void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames) unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; for (unsigned k = 1; k <= entryCount; k++) { ASSERT(m_hasNonEnumerableProperties || !(m_propertyTable->entries()[k].attributes & DontEnum)); - if (m_propertyTable->entries()[k].key && !(m_propertyTable->entries()[k].attributes & DontEnum)) { + if (m_propertyTable->entries()[k].key && (!(m_propertyTable->entries()[k].attributes & DontEnum) || (mode == IncludeDontEnumProperties))) { PropertyMapEntry* value = &m_propertyTable->entries()[k]; int j; for (j = i - 1; j >= 0 && a[j]->index > value->index; --j) @@ -1083,7 +1059,7 @@ void Structure::getEnumerablePropertyNames(PropertyNameArray& propertyNames) PropertyMapEntry** p = sortedEnumerables.data(); unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount; for (unsigned i = 1; i <= entryCount; i++) { - if (m_propertyTable->entries()[i].key && !(m_propertyTable->entries()[i].attributes & DontEnum)) + if (m_propertyTable->entries()[i].key && (!(m_propertyTable->entries()[i].attributes & DontEnum) || (mode == IncludeDontEnumProperties))) *p++ = &m_propertyTable->entries()[i]; } @@ -1148,7 +1124,7 @@ void Structure::checkConsistency() if (!rep) continue; ++nonEmptyEntryCount; - unsigned i = rep->computedHash(); + unsigned i = rep->existingHash(); unsigned k = 0; unsigned entryIndex; while (1) { @@ -1157,7 +1133,7 @@ void Structure::checkConsistency() if (rep == m_propertyTable->entries()[entryIndex - 1].key) break; if (k == 0) - k = 1 | doubleHash(rep->computedHash()); + k = 1 | doubleHash(rep->existingHash()); i += k; } ASSERT(entryIndex == c + 1); diff --git a/JavaScriptCore/runtime/Structure.h b/JavaScriptCore/runtime/Structure.h index c6b7d91..f73f9b8 100644 --- a/JavaScriptCore/runtime/Structure.h +++ b/JavaScriptCore/runtime/Structure.h @@ -51,13 +51,26 @@ namespace JSC { class PropertyNameArray; class PropertyNameArrayData; + enum EnumerationMode { + ExcludeDontEnumProperties, + IncludeDontEnumProperties + }; + class Structure : public RefCounted<Structure> { public: friend class JIT; friend class StructureTransitionTable; - static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo) + static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo, unsigned anonymousSlotCount) { - return adoptRef(new Structure(prototype, typeInfo)); + Structure* structure = (new Structure(prototype, typeInfo)); + if (anonymousSlotCount) { + structure->materializePropertyMap(); + structure->m_isPinnedPropertyTable = true; + structure->m_propertyTable->anonymousSlotCount = anonymousSlotCount; + // Currently we don't allow more anonymous slots than fit in the inline capacity + ASSERT(structure->propertyStorageSize() <= structure->propertyStorageCapacity()); + } + return adoptRef(structure); } static void startIgnoringLeaks(); @@ -70,7 +83,6 @@ namespace JSC { static PassRefPtr<Structure> removePropertyTransition(Structure*, const Identifier& propertyName, size_t& offset); static PassRefPtr<Structure> changePrototypeTransition(Structure*, JSValue prototype); static PassRefPtr<Structure> despecifyFunctionTransition(Structure*, const Identifier&); - static PassRefPtr<Structure> addAnonymousSlotsTransition(Structure*, unsigned count); static PassRefPtr<Structure> getterSetterTransition(Structure*); static PassRefPtr<Structure> toCacheableDictionaryTransition(Structure*); static PassRefPtr<Structure> toUncacheableDictionaryTransition(Structure*); @@ -123,17 +135,23 @@ namespace JSC { bool hasNonEnumerableProperties() const { return m_hasNonEnumerableProperties; } bool hasAnonymousSlots() const { return m_propertyTable && m_propertyTable->anonymousSlotCount; } + unsigned anonymousSlotCount() const { return m_propertyTable ? m_propertyTable->anonymousSlotCount : 0; } bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; } - JSCell* specificValue() { return m_specificValueInPrevious; } void despecifyDictionaryFunction(const Identifier& propertyName); + void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; } void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h. JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); } - void getEnumerablePropertyNames(PropertyNameArray&); - + void getPropertyNames(PropertyNameArray&, EnumerationMode mode); + private: + static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo) + { + return adoptRef(new Structure(prototype, typeInfo)); + } + Structure(JSValue prototype, const TypeInfo&); typedef enum { @@ -145,7 +163,6 @@ namespace JSC { size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue); size_t remove(const Identifier& propertyName); - void addAnonymousSlots(unsigned slotCount); void expandPropertyMapHashTable(); void rehashPropertyMapHashTable(); @@ -156,6 +173,7 @@ namespace JSC { void checkConsistency(); bool despecifyFunction(const Identifier&); + void despecifyAllFunctions(); PropertyMapHashTable* copyPropertyTable(); void materializePropertyMap(); @@ -180,6 +198,8 @@ namespace JSC { static const signed char noOffset = -1; + static const unsigned maxSpecificFunctionThrashCount = 3; + TypeInfo m_typeInfo; JSValue m_prototype; @@ -210,7 +230,8 @@ namespace JSC { #else unsigned m_attributesInPrevious : 7; #endif - unsigned m_anonymousSlotsInPrevious : 6; + unsigned m_specificFunctionThrashCount : 2; + // 10 free bits }; inline size_t Structure::get(const Identifier& propertyName) @@ -223,7 +244,7 @@ namespace JSC { UString::Rep* rep = propertyName._ustring.rep(); - unsigned i = rep->computedHash(); + unsigned i = rep->existingHash(); #if DUMP_PROPERTYMAP_STATS ++numProbes; @@ -240,7 +261,7 @@ namespace JSC { ++numCollisions; #endif - unsigned k = 1 | WTF::doubleHash(rep->computedHash()); + unsigned k = 1 | WTF::doubleHash(rep->existingHash()); while (1) { i += k; diff --git a/JavaScriptCore/runtime/StructureTransitionTable.h b/JavaScriptCore/runtime/StructureTransitionTable.h index 0fa7b73..320dbdd 100644 --- a/JavaScriptCore/runtime/StructureTransitionTable.h +++ b/JavaScriptCore/runtime/StructureTransitionTable.h @@ -42,7 +42,7 @@ namespace JSC { typedef std::pair<RefPtr<UString::Rep>, unsigned> Key; static unsigned hash(const Key& p) { - return p.first->computedHash(); + return p.first->existingHash(); } static bool equal(const Key& a, const Key& b) @@ -69,36 +69,7 @@ namespace JSC { class StructureTransitionTable { typedef std::pair<Structure*, Structure*> Transition; - struct TransitionTable : public HashMap<StructureTransitionTableHash::Key, Transition, StructureTransitionTableHash, StructureTransitionTableHashTraits> { - typedef HashMap<unsigned, Structure*> AnonymousSlotMap; - - void addSlotTransition(unsigned count, Structure* structure) - { - ASSERT(!getSlotTransition(count)); - if (!m_anonymousSlotTable) - m_anonymousSlotTable.set(new AnonymousSlotMap); - m_anonymousSlotTable->add(count, structure); - } - - void removeSlotTransition(unsigned count) - { - ASSERT(getSlotTransition(count)); - m_anonymousSlotTable->remove(count); - } - - Structure* getSlotTransition(unsigned count) - { - if (!m_anonymousSlotTable) - return 0; - - AnonymousSlotMap::iterator find = m_anonymousSlotTable->find(count); - if (find == m_anonymousSlotTable->end()) - return 0; - return find->second; - } - private: - OwnPtr<AnonymousSlotMap> m_anonymousSlotTable; - }; + typedef HashMap<StructureTransitionTableHash::Key, Transition, StructureTransitionTableHash, StructureTransitionTableHashTraits> TransitionTable; public: StructureTransitionTable() { m_transitions.m_singleTransition.set(0); @@ -154,26 +125,6 @@ namespace JSC { } } - Structure* getAnonymousSlotTransition(unsigned count) - { - if (usingSingleTransitionSlot()) - return 0; - return table()->getSlotTransition(count); - } - - void addAnonymousSlotTransition(unsigned count, Structure* structure) - { - if (usingSingleTransitionSlot()) - reifySingleTransition(); - ASSERT(!table()->getSlotTransition(count)); - table()->addSlotTransition(count, structure); - } - - void removeAnonymousSlotTransition(unsigned count) - { - ASSERT(!usingSingleTransitionSlot()); - table()->removeSlotTransition(count); - } private: TransitionTable* table() const { ASSERT(!usingSingleTransitionSlot()); return m_transitions.m_table; } Structure* singleTransition() const { diff --git a/JavaScriptCore/runtime/TimeoutChecker.cpp b/JavaScriptCore/runtime/TimeoutChecker.cpp index 2a056c9..250fdaf 100644 --- a/JavaScriptCore/runtime/TimeoutChecker.cpp +++ b/JavaScriptCore/runtime/TimeoutChecker.cpp @@ -33,14 +33,18 @@ #include "CallFrame.h" #include "JSGlobalObject.h" -#if PLATFORM(DARWIN) +#if OS(DARWIN) #include <mach/mach.h> -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) #include <windows.h> #else #include "CurrentTime.h" #endif +#if PLATFORM(BREWMP) +#include <AEEStdLib.h> +#endif + using namespace std; namespace JSC { @@ -54,7 +58,7 @@ static const int intervalBetweenChecks = 1000; // Returns the time the current thread has spent executing, in milliseconds. static inline unsigned getCPUTime() { -#if PLATFORM(DARWIN) +#if OS(DARWIN) mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT; thread_basic_info_data_t info; @@ -67,7 +71,7 @@ static inline unsigned getCPUTime() time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000; return time; -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) union { FILETIME fileTime; unsigned long long fileTimeAsLong; @@ -80,6 +84,11 @@ static inline unsigned getCPUTime() GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime); return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000; +#elif PLATFORM(BREWMP) + // This function returns a continuously and linearly increasing millisecond + // timer from the time the device was powered on. + // There is only one thread in BREW, so this is enough. + return GETUPTIMEMS(); #else // FIXME: We should return the time the current thread has spent executing. return currentTime() * 1000; diff --git a/JavaScriptCore/runtime/Tracing.d b/JavaScriptCore/runtime/Tracing.d index b9efaff..da854b9 100644 --- a/JavaScriptCore/runtime/Tracing.d +++ b/JavaScriptCore/runtime/Tracing.d @@ -27,7 +27,7 @@ provider JavaScriptCore { probe gc__begin(); probe gc__marked(); - probe gc__end(int, int); + probe gc__end(); probe profile__will_execute(int, char*, char*, int); probe profile__did_execute(int, char*, char*, int); diff --git a/JavaScriptCore/runtime/Tracing.h b/JavaScriptCore/runtime/Tracing.h index e544f66..c28c85f 100644 --- a/JavaScriptCore/runtime/Tracing.h +++ b/JavaScriptCore/runtime/Tracing.h @@ -33,7 +33,7 @@ #define JAVASCRIPTCORE_GC_BEGIN() #define JAVASCRIPTCORE_GC_BEGIN_ENABLED() 0 -#define JAVASCRIPTCORE_GC_END(arg0, arg1) +#define JAVASCRIPTCORE_GC_END() #define JAVASCRIPTCORE_GC_END_ENABLED() 0 #define JAVASCRIPTCORE_GC_MARKED() diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp index 50d23c4..e75a05c 100644 --- a/JavaScriptCore/runtime/UString.cpp +++ b/JavaScriptCore/runtime/UString.cpp @@ -52,52 +52,11 @@ using namespace WTF; using namespace WTF::Unicode; using namespace std; -// This can be tuned differently per platform by putting platform #ifs right here. -// If you don't define this macro at all, then copyChars will just call directly -// to memcpy. -#define USTRING_COPY_CHARS_INLINE_CUTOFF 20 - namespace JSC { extern const double NaN; extern const double Inf; -// This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings. -static const int minLengthToShare = 10; - -static inline size_t overflowIndicator() { return std::numeric_limits<size_t>::max(); } -static inline size_t maxUChars() { return std::numeric_limits<size_t>::max() / sizeof(UChar); } - -static inline PossiblyNull<UChar*> allocChars(size_t length) -{ - ASSERT(length); - if (length > maxUChars()) - return 0; - return tryFastMalloc(sizeof(UChar) * length); -} - -static inline PossiblyNull<UChar*> reallocChars(UChar* buffer, size_t length) -{ - ASSERT(length); - if (length > maxUChars()) - return 0; - return tryFastRealloc(buffer, sizeof(UChar) * length); -} - -static inline void copyChars(UChar* destination, const UChar* source, unsigned numCharacters) -{ -#ifdef USTRING_COPY_CHARS_INLINE_CUTOFF - if (numCharacters <= USTRING_COPY_CHARS_INLINE_CUTOFF) { - for (unsigned i = 0; i < numCharacters; ++i) - destination[i] = source[i]; - return; - } -#endif - memcpy(destination, source, numCharacters * sizeof(UChar)); -} - -COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes); - CString::CString(const char* c) : m_length(strlen(c)) , m_data(new char[m_length + 1]) @@ -190,371 +149,17 @@ bool operator==(const CString& c1, const CString& c2) // These static strings are immutable, except for rc, whose initial value is chosen to // reduce the possibility of it becoming zero due to ref/deref not being thread-safe. static UChar sharedEmptyChar; -UString::BaseString* UString::Rep::nullBaseString; -UString::BaseString* UString::Rep::emptyBaseString; +UStringImpl* UStringImpl::s_null; +UStringImpl* UStringImpl::s_empty; UString* UString::nullUString; -static void initializeStaticBaseString(UString::BaseString& base) -{ - base.rc = INT_MAX / 2; - base.m_identifierTableAndFlags.setFlag(UString::Rep::StaticFlag); - base.checkConsistency(); -} - void initializeUString() { - UString::Rep::nullBaseString = new UString::BaseString(0, 0); - initializeStaticBaseString(*UString::Rep::nullBaseString); - - UString::Rep::emptyBaseString = new UString::BaseString(&sharedEmptyChar, 0); - initializeStaticBaseString(*UString::Rep::emptyBaseString); - + UStringImpl::s_null = new UStringImpl(0, 0, UStringImpl::ConstructStaticString); + UStringImpl::s_empty = new UStringImpl(&sharedEmptyChar, 0, UStringImpl::ConstructStaticString); UString::nullUString = new UString; } -static char* statBuffer = 0; // Only used for debugging via UString::ascii(). - -PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar* d, int l) -{ - UChar* copyD = static_cast<UChar*>(fastMalloc(l * sizeof(UChar))); - copyChars(copyD, d, l); - return create(copyD, l); -} - -PassRefPtr<UString::Rep> UString::Rep::createFromUTF8(const char* string) -{ - if (!string) - return &UString::Rep::null(); - - size_t length = strlen(string); - Vector<UChar, 1024> buffer(length); - UChar* p = buffer.data(); - if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length)) - return &UString::Rep::null(); - - return UString::Rep::createCopying(buffer.data(), p - buffer.data()); -} - -PassRefPtr<UString::Rep> UString::Rep::create(UChar* string, int length, PassRefPtr<UString::SharedUChar> sharedBuffer) -{ - PassRefPtr<UString::Rep> rep = create(string, length); - rep->baseString()->setSharedBuffer(sharedBuffer); - rep->checkConsistency(); - return rep; -} - -UString::SharedUChar* UString::Rep::sharedBuffer() -{ - UString::BaseString* base = baseString(); - if (len < minLengthToShare) - return 0; - - return base->sharedBuffer(); -} - -void UString::Rep::destroy() -{ - checkConsistency(); - - // Static null and empty strings can never be destroyed, but we cannot rely on - // reference counting, because ref/deref are not thread-safe. - if (!isStatic()) { - if (identifierTable()) - Identifier::remove(this); - - UString::BaseString* base = baseString(); - if (base == this) { - if (m_sharedBuffer) - m_sharedBuffer->deref(); - else - fastFree(base->buf); - } else - base->deref(); - - delete this; - } -} - -// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's -// or anything like that. -const unsigned PHI = 0x9e3779b9U; - -// Paul Hsieh's SuperFastHash -// http://www.azillionmonkeys.com/qed/hash.html -unsigned UString::Rep::computeHash(const UChar* s, int len) -{ - unsigned l = len; - uint32_t hash = PHI; - uint32_t tmp; - - int rem = l & 1; - l >>= 1; - - // Main loop - for (; l > 0; l--) { - hash += s[0]; - tmp = (s[1] << 11) ^ hash; - hash = (hash << 16) ^ tmp; - s += 2; - hash += hash >> 11; - } - - // Handle end case - if (rem) { - hash += s[0]; - hash ^= hash << 11; - hash += hash >> 17; - } - - // Force "avalanching" of final 127 bits - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 2; - hash += hash >> 15; - hash ^= hash << 10; - - // 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; - - return hash; -} - -// Paul Hsieh's SuperFastHash -// http://www.azillionmonkeys.com/qed/hash.html -unsigned UString::Rep::computeHash(const char* s, int l) -{ - // This hash is designed to work on 16-bit chunks at a time. But since the normal case - // (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they - // were 16-bit chunks, which should give matching results - - uint32_t hash = PHI; - uint32_t tmp; - - size_t rem = l & 1; - l >>= 1; - - // Main loop - for (; l > 0; l--) { - hash += static_cast<unsigned char>(s[0]); - tmp = (static_cast<unsigned char>(s[1]) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - s += 2; - hash += hash >> 11; - } - - // Handle end case - if (rem) { - hash += static_cast<unsigned char>(s[0]); - hash ^= hash << 11; - hash += hash >> 17; - } - - // Force "avalanching" of final 127 bits - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 2; - hash += hash >> 15; - hash ^= hash << 10; - - // 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; - - return hash; -} - -#ifndef NDEBUG -void UString::Rep::checkConsistency() const -{ - const UString::BaseString* base = baseString(); - - // There is no recursion for base strings. - ASSERT(base == base->baseString()); - - if (isStatic()) { - // There are only two static strings: null and empty. - ASSERT(!len); - - // Static strings cannot get in identifier tables, because they are globally shared. - ASSERT(!identifierTable()); - } - - // The string fits in buffer. - ASSERT(base->usedPreCapacity <= base->preCapacity); - ASSERT(base->usedCapacity <= base->capacity); - ASSERT(-offset <= base->usedPreCapacity); - ASSERT(offset + len <= base->usedCapacity); -} -#endif - -UString::SharedUChar* UString::BaseString::sharedBuffer() -{ - if (!m_sharedBuffer) - setSharedBuffer(SharedUChar::create(new OwnFastMallocPtr<UChar>(buf))); - return m_sharedBuffer; -} - -void UString::BaseString::setSharedBuffer(PassRefPtr<UString::SharedUChar> sharedBuffer) -{ - // The manual steps below are because m_sharedBuffer can't be a RefPtr. m_sharedBuffer - // is in a union with another variable to avoid making BaseString any larger. - if (m_sharedBuffer) - m_sharedBuffer->deref(); - m_sharedBuffer = sharedBuffer.releaseRef(); -} - -bool UString::BaseString::slowIsBufferReadOnly() -{ - // The buffer may not be modified as soon as the underlying data has been shared with another class. - if (m_sharedBuffer->isShared()) - return true; - - // At this point, we know it that the underlying buffer isn't shared outside of this base class, - // so get rid of m_sharedBuffer. - OwnPtr<OwnFastMallocPtr<UChar> > mallocPtr(m_sharedBuffer->release()); - UChar* unsharedBuf = const_cast<UChar*>(mallocPtr->release()); - setSharedBuffer(0); - preCapacity += (buf - unsharedBuf); - buf = unsharedBuf; - return false; -} - -// Put these early so they can be inlined. -static inline size_t expandedSize(size_t capacitySize, size_t precapacitySize) -{ - // Combine capacitySize & precapacitySize to produce a single size to allocate, - // check that doing so does not result in overflow. - size_t size = capacitySize + precapacitySize; - if (size < capacitySize) - return overflowIndicator(); - - // Small Strings (up to 4 pages): - // Expand the allocation size to 112.5% of the amount requested. This is largely sicking - // to our previous policy, however 112.5% is cheaper to calculate. - if (size < 0x4000) { - size_t expandedSize = ((size + (size >> 3)) | 15) + 1; - // Given the limited range within which we calculate the expansion in this - // fashion the above calculation should never overflow. - ASSERT(expandedSize >= size); - ASSERT(expandedSize < maxUChars()); - return expandedSize; - } - - // Medium Strings (up to 128 pages): - // For pages covering multiple pages over-allocation is less of a concern - any unused - // space will not be paged in if it is not used, so this is purely a VM overhead. For - // these strings allocate 2x the requested size. - if (size < 0x80000) { - size_t expandedSize = ((size + size) | 0xfff) + 1; - // Given the limited range within which we calculate the expansion in this - // fashion the above calculation should never overflow. - ASSERT(expandedSize >= size); - ASSERT(expandedSize < maxUChars()); - return expandedSize; - } - - // Large Strings (to infinity and beyond!): - // Revert to our 112.5% policy - probably best to limit the amount of unused VM we allow - // any individual string be responsible for. - size_t expandedSize = ((size + (size >> 3)) | 0xfff) + 1; - - // Check for overflow - any result that is at least as large as requested (but - // still below the limit) is okay. - if ((expandedSize >= size) && (expandedSize < maxUChars())) - return expandedSize; - return overflowIndicator(); -} - -static inline bool expandCapacity(UString::Rep* rep, int requiredLength) -{ - rep->checkConsistency(); - ASSERT(!rep->baseString()->isBufferReadOnly()); - - UString::BaseString* base = rep->baseString(); - - if (requiredLength > base->capacity) { - size_t newCapacity = expandedSize(requiredLength, base->preCapacity); - UChar* oldBuf = base->buf; - if (!reallocChars(base->buf, newCapacity).getValue(base->buf)) { - base->buf = oldBuf; - return false; - } - base->capacity = newCapacity - base->preCapacity; - } - if (requiredLength > base->usedCapacity) - base->usedCapacity = requiredLength; - - rep->checkConsistency(); - return true; -} - -bool UString::Rep::reserveCapacity(int capacity) -{ - // If this is an empty string there is no point 'growing' it - just allocate a new one. - // If the BaseString is shared with another string that is using more capacity than this - // string is, then growing the buffer won't help. - // If the BaseString's buffer is readonly, then it isn't allowed to grow. - UString::BaseString* base = baseString(); - if (!base->buf || !base->capacity || (offset + len) != base->usedCapacity || base->isBufferReadOnly()) - return false; - - // If there is already sufficient capacity, no need to grow! - if (capacity <= base->capacity) - return true; - - checkConsistency(); - - size_t newCapacity = expandedSize(capacity, base->preCapacity); - UChar* oldBuf = base->buf; - if (!reallocChars(base->buf, newCapacity).getValue(base->buf)) { - base->buf = oldBuf; - return false; - } - base->capacity = newCapacity - base->preCapacity; - - checkConsistency(); - return true; -} - -void UString::expandCapacity(int requiredLength) -{ - if (!JSC::expandCapacity(m_rep.get(), requiredLength)) - makeNull(); -} - -void UString::expandPreCapacity(int requiredPreCap) -{ - m_rep->checkConsistency(); - ASSERT(!m_rep->baseString()->isBufferReadOnly()); - - BaseString* base = m_rep->baseString(); - - if (requiredPreCap > base->preCapacity) { - size_t newCapacity = expandedSize(requiredPreCap, base->capacity); - int delta = newCapacity - base->capacity - base->preCapacity; - - UChar* newBuf; - if (!allocChars(newCapacity).getValue(newBuf)) { - makeNull(); - return; - } - copyChars(newBuf + delta, base->buf, base->capacity + base->preCapacity); - fastFree(base->buf); - base->buf = newBuf; - - base->preCapacity = newCapacity - base->capacity; - } - if (requiredPreCap > base->usedPreCapacity) - base->usedPreCapacity = requiredPreCap; - - m_rep->checkConsistency(); -} - static PassRefPtr<UString::Rep> createRep(const char* c) { if (!c) @@ -565,14 +170,13 @@ static PassRefPtr<UString::Rep> createRep(const char* c) size_t length = strlen(c); UChar* d; - if (!allocChars(length).getValue(d)) + PassRefPtr<UStringImpl> result = UStringImpl::tryCreateUninitialized(length, d); + if (!result) return &UString::Rep::null(); - else { - for (size_t i = 0; i < length; i++) - d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend - return UString::Rep::create(d, static_cast<int>(length)); - } + for (size_t i = 0; i < length; i++) + d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend + return result; } static inline PassRefPtr<UString::Rep> createRep(const char* c, int length) @@ -584,12 +188,13 @@ static inline PassRefPtr<UString::Rep> createRep(const char* c, int length) return &UString::Rep::empty(); UChar* d; - if (!allocChars(length).getValue(d)) + PassRefPtr<UStringImpl> result = UStringImpl::tryCreateUninitialized(length, d); + if (!result) return &UString::Rep::null(); for (int i = 0; i < length; i++) d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend - return UString::Rep::create(d, length); + return result; } UString::UString(const char* c) @@ -607,330 +212,21 @@ UString::UString(const UChar* c, int length) if (length == 0) m_rep = &Rep::empty(); else - m_rep = Rep::createCopying(c, length); -} - -UString::UString(UChar* c, int length, bool copy) -{ - if (length == 0) - m_rep = &Rep::empty(); - else if (copy) - m_rep = Rep::createCopying(c, length); - else m_rep = Rep::create(c, length); } -UString::UString(const Vector<UChar>& buffer) +UString UString::createFromUTF8(const char* string) { - if (!buffer.size()) - m_rep = &Rep::empty(); - else - m_rep = Rep::createCopying(buffer.data(), buffer.size()); -} - -static ALWAYS_INLINE int newCapacityWithOverflowCheck(const int currentCapacity, const int extendLength, const bool plusOne = false) -{ - ASSERT_WITH_MESSAGE(extendLength >= 0, "extendedLength = %d", extendLength); - - const int plusLength = plusOne ? 1 : 0; - if (currentCapacity > std::numeric_limits<int>::max() - extendLength - plusLength) - CRASH(); - - return currentCapacity + extendLength + plusLength; -} - -static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Rep> r, const UChar* tData, int tSize) -{ - RefPtr<UString::Rep> rep = r; - - rep->checkConsistency(); - - int thisSize = rep->size(); - int thisOffset = rep->offset; - int length = thisSize + tSize; - UString::BaseString* base = rep->baseString(); - - // possible cases: - if (tSize == 0) { - // t is empty - } else if (thisSize == 0) { - // this is empty - rep = UString::Rep::createCopying(tData, tSize); - } else if (rep == base && !base->isShared()) { - // this is direct and has refcount of 1 (so we can just alter it directly) - if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length))) - rep = &UString::Rep::null(); - if (rep->data()) { - copyChars(rep->data() + thisSize, tData, tSize); - rep->len = length; - rep->_hash = 0; - } - } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) { - // this reaches the end of the buffer - extend it if it's long enough to append to - if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length))) - rep = &UString::Rep::null(); - if (rep->data()) { - copyChars(rep->data() + thisSize, tData, tSize); - rep = UString::Rep::create(rep, 0, length); - } - } else { - // This is shared in some way that prevents us from modifying base, so we must make a whole new string. - size_t newCapacity = expandedSize(length, 0); - UChar* d; - if (!allocChars(newCapacity).getValue(d)) - rep = &UString::Rep::null(); - else { - copyChars(d, rep->data(), thisSize); - copyChars(d + thisSize, tData, tSize); - rep = UString::Rep::create(d, length); - rep->baseString()->capacity = newCapacity; - } - } - - rep->checkConsistency(); - - return rep.release(); -} - -static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Rep> r, const char* t) -{ - RefPtr<UString::Rep> rep = r; - - rep->checkConsistency(); - - int thisSize = rep->size(); - int thisOffset = rep->offset; - int tSize = static_cast<int>(strlen(t)); - int length = thisSize + tSize; - UString::BaseString* base = rep->baseString(); - - // possible cases: - if (thisSize == 0) { - // this is empty - rep = createRep(t); - } else if (tSize == 0) { - // t is empty, we'll just return *this below. - } else if (rep == base && !base->isShared()) { - // this is direct and has refcount of 1 (so we can just alter it directly) - expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)); - UChar* d = rep->data(); - if (d) { - for (int i = 0; i < tSize; ++i) - d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend - rep->len = length; - rep->_hash = 0; - } - } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) { - // this string reaches the end of the buffer - extend it - expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)); - UChar* d = rep->data(); - if (d) { - for (int i = 0; i < tSize; ++i) - d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend - rep = UString::Rep::create(rep, 0, length); - } - } else { - // This is shared in some way that prevents us from modifying base, so we must make a whole new string. - size_t newCapacity = expandedSize(length, 0); - UChar* d; - if (!allocChars(newCapacity).getValue(d)) - rep = &UString::Rep::null(); - else { - copyChars(d, rep->data(), thisSize); - for (int i = 0; i < tSize; ++i) - d[thisSize + i] = static_cast<unsigned char>(t[i]); // use unsigned char to zero-extend instead of sign-extend - rep = UString::Rep::create(d, length); - rep->baseString()->capacity = newCapacity; - } - } - - rep->checkConsistency(); - - return rep.release(); -} - -PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b) -{ - a->checkConsistency(); - b->checkConsistency(); - - int aSize = a->size(); - int bSize = b->size(); - int aOffset = a->offset; - - // possible cases: - - UString::BaseString* aBase = a->baseString(); - if (bSize == 1 && aOffset + aSize == aBase->usedCapacity && aOffset + aSize < aBase->capacity && !aBase->isBufferReadOnly()) { - // b is a single character (common fast case) - ++aBase->usedCapacity; - a->data()[aSize] = b->data()[0]; - return UString::Rep::create(a, 0, aSize + 1); - } - - // a is empty - if (aSize == 0) - return b; - // b is empty - if (bSize == 0) - return a; - - int bOffset = b->offset; - int length = aSize + bSize; - - UString::BaseString* bBase = b->baseString(); - if (aOffset + aSize == aBase->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize - && (-bOffset != bBase->usedPreCapacity || aSize >= bSize) && !aBase->isBufferReadOnly()) { - // - a reaches the end of its buffer so it qualifies for shared append - // - also, it's at least a quarter the length of b - appending to a much shorter - // string does more harm than good - // - however, if b qualifies for prepend and is longer than a, we'd rather prepend - - UString x(a); - x.expandCapacity(newCapacityWithOverflowCheck(aOffset, length)); - if (!a->data() || !x.data()) - return 0; - copyChars(a->data() + aSize, b->data(), bSize); - PassRefPtr<UString::Rep> result = UString::Rep::create(a, 0, length); - - a->checkConsistency(); - b->checkConsistency(); - result->checkConsistency(); - - return result; - } - - if (-bOffset == bBase->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize && !bBase->isBufferReadOnly()) { - // - b reaches the beginning of its buffer so it qualifies for shared prepend - // - also, it's at least a quarter the length of a - prepending to a much shorter - // string does more harm than good - UString y(b); - y.expandPreCapacity(-bOffset + aSize); - if (!b->data() || !y.data()) - return 0; - copyChars(b->data() - aSize, a->data(), aSize); - PassRefPtr<UString::Rep> result = UString::Rep::create(b, -aSize, length); - - a->checkConsistency(); - b->checkConsistency(); - result->checkConsistency(); - - return result; - } - - // a does not qualify for append, and b does not qualify for prepend, gotta make a whole new string - size_t newCapacity = expandedSize(length, 0); - UChar* d; - if (!allocChars(newCapacity).getValue(d)) - return 0; - copyChars(d, a->data(), aSize); - copyChars(d + aSize, b->data(), bSize); - PassRefPtr<UString::Rep> result = UString::Rep::create(d, length); - result->baseString()->capacity = newCapacity; - - a->checkConsistency(); - b->checkConsistency(); - result->checkConsistency(); - - return result; -} - -PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, int i) -{ - UChar buf[1 + sizeof(i) * 3]; - UChar* end = buf + sizeof(buf) / sizeof(UChar); - UChar* p = end; - - if (i == 0) - *--p = '0'; - else if (i == INT_MIN) { - char minBuf[1 + sizeof(i) * 3]; - sprintf(minBuf, "%d", INT_MIN); - return concatenate(rep, minBuf); - } else { - bool negative = false; - if (i < 0) { - negative = true; - i = -i; - } - while (i) { - *--p = static_cast<unsigned short>((i % 10) + '0'); - i /= 10; - } - if (negative) - *--p = '-'; - } + if (!string) + return null(); - return concatenate(rep, p, static_cast<int>(end - p)); + size_t length = strlen(string); + Vector<UChar, 1024> buffer(length); + UChar* p = buffer.data(); + if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length)) + return null(); -} - -PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d) -{ - // avoid ever printing -NaN, in JS conceptually there is only one NaN value - if (isnan(d)) - return concatenate(rep, "NaN"); - - if (d == 0.0) // stringify -0 as 0 - d = 0.0; - - char buf[80]; - int decimalPoint; - int sign; - - char result[80]; - WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL); - int length = static_cast<int>(strlen(result)); - - int i = 0; - if (sign) - buf[i++] = '-'; - - if (decimalPoint <= 0 && decimalPoint > -6) { - buf[i++] = '0'; - buf[i++] = '.'; - for (int j = decimalPoint; j < 0; j++) - buf[i++] = '0'; - strcpy(buf + i, result); - } else if (decimalPoint <= 21 && decimalPoint > 0) { - if (length <= decimalPoint) { - strcpy(buf + i, result); - i += length; - for (int j = 0; j < decimalPoint - length; j++) - buf[i++] = '0'; - buf[i] = '\0'; - } else { - strncpy(buf + i, result, decimalPoint); - i += decimalPoint; - buf[i++] = '.'; - strcpy(buf + i, result + decimalPoint); - } - } else if (result[0] < '0' || result[0] > '9') - strcpy(buf + i, result); - else { - buf[i++] = result[0]; - if (length > 1) { - buf[i++] = '.'; - strcpy(buf + i, result + 1); - i += length - 1; - } - - buf[i++] = 'e'; - buf[i++] = (decimalPoint >= 0) ? '+' : '-'; - // decimalPoint can't be more than 3 digits decimal given the - // nature of float representation - int exponential = decimalPoint - 1; - if (exponential < 0) - exponential = -exponential; - if (exponential >= 100) - buf[i++] = static_cast<char>('0' + exponential / 100); - if (exponential >= 10) - buf[i++] = static_cast<char>('0' + (exponential % 100) / 10); - buf[i++] = static_cast<char>('0' + exponential % 10); - buf[i++] = '\0'; - } - - return concatenate(rep, buf); + return UString(buffer.data(), p - buffer.data()); } UString UString::from(int i) @@ -972,7 +268,7 @@ UString UString::from(long long i) *--p = '0'; else if (i == std::numeric_limits<long long>::min()) { char minBuf[1 + sizeof(i) * 3]; -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) snprintf(minBuf, sizeof(minBuf) - 1, "%I64d", std::numeric_limits<long long>::min()); #else snprintf(minBuf, sizeof(minBuf) - 1, "%lld", std::numeric_limits<long long>::min()); @@ -1073,23 +369,24 @@ UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, in return ""; UChar* buffer; - if (!allocChars(totalLength).getValue(buffer)) + PassRefPtr<Rep> rep = Rep::tryCreateUninitialized(totalLength, buffer); + if (!rep) return null(); int maxCount = max(rangeCount, separatorCount); int bufferPos = 0; for (int i = 0; i < maxCount; i++) { if (i < rangeCount) { - copyChars(buffer + bufferPos, data() + substringRanges[i].position, substringRanges[i].length); + UStringImpl::copyChars(buffer + bufferPos, data() + substringRanges[i].position, substringRanges[i].length); bufferPos += substringRanges[i].length; } if (i < separatorCount) { - copyChars(buffer + bufferPos, separators[i].data(), separators[i].size()); + UStringImpl::copyChars(buffer + bufferPos, separators[i].data(), separators[i].size()); bufferPos += separators[i].size(); } } - return UString::Rep::create(buffer, totalLength); + return rep; } UString UString::replaceRange(int rangeStart, int rangeLength, const UString& replacement) const @@ -1102,136 +399,16 @@ UString UString::replaceRange(int rangeStart, int rangeLength, const UString& re return ""; UChar* buffer; - if (!allocChars(totalLength).getValue(buffer)) + PassRefPtr<Rep> rep = Rep::tryCreateUninitialized(totalLength, buffer); + if (!rep) return null(); - copyChars(buffer, data(), rangeStart); - copyChars(buffer + rangeStart, replacement.data(), replacementLength); + UStringImpl::copyChars(buffer, data(), rangeStart); + UStringImpl::copyChars(buffer + rangeStart, replacement.data(), replacementLength); int rangeEnd = rangeStart + rangeLength; - copyChars(buffer + rangeStart + replacementLength, data() + rangeEnd, size() - rangeEnd); - - return UString::Rep::create(buffer, totalLength); -} - - -UString& UString::append(const UString &t) -{ - m_rep->checkConsistency(); - t.rep()->checkConsistency(); - - int thisSize = size(); - int thisOffset = m_rep->offset; - int tSize = t.size(); - int length = thisSize + tSize; - BaseString* base = m_rep->baseString(); - - // possible cases: - if (thisSize == 0) { - // this is empty - *this = t; - } else if (tSize == 0) { - // t is empty - } else if (m_rep == base && !base->isShared()) { - // this is direct and has refcount of 1 (so we can just alter it directly) - expandCapacity(newCapacityWithOverflowCheck(thisOffset, length)); - if (data()) { - copyChars(m_rep->data() + thisSize, t.data(), tSize); - m_rep->len = length; - m_rep->_hash = 0; - } - } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) { - // this reaches the end of the buffer - extend it if it's long enough to append to - expandCapacity(newCapacityWithOverflowCheck(thisOffset, length)); - if (data()) { - copyChars(m_rep->data() + thisSize, t.data(), tSize); - m_rep = Rep::create(m_rep, 0, length); - } - } else { - // This is shared in some way that prevents us from modifying base, so we must make a whole new string. - size_t newCapacity = expandedSize(length, 0); - UChar* d; - if (!allocChars(newCapacity).getValue(d)) - makeNull(); - else { - copyChars(d, data(), thisSize); - copyChars(d + thisSize, t.data(), tSize); - m_rep = Rep::create(d, length); - m_rep->baseString()->capacity = newCapacity; - } - } - - m_rep->checkConsistency(); - t.rep()->checkConsistency(); + UStringImpl::copyChars(buffer + rangeStart + replacementLength, data() + rangeEnd, size() - rangeEnd); - return *this; -} - -UString& UString::append(const UChar* tData, int tSize) -{ - m_rep = concatenate(m_rep.release(), tData, tSize); - return *this; -} - -UString& UString::append(const char* t) -{ - m_rep = concatenate(m_rep.release(), t); - return *this; -} - -UString& UString::append(UChar c) -{ - m_rep->checkConsistency(); - - int thisOffset = m_rep->offset; - int length = size(); - BaseString* base = m_rep->baseString(); - - // possible cases: - if (length == 0) { - // this is empty - must make a new m_rep because we don't want to pollute the shared empty one - size_t newCapacity = expandedSize(1, 0); - UChar* d; - if (!allocChars(newCapacity).getValue(d)) - makeNull(); - else { - d[0] = c; - m_rep = Rep::create(d, 1); - m_rep->baseString()->capacity = newCapacity; - } - } else if (m_rep == base && !base->isShared()) { - // this is direct and has refcount of 1 (so we can just alter it directly) - expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true)); - UChar* d = m_rep->data(); - if (d) { - d[length] = c; - m_rep->len = length + 1; - m_rep->_hash = 0; - } - } else if (thisOffset + length == base->usedCapacity && length >= minShareSize && !base->isBufferReadOnly()) { - // this reaches the end of the string - extend it and share - expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true)); - UChar* d = m_rep->data(); - if (d) { - d[length] = c; - m_rep = Rep::create(m_rep, 0, length + 1); - } - } else { - // This is shared in some way that prevents us from modifying base, so we must make a whole new string. - size_t newCapacity = expandedSize(length + 1, 0); - UChar* d; - if (!allocChars(newCapacity).getValue(d)) - makeNull(); - else { - copyChars(d, data(), length); - d[length] = c; - m_rep = Rep::create(d, length + 1); - m_rep->baseString()->capacity = newCapacity; - } - } - - m_rep->checkConsistency(); - - return *this; + return rep; } bool UString::getCString(CStringBuffer& buffer) const @@ -1259,13 +436,15 @@ bool UString::getCString(CStringBuffer& buffer) const char* UString::ascii() const { + static char* asciiBuffer = 0; + int length = size(); int neededSize = length + 1; - delete[] statBuffer; - statBuffer = new char[neededSize]; + delete[] asciiBuffer; + asciiBuffer = new char[neededSize]; const UChar* p = data(); - char* q = statBuffer; + char* q = asciiBuffer; const UChar* limit = p + length; while (p != limit) { *q = static_cast<char>(p[0]); @@ -1274,7 +453,7 @@ char* UString::ascii() const } *q = '\0'; - return statBuffer; + return asciiBuffer; } UString& UString::operator=(const char* c) @@ -1290,21 +469,13 @@ UString& UString::operator=(const char* c) } int l = static_cast<int>(strlen(c)); - UChar* d; - BaseString* base = m_rep->baseString(); - if (!base->isShared() && l <= base->capacity && m_rep == base && m_rep->offset == 0 && base->preCapacity == 0) { - d = base->buf; - m_rep->_hash = 0; - m_rep->len = l; - } else { - if (!allocChars(l).getValue(d)) { - makeNull(); - return *this; - } - m_rep = Rep::create(d, l); - } - for (int i = 0; i < l; i++) - d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend + UChar* d = 0; + m_rep = Rep::tryCreateUninitialized(l, d); + if (m_rep) { + for (int i = 0; i < l; i++) + d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend + } else + makeNull(); return *this; } @@ -1462,7 +633,7 @@ uint32_t UString::toStrictUInt32(bool* ok) const *ok = false; // Empty string is not OK. - int len = m_rep->len; + int len = m_rep->size(); if (len == 0) return 0; const UChar* p = m_rep->data(); @@ -1689,8 +860,8 @@ int compare(const UString& s1, const UString& s2) bool equal(const UString::Rep* r, const UString::Rep* b) { - int length = r->len; - if (length != b->len) + int length = r->size(); + if (length != b->size()) return false; const UChar* d = r->data(); const UChar* s = b->data(); diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h index 9b046f2..0c13689 100644 --- a/JavaScriptCore/runtime/UString.h +++ b/JavaScriptCore/runtime/UString.h @@ -24,6 +24,7 @@ #define UString_h #include "Collector.h" +#include "UStringImpl.h" #include <stdint.h> #include <string.h> #include <wtf/Assertions.h> @@ -40,8 +41,6 @@ namespace JSC { using WTF::PlacementNewAdoptType; using WTF::PlacementNewAdopt; - class IdentifierTable; - class CString { public: CString() @@ -71,194 +70,47 @@ namespace JSC { char* m_data; }; + bool operator==(const CString&, const CString&); + typedef Vector<char, 32> CStringBuffer; class UString { friend class JIT; public: - typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar; - struct BaseString; - struct Rep : Noncopyable { - friend class JIT; - - static PassRefPtr<Rep> create(UChar* buffer, int length) - { - return adoptRef(new BaseString(buffer, length)); - } - - static PassRefPtr<Rep> createEmptyBuffer(size_t size) - { - // Guard against integer overflow - if (size < (std::numeric_limits<size_t>::max() / sizeof(UChar))) { - void* buf = 0; - if (tryFastMalloc(size * sizeof(UChar)).getValue(buf)) - return adoptRef(new BaseString(static_cast<UChar*>(buf), 0, size)); - } - return adoptRef(new BaseString(0, 0, 0)); - } - - static PassRefPtr<Rep> createCopying(const UChar*, int); - static PassRefPtr<Rep> create(PassRefPtr<Rep> base, int offset, int length); - - // Constructs a string from a UTF-8 string, using strict conversion (see comments in UTF8.h). - // Returns UString::Rep::null for null input or conversion failure. - static PassRefPtr<Rep> createFromUTF8(const char*); - - // Uses SharedUChar to have joint ownership over the UChar*. - static PassRefPtr<Rep> create(UChar*, int, PassRefPtr<SharedUChar>); - - SharedUChar* sharedBuffer(); - void destroy(); - - bool baseIsSelf() const { return m_identifierTableAndFlags.isFlagSet(BaseStringFlag); } - UChar* data() const; - int size() const { return len; } - - unsigned hash() const { if (_hash == 0) _hash = computeHash(data(), len); return _hash; } - unsigned computedHash() const { ASSERT(_hash); return _hash; } // fast path for Identifiers - - static unsigned computeHash(const UChar*, int length); - static unsigned computeHash(const char*, int length); - static unsigned computeHash(const char* s) { return computeHash(s, strlen(s)); } - - IdentifierTable* identifierTable() const { return m_identifierTableAndFlags.get(); } - void setIdentifierTable(IdentifierTable* table) { ASSERT(!isStatic()); m_identifierTableAndFlags.set(table); } - - bool isStatic() const { return m_identifierTableAndFlags.isFlagSet(StaticFlag); } - void setStatic(bool); - void setBaseString(PassRefPtr<BaseString>); - BaseString* baseString(); - const BaseString* baseString() const; - - Rep* ref() { ++rc; return this; } - ALWAYS_INLINE void deref() { if (--rc == 0) destroy(); } - - void checkConsistency() const; - enum UStringFlags { - StaticFlag, - BaseStringFlag - }; - - // unshared data - int offset; - int len; - int rc; // For null and empty static strings, this field does not reflect a correct count, because ref/deref are not thread-safe. A special case in destroy() guarantees that these do not get deleted. - mutable unsigned _hash; - PtrAndFlags<IdentifierTable, UStringFlags> m_identifierTableAndFlags; - - static BaseString& null() { return *nullBaseString; } - static BaseString& empty() { return *emptyBaseString; } - - bool reserveCapacity(int capacity); - - protected: - // Constructor for use by BaseString subclass; they use the union with m_baseString for another purpose. - Rep(int length) - : offset(0) - , len(length) - , rc(1) - , _hash(0) - , m_baseString(0) - { - } - - Rep(PassRefPtr<BaseString> base, int offsetInBase, int length) - : offset(offsetInBase) - , len(length) - , rc(1) - , _hash(0) - , m_baseString(base.releaseRef()) - { - checkConsistency(); - } - - union { - // If !baseIsSelf() - BaseString* m_baseString; - // If baseIsSelf() - SharedUChar* m_sharedBuffer; - }; - - private: - // For SmallStringStorage which allocates an array and does initialization manually. - Rep() { } - - friend class SmallStringsStorage; - friend void initializeUString(); - JS_EXPORTDATA static BaseString* nullBaseString; - JS_EXPORTDATA static BaseString* emptyBaseString; - }; - - - struct BaseString : public Rep { - bool isShared() { return rc != 1 || isBufferReadOnly(); } - void setSharedBuffer(PassRefPtr<SharedUChar>); - - bool isBufferReadOnly() - { - if (!m_sharedBuffer) - return false; - return slowIsBufferReadOnly(); - } - - // potentially shared data. - UChar* buf; - int preCapacity; - int usedPreCapacity; - int capacity; - int usedCapacity; - - size_t reportedCost; - - private: - BaseString(UChar* buffer, int length, int additionalCapacity = 0) - : Rep(length) - , buf(buffer) - , preCapacity(0) - , usedPreCapacity(0) - , capacity(length + additionalCapacity) - , usedCapacity(length) - , reportedCost(0) - { - m_identifierTableAndFlags.setFlag(BaseStringFlag); - checkConsistency(); - } - - SharedUChar* sharedBuffer(); - bool slowIsBufferReadOnly(); - - friend struct Rep; - friend class SmallStringsStorage; - friend void initializeUString(); - }; - + typedef UStringImpl Rep; + public: + // UString constructors passed char*s assume ISO Latin-1 encoding; for UTF8 use 'createFromUTF8', below. UString(); - // Constructor for null-terminated ASCII string. - UString(const char*); - // Constructor for non-null-terminated ASCII string. + UString(const char*); // Constructor for null-terminated string. UString(const char*, int length); UString(const UChar*, int length); - UString(UChar*, int length, bool copy); + UString(const Vector<UChar>& buffer); UString(const UString& s) : m_rep(s.m_rep) { } - UString(const Vector<UChar>& buffer); + // Special constructor for cases where we overwrite an object in place. + UString(PlacementNewAdoptType) + : m_rep(PlacementNewAdopt) + { + } ~UString() { } - // Special constructor for cases where we overwrite an object in place. - UString(PlacementNewAdoptType) - : m_rep(PlacementNewAdopt) + template<size_t inlineCapacity> + static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector) { + return Rep::adopt(vector); } + static UString createFromUTF8(const char*); + static UString from(int); static UString from(long long); static UString from(unsigned int); @@ -285,12 +137,6 @@ namespace JSC { UString replaceRange(int rangeStart, int RangeEnd, const UString& replacement) const; - UString& append(const UString&); - UString& append(const char*); - UString& append(UChar); - UString& append(char c) { return append(static_cast<UChar>(static_cast<unsigned char>(c))); } - UString& append(const UChar*, int size); - bool getCString(CStringBuffer&) const; // NOTE: This method should only be used for *debugging* purposes as it @@ -309,13 +155,10 @@ namespace JSC { UString& operator=(const char*c); - UString& operator+=(const UString& s) { return append(s); } - UString& operator+=(const char* s) { return append(s); } - const UChar* data() const { return m_rep->data(); } - bool isNull() const { return (m_rep == &Rep::null()); } - bool isEmpty() const { return (!m_rep->len); } + bool isNull() const { return m_rep == &Rep::null(); } + bool isEmpty() const { return !m_rep->size(); } bool is8Bit() const; @@ -351,22 +194,9 @@ namespace JSC { ASSERT(m_rep); } - size_t cost() const; - - // Attempt to grow this string such that it can grow to a total length of 'capacity' - // without reallocation. This may fail a number of reasons - if the BasicString is - // shared and another string is using part of the capacity beyond our end point, if - // the realloc fails, or if this string is empty and has no storage. - // - // This method returns a boolean indicating success. - bool reserveCapacity(int capacity) - { - return m_rep->reserveCapacity(capacity); - } + size_t cost() const { return m_rep->cost(); } private: - void expandCapacity(int requiredLength); - void expandPreCapacity(int requiredPreCap); void makeNull(); RefPtr<Rep> m_rep; @@ -374,13 +204,9 @@ namespace JSC { friend void initializeUString(); friend bool operator==(const UString&, const UString&); - friend PassRefPtr<Rep> concatenate(Rep*, Rep*); // returns 0 if out of memory }; - PassRefPtr<UString::Rep> concatenate(UString::Rep*, UString::Rep*); - PassRefPtr<UString::Rep> concatenate(UString::Rep*, int); - PassRefPtr<UString::Rep> concatenate(UString::Rep*, double); - inline bool operator==(const UString& s1, const UString& s2) + ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2) { int size = s1.size(); switch (size) { @@ -426,117 +252,310 @@ namespace JSC { return !JSC::operator==(s1, s2); } - bool operator==(const CString&, const CString&); + int compare(const UString&, const UString&); - inline UString operator+(const UString& s1, const UString& s2) + inline UString::UString() + : m_rep(&Rep::null()) { - RefPtr<UString::Rep> result = concatenate(s1.rep(), s2.rep()); - return UString(result ? result.release() : UString::nullRep()); } - int compare(const UString&, const UString&); + // Rule from ECMA 15.2 about what an array index is. + // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1. + inline unsigned UString::toArrayIndex(bool* ok) const + { + unsigned i = toStrictUInt32(ok); + if (ok && i >= 0xFFFFFFFFU) + *ok = false; + return i; + } - bool equal(const UString::Rep*, const UString::Rep*); + // We'd rather not do shared substring append for small strings, since + // this runs too much risk of a tiny initial string holding down a + // huge buffer. + // FIXME: this should be size_t but that would cause warnings until we + // fix UString sizes to be size_t instead of int + static const int minShareSize = Heap::minExtraCost / sizeof(UChar); - inline PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<UString::Rep> rep, int offset, int length) - { - ASSERT(rep); - rep->checkConsistency(); + struct IdentifierRepHash : PtrHash<RefPtr<JSC::UString::Rep> > { + static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->existingHash(); } + static unsigned hash(JSC::UString::Rep* key) { return key->existingHash(); } + }; - int repOffset = rep->offset; + void initializeUString(); - PassRefPtr<BaseString> base = rep->baseString(); + template<typename StringType> + class StringTypeAdapter { + }; - ASSERT(-(offset + repOffset) <= base->usedPreCapacity); - ASSERT(offset + repOffset + length <= base->usedCapacity); + template<> + class StringTypeAdapter<char*> { + public: + StringTypeAdapter<char*>(char* buffer) + : m_buffer((unsigned char*)buffer) + , m_length(strlen(buffer)) + { + } - // Steal the single reference this Rep was created with. - return adoptRef(new Rep(base, repOffset + offset, length)); - } + unsigned length() { return m_length; } - inline UChar* UString::Rep::data() const - { - const BaseString* base = baseString(); - return base->buf + base->preCapacity + offset; - } + void writeTo(UChar* destination) + { + for (unsigned i = 0; i < m_length; ++i) + destination[i] = m_buffer[i]; + } - inline void UString::Rep::setStatic(bool v) - { - ASSERT(!identifierTable()); - if (v) - m_identifierTableAndFlags.setFlag(StaticFlag); - else - m_identifierTableAndFlags.clearFlag(StaticFlag); - } + private: + const unsigned char* m_buffer; + unsigned m_length; + }; + + template<> + class StringTypeAdapter<const char*> { + public: + StringTypeAdapter<const char*>(const char* buffer) + : m_buffer((unsigned char*)buffer) + , m_length(strlen(buffer)) + { + } + + unsigned length() { return m_length; } - inline void UString::Rep::setBaseString(PassRefPtr<BaseString> base) + void writeTo(UChar* destination) + { + for (unsigned i = 0; i < m_length; ++i) + destination[i] = m_buffer[i]; + } + + private: + const unsigned char* m_buffer; + unsigned m_length; + }; + + template<> + class StringTypeAdapter<UString> { + public: + StringTypeAdapter<UString>(UString& string) + : m_data(string.data()) + , m_length(string.size()) + { + } + + unsigned length() { return m_length; } + + void writeTo(UChar* destination) + { + for (unsigned i = 0; i < m_length; ++i) + destination[i] = m_data[i]; + } + + private: + const UChar* m_data; + unsigned m_length; + }; + + template<typename StringType1, typename StringType2> + UString makeString(StringType1 string1, StringType2 string2) { - ASSERT(base != this); - ASSERT(!baseIsSelf()); - m_baseString = base.releaseRef(); + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + + UChar* buffer; + unsigned length = adapter1.length() + adapter2.length(); + PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return UString(); + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + + return resultImpl; } - inline UString::BaseString* UString::Rep::baseString() + template<typename StringType1, typename StringType2, typename StringType3> + UString makeString(StringType1 string1, StringType2 string2, StringType3 string3) { - return !baseIsSelf() ? m_baseString : reinterpret_cast<BaseString*>(this) ; + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + + UChar* buffer; + unsigned length = adapter1.length() + adapter2.length() + adapter3.length(); + PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return UString(); + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + + return resultImpl; } - inline const UString::BaseString* UString::Rep::baseString() const + template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> + UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) { - return const_cast<Rep*>(this)->baseString(); + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + + UChar* buffer; + unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length(); + PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return UString(); + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + + return resultImpl; } -#ifdef NDEBUG - inline void UString::Rep::checkConsistency() const + template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> + UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) { + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + + UChar* buffer; + unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length(); + PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return UString(); + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + + return resultImpl; } -#endif - inline UString::UString() - : m_rep(&Rep::null()) + template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> + UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) { + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + StringTypeAdapter<StringType6> adapter6(string6); + + UChar* buffer; + unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length(); + PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return UString(); + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + result += adapter5.length(); + adapter6.writeTo(result); + + return resultImpl; } - // Rule from ECMA 15.2 about what an array index is. - // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1. - inline unsigned UString::toArrayIndex(bool* ok) const + template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> + UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) { - unsigned i = toStrictUInt32(ok); - if (ok && i >= 0xFFFFFFFFU) - *ok = false; - return i; + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + StringTypeAdapter<StringType6> adapter6(string6); + StringTypeAdapter<StringType7> adapter7(string7); + + UChar* buffer; + unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length(); + PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return UString(); + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + result += adapter5.length(); + adapter6.writeTo(result); + result += adapter6.length(); + adapter7.writeTo(result); + + return resultImpl; } - // We'd rather not do shared substring append for small strings, since - // this runs too much risk of a tiny initial string holding down a - // huge buffer. - // FIXME: this should be size_t but that would cause warnings until we - // fix UString sizes to be size_t instead of int - static const int minShareSize = Heap::minExtraCostSize / sizeof(UChar); - - inline size_t UString::cost() const + template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> + UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) { - BaseString* base = m_rep->baseString(); - size_t capacity = (base->capacity + base->preCapacity) * sizeof(UChar); - size_t reportedCost = base->reportedCost; - ASSERT(capacity >= reportedCost); - - size_t capacityDelta = capacity - reportedCost; - - if (capacityDelta < static_cast<size_t>(minShareSize)) - return 0; - - base->reportedCost = capacity; - - return capacityDelta; + StringTypeAdapter<StringType1> adapter1(string1); + StringTypeAdapter<StringType2> adapter2(string2); + StringTypeAdapter<StringType3> adapter3(string3); + StringTypeAdapter<StringType4> adapter4(string4); + StringTypeAdapter<StringType5> adapter5(string5); + StringTypeAdapter<StringType6> adapter6(string6); + StringTypeAdapter<StringType7> adapter7(string7); + StringTypeAdapter<StringType8> adapter8(string8); + + UChar* buffer; + unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length() + adapter8.length(); + PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer); + if (!resultImpl) + return UString(); + + UChar* result = buffer; + adapter1.writeTo(result); + result += adapter1.length(); + adapter2.writeTo(result); + result += adapter2.length(); + adapter3.writeTo(result); + result += adapter3.length(); + adapter4.writeTo(result); + result += adapter4.length(); + adapter5.writeTo(result); + result += adapter5.length(); + adapter6.writeTo(result); + result += adapter6.length(); + adapter7.writeTo(result); + result += adapter7.length(); + adapter8.writeTo(result); + + return resultImpl; } - struct IdentifierRepHash : PtrHash<RefPtr<JSC::UString::Rep> > { - static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->computedHash(); } - static unsigned hash(JSC::UString::Rep* key) { return key->computedHash(); } - }; - - void initializeUString(); } // namespace JSC namespace WTF { diff --git a/JavaScriptCore/runtime/UStringImpl.cpp b/JavaScriptCore/runtime/UStringImpl.cpp new file mode 100644 index 0000000..4b0d1c9 --- /dev/null +++ b/JavaScriptCore/runtime/UStringImpl.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "UStringImpl.h" + +#include "Identifier.h" +#include "UString.h" +#include <wtf/unicode/UTF8.h> + +using namespace WTF::Unicode; +using namespace std; + +namespace JSC { + +SharedUChar* UStringImpl::baseSharedBuffer() +{ + ASSERT((bufferOwnership() == BufferShared) + || ((bufferOwnership() == BufferOwned) && !m_dataBuffer.asPtr<void*>())); + + if (bufferOwnership() != BufferShared) + m_dataBuffer = UntypedPtrAndBitfield(SharedUChar::create(new OwnFastMallocPtr<UChar>(m_data)).releaseRef(), BufferShared); + + return m_dataBuffer.asPtr<SharedUChar*>(); +} + +SharedUChar* UStringImpl::sharedBuffer() +{ + if (m_length < s_minLengthToShare) + return 0; + ASSERT(!isStatic()); + + UStringImpl* owner = bufferOwnerString(); + if (owner->bufferOwnership() == BufferInternal) + return 0; + + return owner->baseSharedBuffer(); +} + +UStringImpl::~UStringImpl() +{ + ASSERT(!isStatic()); + checkConsistency(); + + if (isIdentifier()) + Identifier::remove(this); + + if (bufferOwnership() != BufferInternal) { + if (bufferOwnership() == BufferOwned) + fastFree(m_data); + else if (bufferOwnership() == BufferSubstring) + m_dataBuffer.asPtr<UStringImpl*>()->deref(); + else { + ASSERT(bufferOwnership() == BufferShared); + m_dataBuffer.asPtr<SharedUChar*>()->deref(); + } + } +} + +} diff --git a/JavaScriptCore/runtime/UStringImpl.h b/JavaScriptCore/runtime/UStringImpl.h new file mode 100644 index 0000000..abed637 --- /dev/null +++ b/JavaScriptCore/runtime/UStringImpl.h @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UStringImpl_h +#define UStringImpl_h + +#include <limits> +#include <wtf/CrossThreadRefCounted.h> +#include <wtf/OwnFastMallocPtr.h> +#include <wtf/PossiblyNull.h> +#include <wtf/StringHashFunctions.h> +#include <wtf/Vector.h> +#include <wtf/unicode/Unicode.h> + +namespace JSC { + +class IdentifierTable; + +typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar; + +class UntypedPtrAndBitfield { +public: + UntypedPtrAndBitfield() {} + + UntypedPtrAndBitfield(void* ptrValue, uintptr_t bitValue) + : m_value(reinterpret_cast<uintptr_t>(ptrValue) | bitValue) +#ifndef NDEBUG + , m_leaksPtr(ptrValue) +#endif + { + ASSERT(ptrValue == asPtr<void*>()); + ASSERT((*this & ~s_alignmentMask) == bitValue); + } + + template<typename T> + T asPtr() const { return reinterpret_cast<T>(m_value & s_alignmentMask); } + + UntypedPtrAndBitfield& operator&=(uintptr_t bits) + { + m_value &= bits | s_alignmentMask; + return *this; + } + + UntypedPtrAndBitfield& operator|=(uintptr_t bits) + { + m_value |= bits & ~s_alignmentMask; + return *this; + } + + uintptr_t operator&(uintptr_t mask) const + { + return m_value & mask & ~s_alignmentMask; + } + +private: + static const uintptr_t s_alignmentMask = ~static_cast<uintptr_t>(0x7); + uintptr_t m_value; +#ifndef NDEBUG + void* m_leaksPtr; // Only used to allow tools like leaks on OSX to detect that the memory is referenced. +#endif +}; + +class UStringImpl : Noncopyable { +public: + template<size_t inlineCapacity> + static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector) + { + if (unsigned length = vector.size()) + return adoptRef(new UStringImpl(vector.releaseBuffer(), length, BufferOwned)); + return &empty(); + } + + static PassRefPtr<UStringImpl> create(const UChar* buffer, int length) + { + UChar* newBuffer; + if (PassRefPtr<UStringImpl> impl = tryCreateUninitialized(length, newBuffer)) { + copyChars(newBuffer, buffer, length); + return impl; + } + return &null(); + } + + static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, int offset, int length) + { + ASSERT(rep); + rep->checkConsistency(); + return adoptRef(new UStringImpl(rep->m_data + offset, length, rep->bufferOwnerString())); + } + + static PassRefPtr<UStringImpl> create(PassRefPtr<SharedUChar> sharedBuffer, UChar* buffer, int length) + { + return adoptRef(new UStringImpl(buffer, length, sharedBuffer)); + } + + static PassRefPtr<UStringImpl> createUninitialized(unsigned length, UChar*& output) + { + if (!length) { + output = 0; + return &empty(); + } + + if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar))) + CRASH(); + UStringImpl* resultImpl = static_cast<UStringImpl*>(fastMalloc(sizeof(UChar) * length + sizeof(UStringImpl))); + output = reinterpret_cast<UChar*>(resultImpl + 1); + return adoptRef(new(resultImpl) UStringImpl(output, length, BufferInternal)); + } + + static PassRefPtr<UStringImpl> tryCreateUninitialized(unsigned length, UChar*& output) + { + if (!length) { + output = 0; + return &empty(); + } + + if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar))) + return 0; + UStringImpl* resultImpl; + if (!tryFastMalloc(sizeof(UChar) * length + sizeof(UStringImpl)).getValue(resultImpl)) + return 0; + output = reinterpret_cast<UChar*>(resultImpl + 1); + return adoptRef(new(resultImpl) UStringImpl(output, length, BufferInternal)); + } + + SharedUChar* sharedBuffer(); + UChar* data() const { return m_data; } + int size() const { return m_length; } + size_t cost() + { + // For substrings, return the cost of the base string. + if (bufferOwnership() == BufferSubstring) + return m_dataBuffer.asPtr<UStringImpl*>()->cost(); + + if (m_dataBuffer & s_reportedCostBit) + return 0; + m_dataBuffer |= s_reportedCostBit; + return m_length; + } + unsigned hash() const { if (!m_hash) m_hash = computeHash(data(), m_length); return m_hash; } + unsigned existingHash() 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_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)) delete this; } + + static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters) + { + if (numCharacters <= s_copyCharsInlineCutOff) { + for (unsigned i = 0; i < numCharacters; ++i) + destination[i] = source[i]; + } else + memcpy(destination, source, numCharacters * sizeof(UChar)); + } + + static unsigned computeHash(const UChar* s, int length) { ASSERT(length >= 0); return WTF::stringHash(s, length); } + static unsigned computeHash(const char* s, int length) { ASSERT(length >= 0); return WTF::stringHash(s, length); } + static unsigned computeHash(const char* s) { return WTF::stringHash(s); } + + static UStringImpl& null() { return *s_null; } + static UStringImpl& empty() { return *s_empty; } + + ALWAYS_INLINE void checkConsistency() const + { + // 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() || !isIdentifier()); + } + +private: + enum BufferOwnership { + BufferInternal, + BufferOwned, + BufferSubstring, + BufferShared, + }; + + // For SmallStringStorage, which allocates an array and uses an in-place new. + UStringImpl() { } + + // Used to construct normal strings with an internal or external buffer. + UStringImpl(UChar* data, int length, BufferOwnership ownership) + : m_data(data) + , m_length(length) + , m_refCount(s_refCountIncrement) + , m_hash(0) + , m_isIdentifier(false) + , m_dataBuffer(0, ownership) + { + ASSERT((ownership == BufferInternal) || (ownership == BufferOwned)); + checkConsistency(); + } + + // Used to construct static strings, which have an special refCount that can never hit zero. + // This means that the static string will never be destroyed, which is important because + // static strings will be shared across threads & ref-counted in a non-threadsafe manner. + enum StaticStringConstructType { ConstructStaticString }; + UStringImpl(UChar* data, int length, StaticStringConstructType) + : m_data(data) + , m_length(length) + , m_refCount(s_staticRefCountInitialValue) + , m_hash(0) + , m_isIdentifier(false) + , m_dataBuffer(0, BufferOwned) + { + checkConsistency(); + } + + // Used to create new strings that are a substring of an existing string. + UStringImpl(UChar* data, int length, PassRefPtr<UStringImpl> base) + : m_data(data) + , m_length(length) + , m_refCount(s_refCountIncrement) + , m_hash(0) + , m_isIdentifier(false) + , m_dataBuffer(base.releaseRef(), BufferSubstring) + { + // Do use static strings as a base for substrings; UntypedPtrAndBitfield assumes + // that all pointers will be at least 8-byte aligned, we cannot guarantee that of + // UStringImpls that are not heap allocated. + ASSERT(m_dataBuffer.asPtr<UStringImpl*>()->size()); + ASSERT(!m_dataBuffer.asPtr<UStringImpl*>()->isStatic()); + checkConsistency(); + } + + // Used to construct new strings sharing an existing shared buffer. + UStringImpl(UChar* data, int length, PassRefPtr<SharedUChar> sharedBuffer) + : m_data(data) + , m_length(length) + , m_refCount(s_refCountIncrement) + , m_hash(0) + , m_isIdentifier(false) + , m_dataBuffer(sharedBuffer.releaseRef(), BufferShared) + { + checkConsistency(); + } + + using Noncopyable::operator new; + void* operator new(size_t, void* inPlace) { return inPlace; } + + ~UStringImpl(); + + // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings. + static const int s_minLengthToShare = 10; + static const unsigned s_copyCharsInlineCutOff = 20; + static const uintptr_t s_bufferOwnershipMask = 3; + static const uintptr_t s_reportedCostBit = 4; + // We initialize and increment/decrement the refCount for all normal (non-static) strings by the value 2. + // We initialize static strings with an odd number (specifically, 1), such that the refCount cannot reach zero. + static const int s_refCountIncrement = 2; + static const int s_staticRefCountInitialValue = 1; + + UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() : this; } + const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() : this; } + SharedUChar* baseSharedBuffer(); + unsigned bufferOwnership() const { return m_dataBuffer & s_bufferOwnershipMask; } + bool isStatic() const { return m_refCount & 1; } + + // unshared data + UChar* m_data; + int m_length; + unsigned m_refCount; + mutable unsigned m_hash : 31; + mutable unsigned m_isIdentifier : 1; + UntypedPtrAndBitfield m_dataBuffer; + + JS_EXPORTDATA static UStringImpl* s_null; + JS_EXPORTDATA static UStringImpl* s_empty; + + friend class JIT; + friend class SmallStringsStorage; + friend void initializeUString(); +}; + +bool equal(const UStringImpl*, const UStringImpl*); + +} + +#endif diff --git a/JavaScriptCore/runtime/WeakGCMap.h b/JavaScriptCore/runtime/WeakGCMap.h new file mode 100644 index 0000000..39a91c5 --- /dev/null +++ b/JavaScriptCore/runtime/WeakGCMap.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WeakGCMap_h +#define WeakGCMap_h + +#include "Collector.h" +#include <wtf/HashMap.h> + +namespace JSC { + +class JSCell; + +// A HashMap whose get() function returns emptyValue() for cells awaiting destruction. +template<typename KeyType, typename MappedType> +class WeakGCMap : public FastAllocBase { + /* + Invariants: + * A value enters the WeakGCMap marked. (Guaranteed by set().) + * A value that becomes unmarked leaves the WeakGCMap before being recycled. (Guaranteed by the value's destructor removing it from the WeakGCMap.) + * A value that becomes unmarked leaves the WeakGCMap before becoming marked again. (Guaranteed by all destructors running before the mark phase begins.) + * During the mark phase, all values in the WeakGCMap are valid. (Guaranteed by all destructors running before the mark phase begins.) + */ + +public: + typedef typename HashMap<KeyType, MappedType>::iterator iterator; + typedef typename HashMap<KeyType, MappedType>::const_iterator const_iterator; + + bool isEmpty() { return m_map.isEmpty(); } + + MappedType get(const KeyType& key) const; + pair<iterator, bool> set(const KeyType&, const MappedType&); + MappedType take(const KeyType& key); + + // These unchecked functions provide access to a value even if the value's + // mark bit is not set. This is used, among other things, to retrieve values + // during the GC mark phase, which begins by clearing all mark bits. + + MappedType uncheckedGet(const KeyType& key) const { return m_map.get(key); } + bool uncheckedRemove(const KeyType&, const MappedType&); + + iterator uncheckedBegin() { return m_map.begin(); } + iterator uncheckedEnd() { return m_map.end(); } + + const_iterator uncheckedBegin() const { return m_map.begin(); } + const_iterator uncheckedEnd() const { return m_map.end(); } + +private: + HashMap<KeyType, MappedType> m_map; +}; + +template<typename KeyType, typename MappedType> +inline MappedType WeakGCMap<KeyType, MappedType>::get(const KeyType& key) const +{ + MappedType result = m_map.get(key); + if (result == HashTraits<MappedType>::emptyValue()) + return result; + if (!Heap::isCellMarked(result)) + return HashTraits<MappedType>::emptyValue(); + return result; +} + +template<typename KeyType, typename MappedType> +MappedType WeakGCMap<KeyType, MappedType>::take(const KeyType& key) +{ + MappedType result = m_map.take(key); + if (result == HashTraits<MappedType>::emptyValue()) + return result; + if (!Heap::isCellMarked(result)) + return HashTraits<MappedType>::emptyValue(); + return result; +} + +template<typename KeyType, typename MappedType> +pair<typename HashMap<KeyType, MappedType>::iterator, bool> WeakGCMap<KeyType, MappedType>::set(const KeyType& key, const MappedType& value) +{ + Heap::markCell(value); // If value is newly allocated, it's not marked, so mark it now. + pair<iterator, bool> result = m_map.add(key, value); + if (!result.second) { // pre-existing entry + result.second = !Heap::isCellMarked(result.first->second); + result.first->second = value; + } + return result; +} + +template<typename KeyType, typename MappedType> +bool WeakGCMap<KeyType, MappedType>::uncheckedRemove(const KeyType& key, const MappedType& value) +{ + iterator it = m_map.find(key); + if (it == m_map.end()) + return false; + if (it->second != value) + return false; + m_map.remove(it); + return true; +} + +} // namespace JSC + +#endif // WeakGCMap_h diff --git a/JavaScriptCore/runtime/WeakGCPtr.h b/JavaScriptCore/runtime/WeakGCPtr.h new file mode 100644 index 0000000..8653721 --- /dev/null +++ b/JavaScriptCore/runtime/WeakGCPtr.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WeakGCPtr_h +#define WeakGCPtr_h + +#include "Collector.h" +#include <wtf/Noncopyable.h> + +namespace JSC { + +// A smart pointer whose get() function returns 0 for cells awaiting destruction. +template <typename T> class WeakGCPtr : Noncopyable { +public: + WeakGCPtr() : m_ptr(0) { } + WeakGCPtr(T* ptr) { assign(ptr); } + + T* get() const + { + if (!m_ptr || !Heap::isCellMarked(m_ptr)) + return 0; + return m_ptr; + } + + void clear() { m_ptr = 0; } + + T& operator*() const { return *get(); } + T* operator->() const { return get(); } + + bool operator!() const { return !get(); } + + // This conversion operator allows implicit conversion to bool but not to other integer types. +#if COMPILER(WINSCW) + operator bool() const { return m_ptr; } +#else + typedef T* WeakGCPtr::*UnspecifiedBoolType; + operator UnspecifiedBoolType() const { return get() ? &WeakGCPtr::m_ptr : 0; } +#endif + + WeakGCPtr& operator=(T*); + +private: + void assign(T* ptr) + { + if (ptr) + Heap::markCell(ptr); + m_ptr = ptr; + } + + T* m_ptr; +}; + +template <typename T> inline WeakGCPtr<T>& WeakGCPtr<T>::operator=(T* optr) +{ + assign(optr); + return *this; +} + +template <typename T, typename U> inline bool operator==(const WeakGCPtr<T>& a, const WeakGCPtr<U>& b) +{ + return a.get() == b.get(); +} + +template <typename T, typename U> inline bool operator==(const WeakGCPtr<T>& a, U* b) +{ + return a.get() == b; +} + +template <typename T, typename U> inline bool operator==(T* a, const WeakGCPtr<U>& b) +{ + return a == b.get(); +} + +template <typename T, typename U> inline bool operator!=(const WeakGCPtr<T>& a, const WeakGCPtr<U>& b) +{ + return a.get() != b.get(); +} + +template <typename T, typename U> inline bool operator!=(const WeakGCPtr<T>& a, U* b) +{ + return a.get() != b; +} + +template <typename T, typename U> inline bool operator!=(T* a, const WeakGCPtr<U>& b) +{ + return a != b.get(); +} + +template <typename T, typename U> inline WeakGCPtr<T> static_pointer_cast(const WeakGCPtr<U>& p) +{ + return WeakGCPtr<T>(static_cast<T*>(p.get())); +} + +template <typename T, typename U> inline WeakGCPtr<T> const_pointer_cast(const WeakGCPtr<U>& p) +{ + return WeakGCPtr<T>(const_cast<T*>(p.get())); +} + +template <typename T> inline T* getPtr(const WeakGCPtr<T>& p) +{ + return p.get(); +} + +} // namespace JSC + +#endif // WeakGCPtr_h diff --git a/JavaScriptCore/tests/mozilla/ecma/Date/15.9.5.10-1.js b/JavaScriptCore/tests/mozilla/ecma/Date/15.9.5.10-1.js index f887725..f13e9d7 100644 --- a/JavaScriptCore/tests/mozilla/ecma/Date/15.9.5.10-1.js +++ b/JavaScriptCore/tests/mozilla/ecma/Date/15.9.5.10-1.js @@ -61,14 +61,18 @@ var DST_END_1998 = UTC( GetFirstSundayInNovember(TimeFromYear(1998)) + 2*msPerHour ); - addTestCase( now ); /* + // We don't use |now| because it fails every night at midnight. + // The test is more reproducable if we use concrete times. + addTestCase( now ); addTestCase( TIME_YEAR_0 ); addTestCase( TIME_1970 ); addTestCase( TIME_1900 ); addTestCase( TIME_2000 ); addTestCase( UTC_FEB_29_2000 ); +*/ addTestCase( UTC_JAN_1_2005 ); +/* addTestCase( DST_START_1998 ); addTestCase( DST_START_1998-1 ); addTestCase( DST_START_1998+1 ); diff --git a/JavaScriptCore/tests/mozilla/ecma/Date/15.9.5.12-1.js b/JavaScriptCore/tests/mozilla/ecma/Date/15.9.5.12-1.js index 437a809..8dcf1a4 100644 --- a/JavaScriptCore/tests/mozilla/ecma/Date/15.9.5.12-1.js +++ b/JavaScriptCore/tests/mozilla/ecma/Date/15.9.5.12-1.js @@ -56,14 +56,19 @@ var UTC_JAN_1_2005 = TIME_2000 + TimeInYear(2000)+TimeInYear(2001)+ TimeInYear(2002)+TimeInYear(2003)+TimeInYear(2004); - addTestCase( now ); /* + // We don't use |now| because it fails every night at midnight. + // The test is more reproducable if we use concrete times. + addTestCase( now ); + addTestCase( TIME_YEAR_0 ); addTestCase( TIME_1970 ); addTestCase( TIME_1900 ); addTestCase( TIME_2000 ); addTestCase( UTC_FEB_29_2000 ); +*/ addTestCase( UTC_JAN_1_2005 ); +/* testcases[tc++] = new TestCase( SECTION, "(new Date(NaN)).getDay()", diff --git a/JavaScriptCore/tests/mozilla/ecma_2/RegExp/properties-001.js b/JavaScriptCore/tests/mozilla/ecma_2/RegExp/properties-001.js index 16f265c..3eb51cb 100644 --- a/JavaScriptCore/tests/mozilla/ecma_2/RegExp/properties-001.js +++ b/JavaScriptCore/tests/mozilla/ecma_2/RegExp/properties-001.js @@ -56,8 +56,15 @@ function AddRegExpCases( re, s, g, i, m, l ) { s, re.source ); +/* + * http://bugzilla.mozilla.org/show_bug.cgi?id=225550 changed + * the behavior of toString() and toSource() on empty regexps. + * So branch if |s| is the empty string - + */ + var S = s? s : '(?:)'; + AddTestCase( re + ".toString()", - "/" + s +"/" + (g?"g":"") + (i?"i":"") +(m?"m":""), + "/" + S +"/" + (g?"g":"") + (i?"i":"") +(m?"m":""), re.toString() ); AddTestCase( re + ".global", diff --git a/JavaScriptCore/tests/mozilla/js1_2/regexp/toString.js b/JavaScriptCore/tests/mozilla/js1_2/regexp/toString.js index 554b934..b08b772 100644 --- a/JavaScriptCore/tests/mozilla/js1_2/regexp/toString.js +++ b/JavaScriptCore/tests/mozilla/js1_2/regexp/toString.js @@ -41,7 +41,7 @@ // var re = new RegExp(); re.toString() var re = new RegExp(); testcases[count++] = new TestCase ( SECTION, "var re = new RegExp(); re.toString()", - '//', re.toString()); + '/(?:)/', re.toString()); // re = /.+/; re.toString(); re = /.+/; diff --git a/JavaScriptCore/wrec/WREC.h b/JavaScriptCore/wrec/WREC.h index 483dce0..13324e7 100644 --- a/JavaScriptCore/wrec/WREC.h +++ b/JavaScriptCore/wrec/WREC.h @@ -32,7 +32,7 @@ #include <wtf/unicode/Unicode.h> -#if COMPILER(GCC) && PLATFORM(X86) +#if COMPILER(GCC) && CPU(X86) #define WREC_CALL __attribute__ ((regparm (3))) #else #define WREC_CALL diff --git a/JavaScriptCore/wrec/WRECGenerator.cpp b/JavaScriptCore/wrec/WRECGenerator.cpp index e62add3..7105984 100644 --- a/JavaScriptCore/wrec/WRECGenerator.cpp +++ b/JavaScriptCore/wrec/WRECGenerator.cpp @@ -40,7 +40,7 @@ namespace JSC { namespace WREC { void Generator::generateEnter() { -#if PLATFORM(X86) +#if CPU(X86) // On x86 edi & esi are callee preserved registers. push(X86Registers::edi); push(X86Registers::esi); @@ -71,7 +71,7 @@ void Generator::generateReturnSuccess() store32(index, Address(output, 4)); // match end // Restore callee save registers. -#if PLATFORM(X86) +#if CPU(X86) pop(X86Registers::esi); pop(X86Registers::edi); #endif @@ -110,7 +110,7 @@ void Generator::generateReturnFailure() pop(); move(Imm32(-1), returnRegister); -#if PLATFORM(X86) +#if CPU(X86) pop(X86Registers::esi); pop(X86Registers::edi); #endif diff --git a/JavaScriptCore/wrec/WRECGenerator.h b/JavaScriptCore/wrec/WRECGenerator.h index 294c3d0..d707a6e 100644 --- a/JavaScriptCore/wrec/WRECGenerator.h +++ b/JavaScriptCore/wrec/WRECGenerator.h @@ -62,7 +62,7 @@ namespace JSC { { } -#if PLATFORM(X86) +#if CPU(X86) static const RegisterID input = X86Registers::eax; static const RegisterID index = X86Registers::edx; static const RegisterID length = X86Registers::ecx; @@ -73,7 +73,7 @@ namespace JSC { static const RegisterID returnRegister = X86Registers::eax; #endif -#if PLATFORM(X86_64) +#if CPU(X86_64) static const RegisterID input = X86Registers::edi; static const RegisterID index = X86Registers::esi; static const RegisterID length = X86Registers::edx; diff --git a/JavaScriptCore/wscript b/JavaScriptCore/wscript index 356950f..f5a041f 100644 --- a/JavaScriptCore/wscript +++ b/JavaScriptCore/wscript @@ -34,13 +34,14 @@ jscore_excludes.extend(get_excludes(jscore_dir, ['*CF.cpp', '*Symbian.cpp'])) sources = [] -jscore_excludes.extend(get_excludes(jscore_dir, ['*Win.cpp', '*None.cpp'])) +jscore_excludes.extend(get_excludes(jscore_dir, ['*None.cpp'])) if building_on_win32: - jscore_excludes += ['ExecutableAllocatorPosix.cpp', 'MarkStackPosix.cpp'] + jscore_excludes += ['ExecutableAllocatorPosix.cpp', 'MarkStackPosix.cpp', 'ThreadingPthreads.cpp'] sources += ['jit/ExecutableAllocatorWin.cpp', 'runtime/MarkStackWin.cpp'] else: jscore_excludes.append('JSStringRefBSTR.cpp') + jscore_excludes.extend(get_excludes(jscore_dir, ['*Win.cpp'])) def generate_jscore_derived_sources(): # build the derived sources diff --git a/JavaScriptCore/wtf/AlwaysInline.h b/JavaScriptCore/wtf/AlwaysInline.h index 64fdd99..4e7224c 100644 --- a/JavaScriptCore/wtf/AlwaysInline.h +++ b/JavaScriptCore/wtf/AlwaysInline.h @@ -23,7 +23,7 @@ #ifndef ALWAYS_INLINE #if COMPILER(GCC) && defined(NDEBUG) && !COMPILER(MINGW) #define ALWAYS_INLINE inline __attribute__((__always_inline__)) -#elif COMPILER(MSVC) && defined(NDEBUG) +#elif (COMPILER(MSVC) || COMPILER(RVCT)) && defined(NDEBUG) #define ALWAYS_INLINE __forceinline #else #define ALWAYS_INLINE inline diff --git a/JavaScriptCore/wtf/Assertions.cpp b/JavaScriptCore/wtf/Assertions.cpp index 6c5e2e3..cadbc91 100644 --- a/JavaScriptCore/wtf/Assertions.cpp +++ b/JavaScriptCore/wtf/Assertions.cpp @@ -35,7 +35,7 @@ #include <CoreFoundation/CFString.h> #endif -#if COMPILER(MSVC) && !PLATFORM(WINCE) +#if COMPILER(MSVC) && !OS(WINCE) #ifndef WINVER #define WINVER 0x0500 #endif @@ -46,7 +46,7 @@ #include <crtdbg.h> #endif -#if PLATFORM(WINCE) +#if OS(WINCE) #include <winbase.h> #endif @@ -82,7 +82,7 @@ static void vprintf_stderr_common(const char* format, va_list args) break; if (_vsnprintf(buffer, size, format, args) != -1) { -#if PLATFORM(WINCE) +#if OS(WINCE) // WinCE only supports wide chars wchar_t* wideBuffer = (wchar_t*)malloc(size * sizeof(wchar_t)); if (wideBuffer == NULL) @@ -105,7 +105,7 @@ static void vprintf_stderr_common(const char* format, va_list args) } while (size > 1024); } #endif -#if PLATFORM(SYMBIAN) +#if OS(SYMBIAN) vfprintf(stdout, format, args); #else vfprintf(stderr, format, args); @@ -123,7 +123,7 @@ static void printf_stderr_common(const char* format, ...) static void printCallSite(const char* file, int line, const char* function) { -#if PLATFORM(WIN) && !PLATFORM(WINCE) && defined _DEBUG +#if OS(WIN) && !OS(WINCE) && defined _DEBUG _CrtDbgReport(_CRT_WARN, file, line, NULL, "%s\n", function); #else printf_stderr_common("(%s:%d %s)\n", file, line, function); diff --git a/JavaScriptCore/wtf/Assertions.h b/JavaScriptCore/wtf/Assertions.h index e3340f1..352a74b 100644 --- a/JavaScriptCore/wtf/Assertions.h +++ b/JavaScriptCore/wtf/Assertions.h @@ -50,7 +50,7 @@ #include <inttypes.h> #endif -#if PLATFORM(SYMBIAN) +#if OS(SYMBIAN) #include <e32def.h> #include <e32debug.h> #endif @@ -61,24 +61,50 @@ #define ASSERTIONS_DISABLED_DEFAULT 0 #endif +#if COMPILER(MSVC7) || COMPILER(WINSCW) +#define HAVE_VARIADIC_MACRO 0 +#else +#define HAVE_VARIADIC_MACRO 1 +#endif + #ifndef ASSERT_DISABLED #define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT #endif +#ifndef ASSERT_MSG_DISABLED +#if HAVE(VARIADIC_MACRO) +#define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT +#else +#define ASSERT_MSG_DISABLED 1 +#endif +#endif + #ifndef ASSERT_ARG_DISABLED #define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT #endif #ifndef FATAL_DISABLED +#if HAVE(VARIADIC_MACRO) #define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT +#else +#define FATAL_DISABLED 1 +#endif #endif #ifndef ERROR_DISABLED +#if HAVE(VARIADIC_MACRO) #define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT +#else +#define ERROR_DISABLED 1 +#endif #endif #ifndef LOG_DISABLED +#if HAVE(VARIADIC_MACRO) #define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT +#else +#define LOG_DISABLED 1 +#endif #endif #if COMPILER(GCC) @@ -125,7 +151,7 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann /* CRASH -- gets us into the debugger or the crash reporter -- signals are ignored by the crash reporter so we must do better */ #ifndef CRASH -#if PLATFORM(SYMBIAN) +#if OS(SYMBIAN) #define CRASH() do { \ __DEBUGGER(); \ User::Panic(_L("Webkit CRASH"),0); \ @@ -138,9 +164,9 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann #endif #endif -/* ASSERT, ASSERT_WITH_MESSAGE, ASSERT_NOT_REACHED */ +/* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED */ -#if PLATFORM(WINCE) && !PLATFORM(TORCHMOBILE) +#if OS(WINCE) && !PLATFORM(TORCHMOBILE) /* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */ #include <windows.h> #undef min @@ -148,7 +174,7 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann #undef ERROR #endif -#if PLATFORM(WIN_OS) || PLATFORM(SYMBIAN) +#if OS(WINDOWS) || OS(SYMBIAN) /* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */ #undef ASSERT #endif @@ -156,11 +182,6 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann #if ASSERT_DISABLED #define ASSERT(assertion) ((void)0) -#if COMPILER(MSVC7) || COMPILER(WINSCW) -#define ASSERT_WITH_MESSAGE(assertion) ((void)0) -#else -#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0) -#endif /* COMPILER(MSVC7) */ #define ASSERT_NOT_REACHED() ((void)0) #define ASSERT_UNUSED(variable, assertion) ((void)variable) @@ -172,16 +193,7 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann CRASH(); \ } \ while (0) -#if COMPILER(MSVC7) || COMPILER(WINSCW) -#define ASSERT_WITH_MESSAGE(assertion) ((void)0) -#else -#define ASSERT_WITH_MESSAGE(assertion, ...) do \ - if (!(assertion)) { \ - WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \ - CRASH(); \ - } \ -while (0) -#endif /* COMPILER(MSVC7) */ + #define ASSERT_NOT_REACHED() do { \ WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \ CRASH(); \ @@ -191,6 +203,24 @@ while (0) #endif +/* ASSERT_WITH_MESSAGE */ + +#if COMPILER(MSVC7) +#define ASSERT_WITH_MESSAGE(assertion) ((void)0) +#elif COMPILER(WINSCW) +#define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0) +#elif ASSERT_MSG_DISABLED +#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0) +#else +#define ASSERT_WITH_MESSAGE(assertion, ...) do \ + if (!(assertion)) { \ + WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \ + CRASH(); \ + } \ +while (0) +#endif + + /* ASSERT_ARG */ #if ASSERT_ARG_DISABLED @@ -215,10 +245,12 @@ while (0) /* FATAL */ -#if FATAL_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) -#define FATAL(...) ((void)0) -#elif COMPILER(MSVC7) +#if COMPILER(MSVC7) #define FATAL() ((void)0) +#elif COMPILER(WINSCW) +#define FATAL(arg...) ((void)0) +#elif FATAL_DISABLED +#define FATAL(...) ((void)0) #else #define FATAL(...) do { \ WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \ @@ -228,20 +260,24 @@ while (0) /* LOG_ERROR */ -#if ERROR_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) -#define LOG_ERROR(...) ((void)0) -#elif COMPILER(MSVC7) || COMPILER(WINSCW) +#if COMPILER(MSVC7) #define LOG_ERROR() ((void)0) +#elif COMPILER(WINSCW) +#define LOG_ERROR(arg...) ((void)0) +#elif ERROR_DISABLED +#define LOG_ERROR(...) ((void)0) #else #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__) #endif /* LOG */ -#if LOG_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) -#define LOG(channel, ...) ((void)0) -#elif COMPILER(MSVC7) || COMPILER(WINSCW) +#if COMPILER(MSVC7) #define LOG() ((void)0) +#elif COMPILER(WINSCW) +#define LOG(arg...) ((void)0) +#elif LOG_DISABLED +#define LOG(channel, ...) ((void)0) #else #define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) @@ -250,10 +286,12 @@ while (0) /* LOG_VERBOSE */ -#if LOG_DISABLED && !COMPILER(MSVC7) && !COMPILER(WINSCW) -#define LOG_VERBOSE(channel, ...) ((void)0) -#elif COMPILER(MSVC7) || COMPILER(WINSCW) +#if COMPILER(MSVC7) #define LOG_VERBOSE(channel) ((void)0) +#elif COMPILER(WINSCW) +#define LOG_VERBOSE(channel, arg...) ((void)0) +#elif LOG_DISABLED +#define LOG_VERBOSE(channel, ...) ((void)0) #else #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) #endif diff --git a/JavaScriptCore/wtf/CurrentTime.cpp b/JavaScriptCore/wtf/CurrentTime.cpp index b36cae5..b272874 100644 --- a/JavaScriptCore/wtf/CurrentTime.cpp +++ b/JavaScriptCore/wtf/CurrentTime.cpp @@ -33,7 +33,7 @@ #include "config.h" #include "CurrentTime.h" -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) // Windows is first since we want to use hires timers, despite PLATFORM(CF) // being defined. @@ -45,7 +45,7 @@ #include <time.h> #if USE(QUERY_PERFORMANCE_COUNTER) -#if PLATFORM(WINCE) +#if OS(WINCE) extern "C" time_t mktime(struct tm *t); #else #include <sys/timeb.h> @@ -71,7 +71,7 @@ namespace WTF { const double msPerSecond = 1000.0; -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) #if USE(QUERY_PERFORMANCE_COUNTER) @@ -123,7 +123,7 @@ static double highResUpTime() static double lowResUTCTime() { -#if PLATFORM(WINCE) +#if OS(WINCE) SYSTEMTIME systemTime; GetSystemTime(&systemTime); struct tm tmtime; diff --git a/JavaScriptCore/wtf/CurrentTime.h b/JavaScriptCore/wtf/CurrentTime.h index 472770e..334a6e9 100644 --- a/JavaScriptCore/wtf/CurrentTime.h +++ b/JavaScriptCore/wtf/CurrentTime.h @@ -49,7 +49,7 @@ namespace WTF { inline void getLocalTime(const time_t* localTime, struct tm* localTM) { - #if COMPILER(MSVC7) || COMPILER(MINGW) || PLATFORM(WINCE) + #if COMPILER(MSVC7) || COMPILER(MINGW) || OS(WINCE) *localTM = *localtime(localTime); #elif COMPILER(MSVC) localtime_s(localTM, localTime); diff --git a/JavaScriptCore/wtf/DateMath.cpp b/JavaScriptCore/wtf/DateMath.cpp index 187fa63..b9a0207 100644 --- a/JavaScriptCore/wtf/DateMath.cpp +++ b/JavaScriptCore/wtf/DateMath.cpp @@ -88,7 +88,7 @@ #include <errno.h> #endif -#if PLATFORM(WINCE) +#if OS(WINCE) extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); extern "C" struct tm * localtime(const time_t *timer); #endif @@ -120,6 +120,10 @@ static const double secondsPerYear = 24.0 * 60.0 * 60.0 * 365.0; static const double usecPerSec = 1000000.0; static const double maxUnixTime = 2145859200.0; // 12/31/2037 +// ECMAScript asks not to support for a date of which total +// millisecond value is larger than the following value. +// See 15.9.1.14 of ECMA-262 5th edition. +static const double maxECMAScriptTime = 8.64E15; // Day of year for the first day of each month, where index 0 is January, and day 0 is January 1. // First for non-leap years, then for leap years. @@ -168,7 +172,7 @@ static inline double msToDays(double ms) return floor(ms / msPerDay); } -static inline int msToYear(double ms) +int msToYear(double ms) { int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970); double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear); @@ -179,7 +183,7 @@ static inline int msToYear(double ms) return approxYear; } -static inline int dayInYear(double ms, int year) +int dayInYear(double ms, int year) { return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year)); } @@ -225,7 +229,7 @@ static inline int msToHours(double ms) return static_cast<int>(result); } -static inline int monthFromDayInYear(int dayInYear, bool leapYear) +int monthFromDayInYear(int dayInYear, bool leapYear) { const int d = dayInYear; int step; @@ -263,7 +267,7 @@ static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& star return (dayInYear <= startDayOfNextMonth); } -static inline int dayInMonthFromDayInYear(int dayInYear, bool leapYear) +int dayInMonthFromDayInYear(int dayInYear, bool leapYear) { const int d = dayInYear; int step; @@ -306,7 +310,7 @@ static inline double timeToMS(double hour, double min, double sec, double ms) return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms); } -static int dateToDayInYear(int year, int month, int day) +double dateToDaysFrom1970(int year, int month, int day) { year += month / 12; @@ -316,7 +320,8 @@ static int dateToDayInYear(int year, int month, int day) --year; } - int yearday = static_cast<int>(floor(daysFrom1970ToYear(year))); + double yearday = floor(daysFrom1970ToYear(year)); + ASSERT((year >= 1970 && yearday >= 0) || (year < 1970 && yearday < 0)); int monthday = monthToDayInYear(month, isLeapYear(year)); return yearday + monthday + day - 1; @@ -374,7 +379,11 @@ int equivalentYearForDST(int year) static int32_t calculateUTCOffset() { +#if PLATFORM(BREWMP) + time_t localTime = static_cast<time_t>(currentTime()); +#else time_t localTime = time(0); +#endif tm localt; getLocalTime(&localTime, &localt); @@ -452,7 +461,7 @@ static double calculateDSTOffset(double ms, double utcOffset) int dayInYearLocal = dayInYear(ms, year); int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear); int month = monthFromDayInYear(dayInYearLocal, leapYear); - int day = dateToDayInYear(equivalentYear, month, dayInMonth); + double day = dateToDaysFrom1970(equivalentYear, month, dayInMonth); ms = (day * msPerDay) + msToMilliseconds(ms); } @@ -483,7 +492,7 @@ static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int // We follow the recommendation of RFC 2822 to consider all // obsolete time zones not listed here equivalent to "-0000". static const struct KnownZone { -#if !PLATFORM(WIN_OS) +#if !OS(WINDOWS) const #endif char tzName[4]; @@ -841,7 +850,7 @@ double timeClip(double t) { if (!isfinite(t)) return NaN; - if (fabs(t) > 8.64E15) + if (fabs(t) > maxECMAScriptTime) return NaN; return trunc(t); } @@ -927,7 +936,7 @@ double getUTCOffset(ExecState* exec) double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC) { - int day = dateToDayInYear(t.year + 1900, t.month, t.monthDay); + double day = dateToDaysFrom1970(t.year + 1900, t.month, t.monthDay); double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds); double result = (day * WTF::msPerDay) + ms; diff --git a/JavaScriptCore/wtf/DateMath.h b/JavaScriptCore/wtf/DateMath.h index 6d4ac1e..033d25e 100644 --- a/JavaScriptCore/wtf/DateMath.h +++ b/JavaScriptCore/wtf/DateMath.h @@ -76,8 +76,25 @@ const double msPerHour = 60.0 * 60.0 * 1000.0; const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0; const double msPerMonth = 2592000000.0; +// Returns the number of days from 1970-01-01 to the specified date. +double dateToDaysFrom1970(int year, int month, int day); +int msToYear(double ms); +int dayInYear(double ms, int year); +int monthFromDayInYear(int dayInYear, bool leapYear); +int dayInMonthFromDayInYear(int dayInYear, bool leapYear); + } // namespace WTF +using WTF::dateToDaysFrom1970; +using WTF::dayInMonthFromDayInYear; +using WTF::dayInYear; +using WTF::minutesPerHour; +using WTF::monthFromDayInYear; +using WTF::msPerDay; +using WTF::msPerSecond; +using WTF::msToYear; +using WTF::secondsPerMinute; + #if USE(JSC) namespace JSC { class ExecState; diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp index 6cd8ef0..7b14809 100644 --- a/JavaScriptCore/wtf/FastMalloc.cpp +++ b/JavaScriptCore/wtf/FastMalloc.cpp @@ -114,11 +114,13 @@ static void initializeIsForbiddenKey() pthread_key_create(&isForbiddenKey, 0); } +#if !ASSERT_DISABLED static bool isForbidden() { pthread_once(&isForbiddenKeyOnce, initializeIsForbiddenKey); return !!pthread_getspecific(isForbiddenKey); } +#endif void fastMallocForbid() { @@ -177,6 +179,17 @@ void* fastZeroedMalloc(size_t n) memset(result, 0, n); return result; } + +char* fastStrDup(const char* src) +{ + int len = strlen(src) + 1; + char* dup = static_cast<char*>(fastMalloc(len)); + + if (dup) + memcpy(dup, src, len); + + return dup; +} TryMallocReturnValue tryFastZeroedMalloc(size_t n) { @@ -191,13 +204,6 @@ TryMallocReturnValue tryFastZeroedMalloc(size_t n) #if FORCE_SYSTEM_MALLOC -#include <stdlib.h> -#if !PLATFORM(WIN_OS) - #include <pthread.h> -#else - #include "windows.h" -#endif - namespace WTF { TryMallocReturnValue tryFastMalloc(size_t n) @@ -349,7 +355,7 @@ FastMallocStatistics fastMallocStatistics() } // namespace WTF -#if PLATFORM(DARWIN) +#if OS(DARWIN) // This symbol is present in the JavaScriptCore exports file even when FastMalloc is disabled. // It will never be used in this case, so it's type and value are less interesting than its presence. extern "C" const int jscore_fastmalloc_introspection = 0; @@ -379,7 +385,7 @@ extern "C" const int jscore_fastmalloc_introspection = 0; #include <stdarg.h> #include <stddef.h> #include <stdio.h> -#if PLATFORM(UNIX) +#if OS(UNIX) #include <unistd.h> #endif #if COMPILER(MSVC) @@ -391,11 +397,15 @@ extern "C" const int jscore_fastmalloc_introspection = 0; #if WTF_CHANGES -#if PLATFORM(DARWIN) +#if OS(DARWIN) #include "MallocZoneSupport.h" #include <wtf/HashSet.h> #include <wtf/Vector.h> #endif +#if HAVE(DISPATCH_H) +#include <dispatch/dispatch.h> +#endif + #ifndef PRIuS #define PRIuS "zu" @@ -405,7 +415,7 @@ extern "C" const int jscore_fastmalloc_introspection = 0; // call to the function on Mac OS X, and it's used in performance-critical code. So we // use a function pointer. But that's not necessarily faster on other platforms, and we had // problems with this technique on Windows, so we'll do this only on Mac OS X. -#if PLATFORM(DARWIN) +#if OS(DARWIN) static void* (*pthread_getspecific_function_pointer)(pthread_key_t) = pthread_getspecific; #define pthread_getspecific(key) pthread_getspecific_function_pointer(key) #endif @@ -433,7 +443,7 @@ namespace WTF { #define MESSAGE LOG_ERROR #define CHECK_CONDITION ASSERT -#if PLATFORM(DARWIN) +#if OS(DARWIN) class Span; class TCMalloc_Central_FreeListPadded; class TCMalloc_PageHeap; @@ -990,7 +1000,7 @@ class PageHeapAllocator { int inuse() const { return inuse_; } -#if defined(WTF_CHANGES) && PLATFORM(DARWIN) +#if defined(WTF_CHANGES) && OS(DARWIN) template <class Recorder> void recordAdministrativeRegions(Recorder& recorder, const RemoteMemoryReader& reader) { @@ -1172,7 +1182,7 @@ template <int BITS> class MapSelector { }; #if defined(WTF_CHANGES) -#if PLATFORM(X86_64) +#if CPU(X86_64) // On all known X86-64 platforms, the upper 16 bits are always unused and therefore // can be excluded from the PageMap key. // See http://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details @@ -1223,7 +1233,7 @@ static const int kScavengeTimerDelayInSeconds = 5; static const size_t kMinimumFreeCommittedPageCount = 512; // During a scavenge, we'll release up to a fraction of the free committed pages. -#if PLATFORM(WIN) +#if OS(WINDOWS) // We are slightly less aggressive in releasing memory on Windows due to performance reasons. static const int kMaxScavengeAmountFactor = 3; #else @@ -1372,26 +1382,34 @@ class TCMalloc_PageHeap { // Index of last free list we scavenged size_t scavenge_index_; -#if defined(WTF_CHANGES) && PLATFORM(DARWIN) +#if defined(WTF_CHANGES) && OS(DARWIN) friend class FastMallocZone; #endif #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - static NO_RETURN void* runScavengerThread(void*); + void initializeScavenger(); + ALWAYS_INLINE void signalScavenger(); + void scavenge(); + ALWAYS_INLINE bool shouldContinueScavenging() const; +#if !HAVE(DISPATCH_H) + static NO_RETURN void* runScavengerThread(void*); NO_RETURN void scavengerThread(); - void scavenge(); - - inline bool shouldContinueScavenging() const; + // Keeps track of whether the background thread is actively scavenging memory every kScavengeTimerDelayInSeconds, or + // it's blocked waiting for more pages to be deleted. + bool m_scavengeThreadActive; pthread_mutex_t m_scavengeMutex; - pthread_cond_t m_scavengeCondition; +#else // !HAVE(DISPATCH_H) + void periodicScavenge(); + + dispatch_queue_t m_scavengeQueue; + dispatch_source_t m_scavengeTimer; + bool m_scavengingScheduled; +#endif - // Keeps track of whether the background thread is actively scavenging memory every kScavengeTimerDelayInSeconds, or - // it's blocked waiting for more pages to be deleted. - bool m_scavengeThreadActive; #endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY }; @@ -1419,15 +1437,23 @@ void TCMalloc_PageHeap::init() } #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + initializeScavenger(); +#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY +} + +#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY + +#if !HAVE(DISPATCH_H) + +void TCMalloc_PageHeap::initializeScavenger() +{ pthread_mutex_init(&m_scavengeMutex, 0); pthread_cond_init(&m_scavengeCondition, 0); m_scavengeThreadActive = true; pthread_t thread; pthread_create(&thread, 0, runScavengerThread, this); -#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY } -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY void* TCMalloc_PageHeap::runScavengerThread(void* context) { static_cast<TCMalloc_PageHeap*>(context)->scavengerThread(); @@ -1437,6 +1463,34 @@ void* TCMalloc_PageHeap::runScavengerThread(void* context) #endif } +ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger() +{ + if (!m_scavengeThreadActive && shouldContinueScavenging()) + pthread_cond_signal(&m_scavengeCondition); +} + +#else // !HAVE(DISPATCH_H) + +void TCMalloc_PageHeap::initializeScavenger() +{ + m_scavengeQueue = dispatch_queue_create("com.apple.JavaScriptCore.FastMallocSavenger", NULL); + m_scavengeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_scavengeQueue); + dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, kScavengeTimerDelayInSeconds * NSEC_PER_SEC); + dispatch_source_set_timer(m_scavengeTimer, startTime, kScavengeTimerDelayInSeconds * NSEC_PER_SEC, 1000 * NSEC_PER_USEC); + dispatch_source_set_event_handler(m_scavengeTimer, ^{ periodicScavenge(); }); + m_scavengingScheduled = false; +} + +ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger() +{ + if (!m_scavengingScheduled && shouldContinueScavenging()) { + m_scavengingScheduled = true; + dispatch_resume(m_scavengeTimer); + } +} + +#endif + void TCMalloc_PageHeap::scavenge() { // If we have to commit memory in the last 5 seconds, it means we don't have enough free committed pages @@ -1472,7 +1526,7 @@ void TCMalloc_PageHeap::scavenge() free_committed_pages_ -= pagesDecommitted; } -inline bool TCMalloc_PageHeap::shouldContinueScavenging() const +ALWAYS_INLINE bool TCMalloc_PageHeap::shouldContinueScavenging() const { return free_committed_pages_ > kMinimumFreeCommittedPageCount; } @@ -1734,8 +1788,7 @@ inline void TCMalloc_PageHeap::Delete(Span* span) { } // Make sure the scavenge thread becomes active if we have enough freed pages to release some back to the system. - if (!m_scavengeThreadActive && shouldContinueScavenging()) - pthread_cond_signal(&m_scavengeCondition); + signalScavenger(); #else IncrementalScavenge(n); #endif @@ -2278,7 +2331,9 @@ static inline TCMalloc_PageHeap* getPageHeap() #define pageheap getPageHeap() #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY -#if PLATFORM(WIN_OS) + +#if !HAVE(DISPATCH_H) +#if OS(WINDOWS) static void sleep(unsigned seconds) { ::Sleep(seconds * 1000); @@ -2307,6 +2362,23 @@ void TCMalloc_PageHeap::scavengerThread() } } } + +#else + +void TCMalloc_PageHeap::periodicScavenge() +{ + { + SpinLockHolder h(&pageheap_lock); + pageheap->scavenge(); + } + + if (!shouldContinueScavenging()) { + m_scavengingScheduled = false; + dispatch_suspend(m_scavengeTimer); + } +} +#endif // HAVE(DISPATCH_H) + #endif // If TLS is available, we also store a copy @@ -2816,7 +2888,7 @@ void TCMalloc_ThreadCache::InitModule() { } pageheap->init(); phinited = 1; -#if defined(WTF_CHANGES) && PLATFORM(DARWIN) +#if defined(WTF_CHANGES) && OS(DARWIN) FastMallocZone::init(); #endif } @@ -3795,7 +3867,7 @@ void* realloc(void* old_ptr, size_t new_size) { return new_ptr; } else { #if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - old_ptr = pByte + sizeof(AllocAlignmentInteger); // Set old_ptr back to the user pointer. + old_ptr = static_cast<AllocAlignmentInteger*>(old_ptr) + 1; // Set old_ptr back to the user pointer. #endif return old_ptr; } @@ -4014,7 +4086,7 @@ void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride; #endif -#if defined(WTF_CHANGES) && PLATFORM(DARWIN) +#if defined(WTF_CHANGES) && OS(DARWIN) class FreeObjectFinder { const RemoteMemoryReader& m_reader; @@ -4297,7 +4369,7 @@ extern "C" { malloc_introspection_t jscore_fastmalloc_introspection = { &FastMallocZone::enumerate, &FastMallocZone::goodSize, &FastMallocZone::check, &FastMallocZone::print, &FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE) +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !OS(IPHONE_OS) , 0 // zone_locked will not be called on the zone unless it advertises itself as version five or higher. #endif diff --git a/JavaScriptCore/wtf/FastMalloc.h b/JavaScriptCore/wtf/FastMalloc.h index abe4a58..74d4307 100644 --- a/JavaScriptCore/wtf/FastMalloc.h +++ b/JavaScriptCore/wtf/FastMalloc.h @@ -33,6 +33,7 @@ namespace WTF { void* fastZeroedMalloc(size_t); void* fastCalloc(size_t numElements, size_t elementSize); void* fastRealloc(void*, size_t); + char* fastStrDup(const char*); struct TryMallocReturnValue { TryMallocReturnValue(void* data) @@ -188,17 +189,18 @@ using WTF::tryFastZeroedMalloc; using WTF::tryFastCalloc; using WTF::tryFastRealloc; using WTF::fastFree; +using WTF::fastStrDup; #ifndef NDEBUG using WTF::fastMallocForbid; using WTF::fastMallocAllow; #endif -#if COMPILER(GCC) && PLATFORM(DARWIN) +#if COMPILER(GCC) && OS(DARWIN) #define WTF_PRIVATE_INLINE __private_extern__ inline __attribute__((always_inline)) #elif COMPILER(GCC) #define WTF_PRIVATE_INLINE inline __attribute__((always_inline)) -#elif COMPILER(MSVC) +#elif COMPILER(MSVC) || COMPILER(RVCT) #define WTF_PRIVATE_INLINE __forceinline #else #define WTF_PRIVATE_INLINE inline diff --git a/JavaScriptCore/wtf/HashFunctions.h b/JavaScriptCore/wtf/HashFunctions.h index 13afb72..2c66a2d 100644 --- a/JavaScriptCore/wtf/HashFunctions.h +++ b/JavaScriptCore/wtf/HashFunctions.h @@ -173,9 +173,6 @@ namespace WTF { template<typename P> struct DefaultHash<RefPtr<P> > { typedef PtrHash<RefPtr<P> > Hash; }; template<typename T, typename U> struct DefaultHash<std::pair<T, U> > { typedef PairHash<T, U> Hash; }; - - // Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's - static const unsigned stringHashingStartValue = 0x9e3779b9U; } // namespace WTF diff --git a/JavaScriptCore/wtf/HashMap.h b/JavaScriptCore/wtf/HashMap.h index ece3812..d63a8d4 100644 --- a/JavaScriptCore/wtf/HashMap.h +++ b/JavaScriptCore/wtf/HashMap.h @@ -100,6 +100,8 @@ namespace WTF { // static translate(ValueType&, const T&, unsigned hashCode); template<typename T, typename HashTranslator> pair<iterator, bool> add(const T&, const MappedType&); + void checkConsistency() const; + private: pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&); @@ -281,7 +283,7 @@ namespace WTF { { if (it.m_impl == m_impl.end()) return; - m_impl.checkTableConsistency(); + m_impl.internalCheckTableConsistency(); m_impl.removeWithoutEntryConsistencyCheck(it.m_impl); } @@ -311,6 +313,13 @@ namespace WTF { } template<typename T, typename U, typename V, typename W, typename X> + inline void HashMap<T, U, V, W, X>::checkConsistency() const + { + m_impl.checkTableConsistency(); + } + + + template<typename T, typename U, typename V, typename W, typename X> bool operator==(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b) { if (a.size() != b.size()) diff --git a/JavaScriptCore/wtf/HashSet.h b/JavaScriptCore/wtf/HashSet.h index 0d7b4bb..4429490 100644 --- a/JavaScriptCore/wtf/HashSet.h +++ b/JavaScriptCore/wtf/HashSet.h @@ -224,7 +224,7 @@ namespace WTF { { if (it.m_impl == m_impl.end()) return; - m_impl.checkTableConsistency(); + m_impl.internalCheckTableConsistency(); m_impl.removeWithoutEntryConsistencyCheck(it.m_impl); } diff --git a/JavaScriptCore/wtf/HashTable.h b/JavaScriptCore/wtf/HashTable.h index 3b283f8..f1473e3 100644 --- a/JavaScriptCore/wtf/HashTable.h +++ b/JavaScriptCore/wtf/HashTable.h @@ -30,6 +30,7 @@ namespace WTF { #define DUMP_HASHTABLE_STATS 0 +// Enables internal WTF consistency checks that are invoked automatically. Non-WTF callers can call checkTableConsistency() even if internal checks are disabled. #define CHECK_HASHTABLE_CONSISTENCY 0 #ifdef NDEBUG @@ -197,7 +198,7 @@ namespace WTF { void checkValidity(const const_iterator& other) const { ASSERT(m_table); - ASSERT(other.m_table); + ASSERT_UNUSED(other, other.m_table); ASSERT(m_table == other.m_table); } #else @@ -340,11 +341,18 @@ namespace WTF { ValueType* lookup(const Key& key) { return lookup<Key, IdentityTranslatorType>(key); } template<typename T, typename HashTranslator> ValueType* lookup(const T&); -#if CHECK_HASHTABLE_CONSISTENCY +#if !ASSERT_DISABLED void checkTableConsistency() const; #else static void checkTableConsistency() { } #endif +#if CHECK_HASHTABLE_CONSISTENCY + void internalCheckTableConsistency() const { checkTableConsistency(); } + void internalCheckTableConsistencyExceptSize() const { checkTableConsistencyExceptSize(); } +#else + static void internalCheckTableConsistencyExceptSize() { } + static void internalCheckTableConsistency() { } +#endif private: static ValueType* allocateTable(int size); @@ -383,7 +391,7 @@ namespace WTF { iterator makeKnownGoodIterator(ValueType* pos) { return iterator(this, pos, m_table + m_tableSize, HashItemKnownGood); } const_iterator makeKnownGoodConstIterator(ValueType* pos) const { return const_iterator(this, pos, m_table + m_tableSize, HashItemKnownGood); } -#if CHECK_HASHTABLE_CONSISTENCY +#if !ASSERT_DISABLED void checkTableConsistencyExceptSize() const; #else static void checkTableConsistencyExceptSize() { } @@ -624,7 +632,7 @@ namespace WTF { if (!m_table) expand(); - checkTableConsistency(); + internalCheckTableConsistency(); ASSERT(m_table); @@ -693,7 +701,7 @@ namespace WTF { return p; } - checkTableConsistency(); + internalCheckTableConsistency(); return std::make_pair(makeKnownGoodIterator(entry), true); } @@ -709,7 +717,7 @@ namespace WTF { if (!m_table) expand(); - checkTableConsistency(); + internalCheckTableConsistency(); FullLookupType lookupResult = fullLookupForWriting<T, HashTranslator>(key); @@ -738,7 +746,7 @@ namespace WTF { return p; } - checkTableConsistency(); + internalCheckTableConsistency(); return std::make_pair(makeKnownGoodIterator(entry), true); } @@ -805,7 +813,7 @@ namespace WTF { void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::removeAndInvalidate(ValueType* pos) { invalidateIterators(); - checkTableConsistency(); + internalCheckTableConsistency(); remove(pos); } @@ -823,7 +831,7 @@ namespace WTF { if (shouldShrink()) shrink(); - checkTableConsistency(); + internalCheckTableConsistency(); } template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> @@ -892,7 +900,7 @@ namespace WTF { template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::rehash(int newTableSize) { - checkTableConsistencyExceptSize(); + internalCheckTableConsistencyExceptSize(); int oldTableSize = m_tableSize; ValueType* oldTable = m_table; @@ -914,7 +922,7 @@ namespace WTF { deallocateTable(oldTable, oldTableSize); - checkTableConsistency(); + internalCheckTableConsistency(); } template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> @@ -981,13 +989,13 @@ namespace WTF { return *this; } -#if CHECK_HASHTABLE_CONSISTENCY +#if !ASSERT_DISABLED template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::checkTableConsistency() const { checkTableConsistencyExceptSize(); - ASSERT(!shouldExpand()); + ASSERT(!m_table || !shouldExpand()); ASSERT(!shouldShrink()); } @@ -1012,6 +1020,8 @@ namespace WTF { const_iterator it = find(Extractor::extract(*entry)); ASSERT(entry == it.m_position); ++count; + + KeyTraits::checkValueConsistency(it->first); } ASSERT(count == m_keyCount); @@ -1021,7 +1031,7 @@ namespace WTF { ASSERT(m_tableSize == m_tableSizeMask + 1); } -#endif // CHECK_HASHTABLE_CONSISTENCY +#endif // ASSERT_DISABLED #if CHECK_HASHTABLE_ITERATORS diff --git a/JavaScriptCore/wtf/HashTraits.h b/JavaScriptCore/wtf/HashTraits.h index c8d40f7..96ecac9 100644 --- a/JavaScriptCore/wtf/HashTraits.h +++ b/JavaScriptCore/wtf/HashTraits.h @@ -26,6 +26,13 @@ #include <utility> #include <limits> +// For malloc_size and _msize. +#if OS(DARWIN) +#include <malloc/malloc.h> +#elif COMPILER(MSVC) +#include <malloc.h> +#endif + namespace WTF { using std::pair; @@ -51,6 +58,7 @@ namespace WTF { template<typename T> struct GenericHashTraits : GenericHashTraitsBase<IsInteger<T>::value, T> { typedef T TraitType; static T emptyValue() { return T(); } + static void checkValueConsistency(const T&) { } }; template<typename T> struct HashTraits : GenericHashTraits<T> { }; @@ -79,6 +87,19 @@ namespace WTF { static const bool needsDestruction = false; static void constructDeletedValue(P*& slot) { slot = reinterpret_cast<P*>(-1); } static bool isDeletedValue(P* value) { return value == reinterpret_cast<P*>(-1); } +#if !ASSERT_DISABLED + static void checkValueConsistency(const P* p) + { +#if (defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) || !defined(NDEBUG) +#if OS(DARWIN) + ASSERT(malloc_size(p)); +#elif COMPILER(MSVC) + ASSERT(_msize(const_cast<P*>(p))); +#endif +#endif + HashTraits<P>::checkValueConsistency(*p); + } +#endif }; template<typename P> struct HashTraits<RefPtr<P> > : GenericHashTraits<RefPtr<P> > { diff --git a/JavaScriptCore/wtf/MathExtras.h b/JavaScriptCore/wtf/MathExtras.h index ee2110e..a18949e 100644 --- a/JavaScriptCore/wtf/MathExtras.h +++ b/JavaScriptCore/wtf/MathExtras.h @@ -30,17 +30,17 @@ #include <math.h> #include <stdlib.h> -#if PLATFORM(SOLARIS) +#if OS(SOLARIS) #include <ieeefp.h> #endif -#if PLATFORM(OPENBSD) +#if OS(OPENBSD) #include <sys/types.h> #include <machine/ieee.h> #endif #if COMPILER(MSVC) -#if PLATFORM(WINCE) +#if OS(WINCE) #include <stdlib.h> #endif #include <limits> @@ -62,7 +62,7 @@ const double piOverFourDouble = M_PI_4; const float piOverFourFloat = static_cast<float>(M_PI_4); #endif -#if PLATFORM(DARWIN) +#if OS(DARWIN) // Work around a bug in the Mac OS X libc where ceil(-0.1) return +0. inline double wtf_ceil(double x) { return copysign(ceil(x), x); } @@ -71,7 +71,7 @@ inline double wtf_ceil(double x) { return copysign(ceil(x), x); } #endif -#if PLATFORM(SOLARIS) +#if OS(SOLARIS) #ifndef isfinite inline bool isfinite(double x) { return finite(x) && !isnand(x); } @@ -85,7 +85,7 @@ inline bool signbit(double x) { return x < 0.0; } // FIXME: Wrong for negative 0 #endif -#if PLATFORM(OPENBSD) +#if OS(OPENBSD) #ifndef isfinite inline bool isfinite(double x) { return finite(x); } @@ -98,12 +98,25 @@ inline bool signbit(double x) { struct ieee_double *p = (struct ieee_double *)&x #if COMPILER(MSVC) || COMPILER(RVCT) -inline long long llround(double num) { return static_cast<long long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); } -inline long long llroundf(float num) { return static_cast<long long>(num > 0 ? num + 0.5f : ceil(num - 0.5f)); } -inline long lround(double num) { return static_cast<long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); } -inline long lroundf(float num) { return static_cast<long>(num > 0 ? num + 0.5f : ceilf(num - 0.5f)); } -inline double round(double num) { return num > 0 ? floor(num + 0.5) : ceil(num - 0.5); } -inline float roundf(float num) { return num > 0 ? floorf(num + 0.5f) : ceilf(num - 0.5f); } +// We must not do 'num + 0.5' or 'num - 0.5' because they can cause precision loss. +static double round(double num) +{ + double integer = ceil(num); + if (num > 0) + return integer - num > 0.5 ? integer - 1.0 : integer; + return integer - num >= 0.5 ? integer - 1.0 : integer; +} +static float roundf(float num) +{ + float integer = ceilf(num); + if (num > 0) + return integer - num > 0.5f ? integer - 1.0f : integer; + return integer - num >= 0.5f ? integer - 1.0f : integer; +} +inline long long llround(double num) { return static_cast<long long>(round(num)); } +inline long long llroundf(float num) { return static_cast<long long>(roundf(num)); } +inline long lround(double num) { return static_cast<long>(round(num)); } +inline long lroundf(float num) { return static_cast<long>(roundf(num)); } inline double trunc(double num) { return num > 0 ? floor(num) : ceil(num); } #endif diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index 960b253..5bc9658 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -27,118 +27,377 @@ #ifndef WTF_Platform_h #define WTF_Platform_h -/* PLATFORM handles OS, operating environment, graphics API, and CPU */ +/* ==== PLATFORM handles OS, operating environment, graphics API, and + CPU. This macro will be phased out in favor of platform adaptation + macros, policy decision macros, and top-level port definitions. ==== */ #define PLATFORM(WTF_FEATURE) (defined WTF_PLATFORM_##WTF_FEATURE && WTF_PLATFORM_##WTF_FEATURE) + + +/* ==== Platform adaptation macros: these describe properties of the target environment. ==== */ + +/* COMPILER() - the compiler being used to build the project */ #define COMPILER(WTF_FEATURE) (defined WTF_COMPILER_##WTF_FEATURE && WTF_COMPILER_##WTF_FEATURE) +/* CPU() - the target CPU architecture */ +#define CPU(WTF_FEATURE) (defined WTF_CPU_##WTF_FEATURE && WTF_CPU_##WTF_FEATURE) +/* HAVE() - specific system features (headers, functions or similar) that are present or not */ #define HAVE(WTF_FEATURE) (defined HAVE_##WTF_FEATURE && HAVE_##WTF_FEATURE) +/* OS() - underlying operating system; only to be used for mandated low-level services like + virtual memory, not to choose a GUI toolkit */ +#define OS(WTF_FEATURE) (defined WTF_OS_##WTF_FEATURE && WTF_OS_##WTF_FEATURE) + + +/* ==== Policy decision macros: these define policy choices for a particular port. ==== */ + +/* USE() - use a particular third-party library or optional OS service */ #define USE(WTF_FEATURE) (defined WTF_USE_##WTF_FEATURE && WTF_USE_##WTF_FEATURE) +/* ENABLE() - turn on a specific feature of WebKit */ #define ENABLE(WTF_FEATURE) (defined ENABLE_##WTF_FEATURE && ENABLE_##WTF_FEATURE) -/* Operating systems - low-level dependencies */ -/* PLATFORM(DARWIN) */ -/* Operating system level dependencies for Mac OS X / Darwin that should */ -/* be used regardless of operating environment */ + +/* ==== COMPILER() - the compiler being used to build the project ==== */ + +/* COMPILER(MSVC) Microsoft Visual C++ */ +/* COMPILER(MSVC7) Microsoft Visual C++ v7 or lower*/ +#if defined(_MSC_VER) +#define WTF_COMPILER_MSVC 1 +#if _MSC_VER < 1400 +#define WTF_COMPILER_MSVC7 1 +#endif +#endif + +/* COMPILER(RVCT) - ARM RealView Compilation Tools */ +#if defined(__CC_ARM) || defined(__ARMCC__) +#define WTF_COMPILER_RVCT 1 +#endif + +/* COMPILER(GCC) - GNU Compiler Collection */ +/* --gnu option of the RVCT compiler also defines __GNUC__ */ +#if defined(__GNUC__) && !COMPILER(RVCT) +#define WTF_COMPILER_GCC 1 +#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +/* COMPILER(MINGW) - MinGW GCC */ +#if defined(MINGW) || defined(__MINGW32__) +#define WTF_COMPILER_MINGW 1 +#endif + +/* COMPILER(WINSCW) - CodeWarrior for Symbian emulator */ +#if defined(__WINSCW__) +#define WTF_COMPILER_WINSCW 1 +#endif + + + +/* ==== CPU() - the target CPU architecture ==== */ + +/* This also defines CPU(BIG_ENDIAN) or CPU(MIDDLE_ENDIAN) or neither, as appropriate. */ + +/* CPU(ALPHA) - DEC Alpha */ +#if defined(__alpha__) +#define WTF_CPU_ALPHA 1 +#endif + +/* CPU(IA64) - Itanium / IA-64 */ +#if defined(__ia64__) +#define WTF_CPU_IA64 1 +#endif + +/* CPU(PPC) - PowerPC 32-bit */ +#if defined(__ppc__) \ + || defined(__PPC__) \ + || defined(__powerpc__) \ + || defined(__powerpc) \ + || defined(__POWERPC__) \ + || defined(_M_PPC) \ + || defined(__PPC) +#define WTF_CPU_PPC 1 +#define WTF_CPU_BIG_ENDIAN 1 +#endif + +/* CPU(PPC64) - PowerPC 64-bit */ +#if defined(__ppc64__) \ + || defined(__PPC64__) +#define WTF_CPU_PPC64 1 +#define WTF_CPU_BIG_ENDIAN 1 +#endif + +/* CPU(SH4) - SuperH SH-4 */ +#if defined(__SH4__) +#define WTF_CPU_SH4 1 +#endif + +/* CPU(SPARC32) - SPARC 32-bit */ +#if defined(__sparc) && !defined(__arch64__) || defined(__sparcv8) +#define WTF_CPU_SPARC32 1 +#define WTF_CPU_BIG_ENDIAN 1 +#endif + +/* CPU(SPARC64) - SPARC 64-bit */ +#if defined(__sparc__) && defined(__arch64__) || defined (__sparcv9) +#define WTF_CPU_SPARC64 1 +#define WTF_CPU_BIG_ENDIAN 1 +#endif + +/* CPU(SPARC) - any SPARC, true for CPU(SPARC32) and CPU(SPARC64) */ +#if CPU(SPARC32) || CPU(SPARC64) +#define WTF_CPU_SPARC +#endif + +/* CPU(X86) - i386 / x86 32-bit */ +#if defined(__i386__) \ + || defined(i386) \ + || defined(_M_IX86) \ + || defined(_X86_) \ + || defined(__THW_INTEL) +#define WTF_CPU_X86 1 +#endif + +/* CPU(X86_64) - AMD64 / Intel64 / x86_64 64-bit */ +#if defined(__x86_64__) \ + || defined(_M_X64) +#define WTF_CPU_X86_64 1 +#endif + +/* CPU(ARM) - ARM, any version*/ +#if defined(arm) \ + || defined(__arm__) +#define WTF_CPU_ARM 1 + +#if defined(__ARMEB__) +#define WTF_CPU_BIG_ENDIAN 1 + +#elif !defined(__ARM_EABI__) \ + && !defined(__EABI__) \ + && !defined(__VFP_FP__) \ + && !defined(ANDROID) +#define WTF_CPU_MIDDLE_ENDIAN 1 + +#endif + +#define WTF_ARM_ARCH_AT_LEAST(N) (CPU(ARM) && WTF_ARM_ARCH_VERSION >= N) + +/* Set WTF_ARM_ARCH_VERSION */ +#if defined(__ARM_ARCH_4__) \ + || defined(__ARM_ARCH_4T__) \ + || defined(__MARM_ARMV4__) \ + || defined(_ARMV4I_) +#define WTF_ARM_ARCH_VERSION 4 + +#elif defined(__ARM_ARCH_5__) \ + || defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5E__) \ + || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) \ + || defined(__MARM_ARMV5__) +#define WTF_ARM_ARCH_VERSION 5 + +#elif defined(__ARM_ARCH_6__) \ + || defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6T2__) \ + || defined(__ARMV6__) +#define WTF_ARM_ARCH_VERSION 6 + +#elif defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) +#define WTF_ARM_ARCH_VERSION 7 + +/* RVCT sets _TARGET_ARCH_ARM */ +#elif defined(__TARGET_ARCH_ARM) +#define WTF_ARM_ARCH_VERSION __TARGET_ARCH_ARM + +#else +#define WTF_ARM_ARCH_VERSION 0 + +#endif + +/* Set WTF_THUMB_ARCH_VERSION */ +#if defined(__ARM_ARCH_4T__) +#define WTF_THUMB_ARCH_VERSION 1 + +#elif defined(__ARM_ARCH_5T__) \ + || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) +#define WTF_THUMB_ARCH_VERSION 2 + +#elif defined(__ARM_ARCH_6J__) \ + || defined(__ARM_ARCH_6K__) \ + || defined(__ARM_ARCH_6Z__) \ + || defined(__ARM_ARCH_6ZK__) \ + || defined(__ARM_ARCH_6M__) +#define WTF_THUMB_ARCH_VERSION 3 + +#elif defined(__ARM_ARCH_6T2__) \ + || defined(__ARM_ARCH_7__) \ + || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) \ + || defined(__ARM_ARCH_7M__) +#define WTF_THUMB_ARCH_VERSION 4 + +/* RVCT sets __TARGET_ARCH_THUMB */ +#elif defined(__TARGET_ARCH_THUMB) +#define WTF_THUMB_ARCH_VERSION __TARGET_ARCH_THUMB + +#else +#define WTF_THUMB_ARCH_VERSION 0 +#endif + + +/* CPU(ARMV5_OR_LOWER) - ARM instruction set v5 or earlier */ +/* On ARMv5 and below the natural alignment is required. + And there are some other differences for v5 or earlier. */ +#if !defined(ARMV5_OR_LOWER) && !WTF_ARM_ARCH_AT_LEAST(6) +#define WTF_CPU_ARMV5_OR_LOWER 1 +#endif + + +/* CPU(ARM_TRADITIONAL) - Thumb2 is not available, only traditional ARM (v4 or greater) */ +/* CPU(ARM_THUMB2) - Thumb2 instruction set is available */ +/* Only one of these will be defined. */ +#if !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2) +# if defined(thumb2) || defined(__thumb2__) \ + || ((defined(__thumb) || defined(__thumb__)) && WTF_THUMB_ARCH_VERSION == 4) +# define WTF_CPU_ARM_TRADITIONAL 0 +# define WTF_CPU_ARM_THUMB2 1 +# elif WTF_ARM_ARCH_AT_LEAST(4) +# define WTF_CPU_ARM_TRADITIONAL 1 +# define WTF_CPU_ARM_THUMB2 0 +# else +# error "Not supported ARM architecture" +# endif +#elif CPU(ARM_TRADITIONAL) && CPU(ARM_THUMB2) /* Sanity Check */ +# error "Cannot use both of WTF_CPU_ARM_TRADITIONAL and WTF_CPU_ARM_THUMB2 platforms" +#endif /* !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2) */ + +#endif /* ARM */ + + + +/* ==== OS() - underlying operating system; only to be used for mandated low-level services like + virtual memory, not to choose a GUI toolkit ==== */ + +/* OS(ANDROID) - Android */ +#ifdef ANDROID +#define WTF_OS_ANDROID 1 +#endif + +/* OS(AIX) - AIX */ +#ifdef _AIX +#define WTF_OS_AIX 1 +#endif + +/* OS(DARWIN) - Any Darwin-based OS, including Mac OS X and iPhone OS */ #ifdef __APPLE__ -#define WTF_PLATFORM_DARWIN 1 +#define WTF_OS_DARWIN 1 + +/* FIXME: BUILDING_ON_.., and TARGETING... macros should be folded into the OS() system */ #include <AvailabilityMacros.h> #if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 #define BUILDING_ON_TIGER 1 #elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 #define BUILDING_ON_LEOPARD 1 +#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 +#define BUILDING_ON_SNOW_LEOPARD 1 #endif #if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 #define TARGETING_TIGER 1 #elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6 #define TARGETING_LEOPARD 1 +#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7 +#define TARGETING_SNOW_LEOPARD 1 #endif #include <TargetConditionals.h> + #endif -/* PLATFORM(WIN_OS) */ -/* Operating system level dependencies for Windows that should be used */ -/* regardless of operating environment */ -#if defined(WIN32) || defined(_WIN32) -#define WTF_PLATFORM_WIN_OS 1 +/* OS(IPHONE_OS) - iPhone OS */ +/* OS(MAC_OS_X) - Mac OS X (not including iPhone OS) */ +#if OS(DARWIN) && ((defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) \ + || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) \ + || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR)) +#define WTF_OS_IPHONE_OS 1 +#elif OS(DARWIN) && defined(TARGET_OS_MAC) && TARGET_OS_MAC +#define WTF_OS_MAC_OS_X 1 #endif -/* PLATFORM(WINCE) */ -/* Operating system level dependencies for Windows CE that should be used */ -/* regardless of operating environment */ -/* Note that for this platform PLATFORM(WIN_OS) is also defined. */ -#if defined(_WIN32_WCE) -#define WTF_PLATFORM_WINCE 1 +/* OS(FREEBSD) - FreeBSD */ +#ifdef __FreeBSD__ +#define WTF_OS_FREEBSD 1 #endif -/* PLATFORM(LINUX) */ -/* Operating system level dependencies for Linux-like systems that */ -/* should be used regardless of operating environment */ +/* OS(HAIKU) - Haiku */ +#ifdef __HAIKU__ +#define WTF_OS_HAIKU 1 +#endif + +/* OS(LINUX) - Linux */ #ifdef __linux__ -#define WTF_PLATFORM_LINUX 1 +#define WTF_OS_LINUX 1 #endif -/* PLATFORM(FREEBSD) */ -/* Operating system level dependencies for FreeBSD-like systems that */ -/* should be used regardless of operating environment */ -#ifdef __FreeBSD__ -#define WTF_PLATFORM_FREEBSD 1 +/* OS(NETBSD) - NetBSD */ +#if defined(__NetBSD__) +#define WTF_PLATFORM_NETBSD 1 #endif -/* PLATFORM(OPENBSD) */ -/* Operating system level dependencies for OpenBSD systems that */ -/* should be used regardless of operating environment */ +/* OS(OPENBSD) - OpenBSD */ #ifdef __OpenBSD__ -#define WTF_PLATFORM_OPENBSD 1 +#define WTF_OS_OPENBSD 1 #endif -/* PLATFORM(SOLARIS) */ -/* Operating system level dependencies for Solaris that should be used */ -/* regardless of operating environment */ -#if defined(sun) || defined(__sun) -#define WTF_PLATFORM_SOLARIS 1 +/* OS(QNX) - QNX */ +#if defined(__QNXNTO__) +#define WTF_OS_QNX 1 #endif -#if defined (__SYMBIAN32__) -/* we are cross-compiling, it is not really windows */ -#undef WTF_PLATFORM_WIN_OS -#undef WTF_PLATFORM_WIN -#define WTF_PLATFORM_SYMBIAN 1 +/* OS(SOLARIS) - Solaris */ +#if defined(sun) || defined(__sun) +#define WTF_OS_SOLARIS 1 #endif +/* OS(WINCE) - Windows CE; note that for this platform OS(WINDOWS) is also defined */ +#if defined(_WIN32_WCE) +#define WTF_OS_WINCE 1 +#endif -/* PLATFORM(NETBSD) */ -/* Operating system level dependencies for NetBSD that should be used */ -/* regardless of operating environment */ -#if defined(__NetBSD__) -#define WTF_PLATFORM_NETBSD 1 +/* OS(WINDOWS) - Any version of Windows */ +#if defined(WIN32) || defined(_WIN32) +#define WTF_OS_WINDOWS 1 #endif -/* PLATFORM(QNX) */ -/* Operating system level dependencies for QNX that should be used */ -/* regardless of operating environment */ -#if defined(__QNXNTO__) -#define WTF_PLATFORM_QNX 1 -#endif - -/* PLATFORM(UNIX) */ -/* Operating system level dependencies for Unix-like systems that */ -/* should be used regardless of operating environment */ -#if PLATFORM(DARWIN) \ - || PLATFORM(FREEBSD) \ - || PLATFORM(SYMBIAN) \ - || PLATFORM(NETBSD) \ - || defined(unix) \ - || defined(__unix) \ - || defined(__unix__) \ - || defined(_AIX) \ - || defined(__HAIKU__) \ - || defined(__QNXNTO__) \ - || defined(ANDROID) -#define WTF_PLATFORM_UNIX 1 +/* OS(SYMBIAN) - Symbian */ +#if defined (__SYMBIAN32__) +/* we are cross-compiling, it is not really windows */ +#undef WTF_OS_WINDOWS +#undef WTF_PLATFORM_WIN +#define WTF_OS_SYMBIAN 1 +#endif + +/* OS(UNIX) - Any Unix-like system */ +#if OS(AIX) \ + || OS(ANDROID) \ + || OS(DARWIN) \ + || OS(FREEBSD) \ + || OS(HAIKU) \ + || OS(LINUX) \ + || OS(NETBSD) \ + || OS(OPENBSD) \ + || OS(QNX) \ + || OS(SOLARIS) \ + || OS(SYMBIAN) \ + || defined(unix) \ + || defined(__unix) \ + || defined(__unix__) +#define WTF_OS_UNIX 1 #endif /* Operating environments */ +/* FIXME: these are all mixes of OS, operating environment and policy choices. */ /* PLATFORM(CHROMIUM) */ /* PLATFORM(QT) */ /* PLATFORM(WX) */ @@ -156,13 +415,14 @@ #define WTF_PLATFORM_GTK 1 #elif defined(BUILDING_HAIKU__) #define WTF_PLATFORM_HAIKU 1 -#elif PLATFORM(DARWIN) +#elif OS(DARWIN) #define WTF_PLATFORM_MAC 1 -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) #define WTF_PLATFORM_WIN 1 #endif /* PLATFORM(IPHONE) */ +/* FIXME: this is sometimes used as an OS switch and sometimes for higher-level things */ #if (defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) #define WTF_PLATFORM_IPHONE 1 #endif @@ -180,6 +440,8 @@ #endif /* PLATFORM(ANDROID) */ +/* FIXME: this is sometimes used as an OS() switch, and other times to drive + policy choices */ #if defined(ANDROID) #define WTF_PLATFORM_ANDROID 1 #endif @@ -196,202 +458,28 @@ /* PLATFORM(SKIA) for Win/Linux, CG/CI for Mac */ #if PLATFORM(CHROMIUM) -#if PLATFORM(DARWIN) +#define ENABLE_HISTORY_ALWAYS_ASYNC 1 +#if OS(DARWIN) #define WTF_PLATFORM_CG 1 #define WTF_PLATFORM_CI 1 #define WTF_USE_ATSUI 1 +#define WTF_USE_CORE_TEXT 1 #else #define WTF_PLATFORM_SKIA 1 #endif #endif -/* Makes PLATFORM(WIN) default to PLATFORM(CAIRO) */ -/* FIXME: This should be changed from a blacklist to a whitelist */ -#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(WX) && !PLATFORM(CHROMIUM) && !PLATFORM(WINCE) && !PLATFORM(HAIKU) && !PLATFORM(ANDROID) +#if PLATFORM(GTK) #define WTF_PLATFORM_CAIRO 1 #endif -/* CPU */ - -/* PLATFORM(PPC) */ -#if defined(__ppc__) \ - || defined(__PPC__) \ - || defined(__powerpc__) \ - || defined(__powerpc) \ - || defined(__POWERPC__) \ - || defined(_M_PPC) \ - || defined(__PPC) -#define WTF_PLATFORM_PPC 1 -#define WTF_PLATFORM_BIG_ENDIAN 1 -#endif - -/* PLATFORM(SPARC32) */ -#if defined(__sparc) && !defined(__arch64__) || defined(__sparcv8) -#define WTF_PLATFORM_SPARC32 1 -#define WTF_PLATFORM_BIG_ENDIAN 1 -#endif - -#if PLATFORM(SPARC32) || PLATFORM(SPARC64) -#define WTF_PLATFORM_SPARC -#endif - -/* PLATFORM(PPC64) */ -#if defined(__ppc64__) \ - || defined(__PPC64__) -#define WTF_PLATFORM_PPC64 1 -#define WTF_PLATFORM_BIG_ENDIAN 1 -#endif - -/* PLATFORM(ARM) */ -#define PLATFORM_ARM_ARCH(N) (PLATFORM(ARM) && ARM_ARCH_VERSION >= N) - -#if defined(arm) \ - || defined(__arm__) -#define WTF_PLATFORM_ARM 1 - -#if defined(__ARMEB__) -#define WTF_PLATFORM_BIG_ENDIAN 1 - -#elif !defined(__ARM_EABI__) \ - && !defined(__EABI__) \ - && !defined(__VFP_FP__) \ - && !defined(ANDROID) -#define WTF_PLATFORM_MIDDLE_ENDIAN 1 - -#endif - -/* Set ARM_ARCH_VERSION */ -#if defined(__ARM_ARCH_4__) \ - || defined(__ARM_ARCH_4T__) \ - || defined(__MARM_ARMV4__) \ - || defined(_ARMV4I_) -#define ARM_ARCH_VERSION 4 - -#elif defined(__ARM_ARCH_5__) \ - || defined(__ARM_ARCH_5T__) \ - || defined(__ARM_ARCH_5E__) \ - || defined(__ARM_ARCH_5TE__) \ - || defined(__ARM_ARCH_5TEJ__) \ - || defined(__MARM_ARMV5__) -#define ARM_ARCH_VERSION 5 - -#elif defined(__ARM_ARCH_6__) \ - || defined(__ARM_ARCH_6J__) \ - || defined(__ARM_ARCH_6K__) \ - || defined(__ARM_ARCH_6Z__) \ - || defined(__ARM_ARCH_6ZK__) \ - || defined(__ARM_ARCH_6T2__) \ - || defined(__ARMV6__) -#define ARM_ARCH_VERSION 6 - -#elif defined(__ARM_ARCH_7A__) \ - || defined(__ARM_ARCH_7R__) -#define ARM_ARCH_VERSION 7 - -/* RVCT sets _TARGET_ARCH_ARM */ -#elif defined(__TARGET_ARCH_ARM) -#define ARM_ARCH_VERSION __TARGET_ARCH_ARM - -#else -#define ARM_ARCH_VERSION 0 - -#endif - -/* Set THUMB_ARM_VERSION */ -#if defined(__ARM_ARCH_4T__) -#define THUMB_ARCH_VERSION 1 - -#elif defined(__ARM_ARCH_5T__) \ - || defined(__ARM_ARCH_5TE__) \ - || defined(__ARM_ARCH_5TEJ__) -#define THUMB_ARCH_VERSION 2 - -#elif defined(__ARM_ARCH_6J__) \ - || defined(__ARM_ARCH_6K__) \ - || defined(__ARM_ARCH_6Z__) \ - || defined(__ARM_ARCH_6ZK__) \ - || defined(__ARM_ARCH_6M__) -#define THUMB_ARCH_VERSION 3 - -#elif defined(__ARM_ARCH_6T2__) \ - || defined(__ARM_ARCH_7__) \ - || defined(__ARM_ARCH_7A__) \ - || defined(__ARM_ARCH_7R__) \ - || defined(__ARM_ARCH_7M__) -#define THUMB_ARCH_VERSION 4 - -/* RVCT sets __TARGET_ARCH_THUMB */ -#elif defined(__TARGET_ARCH_THUMB) -#define THUMB_ARCH_VERSION __TARGET_ARCH_THUMB - -#else -#define THUMB_ARCH_VERSION 0 -#endif -/* On ARMv5 and below the natural alignment is required. */ -#if !defined(ARM_REQUIRE_NATURAL_ALIGNMENT) && ARM_ARCH_VERSION <= 5 -#define ARM_REQUIRE_NATURAL_ALIGNMENT 1 -#endif - -/* Defines two pseudo-platforms for ARM and Thumb-2 instruction set. */ -#if !defined(WTF_PLATFORM_ARM_TRADITIONAL) && !defined(WTF_PLATFORM_ARM_THUMB2) -# if defined(thumb2) || defined(__thumb2__) \ - || ((defined(__thumb) || defined(__thumb__)) && THUMB_ARCH_VERSION == 4) -# define WTF_PLATFORM_ARM_TRADITIONAL 0 -# define WTF_PLATFORM_ARM_THUMB2 1 -# elif PLATFORM_ARM_ARCH(4) -# define WTF_PLATFORM_ARM_TRADITIONAL 1 -# define WTF_PLATFORM_ARM_THUMB2 0 -# else -# error "Not supported ARM architecture" -# endif -#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(ARM_THUMB2) /* Sanity Check */ -# error "Cannot use both of WTF_PLATFORM_ARM_TRADITIONAL and WTF_PLATFORM_ARM_THUMB2 platforms" -#endif // !defined(ARM_TRADITIONAL) && !defined(ARM_THUMB2) -#endif /* ARM */ - -/* PLATFORM(X86) */ -#if defined(__i386__) \ - || defined(i386) \ - || defined(_M_IX86) \ - || defined(_X86_) \ - || defined(__THW_INTEL) -#define WTF_PLATFORM_X86 1 -#endif - -/* PLATFORM(X86_64) */ -#if defined(__x86_64__) \ - || defined(_M_X64) -#define WTF_PLATFORM_X86_64 1 -#endif - -/* PLATFORM(IA64) */ -#if defined(__ia64__) -#define WTF_PLATFORM_IA64 1 -#endif - -/* PLATFORM(ALPHA) */ -#if defined(__alpha__) -#define WTF_PLATFORM_ALPHA 1 -#endif - -/* PLATFORM(SH4) */ -#if defined(__SH4__) -#define WTF_PLATFORM_SH4 1 -#endif - -/* PLATFORM(SPARC64) */ -#if defined(__sparc__) && defined(__arch64__) || defined (__sparcv9) -#define WTF_PLATFORM_SPARC64 1 -#define WTF_PLATFORM_BIG_ENDIAN 1 -#endif - -/* PLATFORM(WINCE) && PLATFORM(QT) +/* OS(WINCE) && PLATFORM(QT) We can not determine the endianess at compile time. For Qt for Windows CE the endianess is specified in the device specific makespec */ -#if PLATFORM(WINCE) && PLATFORM(QT) +#if OS(WINCE) && PLATFORM(QT) # include <QtGlobal> # undef WTF_PLATFORM_BIG_ENDIAN # undef WTF_PLATFORM_MIDDLE_ENDIAN @@ -402,60 +490,16 @@ # include <ce_time.h> #endif -/* Compiler */ - -/* COMPILER(MSVC) */ -#if defined(_MSC_VER) -#define WTF_COMPILER_MSVC 1 -#if _MSC_VER < 1400 -#define WTF_COMPILER_MSVC7 1 -#endif -#endif - -/* COMPILER(RVCT) */ -#if defined(__CC_ARM) || defined(__ARMCC__) -#define WTF_COMPILER_RVCT 1 -#endif - -/* COMPILER(GCC) */ -/* --gnu option of the RVCT compiler also defines __GNUC__ */ -#if defined(__GNUC__) && !COMPILER(RVCT) -#define WTF_COMPILER_GCC 1 -#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#endif - -/* COMPILER(MINGW) */ -#if defined(MINGW) || defined(__MINGW32__) -#define WTF_COMPILER_MINGW 1 -#endif - -/* COMPILER(BORLAND) */ -/* not really fully supported - is this relevant any more? */ -#if defined(__BORLANDC__) -#define WTF_COMPILER_BORLAND 1 -#endif - -/* COMPILER(CYGWIN) */ -/* not really fully supported - is this relevant any more? */ -#if defined(__CYGWIN__) -#define WTF_COMPILER_CYGWIN 1 -#endif - -/* COMPILER(WINSCW) */ -#if defined(__WINSCW__) -#define WTF_COMPILER_WINSCW 1 -#endif - -#if (PLATFORM(IPHONE) || PLATFORM(MAC) || PLATFORM(WIN) || (PLATFORM(QT) && PLATFORM(DARWIN))) && !defined(ENABLE_JSC_MULTIPLE_THREADS) +#if (PLATFORM(IPHONE) || PLATFORM(MAC) || PLATFORM(WIN) || (PLATFORM(QT) && OS(DARWIN) && !ENABLE(SINGLE_THREADED))) && !defined(ENABLE_JSC_MULTIPLE_THREADS) #define ENABLE_JSC_MULTIPLE_THREADS 1 #endif /* On Windows, use QueryPerformanceCounter by default */ -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) #define WTF_USE_QUERY_PERFORMANCE_COUNTER 1 #endif -#if PLATFORM(WINCE) && !PLATFORM(QT) +#if OS(WINCE) && !PLATFORM(QT) #undef ENABLE_JSC_MULTIPLE_THREADS #define ENABLE_JSC_MULTIPLE_THREADS 0 #define USE_SYSTEM_MALLOC 0 @@ -466,25 +510,25 @@ #define ENABLE_WML 1 #define HAVE_ACCESSIBILITY 0 -#define NOMINMAX // Windows min and max conflict with standard macros -#define NOSHLWAPI // shlwapi.h not available on WinCe +#define NOMINMAX /* Windows min and max conflict with standard macros */ +#define NOSHLWAPI /* shlwapi.h not available on WinCe */ -// MSDN documentation says these functions are provided with uspce.lib. But we cannot find this file. -#define __usp10__ // disable "usp10.h" +/* MSDN documentation says these functions are provided with uspce.lib. But we cannot find this file. */ +#define __usp10__ /* disable "usp10.h" */ -#define _INC_ASSERT // disable "assert.h" +#define _INC_ASSERT /* disable "assert.h" */ #define assert(x) -// _countof is only included in CE6; for CE5 we need to define it ourself +/* _countof is only included in CE6; for CE5 we need to define it ourself */ #ifndef _countof #define _countof(x) (sizeof(x) / sizeof((x)[0])) #endif -#endif /* PLATFORM(WINCE) && !PLATFORM(QT) */ +#endif /* OS(WINCE) && !PLATFORM(QT) */ #if PLATFORM(QT) #define WTF_USE_QT4_UNICODE 1 -#elif PLATFORM(WINCE) +#elif OS(WINCE) #define WTF_USE_WINCE_UNICODE 1 #elif PLATFORM(GTK) /* The GTK+ Unicode backend is configurable */ @@ -496,7 +540,7 @@ #define WTF_PLATFORM_CF 1 #define WTF_USE_PTHREADS 1 #define HAVE_PTHREAD_RWLOCK 1 -#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && defined(__x86_64__) +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && CPU(X86_64) #define WTF_USE_PLUGIN_HOST_PROCESS 1 #endif #if !defined(ENABLE_MAC_JAVA_BRIDGE) @@ -509,13 +553,13 @@ #define HAVE_RUNLOOP_TIMER 1 #endif /* PLATFORM(MAC) && !PLATFORM(IPHONE) */ -#if PLATFORM(CHROMIUM) && PLATFORM(DARWIN) +#if PLATFORM(CHROMIUM) && OS(DARWIN) #define WTF_PLATFORM_CF 1 #define WTF_USE_PTHREADS 1 #define HAVE_PTHREAD_RWLOCK 1 #endif -#if PLATFORM(QT) && PLATFORM(DARWIN) +#if PLATFORM(QT) && OS(DARWIN) #define WTF_PLATFORM_CF 1 #endif @@ -542,8 +586,8 @@ #define USE_SYSTEM_MALLOC 1 #define ENABLE_MAC_JAVA_BRIDGE 1 #define LOG_DISABLED 1 -// Prevents Webkit from drawing the caret in textfields and textareas -// This prevents unnecessary invals. +/* Prevents Webkit from drawing the caret in textfields and textareas + This prevents unnecessary invals. */ #define ENABLE_TEXT_CARET 1 #define ENABLE_JAVASCRIPT_DEBUGGER 0 #define ENABLE_ORIENTATION_EVENTS 1 @@ -555,7 +599,7 @@ #if PLATFORM(WX) #define ENABLE_ASSEMBLER 1 -#if PLATFORM(DARWIN) +#if OS(DARWIN) #define WTF_PLATFORM_CF 1 #endif #endif @@ -582,19 +626,19 @@ #endif #endif /* !defined(HAVE_ACCESSIBILITY) */ -#if PLATFORM(UNIX) && !PLATFORM(SYMBIAN) +#if OS(UNIX) && !OS(SYMBIAN) #define HAVE_SIGNAL_H 1 #endif -#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !PLATFORM(QNX) \ - && !PLATFORM(SYMBIAN) && !PLATFORM(HAIKU) && !COMPILER(RVCT) \ - && !PLATFORM(ANDROID) +#if !OS(WINDOWS) && !OS(SOLARIS) && !OS(QNX) \ + && !OS(SYMBIAN) && !OS(HAIKU) && !OS(RVCT) \ + && !OS(ANDROID) #define HAVE_TM_GMTOFF 1 #define HAVE_TM_ZONE 1 #define HAVE_TIMEGM 1 -#endif +#endif -#if PLATFORM(DARWIN) +#if OS(DARWIN) #define HAVE_ERRNO_H 1 #define HAVE_LANGINFO_H 1 @@ -606,26 +650,32 @@ #define HAVE_SYS_TIME_H 1 #define HAVE_SYS_TIMEB_H 1 -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE) && !PLATFORM(QT) +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + +#define HAVE_DISPATCH_H 1 + +#if !PLATFORM(IPHONE) && !PLATFORM(QT) #define HAVE_MADV_FREE_REUSE 1 #define HAVE_MADV_FREE 1 #define HAVE_PTHREAD_SETNAME_NP 1 #endif +#endif + #if PLATFORM(IPHONE) #define HAVE_MADV_FREE 1 #endif -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) -#if PLATFORM(WINCE) +#if OS(WINCE) #define HAVE_ERRNO_H 0 #else #define HAVE_SYS_TIMEB_H 1 #endif #define HAVE_VIRTUALALLOC 1 -#elif PLATFORM(SYMBIAN) +#elif OS(SYMBIAN) #define HAVE_ERRNO_H 1 #define HAVE_MMAP 0 @@ -638,7 +688,7 @@ #define HAVE_SYS_PARAM_H 1 #endif -#elif PLATFORM(QNX) +#elif OS(QNX) #define HAVE_ERRNO_H 1 #define HAVE_MMAP 1 @@ -647,7 +697,7 @@ #define HAVE_SYS_PARAM_H 1 #define HAVE_SYS_TIME_H 1 -#elif PLATFORM(ANDROID) +#elif OS(ANDROID) #define HAVE_ERRNO_H 1 #define HAVE_LANGINFO_H 0 @@ -663,7 +713,7 @@ #define HAVE_ERRNO_H 1 /* As long as Haiku doesn't have a complete support of locale this will be disabled. */ -#if !PLATFORM(HAIKU) +#if !OS(HAIKU) #define HAVE_LANGINFO_H 1 #endif #define HAVE_MMAP 1 @@ -769,11 +819,11 @@ #endif #if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) -#if (PLATFORM(X86_64) && (PLATFORM(UNIX) || PLATFORM(WIN_OS))) || PLATFORM(IA64) || PLATFORM(ALPHA) +#if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS))) || CPU(IA64) || CPU(ALPHA) #define WTF_USE_JSVALUE64 1 -#elif PLATFORM(ARM) || PLATFORM(PPC64) +#elif CPU(ARM) || CPU(PPC64) #define WTF_USE_JSVALUE32 1 -#elif PLATFORM(WIN_OS) && COMPILER(MINGW) +#elif OS(WINDOWS) && COMPILER(MINGW) /* Using JSVALUE32_64 causes padding/alignement issues for JITStubArg on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define WTF_USE_JSVALUE32 1 @@ -789,35 +839,37 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #if !defined(ENABLE_JIT) /* The JIT is tested & working on x86_64 Mac */ -#if PLATFORM(X86_64) && PLATFORM(MAC) +#if CPU(X86_64) && PLATFORM(MAC) #define ENABLE_JIT 1 /* The JIT is tested & working on x86 Mac */ -#elif PLATFORM(X86) && PLATFORM(MAC) +#elif CPU(X86) && PLATFORM(MAC) #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 -#elif PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE) +#elif CPU(ARM_THUMB2) && PLATFORM(IPHONE) #define ENABLE_JIT 1 /* The JIT is tested & working on x86 Windows */ -#elif PLATFORM(X86) && PLATFORM(WIN) +#elif CPU(X86) && PLATFORM(WIN) #define ENABLE_JIT 1 #endif #if PLATFORM(QT) -#if PLATFORM(X86_64) && PLATFORM(DARWIN) +#if CPU(X86_64) && OS(DARWIN) #define ENABLE_JIT 1 -#elif PLATFORM(X86) && PLATFORM(DARWIN) +#elif CPU(X86) && OS(DARWIN) #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 -#elif PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100 +#elif CPU(X86) && OS(WINDOWS) && COMPILER(MINGW) && GCC_VERSION >= 40100 #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 -#elif PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MSVC) +#elif CPU(X86) && OS(WINDOWS) && COMPILER(MSVC) #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1 -#elif PLATFORM(X86) && PLATFORM(LINUX) && GCC_VERSION >= 40100 +#elif CPU(X86) && OS(LINUX) && GCC_VERSION >= 40100 #define ENABLE_JIT 1 #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1 -#elif PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX) +#elif CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100 + #define ENABLE_JIT 1 +#elif CPU(ARM_TRADITIONAL) && OS(LINUX) #define ENABLE_JIT 1 #endif #endif /* PLATFORM(QT) */ @@ -839,9 +891,9 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #endif #endif -#if PLATFORM(X86) && COMPILER(MSVC) +#if CPU(X86) && COMPILER(MSVC) #define JSC_HOST_CALL __fastcall -#elif PLATFORM(X86) && COMPILER(GCC) +#elif CPU(X86) && COMPILER(GCC) #define JSC_HOST_CALL __attribute__ ((fastcall)) #else #define JSC_HOST_CALL @@ -861,19 +913,20 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #if !defined(ENABLE_YARR_JIT) /* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */ -#if (PLATFORM(X86) && PLATFORM(MAC)) \ - || (PLATFORM(X86_64) && PLATFORM(MAC)) \ - || (PLATFORM(ARM_THUMB2) && PLATFORM(IPHONE)) \ - || (PLATFORM(X86) && PLATFORM(WIN)) +#if (CPU(X86) && PLATFORM(MAC)) \ + || (CPU(X86_64) && PLATFORM(MAC)) \ + || (CPU(ARM_THUMB2) && PLATFORM(IPHONE)) \ + || (CPU(X86) && PLATFORM(WIN)) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 #endif #if PLATFORM(QT) -#if (PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MINGW) && GCC_VERSION >= 40100) \ - || (PLATFORM(X86) && PLATFORM(WIN_OS) && COMPILER(MSVC)) \ - || (PLATFORM(X86) && PLATFORM(LINUX) && GCC_VERSION >= 40100) \ - || (PLATFORM(ARM_TRADITIONAL) && PLATFORM(LINUX)) +#if (CPU(X86) && OS(WINDOWS) && COMPILER(MINGW) && GCC_VERSION >= 40100) \ + || (CPU(X86) && OS(WINDOWS) && COMPILER(MSVC)) \ + || (CPU(X86) && OS(LINUX) && GCC_VERSION >= 40100) \ + || (CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100) \ + || (CPU(ARM_TRADITIONAL) && OS(LINUX)) #define ENABLE_YARR 1 #define ENABLE_YARR_JIT 1 #endif @@ -897,7 +950,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define ENABLE_ASSEMBLER_WX_EXCLUSIVE 0 #endif -#if !defined(ENABLE_PAN_SCROLLING) && PLATFORM(WIN_OS) +#if !defined(ENABLE_PAN_SCROLLING) && OS(WINDOWS) #define ENABLE_PAN_SCROLLING 1 #endif @@ -927,8 +980,15 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define WTF_USE_ACCELERATED_COMPOSITING 1 #endif +/* FIXME: Defining ENABLE_3D_RENDERING here isn't really right, but it's always used with + with WTF_USE_ACCELERATED_COMPOSITING, and it allows the feature to be turned on and + off in one place. */ #if PLATFORM(WIN) -#define WTF_USE_ACCELERATED_COMPOSITING 0 +#include "QuartzCorePresent.h" +#if QUARTZCORE_PRESENT +#define WTF_USE_ACCELERATED_COMPOSITING 1 +#define ENABLE_3D_RENDERING 1 +#endif #endif #if COMPILER(GCC) @@ -937,7 +997,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define WARN_UNUSED_RETURN #endif -#if !ENABLE(NETSCAPE_PLUGIN_API) || (ENABLE(NETSCAPE_PLUGIN_API) && ((PLATFORM(UNIX) && (PLATFORM(QT) || PLATFORM(WX))) || PLATFORM(GTK))) +#if !ENABLE(NETSCAPE_PLUGIN_API) || (ENABLE(NETSCAPE_PLUGIN_API) && ((OS(UNIX) && (PLATFORM(QT) || PLATFORM(WX))) || PLATFORM(GTK))) #define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1 #endif diff --git a/JavaScriptCore/wtf/RandomNumber.cpp b/JavaScriptCore/wtf/RandomNumber.cpp index 52fb130..fc48263 100644 --- a/JavaScriptCore/wtf/RandomNumber.cpp +++ b/JavaScriptCore/wtf/RandomNumber.cpp @@ -34,12 +34,18 @@ #include <stdint.h> #include <stdlib.h> -#if PLATFORM(WINCE) +#if OS(WINCE) extern "C" { #include "wince/mt19937ar.c" } #endif +#if PLATFORM(BREWMP) +#include <AEEAppGen.h> +#include <AEESource.h> +#include <AEEStdLib.h> +#endif + namespace WTF { double weakRandomNumber() @@ -47,6 +53,10 @@ double weakRandomNumber() #if COMPILER(MSVC) && defined(_CRT_RAND_S) // rand_s is incredibly slow on windows so we fall back on rand for Math.random return (rand() + (rand() / (RAND_MAX + 1.0))) / (RAND_MAX + 1.0); +#elif PLATFORM(BREWMP) + uint32_t bits; + GETRAND(reinterpret_cast<byte*>(&bits), sizeof(uint32_t)); + return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0); #else return randomNumber(); #endif @@ -66,10 +76,10 @@ double randomNumber() uint32_t bits; rand_s(&bits); return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0); -#elif PLATFORM(DARWIN) +#elif OS(DARWIN) uint32_t bits = arc4random(); return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0); -#elif PLATFORM(UNIX) +#elif OS(UNIX) uint32_t part1 = random() & (RAND_MAX - 1); uint32_t part2 = random() & (RAND_MAX - 1); // random only provides 31 bits @@ -80,9 +90,9 @@ double randomNumber() // Mask off the low 53bits fullRandom &= (1LL << 53) - 1; return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); -#elif PLATFORM(WINCE) +#elif OS(WINCE) return genrand_res53(); -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) uint32_t part1 = rand() & (RAND_MAX - 1); uint32_t part2 = rand() & (RAND_MAX - 1); uint32_t part3 = rand() & (RAND_MAX - 1); @@ -99,6 +109,16 @@ double randomNumber() // Mask off the low 53bits fullRandom &= (1LL << 53) - 1; return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); +#elif PLATFORM(BREWMP) + uint32_t bits; + ISource* randomSource; + + IShell* shell = reinterpret_cast<AEEApplet*>(GETAPPINSTANCE())->m_pIShell; + ISHELL_CreateInstance(shell, AEECLSID_RANDOM, reinterpret_cast<void**>(&randomSource)); + ISOURCE_Read(randomSource, reinterpret_cast<char*>(&bits), 4); + ISOURCE_Release(randomSource); + + return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0); #else uint32_t part1 = rand() & (RAND_MAX - 1); uint32_t part2 = rand() & (RAND_MAX - 1); diff --git a/JavaScriptCore/wtf/RandomNumberSeed.h b/JavaScriptCore/wtf/RandomNumberSeed.h index a66433e..ae414c0 100644 --- a/JavaScriptCore/wtf/RandomNumberSeed.h +++ b/JavaScriptCore/wtf/RandomNumberSeed.h @@ -33,12 +33,12 @@ #include <sys/time.h> #endif -#if PLATFORM(UNIX) +#if OS(UNIX) #include <sys/types.h> #include <unistd.h> #endif -#if PLATFORM(WINCE) +#if OS(WINCE) extern "C" { void init_by_array(unsigned long init_key[],int key_length); } @@ -49,9 +49,9 @@ namespace WTF { inline void initializeRandomNumberGenerator() { -#if PLATFORM(DARWIN) +#if OS(DARWIN) // On Darwin we use arc4random which initialises itself. -#elif PLATFORM(WINCE) +#elif OS(WINCE) // initialize rand() srand(static_cast<unsigned>(time(0))); @@ -64,7 +64,7 @@ inline void initializeRandomNumberGenerator() init_by_array(initializationBuffer, 4); #elif COMPILER(MSVC) && defined(_CRT_RAND_S) // On Windows we use rand_s which initialises itself -#elif PLATFORM(UNIX) +#elif OS(UNIX) // srandomdev is not guaranteed to exist on linux so we use this poor seed, this should be improved timeval time; gettimeofday(&time, 0); diff --git a/JavaScriptCore/wtf/RefPtrHashMap.h b/JavaScriptCore/wtf/RefPtrHashMap.h index 9433025..7f6ebfe 100644 --- a/JavaScriptCore/wtf/RefPtrHashMap.h +++ b/JavaScriptCore/wtf/RefPtrHashMap.h @@ -285,7 +285,7 @@ namespace WTF { { if (it.m_impl == m_impl.end()) return; - m_impl.checkTableConsistency(); + m_impl.internalCheckTableConsistency(); m_impl.removeWithoutEntryConsistencyCheck(it.m_impl); } diff --git a/JavaScriptCore/wtf/StdLibExtras.h b/JavaScriptCore/wtf/StdLibExtras.h index dd90c85..9dfb969 100644 --- a/JavaScriptCore/wtf/StdLibExtras.h +++ b/JavaScriptCore/wtf/StdLibExtras.h @@ -69,6 +69,14 @@ namespace WTF { return u.to; } + // Returns a count of the number of bits set in 'bits'. + inline size_t bitCount(unsigned bits) + { + bits = bits - ((bits >> 1) & 0x55555555); + bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333); + return (((bits + (bits >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; + } + } // namespace WTF #endif diff --git a/JavaScriptCore/wtf/StringExtras.cpp b/JavaScriptCore/wtf/StringExtras.cpp new file mode 100644 index 0000000..1b96417 --- /dev/null +++ b/JavaScriptCore/wtf/StringExtras.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009 Company 100, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if COMPILER(RVCT) && __ARMCC_VERSION < 400000 + +#include "StringExtras.h" + +#include "ASCIICType.h" + +int strcasecmp(const char* s1, const char* s2) +{ + while (toASCIIUpper(*s1) == toASCIIUpper(*s2)) { + if (*s1 == '\0') + return 0; + s1++; + s2++; + } + + return toASCIIUpper(*s1) - toASCIIUpper(*s2); +} + +int strncasecmp(const char* s1, const char* s2, size_t len) +{ + while (len > 0 && toASCIIUpper(*s1) == toASCIIUpper(*s2)) { + if (*s1 == '\0') + return 0; + s1++; + s2++; + len--; + } + + if (!len) + return 0; + + return toASCIIUpper(*s1) - toASCIIUpper(*s2); +} + +#endif diff --git a/JavaScriptCore/wtf/StringExtras.h b/JavaScriptCore/wtf/StringExtras.h index 50efe35..b1ec09f 100644 --- a/JavaScriptCore/wtf/StringExtras.h +++ b/JavaScriptCore/wtf/StringExtras.h @@ -34,6 +34,7 @@ #endif #if COMPILER(MSVC) +// FIXME: why a COMPILER check instead of OS? also, these should be HAVE checks inline int snprintf(char* buffer, size_t count, const char* format, ...) { @@ -45,7 +46,7 @@ inline int snprintf(char* buffer, size_t count, const char* format, ...) return result; } -#if COMPILER(MSVC7) || PLATFORM(WINCE) +#if COMPILER(MSVC7) || OS(WINCE) inline int vsnprintf(char* buffer, size_t count, const char* format, va_list args) { @@ -54,7 +55,7 @@ inline int vsnprintf(char* buffer, size_t count, const char* format, va_list arg #endif -#if PLATFORM(WINCE) +#if OS(WINCE) inline int strnicmp(const char* string1, const char* string2, size_t count) { @@ -85,7 +86,8 @@ inline int strcasecmp(const char* s1, const char* s2) #endif -#if PLATFORM(WIN_OS) || PLATFORM(LINUX) || PLATFORM(SOLARIS) +#if OS(WINDOWS) || OS(LINUX) || OS(SOLARIS) +// FIXME: should check HAVE_STRNSTR inline char* strnstr(const char* buffer, const char* target, size_t bufferLength) { @@ -101,4 +103,11 @@ inline char* strnstr(const char* buffer, const char* target, size_t bufferLength #endif +#if COMPILER(RVCT) && __ARMCC_VERSION < 400000 + +int strcasecmp(const char* s1, const char* s2); +int strncasecmp(const char* s1, const char* s2, size_t len); + +#endif + #endif // WTF_StringExtras_h diff --git a/JavaScriptCore/wtf/StringHashFunctions.h b/JavaScriptCore/wtf/StringHashFunctions.h new file mode 100644 index 0000000..07f117f --- /dev/null +++ b/JavaScriptCore/wtf/StringHashFunctions.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2005, 2006, 2008, 2010 Apple Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ +#ifndef WTF_StringHashFunctions_h +#define WTF_StringHashFunctions_h + +#include <wtf/unicode/Unicode.h> + +namespace WTF { + +// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's +static const unsigned stringHashingStartValue = 0x9e3779b9U; + +// stringHash methods based on Paul Hsieh's SuperFastHash. +// http://www.azillionmonkeys.com/qed/hash.html +// char* data is interpreted as latin-encoded (zero extended to 16 bits). + +inline unsigned stringHash(const UChar* data, unsigned length) +{ + unsigned hash = WTF::stringHashingStartValue; + unsigned rem = length & 1; + length >>= 1; + + // Main loop + for (; length > 0; length--) { + hash += data[0]; + unsigned tmp = (data[1] << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2; + hash += hash >> 11; + } + + // Handle end case + if (rem) { + hash += data[0]; + hash ^= hash << 11; + hash += hash >> 17; + } + + // Force "avalanching" of final 127 bits + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 2; + 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 = 0x40000000; + + return hash; +} + +inline unsigned stringHash(const char* data, unsigned length) +{ + unsigned hash = WTF::stringHashingStartValue; + unsigned rem = length & 1; + length >>= 1; + + // Main loop + for (; length > 0; length--) { + hash += static_cast<unsigned char>(data[0]); + unsigned tmp = (static_cast<unsigned char>(data[1]) << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2; + hash += hash >> 11; + } + + // Handle end case + if (rem) { + hash += static_cast<unsigned char>(data[0]); + hash ^= hash << 11; + hash += hash >> 17; + } + + // Force "avalanching" of final 127 bits + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 2; + 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 = 0x40000000; + + return hash; +} + +inline unsigned stringHash(const char* data) +{ + unsigned hash = WTF::stringHashingStartValue; + + // Main loop + for (;;) { + unsigned char b0 = data[0]; + if (!b0) + break; + unsigned char b1 = data[1]; + if (!b1) { + hash += b0; + hash ^= hash << 11; + hash += hash >> 17; + break; + } + hash += b0; + unsigned tmp = (b1 << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2; + hash += hash >> 11; + } + + // Force "avalanching" of final 127 bits. + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 2; + 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 = 0x40000000; + + return hash; +} + +} // namespace WTF + +#endif // WTF_StringHashFunctions_h diff --git a/JavaScriptCore/wtf/TCSpinLock.h b/JavaScriptCore/wtf/TCSpinLock.h index 4cf30c2..8a73e13 100644 --- a/JavaScriptCore/wtf/TCSpinLock.h +++ b/JavaScriptCore/wtf/TCSpinLock.h @@ -33,7 +33,7 @@ #ifndef TCMALLOC_INTERNAL_SPINLOCK_H__ #define TCMALLOC_INTERNAL_SPINLOCK_H__ -#if (PLATFORM(X86) || PLATFORM(PPC)) && (COMPILER(GCC) || COMPILER(MSVC)) +#if (CPU(X86) || CPU(X86_64) || CPU(PPC)) && (COMPILER(GCC) || COMPILER(MSVC)) #include <time.h> /* For nanosleep() */ @@ -47,7 +47,7 @@ #include <sys/types.h> #endif -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif @@ -62,7 +62,7 @@ struct TCMalloc_SpinLock { inline void Lock() { int r; #if COMPILER(GCC) -#if PLATFORM(X86) +#if CPU(X86) || CPU(X86_64) __asm__ __volatile__ ("xchgl %0, %1" : "=r"(r), "=m"(lockword_) @@ -92,7 +92,7 @@ struct TCMalloc_SpinLock { inline void Unlock() { #if COMPILER(GCC) -#if PLATFORM(X86) +#if CPU(X86) || CPU(X86_64) __asm__ __volatile__ ("movl $0, %0" : "=m"(lockword_) @@ -103,7 +103,7 @@ struct TCMalloc_SpinLock { ("isync\n\t" "eieio\n\t" "stw %1, %0" -#if PLATFORM(DARWIN) || PLATFORM(PPC) +#if OS(DARWIN) || CPU(PPC) : "=o" (lockword_) #else : "=m" (lockword_) @@ -138,7 +138,7 @@ static void TCMalloc_SlowLock(volatile unsigned int* lockword) { while (true) { int r; #if COMPILER(GCC) -#if PLATFORM(X86) +#if CPU(X86) || CPU(X86_64) __asm__ __volatile__ ("xchgl %0, %1" : "=r"(r), "=m"(*lockword) @@ -178,7 +178,7 @@ static void TCMalloc_SlowLock(volatile unsigned int* lockword) { // from taking 30 seconds to 16 seconds. // Sleep for a few milliseconds -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) Sleep(2); #else struct timespec tm; diff --git a/JavaScriptCore/wtf/TCSystemAlloc.cpp b/JavaScriptCore/wtf/TCSystemAlloc.cpp index 659bb0e..4d02919 100644 --- a/JavaScriptCore/wtf/TCSystemAlloc.cpp +++ b/JavaScriptCore/wtf/TCSystemAlloc.cpp @@ -47,7 +47,7 @@ #include <sys/types.h> #endif -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) #include "windows.h" #else #include <errno.h> diff --git a/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp b/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp new file mode 100644 index 0000000..042d49e --- /dev/null +++ b/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if USE(PTHREADS) + +#include "ThreadIdentifierDataPthreads.h" + +#include "Threading.h" + +namespace WTF { + +pthread_key_t ThreadIdentifierData::m_key; + +void clearPthreadHandleForIdentifier(ThreadIdentifier); + +ThreadIdentifierData::~ThreadIdentifierData() +{ + clearPthreadHandleForIdentifier(m_identifier); +} + +ThreadIdentifier ThreadIdentifierData::identifier() +{ + initializeKeyOnce(); + ThreadIdentifierData* threadIdentifierData = static_cast<ThreadIdentifierData*>(pthread_getspecific(m_key)); + + return threadIdentifierData ? threadIdentifierData->m_identifier : 0; +} + +void ThreadIdentifierData::initialize(ThreadIdentifier id) +{ + ASSERT(!identifier()); + + initializeKeyOnce(); + pthread_setspecific(m_key, new ThreadIdentifierData(id)); +} + +void ThreadIdentifierData::destruct(void* data) +{ + ThreadIdentifierData* threadIdentifierData = static_cast<ThreadIdentifierData*>(data); + ASSERT(threadIdentifierData); + + if (threadIdentifierData->m_isDestroyedOnce) { + delete threadIdentifierData; + return; + } + + threadIdentifierData->m_isDestroyedOnce = true; + // Re-setting the value for key causes another destruct() call after all other thread-specific destructors were called. + pthread_setspecific(m_key, threadIdentifierData); +} + +void ThreadIdentifierData::initializeKeyOnceHelper() +{ + if (pthread_key_create(&m_key, destruct)) + CRASH(); +} + +void ThreadIdentifierData::initializeKeyOnce() +{ + static pthread_once_t onceControl = PTHREAD_ONCE_INIT; + if (pthread_once(&onceControl, initializeKeyOnceHelper)) + CRASH(); +} + +} // namespace WTF + +#endif // USE(PTHREADS) + diff --git a/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h b/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h new file mode 100644 index 0000000..3af87a8 --- /dev/null +++ b/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ThreadIdentifierDataPthreads_h +#define ThreadIdentifierDataPthreads_h + +#include <wtf/Noncopyable.h> +#include <wtf/Threading.h> + +namespace WTF { + +// Holds ThreadIdentifier in the thread-specific storage and employs pthreads-specific 2-pass destruction to reliably remove +// ThreadIdentifier from threadMap. It assumes regular ThreadSpecific types don't use multiple-pass destruction. +class ThreadIdentifierData : public Noncopyable { +public: + ~ThreadIdentifierData(); + + // Creates and puts an instance of ThreadIdentifierData into thread-specific storage. + static void initialize(ThreadIdentifier identifier); + + // Returns 0 if thread-specific storage was not initialized. + static ThreadIdentifier identifier(); + +private: + ThreadIdentifierData(ThreadIdentifier identifier) + : m_identifier(identifier) + , m_isDestroyedOnce(false) + { + } + + // This thread-specific destructor is called 2 times when thread terminates: + // - first, when all the other thread-specific destructors are called, it simply remembers it was 'destroyed once' + // and re-sets itself into the thread-specific slot to make Pthreads to call it again later. + // - second, after all thread-specific destructors were invoked, it gets called again - this time, we remove the + // ThreadIdentifier from the threadMap, completing the cleanup. + static void destruct(void* data); + + static void initializeKeyOnceHelper(); + static void initializeKeyOnce(); + + ThreadIdentifier m_identifier; + bool m_isDestroyedOnce; + static pthread_key_t m_key; +}; + +} // namespace WTF + +#endif // ThreadIdentifierDataPthreads_h + + diff --git a/JavaScriptCore/wtf/ThreadSpecific.h b/JavaScriptCore/wtf/ThreadSpecific.h index b6f5fd3..7e5679f 100644 --- a/JavaScriptCore/wtf/ThreadSpecific.h +++ b/JavaScriptCore/wtf/ThreadSpecific.h @@ -47,13 +47,13 @@ #include <pthread.h> #elif PLATFORM(QT) #include <QThreadStorage> -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) #include <windows.h> #endif namespace WTF { -#if !USE(PTHREADS) && !PLATFORM(QT) && PLATFORM(WIN_OS) +#if !USE(PTHREADS) && !PLATFORM(QT) && OS(WINDOWS) // ThreadSpecificThreadExit should be called each time when a thread is detached. // This is done automatically for threads created with WTF::createThread. void ThreadSpecificThreadExit(); @@ -68,7 +68,7 @@ public: ~ThreadSpecific(); private: -#if !USE(PTHREADS) && !PLATFORM(QT) && PLATFORM(WIN_OS) +#if !USE(PTHREADS) && !PLATFORM(QT) && OS(WINDOWS) friend void ThreadSpecificThreadExit(); #endif @@ -76,7 +76,7 @@ private: void set(T*); void static destroy(void* ptr); -#if USE(PTHREADS) || PLATFORM(QT) || PLATFORM(WIN_OS) +#if USE(PTHREADS) || PLATFORM(QT) || OS(WINDOWS) struct Data : Noncopyable { Data(T* value, ThreadSpecific<T>* owner) : value(value), owner(owner) {} #if PLATFORM(QT) @@ -91,15 +91,44 @@ private: }; #endif +#if ENABLE(SINGLE_THREADED) + T* m_value; +#else #if USE(PTHREADS) pthread_key_t m_key; #elif PLATFORM(QT) QThreadStorage<Data*> m_key; -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) int m_index; #endif +#endif }; +#if ENABLE(SINGLE_THREADED) +template<typename T> +inline ThreadSpecific<T>::ThreadSpecific() + : m_value(0) +{ +} + +template<typename T> +inline ThreadSpecific<T>::~ThreadSpecific() +{ +} + +template<typename T> +inline T* ThreadSpecific<T>::get() +{ + return m_value; +} + +template<typename T> +inline void ThreadSpecific<T>::set(T* ptr) +{ + ASSERT(!get()); + m_value = ptr; +} +#else #if USE(PTHREADS) template<typename T> inline ThreadSpecific<T>::ThreadSpecific() @@ -157,7 +186,12 @@ inline void ThreadSpecific<T>::set(T* ptr) m_key.setLocalData(data); } -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) + +// TLS_OUT_OF_INDEXES is not defined on WinCE. +#ifndef TLS_OUT_OF_INDEXES +#define TLS_OUT_OF_INDEXES 0xffffffff +#endif // The maximum number of TLS keys that can be created. For simplification, we assume that: // 1) Once the instance of ThreadSpecific<> is created, it will not be destructed until the program dies. @@ -171,14 +205,14 @@ template<typename T> inline ThreadSpecific<T>::ThreadSpecific() : m_index(-1) { - DWORD tls_key = TlsAlloc(); - if (tls_key == TLS_OUT_OF_INDEXES) + DWORD tlsKey = TlsAlloc(); + if (tlsKey == TLS_OUT_OF_INDEXES) CRASH(); m_index = InterlockedIncrement(&tlsKeyCount()) - 1; if (m_index >= kMaxTlsKeySize) CRASH(); - tlsKeys()[m_index] = tls_key; + tlsKeys()[m_index] = tlsKey; } template<typename T> @@ -207,10 +241,12 @@ inline void ThreadSpecific<T>::set(T* ptr) #else #error ThreadSpecific is not implemented for this platform. #endif +#endif template<typename T> inline void ThreadSpecific<T>::destroy(void* ptr) { +#if !ENABLE(SINGLE_THREADED) Data* data = static_cast<Data*>(ptr); #if USE(PTHREADS) @@ -230,7 +266,7 @@ inline void ThreadSpecific<T>::destroy(void* ptr) pthread_setspecific(data->owner->m_key, 0); #elif PLATFORM(QT) // Do nothing here -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) TlsSetValue(tlsKeys()[data->owner->m_index], 0); #else #error ThreadSpecific is not implemented for this platform. @@ -239,6 +275,7 @@ inline void ThreadSpecific<T>::destroy(void* ptr) #if !PLATFORM(QT) delete data; #endif +#endif } template<typename T> diff --git a/JavaScriptCore/wtf/Threading.cpp b/JavaScriptCore/wtf/Threading.cpp index 74c47f4..49de59e 100644 --- a/JavaScriptCore/wtf/Threading.cpp +++ b/JavaScriptCore/wtf/Threading.cpp @@ -49,13 +49,14 @@ static void* threadEntryPoint(void* contextData) { NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData); - setThreadNameInternal(context->name); - - // Block until our creating thread has completed any extra setup work. + // Block until our creating thread has completed any extra setup work, including + // establishing ThreadIdentifier. { MutexLocker locker(context->creationMutex); } + initializeCurrentThreadInternal(context->name); + // Grab the info that we need out of the context, then deallocate it. ThreadFunction entryPoint = context->entryPoint; void* data = context->data; diff --git a/JavaScriptCore/wtf/Threading.h b/JavaScriptCore/wtf/Threading.h index 2a2e9c4..1599562 100644 --- a/JavaScriptCore/wtf/Threading.h +++ b/JavaScriptCore/wtf/Threading.h @@ -61,7 +61,7 @@ #include "Platform.h" -#if PLATFORM(WINCE) +#if OS(WINCE) #include <windows.h> #endif @@ -69,11 +69,11 @@ #include <wtf/Locker.h> #include <wtf/Noncopyable.h> -#if PLATFORM(WIN_OS) && !PLATFORM(WINCE) +#if OS(WINDOWS) && !OS(WINCE) #include <windows.h> -#elif PLATFORM(DARWIN) +#elif OS(DARWIN) #include <libkern/OSAtomic.h> -#elif PLATFORM(ANDROID) +#elif OS(ANDROID) #include <cutils/atomic.h> #elif COMPILER(GCC) #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) @@ -121,7 +121,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadN // Called in the thread during initialization. // Helpful for platforms where the thread name must be set from within the thread. -void setThreadNameInternal(const char* threadName); +void initializeCurrentThreadInternal(const char* threadName); ThreadIdentifier currentThread(); bool isMainThread(); @@ -144,7 +144,7 @@ typedef GOwnPtr<GCond> PlatformCondition; typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex; typedef void* PlatformReadWriteLock; // FIXME: Implement. typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition; -#elif PLATFORM(WIN_OS) +#elif OS(WINDOWS) struct PlatformMutex { CRITICAL_SECTION m_internalMutex; size_t m_recursionCount; @@ -217,10 +217,10 @@ private: PlatformCondition m_condition; }; -#if PLATFORM(WIN_OS) +#if OS(WINDOWS) #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 -#if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WINCE) +#if COMPILER(MINGW) || COMPILER(MSVC7) || OS(WINCE) inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); } inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); } #else @@ -228,18 +228,18 @@ inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(r inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); } #endif -#elif PLATFORM(DARWIN) +#elif OS(DARWIN) #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); } inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); } -#elif PLATFORM(ANDROID) +#elif OS(ANDROID) inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(addend); } inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); } -#elif COMPILER(GCC) && !PLATFORM(SPARC64) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc +#elif COMPILER(GCC) && !CPU(SPARC64) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc #define WTF_USE_LOCKFREE_THREADSAFESHARED 1 inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; } diff --git a/JavaScriptCore/wtf/ThreadingNone.cpp b/JavaScriptCore/wtf/ThreadingNone.cpp index 46f23d2..2e8a259 100644 --- a/JavaScriptCore/wtf/ThreadingNone.cpp +++ b/JavaScriptCore/wtf/ThreadingNone.cpp @@ -30,11 +30,13 @@ #include "config.h" #include "Threading.h" +#if ENABLE(SINGLE_THREADED) + namespace WTF { void initializeThreading() { } ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char*) { return ThreadIdentifier(); } -void setThreadNameInternal(const char*) { } +void initializeCurrentThreadInternal(const char*) { } int waitForThreadCompletion(ThreadIdentifier, void**) { return 0; } void detachThread(ThreadIdentifier) { } ThreadIdentifier currentThread() { return ThreadIdentifier(); } @@ -57,3 +59,5 @@ void lockAtomicallyInitializedStaticMutex() { } void unlockAtomicallyInitializedStaticMutex() { } } // namespace WebCore + +#endif diff --git a/JavaScriptCore/wtf/ThreadingPthreads.cpp b/JavaScriptCore/wtf/ThreadingPthreads.cpp index f5cba5d..e4fc0eb 100644 --- a/JavaScriptCore/wtf/ThreadingPthreads.cpp +++ b/JavaScriptCore/wtf/ThreadingPthreads.cpp @@ -37,6 +37,8 @@ #include "MainThread.h" #include "RandomNumberSeed.h" #include "StdLibExtras.h" +#include "ThreadIdentifierDataPthreads.h" +#include "ThreadSpecific.h" #include "UnusedParam.h" #include <errno.h> @@ -45,8 +47,13 @@ #include <sys/time.h> #endif +<<<<<<< HEAD #if PLATFORM(ANDROID) #include "JNIUtility.h" +======= +#if OS(ANDROID) +#include "jni_utility.h" +>>>>>>> webkit.org at r54127 #endif namespace WTF { @@ -55,10 +62,12 @@ typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap; static Mutex* atomicallyInitializedStaticMutex; -#if !PLATFORM(DARWIN) || PLATFORM(CHROMIUM) +#if !OS(DARWIN) || PLATFORM(CHROMIUM) || USE(WEB_THREAD) static pthread_t mainThread; // The thread that was the first to call initializeThreading(), which must be the main thread. #endif +void clearPthreadHandleForIdentifier(ThreadIdentifier); + static Mutex& threadMapMutex() { DEFINE_STATIC_LOCAL(Mutex, mutex, ()); @@ -71,7 +80,7 @@ void initializeThreading() atomicallyInitializedStaticMutex = new Mutex; threadMapMutex(); initializeRandomNumberGenerator(); -#if !PLATFORM(DARWIN) || PLATFORM(CHROMIUM) +#if !OS(DARWIN) || PLATFORM(CHROMIUM) || USE(WEB_THREAD) mainThread = pthread_self(); #endif initializeMainThread(); @@ -108,7 +117,7 @@ static ThreadIdentifier identifierByPthreadHandle(const pthread_t& pthreadHandle return 0; } -static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHandle) +static ThreadIdentifier establishIdentifierForPthreadHandle(const pthread_t& pthreadHandle) { ASSERT(!identifierByPthreadHandle(pthreadHandle)); @@ -128,7 +137,7 @@ static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id) return threadMap().get(id); } -static void clearPthreadHandleForIdentifier(ThreadIdentifier id) +void clearPthreadHandleForIdentifier(ThreadIdentifier id) { MutexLocker locker(threadMapMutex()); @@ -137,7 +146,7 @@ static void clearPthreadHandleForIdentifier(ThreadIdentifier id) threadMap().remove(id); } -#if PLATFORM(ANDROID) +#if OS(ANDROID) // On the Android platform, threads must be registered with the VM before they run. struct ThreadData { ThreadFunction entryPoint; @@ -185,13 +194,17 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con } #endif -void setThreadNameInternal(const char* threadName) +void initializeCurrentThreadInternal(const char* threadName) { #if HAVE(PTHREAD_SETNAME_NP) pthread_setname_np(threadName); #else UNUSED_PARAM(threadName); #endif + + ThreadIdentifier id = identifierByPthreadHandle(pthread_self()); + ASSERT(id); + ThreadIdentifierData::initialize(id); } int waitForThreadCompletion(ThreadIdentifier threadID, void** result) @@ -199,12 +212,13 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result) ASSERT(threadID); pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID); + if (!pthreadHandle) + return 0; int joinResult = pthread_join(pthreadHandle, result); if (joinResult == EDEADLK) LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID); - clearPthreadHandleForIdentifier(threadID); return joinResult; } @@ -213,23 +227,27 @@ void detachThread(ThreadIdentifier threadID) ASSERT(threadID); pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID); + if (!pthreadHandle) + return; pthread_detach(pthreadHandle); - - clearPthreadHandleForIdentifier(threadID); } ThreadIdentifier currentThread() { - pthread_t currentThread = pthread_self(); - if (ThreadIdentifier id = identifierByPthreadHandle(currentThread)) + ThreadIdentifier id = ThreadIdentifierData::identifier(); + if (id) return id; - return establishIdentifierForPthreadHandle(currentThread); + + // Not a WTF-created thread, ThreadIdentifier is not established yet. + id = establishIdentifierForPthreadHandle(pthread_self()); + ThreadIdentifierData::initialize(id); + return id; } bool isMainThread() { -#if PLATFORM(DARWIN) && !PLATFORM(CHROMIUM) +#if OS(DARWIN) && !PLATFORM(CHROMIUM) && !USE(WEB_THREAD) return pthread_main_np(); #else return pthread_equal(pthread_self(), mainThread); diff --git a/JavaScriptCore/wtf/ThreadingWin.cpp b/JavaScriptCore/wtf/ThreadingWin.cpp index cccbda1..73c3f0c 100644 --- a/JavaScriptCore/wtf/ThreadingWin.cpp +++ b/JavaScriptCore/wtf/ThreadingWin.cpp @@ -87,10 +87,10 @@ #include "Threading.h" #include "MainThread.h" -#if !USE(PTHREADS) && PLATFORM(WIN_OS) +#if !USE(PTHREADS) && OS(WINDOWS) #include "ThreadSpecific.h" #endif -#if !PLATFORM(WINCE) +#if !OS(WINCE) #include <process.h> #endif #if HAVE(ERRNO_H) @@ -118,7 +118,7 @@ typedef struct tagTHREADNAME_INFO { } THREADNAME_INFO; #pragma pack(pop) -void setThreadNameInternal(const char* szThreadName) +void initializeCurrentThreadInternal(const char* szThreadName) { THREADNAME_INFO info; info.dwType = 0x1000; @@ -161,7 +161,7 @@ void initializeThreading() initializeRandomNumberGenerator(); initializeMainThread(); mainThreadIdentifier = currentThread(); - setThreadNameInternal("Main Thread"); + initializeCurrentThreadInternal("Main Thread"); } } @@ -205,7 +205,7 @@ static unsigned __stdcall wtfThreadEntryPoint(void* param) void* result = invocation.function(invocation.data); -#if !USE(PTHREADS) && PLATFORM(WIN_OS) +#if !USE(PTHREADS) && OS(WINDOWS) // Do the TLS cleanup. ThreadSpecificThreadExit(); #endif @@ -218,7 +218,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con unsigned threadIdentifier = 0; ThreadIdentifier threadID = 0; ThreadFunctionInvocation* invocation = new ThreadFunctionInvocation(entryPoint, data); -#if PLATFORM(WINCE) +#if OS(WINCE) // This is safe on WINCE, since CRT is in the core and innately multithreaded. // On desktop Windows, need to use _beginthreadex (not available on WinCE) if using any CRT functions HANDLE threadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)wtfThreadEntryPoint, invocation, 0, (LPDWORD)&threadIdentifier); @@ -226,7 +226,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con HANDLE threadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, wtfThreadEntryPoint, invocation, 0, &threadIdentifier)); #endif if (!threadHandle) { -#if PLATFORM(WINCE) +#if OS(WINCE) LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, ::GetLastError()); #elif defined(NO_ERRNO) LOG_ERROR("Failed to create thread at entry point %p with data %p.", entryPoint, data); diff --git a/JavaScriptCore/wtf/TypeTraits.cpp b/JavaScriptCore/wtf/TypeTraits.cpp index 36fc6c6..9e51ad0 100644 --- a/JavaScriptCore/wtf/TypeTraits.cpp +++ b/JavaScriptCore/wtf/TypeTraits.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2009, 2010 Google Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -101,6 +101,20 @@ COMPILE_ASSERT((!IsSameType<int, int*>::value), WTF_IsSameType_int_int_pointer_f COMPILE_ASSERT((!IsSameType<bool, const bool>::value), WTF_IsSameType_const_change_false); COMPILE_ASSERT((!IsSameType<bool, volatile bool>::value), WTF_IsSameType_volatile_change_false); +template <typename T> +class TestBaseClass { +}; + +class TestDerivedClass : public TestBaseClass<int> { +}; + +COMPILE_ASSERT((IsSubclass<TestDerivedClass, TestBaseClass<int> >::value), WTF_Test_IsSubclass_Derived_From_Base); +COMPILE_ASSERT((!IsSubclass<TestBaseClass<int>, TestDerivedClass>::value), WTF_Test_IsSubclass_Base_From_Derived); +COMPILE_ASSERT((IsSubclassOfTemplate<TestDerivedClass, TestBaseClass>::value), WTF_Test_IsSubclassOfTemplate_Base_From_Derived); +COMPILE_ASSERT((IsSameType<RemoveTemplate<TestBaseClass<int>, TestBaseClass>::Type, int>::value), WTF_Test_RemoveTemplate); +COMPILE_ASSERT((IsSameType<RemoveTemplate<int, TestBaseClass>::Type, int>::value), WTF_Test_RemoveTemplate_WithoutTemplate); + + COMPILE_ASSERT((IsSameType<bool, RemoveConst<const bool>::Type>::value), WTF_test_RemoveConst_const_bool); COMPILE_ASSERT((!IsSameType<bool, RemoveConst<volatile bool>::Type>::value), WTF_test_RemoveConst_volatile_bool); diff --git a/JavaScriptCore/wtf/TypeTraits.h b/JavaScriptCore/wtf/TypeTraits.h index 9e75e7a..62dbc49 100644 --- a/JavaScriptCore/wtf/TypeTraits.h +++ b/JavaScriptCore/wtf/TypeTraits.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2009, 2010 Google Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -104,6 +104,40 @@ namespace WTF { static const bool value = true; }; + template <typename T, typename U> class IsSubclass { + typedef char YesType; + struct NoType { + char padding[8]; + }; + + static YesType subclassCheck(U*); + static NoType subclassCheck(...); + static T* t; + public: + static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType); + }; + + template <typename T, template<class V> class U> class IsSubclassOfTemplate { + typedef char YesType; + struct NoType { + char padding[8]; + }; + + template<typename W> static YesType subclassCheck(U<W>*); + static NoType subclassCheck(...); + static T* t; + public: + static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType); + }; + + template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate { + typedef T Type; + }; + + template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> { + typedef T Type; + }; + template <typename T> struct RemoveConst { typedef T Type; }; diff --git a/JavaScriptCore/wtf/VMTags.h b/JavaScriptCore/wtf/VMTags.h index 519f518..1ec79d9 100644 --- a/JavaScriptCore/wtf/VMTags.h +++ b/JavaScriptCore/wtf/VMTags.h @@ -30,7 +30,7 @@ // On Mac OS X, the VM subsystem allows tagging memory requested from mmap and vm_map // in order to aid tools that inspect system memory use. -#if PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER) +#if OS(DARWIN) && !defined(BUILDING_ON_TIGER) #include <mach/vm_statistics.h> @@ -44,12 +44,12 @@ #define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(65) #endif // defined(VM_MEMORY_JAVASCRIPT_CORE) && defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) && defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) && defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) -#else // PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER) +#else // OS(DARWIN) && !defined(BUILDING_ON_TIGER) #define VM_TAG_FOR_COLLECTOR_MEMORY -1 #define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1 #define VM_TAG_FOR_REGISTERFILE_MEMORY -1 -#endif // PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER) +#endif // OS(DARWIN) && !defined(BUILDING_ON_TIGER) #endif // VMTags_h diff --git a/JavaScriptCore/wtf/chromium/ChromiumThreading.h b/JavaScriptCore/wtf/chromium/ChromiumThreading.h index e9b1f39..b2c5075 100644 --- a/JavaScriptCore/wtf/chromium/ChromiumThreading.h +++ b/JavaScriptCore/wtf/chromium/ChromiumThreading.h @@ -33,12 +33,12 @@ namespace WTF { - // An interface to the embedding layer, which provides threading support. - class ChromiumThreading { - public: - static void initializeMainThread(); - static void scheduleDispatchFunctionsOnMainThread(); - }; +// An interface to the embedding layer, which provides threading support. +class ChromiumThreading { +public: + static void initializeMainThread(); + static void scheduleDispatchFunctionsOnMainThread(); +}; } // namespace WTF diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp index edcb82b..6289d04 100644 --- a/JavaScriptCore/wtf/dtoa.cpp +++ b/JavaScriptCore/wtf/dtoa.cpp @@ -159,9 +159,9 @@ #pragma warning(disable: 4554) #endif -#if PLATFORM(BIG_ENDIAN) +#if CPU(BIG_ENDIAN) #define IEEE_MC68k -#elif PLATFORM(MIDDLE_ENDIAN) +#elif CPU(MIDDLE_ENDIAN) #define IEEE_ARM #else #define IEEE_8087 @@ -262,7 +262,8 @@ typedef union { double d; uint32_t L[2]; } U; #define Pack_32 #endif -#if PLATFORM(PPC64) || PLATFORM(X86_64) +#if CPU(PPC64) || CPU(X86_64) +// FIXME: should we enable this on all 64-bit CPUs? // 64-bit emulation provided by the compiler is likely to be slower than dtoa own code on 32-bit hardware. #define USE_LONG_LONG #endif @@ -560,7 +561,7 @@ static void mult(BigInt& aRef, const BigInt& bRef) aRef = c; } -struct P5Node { +struct P5Node : Noncopyable { BigInt val; P5Node* next; }; diff --git a/JavaScriptCore/wtf/gtk/GOwnPtr.cpp b/JavaScriptCore/wtf/gtk/GOwnPtr.cpp index 8999962..1a151b9 100644 --- a/JavaScriptCore/wtf/gtk/GOwnPtr.cpp +++ b/JavaScriptCore/wtf/gtk/GOwnPtr.cpp @@ -57,11 +57,4 @@ template <> void freeOwnedGPtr<GDir>(GDir* ptr) if (ptr) g_dir_close(ptr); } - -template <> void freeOwnedGPtr<GHashTable>(GHashTable* ptr) -{ - if (ptr) - g_hash_table_unref(ptr); -} - } // namespace WTF diff --git a/JavaScriptCore/wtf/gtk/GRefPtr.cpp b/JavaScriptCore/wtf/gtk/GRefPtr.cpp new file mode 100644 index 0000000..e7cf34b --- /dev/null +++ b/JavaScriptCore/wtf/gtk/GRefPtr.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2009 Martin Robinson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" +#include "GRefPtr.h" + +#include <glib.h> + +namespace WTF { + +template <> GHashTable* refGPtr(GHashTable* ptr) +{ + if (ptr) + g_hash_table_ref(ptr); + return ptr; +} + +template <> void derefGPtr(GHashTable* ptr) +{ + g_hash_table_unref(ptr); +} + +} // namespace WTF diff --git a/JavaScriptCore/wtf/gtk/GRefPtr.h b/JavaScriptCore/wtf/gtk/GRefPtr.h new file mode 100644 index 0000000..66739ef --- /dev/null +++ b/JavaScriptCore/wtf/gtk/GRefPtr.h @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2009 Martin Robinson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef WTF_GRefPtr_h +#define WTF_GRefPtr_h + +#include "AlwaysInline.h" +#include <algorithm> + +typedef struct _GHashTable GHashTable; + +namespace WTF { + +enum GRefPtrAdoptType { GRefPtrAdopt }; +template <typename T> inline T* refGPtr(T*); +template <typename T> inline void derefGPtr(T*); +template <typename T> class GRefPtr; +template <typename T> GRefPtr<T> adoptGRef(T*); +template <> GHashTable* refGPtr(GHashTable* ptr); +template <> void derefGPtr(GHashTable* ptr); + +template <typename T> class GRefPtr { +public: + GRefPtr() : m_ptr(0) { } + GRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) refGPtr(ptr); } + GRefPtr(const GRefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) refGPtr(ptr); } + template <typename U> GRefPtr(const GRefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) refGPtr(ptr); } + + ~GRefPtr() { if (T* ptr = m_ptr) derefGPtr(ptr); } + + void clear() + { + if (T* ptr = m_ptr) + derefGPtr(ptr); + m_ptr = 0; + } + + T* get() const { return m_ptr; } + T& operator*() const { return *m_ptr; } + ALWAYS_INLINE T* operator->() const { return m_ptr; } + + bool operator!() const { return !m_ptr; } + + // This conversion operator allows implicit conversion to bool but not to other integer types. + typedef T* GRefPtr::*UnspecifiedBoolType; + operator UnspecifiedBoolType() const { return m_ptr ? &GRefPtr::m_ptr : 0; } + + GRefPtr& operator=(const GRefPtr&); + GRefPtr& operator=(T*); + template <typename U> GRefPtr& operator=(const GRefPtr<U>&); + + void swap(GRefPtr&); + friend GRefPtr adoptGRef<T>(T*); + +private: + static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } + // Adopting constructor. + GRefPtr(T* ptr, GRefPtrAdoptType) : m_ptr(ptr) {} + + T* m_ptr; +}; + +template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(const GRefPtr<T>& o) +{ + T* optr = o.get(); + if (optr) + refGPtr(optr); + T* ptr = m_ptr; + m_ptr = optr; + if (ptr) + derefGPtr(ptr); + return *this; +} + +template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(T* optr) +{ + T* ptr = m_ptr; + if (optr) + refGPtr(optr); + m_ptr = optr; + if (ptr) + derefGPtr(ptr); + return *this; +} + +template <class T> inline void GRefPtr<T>::swap(GRefPtr<T>& o) +{ + std::swap(m_ptr, o.m_ptr); +} + +template <class T> inline void swap(GRefPtr<T>& a, GRefPtr<T>& b) +{ + a.swap(b); +} + +template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, const GRefPtr<U>& b) +{ + return a.get() == b.get(); +} + +template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, U* b) +{ + return a.get() == b; +} + +template <typename T, typename U> inline bool operator==(T* a, const GRefPtr<U>& b) +{ + return a == b.get(); +} + +template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, const GRefPtr<U>& b) +{ + return a.get() != b.get(); +} + +template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, U* b) +{ + return a.get() != b; +} + +template <typename T, typename U> inline bool operator!=(T* a, const GRefPtr<U>& b) +{ + return a != b.get(); +} + +template <typename T, typename U> inline GRefPtr<T> static_pointer_cast(const GRefPtr<U>& p) +{ + return GRefPtr<T>(static_cast<T*>(p.get())); +} + +template <typename T, typename U> inline GRefPtr<T> const_pointer_cast(const GRefPtr<U>& p) +{ + return GRefPtr<T>(const_cast<T*>(p.get())); +} + +template <typename T> inline T* getPtr(const GRefPtr<T>& p) +{ + return p.get(); +} + +template <typename T> GRefPtr<T> adoptGRef(T* p) +{ + return GRefPtr<T>(p, GRefPtrAdopt); +} + +template <typename T> inline T* refGPtr(T* ptr) +{ + if (ptr) + g_object_ref_sink(ptr); + return ptr; +} + +template <typename T> inline void derefGPtr(T* ptr) +{ + if (ptr) + g_object_unref(ptr); +} + +} // namespace WTF + +using WTF::GRefPtr; +using WTF::refGPtr; +using WTF::derefGPtr; +using WTF::adoptGRef; +using WTF::static_pointer_cast; +using WTF::const_pointer_cast; + +#endif // WTF_GRefPtr_h diff --git a/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp b/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp index b4f4de1..a6ec8f7 100644 --- a/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp +++ b/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp @@ -138,7 +138,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con return threadID; } -void setThreadNameInternal(const char*) +void initializeCurrentThreadInternal(const char*) { } diff --git a/JavaScriptCore/wtf/mac/MainThreadMac.mm b/JavaScriptCore/wtf/mac/MainThreadMac.mm index c79acc1..0ddd5f6 100644 --- a/JavaScriptCore/wtf/mac/MainThreadMac.mm +++ b/JavaScriptCore/wtf/mac/MainThreadMac.mm @@ -49,17 +49,28 @@ namespace WTF { static WTFMainThreadCaller* staticMainThreadCaller = nil; +#if USE(WEB_THREAD) +static NSThread* webThread = nil; +#endif void initializeMainThreadPlatform() { ASSERT(!staticMainThreadCaller); staticMainThreadCaller = [[WTFMainThreadCaller alloc] init]; + +#if USE(WEB_THREAD) + webThread = [[NSThread currentThread] retain]; +#endif } void scheduleDispatchFunctionsOnMainThread() { ASSERT(staticMainThreadCaller); +#if USE(WEB_THREAD) + [staticMainThreadCaller performSelector:@selector(call) onThread:webThread withObject:nil waitUntilDone:NO]; +#else [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO]; +#endif } } // namespace WTF diff --git a/JavaScriptCore/wtf/qt/ThreadingQt.cpp b/JavaScriptCore/wtf/qt/ThreadingQt.cpp index 1fdd2bb..dc04a68 100644 --- a/JavaScriptCore/wtf/qt/ThreadingQt.cpp +++ b/JavaScriptCore/wtf/qt/ThreadingQt.cpp @@ -29,6 +29,8 @@ #include "config.h" #include "Threading.h" +#if !ENABLE(SINGLE_THREADED) + #include "CurrentTime.h" #include "HashMap.h" #include "MainThread.h" @@ -64,6 +66,21 @@ void ThreadPrivate::run() m_returnValue = m_entryPoint(m_data); } +class ThreadMonitor : public QObject { + Q_OBJECT +public: + static ThreadMonitor * instance() + { + static ThreadMonitor *instance = new ThreadMonitor(); + return instance; + } + +public Q_SLOTS: + void threadFinished() + { + sender()->deleteLater(); + } +}; static Mutex* atomicallyInitializedStaticMutex; @@ -155,6 +172,9 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data); return 0; } + + QObject::connect(thread, SIGNAL(finished()), ThreadMonitor::instance(), SLOT(threadFinished())); + thread->start(); QThread* threadRef = static_cast<QThread*>(thread); @@ -162,7 +182,7 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con return establishIdentifierForThread(threadRef); } -void setThreadNameInternal(const char*) +void initializeCurrentThreadInternal(const char*) { } @@ -181,8 +201,10 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result) return !res; } -void detachThread(ThreadIdentifier) +void detachThread(ThreadIdentifier threadID) { + ASSERT(threadID); + clearThreadForIdentifier(threadID); } ThreadIdentifier currentThread() @@ -267,3 +289,7 @@ void ThreadCondition::broadcast() } } // namespace WebCore + +#include "ThreadingQt.moc" + +#endif diff --git a/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp b/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp index 6376bb3..a1753a4 100644 --- a/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp +++ b/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp @@ -36,7 +36,7 @@ #include <unicode/ucol.h> #include <string.h> -#if PLATFORM(DARWIN) +#if OS(DARWIN) #include "RetainPtr.h" #include <CoreFoundation/CoreFoundation.h> #endif @@ -59,9 +59,9 @@ Collator::Collator(const char* locale) std::auto_ptr<Collator> Collator::userDefault() { -#if PLATFORM(DARWIN) && PLATFORM(CF) +#if OS(DARWIN) && PLATFORM(CF) // Mac OS X doesn't set UNIX locale to match user-selected one, so ICU default doesn't work. -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !PLATFORM(IPHONE) +#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !OS(IPHONE_OS) RetainPtr<CFLocaleRef> currentLocale(AdoptCF, CFLocaleCopyCurrent()); CFStringRef collationOrder = (CFStringRef)CFLocaleGetValue(currentLocale.get(), kCFLocaleCollatorIdentifier); #else diff --git a/JavaScriptCore/wtf/win/MainThreadWin.cpp b/JavaScriptCore/wtf/win/MainThreadWin.cpp index c6dcb7d..ee70b59 100644 --- a/JavaScriptCore/wtf/win/MainThreadWin.cpp +++ b/JavaScriptCore/wtf/win/MainThreadWin.cpp @@ -32,7 +32,7 @@ #include "Assertions.h" #include "Threading.h" -#if !PLATFORM(WINCE) +#if !OS(WINCE) #include <windows.h> #endif @@ -56,7 +56,8 @@ void initializeMainThreadPlatform() if (threadingWindowHandle) return; -#if PLATFORM(WINCE) + HWND hWndParent = 0; +#if OS(WINCE) WNDCLASS wcex; memset(&wcex, 0, sizeof(WNDCLASS)); #else @@ -66,14 +67,15 @@ void initializeMainThreadPlatform() #endif wcex.lpfnWndProc = ThreadingWindowWndProc; wcex.lpszClassName = kThreadingWindowClassName; -#if PLATFORM(WINCE) +#if OS(WINCE) RegisterClass(&wcex); #else RegisterClassEx(&wcex); + hWndParent = HWND_MESSAGE; #endif threadingWindowHandle = CreateWindow(kThreadingWindowClassName, 0, 0, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, 0, 0); + CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, hWndParent, 0, 0, 0); threadingFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.MainThreadFired"); } diff --git a/JavaScriptCore/wtf/wince/MemoryManager.cpp b/JavaScriptCore/wtf/wince/MemoryManager.cpp index b65b368..81d4f80 100644 --- a/JavaScriptCore/wtf/wince/MemoryManager.cpp +++ b/JavaScriptCore/wtf/wince/MemoryManager.cpp @@ -139,25 +139,25 @@ void* fastZeroedMalloc(size_t n) return p; } -void* tryFastMalloc(size_t n) +TryMallocReturnValue tryFastMalloc(size_t n) { MemoryAllocationCanFail canFail; return fastMalloc(n); } -void* tryFastZeroedMalloc(size_t n) +TryMallocReturnValue tryFastZeroedMalloc(size_t n) { MemoryAllocationCanFail canFail; return fastZeroedMalloc(n); } -void* tryFastCalloc(size_t n_elements, size_t element_size) +TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size) { MemoryAllocationCanFail canFail; return fastCalloc(n_elements, element_size); } -void* tryFastRealloc(void* p, size_t n) +TryMallocReturnValue tryFastRealloc(void* p, size_t n) { MemoryAllocationCanFail canFail; return fastRealloc(p, n); diff --git a/JavaScriptCore/yarr/RegexCompiler.cpp b/JavaScriptCore/yarr/RegexCompiler.cpp index c7b3c81..9cd3d12 100644 --- a/JavaScriptCore/yarr/RegexCompiler.cpp +++ b/JavaScriptCore/yarr/RegexCompiler.cpp @@ -708,7 +708,7 @@ const char* compileRegex(const UString& patternString, RegexPattern& pattern) unsigned numSubpatterns = pattern.m_numSubpatterns; constructor.reset(); -#ifndef NDEBUG +#if !ASSERT_DISABLED const char* error = #endif parse(constructor, patternString, numSubpatterns); diff --git a/JavaScriptCore/yarr/RegexJIT.cpp b/JavaScriptCore/yarr/RegexJIT.cpp index 5ce579a..fcb8d86 100644 --- a/JavaScriptCore/yarr/RegexJIT.cpp +++ b/JavaScriptCore/yarr/RegexJIT.cpp @@ -44,7 +44,7 @@ namespace JSC { namespace Yarr { class RegexGenerator : private MacroAssembler { friend void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline); -#if PLATFORM(ARM) +#if CPU(ARM) static const RegisterID input = ARMRegisters::r0; static const RegisterID index = ARMRegisters::r1; static const RegisterID length = ARMRegisters::r2; @@ -54,7 +54,7 @@ class RegexGenerator : private MacroAssembler { static const RegisterID regT1 = ARMRegisters::r6; static const RegisterID returnRegister = ARMRegisters::r0; -#elif PLATFORM(X86) +#elif CPU(X86) static const RegisterID input = X86Registers::eax; static const RegisterID index = X86Registers::edx; static const RegisterID length = X86Registers::ecx; @@ -64,7 +64,7 @@ class RegexGenerator : private MacroAssembler { static const RegisterID regT1 = X86Registers::esi; static const RegisterID returnRegister = X86Registers::eax; -#elif PLATFORM(X86_64) +#elif CPU(X86_64) static const RegisterID input = X86Registers::edi; static const RegisterID index = X86Registers::esi; static const RegisterID length = X86Registers::edx; @@ -1288,11 +1288,11 @@ class RegexGenerator : private MacroAssembler { void generateEnter() { -#if PLATFORM(X86_64) +#if CPU(X86_64) push(X86Registers::ebp); move(stackPointerRegister, X86Registers::ebp); push(X86Registers::ebx); -#elif PLATFORM(X86) +#elif CPU(X86) push(X86Registers::ebp); move(stackPointerRegister, X86Registers::ebp); // TODO: do we need spill registers to fill the output pointer if there are no sub captures? @@ -1308,7 +1308,7 @@ class RegexGenerator : private MacroAssembler { #else loadPtr(Address(X86Registers::ebp, 2 * sizeof(void*)), output); #endif -#elif PLATFORM(ARM) +#elif CPU(ARM) push(ARMRegisters::r4); push(ARMRegisters::r5); push(ARMRegisters::r6); @@ -1318,15 +1318,15 @@ class RegexGenerator : private MacroAssembler { void generateReturn() { -#if PLATFORM(X86_64) +#if CPU(X86_64) pop(X86Registers::ebx); pop(X86Registers::ebp); -#elif PLATFORM(X86) +#elif CPU(X86) pop(X86Registers::esi); pop(X86Registers::edi); pop(X86Registers::ebx); pop(X86Registers::ebp); -#elif PLATFORM(ARM) +#elif CPU(ARM) pop(ARMRegisters::r6); pop(ARMRegisters::r5); pop(ARMRegisters::r4); diff --git a/JavaScriptCore/yarr/RegexJIT.h b/JavaScriptCore/yarr/RegexJIT.h index 1872f21..935b9a3 100644 --- a/JavaScriptCore/yarr/RegexJIT.h +++ b/JavaScriptCore/yarr/RegexJIT.h @@ -37,7 +37,7 @@ #include <pcre.h> struct JSRegExp; // temporary, remove when fallback is removed. -#if PLATFORM(X86) && !COMPILER(MSVC) +#if CPU(X86) && !COMPILER(MSVC) #define YARR_CALL __attribute__ ((regparm (3))) #else #define YARR_CALL |