From: Apple Date: Mon, 17 Sep 2012 19:58:38 +0000 (+0000) Subject: JavaScriptCore-1097.3.tar.gz X-Git-Tag: ios-60^0 X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/commitdiff_plain/6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174?ds=inline JavaScriptCore-1097.3.tar.gz --- diff --git a/API/APICast.h b/API/APICast.h index 4294d3d..f019a7a 100644 --- a/API/APICast.h +++ b/API/APICast.h @@ -69,7 +69,7 @@ inline JSC::JSValue toJS(JSC::ExecState* exec, JSValueRef v) if (!jsCell) return JSC::JSValue(); if (jsCell->isAPIValueWrapper()) - return static_cast(jsCell)->value(); + return JSC::jsCast(jsCell)->value(); return jsCell; #else return JSC::JSValue::decode(reinterpret_cast(const_cast(v))); diff --git a/API/APIShims.h b/API/APIShims.h index 2e13851..ac540a2 100644 --- a/API/APIShims.h +++ b/API/APIShims.h @@ -34,27 +34,33 @@ namespace JSC { class APIEntryShimWithoutLock { +public: + enum RefGlobalDataTag { DontRefGlobalData = 0, RefGlobalData }; + protected: - APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread) - : m_globalData(globalData) + APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread, RefGlobalDataTag shouldRefGlobalData) + : m_shouldRefGlobalData(shouldRefGlobalData) + , m_globalData(globalData) , m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(globalData->identifierTable)) { + if (shouldRefGlobalData) + m_globalData->ref(); UNUSED_PARAM(registerThread); -#if ENABLE(JSC_MULTIPLE_THREADS) if (registerThread) globalData->heap.machineThreads().addCurrentThread(); -#endif - m_globalData->heap.activityCallback()->synchronize(); - m_globalData->timeoutChecker.start(); + if (m_globalData->heap.activityCallback()) + m_globalData->heap.activityCallback()->synchronize(); } ~APIEntryShimWithoutLock() { - m_globalData->timeoutChecker.stop(); wtfThreadData().setCurrentIdentifierTable(m_entryIdentifierTable); + if (m_shouldRefGlobalData) + m_globalData->deref(); } -private: +protected: + RefGlobalDataTag m_shouldRefGlobalData; JSGlobalData* m_globalData; IdentifierTable* m_entryIdentifierTable; }; @@ -63,20 +69,38 @@ class APIEntryShim : public APIEntryShimWithoutLock { public: // Normal API entry APIEntryShim(ExecState* exec, bool registerThread = true) - : APIEntryShimWithoutLock(&exec->globalData(), registerThread) - , m_lock(exec) + : APIEntryShimWithoutLock(&exec->globalData(), registerThread, RefGlobalData) { + init(); + } + + // This constructor is necessary for HeapTimer to prevent it from accidentally resurrecting + // the ref count of a "dead" JSGlobalData. + APIEntryShim(JSGlobalData* globalData, RefGlobalDataTag refGlobalData, bool registerThread = true) + : APIEntryShimWithoutLock(globalData, registerThread, refGlobalData) + { + init(); } // JSPropertyNameAccumulator only has a globalData. APIEntryShim(JSGlobalData* globalData, bool registerThread = true) - : APIEntryShimWithoutLock(globalData, registerThread) - , m_lock(globalData->isSharedInstance() ? LockForReal : SilenceAssertionsOnly) + : APIEntryShimWithoutLock(globalData, registerThread, RefGlobalData) + { + init(); + } + + ~APIEntryShim() { + m_globalData->timeoutChecker.stop(); + m_globalData->apiLock().unlock(); } private: - JSLock m_lock; + void init() + { + m_globalData->apiLock().lock(); + m_globalData->timeoutChecker.start(); + } }; class APICallbackShim { @@ -90,7 +114,6 @@ public: ~APICallbackShim() { - m_globalData->heap.activityCallback()->synchronize(); wtfThreadData().setCurrentIdentifierTable(m_globalData->identifierTable); } diff --git a/API/JSBase.cpp b/API/JSBase.cpp index c5f1b15..c0fe6cc 100644 --- a/API/JSBase.cpp +++ b/API/JSBase.cpp @@ -29,7 +29,6 @@ #include "APICast.h" #include "APIShims.h" -#include "Completion.h" #include "OpaqueJSString.h" #include "SourceCode.h" #include @@ -51,18 +50,20 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th // evaluate sets "this" to the global object if it is NULL JSGlobalObject* globalObject = exec->dynamicGlobalObject(); - SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), startingLineNumber); - Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), source, jsThisObject); + SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first())); - if (completion.complType() == Throw) { + JSValue evaluationException; + JSValue returnValue = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), source, jsThisObject, &evaluationException); + + if (evaluationException) { if (exception) - *exception = toRef(exec, completion.value()); + *exception = toRef(exec, evaluationException); return 0; } - if (completion.value()) - return toRef(exec, completion.value()); - + if (returnValue) + return toRef(exec, returnValue); + // happens, for example, when the only statement is an empty (';') statement return toRef(exec, jsUndefined()); } @@ -72,14 +73,17 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); - SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), startingLineNumber); - Completion completion = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source); - if (completion.complType() == Throw) { + SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first())); + + JSValue syntaxException; + bool isValidSyntax = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source, &syntaxException); + + if (!isValidSyntax) { if (exception) - *exception = toRef(exec, completion.value()); + *exception = toRef(exec, syntaxException); return false; } - + return true; } @@ -96,13 +100,7 @@ void JSGarbageCollect(JSContextRef ctx) ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec, false); - JSGlobalData& globalData = exec->globalData(); - if (!globalData.heap.isBusy()) - globalData.heap.collectAllGarbage(); - - // FIXME: Perhaps we should trigger a second mark and sweep - // once the garbage collector is done if this is called when - // the collector is busy. + exec->globalData().heap.reportAbandonedObjectGraph(); } void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) @@ -111,3 +109,8 @@ void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) APIEntryShim entryShim(exec); exec->globalData().heap.reportExtraMemoryCost(size); } + +void JSDisableGCTimer(void) +{ + GCActivityCallback::s_shouldCreateGCTimer = false; +} diff --git a/API/JSBasePrivate.h b/API/JSBasePrivate.h index befa316..3d6be0c 100644 --- a/API/JSBasePrivate.h +++ b/API/JSBasePrivate.h @@ -45,6 +45,9 @@ region. */ JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) AVAILABLE_IN_WEBKIT_VERSION_4_0; +/* Please don't call this. Please. */ +JS_EXPORT void JSDisableGCTimer(void); + #ifdef __cplusplus } #endif diff --git a/API/JSCallbackConstructor.cpp b/API/JSCallbackConstructor.cpp index fa9d216..c8b4c06 100644 --- a/API/JSCallbackConstructor.cpp +++ b/API/JSCallbackConstructor.cpp @@ -36,13 +36,18 @@ namespace JSC { -const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &JSObjectWithGlobalObject::s_info, 0, 0 }; +const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) }; JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Structure* structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback) - : JSObjectWithGlobalObject(globalObject, structure) + : JSNonFinalObject(globalObject->globalData(), structure) , m_class(jsClass) , m_callback(callback) { +} + +void JSCallbackConstructor::finishCreation(JSGlobalObject* globalObject, JSClassRef jsClass) +{ + Base::finishCreation(globalObject->globalData()); ASSERT(inherits(&s_info)); if (m_class) JSClassRetain(jsClass); @@ -54,13 +59,18 @@ JSCallbackConstructor::~JSCallbackConstructor() JSClassRelease(m_class); } +void JSCallbackConstructor::destroy(JSCell* cell) +{ + jsCast(cell)->JSCallbackConstructor::~JSCallbackConstructor(); +} + static EncodedJSValue JSC_HOST_CALL constructJSCallback(ExecState* exec) { JSObject* constructor = exec->callee(); JSContextRef ctx = toRef(exec); JSObjectRef constructorRef = toRef(constructor); - JSObjectCallAsConstructorCallback callback = static_cast(constructor)->callback(); + JSObjectCallAsConstructorCallback callback = jsCast(constructor)->callback(); if (callback) { int argumentCount = static_cast(exec->argumentCount()); Vector arguments(argumentCount); @@ -75,13 +85,16 @@ static EncodedJSValue JSC_HOST_CALL constructJSCallback(ExecState* exec) } if (exception) throwError(exec, toJS(exec, exception)); + // result must be a valid JSValue. + if (!result) + return throwVMTypeError(exec); return JSValue::encode(toJS(result)); } - return JSValue::encode(toJS(JSObjectMake(ctx, static_cast(constructor)->classRef(), 0))); + return JSValue::encode(toJS(JSObjectMake(ctx, jsCast(constructor)->classRef(), 0))); } -ConstructType JSCallbackConstructor::getConstructData(ConstructData& constructData) +ConstructType JSCallbackConstructor::getConstructData(JSCell*, ConstructData& constructData) { constructData.native.function = constructJSCallback; return ConstructTypeHost; diff --git a/API/JSCallbackConstructor.h b/API/JSCallbackConstructor.h index 64b237d..25fde13 100644 --- a/API/JSCallbackConstructor.h +++ b/API/JSCallbackConstructor.h @@ -27,28 +27,39 @@ #define JSCallbackConstructor_h #include "JSObjectRef.h" -#include +#include namespace JSC { -class JSCallbackConstructor : public JSObjectWithGlobalObject { +class JSCallbackConstructor : public JSNonFinalObject { public: - JSCallbackConstructor(JSGlobalObject*, Structure*, JSClassRef, JSObjectCallAsConstructorCallback); - virtual ~JSCallbackConstructor(); + typedef JSNonFinalObject Base; + + static JSCallbackConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, JSObjectCallAsConstructorCallback callback) + { + JSCallbackConstructor* constructor = new (NotNull, allocateCell(*exec->heap())) JSCallbackConstructor(globalObject, structure, classRef, callback); + constructor->finishCreation(globalObject, classRef); + return constructor; + } + + ~JSCallbackConstructor(); + static void destroy(JSCell*); JSClassRef classRef() const { return m_class; } JSObjectCallAsConstructorCallback callback() const { return m_callback; } static const ClassInfo s_info; - static Structure* createStructure(JSGlobalData& globalData, JSValue proto) + static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { - return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); + return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info); } protected: + JSCallbackConstructor(JSGlobalObject*, Structure*, JSClassRef, JSObjectCallAsConstructorCallback); + void finishCreation(JSGlobalObject*, JSClassRef); static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags; private: - virtual ConstructType getConstructData(ConstructData&); + static ConstructType getConstructData(JSCell*, ConstructData&); JSClassRef m_class; JSObjectCallAsConstructorCallback m_callback; diff --git a/API/JSCallbackFunction.cpp b/API/JSCallbackFunction.cpp index 28b3419..d287ab7 100644 --- a/API/JSCallbackFunction.cpp +++ b/API/JSCallbackFunction.cpp @@ -39,13 +39,19 @@ namespace JSC { ASSERT_CLASS_FITS_IN_CELL(JSCallbackFunction); +ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSCallbackFunction); -const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, 0 }; +const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackFunction) }; -JSCallbackFunction::JSCallbackFunction(ExecState* exec, JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, const Identifier& name) - : InternalFunction(&exec->globalData(), globalObject, globalObject->callbackFunctionStructure(), name) +JSCallbackFunction::JSCallbackFunction(JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback) + : InternalFunction(globalObject, globalObject->callbackFunctionStructure()) , m_callback(callback) { +} + +void JSCallbackFunction::finishCreation(JSGlobalData& globalData, const Identifier& name) +{ + Base::finishCreation(globalData, name); ASSERT(inherits(&s_info)); } @@ -64,15 +70,19 @@ EncodedJSValue JSCallbackFunction::call(ExecState* exec) JSValueRef result; { APICallbackShim callbackShim(exec); - result = static_cast(toJS(functionRef))->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception); + result = jsCast(toJS(functionRef))->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception); } if (exception) throwError(exec, toJS(exec, exception)); + // result must be a valid JSValue. + if (!result) + return JSValue::encode(jsUndefined()); + return JSValue::encode(toJS(exec, result)); } -CallType JSCallbackFunction::getCallData(CallData& callData) +CallType JSCallbackFunction::getCallData(JSCell*, CallData& callData) { callData.native.function = call; return CallTypeHost; diff --git a/API/JSCallbackFunction.h b/API/JSCallbackFunction.h index 55c9ed4..fec4136 100644 --- a/API/JSCallbackFunction.h +++ b/API/JSCallbackFunction.h @@ -32,20 +32,31 @@ namespace JSC { class JSCallbackFunction : public InternalFunction { +protected: + JSCallbackFunction(JSGlobalObject*, JSObjectCallAsFunctionCallback); + void finishCreation(JSGlobalData&, const Identifier& name); + public: - JSCallbackFunction(ExecState*, JSGlobalObject*, JSObjectCallAsFunctionCallback, const Identifier& name); + typedef InternalFunction Base; + + static JSCallbackFunction* create(ExecState* exec, JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, const Identifier& name) + { + JSCallbackFunction* function = new (NotNull, allocateCell(*exec->heap())) JSCallbackFunction(globalObject, callback); + function->finishCreation(exec->globalData(), name); + return function; + } static const ClassInfo s_info; // InternalFunction mish-mashes constructor and function behavior -- we should // refactor the code so this override isn't necessary - static Structure* createStructure(JSGlobalData& globalData, JSValue proto) + static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { - return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info); + return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info); } private: - virtual CallType getCallData(CallData&); + static CallType getCallData(JSCell*, CallData&); static EncodedJSValue JSC_HOST_CALL call(ExecState*); diff --git a/API/JSCallbackObject.cpp b/API/JSCallbackObject.cpp index 6a7462a..68c2682 100644 --- a/API/JSCallbackObject.cpp +++ b/API/JSCallbackObject.cpp @@ -32,12 +32,30 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject); +ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject); ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject); // Define the two types of JSCallbackObjects we support. -template <> const ClassInfo JSCallbackObject::s_info = { "CallbackObject", &JSObjectWithGlobalObject::s_info, 0, 0 }; -template <> const ClassInfo JSCallbackObject::s_info = { "CallbackGlobalObject", &JSGlobalObject::s_info, 0, 0 }; +template <> const ClassInfo JSCallbackObject::s_info = { "CallbackObject", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; +template <> const ClassInfo JSCallbackObject::s_info = { "CallbackGlobalObject", &JSGlobalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; + +template <> +Structure* JSCallbackObject::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) +{ + return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info); +} + +template <> +Structure* JSCallbackObject::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) +{ + return Structure::create(globalData, globalObject, proto, TypeInfo(GlobalObjectType, StructureFlags), &s_info); +} + +template +void JSCallbackObject::destroy(JSCell* cell) +{ + jsCast(cell)->JSCallbackObject::~JSCallbackObject(); +} void JSCallbackObjectData::finalize(Handle handle, void* context) { @@ -47,8 +65,7 @@ void JSCallbackObjectData::finalize(Handle handle, void* context) for (; jsClass; jsClass = jsClass->parentClass) if (JSObjectFinalizeCallback finalize = jsClass->finalize) finalize(thisRef); - HandleSlot slot = handle.slot(); - HandleHeap::heapFor(slot)->deallocate(slot); + WeakSet::deallocate(WeakImpl::asWeakImpl(handle.slot())); } } // namespace JSC diff --git a/API/JSCallbackObject.h b/API/JSCallbackObject.h index 2b322e7..9aca0c7 100644 --- a/API/JSCallbackObject.h +++ b/API/JSCallbackObject.h @@ -89,7 +89,7 @@ struct JSCallbackObjectData : WeakHandleOwner { void setPrivateProperty(JSGlobalData& globalData, JSCell* owner, const Identifier& propertyName, JSValue value) { WriteBarrier empty; - m_propertyMap.add(propertyName.impl(), empty).first->second.set(globalData, owner, value); + m_propertyMap.add(propertyName.impl(), empty).iterator->second.set(globalData, owner, value); } void deletePrivateProperty(const Identifier& propertyName) @@ -114,12 +114,32 @@ struct JSCallbackObjectData : WeakHandleOwner { }; -template -class JSCallbackObject : public Base { -public: - JSCallbackObject(ExecState*, JSGlobalObject*, Structure*, JSClassRef, void* data); +template +class JSCallbackObject : public Parent { +protected: + JSCallbackObject(ExecState*, Structure*, JSClassRef, void* data); JSCallbackObject(JSGlobalData&, JSClassRef, Structure*); + void finishCreation(ExecState*); + void finishCreation(JSGlobalData&); + +public: + typedef Parent Base; + + static JSCallbackObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, void* data) + { + ASSERT_UNUSED(globalObject, !structure->globalObject() || structure->globalObject() == globalObject); + JSCallbackObject* callbackObject = new (NotNull, allocateCell(*exec->heap())) JSCallbackObject(exec, structure, classRef, data); + callbackObject->finishCreation(exec); + return callbackObject; + } + static JSCallbackObject* create(JSGlobalData& globalData, JSClassRef classRef, Structure* structure) + { + JSCallbackObject* callbackObject = new (NotNull, allocateCell(globalData.heap)) JSCallbackObject(globalData, classRef, structure); + callbackObject->finishCreation(globalData); + return callbackObject; + } + void setPrivate(void* data); void* getPrivate(); @@ -128,10 +148,7 @@ public: JSClassRef classRef() const { return m_callbackObjectData->jsClass; } bool inherits(JSClassRef) const; - static Structure* createStructure(JSGlobalData& globalData, JSValue proto) - { - return Structure::create(globalData, proto, TypeInfo(ObjectType, StructureFlags), Base::AnonymousSlotCount, &s_info); - } + static Structure* createStructure(JSGlobalData&, JSGlobalObject*, JSValue); JSValue getPrivateProperty(const Identifier& propertyName) const { @@ -148,34 +165,41 @@ public: m_callbackObjectData->deletePrivateProperty(propertyName); } + using Parent::methodTable; + protected: - static const unsigned StructureFlags = ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags; + static const unsigned StructureFlags = ProhibitsPropertyCaching | OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | Parent::StructureFlags; private: - virtual UString className() const; + static UString className(const JSObject*); - virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&); - virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&); - - virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&); + static void destroy(JSCell*); + + static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType); - virtual bool deleteProperty(ExecState*, const Identifier&); - virtual bool deleteProperty(ExecState*, unsigned); + static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&); + static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&); + + static void put(JSCell*, ExecState*, const Identifier&, JSValue, PutPropertySlot&); - virtual bool hasInstance(ExecState* exec, JSValue value, JSValue proto); + static bool deleteProperty(JSCell*, ExecState*, const Identifier&); + static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned); - virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties); + static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue proto); - virtual double toNumber(ExecState*) const; - virtual UString toString(ExecState*) const; + static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); - virtual ConstructType getConstructData(ConstructData&); - virtual CallType getCallData(CallData&); + static ConstructType getConstructData(JSCell*, ConstructData&); + static CallType getCallData(JSCell*, CallData&); - virtual void visitChildren(SlotVisitor& visitor) + static void visitChildren(JSCell* cell, SlotVisitor& visitor) { - Base::visitChildren(visitor); - m_callbackObjectData->visitChildren(visitor); + JSCallbackObject* thisObject = jsCast(cell); + ASSERT_GC_OBJECT_INHERITS((static_cast(thisObject)), &JSCallbackObject::s_info); + COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); + ASSERT(thisObject->Parent::structure()->typeInfo().overridesVisitChildren()); + Parent::visitChildren(thisObject, visitor); + thisObject->m_callbackObjectData->visitChildren(visitor); } void init(ExecState*); diff --git a/API/JSCallbackObjectFunctions.h b/API/JSCallbackObjectFunctions.h index cc8f3a8..b909dde 100644 --- a/API/JSCallbackObjectFunctions.h +++ b/API/JSCallbackObjectFunctions.h @@ -42,36 +42,49 @@ namespace JSC { -template -inline JSCallbackObject* JSCallbackObject::asCallbackObject(JSValue value) +template +inline JSCallbackObject* JSCallbackObject::asCallbackObject(JSValue value) { ASSERT(asObject(value)->inherits(&s_info)); - return static_cast(asObject(value)); + return jsCast(asObject(value)); } -template -JSCallbackObject::JSCallbackObject(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef jsClass, void* data) - : Base(globalObject, structure) +template +JSCallbackObject::JSCallbackObject(ExecState* exec, Structure* structure, JSClassRef jsClass, void* data) + : Parent(exec->globalData(), structure) , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(data, jsClass))) { - ASSERT(Base::inherits(&s_info)); - init(exec); } // Global object constructor. // FIXME: Move this into a separate JSGlobalCallbackObject class derived from this one. -template -JSCallbackObject::JSCallbackObject(JSGlobalData& globalData, JSClassRef jsClass, Structure* structure) - : Base(globalData, structure) +template +JSCallbackObject::JSCallbackObject(JSGlobalData& globalData, JSClassRef jsClass, Structure* structure) + : Parent(globalData, structure) , m_callbackObjectData(adoptPtr(new JSCallbackObjectData(0, jsClass))) { - ASSERT(Base::inherits(&s_info)); - ASSERT(Base::isGlobalObject()); - init(static_cast(this)->globalExec()); } -template -void JSCallbackObject::init(ExecState* exec) +template +void JSCallbackObject::finishCreation(ExecState* exec) +{ + Base::finishCreation(exec->globalData()); + ASSERT(Parent::inherits(&s_info)); + init(exec); +} + +// This is just for Global object, so we can assume that Base::finishCreation is JSGlobalObject::finishCreation. +template +void JSCallbackObject::finishCreation(JSGlobalData& globalData) +{ + ASSERT(Parent::inherits(&s_info)); + ASSERT(Parent::isGlobalObject()); + Base::finishCreation(globalData); + init(jsCast(this)->globalExec()); +} + +template +void JSCallbackObject::init(ExecState* exec) { ASSERT(exec); @@ -89,42 +102,41 @@ void JSCallbackObject::init(ExecState* exec) initialize(toRef(exec), toRef(this)); } - bool needsFinalizer = false; - for (JSClassRef jsClassPtr = classRef(); jsClassPtr && !needsFinalizer; jsClassPtr = jsClassPtr->parentClass) - needsFinalizer = jsClassPtr->finalize; - if (needsFinalizer) { - HandleSlot slot = exec->globalData().allocateGlobalHandle(); - HandleHeap::heapFor(slot)->makeWeak(slot, m_callbackObjectData.get(), classRef()); - HandleHeap::heapFor(slot)->writeBarrier(slot, this); - *slot = this; + for (JSClassRef jsClassPtr = classRef(); jsClassPtr; jsClassPtr = jsClassPtr->parentClass) { + if (jsClassPtr->finalize) { + WeakSet::allocate(this, m_callbackObjectData.get(), classRef()); + break; + } } } -template -UString JSCallbackObject::className() const +template +UString JSCallbackObject::className(const JSObject* object) { - UString thisClassName = classRef()->className(); + const JSCallbackObject* thisObject = jsCast(object); + UString thisClassName = thisObject->classRef()->className(); if (!thisClassName.isEmpty()) return thisClassName; - return Base::className(); + return Parent::className(object); } -template -bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) +template +bool JSCallbackObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { + JSCallbackObject* thisObject = jsCast(cell); JSContextRef ctx = toRef(exec); - JSObjectRef thisRef = toRef(this); + JSObjectRef thisRef = toRef(thisObject); RefPtr propertyNameRef; - for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { + for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) { // optional optimization to bypass getProperty in cases when we only need to know if the property exists if (JSObjectHasPropertyCallback hasProperty = jsClass->hasProperty) { if (!propertyNameRef) propertyNameRef = OpaqueJSString::create(propertyName.ustring()); APICallbackShim callbackShim(exec); if (hasProperty(ctx, thisRef, propertyNameRef.get())) { - slot.setCustom(this, callbackGetter); + slot.setCustom(thisObject, callbackGetter); return true; } } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) { @@ -149,7 +161,7 @@ bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, const Identifie if (OpaqueJSClassStaticValuesTable* staticValues = jsClass->staticValues(exec)) { if (staticValues->contains(propertyName.impl())) { - JSValue value = getStaticValue(exec, propertyName); + JSValue value = thisObject->getStaticValue(exec, propertyName); if (value) { slot.setValue(value); return true; @@ -159,20 +171,45 @@ bool JSCallbackObject::getOwnPropertySlot(ExecState* exec, const Identifie if (OpaqueJSClassStaticFunctionsTable* staticFunctions = jsClass->staticFunctions(exec)) { if (staticFunctions->contains(propertyName.impl())) { - slot.setCustom(this, staticFunctionGetter); + slot.setCustom(thisObject, staticFunctionGetter); return true; } } } - return Base::getOwnPropertySlot(exec, propertyName, slot); + return Parent::getOwnPropertySlot(thisObject, exec, propertyName, slot); +} + +template +JSValue JSCallbackObject::defaultValue(const JSObject* object, ExecState* exec, PreferredPrimitiveType hint) +{ + const JSCallbackObject* thisObject = jsCast(object); + JSContextRef ctx = toRef(exec); + JSObjectRef thisRef = toRef(thisObject); + ::JSType jsHint = hint == PreferString ? kJSTypeString : kJSTypeNumber; + + for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) { + if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) { + JSValueRef exception = 0; + JSValueRef result = convertToType(ctx, thisRef, jsHint, &exception); + if (exception) { + throwError(exec, toJS(exec, exception)); + return jsUndefined(); + } + if (result) + return toJS(exec, result); + } + } + + return Parent::defaultValue(object, exec, hint); } -template -bool JSCallbackObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) +template +bool JSCallbackObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { + JSCallbackObject* thisObject = jsCast(object); PropertySlot slot; - if (getOwnPropertySlot(exec, propertyName, slot)) { + if (thisObject->methodTable()->getOwnPropertySlot(thisObject, 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()) @@ -184,18 +221,19 @@ bool JSCallbackObject::getOwnPropertyDescriptor(ExecState* exec, const Ide return true; } - return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); + return Parent::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); } -template -void JSCallbackObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) +template +void JSCallbackObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { + JSCallbackObject* thisObject = jsCast(cell); JSContextRef ctx = toRef(exec); - JSObjectRef thisRef = toRef(this); + JSObjectRef thisRef = toRef(thisObject); RefPtr propertyNameRef; JSValueRef valueRef = toRef(exec, value); - for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { + for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) { if (!propertyNameRef) propertyNameRef = OpaqueJSString::create(propertyName.ustring()); @@ -236,23 +274,24 @@ void JSCallbackObject::put(ExecState* exec, const Identifier& propertyName if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) { if (entry->attributes & kJSPropertyAttributeReadOnly) return; - JSCallbackObject::putDirect(exec->globalData(), propertyName, value); // put as override property + thisObject->JSCallbackObject::putDirect(exec->globalData(), propertyName, value); // put as override property return; } } } - return Base::put(exec, propertyName, value, slot); + return Parent::put(thisObject, exec, propertyName, value, slot); } -template -bool JSCallbackObject::deleteProperty(ExecState* exec, const Identifier& propertyName) +template +bool JSCallbackObject::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName) { + JSCallbackObject* thisObject = jsCast(cell); JSContextRef ctx = toRef(exec); - JSObjectRef thisRef = toRef(this); + JSObjectRef thisRef = toRef(thisObject); RefPtr propertyNameRef; - for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { + for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) { if (!propertyNameRef) propertyNameRef = OpaqueJSString::create(propertyName.ustring()); @@ -285,19 +324,21 @@ bool JSCallbackObject::deleteProperty(ExecState* exec, const Identifier& p } } - return Base::deleteProperty(exec, propertyName); + return Parent::deleteProperty(thisObject, exec, propertyName); } -template -bool JSCallbackObject::deleteProperty(ExecState* exec, unsigned propertyName) +template +bool JSCallbackObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName) { - return deleteProperty(exec, Identifier::from(exec, propertyName)); + JSCallbackObject* thisObject = jsCast(cell); + return thisObject->methodTable()->deleteProperty(thisObject, exec, Identifier::from(exec, propertyName)); } -template -ConstructType JSCallbackObject::getConstructData(ConstructData& constructData) +template +ConstructType JSCallbackObject::getConstructData(JSCell* cell, ConstructData& constructData) { - for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { + JSCallbackObject* thisObject = jsCast(cell); + for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) { if (jsClass->callAsConstructor) { constructData.native.function = construct; return ConstructTypeHost; @@ -306,14 +347,14 @@ ConstructType JSCallbackObject::getConstructData(ConstructData& constructD return ConstructTypeNone; } -template -EncodedJSValue JSCallbackObject::construct(ExecState* exec) +template +EncodedJSValue JSCallbackObject::construct(ExecState* exec) { JSObject* constructor = exec->callee(); JSContextRef execRef = toRef(exec); JSObjectRef constructorRef = toRef(constructor); - for (JSClassRef jsClass = static_cast*>(constructor)->classRef(); jsClass; jsClass = jsClass->parentClass) { + for (JSClassRef jsClass = jsCast*>(constructor)->classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectCallAsConstructorCallback callAsConstructor = jsClass->callAsConstructor) { int argumentCount = static_cast(exec->argumentCount()); Vector arguments(argumentCount); @@ -335,13 +376,14 @@ EncodedJSValue JSCallbackObject::construct(ExecState* exec) return JSValue::encode(JSValue()); } -template -bool JSCallbackObject::hasInstance(ExecState* exec, JSValue value, JSValue) +template +bool JSCallbackObject::hasInstance(JSObject* object, ExecState* exec, JSValue value, JSValue) { + JSCallbackObject* thisObject = jsCast(object); JSContextRef execRef = toRef(exec); - JSObjectRef thisRef = toRef(this); + JSObjectRef thisRef = toRef(thisObject); - for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { + for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) { JSValueRef valueRef = toRef(exec, value); JSValueRef exception = 0; @@ -358,10 +400,11 @@ bool JSCallbackObject::hasInstance(ExecState* exec, JSValue value, JSValue return false; } -template -CallType JSCallbackObject::getCallData(CallData& callData) +template +CallType JSCallbackObject::getCallData(JSCell* cell, CallData& callData) { - for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { + JSCallbackObject* thisObject = jsCast(cell); + for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) { if (jsClass->callAsFunction) { callData.native.function = call; return CallTypeHost; @@ -370,14 +413,14 @@ CallType JSCallbackObject::getCallData(CallData& callData) return CallTypeNone; } -template -EncodedJSValue JSCallbackObject::call(ExecState* exec) +template +EncodedJSValue JSCallbackObject::call(ExecState* exec) { JSContextRef execRef = toRef(exec); JSObjectRef functionRef = toRef(exec->callee()); JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec)); - for (JSClassRef jsClass = static_cast*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) { + for (JSClassRef jsClass = jsCast*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) { int argumentCount = static_cast(exec->argumentCount()); Vector arguments(argumentCount); @@ -399,13 +442,14 @@ EncodedJSValue JSCallbackObject::call(ExecState* exec) return JSValue::encode(JSValue()); } -template -void JSCallbackObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) +template +void JSCallbackObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { + JSCallbackObject* thisObject = jsCast(object); JSContextRef execRef = toRef(exec); - JSObjectRef thisRef = toRef(this); + JSObjectRef thisRef = toRef(thisObject); - for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) { + for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) { if (JSObjectGetPropertyNamesCallback getPropertyNames = jsClass->getPropertyNames) { APICallbackShim callbackShim(exec); getPropertyNames(execRef, thisRef, toRef(&propertyNames)); @@ -416,7 +460,7 @@ void JSCallbackObject::getOwnPropertyNames(ExecState* exec, PropertyNameAr iterator end = staticValues->end(); for (iterator it = staticValues->begin(); it != end; ++it) { StringImpl* name = it->first.get(); - StaticValueEntry* entry = it->second; + StaticValueEntry* entry = it->second.get(); if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))) propertyNames.add(Identifier(exec, name)); } @@ -427,87 +471,30 @@ void JSCallbackObject::getOwnPropertyNames(ExecState* exec, PropertyNameAr iterator end = staticFunctions->end(); for (iterator it = staticFunctions->begin(); it != end; ++it) { StringImpl* name = it->first.get(); - StaticFunctionEntry* entry = it->second; + StaticFunctionEntry* entry = it->second.get(); if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)) propertyNames.add(Identifier(exec, name)); } } } - Base::getOwnPropertyNames(exec, propertyNames, mode); -} - -template -double JSCallbackObject::toNumber(ExecState* exec) const -{ - // We need this check to guard against the case where this object is rhs of - // a binary expression where lhs threw an exception in its conversion to - // primitive - if (exec->hadException()) - return NaN; - JSContextRef ctx = toRef(exec); - JSObjectRef thisRef = toRef(this); - - for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) - if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) { - JSValueRef exception = 0; - JSValueRef value; - { - APICallbackShim callbackShim(exec); - value = convertToType(ctx, thisRef, kJSTypeNumber, &exception); - } - if (exception) { - throwError(exec, toJS(exec, exception)); - return 0; - } - - double dValue; - if (value) - return toJS(exec, value).getNumber(dValue) ? dValue : NaN; - } - - return Base::toNumber(exec); -} - -template -UString JSCallbackObject::toString(ExecState* exec) const -{ - JSContextRef ctx = toRef(exec); - JSObjectRef thisRef = toRef(this); - - for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) - if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) { - JSValueRef exception = 0; - JSValueRef value; - { - APICallbackShim callbackShim(exec); - value = convertToType(ctx, thisRef, kJSTypeString, &exception); - } - if (exception) { - throwError(exec, toJS(exec, exception)); - return ""; - } - if (value) - return toJS(exec, value).getString(exec); - } - - return Base::toString(exec); + Parent::getOwnPropertyNames(thisObject, exec, propertyNames, mode); } -template -void JSCallbackObject::setPrivate(void* data) +template +void JSCallbackObject::setPrivate(void* data) { m_callbackObjectData->privateData = data; } -template -void* JSCallbackObject::getPrivate() +template +void* JSCallbackObject::getPrivate() { return m_callbackObjectData->privateData; } -template -bool JSCallbackObject::inherits(JSClassRef c) const +template +bool JSCallbackObject::inherits(JSClassRef c) const { for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) if (jsClass == c) @@ -516,8 +503,8 @@ bool JSCallbackObject::inherits(JSClassRef c) const return false; } -template -JSValue JSCallbackObject::getStaticValue(ExecState* exec, const Identifier& propertyName) +template +JSValue JSCallbackObject::getStaticValue(ExecState* exec, const Identifier& propertyName) { JSObjectRef thisRef = toRef(this); RefPtr propertyNameRef; @@ -545,14 +532,14 @@ JSValue JSCallbackObject::getStaticValue(ExecState* exec, const Identifier return JSValue(); } -template -JSValue JSCallbackObject::staticFunctionGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) +template +JSValue JSCallbackObject::staticFunctionGetter(ExecState* exec, JSValue slotParent, const Identifier& propertyName) { - JSCallbackObject* thisObj = asCallbackObject(slotBase); + JSCallbackObject* thisObj = asCallbackObject(slotParent); // Check for cached or override property. PropertySlot slot2(thisObj); - if (thisObj->Base::getOwnPropertySlot(exec, propertyName, slot2)) + if (Parent::getOwnPropertySlot(thisObj, exec, propertyName, slot2)) return slot2.getValue(exec, propertyName); for (JSClassRef jsClass = thisObj->classRef(); jsClass; jsClass = jsClass->parentClass) { @@ -560,7 +547,7 @@ JSValue JSCallbackObject::staticFunctionGetter(ExecState* exec, JSValue sl if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.impl())) { if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) { - JSObject* o = new (exec) JSCallbackFunction(exec, asGlobalObject(thisObj->getAnonymousValue(0)), callAsFunction, propertyName); + JSObject* o = JSCallbackFunction::create(exec, thisObj->globalObject(), callAsFunction, propertyName); thisObj->putDirect(exec->globalData(), propertyName, o, entry->attributes); return o; } @@ -571,10 +558,10 @@ JSValue JSCallbackObject::staticFunctionGetter(ExecState* exec, JSValue sl return throwError(exec, createReferenceError(exec, "Static function property defined with NULL callAsFunction callback.")); } -template -JSValue JSCallbackObject::callbackGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName) +template +JSValue JSCallbackObject::callbackGetter(ExecState* exec, JSValue slotParent, const Identifier& propertyName) { - JSCallbackObject* thisObj = asCallbackObject(slotBase); + JSCallbackObject* thisObj = asCallbackObject(slotParent); JSObjectRef thisRef = toRef(thisObj); RefPtr propertyNameRef; diff --git a/API/JSClassRef.cpp b/API/JSClassRef.cpp index 08dc721..08fa5c5 100644 --- a/API/JSClassRef.cpp +++ b/API/JSClassRef.cpp @@ -71,39 +71,25 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* , hasInstance(definition->hasInstance) , convertToType(definition->convertToType) , m_className(tryCreateStringFromUTF8(definition->className)) - , m_staticValues(0) - , m_staticFunctions(0) { initializeThreading(); if (const JSStaticValue* staticValue = definition->staticValues) { - m_staticValues = new OpaqueJSClassStaticValuesTable(); + m_staticValues = adoptPtr(new OpaqueJSClassStaticValuesTable); while (staticValue->name) { UString valueName = tryCreateStringFromUTF8(staticValue->name); - if (!valueName.isNull()) { - // Use a local variable here to sidestep an RVCT compiler bug. - StaticValueEntry* entry = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes); - StringImpl* impl = valueName.impl(); - StaticValueEntry* existingEntry = m_staticValues->get(impl); - m_staticValues->set(impl, entry); - delete existingEntry; - } + if (!valueName.isNull()) + m_staticValues->set(valueName.impl(), adoptPtr(new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes))); ++staticValue; } } if (const JSStaticFunction* staticFunction = definition->staticFunctions) { - m_staticFunctions = new OpaqueJSClassStaticFunctionsTable(); + m_staticFunctions = adoptPtr(new OpaqueJSClassStaticFunctionsTable); while (staticFunction->name) { UString functionName = tryCreateStringFromUTF8(staticFunction->name); - if (!functionName.isNull()) { - // Use a local variable here to sidestep an RVCT compiler bug. - StaticFunctionEntry* entry = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes); - StringImpl* impl = functionName.impl(); - StaticFunctionEntry* existingEntry = m_staticFunctions->get(impl); - m_staticFunctions->set(impl, entry); - delete existingEntry; - } + if (!functionName.isNull()) + m_staticFunctions->set(functionName.impl(), adoptPtr(new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes))); ++staticFunction; } } @@ -117,23 +103,19 @@ OpaqueJSClass::~OpaqueJSClass() // The empty string is shared across threads & is an identifier, in all other cases we should have done a deep copy in className(), below. ASSERT(!m_className.length() || !m_className.impl()->isIdentifier()); +#ifndef NDEBUG if (m_staticValues) { OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end(); - for (OpaqueJSClassStaticValuesTable::const_iterator it = m_staticValues->begin(); it != end; ++it) { + for (OpaqueJSClassStaticValuesTable::const_iterator it = m_staticValues->begin(); it != end; ++it) ASSERT(!it->first->isIdentifier()); - delete it->second; - } - delete m_staticValues; } if (m_staticFunctions) { OpaqueJSClassStaticFunctionsTable::const_iterator end = m_staticFunctions->end(); - for (OpaqueJSClassStaticFunctionsTable::const_iterator it = m_staticFunctions->begin(); it != end; ++it) { + for (OpaqueJSClassStaticFunctionsTable::const_iterator it = m_staticFunctions->begin(); it != end; ++it) ASSERT(!it->first->isIdentifier()); - delete it->second; - } - delete m_staticFunctions; } +#endif if (prototypeClass) JSClassRelease(prototypeClass); @@ -162,49 +144,29 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSC : m_class(jsClass) { if (jsClass->m_staticValues) { - staticValues = new OpaqueJSClassStaticValuesTable; + staticValues = adoptPtr(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->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(StringImpl::create(it->first->characters(), it->first->length()), entry); + staticValues->add(StringImpl::create(it->first->characters(), it->first->length()), adoptPtr(new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes))); } - } else - staticValues = 0; + } if (jsClass->m_staticFunctions) { - staticFunctions = new OpaqueJSClassStaticFunctionsTable; + staticFunctions = adoptPtr(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->isIdentifier()); - // Use a local variable here to sidestep an RVCT compiler bug. - StaticFunctionEntry* entry = new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes); - staticFunctions->add(StringImpl::create(it->first->characters(), it->first->length()), entry); + staticFunctions->add(StringImpl::create(it->first->characters(), it->first->length()), adoptPtr(new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes))); } - - } else - staticFunctions = 0; -} - -OpaqueJSClassContextData::~OpaqueJSClassContextData() -{ - if (staticValues) { - deleteAllValues(*staticValues); - delete staticValues; - } - - if (staticFunctions) { - deleteAllValues(*staticFunctions); - delete staticFunctions; } } OpaqueJSClassContextData& OpaqueJSClass::contextData(ExecState* exec) { - OpaqueJSClassContextData*& contextData = exec->globalData().opaqueJSClassData.add(this, 0).first->second; + OwnPtr& contextData = exec->globalData().opaqueJSClassData.add(this, nullptr).iterator->second; if (!contextData) - contextData = new OpaqueJSClassContextData(exec->globalData(), this); + contextData = adoptPtr(new OpaqueJSClassContextData(exec->globalData(), this)); return *contextData; } @@ -216,14 +178,12 @@ UString OpaqueJSClass::className() OpaqueJSClassStaticValuesTable* OpaqueJSClass::staticValues(JSC::ExecState* exec) { - OpaqueJSClassContextData& jsClassData = contextData(exec); - return jsClassData.staticValues; + return contextData(exec).staticValues.get(); } OpaqueJSClassStaticFunctionsTable* OpaqueJSClass::staticFunctions(JSC::ExecState* exec) { - OpaqueJSClassContextData& jsClassData = contextData(exec); - return jsClassData.staticFunctions; + return contextData(exec).staticFunctions.get(); } /*! @@ -243,7 +203,7 @@ JSObject* OpaqueJSClass::prototype(ExecState* exec) * | | | * DerivedClass | DerivedClassPrototype */ - + if (!prototypeClass) return 0; @@ -251,7 +211,7 @@ JSObject* OpaqueJSClass::prototype(ExecState* exec) if (!jsClassData.cachedPrototype) { // Recursive, but should be good enough for our purposes - jsClassData.cachedPrototype.set(exec->globalData(), new (exec) JSCallbackObject(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData), 0); // set jsClassData as the object's private data, so it can clear our reference on destruction + jsClassData.cachedPrototype = PassWeak(JSCallbackObject::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData), 0); // set jsClassData as the object's private data, so it can clear our reference on destruction if (parentClass) { if (JSObject* prototype = parentClass->prototype(exec)) jsClassData.cachedPrototype->setPrototype(exec->globalData(), prototype); diff --git a/API/JSClassRef.h b/API/JSClassRef.h index d346cc5..82c7ab3 100644 --- a/API/JSClassRef.h +++ b/API/JSClassRef.h @@ -59,8 +59,8 @@ public: JSPropertyAttributes attributes; }; -typedef HashMap, StaticValueEntry*> OpaqueJSClassStaticValuesTable; -typedef HashMap, StaticFunctionEntry*> OpaqueJSClassStaticFunctionsTable; +typedef HashMap, OwnPtr > OpaqueJSClassStaticValuesTable; +typedef HashMap, OwnPtr > OpaqueJSClassStaticFunctionsTable; struct OpaqueJSClass; @@ -70,7 +70,6 @@ struct OpaqueJSClassContextData { WTF_MAKE_NONCOPYABLE(OpaqueJSClassContextData); WTF_MAKE_FAST_ALLOCATED; public: OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSClass*); - ~OpaqueJSClassContextData(); // It is necessary to keep OpaqueJSClass alive because of the following rare scenario: // 1. A class is created and used, so its context data is stored in JSGlobalData hash map. @@ -80,8 +79,8 @@ public: // 4. When it is used, the old context data is found in JSGlobalData and used. RefPtr m_class; - OpaqueJSClassStaticValuesTable* staticValues; - OpaqueJSClassStaticFunctionsTable* staticFunctions; + OwnPtr staticValues; + OwnPtr staticFunctions; JSC::Weak cachedPrototype; }; @@ -121,8 +120,8 @@ private: // UStrings in these data members should not be put into any IdentifierTable. JSC::UString m_className; - OpaqueJSClassStaticValuesTable* m_staticValues; - OpaqueJSClassStaticFunctionsTable* m_staticFunctions; + OwnPtr m_staticValues; + OwnPtr m_staticFunctions; }; #endif // JSClassRef_h diff --git a/API/JSContextRef.cpp b/API/JSContextRef.cpp index 9c15b22..7a57287 100644 --- a/API/JSContextRef.cpp +++ b/API/JSContextRef.cpp @@ -38,7 +38,6 @@ #include "UStringBuilder.h" #include - #if OS(DARWIN) #include @@ -47,6 +46,11 @@ static const int32_t webkitFirstVersionWithConcurrentGlobalContexts = 0x2100500; using namespace JSC; +// From the API's perspective, a context group remains alive iff +// (a) it has been JSContextGroupRetained +// OR +// (b) one of its contexts has been JSContextRetained + JSContextGroupRef JSContextGroupCreate() { initializeThreading(); @@ -64,18 +68,16 @@ void JSContextGroupRelease(JSContextGroupRef group) toJS(group)->deref(); } +// From the API's perspective, a global context remains alive iff it has been JSGlobalContextRetained. + JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) { initializeThreading(); + #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. -#ifndef BUILDING_ON_LEOPARD + // If the application was linked before JSGlobalContextCreate was changed to use a unique JSGlobalData, + // we use a shared one for backwards compatibility. if (NSVersionOfLinkTimeLibrary("JavaScriptCore") <= webkitFirstVersionWithConcurrentGlobalContexts) { -#else - { -#endif - JSLock lock(LockForReal); return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass); } #endif // OS(DARWIN) @@ -87,21 +89,17 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass { initializeThreading(); - JSLock lock(LockForReal); RefPtr globalData = group ? PassRefPtr(toJS(group)) : JSGlobalData::createContextGroup(ThreadStackTypeSmall); APIEntryShim entryShim(globalData.get(), false); - -#if ENABLE(JSC_MULTIPLE_THREADS) globalData->makeUsableFromMultipleThreads(); -#endif if (!globalObjectClass) { - JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject(*globalData, JSGlobalObject::createStructure(*globalData, jsNull())); + JSGlobalObject* globalObject = JSGlobalObject::create(*globalData, JSGlobalObject::createStructure(*globalData, jsNull())); return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec())); } - JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject(*globalData, globalObjectClass, JSCallbackObject::createStructure(*globalData, jsNull())); + JSGlobalObject* globalObject = JSCallbackObject::create(*globalData, globalObjectClass, JSCallbackObject::createStructure(*globalData, 0, jsNull())); ExecState* exec = globalObject->globalExec(); JSValue prototype = globalObjectClass->prototype(exec); if (!prototype) @@ -123,38 +121,19 @@ JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx) void JSGlobalContextRelease(JSGlobalContextRef ctx) { + IdentifierTable* savedIdentifierTable; ExecState* exec = toJS(ctx); - JSLock lock(exec); + { + JSLockHolder lock(exec); - JSGlobalData& globalData = exec->globalData(); - JSGlobalObject* dgo = exec->dynamicGlobalObject(); - IdentifierTable* savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable); - - // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain(). - bool releasingContextGroup = globalData.refCount() == 2; - bool releasingGlobalObject = Heap::heap(dgo)->unprotect(dgo); - // If this is the last reference to a global data, it should also - // be the only remaining reference to the global object too! - ASSERT(!releasingContextGroup || releasingGlobalObject); - - // An API 'JSGlobalContextRef' retains two things - a global object and a - // global data (or context group, in API terminology). - // * If this is the last reference to any contexts in the given context group, - // call destroy on the heap (the global data is being freed). - // * If this was the last reference to the global object, then unprotecting - // it may release a lot of GC memory - tickle the activity callback to - // garbage collect soon. - // * If there are more references remaining the the global object, then do nothing - // (specifically that is more protects, which we assume come from other JSGlobalContextRefs). - if (releasingContextGroup) { - globalData.clearBuiltinStructures(); - globalData.heap.destroy(); - } else if (releasingGlobalObject) { - globalData.heap.activityCallback()->synchronize(); - (*globalData.heap.activityCallback())(); - } + JSGlobalData& globalData = exec->globalData(); + savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable); - globalData.deref(); + bool protectCountIsZero = Heap::heap(exec->dynamicGlobalObject())->unprotect(exec->dynamicGlobalObject()); + if (protectCountIsZero) + globalData.heap.reportAbandonedObjectGraph(); + globalData.deref(); + } wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable); } @@ -165,7 +144,7 @@ JSObjectRef JSContextGetGlobalObject(JSContextRef ctx) APIEntryShim entryShim(exec); // It is necessary to call toThisObject to get the wrapper object when used with WebCore. - return toRef(exec->lexicalGlobalObject()->toThisObject(exec)); + return toRef(exec->lexicalGlobalObject()->methodTable()->toThisObject(exec->lexicalGlobalObject(), exec)); } JSContextGroupRef JSContextGetGroup(JSContextRef ctx) @@ -185,7 +164,7 @@ JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx) JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) { ExecState* exec = toJS(ctx); - JSLock lock(exec); + JSLockHolder lock(exec); unsigned count = 0; UStringBuilder builder; @@ -212,7 +191,7 @@ JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize) exec->interpreter()->retrieveLastCaller(callFrame, signedLineNumber, sourceID, urlString, function); if (function) - functionName = asFunction(function)->name(exec); + functionName = jsCast(function)->name(exec); else { // Caller is unknown, but if frame is empty we should still add the frame, because // something called us, and gave us arguments. diff --git a/API/JSObjectRef.cpp b/API/JSObjectRef.cpp index 2df010a..e01214d 100644 --- a/API/JSObjectRef.cpp +++ b/API/JSObjectRef.cpp @@ -81,7 +81,7 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data) if (!jsClass) return toRef(constructEmptyObject(exec)); - JSCallbackObject* object = new (exec) JSCallbackObject(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), jsClass, data); + JSCallbackObject* object = JSCallbackObject::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), jsClass, data); if (JSObject* prototype = jsClass->prototype(exec)) object->setPrototype(exec->globalData(), prototype); @@ -95,7 +95,7 @@ JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous"); - return toRef(new (exec) JSCallbackFunction(exec, exec->lexicalGlobalObject(), callAsFunction, nameID)); + return toRef(JSCallbackFunction::create(exec, exec->lexicalGlobalObject(), callAsFunction, nameID)); } JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor) @@ -107,7 +107,7 @@ JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObje if (!jsPrototype) jsPrototype = exec->lexicalGlobalObject()->objectPrototype(); - JSCallbackConstructor* constructor = new (exec) JSCallbackConstructor(exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackConstructorStructure(), jsClass, callAsConstructor); + JSCallbackConstructor* constructor = JSCallbackConstructor::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackConstructorStructure(), jsClass, callAsConstructor); constructor->putDirect(exec->globalData(), exec->propertyNames().prototype, jsPrototype, DontEnum | DontDelete | ReadOnly); return toRef(constructor); } @@ -124,7 +124,7 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa args.append(jsString(exec, parameterNames[i]->ustring())); args.append(jsString(exec, body->ustring())); - JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL->ustring(), startingLineNumber); + JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL->ustring(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first())); if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); @@ -274,10 +274,10 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope JSValue jsValue = toJS(exec, value); if (attributes && !jsObject->hasProperty(exec, name)) - jsObject->putWithAttributes(exec, name, jsValue, attributes); + jsObject->methodTable()->putDirectVirtual(jsObject, exec, name, jsValue, attributes); else { PutPropertySlot slot; - jsObject->put(exec, name, jsValue, slot); + jsObject->methodTable()->put(jsObject, exec, name, jsValue, slot); } if (exec->hadException()) { @@ -312,7 +312,7 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p JSObject* jsObject = toJS(object); JSValue jsValue = toJS(exec, value); - jsObject->put(exec, propertyIndex, jsValue); + jsObject->methodTable()->putByIndex(jsObject, exec, propertyIndex, jsValue, false); if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); @@ -327,7 +327,7 @@ bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr JSObject* jsObject = toJS(object); - bool result = jsObject->deleteProperty(exec, propertyName->identifier(&exec->globalData())); + bool result = jsObject->methodTable()->deleteProperty(jsObject, exec, propertyName->identifier(&exec->globalData())); if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); @@ -341,9 +341,9 @@ void* JSObjectGetPrivate(JSObjectRef object) JSObject* jsObject = toJS(object); if (jsObject->inherits(&JSCallbackObject::s_info)) - return static_cast*>(jsObject)->getPrivate(); - if (jsObject->inherits(&JSCallbackObject::s_info)) - return static_cast*>(jsObject)->getPrivate(); + return jsCast*>(jsObject)->getPrivate(); + if (jsObject->inherits(&JSCallbackObject::s_info)) + return jsCast*>(jsObject)->getPrivate(); return 0; } @@ -353,11 +353,11 @@ bool JSObjectSetPrivate(JSObjectRef object, void* data) JSObject* jsObject = toJS(object); if (jsObject->inherits(&JSCallbackObject::s_info)) { - static_cast*>(jsObject)->setPrivate(data); + jsCast*>(jsObject)->setPrivate(data); return true; } - if (jsObject->inherits(&JSCallbackObject::s_info)) { - static_cast*>(jsObject)->setPrivate(data); + if (jsObject->inherits(&JSCallbackObject::s_info)) { + jsCast*>(jsObject)->setPrivate(data); return true; } @@ -372,9 +372,9 @@ JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSSt JSValue result; Identifier name(propertyName->identifier(&exec->globalData())); if (jsObject->inherits(&JSCallbackObject::s_info)) - result = static_cast*>(jsObject)->getPrivateProperty(name); - else if (jsObject->inherits(&JSCallbackObject::s_info)) - result = static_cast*>(jsObject)->getPrivateProperty(name); + result = jsCast*>(jsObject)->getPrivateProperty(name); + else if (jsObject->inherits(&JSCallbackObject::s_info)) + result = jsCast*>(jsObject)->getPrivateProperty(name); return toRef(exec, result); } @@ -386,11 +386,11 @@ bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRe JSValue jsValue = value ? toJS(exec, value) : JSValue(); Identifier name(propertyName->identifier(&exec->globalData())); if (jsObject->inherits(&JSCallbackObject::s_info)) { - static_cast*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue); + jsCast*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue); return true; } - if (jsObject->inherits(&JSCallbackObject::s_info)) { - static_cast*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue); + if (jsObject->inherits(&JSCallbackObject::s_info)) { + jsCast*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue); return true; } return false; @@ -403,11 +403,11 @@ bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStrin JSObject* jsObject = toJS(object); Identifier name(propertyName->identifier(&exec->globalData())); if (jsObject->inherits(&JSCallbackObject::s_info)) { - static_cast*>(jsObject)->deletePrivateProperty(name); + jsCast*>(jsObject)->deletePrivateProperty(name); return true; } - if (jsObject->inherits(&JSCallbackObject::s_info)) { - static_cast*>(jsObject)->deletePrivateProperty(name); + if (jsObject->inherits(&JSCallbackObject::s_info)) { + jsCast*>(jsObject)->deletePrivateProperty(name); return true; } return false; @@ -416,7 +416,8 @@ bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStrin bool JSObjectIsFunction(JSContextRef, JSObjectRef object) { CallData callData; - return toJS(object)->getCallData(callData) != CallTypeNone; + JSCell* cell = toJS(object); + return cell->methodTable()->getCallData(cell, callData) != CallTypeNone; } JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) @@ -435,7 +436,7 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject argList.append(toJS(exec, arguments[i])); CallData callData; - CallType callType = jsObject->getCallData(callData); + CallType callType = jsObject->methodTable()->getCallData(jsObject, callData); if (callType == CallTypeNone) return 0; @@ -453,7 +454,7 @@ bool JSObjectIsConstructor(JSContextRef, JSObjectRef object) { JSObject* jsObject = toJS(object); ConstructData constructData; - return jsObject->getConstructData(constructData) != ConstructTypeNone; + return jsObject->methodTable()->getConstructData(jsObject, constructData) != ConstructTypeNone; } JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) @@ -464,7 +465,7 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size JSObject* jsObject = toJS(object); ConstructData constructData; - ConstructType constructType = jsObject->getConstructData(constructData); + ConstructType constructType = jsObject->methodTable()->getConstructData(jsObject, constructData); if (constructType == ConstructTypeNone) return 0; @@ -505,7 +506,7 @@ JSPropertyNameArrayRef JSObjectCopyPropertyNames(JSContextRef ctx, JSObjectRef o JSPropertyNameArrayRef propertyNames = new OpaqueJSPropertyNameArray(globalData); PropertyNameArray array(globalData); - jsObject->getPropertyNames(exec, array); + jsObject->methodTable()->getPropertyNames(jsObject, exec, array, ExcludeDontEnumProperties); size_t size = array.size(); propertyNames->array.reserveInitialCapacity(size); diff --git a/API/JSObjectRef.h b/API/JSObjectRef.h index 3e8b0eb..5014726 100644 --- a/API/JSObjectRef.h +++ b/API/JSObjectRef.h @@ -288,7 +288,7 @@ typedef JSValueRef @field attributes A logically ORed set of JSPropertyAttributes to give to the property. */ typedef struct { - const char* const name; + const char* name; JSObjectGetPropertyCallback getProperty; JSObjectSetPropertyCallback setProperty; JSPropertyAttributes attributes; @@ -302,7 +302,7 @@ typedef struct { @field attributes A logically ORed set of JSPropertyAttributes to give to the property. */ typedef struct { - const char* const name; + const char* name; JSObjectCallAsFunctionCallback callAsFunction; JSPropertyAttributes attributes; } JSStaticFunction; diff --git a/API/JSRetainPtr.h b/API/JSRetainPtr.h index 08ef57c..574f7aa 100644 --- a/API/JSRetainPtr.h +++ b/API/JSRetainPtr.h @@ -71,9 +71,6 @@ public: void swap(JSRetainPtr&); - // FIXME: Remove releaseRef once we change all callers to call leakRef instead. - T releaseRef() { return leakRef(); } - private: T m_ptr; }; diff --git a/API/JSStringRef.h b/API/JSStringRef.h index c5c1544..75d73c9 100644 --- a/API/JSStringRef.h +++ b/API/JSStringRef.h @@ -37,7 +37,7 @@ extern "C" { #endif -#if !defined(WIN32) && !defined(_WIN32) && !defined(__WINSCW__) \ +#if !defined(WIN32) && !defined(_WIN32) \ && !((defined(__CC_ARM) || defined(__ARMCC__)) && !defined(__linux__)) /* RVCT */ /*! @typedef JSChar diff --git a/API/JSValueRef.cpp b/API/JSValueRef.cpp index d1603e2..9b7268a 100644 --- a/API/JSValueRef.cpp +++ b/API/JSValueRef.cpp @@ -130,9 +130,9 @@ bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsCla if (JSObject* o = jsValue.getObject()) { if (o->inherits(&JSCallbackObject::s_info)) - return static_cast*>(o)->inherits(jsClass); - if (o->inherits(&JSCallbackObject::s_info)) - return static_cast*>(o)->inherits(jsClass); + return jsCast*>(o)->inherits(jsClass); + if (o->inherits(&JSCallbackObject::s_info)) + return jsCast*>(o)->inherits(jsClass); } return false; } @@ -175,7 +175,7 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject JSObject* jsConstructor = toJS(constructor); if (!jsConstructor->structure()->typeInfo().implementsHasInstance()) return false; - bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown + bool result = jsConstructor->methodTable()->hasInstance(jsConstructor, exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); @@ -217,7 +217,7 @@ JSValueRef JSValueMakeNumber(JSContextRef ctx, double value) // generated internally to JavaScriptCore naturally have that representation, // but an external NaN might not. if (isnan(value)) - value = NaN; + value = std::numeric_limits::quiet_NaN(); return toRef(exec, jsNumber(value)); } @@ -235,7 +235,11 @@ JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); UString str = string->ustring(); - LiteralParser parser(exec, str.characters(), str.length(), LiteralParser::StrictJSON); + if (str.is8Bit()) { + LiteralParser parser(exec, str.characters8(), str.length(), StrictJSON); + return toRef(exec, parser.tryLiteralParse()); + } + LiteralParser parser(exec, str.characters16(), str.length(), StrictJSON); return toRef(exec, parser.tryLiteralParse()); } @@ -277,7 +281,7 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception if (exception) *exception = toRef(exec, exec->exception()); exec->clearException(); - number = NaN; + number = std::numeric_limits::quiet_NaN(); } return number; } @@ -289,7 +293,7 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* JSValue jsValue = toJS(exec, value); - RefPtr stringRef(OpaqueJSString::create(jsValue.toString(exec))); + RefPtr stringRef(OpaqueJSString::create(jsValue.toString(exec)->value(exec))); if (exec->hadException()) { if (exception) *exception = toRef(exec, exec->exception()); diff --git a/API/JSWeakObjectMapRefPrivate.cpp b/API/JSWeakObjectMapRefPrivate.cpp index 13900cf..bdd56f6 100644 --- a/API/JSWeakObjectMapRefPrivate.cpp +++ b/API/JSWeakObjectMapRefPrivate.cpp @@ -57,7 +57,7 @@ void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSO JSObject* obj = toJS(object); if (!obj) return; - ASSERT(obj->inherits(&JSCallbackObject::s_info) || obj->inherits(&JSCallbackObject::s_info)); + ASSERT(obj->inherits(&JSCallbackObject::s_info) || obj->inherits(&JSCallbackObject::s_info)); map->map().set(exec->globalData(), key, obj); } @@ -65,7 +65,7 @@ JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* k { ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); - return toRef(static_cast(map->map().get(key))); + return toRef(jsCast(map->map().get(key))); } void JSWeakObjectMapRemove(JSContextRef ctx, JSWeakObjectMapRef map, void* key) diff --git a/API/OpaqueJSString.h b/API/OpaqueJSString.h index 69c0962..1c63150 100644 --- a/API/OpaqueJSString.h +++ b/API/OpaqueJSString.h @@ -26,6 +26,7 @@ #ifndef OpaqueJSString_h #define OpaqueJSString_h +#include #include namespace JSC { @@ -45,7 +46,7 @@ struct OpaqueJSString : public ThreadSafeRefCounted { return adoptRef(new OpaqueJSString(characters, length)); } - static PassRefPtr create(const JSC::UString&); + JS_EXPORT_PRIVATE static PassRefPtr create(const JSC::UString&); UChar* characters() { return this ? m_characters : 0; } unsigned length() { return this ? m_length : 0; } diff --git a/API/WebKitAvailability.h b/API/WebKitAvailability.h index 0e4f091..7846058 100644 --- a/API/WebKitAvailability.h +++ b/API/WebKitAvailability.h @@ -901,4 +901,23 @@ #endif + + + + +/* + * AVAILABLE_AFTER_WEBKIT_VERSION_5_1 + * + * Used on functions introduced after WebKit 5.1 + */ +#define AVAILABLE_AFTER_WEBKIT_VERSION_5_1 + +/* AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_5_1 + * + * Used on declarations introduced in WebKit 1.3, + * but later deprecated after WebKit 5.1 + */ +#define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_5_1 + + #endif /* __WebKitAvailability__ */ diff --git a/API/tests/JSNode.c b/API/tests/JSNode.c index d9ac0a9..052c88a 100644 --- a/API/tests/JSNode.c +++ b/API/tests/JSNode.c @@ -30,7 +30,7 @@ #include "JSValueRef.h" #include "Node.h" #include "NodeList.h" -#include "UnusedParam.h" +#include #include static JSValueRef JSNode_appendChild(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) diff --git a/API/tests/JSNodeList.c b/API/tests/JSNodeList.c index bc4a8ad..0d19484 100644 --- a/API/tests/JSNodeList.c +++ b/API/tests/JSNodeList.c @@ -27,7 +27,7 @@ #include "JSNodeList.h" #include "JSObjectRef.h" #include "JSValueRef.h" -#include "UnusedParam.h" +#include #include static JSValueRef JSNodeList_item(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) diff --git a/API/tests/testapi.c b/API/tests/testapi.c index e82d41d..91978bb 100644 --- a/API/tests/testapi.c +++ b/API/tests/testapi.c @@ -311,6 +311,16 @@ static JSValueRef MyObject_convertToType(JSContextRef context, JSObjectRef objec return JSValueMakeNull(context); } +static JSValueRef MyObject_convertToTypeWrapper(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception) +{ + UNUSED_PARAM(context); + UNUSED_PARAM(object); + UNUSED_PARAM(type); + UNUSED_PARAM(exception); + // Forward to default object class + return 0; +} + static bool MyObject_set_nullGetForwardSet(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) { UNUSED_PARAM(ctx); @@ -355,14 +365,65 @@ JSClassDefinition MyObject_definition = { MyObject_convertToType, }; +JSClassDefinition MyObject_convertToTypeWrapperDefinition = { + 0, + kJSClassAttributeNone, + + "MyObject", + NULL, + + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + MyObject_convertToTypeWrapper, +}; + +JSClassDefinition MyObject_nullWrapperDefinition = { + 0, + kJSClassAttributeNone, + + "MyObject", + NULL, + + NULL, + NULL, + + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + static JSClassRef MyObject_class(JSContextRef context) { UNUSED_PARAM(context); static JSClassRef jsClass; - if (!jsClass) - jsClass = JSClassCreate(&MyObject_definition); - + if (!jsClass) { + JSClassRef baseClass = JSClassCreate(&MyObject_definition); + MyObject_convertToTypeWrapperDefinition.parentClass = baseClass; + JSClassRef wrapperClass = JSClassCreate(&MyObject_convertToTypeWrapperDefinition); + MyObject_nullWrapperDefinition.parentClass = wrapperClass; + jsClass = JSClassCreate(&MyObject_nullWrapperDefinition); + } + return jsClass; } @@ -617,9 +678,22 @@ static JSValueRef Base_callAsFunction(JSContextRef ctx, JSObjectRef function, JS return JSValueMakeNumber(ctx, 1); // distinguish base call from derived call } +static JSValueRef Base_returnHardNull(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + UNUSED_PARAM(ctx); + UNUSED_PARAM(function); + UNUSED_PARAM(thisObject); + UNUSED_PARAM(argumentCount); + UNUSED_PARAM(arguments); + UNUSED_PARAM(exception); + + return 0; // should convert to undefined! +} + static JSStaticFunction Base_staticFunctions[] = { { "baseProtoDup", NULL, kJSPropertyAttributeNone }, { "baseProto", Base_callAsFunction, kJSPropertyAttributeNone }, + { "baseHardNull", Base_returnHardNull, kJSPropertyAttributeNone }, { 0, 0, 0 } }; @@ -791,6 +865,17 @@ static JSObjectRef myConstructor_callAsConstructor(JSContextRef context, JSObjec return result; } +static JSObjectRef myBadConstructor_callAsConstructor(JSContextRef context, JSObjectRef constructorObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + UNUSED_PARAM(context); + UNUSED_PARAM(constructorObject); + UNUSED_PARAM(argumentCount); + UNUSED_PARAM(arguments); + UNUSED_PARAM(exception); + + return 0; +} + static void globalObject_initialize(JSContextRef context, JSObjectRef object) { @@ -937,6 +1022,14 @@ static bool checkForCycleInPrototypeChain() return result; } +static void checkConstnessInJSObjectNames() +{ + JSStaticFunction fun; + fun.name = "something"; + JSStaticValue val; + val.name = "something"; +} + int main(int argc, char* argv[]) { #if OS(WINDOWS) @@ -1254,6 +1347,8 @@ int main(int argc, char* argv[]) assertEqualsAsUTF8String(jsCFEmptyString, ""); assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, ""); + checkConstnessInJSObjectNames(); + ASSERT(JSValueIsStrictEqual(context, jsTrue, jsTrue)); ASSERT(!JSValueIsStrictEqual(context, jsOne, jsOneString)); @@ -1356,7 +1451,7 @@ int main(int argc, char* argv[]) function = JSObjectMakeFunction(context, foo, 1, argumentNames, functionBody, NULL, 1, &exception); ASSERT(function && !exception); JSValueRef arguments[] = { JSValueMakeNumber(context, 2) }; - v = JSObjectCallAsFunction(context, function, NULL, 1, arguments, &exception); + JSObjectCallAsFunction(context, function, NULL, 1, arguments, &exception); JSStringRelease(foo); JSStringRelease(functionBody); @@ -1377,6 +1472,11 @@ int main(int argc, char* argv[]) JSObjectSetProperty(context, globalObject, myConstructorIString, myConstructor, kJSPropertyAttributeNone, NULL); JSStringRelease(myConstructorIString); + JSStringRef myBadConstructorIString = JSStringCreateWithUTF8CString("MyBadConstructor"); + JSObjectRef myBadConstructor = JSObjectMakeConstructor(context, NULL, myBadConstructor_callAsConstructor); + JSObjectSetProperty(context, globalObject, myBadConstructorIString, myBadConstructor, kJSPropertyAttributeNone, NULL); + JSStringRelease(myBadConstructorIString); + ASSERT(!JSObjectSetPrivate(myConstructor, (void*)1)); ASSERT(!JSObjectGetPrivate(myConstructor)); @@ -1483,7 +1583,7 @@ int main(int argc, char* argv[]) // an assert inside putDirect or lead to a crash during GC. nullDefinition = kJSClassDefinitionEmpty; nullClass = JSClassCreate(&nullDefinition); - myConstructor = JSObjectMakeConstructor(context, nullClass, 0); + JSObjectMakeConstructor(context, nullClass, 0); JSClassRelease(nullClass); char* scriptUTF8 = createStringWithContentsOfFile(scriptPath); diff --git a/API/tests/testapi.js b/API/tests/testapi.js index 61d4533..28fa544 100644 --- a/API/tests/testapi.js +++ b/API/tests/testapi.js @@ -154,9 +154,11 @@ shouldBe("MyObject()", undefined); shouldBe("typeof myObject", "object"); shouldBe("MyObject ? 1 : 0", true); // toBoolean shouldBe("+MyObject", 1); // toNumber +shouldBe("(Object.prototype.toString.call(MyObject))", "[object MyObject]"); // Object.prototype.toString shouldBe("(MyObject.toString())", "[object MyObject]"); // toString -shouldBe("String(MyObject)", "MyObjectAsString"); // type conversion to string +shouldBe("String(MyObject)", "MyObjectAsString"); // toString shouldBe("MyObject - 0", 1); // toNumber +shouldBe("MyObject.valueOf()", 1); // valueOf shouldBe("typeof MyConstructor", "object"); constructedObject = new MyConstructor(1); @@ -165,6 +167,8 @@ shouldBe("constructedObject.value", 1); shouldBe("myObject instanceof MyObject", true); shouldBe("(new Object()) instanceof MyObject", false); +shouldThrow("new MyBadConstructor()"); + MyObject.nullGetSet = 1; shouldBe("MyObject.nullGetSet", 1); shouldThrow("MyObject.nullCall()"); @@ -184,6 +188,8 @@ shouldBe("derived.protoOnly()", 2); shouldBe("derived.protoDup", 2); shouldBe("derived.derivedOnly", 2) +shouldBe("derived.baseHardNull()", undefined) + // base properties throw 1 when set; derived, 2 shouldBe("derived.baseDup = 0", 2); shouldBe("derived.baseOnly = 0", 1); diff --git a/CMakeLists.txt b/CMakeLists.txt index 870b15e..bf48f97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,16 +6,20 @@ SET(JavaScriptCore_INCLUDE_DIRECTORIES "${JAVASCRIPTCORE_DIR}/assembler" "${JAVASCRIPTCORE_DIR}/bytecode" "${JAVASCRIPTCORE_DIR}/bytecompiler" + "${JAVASCRIPTCORE_DIR}/dfg" "${JAVASCRIPTCORE_DIR}/heap" "${JAVASCRIPTCORE_DIR}/debugger" "${JAVASCRIPTCORE_DIR}/interpreter" "${JAVASCRIPTCORE_DIR}/jit" + "${JAVASCRIPTCORE_DIR}/llint" "${JAVASCRIPTCORE_DIR}/parser" "${JAVASCRIPTCORE_DIR}/profiler" "${JAVASCRIPTCORE_DIR}/runtime" + "${JAVASCRIPTCORE_DIR}/tools" "${JAVASCRIPTCORE_DIR}/yarr" - "${WTF_INCLUDE_DIRECTORIES}" - "${CMAKE_SOURCE_DIR}" + "${WTF_DIR}" + "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}" + "${CMAKE_SOURCE_DIR}/Source" ) SET(JavaScriptCore_SOURCES @@ -32,38 +36,88 @@ SET(JavaScriptCore_SOURCES API/JSWeakObjectMapRefPrivate.cpp API/OpaqueJSString.cpp + bytecode/CallLinkInfo.cpp + bytecode/CallLinkStatus.cpp bytecode/CodeBlock.cpp + bytecode/DFGExitProfile.cpp + bytecode/ExecutionCounter.cpp + bytecode/GetByIdStatus.cpp bytecode/JumpTable.cpp + bytecode/LazyOperandValueProfile.cpp + bytecode/MethodCallLinkInfo.cpp + bytecode/MethodCallLinkStatus.cpp + bytecode/MethodOfGettingAValueProfile.cpp bytecode/Opcode.cpp + bytecode/PolymorphicPutByIdList.cpp + bytecode/PredictedType.cpp + bytecode/PutByIdStatus.cpp bytecode/SamplingTool.cpp bytecode/StructureStubInfo.cpp bytecompiler/BytecodeGenerator.cpp bytecompiler/NodesCodegen.cpp - heap/Heap.cpp - heap/HandleHeap.cpp + dfg/DFGAbstractState.cpp + dfg/DFGAssemblyHelpers.cpp + dfg/DFGByteCodeParser.cpp + dfg/DFGCapabilities.cpp + dfg/DFGCFAPhase.cpp + dfg/DFGCorrectableJumpPoint.cpp + dfg/DFGCSEPhase.cpp + dfg/DFGDriver.cpp + dfg/DFGFixupPhase.cpp + dfg/DFGGraph.cpp + dfg/DFGJITCompiler.cpp + dfg/DFGNodeFlags.cpp + dfg/DFGOSREntry.cpp + dfg/DFGOSRExit.cpp + dfg/DFGOSRExitCompiler.cpp + dfg/DFGOSRExitCompiler32_64.cpp + dfg/DFGOSRExitCompiler64.cpp + dfg/DFGOperations.cpp + dfg/DFGPhase.cpp + dfg/DFGPredictionPropagationPhase.cpp + dfg/DFGRedundantPhiEliminationPhase.cpp + dfg/DFGRepatch.cpp + dfg/DFGSpeculativeJIT.cpp + dfg/DFGSpeculativeJIT32_64.cpp + dfg/DFGSpeculativeJIT64.cpp + dfg/DFGThunks.cpp + dfg/DFGVirtualRegisterAllocationPhase.cpp + + heap/BlockAllocator.cpp + heap/CopiedSpace.cpp + heap/ConservativeRoots.cpp + heap/DFGCodeBlocks.cpp + heap/HandleSet.cpp heap/HandleStack.cpp + heap/Heap.cpp heap/MachineStackMarker.cpp + heap/MarkedAllocator.cpp heap/MarkedBlock.cpp heap/MarkedSpace.cpp - heap/ConservativeRoots.cpp heap/MarkStack.cpp + heap/WeakSet.cpp + heap/WeakHandleOwner.cpp + heap/WeakBlock.cpp debugger/Debugger.cpp debugger/DebuggerActivation.cpp debugger/DebuggerCallFrame.cpp - + + interpreter/AbstractPC.cpp interpreter/CallFrame.cpp interpreter/Interpreter.cpp interpreter/RegisterFile.cpp jit/ExecutableAllocator.cpp + jit/HostCallReturnValue.cpp jit/JITArithmetic32_64.cpp jit/JITArithmetic.cpp jit/JITCall32_64.cpp jit/JITCall.cpp jit/JIT.cpp + jit/JITExceptions.cpp jit/JITOpcodes32_64.cpp jit/JITOpcodes.cpp jit/JITPropertyAccess32_64.cpp @@ -71,7 +125,6 @@ SET(JavaScriptCore_SOURCES jit/JITStubs.cpp jit/ThunkGenerators.cpp - parser/JSParser.cpp parser/Lexer.cpp parser/Nodes.cpp parser/Parser.cpp @@ -114,24 +167,25 @@ SET(JavaScriptCore_SOURCES runtime/JSActivation.cpp runtime/JSAPIValueWrapper.cpp runtime/JSArray.cpp - runtime/JSByteArray.cpp runtime/JSCell.cpp + runtime/JSDateMath.cpp runtime/JSFunction.cpp + runtime/JSBoundFunction.cpp runtime/JSGlobalData.cpp runtime/JSGlobalObject.cpp runtime/JSGlobalObjectFunctions.cpp + runtime/JSGlobalThis.cpp runtime/JSLock.cpp runtime/JSNotAnObject.cpp runtime/JSObject.cpp - runtime/JSObjectWithGlobalObject.cpp runtime/JSONObject.cpp runtime/JSPropertyNameIterator.cpp runtime/JSStaticScopeObject.cpp runtime/JSString.cpp + runtime/JSStringJoiner.cpp runtime/JSValue.cpp runtime/JSVariableObject.cpp runtime/JSWrapperObject.cpp - runtime/JSZombie.cpp runtime/LiteralParser.cpp runtime/Lookup.cpp runtime/MathObject.cpp @@ -143,15 +197,17 @@ SET(JavaScriptCore_SOURCES runtime/ObjectConstructor.cpp runtime/ObjectPrototype.cpp runtime/Operations.cpp + runtime/Options.cpp runtime/PropertyDescriptor.cpp runtime/PropertyNameArray.cpp runtime/PropertySlot.cpp runtime/RegExp.cpp runtime/RegExpCache.cpp runtime/RegExpConstructor.cpp + runtime/RegExpCachedResult.cpp + runtime/RegExpMatchesArray.cpp runtime/RegExpObject.cpp runtime/RegExpPrototype.cpp - runtime/RopeImpl.cpp runtime/ScopeChain.cpp runtime/SmallStrings.cpp runtime/StrictEvalActivation.cpp @@ -164,16 +220,15 @@ SET(JavaScriptCore_SOURCES runtime/TimeoutChecker.cpp runtime/UString.cpp + tools/CodeProfile.cpp + tools/CodeProfiling.cpp + + yarr/YarrCanonicalizeUCS2.cpp yarr/YarrPattern.cpp yarr/YarrInterpreter.cpp yarr/YarrJIT.cpp yarr/YarrSyntaxChecker.cpp - - wtf/DateMath.cpp - wtf/PageAllocationAligned.cpp - wtf/PageBlock.cpp ) -SET(JavaScriptCore_HEADERS ) SET(JavaScriptCore_LUT_FILES runtime/ArrayConstructor.cpp @@ -244,10 +299,9 @@ ELSE () ENDIF () -INCLUDE_IF_EXISTS(${JAVASCRIPTCORE_DIR}/CMakeLists${PORT}.txt) +WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS() -ADD_SUBDIRECTORY(wtf) ADD_SUBDIRECTORY(shell) WEBKIT_WRAP_SOURCELIST(${JavaScriptCore_SOURCES}) @@ -255,6 +309,8 @@ INCLUDE_DIRECTORIES(${JavaScriptCore_INCLUDE_DIRECTORIES}) ADD_DEFINITIONS(-DBUILDING_JavaScriptCore) ADD_LIBRARY(${JavaScriptCore_LIBRARY_NAME} ${JavaScriptCore_LIBRARY_TYPE} ${JavaScriptCore_HEADERS} ${JavaScriptCore_SOURCES}) TARGET_LINK_LIBRARIES(${JavaScriptCore_LIBRARY_NAME} ${JavaScriptCore_LIBRARIES}) +SET_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} PROPERTIES FOLDER "JavaScriptCore") +SET_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} PROPERTIES LINK_INTERFACE_LIBRARIES "") IF (JavaScriptCore_LINK_FLAGS) ADD_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} LINK_FLAGS "${JavaScriptCore_LINK_FLAGS}") @@ -262,5 +318,5 @@ ENDIF () IF (SHARED_CORE) SET_TARGET_PROPERTIES(${JavaScriptCore_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) - INSTALL(TARGETS ${JavaScriptCore_LIBRARY_NAME} DESTINATION lib) + INSTALL(TARGETS ${JavaScriptCore_LIBRARY_NAME} DESTINATION "${LIB_INSTALL_DIR}") ENDIF () diff --git a/CMakeListsEfl.txt b/CMakeListsEfl.txt deleted file mode 100644 index cdc3fe2..0000000 --- a/CMakeListsEfl.txt +++ /dev/null @@ -1,20 +0,0 @@ -LIST(APPEND JavaScriptCore_SOURCES - jit/ExecutableAllocatorFixedVMPool.cpp - jit/ExecutableAllocator.cpp - heap/MarkStackPosix.cpp - wtf/OSAllocatorPosix.cpp -) - -LIST(APPEND JavaScriptCore_LIBRARIES - ${ICU_I18N_LIBRARIES} -) - -IF (ENABLE_GLIB_SUPPORT) - LIST(APPEND JavaScriptCore_INCLUDE_DIRECTORIES - ${JAVASCRIPTCORE_DIR}/wtf/gobject - ) -ENDIF () - -LIST(APPEND JavaScriptCore_LINK_FLAGS - ${ECORE_LDFLAGS} -) diff --git a/CMakeListsWinCE.txt b/CMakeListsWinCE.txt deleted file mode 100644 index d878863..0000000 --- a/CMakeListsWinCE.txt +++ /dev/null @@ -1,22 +0,0 @@ -LIST(APPEND JavaScriptCore_SOURCES - jit/ExecutableAllocator.cpp - - heap/MarkStackWin.cpp -) - -IF (ENABLE_JIT AND WTF_CPU_ARM) - ADD_CUSTOM_COMMAND( - OUTPUT ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm - MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/create_jit_stubs - DEPENDS ${JAVASCRIPTCORE_DIR}/jit/JITStubs.cpp - COMMAND ${PERL_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/create_jit_stubs --prefix=MSVC ${JAVASCRIPTCORE_DIR}/jit/JITStubs.cpp > ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm - VERBATIM) - - ADD_CUSTOM_COMMAND( - OUTPUT ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj - MAIN_DEPENDENCY ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm - COMMAND armasm -nologo ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj - VERBATIM) - - LIST (APPEND JavaScriptCore_SOURCES ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj) -ENDIF () diff --git a/DerivedSources.make b/DerivedSources.make index 80af4b6..90e099d 100644 --- a/DerivedSources.make +++ b/DerivedSources.make @@ -43,8 +43,6 @@ all : \ ErrorPrototype.lut.h \ HeaderDetection.h \ JSONObject.lut.h \ - JavaScriptCore.JSVALUE32_64.exp \ - JavaScriptCore.JSVALUE64.exp \ JSGlobalObject.lut.h \ KeywordLookup.h \ Lexer.lut.h \ @@ -80,15 +78,6 @@ RegExpJitTables.h: create_regex_tables KeywordLookup.h: KeywordLookupGenerator.py Keywords.table python $^ > $@ -# export files - -JavaScriptCore.JSVALUE32_64.exp: JavaScriptCore.exp JavaScriptCore.JSVALUE32_64only.exp - cat $^ > $@ - -JavaScriptCore.JSVALUE64.exp: JavaScriptCore.exp JavaScriptCore.JSVALUE64only.exp - cat $^ > $@ - - # header detection ifeq ($(OS),MACOS) diff --git a/DerivedSources.pri b/DerivedSources.pri new file mode 100644 index 0000000..755a5b0 --- /dev/null +++ b/DerivedSources.pri @@ -0,0 +1,81 @@ +# ------------------------------------------------------------------- +# Derived sources for JavaScriptSource +# +# See 'Tools/qmake/README' for an overview of the build system +# ------------------------------------------------------------------- + +TEMPLATE = derived + +LUT_FILES += \ + runtime/ArrayConstructor.cpp \ + runtime/ArrayPrototype.cpp \ + runtime/BooleanPrototype.cpp \ + runtime/DateConstructor.cpp \ + runtime/DatePrototype.cpp \ + runtime/ErrorPrototype.cpp \ + runtime/JSGlobalObject.cpp \ + runtime/JSONObject.cpp \ + runtime/MathObject.cpp \ + runtime/NumberConstructor.cpp \ + runtime/NumberPrototype.cpp \ + runtime/ObjectConstructor.cpp \ + runtime/ObjectPrototype.cpp \ + runtime/RegExpConstructor.cpp \ + runtime/RegExpObject.cpp \ + runtime/RegExpPrototype.cpp \ + runtime/StringConstructor.cpp \ + runtime/StringPrototype.cpp \ + +KEYWORDLUT_FILES += \ + parser/Keywords.table + +JIT_STUB_FILES += \ + jit/JITStubs.cpp + +# GENERATOR 1-A: LUT creator +lut.output = ${QMAKE_FILE_BASE}.lut.h +lut.input = LUT_FILES +lut.script = $$PWD/create_hash_table +lut.commands = perl $$lut.script ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT} +lut.depends = ${QMAKE_FILE_NAME} +GENERATORS += lut + +# GENERATOR 1-B: particular LUT creator (for 1 file only) +keywordlut.output = Lexer.lut.h +keywordlut.input = KEYWORDLUT_FILES +keywordlut.script = $$PWD/create_hash_table +keywordlut.commands = perl $$keywordlut.script ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT} +keywordlut.depends = ${QMAKE_FILE_NAME} +GENERATORS += keywordlut + +# GENERATOR 2-A: JIT Stub functions for RVCT +rvctstubs.output = Generated${QMAKE_FILE_BASE}_RVCT.h +rvctstubs.script = $$PWD/create_jit_stubs +rvctstubs.commands = perl -i $$rvctstubs.script --prefix RVCT ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT} +rvctstubs.depends = ${QMAKE_FILE_NAME} +rvctstubs.input = JIT_STUB_FILES +rvctstubs.CONFIG += no_link +GENERATORS += rvctstubs + +# GENERATOR 2-B: JIT Stub functions for MSVC +msvcstubs.output = Generated${QMAKE_FILE_BASE}_MSVC.asm +msvcstubs.script = $$PWD/create_jit_stubs +msvcstubs.commands = perl -i $$msvcstubs.script --prefix MSVC ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT} +msvcstubs.depends = ${QMAKE_FILE_NAME} +msvcstubs.input = JIT_STUB_FILES +msvcstubs.CONFIG += no_link +GENERATORS += msvcstubs + +#GENERATOR: "RegExpJitTables.h": tables used by Yarr +retgen.output = RegExpJitTables.h +retgen.script = $$PWD/create_regex_tables +retgen.input = retgen.script +retgen.commands = python $$retgen.script > ${QMAKE_FILE_OUT} +GENERATORS += retgen + +#GENERATOR: "KeywordLookup.h": decision tree used by the lexer +klgen.output = KeywordLookup.h +klgen.script = $$PWD/KeywordLookupGenerator.py +klgen.input = KEYWORDLUT_FILES +klgen.commands = python $$klgen.script ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT} +GENERATORS += klgen diff --git a/DerivedSources.pro b/DerivedSources.pro deleted file mode 100644 index 0989605..0000000 --- a/DerivedSources.pro +++ /dev/null @@ -1,108 +0,0 @@ -# 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/ArrayConstructor.cpp \ - runtime/ArrayPrototype.cpp \ - runtime/BooleanPrototype.cpp \ - runtime/DateConstructor.cpp \ - runtime/DatePrototype.cpp \ - runtime/ErrorPrototype.cpp \ - runtime/JSGlobalObject.cpp \ - runtime/JSONObject.cpp \ - runtime/MathObject.cpp \ - runtime/NumberConstructor.cpp \ - runtime/NumberPrototype.cpp \ - runtime/ObjectConstructor.cpp \ - runtime/ObjectPrototype.cpp \ - runtime/RegExpConstructor.cpp \ - runtime/RegExpObject.cpp \ - runtime/RegExpPrototype.cpp \ - runtime/StringConstructor.cpp \ - runtime/StringPrototype.cpp \ - -KEYWORDLUT_FILES += \ - parser/Keywords.table - -JIT_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-A: JIT Stub functions for RVCT -rvctstubs.output = $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}Generated${QMAKE_FILE_BASE}_RVCT.h -rvctstubs.wkScript = $$PWD/create_jit_stubs -rvctstubs.commands = perl -i $$rvctstubs.wkScript --prefix RVCT ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT} -rvctstubs.depends = ${QMAKE_FILE_NAME} -rvctstubs.input = JIT_STUB_FILES -rvctstubs.CONFIG += no_link -addExtraCompiler(rvctstubs) - -# GENERATOR 2-B: JIT Stub functions for MSVC -msvcstubs.output = $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}Generated${QMAKE_FILE_BASE}_MSVC.asm -msvcstubs.wkScript = $$PWD/create_jit_stubs -msvcstubs.commands = perl -i $$msvcstubs.wkScript --prefix MSVC ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT} -msvcstubs.depends = ${QMAKE_FILE_NAME} -msvcstubs.input = JIT_STUB_FILES -msvcstubs.CONFIG += no_link -addExtraCompiler(msvcstubs) - -#GENERATOR: "RegExpJitTables.h": tables used by Yarr -retgen.output = $$JSC_GENERATED_SOURCES_DIR/RegExpJitTables.h -retgen.wkScript = $$PWD/create_regex_tables -retgen.input = retgen.wkScript -retgen.commands = python $$retgen.wkScript > ${QMAKE_FILE_OUT} -addExtraCompiler(retgen) - -#GENERATOR: "KeywordLookup.h": decision tree used by the lexer -klgen.output = $$JSC_GENERATED_SOURCES_DIR/KeywordLookup.h -klgen.wkScript = $$PWD/KeywordLookupGenerator.py -klgen.input = KEYWORDLUT_FILES -klgen.commands = python $$klgen.wkScript ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT} -addExtraCompiler(klgen) diff --git a/GNUmakefile.am b/GNUmakefile.am index c710d2a..e845287 100644 --- a/GNUmakefile.am +++ b/GNUmakefile.am @@ -16,17 +16,18 @@ nodist_EXTRA_libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_M nodist_libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_SOURCES = \ $(javascriptcore_built_sources) -libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_ladir = $(prefix)/include/webkit-@WEBKITGTK_API_VERSION@/JavaScriptCore +libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_ladir = $(libwebkitgtkincludedir)/JavaScriptCore libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_HEADERS = $(javascriptcore_h_api) libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_SOURCES = \ $(javascriptcore_sources) libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_LIBADD = \ + -lpthread \ + libWTF.la \ $(UNICODE_LIBS) \ $(GLIB_LIBS) \ - $(WINMM_LIBS) \ - -lpthread + $(WINMM_LIBS) libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_CXXFLAGS = \ $(global_cxxflags) \ @@ -35,51 +36,57 @@ libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@ libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_CFLAGS = \ -fstrict-aliasing \ -O3 \ - $(global_cflags) \ - $(GLIB_CFLAGS) \ - $(UNICODE_CFLAGS) + $(javascriptcore_cflags) libjavascriptcoregtk_@WEBKITGTK_API_MAJOR_VERSION@_@WEBKITGTK_API_MINOR_VERSION@_la_CPPFLAGS = \ $(global_cppflags) \ $(javascriptcore_cppflags) javascriptcore_cppflags += \ + $(JSC_CPPFLAGS) \ -I$(srcdir)/Source \ -I$(srcdir)/Source/JavaScriptCore \ -I$(srcdir)/Source/JavaScriptCore/API \ -I$(srcdir)/Source/JavaScriptCore/assembler \ -I$(srcdir)/Source/JavaScriptCore/bytecode \ -I$(srcdir)/Source/JavaScriptCore/bytecompiler \ + -I$(srcdir)/Source/JavaScriptCore/dfg \ -I$(srcdir)/Source/JavaScriptCore/heap \ -I$(srcdir)/Source/JavaScriptCore/debugger \ -I$(srcdir)/Source/JavaScriptCore/ForwardingHeaders \ -I$(srcdir)/Source/JavaScriptCore/interpreter \ -I$(srcdir)/Source/JavaScriptCore/jit \ -I$(srcdir)/Source/JavaScriptCore/jit \ + -I$(srcdir)/Source/JavaScriptCore/llint \ -I$(srcdir)/Source/JavaScriptCore/parser \ -I$(srcdir)/Source/JavaScriptCore/profiler \ -I$(srcdir)/Source/JavaScriptCore/runtime \ - -I$(srcdir)/Source/JavaScriptCore/wtf \ - -I$(srcdir)/Source/JavaScriptCore/wtf \ - -I$(srcdir)/Source/JavaScriptCore/wtf/gobject \ - -I$(srcdir)/Source/JavaScriptCore/wtf/gtk \ - -I$(srcdir)/Source/JavaScriptCore/wtf/text \ - -I$(srcdir)/Source/JavaScriptCore/wtf/unicode \ + -I$(srcdir)/Source/JavaScriptCore/tools \ -I$(srcdir)/Source/JavaScriptCore/yarr \ - -I$(top_builddir)/Source/JavaScriptCore \ - -I$(top_builddir)/Source/JavaScriptCore/parser \ - -I$(top_builddir)/Source/JavaScriptCore/runtime + -I$(top_builddir)/DerivedSources/JavaScriptCore + +javascriptcore_cppflags += \ + -I$(srcdir)/Source/WTF -Source/JavaScriptCore/Lexer.lut.h: $(srcdir)/Source/JavaScriptCore/create_hash_table $(srcdir)/Source/JavaScriptCore/parser/Keywords.table +javascriptcore_cflags += \ + $(global_cflags) \ + $(GLIB_CFLAGS) \ + $(UNICODE_CFLAGS) + +pkgconfig_DATA += Source/JavaScriptCore/javascriptcoregtk-@WEBKITGTK_API_VERSION@.pc + +$(shell mkdir -p DerivedSources/JavaScriptCore) + +DerivedSources/JavaScriptCore/Lexer.lut.h: $(srcdir)/Source/JavaScriptCore/create_hash_table $(srcdir)/Source/JavaScriptCore/parser/Keywords.table $(AM_V_GEN)$(PERL) $^ > $@ -Source/JavaScriptCore/%.lut.h: $(srcdir)/Source/JavaScriptCore/create_hash_table $(srcdir)/Source/JavaScriptCore/%.cpp +DerivedSources/JavaScriptCore/%.lut.h: $(srcdir)/Source/JavaScriptCore/create_hash_table $(srcdir)/Source/JavaScriptCore/runtime/%.cpp $(AM_V_GEN)$(PERL) $^ -i > $@ -Source/JavaScriptCore/RegExpJitTables.h: $(srcdir)/Source/JavaScriptCore/create_regex_tables +DerivedSources/JavaScriptCore/RegExpJitTables.h: $(srcdir)/Source/JavaScriptCore/create_regex_tables $(AM_V_GEN)$(PYTHON) $^ > $@ -Source/JavaScriptCore/KeywordLookup.h: $(srcdir)/Source/JavaScriptCore/KeywordLookupGenerator.py $(srcdir)/Source/JavaScriptCore/parser/Keywords.table +DerivedSources/JavaScriptCore/KeywordLookup.h: $(srcdir)/Source/JavaScriptCore/KeywordLookupGenerator.py $(srcdir)/Source/JavaScriptCore/parser/Keywords.table $(AM_V_GEN)$(PYTHON) $^ > $@ jsc: $(javascriptcore_built_nosources) Programs/jsc$(EXEEXT) @@ -142,32 +149,15 @@ EXTRA_DIST += \ Source/JavaScriptCore/create_regex_tables \ Source/JavaScriptCore/icu/LICENSE \ Source/JavaScriptCore/icu/README \ + Source/JavaScriptCore/KeywordLookupGenerator.py \ Source/JavaScriptCore/parser/Keywords.table \ Source/JavaScriptCore/THANKS -# Clean rules for JavaScriptCore -# FIXME: Should this list be generated from javascriptcore_built_nosources? CLEANFILES += \ - Source/JavaScriptCore/Lexer.lut.h \ - Source/JavaScriptCore/RegExpJitTables.h \ - Source/JavaScriptCore/runtime/ArrayConstructor.lut.h \ - Source/JavaScriptCore/runtime/ArrayPrototype.lut.h \ - Source/JavaScriptCore/runtime/BooleanPrototype.lut.h \ - Source/JavaScriptCore/runtime/DateConstructor.lut.h \ - Source/JavaScriptCore/runtime/DatePrototype.lut.h \ - Source/JavaScriptCore/runtime/ErrorPrototype.lut.h \ - Source/JavaScriptCore/runtime/JSGlobalObject.lut.h \ - Source/JavaScriptCore/runtime/JSONObject.lut.h \ - Source/JavaScriptCore/runtime/MathObject.lut.h \ - Source/JavaScriptCore/runtime/NumberConstructor.lut.h \ - Source/JavaScriptCore/runtime/NumberPrototype.lut.h \ - Source/JavaScriptCore/runtime/ObjectConstructor.lut.h \ - Source/JavaScriptCore/runtime/ObjectPrototype.lut.h \ - Source/JavaScriptCore/runtime/RegExpConstructor.lut.h \ - Source/JavaScriptCore/runtime/RegExpObject.lut.h \ - Source/JavaScriptCore/runtime/RegExpPrototype.lut.h \ - Source/JavaScriptCore/runtime/StringConstructor.lut.h \ - Source/JavaScriptCore/runtime/StringPrototype.lut.h \ + $(javascriptcore_built_nosources) \ Programs/jsc \ Programs/jsc-@WEBKITGTK_API_MAJOR_VERSION@ \ Programs/minidom + +DISTCLEANFILES += \ + $(top_builddir)/Source/JavaScriptCore/javascriptcoregtk-@WEBKITGTK_API_VERSION@.pc diff --git a/GNUmakefile.list.am b/GNUmakefile.list.am index e33c2a4..b79bc53 100644 --- a/GNUmakefile.list.am +++ b/GNUmakefile.list.am @@ -11,26 +11,27 @@ javascriptcore_h_api += \ Source/JavaScriptCore/API/WebKitAvailability.h javascriptcore_built_nosources += \ - Source/JavaScriptCore/Lexer.lut.h \ - Source/JavaScriptCore/RegExpJitTables.h \ - Source/JavaScriptCore/runtime/ArrayConstructor.lut.h \ - Source/JavaScriptCore/runtime/ArrayPrototype.lut.h \ - Source/JavaScriptCore/runtime/BooleanPrototype.lut.h \ - Source/JavaScriptCore/runtime/DateConstructor.lut.h \ - Source/JavaScriptCore/runtime/DatePrototype.lut.h \ - Source/JavaScriptCore/runtime/ErrorPrototype.lut.h \ - Source/JavaScriptCore/runtime/JSGlobalObject.lut.h \ - Source/JavaScriptCore/runtime/JSONObject.lut.h \ - Source/JavaScriptCore/runtime/MathObject.lut.h \ - Source/JavaScriptCore/runtime/NumberConstructor.lut.h \ - Source/JavaScriptCore/runtime/NumberPrototype.lut.h \ - Source/JavaScriptCore/runtime/ObjectConstructor.lut.h \ - Source/JavaScriptCore/runtime/ObjectPrototype.lut.h \ - Source/JavaScriptCore/runtime/RegExpConstructor.lut.h \ - Source/JavaScriptCore/runtime/RegExpObject.lut.h \ - Source/JavaScriptCore/runtime/RegExpPrototype.lut.h \ - Source/JavaScriptCore/runtime/StringConstructor.lut.h \ - Source/JavaScriptCore/runtime/StringPrototype.lut.h + DerivedSources/JavaScriptCore/KeywordLookup.h \ + DerivedSources/JavaScriptCore/Lexer.lut.h \ + DerivedSources/JavaScriptCore/RegExpJitTables.h \ + DerivedSources/JavaScriptCore/ArrayConstructor.lut.h \ + DerivedSources/JavaScriptCore/ArrayPrototype.lut.h \ + DerivedSources/JavaScriptCore/BooleanPrototype.lut.h \ + DerivedSources/JavaScriptCore/DateConstructor.lut.h \ + DerivedSources/JavaScriptCore/DatePrototype.lut.h \ + DerivedSources/JavaScriptCore/ErrorPrototype.lut.h \ + DerivedSources/JavaScriptCore/JSGlobalObject.lut.h \ + DerivedSources/JavaScriptCore/JSONObject.lut.h \ + DerivedSources/JavaScriptCore/MathObject.lut.h \ + DerivedSources/JavaScriptCore/NumberConstructor.lut.h \ + DerivedSources/JavaScriptCore/NumberPrototype.lut.h \ + DerivedSources/JavaScriptCore/ObjectConstructor.lut.h \ + DerivedSources/JavaScriptCore/ObjectPrototype.lut.h \ + DerivedSources/JavaScriptCore/RegExpConstructor.lut.h \ + DerivedSources/JavaScriptCore/RegExpObject.lut.h \ + DerivedSources/JavaScriptCore/RegExpPrototype.lut.h \ + DerivedSources/JavaScriptCore/StringConstructor.lut.h \ + DerivedSources/JavaScriptCore/StringPrototype.lut.h javascriptcore_sources += \ Source/JavaScriptCore/API/APICast.h \ @@ -65,65 +66,212 @@ javascriptcore_sources += \ Source/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h \ Source/JavaScriptCore/assembler/CodeLocation.h \ Source/JavaScriptCore/assembler/LinkBuffer.h \ + Source/JavaScriptCore/assembler/MacroAssembler.h \ Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp \ Source/JavaScriptCore/assembler/MacroAssemblerARM.h \ Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h \ Source/JavaScriptCore/assembler/MacroAssemblerCodeRef.h \ - Source/JavaScriptCore/assembler/MacroAssembler.h \ - Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h \ - Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h \ - Source/JavaScriptCore/assembler/MacroAssemblerX86.h \ - Source/JavaScriptCore/assembler/MacroAssemblerSH4.h \ + Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h \ Source/JavaScriptCore/assembler/MacroAssemblerSH4.cpp \ - Source/JavaScriptCore/assembler/SH4Assembler.h \ + Source/JavaScriptCore/assembler/MacroAssemblerSH4.h \ + Source/JavaScriptCore/assembler/MacroAssemblerX86.h \ + Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h \ + Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h \ + Source/JavaScriptCore/assembler/MIPSAssembler.h \ Source/JavaScriptCore/assembler/RepatchBuffer.h \ + Source/JavaScriptCore/assembler/SH4Assembler.h \ Source/JavaScriptCore/assembler/X86Assembler.h \ + Source/JavaScriptCore/bytecode/BytecodeConventions.h \ + Source/JavaScriptCore/bytecode/CallLinkInfo.cpp \ + Source/JavaScriptCore/bytecode/CallLinkInfo.h \ + Source/JavaScriptCore/bytecode/CallLinkStatus.cpp \ + Source/JavaScriptCore/bytecode/CallLinkStatus.h \ + Source/JavaScriptCore/bytecode/CallReturnOffsetToBytecodeOffset.h \ + Source/JavaScriptCore/bytecode/CodeType.h \ Source/JavaScriptCore/bytecode/CodeBlock.cpp \ Source/JavaScriptCore/bytecode/CodeBlock.h \ + Source/JavaScriptCore/bytecode/CodeOrigin.h \ + Source/JavaScriptCore/bytecode/DataFormat.h \ + Source/JavaScriptCore/bytecode/DFGExitProfile.cpp \ + Source/JavaScriptCore/bytecode/DFGExitProfile.h \ Source/JavaScriptCore/bytecode/EvalCodeCache.h \ + Source/JavaScriptCore/bytecode/ExecutionCounter.cpp \ + Source/JavaScriptCore/bytecode/ExecutionCounter.h \ + Source/JavaScriptCore/bytecode/ExpressionRangeInfo.h \ + Source/JavaScriptCore/bytecode/GetByIdStatus.cpp \ + Source/JavaScriptCore/bytecode/GetByIdStatus.h \ + Source/JavaScriptCore/bytecode/GlobalResolveInfo.h \ + Source/JavaScriptCore/bytecode/HandlerInfo.h \ Source/JavaScriptCore/bytecode/Instruction.h \ Source/JavaScriptCore/bytecode/JumpTable.cpp \ Source/JavaScriptCore/bytecode/JumpTable.h \ + Source/JavaScriptCore/bytecode/LLIntCallLinkInfo.h \ + Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp \ + Source/JavaScriptCore/bytecode/LazyOperandValueProfile.h \ + Source/JavaScriptCore/bytecode/LineInfo.h \ + Source/JavaScriptCore/bytecode/MethodCallLinkInfo.cpp \ + Source/JavaScriptCore/bytecode/MethodCallLinkInfo.h \ + Source/JavaScriptCore/bytecode/MethodCallLinkStatus.cpp \ + Source/JavaScriptCore/bytecode/MethodCallLinkStatus.h \ + Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.cpp \ + Source/JavaScriptCore/bytecode/MethodOfGettingAValueProfile.h \ Source/JavaScriptCore/bytecode/Opcode.cpp \ Source/JavaScriptCore/bytecode/Opcode.h \ + Source/JavaScriptCore/bytecode/Operands.h \ + Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.cpp \ + Source/JavaScriptCore/bytecode/PolymorphicPutByIdList.h \ + Source/JavaScriptCore/bytecode/PredictedType.cpp \ + Source/JavaScriptCore/bytecode/PredictedType.h \ + Source/JavaScriptCore/bytecode/PutByIdStatus.cpp \ + Source/JavaScriptCore/bytecode/PutByIdStatus.h \ + Source/JavaScriptCore/bytecode/PutKind.h \ Source/JavaScriptCore/bytecode/SamplingTool.cpp \ Source/JavaScriptCore/bytecode/SamplingTool.h \ + Source/JavaScriptCore/bytecode/StructureSet.h \ Source/JavaScriptCore/bytecode/StructureStubInfo.cpp \ Source/JavaScriptCore/bytecode/StructureStubInfo.h \ + Source/JavaScriptCore/bytecode/ValueProfile.h \ + Source/JavaScriptCore/bytecode/ValueRecovery.h \ + Source/JavaScriptCore/bytecode/VirtualRegister.h \ Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp \ Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h \ Source/JavaScriptCore/bytecompiler/Label.h \ Source/JavaScriptCore/bytecompiler/LabelScope.h \ Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp \ Source/JavaScriptCore/bytecompiler/RegisterID.h \ + Source/JavaScriptCore/dfg/DFGAbstractState.cpp \ + Source/JavaScriptCore/dfg/DFGAbstractState.h \ + Source/JavaScriptCore/dfg/DFGAbstractValue.h \ + Source/JavaScriptCore/dfg/DFGArgumentPosition.h \ + Source/JavaScriptCore/dfg/DFGAssemblyHelpers.cpp \ + Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h \ + Source/JavaScriptCore/dfg/DFGBasicBlock.h \ + Source/JavaScriptCore/dfg/DFGByteCodeCache.h \ + Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp \ + Source/JavaScriptCore/dfg/DFGByteCodeParser.h \ + Source/JavaScriptCore/dfg/DFGCCallHelpers.h \ + Source/JavaScriptCore/dfg/DFGCapabilities.cpp \ + Source/JavaScriptCore/dfg/DFGCapabilities.h \ + Source/JavaScriptCore/dfg/DFGCFAPhase.cpp \ + Source/JavaScriptCore/dfg/DFGCFAPhase.h \ + Source/JavaScriptCore/dfg/DFGCommon.h \ + Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.cpp \ + Source/JavaScriptCore/dfg/DFGCorrectableJumpPoint.h \ + Source/JavaScriptCore/dfg/DFGCSEPhase.cpp \ + Source/JavaScriptCore/dfg/DFGCSEPhase.h \ + Source/JavaScriptCore/dfg/DFGDoubleFormatState.h \ + Source/JavaScriptCore/dfg/DFGDriver.cpp \ + Source/JavaScriptCore/dfg/DFGDriver.h \ + Source/JavaScriptCore/dfg/DFGFPRInfo.h \ + Source/JavaScriptCore/dfg/DFGFixupPhase.cpp \ + Source/JavaScriptCore/dfg/DFGFixupPhase.h \ + Source/JavaScriptCore/dfg/DFGGenerationInfo.h \ + Source/JavaScriptCore/dfg/DFGGPRInfo.h \ + Source/JavaScriptCore/dfg/DFGGraph.cpp \ + Source/JavaScriptCore/dfg/DFGGraph.h \ + Source/JavaScriptCore/dfg/DFGInsertionSet.h \ + Source/JavaScriptCore/dfg/DFGJITCompiler.cpp \ + Source/JavaScriptCore/dfg/DFGJITCompiler.h \ + Source/JavaScriptCore/dfg/DFGNode.h \ + Source/JavaScriptCore/dfg/DFGNodeFlags.cpp \ + Source/JavaScriptCore/dfg/DFGNodeFlags.h \ + Source/JavaScriptCore/dfg/DFGAdjacencyList.h \ + Source/JavaScriptCore/dfg/DFGNodeType.h \ + Source/JavaScriptCore/dfg/DFGEdge.h \ + Source/JavaScriptCore/dfg/DFGOperations.cpp \ + Source/JavaScriptCore/dfg/DFGOperations.h \ + Source/JavaScriptCore/dfg/DFGOSREntry.cpp \ + Source/JavaScriptCore/dfg/DFGOSREntry.h \ + Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp \ + Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp \ + Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp \ + Source/JavaScriptCore/dfg/DFGOSRExitCompiler.h \ + Source/JavaScriptCore/dfg/DFGOSRExit.h \ + Source/JavaScriptCore/dfg/DFGOSRExit.cpp \ + Source/JavaScriptCore/dfg/DFGPhase.cpp \ + Source/JavaScriptCore/dfg/DFGPhase.h \ + Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp \ + Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.h \ + Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.cpp \ + Source/JavaScriptCore/dfg/DFGRedundantPhiEliminationPhase.h \ + Source/JavaScriptCore/dfg/DFGRegisterBank.h \ + Source/JavaScriptCore/dfg/DFGRepatch.cpp \ + Source/JavaScriptCore/dfg/DFGRepatch.h \ + Source/JavaScriptCore/dfg/DFGScoreBoard.h \ + Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp \ + Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp \ + Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp \ + Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h \ + Source/JavaScriptCore/dfg/DFGThunks.cpp \ + Source/JavaScriptCore/dfg/DFGThunks.h \ + Source/JavaScriptCore/dfg/DFGVariableAccessData.h \ + Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.cpp \ + Source/JavaScriptCore/dfg/DFGVirtualRegisterAllocationPhase.h \ + Source/JavaScriptCore/heap/CopiedAllocator.h \ + Source/JavaScriptCore/heap/CopiedBlock.h \ + Source/JavaScriptCore/heap/CopiedSpace.cpp \ + Source/JavaScriptCore/heap/CopiedSpace.h \ + Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h \ + Source/JavaScriptCore/heap/CardSet.h \ Source/JavaScriptCore/heap/ConservativeRoots.cpp \ Source/JavaScriptCore/heap/ConservativeRoots.h \ + Source/JavaScriptCore/heap/DFGCodeBlocks.cpp \ + Source/JavaScriptCore/heap/DFGCodeBlocks.h \ + Source/JavaScriptCore/heap/GCAssertions.h \ Source/JavaScriptCore/heap/Handle.h \ - Source/JavaScriptCore/heap/HandleHeap.cpp \ - Source/JavaScriptCore/heap/HandleHeap.h \ + Source/JavaScriptCore/heap/HandleSet.cpp \ + Source/JavaScriptCore/heap/HandleSet.h \ + Source/JavaScriptCore/heap/HeapBlock.h \ + Source/JavaScriptCore/heap/SlotVisitor.h \ Source/JavaScriptCore/heap/HandleStack.cpp \ Source/JavaScriptCore/heap/HandleStack.h \ Source/JavaScriptCore/heap/HandleTypes.h \ + Source/JavaScriptCore/heap/BlockAllocator.cpp \ + Source/JavaScriptCore/heap/BlockAllocator.h \ Source/JavaScriptCore/heap/Heap.cpp \ Source/JavaScriptCore/heap/Heap.h \ + Source/JavaScriptCore/heap/ListableHandler.h \ Source/JavaScriptCore/heap/Local.h \ Source/JavaScriptCore/heap/LocalScope.h \ Source/JavaScriptCore/heap/MachineStackMarker.cpp \ Source/JavaScriptCore/heap/MachineStackMarker.h \ Source/JavaScriptCore/heap/MarkStack.cpp \ Source/JavaScriptCore/heap/MarkStack.h \ + Source/JavaScriptCore/heap/HeapRootVisitor.h \ + Source/JavaScriptCore/heap/MarkedAllocator.cpp \ + Source/JavaScriptCore/heap/MarkedAllocator.h \ Source/JavaScriptCore/heap/MarkedBlock.cpp \ Source/JavaScriptCore/heap/MarkedBlock.h \ + Source/JavaScriptCore/heap/MarkedBlockSet.h \ + Source/JavaScriptCore/heap/TinyBloomFilter.h \ Source/JavaScriptCore/heap/MarkedSpace.cpp \ Source/JavaScriptCore/heap/MarkedSpace.h \ + Source/JavaScriptCore/heap/PassWeak.h \ Source/JavaScriptCore/heap/Strong.h \ + Source/JavaScriptCore/heap/StrongInlines.h \ + Source/JavaScriptCore/heap/UnconditionalFinalizer.h \ + Source/JavaScriptCore/heap/VTableSpectrum.cpp \ + Source/JavaScriptCore/heap/VTableSpectrum.h \ Source/JavaScriptCore/heap/Weak.h \ + Source/JavaScriptCore/heap/WeakBlock.cpp \ + Source/JavaScriptCore/heap/WeakBlock.h \ + Source/JavaScriptCore/heap/WeakHandleOwner.cpp \ + Source/JavaScriptCore/heap/WeakHandleOwner.h \ + Source/JavaScriptCore/heap/WeakImpl.h \ + Source/JavaScriptCore/heap/WeakSet.cpp \ + Source/JavaScriptCore/heap/WeakSet.h \ + Source/JavaScriptCore/heap/WeakSetInlines.h \ + Source/JavaScriptCore/heap/WeakReferenceHarvester.h \ + Source/JavaScriptCore/heap/WriteBarrierSupport.cpp \ + Source/JavaScriptCore/heap/WriteBarrierSupport.h \ Source/JavaScriptCore/config.h \ Source/JavaScriptCore/debugger/DebuggerActivation.cpp \ Source/JavaScriptCore/debugger/DebuggerActivation.h \ Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp \ Source/JavaScriptCore/debugger/DebuggerCallFrame.h \ Source/JavaScriptCore/debugger/Debugger.cpp \ + Source/JavaScriptCore/heap/MarkedAllocator.cpp \ + Source/JavaScriptCore/heap/MarkedAllocator.h \ Source/JavaScriptCore/debugger/Debugger.h \ Source/JavaScriptCore/ForwardingHeaders/JavaScriptCore/APICast.h \ Source/JavaScriptCore/ForwardingHeaders/JavaScriptCore/APIShims.h \ @@ -160,6 +308,8 @@ javascriptcore_sources += \ Source/JavaScriptCore/icu/unicode/utf_old.h \ Source/JavaScriptCore/icu/unicode/utypes.h \ Source/JavaScriptCore/icu/unicode/uversion.h \ + Source/JavaScriptCore/interpreter/AbstractPC.cpp \ + Source/JavaScriptCore/interpreter/AbstractPC.h \ Source/JavaScriptCore/interpreter/CachedCall.h \ Source/JavaScriptCore/interpreter/CallFrameClosure.h \ Source/JavaScriptCore/interpreter/CallFrame.cpp \ @@ -170,15 +320,22 @@ javascriptcore_sources += \ Source/JavaScriptCore/interpreter/RegisterFile.h \ Source/JavaScriptCore/interpreter/Register.h \ Source/JavaScriptCore/JavaScriptCorePrefix.h \ + Source/JavaScriptCore/jit/CompactJITCodeMap.h \ Source/JavaScriptCore/jit/ExecutableAllocator.cpp \ Source/JavaScriptCore/jit/ExecutableAllocator.h \ + Source/JavaScriptCore/jit/HostCallReturnValue.cpp \ + Source/JavaScriptCore/jit/HostCallReturnValue.h \ Source/JavaScriptCore/jit/JITArithmetic32_64.cpp \ Source/JavaScriptCore/jit/JITArithmetic.cpp \ Source/JavaScriptCore/jit/JITCall32_64.cpp \ Source/JavaScriptCore/jit/JITCall.cpp \ Source/JavaScriptCore/jit/JITCode.h \ + Source/JavaScriptCore/jit/JITCompilationEffort.h \ + Source/JavaScriptCore/jit/JITDriver.h \ Source/JavaScriptCore/jit/JIT.cpp \ Source/JavaScriptCore/jit/JIT.h \ + Source/JavaScriptCore/jit/JITExceptions.cpp \ + Source/JavaScriptCore/jit/JITExceptions.h \ Source/JavaScriptCore/jit/JITInlineMethods.h \ Source/JavaScriptCore/jit/JITOpcodes32_64.cpp \ Source/JavaScriptCore/jit/JITOpcodes.cpp \ @@ -187,15 +344,19 @@ javascriptcore_sources += \ Source/JavaScriptCore/jit/JITStubCall.h \ Source/JavaScriptCore/jit/JITStubs.cpp \ Source/JavaScriptCore/jit/JITStubs.h \ + Source/JavaScriptCore/jit/JITWriteBarrier.h \ Source/JavaScriptCore/jit/JSInterfaceJIT.h \ Source/JavaScriptCore/jit/SpecializedThunkJIT.h \ Source/JavaScriptCore/jit/ThunkGenerators.cpp \ Source/JavaScriptCore/jit/ThunkGenerators.h \ + Source/JavaScriptCore/llint/LLIntData.h \ + Source/JavaScriptCore/llint/LLIntEntrypoints.cpp \ + Source/JavaScriptCore/llint/LLIntEntrypoints.h \ + Source/JavaScriptCore/llint/LowLevelInterpreter.cpp \ + Source/JavaScriptCore/llint/LowLevelInterpreter.h \ Source/JavaScriptCore/os-win32/stdbool.h \ Source/JavaScriptCore/os-win32/stdint.h \ Source/JavaScriptCore/parser/ASTBuilder.h \ - Source/JavaScriptCore/parser/JSParser.cpp \ - Source/JavaScriptCore/parser/JSParser.h \ Source/JavaScriptCore/parser/Lexer.cpp \ Source/JavaScriptCore/parser/Lexer.h \ Source/JavaScriptCore/parser/NodeConstructors.h \ @@ -204,6 +365,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/parser/Nodes.h \ Source/JavaScriptCore/parser/ParserArena.cpp \ Source/JavaScriptCore/parser/ParserArena.h \ + Source/JavaScriptCore/parser/ParserTokens.h \ Source/JavaScriptCore/parser/Parser.cpp \ Source/JavaScriptCore/parser/Parser.h \ Source/JavaScriptCore/parser/ResultType.h \ @@ -231,6 +393,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/ArrayPrototype.cpp \ Source/JavaScriptCore/runtime/ArrayPrototype.h \ Source/JavaScriptCore/runtime/BatchedTransitionOptimizer.h \ + Source/JavaScriptCore/runtime/BigInteger.h \ Source/JavaScriptCore/runtime/BooleanConstructor.cpp \ Source/JavaScriptCore/runtime/BooleanConstructor.h \ Source/JavaScriptCore/runtime/BooleanObject.cpp \ @@ -241,8 +404,10 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/CallData.cpp \ Source/JavaScriptCore/runtime/CallData.h \ Source/JavaScriptCore/runtime/ClassInfo.h \ + Source/JavaScriptCore/runtime/CodeSpecializationKind.h \ Source/JavaScriptCore/runtime/CommonIdentifiers.cpp \ Source/JavaScriptCore/runtime/CommonIdentifiers.h \ + Source/JavaScriptCore/runtime/CommonSlowPaths.h \ Source/JavaScriptCore/runtime/Completion.cpp \ Source/JavaScriptCore/runtime/Completion.h \ Source/JavaScriptCore/runtime/ConstructData.cpp \ @@ -268,6 +433,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/ExceptionHelpers.h \ Source/JavaScriptCore/runtime/Executable.cpp \ Source/JavaScriptCore/runtime/Executable.h \ + Source/JavaScriptCore/runtime/ExecutionHarness.h \ Source/JavaScriptCore/runtime/FunctionConstructor.cpp \ Source/JavaScriptCore/runtime/FunctionConstructor.h \ Source/JavaScriptCore/runtime/FunctionPrototype.cpp \ @@ -282,32 +448,36 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/InitializeThreading.h \ Source/JavaScriptCore/runtime/InternalFunction.cpp \ Source/JavaScriptCore/runtime/InternalFunction.h \ + Source/JavaScriptCore/runtime/Intrinsic.h \ Source/JavaScriptCore/runtime/JSActivation.cpp \ Source/JavaScriptCore/runtime/JSActivation.h \ Source/JavaScriptCore/runtime/JSAPIValueWrapper.cpp \ Source/JavaScriptCore/runtime/JSAPIValueWrapper.h \ Source/JavaScriptCore/runtime/JSArray.cpp \ Source/JavaScriptCore/runtime/JSArray.h \ - Source/JavaScriptCore/runtime/JSByteArray.cpp \ - Source/JavaScriptCore/runtime/JSByteArray.h \ Source/JavaScriptCore/runtime/JSCell.cpp \ Source/JavaScriptCore/runtime/JSCell.h \ + Source/JavaScriptCore/runtime/JSDateMath.cpp \ + Source/JavaScriptCore/runtime/JSDateMath.h \ Source/JavaScriptCore/runtime/JSFunction.cpp \ Source/JavaScriptCore/runtime/JSFunction.h \ + Source/JavaScriptCore/runtime/JSBoundFunction.cpp \ + Source/JavaScriptCore/runtime/JSBoundFunction.h \ + Source/JavaScriptCore/runtime/JSExportMacros.h \ Source/JavaScriptCore/runtime/JSGlobalData.cpp \ Source/JavaScriptCore/runtime/JSGlobalData.h \ Source/JavaScriptCore/runtime/JSGlobalObject.cpp \ Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp \ Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h \ Source/JavaScriptCore/runtime/JSGlobalObject.h \ + Source/JavaScriptCore/runtime/JSGlobalThis.cpp \ + Source/JavaScriptCore/runtime/JSGlobalThis.h \ Source/JavaScriptCore/runtime/JSLock.cpp \ Source/JavaScriptCore/runtime/JSLock.h \ Source/JavaScriptCore/runtime/JSNotAnObject.cpp \ Source/JavaScriptCore/runtime/JSNotAnObject.h \ Source/JavaScriptCore/runtime/JSObject.cpp \ Source/JavaScriptCore/runtime/JSObject.h \ - Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.cpp \ - Source/JavaScriptCore/runtime/JSObjectWithGlobalObject.h \ Source/JavaScriptCore/runtime/JSONObject.cpp \ Source/JavaScriptCore/runtime/JSONObject.h \ Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp \ @@ -315,6 +485,8 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp \ Source/JavaScriptCore/runtime/JSStaticScopeObject.h \ Source/JavaScriptCore/runtime/JSStringBuilder.h \ + Source/JavaScriptCore/runtime/JSStringJoiner.cpp \ + Source/JavaScriptCore/runtime/JSStringJoiner.h \ Source/JavaScriptCore/runtime/JSString.cpp \ Source/JavaScriptCore/runtime/JSString.h \ Source/JavaScriptCore/runtime/JSType.h \ @@ -326,13 +498,14 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/JSVariableObject.h \ Source/JavaScriptCore/runtime/JSWrapperObject.cpp \ Source/JavaScriptCore/runtime/JSWrapperObject.h \ - Source/JavaScriptCore/runtime/JSZombie.h \ Source/JavaScriptCore/runtime/LiteralParser.cpp \ Source/JavaScriptCore/runtime/LiteralParser.h \ Source/JavaScriptCore/runtime/Lookup.cpp \ Source/JavaScriptCore/runtime/Lookup.h \ + Source/JavaScriptCore/runtime/MatchResult.h \ Source/JavaScriptCore/runtime/MathObject.cpp \ Source/JavaScriptCore/runtime/MathObject.h \ + Source/JavaScriptCore/runtime/MemoryStatistics.h \ Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp \ Source/JavaScriptCore/runtime/NativeErrorConstructor.h \ Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp \ @@ -350,6 +523,8 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/ObjectPrototype.h \ Source/JavaScriptCore/runtime/Operations.cpp \ Source/JavaScriptCore/runtime/Operations.h \ + Source/JavaScriptCore/runtime/Options.cpp \ + Source/JavaScriptCore/runtime/Options.h \ Source/JavaScriptCore/runtime/PropertyDescriptor.cpp \ Source/JavaScriptCore/runtime/PropertyDescriptor.h \ Source/JavaScriptCore/runtime/PropertyMapHashTable.h \ @@ -366,25 +541,28 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/RegExp.cpp \ Source/JavaScriptCore/runtime/RegExp.h \ Source/JavaScriptCore/runtime/RegExpKey.h \ + Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp \ Source/JavaScriptCore/runtime/RegExpMatchesArray.h \ + Source/JavaScriptCore/runtime/RegExpCachedResult.cpp \ + Source/JavaScriptCore/runtime/RegExpCachedResult.h \ Source/JavaScriptCore/runtime/RegExpObject.cpp \ Source/JavaScriptCore/runtime/RegExpObject.h \ Source/JavaScriptCore/runtime/RegExpPrototype.cpp \ Source/JavaScriptCore/runtime/RegExpPrototype.h \ - Source/JavaScriptCore/runtime/RopeImpl.cpp \ - Source/JavaScriptCore/runtime/RopeImpl.h \ + Source/JavaScriptCore/runtime/SamplingCounter.cpp \ + Source/JavaScriptCore/runtime/SamplingCounter.h \ Source/JavaScriptCore/runtime/ScopeChain.cpp \ Source/JavaScriptCore/runtime/ScopeChain.h \ Source/JavaScriptCore/runtime/ScopeChainMark.h \ Source/JavaScriptCore/runtime/SmallStrings.cpp \ Source/JavaScriptCore/runtime/SmallStrings.h \ + Source/JavaScriptCore/runtime/StorageBarrier.h \ Source/JavaScriptCore/runtime/StrictEvalActivation.cpp \ Source/JavaScriptCore/runtime/StrictEvalActivation.h \ Source/JavaScriptCore/runtime/StringConstructor.cpp \ Source/JavaScriptCore/runtime/StringConstructor.h \ Source/JavaScriptCore/runtime/StringObject.cpp \ Source/JavaScriptCore/runtime/StringObject.h \ - Source/JavaScriptCore/runtime/StringObjectThatMasqueradesAsUndefined.h \ Source/JavaScriptCore/runtime/StringPrototype.cpp \ Source/JavaScriptCore/runtime/StringPrototype.h \ Source/JavaScriptCore/runtime/StringRecursionChecker.cpp \ @@ -399,6 +577,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/TimeoutChecker.cpp \ Source/JavaScriptCore/runtime/TimeoutChecker.h \ Source/JavaScriptCore/runtime/Tracing.h \ + Source/JavaScriptCore/runtime/Uint16WithFraction.h \ Source/JavaScriptCore/runtime/UString.cpp \ Source/JavaScriptCore/runtime/UString.h \ Source/JavaScriptCore/runtime/UStringBuilder.h \ @@ -406,164 +585,15 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/WeakGCMap.h \ Source/JavaScriptCore/runtime/WeakRandom.h \ Source/JavaScriptCore/runtime/WriteBarrier.h \ - Source/JavaScriptCore/wtf/AlwaysInline.h \ - Source/JavaScriptCore/wtf/ASCIICType.h \ - Source/JavaScriptCore/wtf/Assertions.cpp \ - Source/JavaScriptCore/wtf/Assertions.h \ - Source/JavaScriptCore/wtf/Atomics.h \ - Source/JavaScriptCore/wtf/AVLTree.h \ - Source/JavaScriptCore/wtf/Bitmap.h \ - Source/JavaScriptCore/wtf/BlockStack.h \ - Source/JavaScriptCore/wtf/BloomFilter.h \ - Source/JavaScriptCore/wtf/BumpPointerAllocator.h \ - Source/JavaScriptCore/wtf/ByteArray.cpp \ - Source/JavaScriptCore/wtf/ByteArray.h \ - Source/JavaScriptCore/wtf/CrossThreadRefCounted.h \ - Source/JavaScriptCore/wtf/CryptographicallyRandomNumber.cpp \ - Source/JavaScriptCore/wtf/CryptographicallyRandomNumber.h \ - Source/JavaScriptCore/wtf/CurrentTime.cpp \ - Source/JavaScriptCore/wtf/CurrentTime.h \ - Source/JavaScriptCore/wtf/DateMath.cpp \ - Source/JavaScriptCore/wtf/DateMath.h \ - Source/JavaScriptCore/wtf/DecimalNumber.h \ - Source/JavaScriptCore/wtf/DecimalNumber.cpp \ - Source/JavaScriptCore/wtf/Decoder.h \ - Source/JavaScriptCore/wtf/Deque.h \ - Source/JavaScriptCore/wtf/DisallowCType.h \ - Source/JavaScriptCore/wtf/DoublyLinkedList.h \ - Source/JavaScriptCore/wtf/dtoa.cpp \ - Source/JavaScriptCore/wtf/dtoa.h \ - Source/JavaScriptCore/wtf/DynamicAnnotations.cpp \ - Source/JavaScriptCore/wtf/DynamicAnnotations.h \ - Source/JavaScriptCore/wtf/Encoder.h \ - Source/JavaScriptCore/wtf/FastAllocBase.h \ - Source/JavaScriptCore/wtf/FastMalloc.cpp \ - Source/JavaScriptCore/wtf/FastMalloc.h \ - Source/JavaScriptCore/wtf/FixedArray.h \ - Source/JavaScriptCore/wtf/Forward.h \ - Source/JavaScriptCore/wtf/GetPtr.h \ - Source/JavaScriptCore/wtf/gobject/GOwnPtr.cpp \ - Source/JavaScriptCore/wtf/gobject/GOwnPtr.h \ - Source/JavaScriptCore/wtf/gobject/GRefPtr.cpp \ - Source/JavaScriptCore/wtf/gobject/GRefPtr.h \ - Source/JavaScriptCore/wtf/gobject/GTypedefs.h \ - Source/JavaScriptCore/wtf/gtk/MainThreadGtk.cpp \ - Source/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp \ - Source/JavaScriptCore/wtf/HashCountedSet.h \ - Source/JavaScriptCore/wtf/HashFunctions.h \ - Source/JavaScriptCore/wtf/HashIterators.h \ - Source/JavaScriptCore/wtf/HashMap.h \ - Source/JavaScriptCore/wtf/HashSet.h \ - Source/JavaScriptCore/wtf/HashTable.cpp \ - Source/JavaScriptCore/wtf/HashTable.h \ - Source/JavaScriptCore/wtf/HashTraits.h \ - Source/JavaScriptCore/wtf/HexNumber.h \ - Source/JavaScriptCore/wtf/ListHashSet.h \ - Source/JavaScriptCore/wtf/ListRefPtr.h \ - Source/JavaScriptCore/wtf/Locker.h \ - Source/JavaScriptCore/wtf/MainThread.cpp \ - Source/JavaScriptCore/wtf/MainThread.h \ - Source/JavaScriptCore/wtf/MallocZoneSupport.h \ - Source/JavaScriptCore/wtf/MathExtras.h \ - Source/JavaScriptCore/wtf/MD5.cpp \ - Source/JavaScriptCore/wtf/MD5.h \ - Source/JavaScriptCore/wtf/MessageQueue.h \ - Source/JavaScriptCore/wtf/NonCopyingSort.h \ - Source/JavaScriptCore/wtf/Noncopyable.h \ - Source/JavaScriptCore/wtf/NotFound.h \ - Source/JavaScriptCore/wtf/NullPtr.h \ - Source/JavaScriptCore/wtf/OSAllocator.h \ - Source/JavaScriptCore/wtf/OSRandomSource.cpp \ - Source/JavaScriptCore/wtf/OSRandomSource.h \ - Source/JavaScriptCore/wtf/OwnArrayPtr.h \ - Source/JavaScriptCore/wtf/OwnFastMallocPtr.h \ - Source/JavaScriptCore/wtf/OwnPtrCommon.h \ - Source/JavaScriptCore/wtf/OwnPtr.h \ - Source/JavaScriptCore/wtf/PageAllocation.h \ - Source/JavaScriptCore/wtf/PageAllocationAligned.cpp \ - Source/JavaScriptCore/wtf/PageAllocationAligned.h \ - Source/JavaScriptCore/wtf/PageReservation.h \ - Source/JavaScriptCore/wtf/PageBlock.cpp \ - Source/JavaScriptCore/wtf/PageBlock.h \ - Source/JavaScriptCore/wtf/PassOwnArrayPtr.h \ - Source/JavaScriptCore/wtf/PassOwnPtr.h \ - Source/JavaScriptCore/wtf/PassRefPtr.h \ - Source/JavaScriptCore/wtf/PassTraits.h \ - Source/JavaScriptCore/wtf/ParallelJobs.h \ - Source/JavaScriptCore/wtf/ParallelJobsGeneric.cpp \ - Source/JavaScriptCore/wtf/ParallelJobsGeneric.h \ - Source/JavaScriptCore/wtf/ParallelJobsLibdispatch.h \ - Source/JavaScriptCore/wtf/ParallelJobsOpenMP.h \ - Source/JavaScriptCore/wtf/Platform.h \ - Source/JavaScriptCore/wtf/PossiblyNull.h \ - Source/JavaScriptCore/wtf/RandomNumber.cpp \ - Source/JavaScriptCore/wtf/RandomNumber.h \ - Source/JavaScriptCore/wtf/RandomNumberSeed.h \ - Source/JavaScriptCore/wtf/RefCounted.h \ - Source/JavaScriptCore/wtf/RefCountedLeakCounter.cpp \ - Source/JavaScriptCore/wtf/RefCountedLeakCounter.h \ - Source/JavaScriptCore/wtf/RefPtr.h \ - Source/JavaScriptCore/wtf/RefPtrHashMap.h \ - Source/JavaScriptCore/wtf/RetainPtr.h \ - Source/JavaScriptCore/wtf/SegmentedVector.h \ - Source/JavaScriptCore/wtf/SentinelLinkedList.h \ - Source/JavaScriptCore/wtf/SHA1.cpp \ - Source/JavaScriptCore/wtf/SHA1.h \ - Source/JavaScriptCore/wtf/SinglyLinkedList.h \ - Source/JavaScriptCore/wtf/StackBounds.cpp \ - Source/JavaScriptCore/wtf/StackBounds.h \ - Source/JavaScriptCore/wtf/StaticConstructors.h \ - Source/JavaScriptCore/wtf/StdLibExtras.h \ - Source/JavaScriptCore/wtf/StringExtras.h \ - Source/JavaScriptCore/wtf/StringHasher.h \ - Source/JavaScriptCore/wtf/TCPackedCache.h \ - Source/JavaScriptCore/wtf/TCPageMap.h \ - Source/JavaScriptCore/wtf/TCSpinLock.h \ - Source/JavaScriptCore/wtf/TCSystemAlloc.cpp \ - Source/JavaScriptCore/wtf/TCSystemAlloc.h \ - Source/JavaScriptCore/wtf/text/AtomicString.cpp \ - Source/JavaScriptCore/wtf/text/AtomicString.h \ - Source/JavaScriptCore/wtf/text/AtomicStringHash.h \ - Source/JavaScriptCore/wtf/text/AtomicStringImpl.h \ - Source/JavaScriptCore/wtf/text/CString.cpp \ - Source/JavaScriptCore/wtf/text/CString.h \ - Source/JavaScriptCore/wtf/text/StringBuffer.h \ - Source/JavaScriptCore/wtf/text/StringBuilder.cpp \ - Source/JavaScriptCore/wtf/text/StringBuilder.h \ - Source/JavaScriptCore/wtf/text/StringConcatenate.h \ - Source/JavaScriptCore/wtf/text/StringHash.h \ - Source/JavaScriptCore/wtf/text/StringImplBase.h \ - Source/JavaScriptCore/wtf/text/StringImpl.cpp \ - Source/JavaScriptCore/wtf/text/StringImpl.h \ - Source/JavaScriptCore/wtf/text/StringOperators.h \ - Source/JavaScriptCore/wtf/text/StringStatics.cpp \ - Source/JavaScriptCore/wtf/text/TextPosition.h \ - Source/JavaScriptCore/wtf/text/WTFString.cpp \ - Source/JavaScriptCore/wtf/text/WTFString.h \ - Source/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp \ - Source/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h \ - Source/JavaScriptCore/wtf/Threading.cpp \ - Source/JavaScriptCore/wtf/Threading.h \ - Source/JavaScriptCore/wtf/ThreadingPrimitives.h \ - Source/JavaScriptCore/wtf/ThreadingPthreads.cpp \ - Source/JavaScriptCore/wtf/ThreadSafeRefCounted.h \ - Source/JavaScriptCore/wtf/ThreadSpecific.h \ - Source/JavaScriptCore/wtf/TypeTraits.cpp \ - Source/JavaScriptCore/wtf/TypeTraits.h \ - Source/JavaScriptCore/wtf/unicode/CharacterNames.h \ - Source/JavaScriptCore/wtf/unicode/CollatorDefault.cpp \ - Source/JavaScriptCore/wtf/unicode/Collator.h \ - Source/JavaScriptCore/wtf/unicode/Unicode.h \ - Source/JavaScriptCore/wtf/unicode/UTF8.cpp \ - Source/JavaScriptCore/wtf/unicode/UTF8.h \ - Source/JavaScriptCore/wtf/UnusedParam.h \ - Source/JavaScriptCore/wtf/ValueCheck.h \ - Source/JavaScriptCore/wtf/Vector.h \ - Source/JavaScriptCore/wtf/VectorTraits.h \ - Source/JavaScriptCore/wtf/VMTags.h \ - Source/JavaScriptCore/wtf/WTFThreadData.cpp \ - Source/JavaScriptCore/wtf/WTFThreadData.h \ + Source/JavaScriptCore/tools/CodeProfile.cpp \ + Source/JavaScriptCore/tools/CodeProfile.h \ + Source/JavaScriptCore/tools/CodeProfiling.cpp \ + Source/JavaScriptCore/tools/CodeProfiling.h \ + Source/JavaScriptCore/tools/ProfileTreeNode.h \ + Source/JavaScriptCore/tools/TieredMMapArray.h \ Source/JavaScriptCore/yarr/Yarr.h \ + Source/JavaScriptCore/yarr/YarrCanonicalizeUCS2.cpp \ + Source/JavaScriptCore/yarr/YarrCanonicalizeUCS2.h \ Source/JavaScriptCore/yarr/YarrInterpreter.cpp \ Source/JavaScriptCore/yarr/YarrInterpreter.h \ Source/JavaScriptCore/yarr/YarrJIT.cpp \ @@ -575,35 +605,11 @@ javascriptcore_sources += \ Source/JavaScriptCore/yarr/YarrSyntaxChecker.h if TARGET_WIN32 -javascriptcore_sources += \ - Source/JavaScriptCore/heap/MarkStackWin.cpp \ - Source/JavaScriptCore/wtf/OSAllocatorWin.cpp else javascriptcore_sources += \ - Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp \ - Source/JavaScriptCore/heap/MarkStackPosix.cpp \ - Source/JavaScriptCore/wtf/OSAllocatorPosix.cpp + Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp endif -# ---- -# icu unicode backend -# ---- -if USE_ICU_UNICODE -javascriptcore_sources += \ - Source/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp \ - Source/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h -endif # USE_ICU_UNICODE - -# ---- -# glib unicode backend -# ---- -if USE_GLIB_UNICODE -javascriptcore_sources += \ - Source/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h \ - Source/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h \ - Source/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp -endif # USE_GLIB_UNICODE - # minidom Programs_minidom_SOURCES = \ Source/JavaScriptCore/API/tests/JSNode.c \ @@ -617,4 +623,5 @@ Programs_minidom_SOURCES = \ Source/JavaScriptCore/API/tests/minidom.c Programs_jsc_@WEBKITGTK_API_MAJOR_VERSION@_SOURCES = \ + Source/JavaScriptCore/JSCTypedArrayStubs.h \ Source/JavaScriptCore/jsc.cpp diff --git a/Info.plist b/Info.plist index a8ae5cc..3c0bf46 100644 --- a/Info.plist +++ b/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable ${PRODUCT_NAME} CFBundleGetInfoString - ${BUNDLE_VERSION}, Copyright 2003-2011 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. + ${BUNDLE_VERSION}, Copyright 2003-2012 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. CFBundleIdentifier com.apple.${PRODUCT_NAME} CFBundleInfoDictionaryVersion diff --git a/JSCTypedArrayStubs.h b/JSCTypedArrayStubs.h new file mode 100644 index 0000000..ca40301 --- /dev/null +++ b/JSCTypedArrayStubs.h @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2012 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 JSCTypedArrayStubs_h +#define JSCTypedArrayStubs_h + +#include "JSObject.h" +#include "ObjectPrototype.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace JSC { + +#define TYPED_ARRAY(name, type) \ +class JS##name##Array : public JSNonFinalObject { \ +public: \ + typedef JSNonFinalObject Base; \ + static JS##name##Array* create(JSC::Structure* structure, JSGlobalObject* globalObject, PassRefPtr impl) \ + { \ + JS##name##Array* ptr = new (NotNull, JSC::allocateCell(globalObject->globalData().heap)) JS##name##Array(structure, globalObject, impl); \ + ptr->finishCreation(globalObject->globalData()); \ + return ptr; \ + }\ +\ + static bool getOwnPropertySlot(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);\ + static bool getOwnPropertyDescriptor(JSC::JSObject*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&);\ + static bool getOwnPropertySlotByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);\ + static void put(JSC::JSCell*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);\ + static void putByIndex(JSC::JSCell*, JSC::ExecState*, unsigned propertyName, JSC::JSValue, bool);\ + static const JSC::ClassInfo s_info;\ +\ + static JSC::Structure* createStructure(JSC::JSGlobalData& globalData, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)\ + {\ + return JSC::Structure::create(globalData, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), &s_info);\ + }\ +\ + static void getOwnPropertyNames(JSC::JSObject*, JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties);\ + static JSC::JSValue getConstructor(JSC::ExecState*, JSC::JSGlobalObject*);\ +\ + static const JSC::TypedArrayType TypedArrayStorageType = JSC::TypedArray##name;\ + uint32_t m_storageLength;\ + type* m_storage;\ + RefPtr m_impl;\ +protected:\ + JS##name##Array(JSC::Structure*, JSGlobalObject*, PassRefPtr);\ + void finishCreation(JSC::JSGlobalData&);\ + static const unsigned StructureFlags = JSC::OverridesGetPropertyNames | JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;\ + JSC::JSValue getByIndex(JSC::ExecState*, unsigned index);\ + void indexSetter(JSC::ExecState*, unsigned index, JSC::JSValue);\ +};\ +\ +const ClassInfo JS##name##Array::s_info = { #name "Array" , &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JS##name##Array) };\ +\ +JS##name##Array::JS##name##Array(Structure* structure, JSGlobalObject* globalObject, PassRefPtr impl)\ + : Base(globalObject->globalData(), structure)\ + , m_impl(impl)\ +{\ +}\ +\ +void JS##name##Array::finishCreation(JSGlobalData& globalData)\ +{\ + Base::finishCreation(globalData);\ + TypedArrayDescriptor descriptor(&JS##name##Array::s_info, OBJECT_OFFSETOF(JS##name##Array, m_storage), OBJECT_OFFSETOF(JS##name##Array, m_storageLength));\ + globalData.registerTypedArrayDescriptor(m_impl.get(), descriptor);\ + m_storage = m_impl->data();\ + m_storageLength = m_impl->length();\ + putDirect(globalData, globalData.propertyNames->length, jsNumber(m_storageLength), DontDelete | ReadOnly | DontEnum); \ + ASSERT(inherits(&s_info));\ +}\ +\ +bool JS##name##Array::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)\ +{\ + JS##name##Array* thisObject = jsCast(cell);\ + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);\ + bool ok;\ + unsigned index = propertyName.toUInt32(ok);\ + if (ok && index < thisObject->m_storageLength) {\ + slot.setValue(thisObject->getByIndex(exec, index));\ + return true;\ + }\ + return Base::getOwnPropertySlot(cell, exec, propertyName, slot);\ +}\ +\ +bool JS##name##Array::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)\ +{\ + JS##name##Array* thisObject = jsCast(object);\ + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);\ + bool ok;\ + unsigned index = propertyName.toUInt32(ok);\ + if (ok && index < thisObject->m_storageLength) {\ + descriptor.setDescriptor(thisObject->getByIndex(exec, index), DontDelete);\ + return true;\ + }\ + return Base::getOwnPropertyDescriptor(object, exec, propertyName, descriptor);\ +}\ +\ +bool JS##name##Array::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot)\ +{\ + JS##name##Array* thisObject = jsCast(cell);\ + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);\ + if (propertyName < thisObject->m_storageLength) {\ + slot.setValue(thisObject->getByIndex(exec, propertyName));\ + return true;\ + }\ + return thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, Identifier::from(exec, propertyName), slot);\ +}\ +\ +void JS##name##Array::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)\ +{\ + JS##name##Array* thisObject = jsCast(cell);\ + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);\ + bool ok;\ + unsigned index = propertyName.toUInt32(ok);\ + if (ok) {\ + thisObject->indexSetter(exec, index, value);\ + return;\ + }\ + Base::put(thisObject, exec, propertyName, value, slot);\ +}\ +\ +void JS##name##Array::indexSetter(JSC::ExecState* exec, unsigned index, JSC::JSValue value) \ +{\ + m_impl->set(index, value.toNumber(exec));\ +}\ +\ +void JS##name##Array::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool)\ +{\ + JS##name##Array* thisObject = jsCast(cell);\ + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);\ + thisObject->indexSetter(exec, propertyName, value);\ + return;\ +}\ +\ +void JS##name##Array::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)\ +{\ + JS##name##Array* thisObject = jsCast(object);\ + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);\ + for (unsigned i = 0; i < thisObject->m_storageLength; ++i)\ + propertyNames.add(Identifier::from(exec, i));\ + Base::getOwnPropertyNames(thisObject, exec, propertyNames, mode);\ +}\ +\ +JSValue JS##name##Array::getByIndex(ExecState*, unsigned index)\ +{\ + ASSERT_GC_OBJECT_INHERITS(this, &s_info);\ + type result = m_impl->item(index);\ + if (isnan((double)result))\ + return jsNaN();\ + return JSValue(result);\ +}\ +static EncodedJSValue JSC_HOST_CALL constructJS##name##Array(ExecState* callFrame) { \ + if (callFrame->argumentCount() < 1) \ + return JSValue::encode(jsUndefined()); \ + int32_t length = callFrame->argument(0).toInt32(callFrame); \ + if (length < 0) \ + return JSValue::encode(jsUndefined()); \ + Structure* structure = JS##name##Array::createStructure(callFrame->globalData(), callFrame->lexicalGlobalObject(), callFrame->lexicalGlobalObject()->objectPrototype()); \ + return JSValue::encode(JS##name##Array::create(structure, callFrame->lexicalGlobalObject(), name##Array::create(length)));\ +} + +TYPED_ARRAY(Uint8, uint8_t); +TYPED_ARRAY(Uint8Clamped, uint8_t); +TYPED_ARRAY(Uint16, uint16_t); +TYPED_ARRAY(Uint32, uint32_t); +TYPED_ARRAY(Int8, int8_t); +TYPED_ARRAY(Int16, int16_t); +TYPED_ARRAY(Int32, int32_t); +TYPED_ARRAY(Float32, float); +TYPED_ARRAY(Float64, double); + +} + +#endif diff --git a/JavaScriptCore.JSVALUE32_64only.exp b/JavaScriptCore.JSVALUE32_64only.exp deleted file mode 100644 index f9eee85..0000000 --- a/JavaScriptCore.JSVALUE32_64only.exp +++ /dev/null @@ -1 +0,0 @@ -__ZN3JSC10JSFunctionC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEiRKNS_10IdentifierEPFxS2_E diff --git a/JavaScriptCore.JSVALUE64only.exp b/JavaScriptCore.JSVALUE64only.exp deleted file mode 100644 index eaa9f51..0000000 --- a/JavaScriptCore.JSVALUE64only.exp +++ /dev/null @@ -1 +0,0 @@ -__ZN3JSC10JSFunctionC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEiRKNS_10IdentifierEPFPvS2_E diff --git a/JavaScriptCore.exp b/JavaScriptCore.exp deleted file mode 100644 index 9c88059..0000000 --- a/JavaScriptCore.exp +++ /dev/null @@ -1,635 +0,0 @@ -_JSCheckScriptSyntax -_JSClassCreate -_JSClassRelease -_JSClassRetain -_JSContextGetGlobalContext -_JSContextGetGlobalObject -_JSContextGetGroup -_JSContextGroupCreate -_JSContextGroupRelease -_JSContextGroupRetain -_JSContextCreateBacktrace -_JSEndProfiling -_JSEvaluateScript -_JSGarbageCollect -_JSGlobalContextCreate -_JSGlobalContextCreateInGroup -_JSGlobalContextRelease -_JSGlobalContextRetain -_JSObjectCallAsConstructor -_JSObjectCallAsFunction -_JSObjectCopyPropertyNames -_JSObjectDeletePrivateProperty -_JSObjectDeleteProperty -_JSObjectGetPrivate -_JSObjectGetPrivateProperty -_JSObjectGetProperty -_JSObjectGetPropertyAtIndex -_JSObjectGetPrototype -_JSObjectHasProperty -_JSObjectIsConstructor -_JSObjectIsFunction -_JSObjectMake -_JSObjectMakeArray -_JSObjectMakeConstructor -_JSObjectMakeDate -_JSObjectMakeError -_JSObjectMakeFunction -_JSObjectMakeFunctionWithCallback -_JSObjectMakeRegExp -_JSObjectSetPrivate -_JSObjectSetPrivateProperty -_JSObjectSetProperty -_JSObjectSetPropertyAtIndex -_JSObjectSetPrototype -_JSPropertyNameAccumulatorAddName -_JSPropertyNameArrayGetCount -_JSPropertyNameArrayGetNameAtIndex -_JSPropertyNameArrayRelease -_JSPropertyNameArrayRetain -_JSReportExtraMemoryCost -_JSStartProfiling -_JSStringCopyCFString -_JSStringCreateWithCFString -_JSStringCreateWithCharacters -_JSStringCreateWithUTF8CString -_JSStringGetCharactersPtr -_JSStringGetLength -_JSStringGetMaximumUTF8CStringSize -_JSStringGetUTF8CString -_JSStringIsEqual -_JSStringIsEqualToUTF8CString -_JSStringRelease -_JSStringRetain -_JSValueCreateJSONString -_JSValueGetType -_JSValueIsBoolean -_JSValueIsEqual -_JSValueIsInstanceOfConstructor -_JSValueIsNull -_JSValueIsNumber -_JSValueIsObject -_JSValueIsObjectOfClass -_JSValueIsStrictEqual -_JSValueIsString -_JSValueIsUndefined -_JSValueMakeBoolean -_JSValueMakeFromJSONString -_JSValueMakeNull -_JSValueMakeNumber -_JSValueMakeString -_JSValueMakeUndefined -_JSValueProtect -_JSValueToBoolean -_JSValueToNumber -_JSValueToObject -_JSValueToStringCopy -_JSValueUnprotect -_JSWeakObjectMapClear -_JSWeakObjectMapCreate -_JSWeakObjectMapGet -_JSWeakObjectMapRemove -_JSWeakObjectMapSet -_WTFLog -_WTFLogVerbose -_WTFReportArgumentAssertionFailure -_WTFReportAssertionFailure -_WTFReportAssertionFailureWithMessage -_WTFReportBacktrace -_WTFReportError -_WTFReportFatalError -_WebCoreWebThreadIsLockedOrDisabled -__ZN14OpaqueJSString6createERKN3JSC7UStringE -__ZN3JSC10HandleHeap12writeBarrierEPNS_7JSValueERKS1_ -__ZN3JSC10HandleHeap4growEv -__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPN3WTF10StringImplE -__ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPN3WTF10StringImplE -__ZN3JSC10Identifier27checkCurrentIdentifierTableEPNS_12JSGlobalDataE -__ZN3JSC10Identifier27checkCurrentIdentifierTableEPNS_9ExecStateE -__ZN3JSC10Identifier3addEPNS_9ExecStateEPKc -__ZN3JSC10Identifier4fromEPNS_9ExecStateEi -__ZN3JSC10Identifier4fromEPNS_9ExecStateEj -__ZN3JSC10Identifier5equalEPKN3WTF10StringImplEPKc -__ZN3JSC10Identifier8toUInt32ERKNS_7UStringERb -__ZN3JSC10JSFunction4nameEPNS_9ExecStateE -__ZN3JSC10JSFunction6s_infoE -__ZN3JSC10throwErrorEPNS_9ExecStateENS_7JSValueE -__ZN3JSC10throwErrorEPNS_9ExecStateEPNS_8JSObjectE -__ZN3JSC11JSByteArray13s_defaultInfoE -__ZN3JSC11JSByteArray15createStructureERNS_12JSGlobalDataENS_7JSValueEPKNS_9ClassInfoE -__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEPNS_9StructureEPN3WTF9ByteArrayE -__ZN3JSC11MarkedSpace21allocateFromSizeClassERNS0_9SizeClassE -__ZN3JSC11ParserArena5resetEv -__ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE -__ZN3JSC11createErrorEPNS_9ExecStateERKNS_7UStringE -__ZN3JSC11regExpFlagsERKNS_7UStringE -__ZN3JSC12DateInstance6s_infoE -__ZN3JSC12DateInstanceC1EPNS_9ExecStateEPNS_9StructureEd -__ZN3JSC12JSGlobalData10ClientDataD2Ev -__ZN3JSC12JSGlobalData11jsArrayVPtrE -__ZN3JSC12JSGlobalData12createLeakedENS_15ThreadStackTypeE -__ZN3JSC12JSGlobalData12jsStringVPtrE -__ZN3JSC12JSGlobalData12stopSamplingEv -__ZN3JSC12JSGlobalData13startSamplingEv -__ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE -__ZN3JSC12JSGlobalData14resetDateCacheEv -__ZN3JSC12JSGlobalData14sharedInstanceEv -__ZN3JSC12JSGlobalData15dumpRegExpTraceEv -__ZN3JSC12JSGlobalData22clearBuiltinStructuresEv -#ifndef NDEBUG -__ZN3JSC12JSGlobalData23releaseExecutableMemoryEv -#endif -__ZN3JSC12JSGlobalData6createENS_15ThreadStackTypeE -__ZN3JSC12JSGlobalDataD1Ev -__ZN3JSC12RegExpObject6s_infoE -__ZN3JSC12RegExpObjectC1EPNS_14JSGlobalObjectEPNS_9StructureEPNS_6RegExpE -__ZN3JSC12SamplingTool5setupEv -__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE -__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh -__ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE -__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE -__ZN3JSC12StringObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE -__ZN3JSC12StringObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE -__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE -__ZN3JSC12StringObject6s_infoE -__ZN3JSC12StringObjectC2EPNS_9ExecStateEPNS_9StructureERKNS_7UStringE -__ZN3JSC12nonInlineNaNEv -__ZN3JSC13SamplingFlags4stopEv -__ZN3JSC13SamplingFlags5startEv -__ZN3JSC13SamplingFlags7s_flagsE -__ZN3JSC13StatementNode6setLocEii -__ZN3JSC14JSGlobalObject10globalExecEv -__ZN3JSC14JSGlobalObject11disableEvalEv -__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj -__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj -__ZN3JSC14JSGlobalObject13visitChildrenERNS_9MarkStackE -__ZN3JSC14JSGlobalObject16addStaticGlobalsEPNS0_18GlobalPropertyInfoEi -__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj -__ZN3JSC14JSGlobalObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC14JSGlobalObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE -__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE -__ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE -__ZN3JSC14JSGlobalObject6s_infoE -__ZN3JSC14JSGlobalObjectD2Ev -__ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE -__ZN3JSC14MachineThreads16addCurrentThreadEv -__ZN3JSC14MachineThreads29makeUsableFromMultipleThreadsEv -__ZN3JSC14SamplingThread4stopEv -__ZN3JSC14SamplingThread5startEj -__ZN3JSC14ScopeChainNode6s_infoE -__ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE -__ZN3JSC14TimeoutChecker5resetEv -__ZN3JSC14throwTypeErrorEPNS_9ExecStateE -__ZN3JSC15JSWrapperObject13visitChildrenERNS_9MarkStackE -__ZN3JSC15WeakHandleOwner26isReachableFromOpaqueRootsENS_6HandleINS_7UnknownEEEPvRNS_9MarkStackE -__ZN3JSC15WeakHandleOwner8finalizeENS_6HandleINS_7UnknownEEEPv -__ZN3JSC15WeakHandleOwnerD2Ev -__ZN3JSC15createTypeErrorEPNS_9ExecStateERKNS_7UStringE -__ZN3JSC16InternalFunction12vtableAnchorEv -__ZN3JSC16InternalFunction4nameEPNS_9ExecStateE -__ZN3JSC16InternalFunction6s_infoE -__ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEPNS_14JSGlobalObjectEPNS_9StructureERKNS_10IdentifierE -__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE -__ZN3JSC16JSVariableObject14symbolTableGetERKNS_10IdentifierERNS_18PropertyDescriptorE -__ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE -__ZN3JSC16createRangeErrorEPNS_9ExecStateERKNS_7UStringE -__ZN3JSC16slowValidateCellEPNS_14JSGlobalObjectE -__ZN3JSC16slowValidateCellEPNS_6JSCellE -__ZN3JSC16throwSyntaxErrorEPNS_9ExecStateE -__ZN3JSC17BytecodeGenerator21setDumpsGeneratedCodeEb -__ZN3JSC17PropertyNameArray3addEPN3WTF10StringImplE -__ZN3JSC17constructFunctionEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi -__ZN3JSC17createSyntaxErrorEPNS_9ExecStateERKNS_7UStringE -__ZN3JSC18DebuggerActivationC1ERNS_12JSGlobalDataEPNS_8JSObjectE -__ZN3JSC18PropertyDescriptor11setWritableEb -__ZN3JSC18PropertyDescriptor12setUndefinedEv -__ZN3JSC18PropertyDescriptor13setDescriptorENS_7JSValueEj -__ZN3JSC18PropertyDescriptor13setEnumerableEb -__ZN3JSC18PropertyDescriptor15setConfigurableEb -__ZN3JSC18PropertyDescriptor17defaultAttributesE -__ZN3JSC18PropertyDescriptor21setAccessorDescriptorENS_7JSValueES1_j -__ZN3JSC18PropertyDescriptor9setGetterENS_7JSValueE -__ZN3JSC18PropertyDescriptor9setSetterENS_7JSValueE -__ZN3JSC19SourceProviderCache5clearEv -__ZN3JSC19SourceProviderCacheD1Ev -__ZN3JSC19initializeThreadingEv -__ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE -__ZN3JSC20createReferenceErrorEPNS_9ExecStateERKNS_7UStringE -__ZN3JSC22globalMemoryStatisticsEv -__ZN3JSC22objectConstructorTableE -__ZN3JSC23AbstractSamplingCounter4dumpEv -__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE -__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC24DynamicGlobalObjectScopeC1ERNS_12JSGlobalDataEPNS_14JSGlobalObjectE -__ZN3JSC24JSObjectWithGlobalObjectC2EPNS_14JSGlobalObjectEPNS_9StructureE -__ZN3JSC24JSObjectWithGlobalObjectC2ERNS_12JSGlobalDataEPNS_14JSGlobalObjectEPNS_9StructureE -__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE -__ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE -__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE -__ZN3JSC3NaNE -__ZN3JSC41constructFunctionSkippingEvalEnabledCheckEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi -__ZN3JSC4Heap16activityCallbackEv -__ZN3JSC4Heap16allocateSlowCaseEm -__ZN3JSC4Heap16objectTypeCountsEv -__ZN3JSC4Heap17collectAllGarbageEv -__ZN3JSC4Heap17globalObjectCountEv -__ZN3JSC4Heap19setActivityCallbackEN3WTF10PassOwnPtrINS_18GCActivityCallbackEEE -__ZN3JSC4Heap20protectedObjectCountEv -__ZN3JSC4Heap25protectedObjectTypeCountsEv -__ZN3JSC4Heap26protectedGlobalObjectCountEv -__ZN3JSC4Heap29reportExtraMemoryCostSlowCaseEm -__ZN3JSC4Heap7destroyEv -__ZN3JSC4Heap7protectENS_7JSValueE -__ZN3JSC4Heap9unprotectENS_7JSValueE -__ZN3JSC4Yarr11YarrPatternC1ERKNS_7UStringEbbPPKc -__ZN3JSC4Yarr11byteCompileERNS0_11YarrPatternEPN3WTF20BumpPointerAllocatorE -__ZN3JSC4Yarr9interpretEPNS0_15BytecodePatternEPKtjjPi -__ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE -__ZN3JSC6JSCell11getCallDataERNS_8CallDataE -__ZN3JSC6JSCell11getJSNumberEv -__ZN3JSC6JSCell14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE -__ZN3JSC6JSCell14deletePropertyEPNS_9ExecStateEj -__ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE -__ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE -__ZN3JSC6JSCell18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE -__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE -__ZN3JSC6JSCell3putEPNS_9ExecStateEjNS_7JSValueE -__ZN3JSC6JSCell9getObjectEv -__ZN3JSC6JSLock12DropAllLocksC1ENS_14JSLockBehaviorE -__ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE -__ZN3JSC6JSLock12DropAllLocksD1Ev -__ZN3JSC6JSLock26currentThreadIsHoldingLockEv -__ZN3JSC6JSLock4lockENS_14JSLockBehaviorE -__ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE -__ZN3JSC6JSLock9lockCountEv -__ZN3JSC6JSLockC1EPNS_9ExecStateE -__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringENS_11RegExpFlagsE -__ZN3JSC6RegExpD1Ev -__ZN3JSC7JSArray13visitChildrenERNS_9MarkStackE -__ZN3JSC7JSArray15setSubclassDataEPv -__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE -__ZN3JSC7JSArray6s_infoE -__ZN3JSC7JSArray9setLengthEj -__ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureE -__ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureERKNS_7ArgListE -__ZN3JSC7JSArrayC2ERNS_12JSGlobalDataEPNS_9StructureE -__ZN3JSC7JSArrayD2Ev -__ZN3JSC7JSValue13isValidCalleeEv -__ZN3JSC7Profile10restoreAllEv -__ZN3JSC7Profile5focusEPKNS_11ProfileNodeE -__ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE -__ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE -__ZN3JSC7UString6numberEd -__ZN3JSC7UString6numberEi -__ZN3JSC7UString6numberEj -__ZN3JSC7UString6numberEl -__ZN3JSC7UStringC1EPKc -__ZN3JSC7UStringC1EPKcj -__ZN3JSC7UStringC1EPKt -__ZN3JSC7UStringC1EPKtj -__ZN3JSC7toInt32Ed -__ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12JSGlobalDataE -__ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE -__ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE -__ZN3JSC8DebuggerD2Ev -__ZN3JSC8JSObject11hasInstanceEPNS_9ExecStateENS_7JSValueES3_ -__ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_j -__ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_j -__ZN3JSC8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE -__ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE -__ZN3JSC8JSObject13visitChildrenERNS_9MarkStackE -__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE -__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj -__ZN3JSC8JSObject15unwrappedObjectEv -__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE -__ZN3JSC8JSObject17defineOwnPropertyEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorEb -__ZN3JSC8JSObject17preventExtensionsERNS_12JSGlobalDataE -__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_10JSFunctionEj -__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj -__ZN3JSC8JSObject17putWithAttributesEPNS_12JSGlobalDataERKNS_10IdentifierENS_7JSValueEj -__ZN3JSC8JSObject17putWithAttributesEPNS_12JSGlobalDataERKNS_10IdentifierENS_7JSValueEjbRNS_15PutPropertySlotE -__ZN3JSC8JSObject17putWithAttributesEPNS_12JSGlobalDataEjNS_7JSValueEj -__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj -__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEjbRNS_15PutPropertySlotE -__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateEjNS_7JSValueEj -__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE -__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE -__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE -__ZN3JSC8JSObject21getPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE -__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_16WriteBarrierBaseINS_7UnknownEEE -__ZN3JSC8JSObject23allocatePropertyStorageEmm -__ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE -__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE -__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE -__ZN3JSC8JSObject6s_infoE -__ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE -__ZN3JSC8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE -__ZN3JSC8Profiler8profilerEv -__ZN3JSC8evaluateEPNS_9ExecStateEPNS_14ScopeChainNodeERKNS_10SourceCodeENS_7JSValueE -__ZN3JSC8isZombieEPKNS_6JSCellE -__ZN3JSC9CodeBlockD1Ev -__ZN3JSC9CodeBlockD2Ev -__ZN3JSC9MarkStack10s_pageSizeE -__ZN3JSC9MarkStack18initializePagesizeEv -__ZN3JSC9Structure21addPropertyTransitionERNS_12JSGlobalDataEPS0_RKNS_10IdentifierEjPNS_6JSCellERm -__ZN3JSC9Structure22materializePropertyMapERNS_12JSGlobalDataE -__ZN3JSC9Structure25changePrototypeTransitionERNS_12JSGlobalDataEPS0_NS_7JSValueE -__ZN3JSC9Structure27despecifyDictionaryFunctionERNS_12JSGlobalDataERKNS_10IdentifierE -__ZN3JSC9Structure27despecifyFunctionTransitionERNS_12JSGlobalDataEPS0_RKNS_10IdentifierE -__ZN3JSC9Structure28addPropertyWithoutTransitionERNS_12JSGlobalDataERKNS_10IdentifierEjPNS_6JSCellE -__ZN3JSC9Structure3getERNS_12JSGlobalDataEPN3WTF10StringImplERjRPNS_6JSCellE -__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm -__ZN3JSC9Structure6s_infoE -__ZN3JSC9StructureC1ERNS_12JSGlobalDataENS_7JSValueERKNS_8TypeInfoEjPKNS_9ClassInfoE -__ZN3JSC9StructureD1Ev -__ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE -__ZN3JSCeqERKNS_7UStringEPKc -__ZN3JSCgtERKNS_7UStringES2_ -__ZN3JSCltERKNS_7UStringES2_ -__ZN3WTF10StringImpl11reverseFindEPS0_j -__ZN3WTF10StringImpl11reverseFindEtj -__ZN3WTF10StringImpl12sharedBufferEv -__ZN3WTF10StringImpl16findIgnoringCaseEPKcj -__ZN3WTF10StringImpl16findIgnoringCaseEPS0_j -__ZN3WTF10StringImpl18simplifyWhiteSpaceEv -__ZN3WTF10StringImpl19characterStartingAtEj -__ZN3WTF10StringImpl19createUninitializedEjRPt -__ZN3WTF10StringImpl22containsOnlyWhitespaceEv -__ZN3WTF10StringImpl23defaultWritingDirectionEPb -__ZN3WTF10StringImpl23reverseFindIgnoringCaseEPS0_j -__ZN3WTF10StringImpl37createStrippingNullCharactersSlowCaseEPKtj -__ZN3WTF10StringImpl4findEPFbtEj -__ZN3WTF10StringImpl4findEPKcj -__ZN3WTF10StringImpl4findEPS0_j -__ZN3WTF10StringImpl4findEtj -__ZN3WTF10StringImpl5adoptERNS_12StringBufferE -__ZN3WTF10StringImpl5emptyEv -__ZN3WTF10StringImpl5lowerEv -__ZN3WTF10StringImpl5toIntEPb -__ZN3WTF10StringImpl5upperEv -__ZN3WTF10StringImpl6createEPKc -__ZN3WTF10StringImpl6createEPKcj -__ZN3WTF10StringImpl6createEPKtj -__ZN3WTF10StringImpl6secureEtNS0_21LastCharacterBehaviorE -__ZN3WTF10StringImpl7replaceEPS0_S1_ -__ZN3WTF10StringImpl7replaceEjjPS0_ -__ZN3WTF10StringImpl7replaceEtPS0_ -__ZN3WTF10StringImpl7replaceEtt -__ZN3WTF10StringImpl8endsWithEPS0_b -__ZN3WTF10StringImpl9substringEjj -__ZN3WTF10StringImplD1Ev -__ZN3WTF10fastCallocEmm -__ZN3WTF10fastMallocEm -__ZN3WTF10fastStrDupEPKc -__ZN3WTF11OSAllocator16reserveAndCommitEmNS0_5UsageEbbb -__ZN3WTF11OSAllocator18releaseDecommittedEPvm -__ZN3WTF11commentAtomE -__ZN3WTF11currentTimeEv -__ZN3WTF11dtoaRoundDPEPcdiRbRiRj -__ZN3WTF11dtoaRoundSFEPcdiRbRiRj -__ZN3WTF11emptyStringEv -__ZN3WTF11fastReallocEPvm -__ZN3WTF12AtomicString11addSlowCaseEPNS_10StringImplE -__ZN3WTF12AtomicString16fromUTF8InternalEPKcS2_ -__ZN3WTF12AtomicString3addEPKc -__ZN3WTF12AtomicString3addEPKt -__ZN3WTF12AtomicString3addEPKtj -__ZN3WTF12AtomicString3addEPKtjj -__ZN3WTF12AtomicString4findEPKtjj -__ZN3WTF12AtomicString4initEv -__ZN3WTF12createThreadEPFPvS0_ES0_ -__ZN3WTF12createThreadEPFPvS0_ES0_PKc -__ZN3WTF12detachThreadEj -__ZN3WTF12isMainThreadEv -__ZN3WTF12randomNumberEv -__ZN3WTF13StringBuilder11reifyStringEv -__ZN3WTF13StringBuilder11shrinkToFitEv -__ZN3WTF13StringBuilder15reserveCapacityEj -__ZN3WTF13StringBuilder6appendEPKcj -__ZN3WTF13StringBuilder6appendEPKtj -__ZN3WTF13StringBuilder6resizeEj -__ZN3WTF13WTFThreadData10staticDataE -__ZN3WTF13WTFThreadDataC1Ev -__ZN3WTF13WTFThreadDataD1Ev -__ZN3WTF13currentThreadEv -__ZN3WTF13tryFastCallocEmm -__ZN3WTF13tryFastMallocEm -__ZN3WTF14fastMallocSizeEPKv -__ZN3WTF14numberToStringEdPt -__ZN3WTF14tryFastReallocEPvm -__ZN3WTF15ThreadCondition4waitERNS_5MutexE -__ZN3WTF15ThreadCondition6signalEv -__ZN3WTF15ThreadCondition9broadcastEv -__ZN3WTF15ThreadCondition9timedWaitERNS_5MutexEd -__ZN3WTF15ThreadConditionC1Ev -__ZN3WTF15ThreadConditionD1Ev -__ZN3WTF15charactersToIntEPKtmPb -__ZN3WTF16callOnMainThreadEPFvPvES0_ -__ZN3WTF16codePointCompareERKNS_6StringES2_ -__ZN3WTF16fastZeroedMallocEm -__ZN3WTF17charactersToFloatEPKtmPbS2_ -__ZN3WTF17equalIgnoringCaseEPKtPKcj -__ZN3WTF17equalIgnoringCaseEPNS_10StringImplEPKc -__ZN3WTF17equalIgnoringCaseEPNS_10StringImplES1_ -__ZN3WTF18calculateDSTOffsetEdd -__ZN3WTF18calculateUTCOffsetEv -__ZN3WTF18charactersToDoubleEPKtmPbS2_ -__ZN3WTF18dateToDaysFrom1970Eiii -__ZN3WTF18monthFromDayInYearEib -__ZN3WTF19initializeThreadingEv -__ZN3WTF20equalIgnoringNullityEPNS_10StringImplES1_ -__ZN3WTF20fastMallocStatisticsEv -__ZN3WTF20initializeMainThreadEv -__ZN3WTF21RefCountedLeakCounter16suppressMessagesEPKc -__ZN3WTF21RefCountedLeakCounter24cancelMessageSuppressionEPKc -__ZN3WTF21RefCountedLeakCounter9decrementEv -__ZN3WTF21RefCountedLeakCounter9incrementEv -__ZN3WTF21RefCountedLeakCounterC1EPKc -__ZN3WTF21RefCountedLeakCounterD1Ev -__ZN3WTF21charactersToIntStrictEPKtmPbi -__ZN3WTF22cancelCallOnMainThreadEPFvPvES0_ -__ZN3WTF22charactersToUIntStrictEPKtmPbi -__ZN3WTF23callOnMainThreadAndWaitEPFvPvES0_ -__ZN3WTF23dayInMonthFromDayInYearEib -__ZN3WTF23waitForThreadCompletionEjPPv -__ZN3WTF27releaseFastMallocFreeMemoryEv -__ZN3WTF28setMainThreadCallbacksPausedEb -__ZN3WTF29cryptographicallyRandomNumberEv -__ZN3WTF29cryptographicallyRandomValuesEPvm -__ZN3WTF36lockAtomicallyInitializedStaticMutexEv -__ZN3WTF37parseDateFromNullTerminatedCharactersEPKc -__ZN3WTF38unlockAtomicallyInitializedStaticMutexEv -__ZN3WTF39initializeMainThreadToProcessMainThreadEv -__ZN3WTF3MD58addBytesEPKhm -__ZN3WTF3MD58checksumERNS_6VectorIhLm16EEE -__ZN3WTF3MD5C1Ev -__ZN3WTF4SHA111computeHashERNS_6VectorIhLm20EEE -__ZN3WTF4SHA18addBytesEPKhm -__ZN3WTF4SHA1C1Ev -__ZN3WTF4dtoaEPcdRbRiRj -__ZN3WTF5Mutex4lockEv -__ZN3WTF5Mutex6unlockEv -__ZN3WTF5Mutex7tryLockEv -__ZN3WTF5MutexC1Ev -__ZN3WTF5MutexD1Ev -__ZN3WTF5equalEPKNS_10StringImplEPKc -__ZN3WTF5equalEPKNS_10StringImplES2_ -__ZN3WTF5yieldEv -__ZN3WTF6String26fromUTF8WithLatin1FallbackEPKcm -__ZN3WTF6String29charactersWithNullTerminationEv -__ZN3WTF6String6appendEPKtj -__ZN3WTF6String6appendERKS0_ -__ZN3WTF6String6appendEc -__ZN3WTF6String6appendEt -__ZN3WTF6String6formatEPKcz -__ZN3WTF6String6insertERKS0_j -__ZN3WTF6String6numberEd -__ZN3WTF6String6numberEi -__ZN3WTF6String6numberEj -__ZN3WTF6String6numberEl -__ZN3WTF6String6numberEm -__ZN3WTF6String6numberEt -__ZN3WTF6String6numberEx -__ZN3WTF6String6numberEy -__ZN3WTF6String6removeEji -__ZN3WTF6String8fromUTF8EPKc -__ZN3WTF6String8fromUTF8EPKcm -__ZN3WTF6String8truncateEj -__ZN3WTF6StringC1EPKc -__ZN3WTF6StringC1EPKcj -__ZN3WTF6StringC1EPKt -__ZN3WTF6StringC1EPKtj -__ZN3WTF6strtodEPKcPPc -__ZN3WTF7CString11mutableDataEv -__ZN3WTF7CString16newUninitializedEmRPc -__ZN3WTF7CStringC1EPKc -__ZN3WTF7CStringC1EPKcm -__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b -__ZN3WTF7Unicode18convertUTF8ToUTF16EPPKcS2_PPtS4_b -__ZN3WTF7xmlAtomE -__ZN3WTF8Collator18setOrderLowerFirstEb -__ZN3WTF8CollatorC1EPKc -__ZN3WTF8CollatorD1Ev -__ZN3WTF8Internal21fastMallocMatchFailedEPv -__ZN3WTF8fastFreeEPv -__ZN3WTF8msToYearEd -__ZN3WTF8nullAtomE -__ZN3WTF8starAtomE -__ZN3WTF8textAtomE -__ZN3WTF9ByteArray6createEm -__ZN3WTF9dayInYearEdi -__ZN3WTF9emptyAtomE -__ZN3WTF9xmlnsAtomE -__ZN3WTFeqERKNS_12AtomicStringEPKc -__ZN3WTFeqERKNS_12AtomicStringERKNS_6VectorItLm0EEE -__ZN3WTFeqERKNS_7CStringES2_ -__ZNK3JSC10JSFunction23isHostFunctionNonInlineEv -__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_10JSFunctionE -__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE -__ZNK3JSC12PropertySlot14functionGetterEPNS_9ExecStateE -__ZNK3JSC14JSGlobalObject14isDynamicScopeERb -__ZNK3JSC16JSVariableObject16isVariableObjectEv -__ZNK3JSC17DebuggerCallFrame10thisObjectEv -__ZNK3JSC17DebuggerCallFrame12functionNameEv -__ZNK3JSC17DebuggerCallFrame22calculatedFunctionNameEv -__ZNK3JSC17DebuggerCallFrame4typeEv -__ZNK3JSC17DebuggerCallFrame8evaluateERKNS_7UStringERNS_7JSValueE -__ZNK3JSC18PropertyDescriptor10enumerableEv -__ZNK3JSC18PropertyDescriptor12configurableEv -__ZNK3JSC18PropertyDescriptor16isDataDescriptorEv -__ZNK3JSC18PropertyDescriptor20isAccessorDescriptorEv -__ZNK3JSC18PropertyDescriptor6getterEv -__ZNK3JSC18PropertyDescriptor6setterEv -__ZNK3JSC18PropertyDescriptor8writableEv -__ZNK3JSC19SourceProviderCache8byteSizeEv -__ZNK3JSC4Heap11objectCountEv -__ZNK3JSC4Heap4sizeEv -__ZNK3JSC4Heap8capacityEv -__ZNK3JSC6JSCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE -__ZNK3JSC6JSCell12toThisObjectEPNS_9ExecStateE -__ZNK3JSC6JSCell14isGetterSetterEv -__ZNK3JSC6JSCell8toNumberEPNS_9ExecStateE -__ZNK3JSC6JSCell8toObjectEPNS_9ExecStateEPNS_14JSGlobalObjectE -__ZNK3JSC6JSCell8toStringEPNS_9ExecStateE -__ZNK3JSC6JSCell9getStringEPNS_9ExecStateE -__ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE -__ZNK3JSC6JSCell9getUInt32ERj -__ZNK3JSC6JSCell9toBooleanEPNS_9ExecStateE -__ZNK3JSC7ArgList8getSliceEiRS0_ -__ZNK3JSC7JSArray12subclassDataEv -__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateEPNS_14JSGlobalObjectE -__ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE -__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE -__ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE -__ZNK3JSC7UString20substringSharingImplEjj -__ZNK3JSC7UString4utf8Eb -__ZNK3JSC7UString5asciiEv -__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE -__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj -__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE -__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE -__ZNK3JSC8JSObject18toStrictThisObjectEPNS_9ExecStateE -__ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE -__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateEPNS_14JSGlobalObjectE -__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE -__ZNK3JSC8JSObject9classNameEv -__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE -__ZNK3JSC8JSString11resolveRopeEPNS_9ExecStateE -__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE -__ZNK3JSC9HashTable11deleteTableEv -__ZNK3WTF12AtomicString5lowerEv -__ZNK3WTF13DecimalNumber15toStringDecimalEPtj -__ZNK3WTF13DecimalNumber19toStringExponentialEPtj -__ZNK3WTF13DecimalNumber28bufferLengthForStringDecimalEv -__ZNK3WTF13DecimalNumber32bufferLengthForStringExponentialEv -__ZNK3WTF6String11toIntStrictEPbi -__ZNK3WTF6String12toUIntStrictEPbi -__ZNK3WTF6String13toInt64StrictEPbi -__ZNK3WTF6String14threadsafeCopyEv -__ZNK3WTF6String15stripWhiteSpaceEv -__ZNK3WTF6String16removeCharactersEPFbtE -__ZNK3WTF6String17crossThreadStringEv -__ZNK3WTF6String18simplifyWhiteSpaceEv -__ZNK3WTF6String19characterStartingAtEj -__ZNK3WTF6String4utf8Eb -__ZNK3WTF6String5asciiEv -__ZNK3WTF6String5lowerEv -__ZNK3WTF6String5splitERKS0_RNS_6VectorIS0_Lm0EEE -__ZNK3WTF6String5splitERKS0_bRNS_6VectorIS0_Lm0EEE -__ZNK3WTF6String5splitEtRNS_6VectorIS0_Lm0EEE -__ZNK3WTF6String5splitEtbRNS_6VectorIS0_Lm0EEE -__ZNK3WTF6String5toIntEPb -__ZNK3WTF6String5upperEv -__ZNK3WTF6String6latin1Ev -__ZNK3WTF6String6toUIntEPb -__ZNK3WTF6String7toFloatEPbS1_ -__ZNK3WTF6String8foldCaseEv -__ZNK3WTF6String8toDoubleEPbS1_ -__ZNK3WTF6String8toIntPtrEPb -__ZNK3WTF6String8toUInt64EPb -__ZNK3WTF6String9substringEjj -__ZNK3WTF8Collator7collateEPKtmS2_m -__ZTVN3JSC12StringObjectE -__ZTVN3JSC14JSGlobalObjectE -__ZTVN3JSC14ScopeChainNodeE -__ZTVN3JSC15JSWrapperObjectE -__ZTVN3JSC15WeakHandleOwnerE -__ZTVN3JSC16InternalFunctionE -__ZTVN3JSC16JSVariableObjectE -__ZTVN3JSC8DebuggerE -__ZTVN3JSC8JSObjectE -__ZTVN3JSC8JSStringE -_jscore_fastmalloc_introspection -_kJSClassDefinitionEmpty - -# iOS methods -__ZN3WTF11isWebThreadEv -__ZN3JSC12JSGlobalData23recompileAllJSFunctionsEv -__ZN3JSC12JSGlobalData20sharedInstanceExistsEv -__ZN3JSC25DefaultGCActivityCallbackC2EPNS_4HeapEP11__CFRunLoop -__ZN3JSC25DefaultGCActivityCallbackD2Ev -__ZN3JSC25DefaultGCActivityCallbackclEv -__ZN3JSC25DefaultGCActivityCallback11synchronizeEv -__ZTVN3JSC25DefaultGCActivityCallbackE diff --git a/JavaScriptCore.gyp/.gitignore b/JavaScriptCore.gyp/.gitignore new file mode 100644 index 0000000..9b06f58 --- /dev/null +++ b/JavaScriptCore.gyp/.gitignore @@ -0,0 +1,5 @@ +*.Makefile +*.mk +*.sln +*.vcproj* +JavaScriptCore.xcodeproj diff --git a/JavaScriptCore.gyp/JavaScriptCore.gyp b/JavaScriptCore.gyp/JavaScriptCore.gyp index eff3607..a89ac51 100644 --- a/JavaScriptCore.gyp/JavaScriptCore.gyp +++ b/JavaScriptCore.gyp/JavaScriptCore.gyp @@ -1,10 +1,10 @@ # -# Copyright (C) 2009 Google Inc. All rights reserved. -# +# Copyright (C) 2009, 2012 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 @@ -14,7 +14,7 @@ # * 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 @@ -30,8 +30,7 @@ { 'includes': [ - # FIXME: Sense whether upstream or downstream build, and - # include the right features.gypi + '../../WebKit/chromium/WinPrecompile.gypi', '../../WebKit/chromium/features.gypi', '../JavaScriptCore.gypi', ], @@ -47,159 +46,23 @@ }], ], }, - 'targets': [ - { - # This target sets up defines and includes that are required by WTF and - # its dependents. - 'target_name': 'wtf_config', - 'type': 'none', - 'msvs_guid': '2E2D3301-2EC4-4C0F-B889-87073B30F673', - 'direct_dependent_settings': { - 'defines': [ - # Import features_defines from features.gypi - '<@(feature_defines)', - - # Turns on #if PLATFORM(CHROMIUM) - 'BUILDING_CHROMIUM__=1', - # Controls wtf/FastMalloc - # FIXME: consider moving into config.h - 'USE_SYSTEM_MALLOC=1', - ], - 'conditions': [ - ['OS=="win"', { - 'defines': [ - '__STD_C', - '_CRT_SECURE_NO_DEPRECATE', - '_SCL_SECURE_NO_DEPRECATE', - 'CRASH=__debugbreak', - ], - 'include_dirs': [ - '../os-win32', - ], - }], - ['OS=="mac"', { - 'defines': [ - # Use USE_NEW_THEME on Mac. - 'WTF_USE_NEW_THEME=1', - ], - }], - ['OS=="linux" or OS=="freebsd"', { - 'defines': [ - 'WTF_USE_PTHREADS=1', - ], - }], - ], - } - }, - { - 'target_name': 'wtf', - 'type': '<(library)', - 'msvs_guid': 'AA8A5A85-592B-4357-BC60-E0E91E026AF6', - 'dependencies': [ - 'wtf_config', - '<(chromium_src_dir)/third_party/icu/icu.gyp:icui18n', - '<(chromium_src_dir)/third_party/icu/icu.gyp:icuuc', - ], - 'include_dirs': [ - '../', - '../wtf', - '../wtf/unicode', - ], - 'sources': [ - '<@(javascriptcore_publicheader_files)', - '<@(javascriptcore_privateheader_files)', - '<@(javascriptcore_files)', - ], - 'sources/': [ - # First exclude everything ... - ['exclude', '../'], - # ... Then include what we want. - ['include', '../wtf/'], - # FIXME: This is clearly not sustainable. - ['exclude', '../wtf/android'], - ['exclude', '../wtf/brew'], - ['exclude', '../wtf/efl'], - ['exclude', '../wtf/gobject'], - ['exclude', '../wtf/gtk'], - ['exclude', '../wtf/haiku'], - ['exclude', '../wtf/mac'], - ['exclude', '../wtf/qt'], - ['exclude', '../wtf/url'], - ['exclude', '../wtf/wince'], - ['exclude', '../wtf/wx'], - ['exclude', '../wtf/unicode/brew'], - ['exclude', '../wtf/unicode/wince'], - ['exclude', '../wtf/unicode/glib'], - ['exclude', '../wtf/unicode/qt4'], - # GLib/GTK, even though its name doesn't really indicate. - ['exclude', '/(gtk|glib|gobject)/.*\\.(cpp|h)$'], - ['exclude', '(Default|Gtk|Mac|None|Qt|Win|Wx|Efl|Symbian)\\.(cpp|mm)$'], - ['exclude', 'wtf/CurrentTime\\.cpp$'], - ['exclude', 'wtf/OSRandomSource\\.cpp$'], - ['exclude', 'wtf/MainThread.cpp$'], - ['exclude', 'wtf/TC.*\\.(cpp|h)$'], - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '../', - '../wtf', - ], - # Some warnings occur in JSC headers, so they must also be disabled - # in targets that use JSC. - 'msvs_disabled_warnings': [ - # Don't complain about calling specific versions of templatized - # functions (e.g. in RefPtrHashMap.h). - 4344, - # Don't complain about using "this" in an initializer list - # (e.g. in StringImpl.h). - 4355, - ], + 'conditions': [ + ['os_posix == 1 and OS != "mac" and OS != "android" and gcc_version==46', { + 'target_defaults': { + # Disable warnings about c++0x compatibility, as some names (such as nullptr) conflict + # with upcoming c++0x types. + 'cflags_cc': ['-Wno-c++0x-compat'], }, - 'export_dependent_settings': [ - 'wtf_config', - '<(chromium_src_dir)/third_party/icu/icu.gyp:icui18n', - '<(chromium_src_dir)/third_party/icu/icu.gyp:icuuc', - ], - 'msvs_disabled_warnings': [4127, 4355, 4510, 4512, 4610, 4706], - 'conditions': [ - ['OS=="win"', { - 'sources/': [ - ['exclude', 'ThreadIdentifierDataPthreads\\.(h|cpp)$'], - ['exclude', 'ThreadingPthreads\\.cpp$'], - ['include', 'Thread(ing|Specific)Win\\.cpp$'], - ['exclude', 'OSAllocatorPosix\\.cpp$'], - ['include', 'OSAllocatorWin\\.cpp$'] - ], - 'include_dirs!': [ - '<(SHARED_INTERMEDIATE_DIR)/webkit', - ], - 'conditions': [ - ['inside_chromium_build==1 and component=="shared_library"', { - # Chromium windows multi-dll build enables c++ exception and this - # causes wtf generates 4291 warning due to operator new/delete - # implementations. Disable the warning for chromium windows - # multi-dll build. - 'msvs_disabled_warnings': [4291], - 'direct_dependent_settings': { - 'msvs_disabled_warnings': [4291], - }, - }], - ], - }], - ], - }, + }], + ], + 'targets': [ { 'target_name': 'yarr', - 'type': '<(library)', + 'type': 'static_library', 'dependencies': [ - 'wtf', - ], - 'conditions': [ - ['OS=="win"', { - 'dependencies': ['<(chromium_src_dir)/build/win/system.gyp:cygwin'], - }], + '../../WTF/WTF.gyp/WTF.gyp:wtf', ], - 'msvs_guid': '49909552-0B0C-4C14-8CF6-DB8A2ADE0934', + 'variables': { 'optimize': 'max' }, 'actions': [ { 'action_name': 'retgen', @@ -230,6 +93,7 @@ ], 'include_dirs': [ '<(INTERMEDIATE_DIR)', + '..', '../runtime', ], 'sources': [ @@ -244,7 +108,7 @@ ['exclude', '../yarr/YarrJIT\\.(h|cpp)$'], ], 'export_dependent_settings': [ - 'wtf', + '../../WTF/WTF.gyp/WTF.gyp:wtf', ], }, ], # targets diff --git a/JavaScriptCore.gypi b/JavaScriptCore.gypi index c101031..4a03be8 100644 --- a/JavaScriptCore.gypi +++ b/JavaScriptCore.gypi @@ -3,105 +3,285 @@ 'project_dir': ['.'], # These headers are part of JavaScriptCore's public API in the Apple Mac build. 'javascriptcore_publicheader_files': [ + 'API/APICast.h', + 'API/APIShims.h', 'API/JSBase.h', 'API/JSContextRef.h', + 'API/JSContextRefPrivate.h', 'API/JSObjectRef.h', + 'API/JSObjectRefPrivate.h', + 'API/JSRetainPtr.h', 'API/JSStringRef.h', + 'API/JSStringRefBSTR.h', 'API/JSStringRefCF.h', 'API/JSValueRef.h', + 'API/JSWeakObjectMapRefInternal.h', + 'API/JSWeakObjectMapRefPrivate.h', 'API/JavaScript.h', 'API/JavaScriptCore.h', + 'API/OpaqueJSString.h', 'API/WebKitAvailability.h', ], # These headers are part of JavaScriptCore's private API in the Apple Mac build. 'javascriptcore_privateheader_files': [ - 'API/APICast.h', - 'API/APIShims.h', - 'API/JSBasePrivate.h', - 'API/JSContextRefPrivate.h', - 'API/JSObjectRefPrivate.h', - 'API/JSProfilerPrivate.h', - 'API/JSRetainPtr.h', - 'API/JSWeakObjectMapRefInternal.h', - 'API/JSWeakObjectMapRefPrivate.h', - 'API/OpaqueJSString.h', + 'assembler/AbstractMacroAssembler.h', + 'assembler/ARMAssembler.h', + 'assembler/ARMv7Assembler.h', + 'assembler/AssemblerBuffer.h', + 'assembler/AssemblerBufferWithConstantPool.h', + 'assembler/CodeLocation.h', + 'assembler/LinkBuffer.h', + 'assembler/MacroAssembler.h', + 'assembler/MacroAssemblerARM.h', + 'assembler/MacroAssemblerARMv7.h', 'assembler/MacroAssemblerCodeRef.h', + 'assembler/MacroAssemblerMIPS.h', + 'assembler/MacroAssemblerSH4.h', + 'assembler/MacroAssemblerX86.h', + 'assembler/MacroAssemblerX86Common.h', + 'assembler/MacroAssemblerX86_64.h', + 'assembler/MIPSAssembler.h', + 'assembler/RepatchBuffer.h', + 'assembler/SH4Assembler.h', + 'assembler/X86Assembler.h', + 'bytecode/BytecodeConventions.h', + 'bytecode/CallLinkInfo.h', + 'bytecode/CallLinkStatus.h', + 'bytecode/CallReturnOffsetToBytecodeOffset.h', + 'bytecode/CodeBlock.h', + 'bytecode/CodeOrigin.h', + 'bytecode/CodeType.h', + 'bytecode/DataFormat.h', + 'bytecode/DFGExitProfile.h', + 'bytecode/EvalCodeCache.h', + 'bytecode/ExecutionCounter.h', + 'bytecode/ExpressionRangeInfo.h', + 'bytecode/GetByIdStatus.h', + 'bytecode/GlobalResolveInfo.h', + 'bytecode/HandlerInfo.h', + 'bytecode/Instruction.h', + 'bytecode/JumpTable.h', + 'bytecode/LazyOperandValueProfile.h', + 'bytecode/LineInfo.h', + 'bytecode/LLIntCallLinkInfo.h', + 'bytecode/MethodCallLinkInfo.h', + 'bytecode/MethodCallLinkStatus.h', + 'bytecode/MethodOfGettingAValueProfile.h', 'bytecode/Opcode.h', + 'bytecode/Operands.h', + 'bytecode/PolymorphicPutByIdList.h', + 'bytecode/PredictedType.h', + 'bytecode/PredictionTracker.h', + 'bytecode/PutByIdStatus.h', + 'bytecode/PutKind.h', + 'bytecode/SamplingTool.h', + 'bytecode/StructureSet.h', + 'bytecode/StructureStubInfo.h', + 'bytecode/ValueProfile.h', + 'bytecode/ValueRecovery.h', + 'bytecode/VirtualRegister.h', + 'dfg/DFGAbstractState.h', + 'dfg/DFGAbstractValue.h', + 'dfg/DFGAdjacencyList.h', + 'dfg/DFGAssemblyHelpers.h', + 'dfg/DFGBasicBlock.h', + 'dfg/DFGByteCodeCache.h', + 'dfg/DFGByteCodeParser.h', + 'dfg/DFGCapabilities.h', + 'dfg/DFGCCallHelpers.h', + 'dfg/DFGCFAPhase.h', + 'dfg/DFGCommon.h', + 'dfg/DFGCorrectableJumpPoint.h', + 'dfg/DFGCSEPhase.h', + 'dfg/DFGDriver.h', + 'dfg/DFGEdge.h', + 'dfg/DFGFixupPhase.h', + 'dfg/DFGFPRInfo.h', + 'dfg/DFGGenerationInfo.h', + 'dfg/DFGGPRInfo.h', + 'dfg/DFGGraph.h', + 'dfg/DFGInsertionSet.h', + 'dfg/DFGJITCompiler.h', + 'dfg/DFGNode.h', + 'dfg/DFGNodeFlags.h', + 'dfg/DFGNodeType.h', + 'dfg/DFGOperations.h', + 'dfg/DFGOSREntry.h', + 'dfg/DFGOSRExit.h', + 'dfg/DFGOSRExitCompiler.h', + 'dfg/DFGPhase.h', + 'dfg/DFGPredictionPropagationPhase.h', + 'dfg/DFGRedundantPhiEliminationPhase.h', + 'dfg/DFGRegisterBank.h', + 'dfg/DFGRepatch.h', + 'dfg/DFGScoreBoard.h', + 'dfg/DFGSpeculativeJIT.h', + 'dfg/DFGThunks.h', + 'dfg/DFGVariableAccessData.h', + 'dfg/DFGVirtualRegisterAllocationPhase.h', + 'heap/CardSet.h', 'heap/ConservativeRoots.h', + 'heap/CopiedAllocator.h', + 'heap/CopiedBlock.h', + 'heap/CopiedSpace.h', + 'heap/CopiedSpaceInlineMethods.h', + 'heap/DFGCodeBlocks.h', + 'heap/GCAssertions.h', 'heap/Handle.h', - 'heap/HandleHeap.h', + 'heap/HandleSet.h', 'heap/HandleStack.h', 'heap/HandleTypes.h', 'heap/Heap.h', + 'heap/HeapBlock.h', + 'heap/HeapRootVisitor.h', + 'heap/ListableHandler.h', 'heap/Local.h', 'heap/LocalScope.h', + 'heap/MachineStackMarker.h', + 'heap/MarkedAllocator.h', + 'heap/MarkedBlock.h', + 'heap/MarkedBlockSet.h', + 'heap/MarkedSpace.h', + 'heap/MarkStack.h', + 'heap/PassWeak.h', + 'heap/SlotVisitor.h', 'heap/Strong.h', + 'heap/StrongInlines.h', + 'heap/TinyBloomFilter.h', + 'heap/UnconditionalFinalizer.h', + 'heap/VTableSpectrum.h', 'heap/Weak.h', - 'config.h', + 'heap/WeakBlock.h', + 'heap/WeakHandleOwner.h', + 'heap/WeakImpl.h', + 'heap/WeakReferenceHarvester.h', + 'heap/WeakSet.h', + 'heap/WeakSetInlines.h', + 'heap/WriteBarrierSupport.h', 'debugger/Debugger.h', 'debugger/DebuggerActivation.h', 'debugger/DebuggerCallFrame.h', + 'interpreter/AbstractPC.h', + 'interpreter/CachedCall.h', 'interpreter/CallFrame.h', + 'interpreter/CallFrameClosure.h', 'interpreter/Interpreter.h', 'interpreter/Register.h', 'interpreter/RegisterFile.h', + 'jit/CompactJITCodeMap.h', 'jit/ExecutableAllocator.h', + 'jit/HostCallReturnValue.h', + 'jit/JIT.h', 'jit/JITCode.h', + 'jit/JITCompilationEffort.h', + 'jit/JITDriver.h', + 'jit/JITExceptions.h', + 'jit/JITInlineMethods.h', + 'jit/JITStubCall.h', 'jit/JITStubs.h', + 'jit/JITWriteBarrier.h', + 'jit/JSInterfaceJIT.h', + 'jit/SpecializedThunkJIT.h', 'jit/ThunkGenerators.h', + 'parser/ASTBuilder.h', + 'parser/Lexer.h', + 'parser/NodeConstructors.h', + 'parser/NodeInfo.h', + 'parser/Nodes.h', + 'parser/Parser.h', + 'parser/ParserArena.h', + 'parser/ParserTokens.h', 'parser/ResultType.h', 'parser/SourceCode.h', 'parser/SourceProvider.h', 'parser/SourceProviderCache.h', + 'parser/SourceProviderCacheItem.h', + 'parser/SyntaxChecker.h', 'profiler/CallIdentifier.h', 'profiler/Profile.h', + 'profiler/ProfileGenerator.h', 'profiler/ProfileNode.h', 'profiler/Profiler.h', 'runtime/ArgList.h', + 'runtime/Arguments.h', + 'runtime/ArrayConstructor.h', 'runtime/ArrayPrototype.h', + 'runtime/BatchedTransitionOptimizer.h', + 'runtime/BigInteger.h', + 'runtime/BooleanConstructor.h', 'runtime/BooleanObject.h', + 'runtime/BooleanPrototype.h', 'runtime/CachedTranscendentalFunction.h', 'runtime/CallData.h', 'runtime/ClassInfo.h', + 'runtime/CodeSpecializationKind.h', 'runtime/CommonIdentifiers.h', + 'runtime/CommonSlowPaths.h', 'runtime/Completion.h', 'runtime/ConstructData.h', + 'runtime/DateConstructor.h', + 'runtime/DateConversion.h', 'runtime/DateInstance.h', 'runtime/DateInstanceCache.h', + 'runtime/DatePrototype.h', 'runtime/Error.h', + 'runtime/ErrorConstructor.h', + 'runtime/ErrorInstance.h', + 'runtime/ErrorPrototype.h', 'runtime/ExceptionHelpers.h', + 'runtime/Executable.h', + 'runtime/ExecutionHarness.h', 'runtime/FunctionConstructor.h', 'runtime/FunctionPrototype.h', 'runtime/GCActivityCallback.h', + 'runtime/GetterSetter.h', 'runtime/Identifier.h', 'runtime/InitializeThreading.h', 'runtime/InternalFunction.h', + 'runtime/Intrinsic.h', + 'runtime/JSActivation.h', 'runtime/JSAPIValueWrapper.h', 'runtime/JSArray.h', - 'runtime/JSByteArray.h', + 'runtime/JSBoundFunction.h', 'runtime/JSCell.h', + 'runtime/JSChunk.h', + 'runtime/JSDateMath.h', + 'runtime/JSExportMacros.h', 'runtime/JSFunction.h', 'runtime/JSGlobalData.h', 'runtime/JSGlobalObject.h', + 'runtime/JSGlobalObjectFunctions.h', + 'runtime/JSGlobalThis.h', 'runtime/JSLock.h', - 'runtime/JSNumberCell.h', + 'runtime/JSNotAnObject.h', 'runtime/JSObject.h', - 'runtime/JSObjectWithGlobalObject.h', + 'runtime/JSONObject.h', + 'runtime/JSPropertyNameIterator.h', + 'runtime/JSStaticScopeObject.h', 'runtime/JSString.h', + 'runtime/JSStringBuilder.h', + 'runtime/JSStringJoiner.h', 'runtime/JSType.h', 'runtime/JSTypeInfo.h', 'runtime/JSValue.h', 'runtime/JSValueInlineMethods.h', 'runtime/JSVariableObject.h', 'runtime/JSWrapperObject.h', + 'runtime/LiteralParser.h', 'runtime/Lookup.h', + 'runtime/MatchResult.h', 'runtime/MathObject.h', 'runtime/MemoryStatistics.h', + 'runtime/NativeErrorConstructor.h', + 'runtime/NativeErrorPrototype.h', + 'runtime/NumberConstructor.h', 'runtime/NumberObject.h', 'runtime/NumberPrototype.h', 'runtime/NumericStrings.h', + 'runtime/ObjectConstructor.h', 'runtime/ObjectPrototype.h', 'runtime/Operations.h', + 'runtime/Options.h', 'runtime/PropertyDescriptor.h', 'runtime/PropertyMapHashTable.h', 'runtime/PropertyNameArray.h', @@ -109,587 +289,252 @@ 'runtime/Protect.h', 'runtime/PutPropertySlot.h', 'runtime/RegExp.h', - 'runtime/RegExpKey.h', 'runtime/RegExpCache.h', + 'runtime/RegExpCachedResult.h', + 'runtime/RegExpConstructor.h', + 'runtime/RegExpKey.h', + 'runtime/RegExpMatchesArray.h', 'runtime/RegExpObject.h', - 'runtime/RopeImpl.h', + 'runtime/RegExpPrototype.h', + 'runtime/SamplingCounter.h', 'runtime/ScopeChain.h', + 'runtime/ScopeChainMark.h', 'runtime/SmallStrings.h', + 'runtime/StorageBarrier.h', + 'runtime/StrictEvalActivation.h', + 'runtime/StringConstructor.h', 'runtime/StringObject.h', - 'runtime/StringObjectThatMasqueradesAsUndefined.h', 'runtime/StringPrototype.h', + 'runtime/StringRecursionChecker.h', 'runtime/Structure.h', 'runtime/StructureChain.h', 'runtime/StructureTransitionTable.h', 'runtime/SymbolTable.h', 'runtime/Terminator.h', 'runtime/TimeoutChecker.h', + 'runtime/Tracing.h', + 'runtime/Uint16WithFraction.h', 'runtime/UString.h', 'runtime/UStringBuilder.h', + 'runtime/UStringConcatenate.h', 'runtime/WeakGCMap.h', 'runtime/WeakRandom.h', 'runtime/WriteBarrier.h', - 'wtf/ASCIICType.h', - 'wtf/AVLTree.h', - 'wtf/Alignment.h', - 'wtf/AlwaysInline.h', - 'wtf/Assertions.h', - 'wtf/Atomics.h', - 'wtf/Bitmap.h', - 'wtf/BlockStack.h', - 'wtf/BloomFilter.h', - 'wtf/BumpPointerAllocator.h', - 'wtf/ByteArray.h', - 'wtf/Complex.h', - 'wtf/CrossThreadRefCounted.h', - 'wtf/CryptographicallyRandomNumber.h', - 'wtf/CurrentTime.h', - 'wtf/DateMath.h', - 'wtf/DecimalNumber.h', - 'wtf/Decoder.h', - 'wtf/Deque.h', - 'wtf/DisallowCType.h', - 'wtf/DoublyLinkedList.h', - 'wtf/Encoder.h', - 'wtf/FastAllocBase.h', - 'wtf/FastMalloc.h', - 'wtf/FixedArray.h', - 'wtf/Forward.h', - 'wtf/GetPtr.h', - 'wtf/HashCountedSet.h', - 'wtf/HashFunctions.h', - 'wtf/HashIterators.h', - 'wtf/HashMap.h', - 'wtf/HashSet.h', - 'wtf/HashTable.h', - 'wtf/HashTraits.h', - 'wtf/HexNumber.h', - 'wtf/ListHashSet.h', - 'wtf/ListRefPtr.h', - 'wtf/Locker.h', - 'wtf/MD5.h', - 'wtf/MainThread.h', - 'wtf/MathExtras.h', - 'wtf/MessageQueue.h', - 'wtf/NonCopyingSort.h', - 'wtf/Noncopyable.h', - 'wtf/NotFound.h', - 'wtf/NullPtr.h', - 'wtf/OSAllocator.h', - 'wtf/OwnArrayPtr.h', - 'wtf/OwnFastMallocPtr.h', - 'wtf/OwnPtr.h', - 'wtf/OwnPtrCommon.h', - 'wtf/PageAllocation.h', - 'wtf/PageAllocationAligned.h', - 'wtf/PageBlock.h', - 'wtf/PageReservation.h', - 'wtf/PassOwnArrayPtr.h', - 'wtf/PassOwnPtr.h', - 'wtf/PassRefPtr.h', - 'wtf/PassTraits.h', - 'wtf/Platform.h', - 'wtf/PossiblyNull.h', - 'wtf/RandomNumber.h', - 'wtf/RefCounted.h', - 'wtf/RefCountedLeakCounter.h', - 'wtf/RefPtr.h', - 'wtf/RefPtrHashMap.h', - 'wtf/RetainPtr.h', - 'wtf/SentinelLinkedList.h', - 'wtf/SinglyLinkedList.h', - 'wtf/StackBounds.h', - 'wtf/StaticConstructors.h', - 'wtf/StdLibExtras.h', - 'wtf/StringExtras.h', - 'wtf/StringHasher.h', - 'wtf/ThreadSafeRefCounted.h', - 'wtf/ThreadSpecific.h', - 'wtf/Threading.h', - 'wtf/ThreadingPrimitives.h', - 'wtf/TypeTraits.h', - 'wtf/UnusedParam.h', - 'wtf/VMTags.h', - 'wtf/ValueCheck.h', - 'wtf/Vector.h', - 'wtf/VectorTraits.h', - 'wtf/WTFThreadData.h', - 'wtf/dtoa.h', - 'wtf/text/AtomicString.h', - 'wtf/text/AtomicStringHash.h', - 'wtf/text/AtomicStringImpl.h', - 'wtf/text/CString.h', - 'wtf/text/StringBuffer.h', - 'wtf/text/StringBuilder.h', - 'wtf/text/StringConcatenate.h', - 'wtf/text/StringHash.h', - 'wtf/text/StringImpl.h', - 'wtf/text/StringImplBase.h', - 'wtf/text/StringOperators.h', - 'wtf/text/TextPosition.h', - 'wtf/text/WTFString.h', - 'wtf/unicode/CharacterNames.h', - 'wtf/unicode/Collator.h', - 'wtf/unicode/UTF8.h', - 'wtf/unicode/Unicode.h', - 'wtf/unicode/icu/UnicodeIcu.h', 'yarr/Yarr.h', + 'yarr/YarrCanonicalizeUCS2.h', 'yarr/YarrInterpreter.h', + 'yarr/YarrJIT.h', + 'yarr/YarrParser.h', 'yarr/YarrPattern.h', + 'yarr/YarrSyntaxChecker.h', ], 'javascriptcore_files': [ - 'API/APIShims.h', 'API/JSBase.cpp', 'API/JSCallbackConstructor.cpp', - 'API/JSCallbackConstructor.h', 'API/JSCallbackFunction.cpp', - 'API/JSCallbackFunction.h', 'API/JSCallbackObject.cpp', - 'API/JSCallbackObject.h', - 'API/JSCallbackObjectFunctions.h', 'API/JSClassRef.cpp', - 'API/JSClassRef.h', 'API/JSContextRef.cpp', 'API/JSObjectRef.cpp', 'API/JSProfilerPrivate.cpp', 'API/JSStringRef.cpp', 'API/JSStringRefBSTR.cpp', - 'API/JSStringRefBSTR.h', 'API/JSStringRefCF.cpp', 'API/JSValueRef.cpp', 'API/JSWeakObjectMapRefPrivate.cpp', 'API/OpaqueJSString.cpp', - 'AllInOneFile.cpp', - 'ForwardingHeaders/JavaScriptCore/APICast.h', - 'ForwardingHeaders/JavaScriptCore/APIShims.h', - 'ForwardingHeaders/JavaScriptCore/JSBase.h', - 'ForwardingHeaders/JavaScriptCore/JSContextRef.h', - 'ForwardingHeaders/JavaScriptCore/JSObjectRef.h', - 'ForwardingHeaders/JavaScriptCore/JSRetainPtr.h', - 'ForwardingHeaders/JavaScriptCore/JSStringRef.h', - 'ForwardingHeaders/JavaScriptCore/JSStringRefCF.h', - 'ForwardingHeaders/JavaScriptCore/JSValueRef.h', - 'ForwardingHeaders/JavaScriptCore/JavaScript.h', - 'ForwardingHeaders/JavaScriptCore/JavaScriptCore.h', - 'ForwardingHeaders/JavaScriptCore/OpaqueJSString.h', - 'ForwardingHeaders/JavaScriptCore/WebKitAvailability.h', - 'JavaScriptCorePrefix.h', 'assembler/ARMAssembler.cpp', - 'assembler/ARMAssembler.h', 'assembler/ARMv7Assembler.cpp', - 'assembler/ARMv7Assembler.h', - 'assembler/AbstractMacroAssembler.h', - 'assembler/AssemblerBuffer.h', - 'assembler/AssemblerBufferWithConstantPool.h', - 'assembler/CodeLocation.h', - 'assembler/LinkBuffer.h', - 'assembler/MIPSAssembler.h', - 'assembler/MacroAssembler.h', 'assembler/MacroAssemblerARM.cpp', - 'assembler/MacroAssemblerARM.h', - 'assembler/MacroAssemblerARMv7.h', - 'assembler/MacroAssemblerMIPS.h', - 'assembler/MacroAssemblerX86.h', - 'assembler/MacroAssemblerX86Common.h', - 'assembler/MacroAssemblerX86_64.h', - 'assembler/RepatchBuffer.h', - 'assembler/X86Assembler.h', + 'assembler/MacroAssemblerSH4.cpp', + 'bytecode/CallLinkInfo.cpp', + 'bytecode/CallLinkStatus.cpp', 'bytecode/CodeBlock.cpp', - 'bytecode/CodeBlock.h', - 'bytecode/EvalCodeCache.h', - 'bytecode/Instruction.h', + 'bytecode/DFGExitProfile.cpp', + 'bytecode/ExecutionCounter.cpp', + 'bytecode/GetByIdStatus.cpp', 'bytecode/JumpTable.cpp', - 'bytecode/JumpTable.h', + 'bytecode/LazyOperandValueProfile.cpp', + 'bytecode/MethodCallLinkInfo.cpp', + 'bytecode/MethodCallLinkStatus.cpp', + 'bytecode/MethodOfGettingAValueProfile.cpp', 'bytecode/Opcode.cpp', + 'bytecode/PolymorphicPutByIdList.cpp', + 'bytecode/PredictedType.cpp', + 'bytecode/PutByIdStatus.cpp', 'bytecode/SamplingTool.cpp', - 'bytecode/SamplingTool.h', 'bytecode/StructureStubInfo.cpp', - 'bytecode/StructureStubInfo.h', 'bytecompiler/BytecodeGenerator.cpp', - 'bytecompiler/BytecodeGenerator.h', - 'bytecompiler/Label.h', - 'bytecompiler/LabelScope.h', 'bytecompiler/NodesCodegen.cpp', - 'bytecompiler/RegisterID.h', - 'heap/ConservativeRoots.cpp', - 'heap/HandleHeap.cpp', - 'heap/HandleStack.cpp', - 'heap/Heap.cpp', - 'heap/MachineStackMarker.cpp', - 'heap/MachineStackMarker.h', - 'heap/MarkStack.cpp', - 'heap/MarkStack.h', - 'heap/MarkStackPosix.cpp', - 'heap/MarkStackSymbian.cpp', - 'heap/MarkStackWin.cpp', - 'heap/MarkedBlock.cpp', - 'heap/MarkedBlock.h', - 'heap/MarkedSpace.cpp', - 'heap/MarkedSpace.h', 'debugger/Debugger.cpp', 'debugger/DebuggerActivation.cpp', 'debugger/DebuggerCallFrame.cpp', - 'dfg/DFGAliasTracker.h', + 'dfg/DFGAbstractState.cpp', + 'dfg/DFGAssemblyHelpers.cpp', 'dfg/DFGByteCodeParser.cpp', - 'dfg/DFGByteCodeParser.h', - 'dfg/DFGGenerationInfo.h', + 'dfg/DFGCapabilities.cpp', + 'dfg/DFGCFAPhase.cpp', + 'dfg/DFGCorrectableJumpPoint.cpp', + 'dfg/DFGCSEPhase.cpp', + 'dfg/DFGDriver.cpp', + 'dfg/DFGFixupPhase.cpp', 'dfg/DFGGraph.cpp', - 'dfg/DFGGraph.h', - 'dfg/DFGJITCodeGenerator.cpp', - 'dfg/DFGJITCodeGenerator.h', 'dfg/DFGJITCompiler.cpp', - 'dfg/DFGJITCompiler.h', - 'dfg/DFGNode.h', - 'dfg/DFGNonSpeculativeJIT.cpp', - 'dfg/DFGNonSpeculativeJIT.h', + 'dfg/DFGNodeFlags.cpp', 'dfg/DFGOperations.cpp', - 'dfg/DFGOperations.h', - 'dfg/DFGRegisterBank.h', - 'dfg/DFGScoreBoard.h', + 'dfg/DFGOSREntry.cpp', + 'dfg/DFGOSRExit.cpp', + 'dfg/DFGOSRExitCompiler.cpp', + 'dfg/DFGOSRExitCompiler32_64.cpp', + 'dfg/DFGOSRExitCompiler64.cpp', + 'dfg/DFGPhase.cpp', + 'dfg/DFGPredictionPropagationPhase.cpp', + 'dfg/DFGRedundantPhiEliminationPhase.cpp', + 'dfg/DFGRepatch.cpp', 'dfg/DFGSpeculativeJIT.cpp', - 'dfg/DFGSpeculativeJIT.h', - 'icu/unicode/parseerr.h', - 'icu/unicode/platform.h', - 'icu/unicode/putil.h', - 'icu/unicode/uchar.h', - 'icu/unicode/ucnv.h', - 'icu/unicode/ucnv_err.h', - 'icu/unicode/ucol.h', - 'icu/unicode/uconfig.h', - 'icu/unicode/uenum.h', - 'icu/unicode/uiter.h', - 'icu/unicode/uloc.h', - 'icu/unicode/umachine.h', - 'icu/unicode/unorm.h', - 'icu/unicode/urename.h', - 'icu/unicode/uset.h', - 'icu/unicode/ustring.h', - 'icu/unicode/utf.h', - 'icu/unicode/utf16.h', - 'icu/unicode/utf8.h', - 'icu/unicode/utf_old.h', - 'icu/unicode/utypes.h', - 'icu/unicode/uversion.h', - 'interpreter/CachedCall.h', + 'dfg/DFGSpeculativeJIT32_64.cpp', + 'dfg/DFGSpeculativeJIT64.cpp', + 'dfg/DFGThunks.cpp', + 'dfg/DFGVirtualRegisterAllocationPhase.cpp', + 'heap/ConservativeRoots.cpp', + 'heap/CopiedSpace.cpp', + 'heap/DFGCodeBlocks.cpp', + 'heap/HandleSet.cpp', + 'heap/HandleStack.cpp', + 'heap/BlockAllocator.cpp', + 'heap/Heap.cpp', + 'heap/MachineStackMarker.cpp', + 'heap/MarkedAllocator.cpp', + 'heap/MarkedBlock.cpp', + 'heap/MarkedSpace.cpp', + 'heap/MarkStack.cpp', + 'heap/VTableSpectrum.cpp', + 'heap/WeakBlock.cpp', + 'heap/WeakHandleOwner.cpp', + 'heap/WeakSet.cpp', + 'heap/WriteBarrierSupport.cpp', + 'interpreter/AbstractPC.cpp', 'interpreter/CallFrame.cpp', - 'interpreter/CallFrameClosure.h', 'interpreter/Interpreter.cpp', 'interpreter/RegisterFile.cpp', 'jit/ExecutableAllocator.cpp', 'jit/ExecutableAllocatorFixedVMPool.cpp', + 'jit/HostCallReturnValue.cpp', 'jit/JIT.cpp', - 'jit/JIT.h', 'jit/JITArithmetic.cpp', 'jit/JITArithmetic32_64.cpp', 'jit/JITCall.cpp', 'jit/JITCall32_64.cpp', - 'jit/JITInlineMethods.h', + 'jit/JITExceptions.cpp', 'jit/JITOpcodes.cpp', 'jit/JITOpcodes32_64.cpp', 'jit/JITPropertyAccess.cpp', 'jit/JITPropertyAccess32_64.cpp', - 'jit/JITStubCall.h', 'jit/JITStubs.cpp', - 'jit/JSInterfaceJIT.h', - 'jit/SpecializedThunkJIT.h', 'jit/ThunkGenerators.cpp', - 'os-win32/WinMain.cpp', - 'os-win32/inttypes.h', - 'os-win32/stdbool.h', - 'os-win32/stdint.h', - 'parser/ASTBuilder.h', - 'parser/JSParser.cpp', - 'parser/JSParser.h', 'parser/Lexer.cpp', - 'parser/Lexer.h', - 'parser/NodeConstructors.h', - 'parser/NodeInfo.h', 'parser/Nodes.cpp', - 'parser/Nodes.h', 'parser/Parser.cpp', - 'parser/Parser.h', 'parser/ParserArena.cpp', - 'parser/ParserArena.h', 'parser/SourceProviderCache.cpp', - 'parser/SourceProviderCacheItem.h', - 'parser/SyntaxChecker.h', 'profiler/Profile.cpp', 'profiler/ProfileGenerator.cpp', - 'profiler/ProfileGenerator.h', 'profiler/ProfileNode.cpp', 'profiler/Profiler.cpp', - 'profiler/ProfilerServer.h', - 'profiler/ProfilerServer.mm', - 'qt/api/qscriptconverter_p.h', - 'qt/api/qscriptengine.cpp', - 'qt/api/qscriptengine.h', - 'qt/api/qscriptengine_p.cpp', - 'qt/api/qscriptengine_p.h', - 'qt/api/qscriptfunction.cpp', - 'qt/api/qscriptfunction_p.h', - 'qt/api/qscriptoriginalglobalobject_p.h', - 'qt/api/qscriptprogram.cpp', - 'qt/api/qscriptprogram.h', - 'qt/api/qscriptprogram_p.h', - 'qt/api/qscriptstring.cpp', - 'qt/api/qscriptstring.h', - 'qt/api/qscriptstring_p.h', - 'qt/api/qscriptsyntaxcheckresult.cpp', - 'qt/api/qscriptsyntaxcheckresult.h', - 'qt/api/qscriptsyntaxcheckresult_p.h', - 'qt/api/qscriptvalue.cpp', - 'qt/api/qscriptvalue.h', - 'qt/api/qscriptvalue_p.h', - 'qt/api/qscriptvalueiterator.cpp', - 'qt/api/qscriptvalueiterator.h', - 'qt/api/qscriptvalueiterator_p.h', - 'qt/api/qtscriptglobal.h', - 'qt/benchmarks/qscriptengine/tst_qscriptengine.cpp', - 'qt/benchmarks/qscriptvalue/tst_qscriptvalue.cpp', - 'qt/tests/qscriptengine/tst_qscriptengine.cpp', - 'qt/tests/qscriptstring/tst_qscriptstring.cpp', - 'qt/tests/qscriptvalue/tst_qscriptvalue.cpp', - 'qt/tests/qscriptvalue/tst_qscriptvalue.h', - 'qt/tests/qscriptvalue/tst_qscriptvalue_generated_comparison.cpp', - 'qt/tests/qscriptvalue/tst_qscriptvalue_generated_init.cpp', - 'qt/tests/qscriptvalue/tst_qscriptvalue_generated_istype.cpp', - 'qt/tests/qscriptvalue/tst_qscriptvalue_generated_totype.cpp', - 'qt/tests/qscriptvalueiterator/tst_qscriptvalueiterator.cpp', 'runtime/ArgList.cpp', 'runtime/Arguments.cpp', - 'runtime/Arguments.h', 'runtime/ArrayConstructor.cpp', - 'runtime/ArrayConstructor.h', 'runtime/ArrayPrototype.cpp', - 'runtime/BatchedTransitionOptimizer.h', 'runtime/BooleanConstructor.cpp', - 'runtime/BooleanConstructor.h', 'runtime/BooleanObject.cpp', 'runtime/BooleanPrototype.cpp', - 'runtime/BooleanPrototype.h', 'runtime/CallData.cpp', 'runtime/CommonIdentifiers.cpp', 'runtime/Completion.cpp', 'runtime/ConstructData.cpp', 'runtime/DateConstructor.cpp', - 'runtime/DateConstructor.h', 'runtime/DateConversion.cpp', - 'runtime/DateConversion.h', 'runtime/DateInstance.cpp', 'runtime/DatePrototype.cpp', - 'runtime/DatePrototype.h', 'runtime/Error.cpp', 'runtime/ErrorConstructor.cpp', - 'runtime/ErrorConstructor.h', 'runtime/ErrorInstance.cpp', - 'runtime/ErrorInstance.h', 'runtime/ErrorPrototype.cpp', - 'runtime/ErrorPrototype.h', 'runtime/ExceptionHelpers.cpp', 'runtime/Executable.cpp', - 'runtime/Executable.h', 'runtime/FunctionConstructor.cpp', 'runtime/FunctionPrototype.cpp', 'runtime/GCActivityCallback.cpp', 'runtime/GCActivityCallbackCF.cpp', 'runtime/GetterSetter.cpp', - 'runtime/GetterSetter.h', 'runtime/Identifier.cpp', 'runtime/InitializeThreading.cpp', 'runtime/InternalFunction.cpp', - 'runtime/JSAPIValueWrapper.cpp', 'runtime/JSActivation.cpp', - 'runtime/JSActivation.h', + 'runtime/JSAPIValueWrapper.cpp', 'runtime/JSArray.cpp', - 'runtime/JSByteArray.cpp', + 'runtime/JSBoundFunction.cpp', 'runtime/JSCell.cpp', + 'runtime/JSChunk.cpp', + 'runtime/JSDateMath.cpp', 'runtime/JSFunction.cpp', 'runtime/JSGlobalData.cpp', 'runtime/JSGlobalObject.cpp', 'runtime/JSGlobalObjectFunctions.cpp', - 'runtime/JSGlobalObjectFunctions.h', + 'runtime/JSGlobalThis.cpp', 'runtime/JSLock.cpp', 'runtime/JSNotAnObject.cpp', - 'runtime/JSNotAnObject.h', - 'runtime/JSNumberCell.cpp', - 'runtime/JSONObject.cpp', - 'runtime/JSONObject.h', 'runtime/JSObject.cpp', - 'runtime/JSObjectWithGlobalObject.cpp', + 'runtime/JSONObject.cpp', 'runtime/JSPropertyNameIterator.cpp', - 'runtime/JSPropertyNameIterator.h', 'runtime/JSStaticScopeObject.cpp', - 'runtime/JSStaticScopeObject.h', 'runtime/JSString.cpp', - 'runtime/JSStringBuilder.h', + 'runtime/JSStringJoiner.cpp', 'runtime/JSValue.cpp', 'runtime/JSVariableObject.cpp', 'runtime/JSWrapperObject.cpp', - 'runtime/JSZombie.cpp', - 'runtime/JSZombie.h', 'runtime/LiteralParser.cpp', - 'runtime/LiteralParser.h', 'runtime/Lookup.cpp', 'runtime/MathObject.cpp', 'runtime/MemoryStatistics.cpp', 'runtime/NativeErrorConstructor.cpp', - 'runtime/NativeErrorConstructor.h', 'runtime/NativeErrorPrototype.cpp', - 'runtime/NativeErrorPrototype.h', 'runtime/NumberConstructor.cpp', - 'runtime/NumberConstructor.h', 'runtime/NumberObject.cpp', 'runtime/NumberPrototype.cpp', 'runtime/ObjectConstructor.cpp', - 'runtime/ObjectConstructor.h', 'runtime/ObjectPrototype.cpp', 'runtime/Operations.cpp', + 'runtime/Options.cpp', 'runtime/PropertyDescriptor.cpp', 'runtime/PropertyNameArray.cpp', 'runtime/PropertySlot.cpp', 'runtime/RegExp.cpp', 'runtime/RegExpCache.cpp', + 'runtime/RegExpCachedResult.cpp', 'runtime/RegExpConstructor.cpp', - 'runtime/RegExpConstructor.h', - 'runtime/RegExpMatchesArray.h', + 'runtime/RegExpMatchesArray.cpp', 'runtime/RegExpObject.cpp', 'runtime/RegExpPrototype.cpp', - 'runtime/RegExpPrototype.h', - 'runtime/RopeImpl.cpp', + 'runtime/SamplingCounter.cpp', 'runtime/ScopeChain.cpp', - 'runtime/ScopeChainMark.h', 'runtime/SmallStrings.cpp', 'runtime/StrictEvalActivation.cpp', - 'runtime/StrictEvalActivation.h', 'runtime/StringConstructor.cpp', - 'runtime/StringConstructor.h', 'runtime/StringObject.cpp', 'runtime/StringPrototype.cpp', 'runtime/StringRecursionChecker.cpp', - 'runtime/StringRecursionChecker.h', 'runtime/Structure.cpp', 'runtime/StructureChain.cpp', 'runtime/TimeoutChecker.cpp', - 'runtime/Tracing.d', - 'runtime/Tracing.h', 'runtime/UString.cpp', - 'runtime/UStringConcatenate.h', - 'wtf/Assertions.cpp', - 'wtf/ByteArray.cpp', - 'wtf/CryptographicallyRandomNumber.cpp', - 'wtf/CurrentTime.cpp', - 'wtf/DateMath.cpp', - 'wtf/DecimalNumber.cpp', - 'wtf/DynamicAnnotations.cpp', - 'wtf/DynamicAnnotations.h', - 'wtf/FastMalloc.cpp', - 'wtf/HashTable.cpp', - 'wtf/MD5.cpp', - 'wtf/MainThread.cpp', - 'wtf/MallocZoneSupport.h', - 'wtf/NullPtr.cpp', - 'wtf/OSAllocatorPosix.cpp', - 'wtf/OSAllocatorSymbian.cpp', - 'wtf/OSAllocatorWin.cpp', - 'wtf/OSRandomSource.cpp', - 'wtf/OSRandomSource.h', - 'wtf/PageAllocationAligned.cpp', - 'wtf/PageAllocatorSymbian.h', - 'wtf/PageBlock.cpp', - 'wtf/RandomNumber.cpp', - 'wtf/RandomNumberSeed.h', - 'wtf/RefCountedLeakCounter.cpp', - 'wtf/SHA1.cpp', - 'wtf/SHA1.h', - 'wtf/SegmentedVector.h', - 'wtf/SizeLimits.cpp', - 'wtf/StackBounds.cpp', - 'wtf/StringExtras.cpp', - 'wtf/TCPackedCache.h', - 'wtf/TCPageMap.h', - 'wtf/TCSpinLock.h', - 'wtf/TCSystemAlloc.cpp', - 'wtf/TCSystemAlloc.h', - 'wtf/ThreadFunctionInvocation.h', - 'wtf/ThreadIdentifierDataPthreads.cpp', - 'wtf/ThreadIdentifierDataPthreads.h', - 'wtf/ThreadSpecificWin.cpp', - 'wtf/Threading.cpp', - 'wtf/ThreadingNone.cpp', - 'wtf/ThreadingPthreads.cpp', - 'wtf/ThreadingWin.cpp', - 'wtf/TypeTraits.cpp', - 'wtf/WTFThreadData.cpp', - 'wtf/android/AndroidThreading.h', - 'wtf/android/MainThreadAndroid.cpp', - 'wtf/brew/MainThreadBrew.cpp', - 'wtf/brew/OwnPtrBrew.cpp', - 'wtf/brew/RefPtrBrew.h', - 'wtf/brew/ShellBrew.h', - 'wtf/brew/StringBrew.cpp', - 'wtf/brew/SystemMallocBrew.h', - 'wtf/chromium/ChromiumThreading.h', - 'wtf/chromium/MainThreadChromium.cpp', - 'wtf/dtoa.cpp', - 'wtf/efl/MainThreadEfl.cpp', - 'wtf/gobject/GOwnPtr.cpp', - 'wtf/gobject/GOwnPtr.h', - 'wtf/gobject/GRefPtr.cpp', - 'wtf/gobject/GRefPtr.h', - 'wtf/gobject/GTypedefs.h', - 'wtf/gtk/MainThreadGtk.cpp', - 'wtf/gtk/ThreadingGtk.cpp', - 'wtf/haiku/MainThreadHaiku.cpp', - 'wtf/haiku/StringHaiku.cpp', - 'wtf/mac/MainThreadMac.mm', - 'wtf/qt/MainThreadQt.cpp', - 'wtf/qt/StringQt.cpp', - 'wtf/qt/ThreadingQt.cpp', - 'wtf/text/AtomicString.cpp', - 'wtf/text/CString.cpp', - 'wtf/text/StringBuilder.cpp', - 'wtf/text/StringImpl.cpp', - 'wtf/text/StringStatics.cpp', - 'wtf/text/WTFString.cpp', - 'wtf/unicode/CollatorDefault.cpp', - 'wtf/unicode/UTF8.cpp', - 'wtf/unicode/UnicodeMacrosFromICU.h', - 'wtf/unicode/brew/UnicodeBrew.cpp', - 'wtf/unicode/brew/UnicodeBrew.h', - 'wtf/unicode/glib/UnicodeGLib.cpp', - 'wtf/unicode/glib/UnicodeGLib.h', - 'wtf/unicode/icu/CollatorICU.cpp', - 'wtf/unicode/qt4/UnicodeQt4.h', - 'wtf/unicode/wince/UnicodeWinCE.cpp', - 'wtf/unicode/wince/UnicodeWinCE.h', - 'wtf/url/api/ParsedURL.cpp', - 'wtf/url/api/ParsedURL.h', - 'wtf/url/api/URLString.h', - 'wtf/url/src/RawURLBuffer.h', - 'wtf/url/src/URLBuffer.h', - 'wtf/url/src/URLCharacterTypes.cpp', - 'wtf/url/src/URLCharacterTypes.h', - 'wtf/url/src/URLComponent.h', - 'wtf/url/src/URLEscape.cpp', - 'wtf/url/src/URLEscape.h', - 'wtf/url/src/URLParser.h', - 'wtf/url/src/URLQueryCanonicalizer.h', - 'wtf/url/src/URLSegments.cpp', - 'wtf/url/src/URLSegments.h', - 'wtf/win/MainThreadWin.cpp', - 'wtf/win/OwnPtrWin.cpp', - 'wtf/wince/FastMallocWinCE.h', - 'wtf/wince/MemoryManager.cpp', - 'wtf/wince/MemoryManager.h', - 'wtf/wx/MainThreadWx.cpp', - 'wtf/wx/StringWx.cpp', + 'tools/CodeProfile.cpp', + 'tools/CodeProfiling.cpp', + 'yarr/YarrCanonicalizeUCS2.cpp', 'yarr/YarrInterpreter.cpp', 'yarr/YarrJIT.cpp', - 'yarr/YarrJIT.h', - 'yarr/YarrParser.h', 'yarr/YarrPattern.cpp', 'yarr/YarrSyntaxChecker.cpp', - 'yarr/YarrSyntaxChecker.h', ], 'javascriptcore_derived_source_files': [ '<(PRODUCT_DIR)/DerivedSources/JavaScriptCore/Lexer.lut.h', diff --git a/JavaScriptCore.order b/JavaScriptCore.order index 275f35c..3a45007 100644 --- a/JavaScriptCore.order +++ b/JavaScriptCore.order @@ -42,66 +42,39 @@ __ZN3WTF10StringImpl6createEPKtj __ZN3WTF12isMainThreadEv __ZN3WTF10StringImplD1Ev __ZN3WTF10StringImplD2Ev +__ZN3WTF6String6numberEy +__ZN3WTF6String6formatEPKcz +__ZN3WTF6VectorIcLm256EE4growEm +__ZN3WTF13tryFastMallocEm +__ZN3WTF15ThreadConditionC1Ev +__ZN3WTF10StringImpl11reverseFindEtj +__ZNK3WTF6String9substringEjj +__ZN3WTF10StringImpl9substringEjj +__ZN3WTF7CString16newUninitializedEmRPc +__ZN3WTF7CString11mutableDataEv +__ZN3WTF7CString18copyBufferIfNeededEv __ZN3WTF5Mutex4lockEv -__ZNK3WTF6String14threadsafeCopyEv -__ZNK3WTF10StringImpl14threadsafeCopyEv __ZN3WTF5Mutex6unlockEv +__ZN3WTF10StringImpl12sharedBufferEv __ZN3WTF10StringImpl8endsWithEPS0_b -__ZN3WTF13tryFastMallocEm -__ZN3WTF7CString16newUninitializedEmRPc -__ZN3WTF15ThreadConditionC1Ev __ZN3WTF12createThreadEPFPvS0_ES0_PKc +__ZN3WTF12createThreadEPFvPvES0_PKc __ZN3WTF20createThreadInternalEPFPvS0_ES0_PKc __ZN3WTFL35establishIdentifierForPthreadHandleERKP17_opaque_pthread_t __ZN3WTF9HashTableIjSt4pairIjP17_opaque_pthread_tENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSA_IS3_EEEESB_E6rehashEi -__ZN3WTF15ThreadCondition6signalEv __ZN3WTFL16threadEntryPointEPv __ZN3WTF31initializeCurrentThreadInternalEPKc __ZN3WTF20ThreadIdentifierData10initializeEj __ZN3WTF20ThreadIdentifierData23initializeKeyOnceHelperEv __ZN3WTF5MutexD1Ev -__ZNK3WTF6String4utf8Eb -__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b -__ZN3WTF7CStringC1EPKcm -__ZN3WTF7CString4initEPKcm -__ZN3WTF15ThreadCondition9timedWaitERNS_5MutexEd -__ZN3WTF12AtomicString4initEv -__ZN3WTF12AtomicString3addEPKc -__ZN3WTF9HashTableIPNS_10StringImplES2_NS_17IdentityExtractorIS2_EENS_10StringHashENS_10HashTraitsIS2_EES7_E6rehashEi -__ZNK3WTF6String9substringEjj -__ZNK3WTF6String5lowerEv -__ZN3WTF10StringImpl5lowerEv -__ZN3WTF5equalEPKNS_10StringImplEPKc -__ZN3WTF6StringC1EPKcj -__ZN3WTF12AtomicString3addEPKtj -__ZN3WTF17equalIgnoringCaseEPNS_10StringImplEPKc -__ZN3WTF6String6appendERKS0_ -__ZN3WTF6StringC1EPKtj -__ZN3WTF18charactersToDoubleEPKtmPbS2_ -__ZN3WTF6strtodEPKcPPc -__ZN3WTF10StringImpl22containsOnlyWhitespaceEv -__ZN3WTF12AtomicString11addSlowCaseEPNS_10StringImplE -__ZN3WTF12AtomicString6removeEPNS_10StringImplE -__ZN3WTF6String6numberEy -__ZN3WTF6String6formatEPKcz -__ZN3WTF6VectorIcLm256EE4growEm -__ZN3WTF10StringImpl11reverseFindEtj -__ZN3WTF10StringImpl9substringEjj -__ZN3WTF7CString11mutableDataEv -__ZN3WTF7CString18copyBufferIfNeededEv -__ZNK3WTF6String17crossThreadStringEv -__ZN3WTF10StringImpl17crossThreadStringEv -__ZN3WTF10StringImpl12sharedBufferEv __ZN3WTF6String29charactersWithNullTerminationEv __ZN3WTF10StringImpl34createWithTerminatingNullCharacterERKS0_ __ZN3WTF13currentThreadEv __ZN3WTF20ThreadIdentifierData10identifierEv __ZNK3WTF6String15stripWhiteSpaceEv __ZN3WTF10StringImpl15stripWhiteSpaceEv -_JSStringCreateWithCFString -_JSStringRetain -_JSStringRelease -__ZN3WTF6String6numberEi +__ZN3WTF6StringC1EPKt +__ZN3WTF6StringC2EPKt __ZN3WTF16callOnMainThreadEPFvPvES0_ __ZN3WTF5DequeINS_19FunctionWithContextELm0EE14expandCapacityEv __ZN3WTF37scheduleDispatchFunctionsOnMainThreadEv @@ -109,31 +82,40 @@ __ZN3WTF15ThreadCondition4waitERNS_5MutexE __ZN3WTF6String8fromUTF8EPKc __ZN3WTF6String8fromUTF8EPKcm __ZN3WTF7Unicode18convertUTF8ToUTF16EPPKcS2_PPtS4_b +__ZN3WTF15ThreadCondition6signalEv __ZN3WTF7CStringC1EPKc +__ZN3WTF7CString4initEPKcm +__ZNK3WTF6String4utf8Eb +__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b +__ZN3WTF7CStringC1EPKcm __ZN3WTF11fastReallocEPvm +__ZN3WTF12AtomicString3addEPKc +__ZN3WTF9HashTableIPNS_10StringImplES2_NS_17IdentityExtractorIS2_EENS_10StringHashENS_10HashTraitsIS2_EES7_E6rehashEi +__ZN3WTF12AtomicString3addEPKtj +__ZN3WTF10StringImpl4findEtj +__ZN3WTF25TCMalloc_Central_FreeList11InsertRangeEPvS1_i +__ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansEPv -[WTFMainThreadCaller call] __ZN3WTF31dispatchFunctionsFromMainThreadEv -__ZN3WTF25TCMalloc_Central_FreeList11InsertRangeEPvS1_i -__ZN3WTF25TCMalloc_Central_FreeList11ShrinkCacheEib __ZN3WTF15ThreadCondition9broadcastEv -__ZN3WTF20TCMalloc_ThreadCache18DestroyThreadCacheEPv -__ZN3WTF20TCMalloc_ThreadCache11DeleteCacheEPS0_ -__ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansEPv -__ZN3WTF20ThreadIdentifierData8destructEPv -__ZN3WTF31clearPthreadHandleForIdentifierEj +__ZN3WTF15ThreadCondition9timedWaitERNS_5MutexEd __ZN3WTF12detachThreadEj __ZN3WTFL26pthreadHandleForIdentifierEj -__ZN3WTF14FastMallocZone4sizeEP14_malloc_zone_tPKv -__ZN3WTF10StringImpl4findEtj -___initializeScavenger_block_invoke_1 -__ZN3WTF23waitForThreadCompletionEjPPv -__ZN3WTF22cancelCallOnMainThreadEPFvPvES0_ -__ZN3WTF6StringC1EPKt -__ZN3WTF6StringC2EPKt +__ZN3WTF20ThreadIdentifierData8destructEPv +__ZN3WTF31clearPthreadHandleForIdentifierEj +__ZN3WTF20TCMalloc_ThreadCache18DestroyThreadCacheEPv +__ZN3WTF20TCMalloc_ThreadCache11DeleteCacheEPS0_ +__ZN3WTF25TCMalloc_Central_FreeList11ShrinkCacheEib +__ZN3WTFL10timerFiredEP16__CFRunLoopTimerPv +__ZNK3WTF6String5lowerEv +__ZN3WTF10StringImpl5lowerEv __ZNK3WTF6String5splitEtRNS_6VectorIS0_Lm0EEE __ZNK3WTF6String5splitERKS0_bRNS_6VectorIS0_Lm0EEE __ZN3WTF10StringImpl4findEPS0_j __ZN3WTF6VectorINS_6StringELm0EE14expandCapacityEm +__ZN3WTF6StringC1EPKcj +__ZN3WTF12AtomicString11addSlowCaseEPNS_10StringImplE +__ZN3WTF12AtomicString6removeEPNS_10StringImplE _JSGlobalContextCreate __ZN3JSC6JSLock4lockENS_14JSLockBehaviorE __ZN3JSCL17createJSLockCountEv @@ -286,7 +268,6 @@ __ZN3JSC12X86Assembler7addl_irEiNS_12X86Registers10RegisterIDE __ZN3JSC14MacroAssembler4jumpENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5LabelE __ZN3WTF15deleteAllValuesIPN3JSC4Yarr18PatternDisjunctionELm4EEEvRKNS_6VectorIT_XT0_EEE __ZN3WTF15deleteAllValuesIPN3JSC4Yarr14CharacterClassELm0EEEvRKNS_6VectorIT_XT0_EEE -__ZN3JSC12RegExpObjectC2EPNS_14JSGlobalObjectEPNS_9StructureEN3WTF17NonNullPassRefPtrINS_6RegExpEEE __ZN3JSC14ErrorPrototypeC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE __ZN3JSC14ErrorPrototypeC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureE __ZN3JSC13ErrorInstanceC2EPNS_12JSGlobalDataEPNS_9StructureE @@ -330,9 +311,8 @@ _JSGlobalContextRetain __ZN3JSC14MachineThreads16addCurrentThreadEv __ZN3JSC6JSLockC1EPNS_9ExecStateE __ZN3JSC4Heap7protectENS_7JSValueE -__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E4findIS3_NS_22IdentityHashTranslatorIS3_S5_S9_EEEENS_17HashTableIteratorIS3_S5_S7_S9_SE_SC_EERKT_ -__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi __ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE +_JSStringCreateWithCFString _JSValueMakeFromJSONString __ZNK14OpaqueJSString7ustringEv __ZN3JSC7UStringC1EPKtj @@ -343,11 +323,12 @@ __ZN3WTF13StringBuilder6appendEPKtj __ZN3WTF13StringBuilder19appendUninitializedEj __ZN3WTF13StringBuilder14allocateBufferEPKtj __ZN3WTF13StringBuilder11shrinkToFitEv -__ZN3WTF13StringBuilder11reifyStringEv -__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh +__ZNK3WTF13StringBuilder11reifyStringEv +__ZNK3WTF13StringBuilder9canShrinkEv __ZN3JSC7JSArray4pushEPNS_9ExecStateENS_7JSValueE __ZN3JSC7JSArray20increaseVectorLengthEj __ZN3WTF14tryFastReallocEPvm +_JSStringRelease _JSValueIsNull _JSValueIsUndefined _JSValueIsBoolean @@ -375,17 +356,12 @@ _JSValueToStringCopy __ZNK3JSC7JSValue8toStringEPNS_9ExecStateE __ZN14OpaqueJSString6createERKN3JSC7UStringE _JSStringCopyCFString -_JSObjectCopyPropertyNames -__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE -__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE -__ZN3JSC9Structure16getPropertyNamesERNS_12JSGlobalDataERNS_17PropertyNameArrayENS_15EnumerationModeE -__ZN3JSC9ExecState20objectPrototypeTableEPS0_ -__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE -_JSPropertyNameArrayGetCount -_JSPropertyNameArrayRelease _JSGlobalContextRelease __ZN3JSC4Heap9unprotectENS_7JSValueE +__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E4findIS3_NS_22IdentityHashTranslatorIS3_S5_S9_EEEENS_17HashTableIteratorIS3_S5_S7_S9_SE_SC_EERKT_ +__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi __ZN3JSC10HandleHeap4growEv +__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh __ZN3JSC37DefaultGCActivityCallbackPlatformData7triggerEP16__CFRunLoopTimerPv __ZN3JSC4Heap17collectAllGarbageEv __ZN3JSC12JSGlobalData23recompileAllJSFunctionsEv @@ -411,7 +387,10 @@ __ZN3JSC10HandleHeap19finalizeWeakHandlesEv __ZN3JSC11MarkedSpace5resetEv __ZN3JSC11MarkedSpace5sweepEv __ZN3JSC11MarkedBlock5sweepEv -__ZN3JSC9StructureD1Ev +__ZN3JSC14JSGlobalObjectD1Ev +__ZN3JSC14JSGlobalObjectD2Ev +__ZN3WTF9HashTableINS_6RefPtrI21OpaqueJSWeakObjectMapEES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E15deallocateTableEPS3_i +__ZN3WTF9HashTableINS_6RefPtrI21OpaqueJSWeakObjectMapEES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi __ZN3JSC8JSStringD1Ev __ZN3JSC10JSFunctionD1Ev __ZN3JSC14ArrayPrototypeD1Ev @@ -419,6 +398,20 @@ __ZN3JSC7JSArrayD2Ev __ZN3JSC13DatePrototypeD1Ev __ZN3JSC13JSFinalObjectD1Ev __ZN3JSC7JSArrayD1Ev +__ZN3JSC9StructureD1Ev +__ZN3JSC16NativeExecutableD1Ev +__ZN3JSC20NativeErrorPrototypeD1Ev +__ZN3JSC10MathObjectD1Ev +__ZN3JSC10JSONObjectD1Ev +__ZN3JSC17FunctionPrototypeD1Ev +__ZN3JSC17ObjectConstructorD1Ev +__ZN3JSC19FunctionConstructorD1Ev +__ZN3JSC16ArrayConstructorD1Ev +__ZN3JSC17StringConstructorD1Ev +__ZN3JSC18BooleanConstructorD1Ev +__ZN3JSC17NumberConstructorD1Ev +__ZN3JSC15DateConstructorD1Ev +__ZN3JSC16ErrorConstructorD1Ev __ZN3JSC14ScopeChainNodeD1Ev __ZN3JSC15ObjectPrototypeD1Ev __ZN3JSC15StringPrototypeD1Ev @@ -430,94 +423,25 @@ __ZN3JSC6RegExpD1Ev __ZN3JSC14ErrorPrototypeD1Ev __ZN3JSC17RegExpConstructorD1Ev __ZN3JSC22NativeErrorConstructorD1Ev -__ZN3JSC17FunctionPrototypeD1Ev -__ZN3JSC17ObjectConstructorD1Ev -__ZN3JSC19FunctionConstructorD1Ev -__ZN3JSC16ArrayConstructorD1Ev -__ZN3JSC17StringConstructorD1Ev -__ZN3JSC18BooleanConstructorD1Ev -__ZN3JSC17NumberConstructorD1Ev -__ZN3JSC15DateConstructorD1Ev -__ZN3JSC16ErrorConstructorD1Ev -__ZN3JSC20NativeErrorPrototypeD1Ev -__ZN3JSC10MathObjectD1Ev -__ZN3JSC10JSONObjectD1Ev -__ZN3JSC16NativeExecutableD1Ev -__ZN3JSC14JSGlobalObjectD1Ev -__ZN3JSC14JSGlobalObjectD2Ev -__ZN3WTF9HashTableINS_6RefPtrI21OpaqueJSWeakObjectMapEES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E15deallocateTableEPS3_i -__ZN3WTF9HashTableINS_6RefPtrI21OpaqueJSWeakObjectMapEES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi __ZN3JSC11MarkedSpace6shrinkEv __ZN3JSC11MarkedSpace10freeBlocksERN3WTF16DoublyLinkedListINS_11MarkedBlockEEE __ZN3JSC11MarkedBlock7destroyEPS0_ __ZN3WTF21PageAllocationAligned10deallocateEv __ZNK3JSC11MarkedSpace4sizeEv -__Z22TCMalloc_SystemReleasePvm -__Z21TCMalloc_SystemCommitPvm -__ZN3WTFL10timerFiredEP16__CFRunLoopTimerPv -__ZN3WTF15ThreadConditionD1Ev -__ZNK3WTF6String5toIntEPb -__ZN3WTF10StringImpl5toIntEPb -__ZN3WTF15charactersToIntEPKtmPb -__ZN3WTF22charactersToUIntStrictEPKtmPbi -__ZN3WTF6VectorIN3JSC4Yarr11PatternTermELm0EE14expandCapacityEm -__ZN3JSC4Yarr6ParserINS0_22YarrPatternConstructorEE28CharacterClassParserDelegate20atomPatternCharacterEtb -__ZN3JSC4Yarr25CharacterClassConstructor14addSortedRangeERN3WTF6VectorINS0_14CharacterRangeELm0EEEtt -__ZN3WTF6VectorIN3JSC4Yarr14CharacterRangeELm0EE14expandCapacityEmPKS3_ -__ZN3WTF6VectorIN3JSC4Yarr14CharacterRangeELm0EE14expandCapacityEm -__ZN3JSC4Yarr6ParserINS0_22YarrPatternConstructorEE11parseEscapeILb1ENS3_28CharacterClassParserDelegateEEEbRT0_ -__ZN3JSC4Yarr25CharacterClassConstructor7putCharEt -__ZN3WTF6VectorItLm0EE14expandCapacityEm -__ZN3JSC4Yarr22YarrPatternConstructor21atomCharacterClassEndEv -__ZN3WTF6VectorIPN3JSC4Yarr14CharacterClassELm0EE14expandCapacityEm -__ZN3JSC4Yarr22YarrPatternConstructor20atomPatternCharacterEt -__ZN3JSC4Yarr6ParserINS0_22YarrPatternConstructorEE11parseEscapeILb0ES2_EEbRT0_ -__ZN3JSC4Yarr11byteCompileERNS0_11YarrPatternEPN3WTF20BumpPointerAllocatorE -__ZN3WTF6VectorIN3JSC4Yarr8ByteTermELm0EE14expandCapacityEm -__ZN3JSC4Yarr12ByteCompiler15emitDisjunctionEPNS0_18PatternDisjunctionEjj -__ZN3JSC4Yarr13newlineCreateEv -__ZN3JSC4Yarr14wordcharCreateEv -__ZN3JSC4Yarr9interpretEPNS0_15BytecodePatternEPKtjjPi -__ZN3JSC4Yarr11Interpreter16matchDisjunctionEPNS0_15ByteDisjunctionEPNS1_18DisjunctionContextEb -__ZN3WTF10StringImpl23reverseFindIgnoringCaseEPS0_j +__ZN3WTFL43initializeMainThreadToProcessMainThreadOnceEv +__ZN3WTF47initializeMainThreadToProcessMainThreadPlatformEv +__ZN3WTF5equalEPKNS_10StringImplEPKc +__ZN3WTF17equalIgnoringCaseEPNS_10StringImplEPKc +__ZN3WTF12AtomicString4initEv +__ZN3WTF6String6appendERKS0_ +__ZN3WTF6StringC1EPKtj +__ZN3WTF18charactersToDoubleEPKtmPbS2_ +__ZN3WTF6strtodEPKcPPc +__ZN3WTF10StringImpl22containsOnlyWhitespaceEv +__ZN3WTF10StringImpl11reverseFindEPS0_j +__ZN3WTF17equalIgnoringCaseEPNS_10StringImplES1_ __ZN3JSC12JSGlobalData12createLeakedENS_15ThreadStackTypeE -__ZN3WTF10StringImpl5adoptERNS_12StringBufferE -__ZN3WTF10StringImpl7replaceEtt -__ZNK3WTF6String16removeCharactersEPFbtE -__ZN3WTF10StringImpl16removeCharactersEPFbtE -__ZN3WTF10StringImpl4findEPFbtEj __ZN3JSC24JSObjectWithGlobalObjectC2ERNS_12JSGlobalDataEPNS_14JSGlobalObjectEPNS_9StructureE -_JSContextGetGlobalContext -_JSWeakObjectMapCreate -__ZN3JSC14JSGlobalObject17weakMapsFinalizerEv -_JSWeakObjectMapGet -_JSClassCreate -__ZN13OpaqueJSClass6createEPK17JSClassDefinition -__ZN13OpaqueJSClassC2EPK17JSClassDefinitionPS_ -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_P16StaticValueEntryENS_18PairFirstExtractorIS7_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSC_IS6_EEEESD_E6expandEv -_JSClassRetain -_JSObjectMake -__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEEC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEP13OpaqueJSClassPv -__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE4initEPNS_9ExecStateE -__ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE -_JSObjectGetPrivate -__ZN3JSC6JSLock12DropAllLocksD1Ev -__ZN13OpaqueJSClass9prototypeEPN3JSC9ExecStateE -__ZN13OpaqueJSClass11contextDataEPN3JSC9ExecStateE -__ZN3WTF9HashTableIP13OpaqueJSClassSt4pairIS2_P24OpaqueJSClassContextDataENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS5_EEEESD_E6expandEv -__ZN24OpaqueJSClassContextDataC2ERN3JSC12JSGlobalDataEP13OpaqueJSClass -_JSWeakObjectMapSet -__ZN3WTF9HashTableIPvSt4pairIS1_PN3JSC7JSValueEENS_18PairFirstExtractorIS6_EENS_7PtrHashIS1_EENS_14PairHashTraitsINS_10HashTraitsIS1_EENSC_IS5_EEEESD_E6rehashEi -_JSObjectSetProperty -__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE -__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC15ObjectPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj -__ZN3JSC10Identifier8toUInt32ERKNS_7UStringERb -__ZN3WTF12AtomicString4findEPKtjj -__ZNK3WTF9HashTableIPNS_10StringImplES2_NS_17IdentityExtractorIS2_EENS_10StringHashENS_10HashTraitsIS2_EES7_E4findINS_17HashAndCharactersENS_24HashSetTranslatorAdapterIS2_S7_SA_NS_27HashAndCharactersTranslatorEEEEENS_22HashTableConstIteratorIS2_S2_S4_S5_S7_S7_EERKT_ -__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj -__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE __ZN3JSC8evaluateEPNS_9ExecStateEPNS_14ScopeChainNodeERKNS_10SourceCodeENS_7JSValueE __ZN3JSC17ProgramExecutableC1EPNS_9ExecStateERKNS_10SourceCodeE __ZN3JSC11Interpreter7executeEPNS_17ProgramExecutableEPNS_9ExecStateEPNS_14ScopeChainNodeEPNS_8JSObjectE @@ -533,75 +457,19 @@ __ZN3JSC8JSParserC2EPNS_5LexerEPNS_12JSGlobalDataEPNS_18FunctionParametersEbbPNS __ZN3JSC8JSParser9pushScopeEv __ZN3JSC8JSParser4nextENS_5Lexer7LexTypeE __ZN3JSC5Lexer3lexEPNS_11JSTokenDataEPNS_11JSTokenInfoENS0_7LexTypeEb -__ZN3WTF15SegmentedVectorIN3JSC10IdentifierELm64EE6appendIS2_EEvRKT_ __ZN3JSC8JSParser12parseProgramEv __ZNK3JSC19SourceProviderCache8byteSizeEv __ZN3WTF6VectorIPN3JSC20ParserArenaDeletableELm0EE15reserveCapacityEm __ZN3JSC8JSParser19parseSourceElementsILNS0_18SourceElementsModeE0ENS_10ASTBuilderEEENT0_14SourceElementsERS4_ __ZN3JSC8JSParser14parseStatementINS_10ASTBuilderEEENT_9StatementERS3_RPKNS_10IdentifierE -__ZN3JSC8JSParser24parseFunctionDeclarationINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3JSC8JSParser17parseFunctionInfoILNS0_20FunctionRequirementsE1ELb1ENS_10ASTBuilderEEEbRT1_RPKNS_10IdentifierERNS4_19FormalParameterListERNS4_12FunctionBodyERiSE_SE_ -__ZN3JSC8JSParser16declareParameterEPKNS_10IdentifierE -__ZN3JSC11ParserArena16allocateFreeableEm -__ZN3JSC11ParserArena20allocateFreeablePoolEv -__ZN3JSC8JSParser19parseSourceElementsILNS0_18SourceElementsModeE0ENS_13SyntaxCheckerEEENT0_14SourceElementsERS4_ -__ZN3JSC8JSParser14parseStatementINS_13SyntaxCheckerEEENT_9StatementERS3_RPKNS_10IdentifierE -__ZN3JSC8JSParser17parseForStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3JSC8JSParser5Scope15declareVariableEPKNS_10IdentifierE -__ZN3JSC5Lexer7record8Ei -__ZN3JSC8JSParser25parseAssignmentExpressionINS_13SyntaxCheckerEEENT_10ExpressionERS3_ -__ZN3JSC8JSParser21parseMemberExpressionINS_13SyntaxCheckerEEENT_10ExpressionERS3_ -__ZN3JSC8JSParser15parseExpressionINS_13SyntaxCheckerEEENT_10ExpressionERS3_ -__ZN3WTF7HashSetINS_6RefPtrINS_10StringImplEEEN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EEE3addERKS3_ -__ZN3JSC8JSParser16parseIfStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3JSC8JSParser31parseExpressionOrLabelStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3JSC5Lexer16nextTokenIsColonEv -__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEb +__ZN3JSC6Parser16didFinishParsingEPNS_14SourceElementsEPNS_15ParserArenaDataIN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEEEPNS3_INS5_IPNS_16FunctionBodyNodeELm0EEEEEjiiRNS4_7HashSetINS4_6RefPtrINS4_10StringImplEEENS_17IdentifierRepHashENS4_10HashTraitsISM_EEEE +__ZN3JSC11ParserArenaD1Ev +__ZN3JSC5Lexer5clearEv +__ZN3JSC11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISL_EEEERKNS_10SourceCodeEji +__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS9_IPNS_16FunctionBodyNodeELm0EEERNS8_7HashSetINS8_6RefPtrINS8_10StringImplEEENS_17IdentifierRepHashENS8_10HashTraitsISO_EEEEji __ZN3JSC11ParserArena14derefWithArenaEN3WTF10PassRefPtrINS_21ParserArenaRefCountedEEE -__ZN3WTF14deleteOwnedPtrIN3JSC23SourceProviderCacheItemEEEvPT_ -__ZN3JSC8JSParser5Scope29copyCapturedVariablesToVectorERKN3WTF7HashSetINS2_6RefPtrINS2_10StringImplEEENS_17IdentifierRepHashENS2_10HashTraitsIS6_EEEERNS2_6VectorIS6_Lm0EEE -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEES3_NS_17IdentityExtractorIS3_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EES9_E13isEmptyBucketERKS3_ -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEES3_NS_17IdentityExtractorIS3_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EES9_E15deallocateTableEPS3_i -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEES3_NS_17IdentityExtractorIS3_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EES9_E6expandEv -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEES3_NS_17IdentityExtractorIS3_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EES9_E6rehashEi -__ZN3WTF6VectorINS_6RefPtrINS_10StringImplEEELm0EE14expandCapacityEm -__ZN3JSC8JSParser5ScopeD1Ev -__ZN3JSC19SourceProviderCache3addEiN3WTF10PassOwnPtrINS_23SourceProviderCacheItemEEEj -__ZN3WTF9HashTableIiSt4pairIiPN3JSC23SourceProviderCacheItemEENS_18PairFirstExtractorIS5_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIiEENSB_IS4_EEEESC_E6expandEv -__ZN3JSC5Lexer10sourceCodeEiii -__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeERKNS_10IdentifierE -__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEm -__ZN3JSC16FunctionBodyNode13finishParsingEN3WTF10PassRefPtrINS_18FunctionParametersEEERKNS_10IdentifierE -__ZN3WTF6VectorIPN3JSC16FunctionBodyNodeELm0EE15reserveCapacityEm -__ZN3JSC13StatementNode6setLocEii -__ZN3JSC14SourceElements6appendEPNS_13StatementNodeE -__ZNK3JSC13StatementNode16isEmptyStatementEv -__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14expandCapacityEm -__ZN3JSC8JSParser21parseConstDeclarationINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3WTF6VectorISt4pairIPKN3JSC10IdentifierEjELm0EE15reserveCapacityEm -__ZN3JSC8JSParser25parseAssignmentExpressionINS_10ASTBuilderEEENT_10ExpressionERS3_ -__ZN3JSC8JSParser21parseMemberExpressionINS_10ASTBuilderEEENT_10ExpressionERS3_ -__ZN3JSC5Lexer10scanRegExpERPKNS_10IdentifierES4_t -__ZN3JSC4Yarr11checkSyntaxERKNS_7UStringE -__ZN3JSC4Yarr6ParserINS0_13SyntaxCheckerEE5parseEv -__ZN3JSC4Yarr6ParserINS0_13SyntaxCheckerEE11parseEscapeILb1ENS3_28CharacterClassParserDelegateEEEbRT0_ -__ZN3JSC8JSParser20parseReturnStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3WTF6VectorIiLm0EE14expandCapacityEm -__ZN3JSC8JSParser19parseVarDeclarationINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3JSC8JSParser17parseFunctionInfoILNS0_20FunctionRequirementsE0ELb0ENS_13SyntaxCheckerEEEbRT1_RPKNS_10IdentifierERNS4_19FormalParameterListERNS4_12FunctionBodyERiSE_SE_ -__ZN3JSC8JSParser19parseWhileStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3JSC10ASTBuilder20makeFunctionCallNodeEPNS_14ExpressionNodeEPNS_13ArgumentsNodeEiii -__ZNK3JSC11ResolveNode10isLocationEv -__ZNK3JSC11ResolveNode13isResolveNodeEv -__ZN3WTF6VectorISt4pairIiiELm0EE14expandCapacityEm -__ZN3JSC8JSParser22parseContinueStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3JSC8JSParser17parseTryStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3JSC6Parser16didFinishParsingEPNS_14SourceElementsEPNS_15ParserArenaDataIN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEEEPNS3_INS5_IPNS_16FunctionBodyNodeELm0EEEEEjiiRNS4_7HashSetINS4_6RefPtrINS4_10StringImplEEENS_17IdentifierRepHashENS4_10HashTraitsISM_EEEE -__ZN3JSC11ParserArenaD1Ev -__ZN3JSC5Lexer5clearEv -__ZN3JSC11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISL_EEEERKNS_10SourceCodeEji -__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS9_IPNS_16FunctionBodyNodeELm0EEERNS8_7HashSetINS8_6RefPtrINS8_10StringImplEEENS_17IdentifierRepHashENS8_10HashTraitsISO_EEEEji __ZN3JSC11ParserArena10removeLastEv +__ZN3JSC13StatementNode6setLocEii __ZN3JSC11ParserArena5resetEv __ZN3WTF6VectorIN3JSC10IdentifierELm64EE14shrinkCapacityEm __ZN3JSC9CodeBlockC2EPNS_16ScriptExecutableENS_8CodeTypeEPNS_14JSGlobalObjectEN3WTF10PassRefPtrINS_14SourceProviderEEEjPNS6_7HashMapINS6_6RefPtrINS6_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS6_10HashTraitsISD_EENS_26SymbolTableIndexHashTraitsEEEb @@ -610,16 +478,7 @@ __ZN3JSC17BytecodeGeneratorC2EPNS_11ProgramNodeEPNS_14ScopeChainNodeEPN3WTF7Hash __ZN3JSC17BytecodeGenerator10emitOpcodeENS_8OpcodeIDE __ZN3WTF6VectorIN3JSC11InstructionELm0EE15reserveCapacityEm __ZN3WTF15SegmentedVectorIN3JSC10RegisterIDELm32EE13ensureSegmentEmm -__ZN3JSC8JSObject12removeDirectERNS_12JSGlobalDataERKNS_10IdentifierE -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS5_26SymbolTableIndexHashTraitsEEESD_E13isEmptyBucketERKS7_ -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS5_26SymbolTableIndexHashTraitsEEESD_E6expandEv -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS5_26SymbolTableIndexHashTraitsEEESD_E6rehashEi -__ZN3WTF9HashTableIPNS_10StringImplES2_NS_17IdentityExtractorIS2_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS2_EES8_E6rehashEi __ZN3JSC14JSGlobalObject15resizeRegistersEii -__ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE -__ZN3JSC18FunctionExecutableC1EPNS_9ExecStateERKNS_10IdentifierERKNS_10SourceCodeEbPNS_18FunctionParametersEbii -__ZN3JSC10JSFunctionC1EPNS_9ExecStateEPNS_18FunctionExecutableEPNS_14ScopeChainNodeE -__ZN3JSC10JSFunctionC2EPNS_9ExecStateEPNS_18FunctionExecutableEPNS_14ScopeChainNodeE __ZN3JSC17BytecodeGenerator8generateEv __ZN3JSC11ProgramNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17BytecodeGenerator13emitDebugHookENS_11DebugHookIDEii @@ -629,48 +488,6 @@ __ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDENS_7JSValueE __ZN3JSC17BytecodeGenerator16addConstantValueENS_7JSValueE __ZN3WTF9HashTableIPvSt4pairIS1_jENS_18PairFirstExtractorIS3_EENS_7PtrHashIS1_EENS_14PairHashTraitsIN3JSC24EncodedJSValueHashTraitsENS_10HashTraitsIjEEEESA_E6expandEv __ZN3WTF6VectorIN3JSC12WriteBarrierINS1_7UnknownEEELm0EE14expandCapacityEm -__ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC18ConstStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator8emitNodeEPNS_10RegisterIDEPNS_4NodeE -__ZN3JSC13ConstDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC13ConstDeclNode14emitCodeSingleERNS_17BytecodeGeneratorE -__ZN3JSC17BytecodeGenerator16constRegisterForERKNS_10IdentifierE -__ZN3JSC10RegExpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC11regExpFlagsERKNS_7UStringE -__ZN3JSC11RegExpCache14lookupOrCreateERKNS_7UStringENS_11RegExpFlagsE -__ZN3WTF9HashTableIN3JSC9RegExpKeyESt4pairIS2_NS_6RefPtrINS1_6RegExpEEEENS_18PairFirstExtractorIS7_EENS_10RegExpHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSD_IS6_EEEESE_E6rehashEi -__ZN3JSC11RegExpCache6createERKNS_7UStringENS_11RegExpFlagsEN3WTF24HashTableIteratorAdapterINS5_9HashTableINS_9RegExpKeyESt4pairIS8_NS5_6RefPtrINS_6RegExpEEEENS5_18PairFirstExtractorISD_EENS5_10RegExpHashIS8_EENS5_14PairHashTraitsINS5_10HashTraitsIS8_EENSJ_ISC_EEEESK_EESD_EE -__ZN3JSC4Yarr13YarrGenerator12generateTermEm -__ZN3JSC4Yarr13YarrGenerator13readCharacterEiNS_12X86Registers10RegisterIDE -__ZN3JSC4Yarr13YarrGenerator19matchCharacterClassENS_12X86Registers10RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListEPKNS0_14CharacterClassE -__ZN3JSC23MacroAssemblerX86Common4moveENS_22AbstractMacroAssemblerINS_12X86AssemblerEE12TrustedImm32ENS_12X86Registers10RegisterIDE -__ZN3JSC4Yarr13YarrGenerator12atEndOfInputEv -__ZN3JSC14MacroAssembler4pokeENS_12X86Registers10RegisterIDEi -__ZN3JSC4Yarr13YarrGenerator19jumpIfCharNotEqualsEti -__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDES4_ii -__ZN3JSC12X86Assembler7subl_irEiNS_12X86Registers10RegisterIDE -__ZN3JSC4Yarr13YarrGenerator13backtrackTermEm -__ZN3JSC4Yarr13YarrGenerator20backtrackTermDefaultEm -__ZN3JSC4Yarr13YarrGenerator17BacktrackingState6linkToENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5LabelEPNS_14MacroAssemblerE -__ZN3JSC17BytecodeGenerator13emitNewRegExpEPNS_10RegisterIDEN3WTF10PassRefPtrINS_6RegExpEEE -__ZN3JSC17BytecodeGenerator9addRegExpEN3WTF10PassRefPtrINS_6RegExpEEE -__ZN3JSC9CodeBlock25createRareDataIfNecessaryEv -__ZN3WTF16VectorBufferBaseIcE14allocateBufferEm -__ZN3WTF6VectorIcLm128EE15reserveCapacityEm -__ZN3JSC23FunctionCallResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator11registerForERKNS_10IdentifierE -__ZN3JSC13CallArgumentsC2ERNS_17BytecodeGeneratorEPNS_13ArgumentsNodeE -__ZN3JSC17BytecodeGenerator8emitCallEPNS_10RegisterIDES2_RNS_13CallArgumentsEjjj -__ZN3JSC17BytecodeGenerator8emitCallENS_8OpcodeIDEPNS_10RegisterIDES3_RNS_13CallArgumentsEjjj -__ZN3JSC16ArgumentListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC10StringNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDERKNS_10IdentifierE -__ZN3WTF9HashTableIPNS_10StringImplESt4pairIS2_PN3JSC8JSStringEENS_18PairFirstExtractorIS7_EENS4_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS6_EEEESD_E6rehashEi -__ZN3WTF6VectorIN3JSC12CallLinkInfoELm0EE14expandCapacityEm -__ZN3JSC11ResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator8emitMoveEPNS_10RegisterIDES2_ -__ZN3JSC9ArrayNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator12emitNewArrayEPNS_10RegisterIDEPNS_11ElementNodeE __ZN3JSC17BytecodeGenerator16emitUnaryNoDstOpENS_8OpcodeIDEPNS_10RegisterIDE __ZN3JSC9CodeBlock11shrinkToFitEv __ZN3WTF6VectorIN3JSC11InstructionELm0EE14shrinkCapacityEm @@ -678,32 +495,16 @@ __ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14shrinkCapacityEm __ZN3WTF6VectorIN3JSC10IdentifierELm0EE14shrinkCapacityEm __ZN3WTF6VectorIN3JSC12WriteBarrierINS1_18FunctionExecutableEEELm0EE14shrinkCapacityEm __ZN3WTF6VectorIN3JSC12WriteBarrierINS1_7UnknownEEELm0EE14shrinkCapacityEm -__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14shrinkCapacityEm -__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14shrinkCapacityEm -__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14shrinkCapacityEm -__ZN3WTF6VectorIN3JSC8LineInfoELm0EE14shrinkCapacityEm __ZN3JSC15ParserArenaDataIN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEED1Ev __ZN3JSC15ParserArenaDataIN3WTF6VectorIPNS_16FunctionBodyNodeELm0EEEED1Ev __ZN3JSC14SourceElementsD1Ev -__ZThn16_N3JSC16FunctionBodyNodeD0Ev -__ZN3JSC16FunctionBodyNodeD0Ev __ZN3JSC3JIT14privateCompileEPNS_21MacroAssemblerCodePtrE __ZN3JSC3JIT22privateCompileMainPassEv __ZN3JSC3JIT13emit_op_enterEPNS_11InstructionE __ZN3JSC3JIT11emit_op_movEPNS_11InstructionE -__ZN3JSC3JIT18emit_op_new_regexpEPNS_11InstructionE -__ZN3JSC11JITStubCall4callEj -__ZN3WTF6VectorIN3JSC10CallRecordELm0EE15reserveCapacityEm -__ZN3JSC3JIT12emit_op_callEPNS_11InstructionE -__ZN3JSC3JIT13compileOpCallENS_8OpcodeIDEPNS_11InstructionEj -__ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE14expandCapacityEm -__ZN3JSC3JIT23emit_op_call_put_resultEPNS_11InstructionE -__ZN3JSC3JIT17emit_op_new_arrayEPNS_11InstructionE __ZN3JSC3JIT11emit_op_endEPNS_11InstructionE __ZN3JSC3JIT22privateCompileLinkPassEv __ZN3JSC3JIT23privateCompileSlowCasesEv -__ZN3JSC3JIT16emitSlow_op_callEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT21compileOpCallSlowCaseEPNS_11InstructionERPNS_13SlowCaseEntryEjNS_8OpcodeIDE __ZN3WTF6VectorIN3JSC18MethodCallLinkInfoELm0EE4growEm __ZN3JSC17BytecodeGenerator18dumpsGeneratedCodeEv __ZN3JSC4Heap29reportExtraMemoryCostSlowCaseEm @@ -714,717 +515,1171 @@ __ZN3JSC12RegisterFile12globalObjectEv __ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12RegisterFileE __ZN3JSC12RegisterFile15setGlobalObjectEPNS_14JSGlobalObjectE _ctiTrampoline -_cti_op_new_regexp -__ZN3JSC12RegExpObjectC1EPNS_14JSGlobalObjectEPNS_9StructureEN3WTF17NonNullPassRefPtrINS_6RegExpEEE -_cti_vm_lazyLinkCall -__ZN3JSC18FunctionExecutable22compileForCallInternalEPNS_9ExecStateEPNS_14ScopeChainNodeE -__ZN3JSC6Parser5parseINS_16FunctionBodyNodeEEEN3WTF10PassRefPtrIT_EEPNS_14JSGlobalObjectEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPNS_18FunctionParametersENS_18JSParserStrictnessEPPNS_8JSObjectE -__ZN3JSC8JSParser19parseSourceElementsILNS0_18SourceElementsModeE1ENS_10ASTBuilderEEENT0_14SourceElementsERS4_ -__ZN3JSC8JSParser20parseReturnStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3WTF15SegmentedVectorIN3JSC10IdentifierELm64EE6appendIS2_EEvRKT_ +__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE +__ZN3JSC8JSParser31parseExpressionOrLabelStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3JSC5Lexer16nextTokenIsColonEv __ZN3JSC8JSParser15parseExpressionINS_10ASTBuilderEEENT_10ExpressionERS3_ -__ZNK3JSC15DotAccessorNode10isLocationEv -__ZNK3JSC14ExpressionNode13isResolveNodeEv -__ZNK3JSC14ExpressionNode21isBracketAccessorNodeEv -__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPS0_Lm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISK_EEEERKNS_10SourceCodeEji -__ZN3JSC17BytecodeGeneratorC1EPNS_16FunctionBodyNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE -__ZN3JSC17BytecodeGeneratorC2EPNS_16FunctionBodyNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE -__ZN3WTF15SegmentedVectorIN3JSC10RegisterIDELm32EEC1Ev -__ZN3WTF6VectorIN3JSC11InstructionELm0EE14expandCapacityEm -__ZN3JSC17BytecodeGenerator12addParameterERKNS_10IdentifierEi -__ZN3JSC16FunctionBodyNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC9BlockNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC10ReturnNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC19FunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC8JSParser25parseAssignmentExpressionINS_10ASTBuilderEEENT_10ExpressionERS3_ +__ZN3JSC8JSParser21parseMemberExpressionINS_10ASTBuilderEEENT_10ExpressionERS3_ +__ZN3JSC11ParserArena20allocateFreeablePoolEv +__ZN3JSCL19isNonASCIIIdentPartEi +__ZN3JSC11ParserArena16allocateFreeableEm +__ZN3JSC14SourceElements6appendEPNS_13StatementNodeE +__ZNK3JSC13StatementNode16isEmptyStatementEv +__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14expandCapacityEm +__ZN3JSC17ExprStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC15DotAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator8emitNodeEPNS_10RegisterIDEPNS_4NodeE +__ZN3JSC11ResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator11registerForERKNS_10IdentifierE __ZN3JSC17BytecodeGenerator11emitResolveEPNS_10RegisterIDERKNS_10IdentifierE __ZN3JSC17BytecodeGenerator18findScopedPropertyERKNS_10IdentifierERiRmbRbRPNS_8JSObjectE -__ZNK3JSC16JSVariableObject16isVariableObjectEv -__ZN3JSC17BytecodeGenerator16emitGetScopedVarEPNS_10RegisterIDEmiNS_7JSValueE -__ZN3JSC17BytecodeGenerator15emitMethodCheckEv -__ZN3JSC17BytecodeGenerator11emitGetByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE -__ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14expandCapacityEm +__ZN3WTF6VectorIN3JSC17GlobalResolveInfoELm0EE14expandCapacityEm __ZN3JSC17BytecodeGenerator11addConstantERKNS_10IdentifierE __ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEmPKS2_ __ZN3WTF6VectorIN3JSC10IdentifierELm0EE15reserveCapacityEm -__ZN3JSC17BytecodeGenerator10emitReturnEPNS_10RegisterIDE -__ZNK3JSC9ScopeNode15singleStatementEv -__ZNK3JSC9BlockNode7isBlockEv -__ZNK3JSC10ReturnNode12isReturnNodeEv -__ZNK3JSC14SourceElements15singleStatementEv -__ZNK3JSC14ExpressionNode10isSubtractEv -__ZN3JSC3JIT22emit_op_get_global_varEPNS_11InstructionE -__ZN3JSC3JIT20emit_op_method_checkEPNS_11InstructionE -__ZN3WTF6VectorIN3JSC25MethodCallCompilationInfoELm0EE14expandCapacityEm -__ZN3JSC3JIT21compileGetByIdHotPathEiiPNS_10IdentifierEj +__ZN3JSC17BytecodeGenerator11emitGetByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE +__ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14expandCapacityEm +__ZN3JSC3JIT22emit_op_resolve_globalEPNS_11InstructionEb __ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE14expandCapacityEmPKS2_ -__ZN3WTF6VectorIN3JSC10CallRecordELm0EE14expandCapacityEmPKS2_ -__ZN3JSC3JIT11emit_op_retEPNS_11InstructionE -__ZN3JSC3JIT24emitSlow_op_method_checkEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE14expandCapacityEm +__ZN3JSC3JIT17emit_op_get_by_idEPNS_11InstructionE +__ZN3JSC3JIT21compileGetByIdHotPathEiiPNS_10IdentifierEj +__ZN3JSC3JIT26emitSlow_op_resolve_globalEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC20MacroAssemblerX86_648storePtrENS_22AbstractMacroAssemblerINS_12X86AssemblerEE13TrustedImmPtrENS3_15ImplicitAddressE +__ZN3JSC11JITStubCall4callEj +__ZN3WTF6VectorIN3JSC10CallRecordELm0EE15reserveCapacityEm +__ZN3JSC3JIT21emitSlow_op_get_by_idEPNS_11InstructionERPNS_13SlowCaseEntryE __ZN3JSC3JIT22compileGetByIdSlowCaseEiiPNS_10IdentifierERPNS_13SlowCaseEntryEb __ZN3JSC11JITStubCall4callEv -_cti_register_file_check -_cti_op_get_by_id_method_check -__ZNK3JSC7JSValue3getEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +_cti_op_resolve_global +__ZN3JSC15ObjectPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC10Identifier8toUInt32ERKNS_7UStringERb +__ZN3WTF12AtomicString4findEPKtjj +__ZNK3WTF9HashTableIPNS_10StringImplES2_NS_17IdentityExtractorIS2_EENS_10StringHashENS_10HashTraitsIS2_EES7_E4findINS_17HashAndCharactersENS_24HashSetTranslatorAdapterIS2_S7_SA_NS_27HashAndCharactersTranslatorEEEEENS_22HashTableConstIteratorIS2_S2_S4_S5_S7_S7_EERKT_ +__ZN3JSC28createUndefinedVariableErrorEPNS_9ExecStateERKNS_10IdentifierE +__ZN3JSC11makeUStringIPKcNS_7UStringEEES3_T_T0_ +__ZN3WTF13tryMakeStringIPKcN3JSC7UStringEEENS_10PassRefPtrINS_10StringImplEEET_T0_ +__ZN3JSC20createReferenceErrorEPNS_9ExecStateERKNS_7UStringE +__ZN3JSC13ErrorInstance6createEPNS_12JSGlobalDataEPNS_9StructureERKNS_7UStringE +__ZN3JSC13ErrorInstanceC2EPNS_12JSGlobalDataEPNS_9StructureERKNS_7UStringE +__ZN3JSCL23returnToThrowTrampolineEPNS_12JSGlobalDataENS_16ReturnAddressPtrERS2_ +_ctiVMThrowTrampoline +_cti_vm_throw +__ZN3JSC11Interpreter14throwExceptionERPNS_9ExecStateERNS_7JSValueEj +__ZNK3JSC13ErrorInstance15isErrorInstanceEv +__ZNK3JSC8JSObject13exceptionTypeEv +__ZN3JSC9CodeBlock24handlerForBytecodeOffsetEj +__ZN3JSC11Interpreter15unwindCallFrameERPNS_9ExecStateENS_7JSValueERjRPNS_9CodeBlockE +_ctiOpThrowNotCaught +__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE +__ZNK3JSC8JSObject11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE +__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE +__ZN3JSC14ErrorPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE __ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE -__ZNK3WTF12AtomicString5lowerEv -__ZNK3JSC8JSObject24getPropertySpecificValueEPNS_9ExecStateERKNS_10IdentifierERPNS_6JSCellE -__ZN3JSC27ctiPatchCallByReturnAddressEPNS_9CodeBlockENS_16ReturnAddressPtrENS_11FunctionPtrE -__ZN3JSC3JIT8linkCallEPNS_10JSFunctionEPNS_9CodeBlockES4_NS_21MacroAssemblerCodePtrEPNS_12CallLinkInfoEiPNS_12JSGlobalDataE -_cti_op_get_by_id +__ZN3JSC10JSFunction11getCallDataERNS_8CallDataE +__ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE +__ZN3JSC11Interpreter11executeCallEPNS_9ExecStateEPNS_8JSObjectENS_8CallTypeERKNS_8CallDataENS_7JSValueERKNS_7ArgListE +__ZN3JSCL22errorProtoFuncToStringEPNS_9ExecStateE +__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi +__ZNK3JSC8JSObject3getEPNS_9ExecStateERKNS_10IdentifierE +__ZN3WTF13tryMakeStringIN3JSC7UStringEPKcS2_EENS_10PassRefPtrINS_10StringImplEEET_T0_T1_ +__ZN3JSC7toInt32Ed +__ZN3JSC11NewExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC13CallArgumentsC2ERNS_17BytecodeGeneratorEPNS_13ArgumentsNodeE +__ZN3JSC17BytecodeGenerator13emitConstructEPNS_10RegisterIDES2_RNS_13CallArgumentsEjjj +__ZN3JSC16ArgumentListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC10StringNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDERKNS_10IdentifierE +__ZN3WTF9HashTableIPNS_10StringImplESt4pairIS2_PN3JSC8JSStringEENS_18PairFirstExtractorIS7_EENS4_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS6_EEEESD_E6rehashEi +__ZN3WTF6VectorIN3JSC12CallLinkInfoELm0EE14expandCapacityEm +__ZN3JSC3JIT17emit_op_constructEPNS_11InstructionE +__ZN3JSC3JIT13compileOpCallENS_8OpcodeIDEPNS_11InstructionEj +__ZN3WTF6VectorIcLm128EE15reserveCapacityEm +__ZN3WTF6VectorIN3JSC10CallRecordELm0EE14expandCapacityEmPKS2_ +__ZN3JSC3JIT23emit_op_call_put_resultEPNS_11InstructionE +__ZN3JSC3JIT21emitSlow_op_constructEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT21compileOpCallSlowCaseEPNS_11InstructionERPNS_13SlowCaseEntryEjNS_8OpcodeIDE +_cti_op_construct_NotJSConstruct +__ZN3JSC17StringConstructor16getConstructDataERNS_13ConstructDataE +__ZN3JSCL30constructWithStringConstructorEPNS_9ExecStateE +__ZN3JSC12StringObjectC1EPNS_9ExecStateEPNS_9StructureERKNS_7UStringE +__ZN3JSC12StringObjectC2EPNS_9ExecStateEPNS_9StructureERKNS_7UStringE +__ZN3JSC11BooleanNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEb +__ZN3JSC9BlockNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC9ArrayNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator12emitNewArrayEPNS_10RegisterIDEPNS_11ElementNodeE +__ZN3JSC3JIT17emit_op_new_arrayEPNS_11InstructionE _cti_op_new_array __ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureERKNS_7ArgListE -__ZN3JSC18FunctionExecutable11discardCodeEv -__ZN3JSC17FunctionCodeBlockD0Ev -__ZN3JSC9CodeBlockD2Ev -__ZN3JSC17StructureStubInfo5derefEv -__ZN3JSC8JSObject13visitChildrenERNS_9MarkStackE -__ZN3JSC14JSGlobalObject13visitChildrenERNS_9MarkStackE -__ZN3JSC9MarkStack14MarkStackArrayIPNS_6JSCellEE6appendERKS3_ -__ZN3JSC10JSFunction13visitChildrenERNS_9MarkStackE -__ZN3JSC12RegExpObject13visitChildrenERNS_9MarkStackE -__ZN3JSC15JSWrapperObject13visitChildrenERNS_9MarkStackE -__ZN3JSC7JSArray13visitChildrenERNS_9MarkStackE -__ZN3JSC22NativeErrorConstructor13visitChildrenERNS_9MarkStackE -__ZN3JSC14ScopeChainNode13visitChildrenERNS_9MarkStackE -__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE13visitChildrenERNS_9MarkStackE -__ZN3JSC18FunctionExecutable13visitChildrenERNS_9MarkStackE -__ZN3JSC17ProgramExecutableD1Ev -__ZN3JSC16ProgramCodeBlockD0Ev -__ZN3JSC8JSParser31parseExpressionOrLabelStatementINS_10ASTBuilderEEENT_9StatementERS3_ __ZN3JSC8JSParser17parseFunctionInfoILNS0_20FunctionRequirementsE0ELb0ENS_10ASTBuilderEEEbRT1_RPKNS_10IdentifierERNS4_19FormalParameterListERNS4_12FunctionBodyERiSE_SE_ -__ZN3JSC10ASTBuilder14makeAssignNodeEPNS_14ExpressionNodeENS_8OperatorES2_bbiii -__ZN3JSC8JSParser19parseBreakStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3JSC17ExprStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC13AssignDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZNK3JSC14ExpressionNode6isPureERNS_17BytecodeGeneratorE -__ZN3JSC15DotAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE -__ZN3JSC18FunctionExecutableC1EPNS_12JSGlobalDataERKNS_10IdentifierERKNS_10SourceCodeEbPNS_18FunctionParametersEbii -__ZN3WTF6VectorIN3JSC12WriteBarrierINS1_18FunctionExecutableEEELm0EE14expandCapacityEm -__ZN3JSC17BytecodeGenerator11emitPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_ -__ZN3JSC3JIT17emit_op_get_by_idEPNS_11InstructionE +__ZN3JSC8JSParser19parseSourceElementsILNS0_18SourceElementsModeE0ENS_13SyntaxCheckerEEENT0_14SourceElementsERS4_ +__ZN3JSC8JSParser14parseStatementINS_13SyntaxCheckerEEENT_9StatementERS3_RPKNS_10IdentifierE +__ZN3JSC8JSParser15parseExpressionINS_13SyntaxCheckerEEENT_10ExpressionERS3_ +__ZN3JSC8JSParser25parseAssignmentExpressionINS_13SyntaxCheckerEEENT_10ExpressionERS3_ +__ZN3JSC8JSParser21parseMemberExpressionINS_13SyntaxCheckerEEENT_10ExpressionERS3_ +__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEb +__ZN3JSC8JSParser5ScopeD1Ev +__ZN3JSC5Lexer10sourceCodeEiii +__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeERKNS_10IdentifierE +__ZN3JSC16FunctionBodyNode13finishParsingEN3WTF10PassRefPtrINS_18FunctionParametersEEERKNS_10IdentifierE +__ZN3JSC10ASTBuilder20makeFunctionCallNodeEPNS_14ExpressionNodeEPNS_13ArgumentsNodeEiii +__ZNK3JSC14ExpressionNode10isLocationEv +__ZN3JSC21FunctionCallValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE +__ZN3JSC18FunctionExecutableC1EPNS_12JSGlobalDataERKNS_10IdentifierERKNS_10SourceCodeEbPNS_18FunctionParametersEbii +__ZN3WTF6VectorIN3JSC12WriteBarrierINS1_18FunctionExecutableEEELm0EE14expandCapacityEm +__ZN3JSC17BytecodeGenerator8emitCallEPNS_10RegisterIDES2_RNS_13CallArgumentsEjjj +__ZN3JSC17BytecodeGenerator8emitCallENS_8OpcodeIDEPNS_10RegisterIDES3_RNS_13CallArgumentsEjjj +__ZThn16_N3JSC16FunctionBodyNodeD0Ev +__ZN3JSC16FunctionBodyNodeD0Ev __ZN3JSC3JIT20emit_op_new_func_expEPNS_11InstructionE -__ZN3JSC20MacroAssemblerX86_648storePtrENS_22AbstractMacroAssemblerINS_12X86AssemblerEE13TrustedImmPtrENS3_15ImplicitAddressE -__ZN3JSC3JIT17emit_op_put_by_idEPNS_11InstructionE -__ZN3JSC3JIT21emitSlow_op_get_by_idEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT21emitSlow_op_put_by_idEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC10JSFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC9Structure22materializePropertyMapERNS_12JSGlobalDataE -__ZN3WTF9HashTableISt4pairINS_6RefPtrINS_10StringImplEEEjES1_IS5_PN3JSC7JSValueEENS_18PairFirstExtractorIS9_EENS6_24StructureTransitionTable4HashENS_14PairHashTraitsINSC_10HashTraitsENS_10HashTraitsIS8_EEEESF_E6rehashEi +__ZN3JSC3JIT12emit_op_callEPNS_11InstructionE +__ZN3JSC3JIT16emitSlow_op_callEPNS_11InstructionERPNS_13SlowCaseEntryE _cti_op_new_func_exp -_cti_op_put_by_id -__ZN3JSC8JSParser20parseSwitchStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3JSC8JSParser18parseSwitchClausesINS_13SyntaxCheckerEEENT_10ClauseListERS3_ -__ZN3WTF6VectorIPvLm0EE14expandCapacityEm -__ZN3JSC8JSParser17parseForStatementINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3JSC8JSParser19parseVarDeclarationINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3JSC8JSParser21parseDoWhileStatementINS_10ASTBuilderEEENT_9StatementERS3_ -__ZNK3JSC19BracketAccessorNode10isLocationEv -__ZNK3JSC19BracketAccessorNode21isBracketAccessorNodeEv -__ZN3JSC10ASTBuilder14makeBinaryNodeEiSt4pairIPNS_14ExpressionNodeENS0_12BinaryOpInfoEES5_ -__ZN3JSC17ObjectLiteralNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC16PropertyListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator13emitNewObjectEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator17emitDirectPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_ -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_iENS_18PairFirstExtractorIS5_EEN3JSC17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS8_17BytecodeGenerator28IdentifierMapIndexHashTraitsEEESC_E4findIS3_NS_22IdentityHashTranslatorIS3_S5_S9_EEEENS_17HashTableIteratorIS3_S5_S7_S9_SF_SC_EERKT_ -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_iENS_18PairFirstExtractorIS5_EEN3JSC17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS8_17BytecodeGenerator28IdentifierMapIndexHashTraitsEEESC_E6rehashEi -__ZN3JSC9ForInNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator13newLabelScopeENS_10LabelScope4TypeEPKNS_10IdentifierE +__ZN3JSC10JSFunctionC1EPNS_9ExecStateEPNS_18FunctionExecutableEPNS_14ScopeChainNodeE +__ZN3JSC10JSFunctionC2EPNS_9ExecStateEPNS_18FunctionExecutableEPNS_14ScopeChainNodeE +_cti_vm_lazyLinkCall +__ZN3JSC18FunctionExecutable22compileForCallInternalEPNS_9ExecStateEPNS_14ScopeChainNodeE +__ZN3JSC6Parser5parseINS_16FunctionBodyNodeEEEN3WTF10PassRefPtrIT_EEPNS_14JSGlobalObjectEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPNS_18FunctionParametersENS_18JSParserStrictnessEPPNS_8JSObjectE +__ZN3JSC8JSParser19parseSourceElementsILNS0_18SourceElementsModeE1ENS_10ASTBuilderEEENT0_14SourceElementsERS4_ +__ZN3JSC8JSParser19parseThrowStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPS0_Lm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISK_EEEERKNS_10SourceCodeEji +__ZN3JSC17BytecodeGeneratorC1EPNS_16FunctionBodyNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE +__ZN3JSC17BytecodeGeneratorC2EPNS_16FunctionBodyNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE +__ZN3WTF15SegmentedVectorIN3JSC10RegisterIDELm32EEC1Ev +__ZN3WTF6VectorIN3JSC11InstructionELm0EE14expandCapacityEm +__ZN3JSC16FunctionBodyNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC9ThrowNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZNK3JSC9ScopeNode15singleStatementEv +__ZNK3JSC9BlockNode7isBlockEv +__ZNK3JSC13StatementNode12isReturnNodeEv +__ZN3JSC17BytecodeGenerator10emitReturnEPNS_10RegisterIDE +__ZN3JSC3JIT13emit_op_throwEPNS_11InstructionE +__ZN3JSC11JITStubCall11addArgumentEjNS_12X86Registers10RegisterIDE +__ZN3JSC3JIT11emit_op_retEPNS_11InstructionE +_cti_op_throw +__ZNK3JSC8JSString8toObjectEPNS_9ExecStateEPNS_14JSGlobalObjectE +__ZN3JSC12StringObjectC1ERNS_12JSGlobalDataEPNS_9StructureEPNS_8JSStringE +__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC15StringPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC17BytecodeGenerator8emitMoveEPNS_10RegisterIDES2_ +__ZN3JSCL20isNonASCIIIdentStartEi +__ZN3JSC10NumberNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEd +__ZN3WTF9HashTableIdSt4pairIdN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsIdEENSA_IS3_EEEESB_E6expandEv +__ZN3JSC7UString6numberEj +__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateEPNS_14JSGlobalObjectE +__ZN3JSC15constructNumberEPNS_9ExecStateEPNS_14JSGlobalObjectENS_7JSValueE +__ZN3JSC15NumberPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC12StringObjectC1EPNS_9ExecStateEPNS_9StructureE +__ZN3JSC5Lexer7record8Ei +__ZN3JSC8NullNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC18FunctionExecutable11discardCodeEv +__ZN3JSC17FunctionCodeBlockD0Ev +__ZN3JSC9CodeBlockD2Ev +__ZN3JSC15WeakHandleOwner26isReachableFromOpaqueRootsENS_6HandleINS_7UnknownEEEPvRNS_9MarkStackE +__ZN3JSC12RegisterFile17GlobalObjectOwner8finalizeENS_6HandleINS_7UnknownEEEPv +__ZN3JSC13ErrorInstanceD1Ev +__ZN3JSC12StringObjectD1Ev +__ZN3JSC12NumberObjectD1Ev +__ZN3JSC17ProgramExecutableD1Ev +__ZN3JSC16ProgramCodeBlockD0Ev +__ZN3JSC19SourceProviderCacheD1Ev +__ZN3WTF20deleteAllPairSecondsIPN3JSC23SourceProviderCacheItemEKNS_7HashMapIiS3_NS_7IntHashIjEENS_10HashTraitsIiEENS7_IS3_EEEEEEvRT0_ +__ZN3JSC17StructureStubInfo5derefEv +__ZN3JSC18FunctionExecutableD1Ev +__ZN3WTFeqERKNS_12AtomicStringEPKc +_JSClassCreate +__ZN13OpaqueJSClass6createEPK17JSClassDefinition +__ZN13OpaqueJSClassC2EPK17JSClassDefinitionPS_ +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_P19StaticFunctionEntryENS_18PairFirstExtractorIS7_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSC_IS6_EEEESD_E6expandEv +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_P16StaticValueEntryENS_18PairFirstExtractorIS7_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSC_IS6_EEEESD_E6expandEv +_JSClassRetain +_JSObjectMake +__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEEC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEP13OpaqueJSClassPv +__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE4initEPNS_9ExecStateE +__ZN13OpaqueJSClass9prototypeEPN3JSC9ExecStateE +__ZN13OpaqueJSClass11contextDataEPN3JSC9ExecStateE +__ZN3WTF9HashTableIP13OpaqueJSClassSt4pairIS2_P24OpaqueJSClassContextDataENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS5_EEEESD_E6expandEv +__ZN24OpaqueJSClassContextDataC2ERN3JSC12JSGlobalDataEP13OpaqueJSClass +_JSClassRelease +_JSObjectSetProperty +__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE +__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj +__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE +__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj +__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE +__ZN3JSC8JSParser16parseIfStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZNK3JSC15DotAccessorNode10isLocationEv +__ZNK3JSC14ExpressionNode13isResolveNodeEv +__ZNK3JSC14ExpressionNode21isBracketAccessorNodeEv +__ZN3JSC9CodeBlock25createRareDataIfNecessaryEv +__ZN3WTF6VectorIN3JSC8LineInfoELm0EE14expandCapacityEm +__ZN3JSC6IfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17BytecodeGenerator8newLabelEv -__ZN3JSC17BytecodeGenerator20emitGetPropertyNamesEPNS_10RegisterIDES2_S2_S2_PNS_5LabelE -__ZN3JSC17BytecodeGenerator8emitJumpEPNS_5LabelE +__ZNK3JSC14ExpressionNode26hasConditionContextCodegenEv +__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14expandCapacityEm +__ZN3JSC17BytecodeGenerator15emitJumpIfFalseEPNS_10RegisterIDEPNS_5LabelE +__ZN3JSC19FunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator15emitMethodCheckEv __ZN3JSC17BytecodeGenerator9emitLabelEPNS_5LabelE __ZN3WTF6VectorIjLm0EE15reserveCapacityEm -__ZN3WTF6VectorIN3JSC12ForInContextELm0EE14expandCapacityEm +__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14shrinkCapacityEm +__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14shrinkCapacityEm +__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14shrinkCapacityEm +__ZN3WTF6VectorIN3JSC8LineInfoELm0EE14shrinkCapacityEm +__ZN3JSC3JIT14emit_op_jfalseEPNS_11InstructionE +__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common19RelationalConditionENS_12X86Registers10RegisterIDES4_ +__ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEmPKS2_ +__ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEm +__ZN3JSC3JIT20emit_op_method_checkEPNS_11InstructionE +__ZN3WTF6VectorIN3JSC25MethodCallCompilationInfoELm0EE14expandCapacityEm +__ZN3JSC3JIT18emitSlow_op_jfalseEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC23MacroAssemblerX86Common12branchTest32ENS0_15ResultConditionENS_12X86Registers10RegisterIDENS_22AbstractMacroAssemblerINS_12X86AssemblerEE12TrustedImm32E +__ZN3JSC3JIT24emitSlow_op_method_checkEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3WTF6VectorIN3JSC32CallReturnOffsetToBytecodeOffsetELm0EE15reserveCapacityEm +_cti_op_get_by_id +__ZNK3JSC7JSValue3getEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +_cti_op_jtrue +__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE +_cti_op_get_by_id_method_check +__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE20staticFunctionGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE +__ZN3JSC18JSCallbackFunctionC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPFPK13OpaqueJSValuePK15OpaqueJSContextPS5_SB_mPKS7_PS7_ERKNS_10IdentifierE +_cti_op_call_NotJSFunction +__ZN3JSC18JSCallbackFunction11getCallDataERNS_8CallDataE +__ZN3JSC18JSCallbackFunction4callEPNS_9ExecStateE +__ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE +_JSObjectGetPrivate +_JSValueMakeUndefined +__ZN3JSC6JSLock12DropAllLocksD1Ev +__ZN3WTF6String6appendEPKtj +__ZN3JSC15WeakHandleOwnerD2Ev +__ZN3JSC8JSParser24parseFunctionDeclarationINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3JSC8JSParser17parseFunctionInfoILNS0_20FunctionRequirementsE1ELb1ENS_10ASTBuilderEEEbRT1_RPKNS_10IdentifierERNS4_19FormalParameterListERNS4_12FunctionBodyERiSE_SE_ +__ZN3JSC8JSParser16parseIfStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3WTF7HashSetINS_6RefPtrINS_10StringImplEEEN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EEE3addERKS3_ +__ZN3JSC8JSParser31parseExpressionOrLabelStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3JSC8JSParser19parseVarDeclarationINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3JSC8JSParser5Scope15declareVariableEPKNS_10IdentifierE +__ZN3WTF14deleteOwnedPtrIN3JSC23SourceProviderCacheItemEEEvPT_ +__ZN3JSC8JSParser5Scope29copyCapturedVariablesToVectorERKN3WTF7HashSetINS2_6RefPtrINS2_10StringImplEEENS_17IdentifierRepHashENS2_10HashTraitsIS6_EEEERNS2_6VectorIS6_Lm0EEE +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEES3_NS_17IdentityExtractorIS3_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EES9_E13isEmptyBucketERKS3_ +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEES3_NS_17IdentityExtractorIS3_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EES9_E15deallocateTableEPS3_i +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEES3_NS_17IdentityExtractorIS3_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EES9_E6expandEv +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEES3_NS_17IdentityExtractorIS3_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EES9_E6rehashEi +__ZN3WTF6VectorINS_6RefPtrINS_10StringImplEEELm0EE14expandCapacityEm +__ZN3JSC19SourceProviderCache3addEiN3WTF10PassOwnPtrINS_23SourceProviderCacheItemEEEj +__ZN3WTF9HashTableIiSt4pairIiPN3JSC23SourceProviderCacheItemEENS_18PairFirstExtractorIS5_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIiEENSB_IS4_EEEESC_E6expandEv +__ZN3WTF6VectorIPN3JSC16FunctionBodyNodeELm0EE15reserveCapacityEm +__ZN3JSC8JSObject12removeDirectERNS_12JSGlobalDataERKNS_10IdentifierE +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS5_26SymbolTableIndexHashTraitsEEESD_E13isEmptyBucketERKS7_ +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS5_26SymbolTableIndexHashTraitsEEESD_E6expandEv +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS5_26SymbolTableIndexHashTraitsEEESD_E6rehashEi +__ZN3WTF9HashTableIPNS_10StringImplES2_NS_17IdentityExtractorIS2_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS2_EES8_E6rehashEi +__ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE +__ZN3JSC18FunctionExecutableC1EPNS_9ExecStateERKNS_10IdentifierERKNS_10SourceCodeEbPNS_18FunctionParametersEbii +__ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC14JSGlobalObject15copyGlobalsFromERNS_12RegisterFileE +__ZNK3WTF12AtomicString5lowerEv +__ZN3JSC41constructFunctionSkippingEvalEnabledCheckEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi +__ZN3WTF13StringBuilder6appendEPKcj +__ZNK3JSC21UStringSourceProvider6lengthEv +__ZN3JSC18FunctionExecutable14fromGlobalCodeERKNS_10IdentifierEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPPNS_8JSObjectE +__ZNK3JSC21UStringSourceProvider4dataEv +__ZN3JSC8JSParser16declareParameterEPKNS_10IdentifierE +__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEm +__ZN3JSC10JSFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC9Structure22materializePropertyMapERNS_12JSGlobalDataE +__ZNK3JSC11ResolveNode10isLocationEv +__ZNK3JSC11ResolveNode13isResolveNodeEv +__ZN3JSC17BytecodeGenerator12addParameterERKNS_10IdentifierEi +__ZN3JSC23FunctionCallResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZNK3JSC16JSVariableObject16isVariableObjectEv +__ZN3JSC17BytecodeGenerator16emitGetScopedVarEPNS_10RegisterIDEmiNS_7JSValueE +__ZN3JSC3JIT22emit_op_get_global_varEPNS_11InstructionE +__ZN3JSC8JSParser19parseVarDeclarationINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3WTF6VectorISt4pairIPKN3JSC10IdentifierEjELm0EE15reserveCapacityEm +__ZN3JSC9ScopeNode8capturesERKNS_10IdentifierE +__ZN3JSC17BytecodeGenerator6addVarERKNS_10IdentifierEbRPNS_10RegisterIDE +__ZNK3JSC14JSGlobalObject14isDynamicScopeERb __ZN3JSC16VarStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17AssignResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17BytecodeGenerator15isLocalConstantERKNS_10IdentifierE -__ZN3WTF6VectorIN3JSC17GlobalResolveInfoELm0EE14expandCapacityEm -__ZN3JSC11DoWhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17AssignBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZNK3JSC11ResolveNode6isPureERNS_17BytecodeGeneratorE -__ZN3JSC17BytecodeGenerator7isLocalERKNS_10IdentifierE +_cti_register_file_check +__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE17staticValueGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE +__ZN3WTF9HashTableISt4pairINS_6RefPtrINS_10StringImplEEEjES1_IS5_PN3JSC7JSValueEENS_18PairFirstExtractorIS9_EENS6_24StructureTransitionTable4HashENS_14PairHashTraitsINSC_10HashTraitsENS_10HashTraitsIS8_EEEESF_E6rehashEi +_JSValueMakeString __ZN3JSC8ThisNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC19BracketAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator22willResolveToArgumentsERKNS_10IdentifierE -__ZN3JSC17BytecodeGenerator12emitGetByValEPNS_10RegisterIDES2_S2_ -__ZN3JSC17BytecodeGenerator12emitPutByValEPNS_10RegisterIDES2_S2_ -__ZNK3JSC14ExpressionNode26hasConditionContextCodegenEv -__ZN3JSC15StrictEqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator14emitEqualityOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_ -__ZN3JSC17BytecodeGenerator14emitJumpIfTrueEPNS_10RegisterIDEPNS_5LabelE +__ZN3JSC3JIT20emit_op_convert_thisEPNS_11InstructionE +__ZN3JSC23MacroAssemblerX86Common11branchTest8ENS0_15ResultConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_12TrustedImm32E +__ZN3JSC3JIT24emitSlow_op_convert_thisEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC8JSObject13visitChildrenERNS_9MarkStackE +__ZN3JSC14JSGlobalObject13visitChildrenERNS_9MarkStackE +__ZN3JSC9MarkStack14MarkStackArrayIPNS_6JSCellEE6appendERKS3_ +__ZN3JSC10JSFunction13visitChildrenERNS_9MarkStackE +__ZN3JSC18FunctionExecutable13visitChildrenERNS_9MarkStackE +__ZN3JSC14ScopeChainNode13visitChildrenERNS_9MarkStackE +__ZN3JSC12RegExpObject13visitChildrenERNS_9MarkStackE +__ZN3JSC15JSWrapperObject13visitChildrenERNS_9MarkStackE +__ZN3JSC7JSArray13visitChildrenERNS_9MarkStackE +__ZN3JSC22NativeErrorConstructor13visitChildrenERNS_9MarkStackE +__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE13visitChildrenERNS_9MarkStackE +__ZN3JSC9WeakGCMapISt4pairIN3WTF6RefPtrINS2_10StringImplEEEjENS_9StructureENS_24StructureTransitionTable26WeakGCMapFinalizerCallbackENS8_4HashENS8_10HashTraitsEE8finalizeENS_6HandleINS_7UnknownEEEPv +__ZN3JSC9WeakGCMapISt4pairIN3WTF6RefPtrINS2_10StringImplEEEjENS_9StructureENS_24StructureTransitionTable26WeakGCMapFinalizerCallbackENS8_4HashENS8_10HashTraitsEED0Ev +__ZN3JSC9WeakGCMapISt4pairIN3WTF6RefPtrINS2_10StringImplEEEjENS_9StructureENS_24StructureTransitionTable26WeakGCMapFinalizerCallbackENS8_4HashENS8_10HashTraitsEED1Ev +__ZN3WTF7HashMapISt4pairINS_6RefPtrINS_10StringImplEEEjEPN3JSC7JSValueENS6_24StructureTransitionTable4HashENS9_10HashTraitsENS_10HashTraitsIS8_EEE4takeERKS5_ +__ZN3JSC20JSCallbackObjectData8finalizeENS_6HandleINS_7UnknownEEEPv +__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEED1Ev +__ZN3JSC20JSCallbackObjectDataD0Ev +__ZN3JSC18JSCallbackFunctionD1Ev +__ZN3WTF10StringImpl23reverseFindIgnoringCaseEPS0_j +__ZN3WTF6VectorIN3JSC4Yarr11PatternTermELm0EE14expandCapacityEm +__ZN3JSC4Yarr6ParserINS0_22YarrPatternConstructorEE28CharacterClassParserDelegate20atomPatternCharacterEtb +__ZN3JSC4Yarr25CharacterClassConstructor14addSortedRangeERN3WTF6VectorINS0_14CharacterRangeELm0EEEtt +__ZN3WTF6VectorIN3JSC4Yarr14CharacterRangeELm0EE14expandCapacityEmPKS3_ +__ZN3WTF6VectorIN3JSC4Yarr14CharacterRangeELm0EE14expandCapacityEm +__ZN3JSC4Yarr6ParserINS0_22YarrPatternConstructorEE11parseEscapeILb1ENS3_28CharacterClassParserDelegateEEEbRT0_ +__ZN3JSC4Yarr25CharacterClassConstructor7putCharEt +__ZN3WTF6VectorItLm0EE14expandCapacityEm +__ZN3JSC4Yarr22YarrPatternConstructor21atomCharacterClassEndEv +__ZN3WTF6VectorIPN3JSC4Yarr14CharacterClassELm0EE14expandCapacityEm +__ZN3JSC4Yarr22YarrPatternConstructor20atomPatternCharacterEt +__ZN3JSC4Yarr6ParserINS0_22YarrPatternConstructorEE11parseEscapeILb0ES2_EEbRT0_ +__ZN3JSC4Yarr11byteCompileERNS0_11YarrPatternEPN3WTF20BumpPointerAllocatorE +__ZN3WTF6VectorIN3JSC4Yarr8ByteTermELm0EE14expandCapacityEm +__ZN3JSC4Yarr12ByteCompiler15emitDisjunctionEPNS0_18PatternDisjunctionEjj +__ZN3JSC4Yarr13newlineCreateEv +__ZN3JSC4Yarr14wordcharCreateEv +__ZN3JSC4Yarr9interpretEPNS0_15BytecodePatternEPKtjjPi +__ZN3JSC4Yarr11Interpreter16matchDisjunctionEPNS0_15ByteDisjunctionEPNS1_18DisjunctionContextEb +__ZN3WTF6VectorIiLm0EE14expandCapacityEm +__ZN3JSC8JSParser20parseReturnStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3JSC5Lexer10scanRegExpERPKNS_10IdentifierES4_t +__ZN3JSC4Yarr11checkSyntaxERKNS_7UStringE +__ZN3JSC4Yarr6ParserINS0_13SyntaxCheckerEE5parseEv +__ZN3JSC8JSParser17parseTryStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3JSC8JSParser17parseForStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3WTF6VectorISt4pairIiiELm0EE14expandCapacityEm +__ZN3JSC8JSParser24parseFunctionDeclarationINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3JSC8JSParser17parseFunctionInfoILNS0_20FunctionRequirementsE1ELb1ENS_13SyntaxCheckerEEEbRT1_RPKNS_10IdentifierERNS4_19FormalParameterListERNS4_12FunctionBodyERiSE_SE_ +_JSValueToBoolean +__ZN3WTF21charactersToIntStrictEPKtmPbi +__ZN3JSC8JSParser17parseForStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3JSC10ASTBuilder14makeBinaryNodeEiSt4pairIPNS_14ExpressionNodeENS0_12BinaryOpInfoEES5_ +__ZN3JSC10ASTBuilder15makePostfixNodeEPNS_14ExpressionNodeENS_8OperatorEiii +__ZN3JSC10ASTBuilder14makeAssignNodeEPNS_14ExpressionNodeENS_8OperatorES2_bbiii +__ZN3JSC7ForNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator13newLabelScopeENS_10LabelScope4TypeEPKNS_10IdentifierE +__ZN3JSC17BytecodeGenerator8emitJumpEPNS_5LabelE +__ZN3JSC19BracketAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZNK3JSC10NumberNode6isPureERNS_17BytecodeGeneratorE +__ZN3JSC17BytecodeGenerator22willResolveToArgumentsERKNS_10IdentifierE +__ZNK3JSC11ResolveNode6isPureERNS_17BytecodeGeneratorE +__ZN3JSC17BytecodeGenerator7isLocalERKNS_10IdentifierE +__ZN3JSC17BytecodeGenerator12emitGetByValEPNS_10RegisterIDES2_S2_ +__ZN3JSC18PostfixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator10emitPreIncEPNS_10RegisterIDE +__ZN3JSC12BinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZNK3JSC14ExpressionNode6isPureERNS_17BytecodeGeneratorE +__ZN3JSC17BytecodeGenerator12emitBinaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_NS_12OperandTypesE +__ZN3JSC17BytecodeGenerator14emitJumpIfTrueEPNS_10RegisterIDEPNS_5LabelE +__ZN3JSC3JIT11emit_op_jmpEPNS_11InstructionE +__ZN3JSC3JIT18emit_op_get_by_valEPNS_11InstructionE +__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common19RelationalConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS5_13TrustedImmPtrE +__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDES4_ii +__ZN3JSC3JIT15emit_op_pre_incEPNS_11InstructionE +__ZN3JSC3JIT16emitTimeoutCheckEv +__ZN3JSC3JIT13emit_op_jlessEPNS_11InstructionE +__ZN3JSC3JIT22emitSlow_op_get_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC9JITThunks7ctiStubEPNS_12JSGlobalDataEPFNS_21MacroAssemblerCodePtrES2_PNS_14ExecutablePoolEE +__ZN3WTF9HashTableIPFN3JSC21MacroAssemblerCodePtrEPNS1_12JSGlobalDataEPNS1_14ExecutablePoolEESt4pairIS8_S2_ENS_18PairFirstExtractorISA_EENS_7PtrHashIS8_EENS_14PairHashTraitsINS_10HashTraitsIS8_EENSG_IS2_EEEESH_E6expandEv +__ZN3JSC3JIT27stringGetByValStubGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE +__ZN3JSC21roundUpAllocationSizeEmm +__ZN3JSC3JIT19emitSlow_op_pre_incEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT17emitSlow_op_jlessEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC12X86Assembler7movq_rrENS_12X86Registers10RegisterIDENS1_13XMMRegisterIDE +__ZN3JSC23MacroAssemblerX86Common12branchDoubleENS0_15DoubleConditionENS_12X86Registers13XMMRegisterIDES3_ +__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_12X86Registers10RegisterIDE +__ZN3JSC10ASTBuilder11makeAddNodeEPNS_14ExpressionNodeES2_b +__ZNK3JSC14ExpressionNode8isNumberEv +__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14expandCapacityEmPKS3_ +__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE15reserveCapacityEm +__ZN3JSC13AssignDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZNK3JSC7AddNode5isAddEv +__ZN3JSC12BinaryOpNode10emitStrcatERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_PNS_21ReadModifyResolveNodeE +__ZNK3JSC14ExpressionNode5isAddEv +__ZNK3JSC10StringNode8isStringEv +__ZNK3JSC14ExpressionNode8isStringEv +__ZN3JSC17BytecodeGenerator15emitToPrimitiveEPNS_10RegisterIDES2_ +__ZN3JSC17BytecodeGenerator10emitStrcatEPNS_10RegisterIDES2_i +__ZN3JSC17BytecodeGenerator11emitPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_ +__ZN3JSC10IfElseNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC3JIT20emit_op_to_primitiveEPNS_11InstructionE +__ZN3JSC3JIT14emit_op_strcatEPNS_11InstructionE +__ZN3JSC3JIT17emit_op_put_by_idEPNS_11InstructionE +__ZN3JSC3JIT24emitSlow_op_to_primitiveEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT21emitSlow_op_put_by_idEPNS_11InstructionERPNS_13SlowCaseEntryE +_cti_op_strcat +_cti_op_put_by_id +__ZNK3JSC8JSString11resolveRopeEPNS_9ExecStateE +__ZNK3JSC8JSString19resolveRopeSlowCaseEPNS_9ExecStateEPt +__ZNK3JSC18EmptyStatementNode16isEmptyStatementEv +__ZN3JSC8JSParser17parseTryStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm0EE14expandCapacityEm +__ZN3JSC17BytecodeGenerator20emitInitLazyRegisterEPNS_10RegisterIDE +__ZNK3JSC13LogicalOpNode26hasConditionContextCodegenEv +__ZN3JSC13LogicalOpNode30emitBytecodeInConditionContextERNS_17BytecodeGeneratorEPNS_5LabelES4_b +__ZNK3JSC14ExpressionNode6isNullEv +__ZNK3JSC10StringNode6isPureERNS_17BytecodeGeneratorE +__ZN3JSC17TypeOfResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator11emitUnaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_ +__ZN3JSC17BytecodeGenerator19emitResolveWithBaseEPNS_10RegisterIDES2_RKNS_10IdentifierE +__ZN3JSC7TryNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC20EvalFunctionCallNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator12emitCallEvalEPNS_10RegisterIDES2_RNS_13CallArgumentsEjjj +__ZN3JSC17BytecodeGenerator9emitCatchEPNS_10RegisterIDEPNS_5LabelES4_ +__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14expandCapacityEm +__ZN3JSC17BytecodeGenerator16emitPushNewScopeEPNS_10RegisterIDERKNS_10IdentifierES2_ +__ZN3WTF6VectorIN3JSC18ControlFlowContextELm0EE14expandCapacityEm +__ZN3JSC17BytecodeGenerator21emitResolveBaseForPutEPNS_10RegisterIDERKNS_10IdentifierE +__ZN3JSC17BytecodeGenerator15emitResolveBaseEPNS_10RegisterIDERKNS_10IdentifierE +__ZN3JSC17BytecodeGenerator12emitPopScopeEv +__ZN3JSC9EqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator14emitEqualityOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_ +__ZN3JSC3JIT21emit_op_init_lazy_regEPNS_11InstructionE +__ZN3JSC3JIT25emit_op_create_activationEPNS_11InstructionE +__ZN3JSC20MacroAssemblerX86_6413branchTestPtrENS_23MacroAssemblerX86Common15ResultConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS5_12TrustedImm32E +__ZN3JSC3JIT11emit_op_neqEPNS_11InstructionE +__ZN3JSC12X86Assembler6orl_irEiNS_12X86Registers10RegisterIDE +__ZN3JSC3JIT13emit_op_jtrueEPNS_11InstructionE +__ZN3JSC3JIT25emit_op_resolve_with_baseEPNS_11InstructionE +__ZN3JSC3JIT17emit_op_call_evalEPNS_11InstructionE +__ZN3JSC3JIT13emit_op_catchEPNS_11InstructionE +__ZN3JSC20MacroAssemblerX86_647loadPtrENS_22AbstractMacroAssemblerINS_12X86AssemblerEE15ImplicitAddressENS_12X86Registers10RegisterIDE +__ZN3JSC3JIT22emit_op_push_new_scopeEPNS_11InstructionE +__ZN3JSC3JIT20emit_op_resolve_baseEPNS_11InstructionE +__ZN3JSC3JIT15emit_op_resolveEPNS_11InstructionE +__ZN3JSC3JIT17emit_op_pop_scopeEPNS_11InstructionE +__ZN3JSC3JIT10emit_op_eqEPNS_11InstructionE +__ZN3JSC3JIT27emit_op_tear_off_activationEPNS_11InstructionE +__ZN3JSC3JIT15emitSlow_op_neqEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT17emitSlow_op_jtrueEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT21emitSlow_op_call_evalEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT14emitSlow_op_eqEPNS_11InstructionERPNS_13SlowCaseEntryE +_cti_op_push_activation +__ZN3JSC12JSActivationC1EPNS_9ExecStateEPNS_18FunctionExecutableE +_cti_op_typeof +__ZN3JSC20jsTypeStringForValueEPNS_9ExecStateENS_7JSValueE +_cti_op_eq +_cti_op_resolve_with_base +__ZN3JSC12JSActivation18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +_cti_op_call_eval +__ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12RegisterFileEPNS_8RegisterEii +__ZN3JSC14EvalExecutableC1EPNS_9ExecStateERKNS_10SourceCodeEb +__ZN3JSC14EvalExecutable15compileInternalEPNS_9ExecStateEPNS_14ScopeChainNodeE +__ZN3JSC6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_14JSGlobalObjectEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPNS_18FunctionParametersENS_18JSParserStrictnessEPPNS_8JSObjectE +__ZN3JSC8EvalNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISL_EEEERKNS_10SourceCodeEji +__ZN3JSC14ScopeChainNode10localDepthEv +__ZN3JSC17BytecodeGeneratorC1EPNS_8EvalNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE +__ZN3JSC17BytecodeGeneratorC2EPNS_8EvalNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE +__ZN3JSC8EvalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZThn16_N3JSC8EvalNodeD0Ev +__ZN3JSC8EvalNodeD0Ev +__ZN3WTF7HashMapINS_6RefPtrINS_10StringImplEEEN3JSC12WriteBarrierINS4_14EvalExecutableEEENS_10StringHashENS_10HashTraitsIS3_EENS9_IS7_EEE3setEPS2_RKS7_ +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC12WriteBarrierINS5_14EvalExecutableEEEENS_18PairFirstExtractorIS9_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSE_IS8_EEEESF_E6expandEv +__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE +__ZN3JSC11Interpreter7executeEPNS_14EvalExecutableEPNS_9ExecStateEPNS_8JSObjectEiPNS_14ScopeChainNodeE +_cti_op_resolve +_JSValueMakeBoolean +__ZN3JSC8JSParser20parseReturnStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3JSC10ASTBuilder11makeDivNodeEPNS_14ExpressionNodeES2_b +__ZN3JSC14ExpressionNode14stripUnaryPlusEv +__ZNK3JSC10NumberNode8isNumberEv +__ZN3JSC15StrictEqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC10ReturnNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC13LogicalOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSCeqERKNS_7UStringEPKc +__ZN3JSC23CallFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator25emitJumpIfNotFunctionCallEPNS_10RegisterIDEPNS_5LabelE +__ZNK3JSC10ReturnNode12isReturnNodeEv +__ZNK3JSC14SourceElements15singleStatementEv +__ZN3JSC3JIT16emit_op_stricteqEPNS_11InstructionE +__ZN3JSC3JIT17compileOpStrictEqEPNS_11InstructionENS0_21CompileOpStrictEqTypeE +__ZN3JSC3JIT11emit_op_divEPNS_11InstructionE +__ZN3JSC23MacroAssemblerX86Common4moveENS_22AbstractMacroAssemblerINS_12X86AssemblerEE12TrustedImm32ENS_12X86Registers10RegisterIDE +__ZN3JSC12X86Assembler11cvtsi2sd_rrENS_12X86Registers10RegisterIDENS1_13XMMRegisterIDE +__ZN3JSC3JIT16emit_op_jneq_ptrEPNS_11InstructionE +__ZN3JSC3JIT20emitSlow_op_stricteqEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT15emitSlow_op_divEPNS_11InstructionERPNS_13SlowCaseEntryE +_cti_op_stricteq +__ZN3JSC10RegExpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC11regExpFlagsERKNS_7UStringE +__ZN3JSC11RegExpCache14lookupOrCreateERKNS_7UStringENS_11RegExpFlagsE +__ZN3WTF9HashTableIN3JSC9RegExpKeyESt4pairIS2_NS_6RefPtrINS1_6RegExpEEEENS_18PairFirstExtractorIS7_EENS_10RegExpHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSD_IS6_EEEESE_E6rehashEi +__ZN3JSC11RegExpCache6createERKNS_7UStringENS_11RegExpFlagsEN3WTF24HashTableIteratorAdapterINS5_9HashTableINS_9RegExpKeyESt4pairIS8_NS5_6RefPtrINS_6RegExpEEEENS5_18PairFirstExtractorISD_EENS5_10RegExpHashIS8_EENS5_14PairHashTraitsINS5_10HashTraitsIS8_EENSJ_ISC_EEEESK_EESD_EE +__ZN3JSC4Yarr13YarrGenerator12generateTermEm +__ZN3JSC4Yarr13YarrGenerator19jumpIfCharNotEqualsEti +__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDES4_ii +__ZN3JSC12X86Assembler7subl_irEiNS_12X86Registers10RegisterIDE +__ZN3JSC4Yarr13YarrGenerator13backtrackTermEm +__ZN3JSC4Yarr13YarrGenerator20backtrackTermDefaultEm +__ZN3JSC17BytecodeGenerator13emitNewRegExpEPNS_10RegisterIDEN3WTF10PassRefPtrINS_6RegExpEEE +__ZN3JSC17BytecodeGenerator9addRegExpEN3WTF10PassRefPtrINS_6RegExpEEE +__ZNK3JSC14ExpressionNode10isSubtractEv +__ZN3JSC3JIT18emit_op_new_regexpEPNS_11InstructionE +__ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +_cti_op_new_regexp +__ZN3JSCL22stringProtoFuncReplaceEPNS_9ExecStateE +__ZNK3JSC7JSValue14toThisJSStringEPNS_9ExecStateE +__ZN3JSC9ExecState8argumentEi +__ZN3JSC6JSCell11getCallDataERNS_8CallDataE +__ZN3WTF6RefPtrINS_10StringImplEEaSERKS2_ +__ZN3JSC6RegExp5matchERKNS_7UStringEiPN3WTF6VectorIiLm32EEE +__ZN3JSC4Yarr7executeERNS0_13YarrCodeBlockEPKtjjPi +__ZN3JSC3JIT11emit_op_addEPNS_11InstructionE +_cti_op_add +_cti_op_tear_off_activation +__ZN3JSC9JITThunks15tryCacheGetByIDEPNS_9ExecStateEPNS_9CodeBlockENS_16ReturnAddressPtrENS_7JSValueERKNS_10IdentifierERKNS_12PropertySlotEPNS_17StructureStubInfoE +__ZN3JSC3JIT33privateCompilePatchGetArrayLengthENS_16ReturnAddressPtrE +__ZNK3JSC8JSObject24getPropertySpecificValueEPNS_9ExecStateERKNS_10IdentifierERPNS_6JSCellE +__ZN3JSC27ctiPatchCallByReturnAddressEPNS_9CodeBlockENS_16ReturnAddressPtrENS_11FunctionPtrE +__ZN3JSC3JIT8linkCallEPNS_10JSFunctionEPNS_9CodeBlockES4_NS_21MacroAssemblerCodePtrEPNS_12CallLinkInfoEiPNS_12JSGlobalDataE +__ZN3JSC3JIT20patchMethodCallProtoERNS_12JSGlobalDataEPNS_9CodeBlockERNS_18MethodCallLinkInfoEPNS_10JSFunctionEPNS_9StructureEPNS_8JSObjectENS_16ReturnAddressPtrE +__ZN3JSC9JITThunks15tryCachePutByIDEPNS_9ExecStateEPNS_9CodeBlockENS_16ReturnAddressPtrENS_7JSValueERKNS_15PutPropertySlotEPNS_17StructureStubInfoEb +_cti_op_get_by_id_generic +_cti_op_put_by_id_generic +__ZN3JSC14StructureChainC1ERNS_12JSGlobalDataEPNS_9StructureES4_ +__ZN3JSC14StructureChainC2ERNS_12JSGlobalDataEPNS_9StructureES4_ +__ZN3JSC3JIT26privateCompileGetByIdChainEPNS_17StructureStubInfoEPNS_9StructureEPNS_14StructureChainEmRKNS_10IdentifierERKNS_12PropertySlotEmNS_16ReturnAddressPtrEPNS_9ExecStateE +__ZN3JSC3JIT13testPrototypeENS_7JSValueERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListE +__ZN3JSC3JIT22compileGetDirectOffsetEPNS_8JSObjectENS_12X86Registers10RegisterIDEm +_cti_op_get_by_id_proto_list +__ZN3JSC3JIT30privateCompileGetByIdChainListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureEPNS_14StructureChainEmRKNS_10IdentifierERKNS_12PropertySlotEmPNS_9ExecStateE +__ZNK3JSC14LogicalNotNode26hasConditionContextCodegenEv +__ZN3JSC11UnaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC14StructureChain13visitChildrenERNS_9MarkStackE +__ZN3JSC12RegExpObjectD1Ev +__ZN3JSC21UStringSourceProviderD0Ev +__ZN3JSC14EvalExecutableD1Ev +__ZN3JSC13EvalCodeBlockD0Ev +__ZN3JSC14ExecutablePool13systemReleaseERNS0_10AllocationE +__ZN3WTF11OSAllocator8decommitEPvm +__ZN3JSC12JSActivationD1Ev +__ZN3JSC19SourceProviderCache5clearEv +__ZNK3WTF6String8toDoubleEPbS1_ +__ZN3JSC8JSParser5Scope19restoreFunctionInfoEPKNS_23SourceProviderCacheItemE +__ZN3JSC5Lexer9setOffsetEi +_JSStringCreateWithCharacters +__ZN3WTF6VectorItLm0EE14expandCapacityEmPKt +__ZN3WTF10StringImpl7replaceEtt +__ZN3JSC14StructureChainD1Ev +__ZN3WTF10StringImpl7replaceEPS0_S1_ +__ZNK3WTF6String5toIntEPb +__ZN3WTF10StringImpl5toIntEPb +__ZN3WTF15charactersToIntEPKtmPb +__ZN3WTF6String6numberEi +__ZN3WTF6String6numberEt +__ZNK3WTF6String18simplifyWhiteSpaceEv +__ZN3WTF10StringImpl18simplifyWhiteSpaceEv +_JSValueMakeNumber +__ZN3JSC13LiteralParser5Lexer9lexNumberERNS1_18LiteralParserTokenE +__ZN3JSCL22stringProtoFuncIndexOfEPNS_9ExecStateE +__ZN3WTF10StringImpl5adoptERNS_12StringBufferE +__ZNK3WTF6String8foldCaseEv +__ZN3WTF10StringImpl8foldCaseEv +__ZN3WTF14FastMallocZone4sizeEP14_malloc_zone_tPKv +__ZNK3WTF6String7toFloatEPbS1_ +__ZN3WTF10StringImpl7toFloatEPbS1_ +__ZN3WTF17charactersToFloatEPKtmPbS2_ +__ZN3JSC17ReadModifyDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC7UString6numberEi +__ZN3JSC3JIT15emitSlow_op_addEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT28compileBinaryArithOpSlowCaseENS_8OpcodeIDERPNS_13SlowCaseEntryEjjjNS_12OperandTypesEbb +__ZNK3JSC7UString5asciiEv +__ZN3JSC6JSLock12DropAllLocksC1ENS_14JSLockBehaviorE +_cti_op_less +__ZN3JSC8jsStringEPNS_9ExecStateERKNS_7UStringE +_cti_op_get_by_val +__ZN3WTF10StringImpl5upperEv +__ZN3JSC10ASTBuilder14makePrefixNodeEPNS_14ExpressionNodeENS_8OperatorEiii +__ZN3JSC17PrefixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC4Yarr22YarrPatternConstructor25atomBuiltInCharacterClassENS0_23BuiltInCharacterClassIDEb +__ZN3JSC4Yarr13YarrGenerator12atEndOfInputEv +__ZN3JSC4Yarr13YarrGenerator13readCharacterEiNS_12X86Registers10RegisterIDE +__ZN3JSC4Yarr13YarrGenerator19matchCharacterClassENS_12X86Registers10RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListEPKNS0_14CharacterClassE +__ZN3JSC14MacroAssembler4pokeENS_12X86Registers10RegisterIDEi +__ZN3JSC21ReadModifyResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC3JIT20compileBinaryArithOpENS_8OpcodeIDEjjjNS_12OperandTypesE +__ZN3JSC23MacroAssemblerX86Common4moveENS_12X86Registers10RegisterIDES2_ +__ZN3JSCL20stringProtoFuncMatchEPNS_9ExecStateE +__ZNK3JSC17RegExpConstructor14arrayOfMatchesEPNS_9ExecStateE +__ZN3JSC18RegExpMatchesArrayC2EPNS_9ExecStateEPNS_24RegExpConstructorPrivateE +__ZN3JSC7JSArrayC2ERNS_12JSGlobalDataEPNS_9StructureEjNS_17ArrayCreationModeE +__ZN3JSC7JSArray15setSubclassDataEPv +__ZN3JSC18RegExpMatchesArrayD1Ev +__ZNK3JSC7JSArray12subclassDataEv +__ZN3WTF10StringImpl16findIgnoringCaseEPKcj +__ZN3WTF14numberToStringEdPt +__ZN3WTF4dtoaILb1ELb0ELb0ELb1EEEvPcdiRbRiRj +__ZNK3WTF13DecimalNumber15toStringDecimalEPtj +__ZN3WTF10StringImpl8toDoubleEPbS1_ +__ZN3WTF6VectorIjLm16EE6resizeEm +__ZN3WTFL7multaddERNS_6BigIntEii +__ZN3WTFL4multERNS_6BigIntERKS0_ +__ZN3WTF6VectorIjLm16EEaSERKS1_ +__ZN3WTF6String6numberEd +__ZN3JSC17BytecodeGenerator16emitPutScopedVarEmiPNS_10RegisterIDENS_7JSValueE +__ZN3JSC3JIT22emit_op_put_global_varEPNS_11InstructionE +__ZN3JSC3JIT11emit_op_subEPNS_11InstructionE +__ZN3JSC3JIT15emitSlow_op_subEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSCL21stringProtoFuncSubstrEPNS_9ExecStateE +__ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE +__ZNK3JSC8JSString8toNumberEPNS_9ExecStateE +__ZN3JSC10jsToNumberERKNS_7UStringE +__ZN3JSCL19jsStrDecimalLiteralERPKtS1_ +__ZN3WTF22cancelCallOnMainThreadEPFvPvES0_ +__ZN3WTF22isMainThreadOrGCThreadEv +__ZNK3JSC8JSString9toBooleanEPNS_9ExecStateE +__ZN3WTF10StringImpl4findEPFbtEj +__ZN3WTF10StringImpl4findEPKcj +__ZN3WTF6String26fromUTF8WithLatin1FallbackEPKcm +__ZN3WTF10fastStrDupEPKc +__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPN3WTF10StringImplE +_JSStringRetain +___initializeScavenger_block_invoke_1 +__ZN3WTF23waitForThreadCompletionEj +__ZN3WTF23waitForThreadCompletionEjPPv +_JSObjectCopyPropertyNames +__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE +__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE +__ZN3JSC9Structure16getPropertyNamesERNS_12JSGlobalDataERNS_17PropertyNameArrayENS_15EnumerationModeE +__ZN3JSC9ExecState20objectPrototypeTableEPS0_ +_JSPropertyNameArrayGetCount +_JSPropertyNameArrayRelease +__Z22TCMalloc_SystemReleasePvm +__Z21TCMalloc_SystemCommitPvm +__ZN3WTF6VectorIPvLm0EE14expandCapacityEm +__ZN3JSC3JIT15emit_op_jlesseqEPNS_11InstructionEb +__ZN3JSC3JIT16emit_op_jnlesseqEPNS_11InstructionE +__ZN3JSC3JIT19emitSlow_op_jlesseqEPNS_11InstructionERPNS_13SlowCaseEntryEb +__ZN3JSC3JIT20emitSlow_op_jnlesseqEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC19ReverseBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC3JIT14emit_op_jnlessEPNS_11InstructionE +__ZN3JSC3JIT18emitSlow_op_jnlessEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3WTF6String8truncateEj +_cti_op_get_by_id_self_fail +__ZN3JSC3JIT29privateCompileGetByIdSelfListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureERKNS_10IdentifierERKNS_12PropertySlotEm +_cti_op_get_by_id_custom_stub +__ZN3JSC10ASTBuilder12makeMultNodeEPNS_14ExpressionNodeES2_b +__ZN3JSC3JIT11emit_op_mulEPNS_11InstructionE +__ZN3JSC3JIT15emitSlow_op_mulEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3WTF13StringBuilder15reserveCapacityEj +__ZN3WTF17equalIgnoringCaseEPKtPKcj +__ZN3WTF4dtoaEPcdRbRiRj +__ZNK3WTF13DecimalNumber28bufferLengthForStringDecimalEv +__ZN3JSC3JIT19patchPutByIdReplaceEPNS_9CodeBlockEPNS_17StructureStubInfoEPNS_9StructureEmNS_16ReturnAddressPtrEb +__ZN3JSC10Identifier5equalEPKN3WTF10StringImplEPKc +__ZN3JSC8JSParser19parseBreakStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3JSC8JSParser17parseFunctionInfoILNS0_20FunctionRequirementsE0ELb0ENS_13SyntaxCheckerEEEbRT1_RPKNS_10IdentifierERNS4_19FormalParameterListERNS4_12FunctionBodyERiSE_SE_ +__ZN3JSC8JSParser21parseConstDeclarationINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3JSC18ConstStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC13ConstDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC13ConstDeclNode14emitCodeSingleERNS_17BytecodeGeneratorE +__ZN3JSC17BytecodeGenerator16constRegisterForERKNS_10IdentifierE +__ZN3JSC21ThrowableBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +_cti_op_call_arityCheck +_cti_op_in +__ZN3JSC12JSActivation13visitChildrenERNS_9MarkStackE +__ZNK3JSC12JSActivation14isDynamicScopeERb +__ZN3JSC3JIT22emit_op_get_scoped_varEPNS_11InstructionE +__ZN3JSC8JSParser19parseBreakStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3JSC15ConditionalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC9BreakNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator11breakTargetERKNS_10IdentifierE +__ZN3JSC17BytecodeGenerator14emitJumpScopesEPNS_5LabelEi +__ZN3JSCL20stringProtoFuncSplitEPNS_9ExecStateE +__ZN3JSC11jsSubstringEPNS_12JSGlobalDataERKNS_7UStringEjj +__ZN3JSC7JSArray3putEPNS_9ExecStateEjNS_7JSValueE +__ZN3JSC7JSArray11putSlowCaseEPNS_9ExecStateEjNS_7JSValueE +__ZN3JSC10ASTBuilder11makeSubNodeEPNS_14ExpressionNodeES2_b +__ZN3JSC10MathObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSCL16mathProtoFuncAbsEPNS_9ExecStateE +_cti_op_lesseq +__ZN3JSC7UString6numberEd +__ZN3JSC9CodeBlock14visitAggregateERNS_9MarkStackE +__ZN3JSC13EvalCodeCache14visitAggregateERNS_9MarkStackE +__ZN3JSC17StructureStubInfo14visitAggregateERNS_9MarkStackE +_cti_op_resolve_base +__ZN3JSC17ObjectLiteralNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC16PropertyListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator13emitNewObjectEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator17emitDirectPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_ +__ZN3JSC3JIT18emit_op_new_objectEPNS_11InstructionE +_cti_op_new_object +_cti_op_put_by_id_direct +__ZN3JSC14ArrayPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSCL21arrayProtoFuncForEachEPNS_9ExecStateE +__ZN3JSC11Interpreter20prepareForRepeatCallEPNS_18FunctionExecutableEPNS_9ExecStateEPNS_10JSFunctionEiPNS_14ScopeChainNodeE +__ZNK3JSC19BracketAccessorNode10isLocationEv +__ZNK3JSC19BracketAccessorNode21isBracketAccessorNodeEv +__ZN3JSC17AssignBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator12emitPutByValEPNS_10RegisterIDES2_S2_ +__ZN3JSC3JIT18emit_op_put_by_valEPNS_11InstructionE +__ZN3JSC3JIT22emitSlow_op_put_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC11Interpreter7executeERNS_16CallFrameClosureE +__ZN3JSC3JIT16patchGetByIdSelfEPNS_9CodeBlockEPNS_17StructureStubInfoEPNS_9StructureEmNS_16ReturnAddressPtrE +_cti_op_put_by_val +__ZN3JSC11Interpreter13endRepeatCallERNS_16CallFrameClosureE +__ZN3JSC3JIT22emit_op_put_scoped_varEPNS_11InstructionE +_cti_op_is_string +_cti_op_is_number +__ZN3JSC20globalFuncParseFloatEPNS_9ExecStateE +__ZN3WTF6VectorIcLm32EE14expandCapacityEm +_cti_op_to_primitive +__ZN3JSCL22objectProtoFuncValueOfEPNS_9ExecStateE +__ZN3JSCL22arrayProtoFuncToStringEPNS_9ExecStateE +_cti_op_jless +__ZN3JSCL24stringProtoFuncSubstringEPNS_9ExecStateE +__ZN3JSC18globalFuncParseIntEPNS_9ExecStateE +__ZN3JSCL8parseIntERKNS_7UStringEi +__ZN3JSC15TypeOfValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC3JIT26privateCompileGetByIdProtoEPNS_17StructureStubInfoEPNS_9StructureES4_RKNS_10IdentifierERKNS_12PropertySlotEmNS_16ReturnAddressPtrEPNS_9ExecStateE +_cti_op_sub +__ZN3WTF6String6appendEc +__ZN3JSCL18arrayProtoFuncPushEPNS_9ExecStateE +__ZN3JSCL18arrayProtoFuncSortEPNS_9ExecStateE +__ZN3JSC7JSArray4sortEPNS_9ExecStateE +__ZN3JSC7JSArray17compactForSortingEv +__ZN3JSC4Heap18pushTempSortVectorEPN3WTF6VectorISt4pairINS_7JSValueENS_7UStringEELm0EEE +__ZN3WTF6VectorIPNS0_ISt4pairIN3JSC7JSValueENS2_7UStringEELm0EEELm0EE15reserveCapacityEm +__ZN3JSCL27compareByStringPairForQSortEPKvS1_ +__ZN3WTF16codePointCompareEPKNS_10StringImplES2_ +__ZN3JSC4Heap17popTempSortVectorEPN3WTF6VectorISt4pairINS_7JSValueENS_7UStringEELm0EEE +__ZN3JSCL18arrayProtoFuncJoinEPNS_9ExecStateE +__ZN3WTF6VectorItLm64EE17tryExpandCapacityEm +__ZN3JSC15JSStringBuilder5buildEPNS_9ExecStateE +__ZN3JSC17BytecodeGenerator15emitNewFunctionEPNS_10RegisterIDEPNS_16FunctionBodyNodeE +__ZN3JSC17BytecodeGenerator23emitNewFunctionInternalEPNS_10RegisterIDEjb +__ZN3JSC3JIT16emit_op_new_funcEPNS_11InstructionE +_cti_op_new_func +__ZN3JSC3JIT17emit_op_nstricteqEPNS_11InstructionE +__ZN3JSC3JIT21emitSlow_op_nstricteqEPNS_11InstructionERPNS_13SlowCaseEntryE +_cti_op_nstricteq +__ZN3JSC14LogicalNotNode30emitBytecodeInConditionContextERNS_17BytecodeGeneratorEPNS_5LabelES4_b +__ZN3JSC3JIT18emit_op_jmp_scopesEPNS_11InstructionE +_cti_op_negate +__ZN3JSCL16mathProtoFuncMaxEPNS_9ExecStateE +__ZN3WTF15ThreadConditionD1Ev +__ZN3JSCL23stringProtoFuncToStringEPNS_9ExecStateE +__ZN3JSC24ApplyFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZNK3JSC14ExpressionNode13isSimpleArrayEv +__ZN3JSC17BytecodeGenerator26emitJumpIfNotFunctionApplyEPNS_10RegisterIDEPNS_5LabelE +__ZN3JSC17BytecodeGenerator29uncheckedRegisterForArgumentsEv +__ZN3JSC17BytecodeGenerator15emitLoadVarargsEPNS_10RegisterIDES2_S2_ +__ZN3JSC17BytecodeGenerator15emitCallVarargsEPNS_10RegisterIDES2_S2_S2_jjj +__ZN3JSC3JIT20emit_op_load_varargsEPNS_11InstructionE +__ZN3JSC3JIT20emit_op_call_varargsEPNS_11InstructionE +__ZN3JSC3JIT20compileOpCallVarargsEPNS_11InstructionE +__ZN3JSC3JIT24emit_op_create_argumentsEPNS_11InstructionE +__ZN3JSC3JIT24emitSlow_op_load_varargsEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT24emitSlow_op_call_varargsEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT28compileOpCallVarargsSlowCaseEPNS_11InstructionERPNS_13SlowCaseEntryE +_cti_op_call_jitCompile +__ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE +__ZN3JSC16BooleanPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSCL24booleanProtoFuncToStringEPNS_9ExecStateE +__ZN3JSC17BytecodeGenerator18pushFinallyContextEPNS_5LabelEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator17popFinallyContextEv +__ZN3JSC17BytecodeGenerator19highestUsedRegisterEv +__ZN3JSC17BytecodeGenerator18emitJumpSubroutineEPNS_10RegisterIDEPNS_5LabelE +__ZN3JSC17BytecodeGenerator20emitSubroutineReturnEPNS_10RegisterIDE +__ZN3JSC3JIT11emit_op_jsrEPNS_11InstructionE +__ZN3WTF6VectorIN3JSC3JIT7JSRInfoELm0EE14expandCapacityEm +__ZN3JSC3JIT12emit_op_sretEPNS_11InstructionE +__ZN3JSC10throwErrorEPNS_9ExecStateENS_7JSValueE +__ZN3JSC12hasErrorInfoEPNS_9ExecStateEPNS_8JSObjectE +__ZN3JSC9CodeBlock27lineNumberForBytecodeOffsetEj +__ZN3JSC12addErrorInfoEPNS_9ExecStateEPNS_8JSObjectEiRKNS_10SourceCodeE +__ZN3JSC12addErrorInfoEPNS_12JSGlobalDataEPNS_8JSObjectEiRKNS_10SourceCodeE +__ZN3JSC8JSObject17putWithAttributesEPNS_12JSGlobalDataERKNS_10IdentifierENS_7JSValueEj +_cti_op_push_new_scope +__ZN3JSC19JSStaticScopeObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC12JSActivation3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE +_cti_op_pop_scope +__ZN3JSC19JSStaticScopeObjectD1Ev +__ZN3JSC14InstanceOfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator20emitCheckHasInstanceEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator14emitInstanceOfEPNS_10RegisterIDES2_S2_S2_ +__ZN3JSC3JIT26emit_op_check_has_instanceEPNS_11InstructionE +__ZN3JSC3JIT18emit_op_instanceofEPNS_11InstructionE +__ZN3JSC3JIT30emitSlow_op_check_has_instanceEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC3JIT22emitSlow_op_instanceofEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC14throwTypeErrorEPNS_9ExecStateE +__ZN3JSC4Yarr12digitsCreateEv +__ZN3WTF16VectorBufferBaseIcE14allocateBufferEm +__ZN3JSC4Yarr13YarrGenerator24matchCharacterClassRangeENS_12X86Registers10RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListES8_PKNS0_14CharacterRangeEjPjPKtj +__ZN3JSC23MacroAssemblerX86Common4jumpEv +__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_19RelationalConditionENS_12X86Registers10RegisterIDES3_ +__ZN3JSC4Yarr13YarrGenerator17BacktrackingState6linkToENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5LabelEPNS_14MacroAssemblerE +__ZN3JSC4Yarr22YarrPatternConstructor23setupDisjunctionOffsetsEPNS0_18PatternDisjunctionEjj +__ZN3JSC4Yarr13YarrGenerator17BacktrackingState24takeBacktracksToJumpListERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListEPNS_14MacroAssemblerE +__ZNK3JSC11BooleanNode6isPureERNS_17BytecodeGeneratorE +_cti_timeout_check +__ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE +__ZN3JSC22createNotAnObjectErrorEPNS_9ExecStateENS_7JSValueE +__ZN3JSC11makeUStringIPKcNS_7UStringES2_EES3_T_T0_T1_ +__ZN3WTF13tryMakeStringIPKcN3JSC7UStringES2_EENS_10PassRefPtrINS_10StringImplEEET_T0_T1_ +__ZN3JSC15createTypeErrorEPNS_9ExecStateERKNS_7UStringE +__ZN3JSC10throwErrorEPNS_9ExecStateEPNS_8JSObjectE +__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC9CodeBlock32expressionRangeForBytecodeOffsetEjRiS1_S1_ +__ZN3JSC11makeUStringINS_7UStringEPKcS1_S3_EES1_T_T0_T1_T2_ +__ZN3WTF13tryMakeStringIN3JSC7UStringEPKcS2_S4_EENS_10PassRefPtrINS_10StringImplEEET_T0_T1_T2_ +__ZN3JSC13JSNotAnObjectD1Ev +__ZN3JSCL18mathProtoFuncRoundEPNS_9ExecStateE +__ZN3JSCL18mathProtoFuncFloorEPNS_9ExecStateE +__ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE +__ZN3JSC26createNotAConstructorErrorEPNS_9ExecStateENS_7JSValueE +__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE +__ZNK3JSC8JSObject9classNameEv +__ZNK3JSC14ExpressionNode11isCommaNodeEv +__ZN3JSC9CommaNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC9CommaNodeD1Ev +__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE14expandCapacityEm +__ZN3JSC10ASTBuilder11makeModNodeEPNS_14ExpressionNodeES2_b +__ZN3JSC3JIT11emit_op_modEPNS_11InstructionE +__ZN3JSC3JIT15emitSlow_op_modEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_iENS_18PairFirstExtractorIS5_EEN3JSC17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS8_17BytecodeGenerator28IdentifierMapIndexHashTraitsEEESC_E4findIS3_NS_22IdentityHashTranslatorIS3_S5_S9_EEEENS_17HashTableIteratorIS3_S5_S7_S9_SF_SC_EERKT_ +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_iENS_18PairFirstExtractorIS5_EEN3JSC17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENS8_17BytecodeGenerator28IdentifierMapIndexHashTraitsEEESC_E6rehashEi +__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm32EEELm32EE14expandCapacityEmPKS4_ +__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm32EEELm32EE15reserveCapacityEm +__ZN3JSC16throwSyntaxErrorEPNS_9ExecStateE +_cti_op_load_varargs +__ZN3WTF13tryFastCallocEmm +__ZN3JSC17BytecodeGenerator10emitPreDecEPNS_10RegisterIDE +__ZN3JSC3JIT15emit_op_pre_decEPNS_11InstructionE +__ZN3JSC3JIT19emitSlow_op_pre_decEPNS_11InstructionERPNS_13SlowCaseEntryE +_cti_op_pre_dec +__ZN3WTF10StringImpl16findIgnoringCaseEPS0_j +__ZN3JSC5Lexer19getUnicodeCharacterEv +__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateE +__ZN3JSC12JSGlobalData15getHostFunctionEPFPvPNS_9ExecStateEEPFNS_21MacroAssemblerCodePtrEPS0_PNS_14ExecutablePoolEE +__ZN3JSC9JITThunks16hostFunctionStubEPNS_12JSGlobalDataEPFPvPNS_9ExecStateEEPFNS_21MacroAssemblerCodePtrES2_PNS_14ExecutablePoolEE +__ZN3JSC18sqrtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE +__ZN3JSC19SpecializedThunkJIT8finalizeENS_21MacroAssemblerCodePtrE +__ZN3JSC10JSFunctionC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEiRKNS_10IdentifierEPNS_16NativeExecutableE +__ZN3JSC10JSFunctionC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEiRKNS_10IdentifierEPNS_16NativeExecutableE +__ZN3JSC3JIT11emit_op_notEPNS_11InstructionE +__ZN3JSC3JIT15emitSlow_op_notEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC17powThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE +__ZN3JSC12X86Assembler7cmpl_imEiiNS_12X86Registers10RegisterIDE +__ZN3JSC23MacroAssemblerX86Common26branchConvertDoubleToInt32ENS_12X86Registers13XMMRegisterIDENS1_10RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListES2_ +__ZN3JSC19SpecializedThunkJIT11returnInt32ENS_12X86Registers10RegisterIDE +__ZN3JSC19SpecializedThunkJIT12returnDoubleENS_12X86Registers13XMMRegisterIDE +__ZN3JSC19SpecializedThunkJITD1Ev +__ZN3JSC10ASTBuilder14makeDeleteNodeEPNS_14ExpressionNodeEiii +__ZN3JSC13DeleteDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator14emitDeleteByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE +__ZN3JSC3JIT17emit_op_del_by_idEPNS_11InstructionE +_cti_op_del_by_id +__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE +__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE +__ZN3JSC17ObjectConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC9Structure27despecifyFunctionTransitionERNS_12JSGlobalDataEPS0_RKNS_10IdentifierE +__ZN3JSC13PropertyTableC2ERNS_12JSGlobalDataEPNS_6JSCellERKS0_ +__ZNK3WTF6String6toUIntEPb +__ZN3WTF10StringImpl6toUIntEPb +__ZN3WTF16charactersToUIntEPKtmPb +__ZN3JSC8JSParser20parseSwitchStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3JSC8JSParser18parseSwitchClausesINS_13SyntaxCheckerEEENT_10ClauseListERS3_ +__ZN3JSC15ObjectPrototype18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE +__ZN3JSC8JSParser20parseSwitchStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3JSC8JSParser18parseSwitchClausesINS_10ASTBuilderEEENT_10ClauseListERS3_ +__ZN3JSC10SwitchNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC13CaseBlockNode20emitBytecodeForBlockERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_ +__ZN3JSC13CaseBlockNode18tryOptimizedSwitchERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERiS7_ +__ZN3JSCL17processClauseListEPNS_14ClauseListNodeERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERNS_10SwitchKindERbRiSB_ +__ZN3JSC3JIT14emit_op_bitandEPNS_11InstructionE +__ZN3JSC3JIT18emitSlow_op_bitandEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC12RegExpObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC15RegExpPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSCL19regExpProtoFuncTestEPNS_9ExecStateE +__ZN3JSC12RegExpObject4testEPNS_9ExecStateE +__ZN3JSC12RegExpObject5matchEPNS_9ExecStateE +__ZN3JSC3JIT20emit_op_resolve_skipEPNS_11InstructionE +_cti_op_resolve_skip +__ZN3WTFeqERKNS_12AtomicStringERKNS_6VectorItLm0EEE +__ZN3WTF11OSAllocator18releaseDecommittedEPvm +__ZN3WTF12AtomicString16fromUTF8InternalEPKcS2_ +__ZN3WTF7Unicode36calculateStringHashAndLengthFromUTF8EPKcS2_RjS3_ +__ZN3JSC17BytecodeGenerator11beginSwitchEPNS_10RegisterIDENS_10SwitchInfo10SwitchTypeE +__ZN3WTF6VectorIN3JSC10SwitchInfoELm0EE14expandCapacityEm +__ZN3JSC17BytecodeGenerator9endSwitchEjPN3WTF6RefPtrINS_5LabelEEEPPNS_14ExpressionNodeEPS3_ii +__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14expandCapacityEm +__ZN3JSC15StringJumpTableC1ERKS0_ +__ZN3JSC3JIT21emit_op_switch_stringEPNS_11InstructionE +__ZN3WTF6VectorIN3JSC12SwitchRecordELm0EE14expandCapacityEm +_cti_op_switch_string +__ZN3JSC10ASTBuilder13makeBitOrNodeEPNS_14ExpressionNodeES2_b +__ZN3JSC3JIT13emit_op_bitorEPNS_11InstructionE +__ZN3JSC3JIT17emitSlow_op_bitorEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZNK3WTF6String5splitERKS0_RNS_6VectorIS0_Lm0EEE +__ZN3JSC8JSParser19parseWhileStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3JSC8JSParser19parseWhileStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3JSC9WhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3WTF10StringImpl7replaceEtPS0_ +__ZN3JSC3JIT31privateCompilePutByIdTransitionEPNS_17StructureStubInfoEPNS_9StructureES4_mPNS_14StructureChainENS_16ReturnAddressPtrEb +_cti_op_put_by_id_fail +__ZN3JSC17BytecodeGenerator11emitPostIncEPNS_10RegisterIDES2_ +__ZN3JSC3JIT16emit_op_post_incEPNS_11InstructionE +__ZN3JSC3JIT20emitSlow_op_post_incEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSCL23createPrototypePropertyERNS_12JSGlobalDataEPNS_14JSGlobalObjectEPNS_10JSFunctionE +__ZNK3JSC8NullNode6isNullEv +__ZN3JSC3JIT17emit_op_jneq_nullEPNS_11InstructionE +_cti_op_convert_this +_cti_vm_lazyLinkConstruct +__ZN3JSC18FunctionExecutable27compileForConstructInternalEPNS_9ExecStateEPNS_14ScopeChainNodeE +__ZN3JSC3JIT18emit_op_get_calleeEPNS_11InstructionE +__ZN3JSC3JIT19emit_op_create_thisEPNS_11InstructionE +_cti_op_create_this +__ZN3JSC16ArrayConstructor16getConstructDataERNS_13ConstructDataE +__ZN3JSCL29constructWithArrayConstructorEPNS_9ExecStateE +__ZN3JSCL27constructArrayWithSizeQuirkEPNS_9ExecStateERKNS_7ArgListE +__ZN3JSC3JIT16emit_op_jeq_nullEPNS_11InstructionE +__ZN3JSC3JIT16emit_op_neq_nullEPNS_11InstructionE +__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14expandCapacityEm +__ZNK3JSC5Label4bindEii +__ZN3WTF6VectorIiLm0EEC2ERKS1_ +__ZN3JSC3JIT18emit_op_switch_immEPNS_11InstructionE +__ZN3WTF6VectorIN3JSC17CodeLocationLabelELm0EE14expandCapacityEm +_cti_op_switch_imm +__ZN3JSCL26stringProtoFuncToLowerCaseEPNS_9ExecStateE +__ZN3JSC8JSString17substringFromRopeEPNS_9ExecStateEjj +__ZN3WTF6String6removeEji +__ZN3WTF6String6insertERKS0_j +__ZN3WTF6String6insertEPKtjj +__ZN3JSCL26stringProtoFuncToUpperCaseEPNS_9ExecStateE +__ZN3JSCL26stringProtoFuncLastIndexOfEPNS_9ExecStateE +__ZNK3JSC7JSValue20toIntegerPreserveNaNEPNS_9ExecStateE +__ZN3WTFeqERKNS_7CStringES2_ +__ZN3WTF10StringImpl4fillEt +__ZN3WTF22charactersToUIntStrictEPKtmPbi +__ZNK3WTF6String5upperEv +__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE +__ZN3JSC23createNotAFunctionErrorEPNS_9ExecStateENS_7JSValueE +_cti_op_jmp_scopes +__ZNK3WTF6String6latin1Ev +__ZN3JSC3JIT30privateCompileGetByIdProtoListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureES6_RKNS_10IdentifierERKNS_12PropertySlotEmPNS_9ExecStateE +__ZN3JSC3JIT15emit_op_eq_nullEPNS_11InstructionE +__ZN3WTF6VectorISt4pairIiiELm8EE14expandCapacityEm +__ZN3WTF7Unicode18equalUTF16WithUTF8EPKtS2_PKcS4_ +__ZN3WTF11emptyStringEv +__ZN3WTF6String6numberEj +__ZN3JSC14PostfixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureEjNS_17ArrayCreationModeE +__ZN3JSC10Identifier4fromEPNS_9ExecStateEj +__ZN3JSC3JIT22compileGetDirectOffsetENS_12X86Registers10RegisterIDES2_PNS_9StructureEm +__ZN3WTF6VectorIN3JSC14ExecutablePool10AllocationELm2EE15reserveCapacityEm +__ZN3JSC4Yarr12spacesCreateEv +__ZN3WTF10StringImpl4costEv +__ZN3JSC17BytecodeGenerator22emitGetArgumentsLengthEPNS_10RegisterIDES2_ +__ZN3JSC3JIT28emit_op_get_arguments_lengthEPNS_11InstructionE +__ZN3JSC3JIT26emit_op_tear_off_argumentsEPNS_11InstructionE +__ZN3JSC3JIT32emitSlow_op_get_arguments_lengthEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC27ctiPatchCallByReturnAddressEPNS_9CodeBlockENS_16ReturnAddressPtrENS_21MacroAssemblerCodePtrE +__ZN3WTF6VectorIN3JSC4Yarr11PatternTermELm0EE14expandCapacityEmPKS3_ +__ZN3JSC4Yarr13YarrGenerator29generateAssertionWordBoundaryEm +__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_12X86Registers10RegisterIDES3_ii +__ZN3JSCL21stringProtoFuncSearchEPNS_9ExecStateE +__ZN3JSC17StringConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3JSC26fromCharCodeThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE +__ZN3JSCL12charToStringERNS_19SpecializedThunkJITEPNS_12JSGlobalDataENS_12X86Registers10RegisterIDES5_S5_ +__ZN3JSCL18stringFromCharCodeEPNS_9ExecStateE +__ZNK3JSC8JSObject14isGlobalObjectEv +__ZNK3WTF6String16removeCharactersEPFbtE +__ZN3WTF10StringImpl16removeCharactersEPFbtE +_JSContextGetGlobalContext +_JSWeakObjectMapCreate +__ZN3JSC14JSGlobalObject17weakMapsFinalizerEv +_JSWeakObjectMapGet +_JSWeakObjectMapSet +__ZN3WTF9HashTableIPvSt4pairIS1_PN3JSC7JSValueEENS_18PairFirstExtractorIS6_EENS_7PtrHashIS1_EENS_14PairHashTraitsINS_10HashTraitsIS1_EENSC_IS5_EEEESD_E6rehashEi +__ZN3JSC4Yarr6ParserINS0_13SyntaxCheckerEE11parseEscapeILb1ENS3_28CharacterClassParserDelegateEEEbRT0_ +__ZN3JSC8JSParser22parseContinueStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3JSC8JSParser21parseDoWhileStatementINS_10ASTBuilderEEENT_9StatementERS3_ +__ZN3JSC9ForInNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC17BytecodeGenerator20emitGetPropertyNamesEPNS_10RegisterIDES2_S2_S2_PNS_5LabelE +__ZN3WTF6VectorIN3JSC12ForInContextELm0EE14expandCapacityEm +__ZN3JSC11DoWhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17BytecodeGenerator20emitNextPropertyNameEPNS_10RegisterIDES2_S2_S2_S2_PNS_5LabelE -__ZN3JSC3JIT18emit_op_new_objectEPNS_11InstructionE __ZN3JSC3JIT18emit_op_get_pnamesEPNS_11InstructionE -__ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEmPKS2_ -__ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEm -__ZN3JSC3JIT11emit_op_jmpEPNS_11InstructionE -__ZN3JSC3JIT22emit_op_resolve_globalEPNS_11InstructionEb __ZN3JSC3JIT20emit_op_get_by_pnameEPNS_11InstructionE -__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDES4_ii -__ZN3JSC3JIT18emit_op_get_by_valEPNS_11InstructionE -__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common19RelationalConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS5_13TrustedImmPtrE -__ZN3JSC3JIT18emit_op_put_by_valEPNS_11InstructionE -__ZN3JSC3JIT16emit_op_stricteqEPNS_11InstructionE -__ZN3JSC3JIT17compileOpStrictEqEPNS_11InstructionENS0_21CompileOpStrictEqTypeE -__ZN3JSC12X86Assembler6orl_irEiNS_12X86Registers10RegisterIDE -__ZN3JSC3JIT16emitTimeoutCheckEv -__ZN3JSC3JIT13emit_op_jtrueEPNS_11InstructionE -__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common19RelationalConditionENS_12X86Registers10RegisterIDES4_ __ZN3JSC3JIT18emit_op_next_pnameEPNS_11InstructionE -__ZN3JSC20MacroAssemblerX86_6413branchTestPtrENS_23MacroAssemblerX86Common15ResultConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS5_12TrustedImm32E -__ZN3JSC23MacroAssemblerX86Common12branchTest32ENS0_15ResultConditionENS_12X86Registers10RegisterIDENS_22AbstractMacroAssemblerINS_12X86AssemblerEE12TrustedImm32E -__ZN3JSC3JIT26emitSlow_op_resolve_globalEPNS_11InstructionERPNS_13SlowCaseEntryE __ZN3JSC3JIT24emitSlow_op_get_by_pnameEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC11JITStubCall11addArgumentEjNS_12X86Registers10RegisterIDE -__ZN3JSC3JIT22emitSlow_op_get_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC9JITThunks7ctiStubEPNS_12JSGlobalDataEPFNS_21MacroAssemblerCodePtrES2_PNS_14ExecutablePoolEE -__ZN3WTF9HashTableIPFN3JSC21MacroAssemblerCodePtrEPNS1_12JSGlobalDataEPNS1_14ExecutablePoolEESt4pairIS8_S2_ENS_18PairFirstExtractorISA_EENS_7PtrHashIS8_EENS_14PairHashTraitsINS_10HashTraitsIS8_EENSG_IS2_EEEESH_E6expandEv -__ZN3JSC3JIT27stringGetByValStubGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE -__ZN3JSC21roundUpAllocationSizeEmm -__ZN3JSC3JIT22emitSlow_op_put_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT20emitSlow_op_stricteqEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT17emitSlow_op_jtrueEPNS_11InstructionERPNS_13SlowCaseEntryE -_cti_op_new_object -_cti_op_put_by_id_direct __ZN3JSC9Structure22toDictionaryTransitionERNS_12JSGlobalDataEPS0_NS0_14DictionaryKindE _cti_op_get_pnames __ZN3JSC22JSPropertyNameIterator6createEPNS_9ExecStateEPNS_8JSObjectE __ZN3WTF6VectorIN3JSC10IdentifierELm20EE14expandCapacityEm _cti_has_property -_cti_op_resolve_global -_cti_op_get_by_val -_cti_op_put_by_val -__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE -__ZN3JSC8JSParser20parseSwitchStatementINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3JSC8JSParser18parseSwitchClausesINS_10ASTBuilderEEENT_10ClauseListERS3_ -__ZN3JSC10SwitchNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC13CaseBlockNode20emitBytecodeForBlockERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_ -__ZN3JSC13CaseBlockNode18tryOptimizedSwitchERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERiS7_ -__ZN3JSCL17processClauseListEPNS_14ClauseListNodeERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERNS_10SwitchKindERbRiSB_ -__ZNK3JSC14ExpressionNode8isNumberEv -__ZNK3JSC10StringNode8isStringEv -__ZN3JSC17BytecodeGenerator11beginSwitchEPNS_10RegisterIDENS_10SwitchInfo10SwitchTypeE -__ZN3WTF6VectorIN3JSC10SwitchInfoELm0EE14expandCapacityEm -__ZN3JSC17BytecodeGenerator9endSwitchEjPN3WTF6RefPtrINS_5LabelEEEPPNS_14ExpressionNodeEPS3_ii -__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14expandCapacityEm -__ZNK3JSC13StatementNode12isReturnNodeEv -__ZN3JSC15StringJumpTableC1ERKS0_ -__ZN3JSC3JIT21emit_op_switch_stringEPNS_11InstructionE -__ZN3WTF6VectorIN3JSC12SwitchRecordELm0EE14expandCapacityEm -_cti_op_switch_string -__ZN3JSC9JITThunks15tryCacheGetByIDEPNS_9ExecStateEPNS_9CodeBlockENS_16ReturnAddressPtrENS_7JSValueERKNS_10IdentifierERKNS_12PropertySlotEPNS_17StructureStubInfoE -_cti_op_get_by_id_self_fail -__ZN3JSC3JIT29privateCompileGetByIdSelfListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureERKNS_10IdentifierERKNS_12PropertySlotEm -_cti_op_get_by_id_custom_stub -__ZN3JSC8JSParser16parseIfStatementINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3JSC5Lexer19getUnicodeCharacterEv -__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm0EE14expandCapacityEm -__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14expandCapacityEmPKS3_ -__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE15reserveCapacityEm __ZN3JSC9Structure26flattenDictionaryStructureERNS_12JSGlobalDataEPNS_8JSObjectE -__ZN3JSC6IfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator15emitJumpIfFalseEPNS_10RegisterIDEPNS_5LabelE -__ZNK3JSC11BooleanNode6isPureERNS_17BytecodeGeneratorE -__ZN3JSC11BooleanNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEb -__ZN3JSC10NumberNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEd -__ZN3WTF9HashTableIdSt4pairIdN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsIdEENSA_IS3_EEEESB_E6expandEv -__ZN3JSC11NewExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator13emitConstructEPNS_10RegisterIDES2_RNS_13CallArgumentsEjjj -__ZN3JSC10IfElseNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC12BinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZNK3JSC10NumberNode6isPureERNS_17BytecodeGeneratorE -__ZN3JSC17BytecodeGenerator12emitBinaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_NS_12OperandTypesE -__ZN3JSC3JIT14emit_op_jfalseEPNS_11InstructionE -__ZN3JSC3JIT17emit_op_constructEPNS_11InstructionE -__ZN3JSC3JIT14emit_op_jnlessEPNS_11InstructionE -__ZN3JSC3JIT18emitSlow_op_jfalseEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT21emitSlow_op_constructEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT18emitSlow_op_jnlessEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC12X86Assembler7movq_rrENS_12X86Registers10RegisterIDENS1_13XMMRegisterIDE -__ZN3JSC12X86Assembler11cvtsi2sd_rrENS_12X86Registers10RegisterIDENS1_13XMMRegisterIDE -__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_12X86Registers10RegisterIDE -__ZN3JSC23MacroAssemblerX86Common12branchDoubleENS0_15DoubleConditionENS_12X86Registers13XMMRegisterIDES3_ -__ZN3JSC12RegExpObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC15RegExpPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSCL19regExpProtoFuncTestEPNS_9ExecStateE -__ZN3JSC12RegExpObject4testEPNS_9ExecStateE -__ZN3JSC12RegExpObject5matchEPNS_9ExecStateE -__ZN3JSC6RegExp5matchERKNS_7UStringEiPN3WTF6VectorIiLm32EEE -__ZN3JSC4Yarr7executeERNS0_13YarrCodeBlockEPKtjjPi -__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE17staticValueGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE _JSValueIsObjectOfClass -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_P19StaticFunctionEntryENS_18PairFirstExtractorIS7_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSC_IS6_EEEESD_E6expandEv __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE _JSValueCreateJSONString __ZN3JSC13JSONStringifyEPNS_9ExecStateENS_7JSValueEj __ZN3JSC11StringifierC2EPNS_9ExecStateERKNS_5LocalINS_7UnknownEEES7_ __ZN3JSC11Stringifier9stringifyENS_6HandleINS_7UnknownEEE __ZN3JSC11Stringifier22appendStringifiedValueERNS_14UStringBuilderENS_7JSValueEPNS_8JSObjectERKNS_27PropertyNameForFunctionCallE -__ZN3WTF13StringBuilder6appendEPKcj __ZNK3JSC6JSCell9getStringEPNS_9ExecStateE -_cti_vm_lazyLinkConstruct -__ZN3JSC18FunctionExecutable27compileForConstructInternalEPNS_9ExecStateEPNS_14ScopeChainNodeE -__ZN3JSC3JIT18emit_op_get_calleeEPNS_11InstructionE -__ZN3JSC3JIT19emit_op_create_thisEPNS_11InstructionE -_cti_op_create_this -__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE20staticFunctionGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE -__ZN3JSC18JSCallbackFunctionC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPFPK13OpaqueJSValuePK15OpaqueJSContextPS5_SB_mPKS7_PS7_ERKNS_10IdentifierE -_cti_op_call_NotJSFunction -__ZN3JSC18JSCallbackFunction11getCallDataERNS_8CallDataE -__ZN3JSC18JSCallbackFunction4callEPNS_9ExecStateE -_JSValueToBoolean _JSValueProtect -_JSValueMakeUndefined -_cti_op_jless -__ZN3JSC7UString6numberEd -__ZN3WTF14numberToStringEdPt -__ZN3WTF4dtoaILb1ELb0ELb0ELb1EEEvPcdiRbRiRj -__ZNK3WTF13DecimalNumber15toStringDecimalEPtj -__ZN3WTF6String6appendEPKtj -__ZN3WTF10StringImpl11reverseFindEPS0_j -__ZN3WTF17equalIgnoringCaseEPNS_10StringImplES1_ -__ZN3WTF6String8truncateEj -__ZN3JSC14JSGlobalObject15copyGlobalsFromERNS_12RegisterFileE -__ZN3JSC8JSParser24parseFunctionDeclarationINS_13SyntaxCheckerEEENT_9StatementERS3_ -__ZN3JSC8JSParser17parseFunctionInfoILNS0_20FunctionRequirementsE1ELb1ENS_13SyntaxCheckerEEEbRT1_RPKNS_10IdentifierERNS4_19FormalParameterListERNS4_12FunctionBodyERiSE_SE_ -__ZN3JSC17BytecodeGenerator21emitResolveBaseForPutEPNS_10RegisterIDERKNS_10IdentifierE -__ZN3JSC17BytecodeGenerator15emitResolveBaseEPNS_10RegisterIDERKNS_10IdentifierE -__ZN3JSC17StringConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3WTF10StringImpl19characterStartingAtEj __ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE __ZN3JSCL27objectProtoFuncDefineGetterEPNS_9ExecStateE -__ZN3JSC10JSFunction11getCallDataERNS_8CallDataE __ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_j __ZN3JSC7JSArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE __ZN3JSC10JSFunction3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE __ZN3JSC8JSParser21parseConstDeclarationINS_13SyntaxCheckerEEENT_9StatementERS3_ __ZN3JSC8JSParser17parseFunctionInfoILNS0_20FunctionRequirementsE1ELb0ENS_10ASTBuilderEEEbRT1_RPKNS_10IdentifierERNS4_19FormalParameterListERNS4_12FunctionBodyERiSE_SE_ -__ZN3JSC8JSParser5Scope19restoreFunctionInfoEPKNS_23SourceProviderCacheItemE __ZN3WTF7HashMapINS_6RefPtrINS_10StringImplEEEjN3JSC17IdentifierRepHashENS_10HashTraitsIS3_EENS6_IjEEE3addEPS2_RKj __ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_jENS_18PairFirstExtractorIS5_EEN3JSC17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi __ZN3JSC17BytecodeGenerator13emitPutGetterEPNS_10RegisterIDERKNS_10IdentifierES2_ __ZN3JSC17BytecodeGenerator13emitPutSetterEPNS_10RegisterIDERKNS_10IdentifierES2_ -__ZN3JSC8NullNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC3JIT18emit_op_put_getterEPNS_11InstructionE __ZN3JSC3JIT18emit_op_put_setterEPNS_11InstructionE _cti_op_put_getter _cti_op_put_setter __ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_j __ZNK3JSC12GetterSetter14isGetterSetterEv -__ZNK3JSC18EmptyStatementNode16isEmptyStatementEv -__ZN3JSC10ASTBuilder11makeAddNodeEPNS_14ExpressionNodeES2_b -__ZN3JSC9ScopeNode8capturesERKNS_10IdentifierE -__ZN3JSC17BytecodeGenerator6addVarERKNS_10IdentifierEbRPNS_10RegisterIDE -__ZNK3JSC13LogicalOpNode26hasConditionContextCodegenEv -__ZN3JSC13LogicalOpNode30emitBytecodeInConditionContextERNS_17BytecodeGeneratorEPNS_5LabelES4_b -__ZNK3JSC14LogicalNotNode26hasConditionContextCodegenEv -__ZN3JSC11UnaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator11emitUnaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_ -__ZNK3JSC10StringNode6isPureERNS_17BytecodeGeneratorE -__ZNK3JSC14ExpressionNode5isAddEv -__ZNK3JSC14JSGlobalObject14isDynamicScopeERb -__ZNK3JSC7AddNode5isAddEv -__ZN3JSC12BinaryOpNode10emitStrcatERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_PNS_21ReadModifyResolveNodeE -__ZNK3JSC14ExpressionNode8isStringEv -__ZN3JSC17BytecodeGenerator15emitToPrimitiveEPNS_10RegisterIDES2_ -__ZN3JSC17BytecodeGenerator10emitStrcatEPNS_10RegisterIDES2_i -__ZN3JSC3JIT11emit_op_addEPNS_11InstructionE -__ZN3JSC3JIT20emit_op_to_primitiveEPNS_11InstructionE -__ZN3JSC3JIT14emit_op_strcatEPNS_11InstructionE -__ZN3JSC3JIT24emitSlow_op_to_primitiveEPNS_11InstructionERPNS_13SlowCaseEntryE -_JSValueMakeString -_cti_op_jtrue -__ZNK3JSC8JSString9toBooleanEPNS_9ExecStateE -_cti_op_strcat -__ZNK3JSC8JSString11resolveRopeEPNS_9ExecStateE -__ZNK3JSC8JSString19resolveRopeSlowCaseEPNS_9ExecStateEPt -__ZN3JSC8RopeImpl20destructNonRecursiveEv -__ZN3JSC8RopeImpl23derefFibersNonRecursiveERN3WTF6VectorIPS0_Lm32EEE -_cti_op_construct_NotJSConstruct __ZN3JSC17ObjectConstructor16getConstructDataERNS_13ConstructDataE __ZN3JSCL30constructWithObjectConstructorEPNS_9ExecStateE -__ZN3WTF21charactersToIntStrictEPKtmPbi -__ZN3JSC41constructFunctionSkippingEvalEnabledCheckEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi -__ZNK3JSC21UStringSourceProvider6lengthEv -__ZN3JSC18FunctionExecutable14fromGlobalCodeERKNS_10IdentifierEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPPNS_8JSObjectE -__ZNK3JSC21UStringSourceProvider4dataEv -__ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE -__ZN3JSC11Interpreter11executeCallEPNS_9ExecStateEPNS_8JSObjectENS_8CallTypeERKNS_8CallDataENS_7JSValueERKNS_7ArgListE -__ZN3JSC10ASTBuilder15makePostfixNodeEPNS_14ExpressionNodeENS_8OperatorEiii -__ZN3JSC7ForNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC18PostfixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator10emitPreIncEPNS_10RegisterIDE -__ZN3JSC9EqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZNK3JSC14ExpressionNode6isNullEv -__ZN3JSC3JIT15emit_op_pre_incEPNS_11InstructionE -__ZN3JSC3JIT13emit_op_jlessEPNS_11InstructionE -__ZN3JSC3JIT10emit_op_eqEPNS_11InstructionE -__ZN3JSC3JIT19emitSlow_op_pre_incEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT17emitSlow_op_jlessEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT14emitSlow_op_eqEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3WTF11emptyStringEv -__ZN3JSC13LogicalOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -_cti_op_stricteq -_cti_op_eq -__ZN3JSC10ASTBuilder14makePrefixNodeEPNS_14ExpressionNodeENS_8OperatorEiii -__ZN3JSC17PrefixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC21ThrowableBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE -_cti_op_in -__ZN3JSC9JITThunks15tryCachePutByIDEPNS_9ExecStateEPNS_9CodeBlockENS_16ReturnAddressPtrENS_7JSValueERKNS_15PutPropertySlotEPNS_17StructureStubInfoEb -_cti_op_get_by_id_generic -_cti_op_put_by_id_generic -__ZN3JSC3JIT16patchGetByIdSelfEPNS_9CodeBlockEPNS_17StructureStubInfoEPNS_9StructureEmNS_16ReturnAddressPtrE __ZNK3JSC6JSCell14isGetterSetterEv _JSObjectIsFunction _JSObjectCallAsFunction -__ZN3JSC3JIT20emit_op_convert_thisEPNS_11InstructionE -__ZN3JSC23MacroAssemblerX86Common11branchTest8ENS0_15ResultConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_12TrustedImm32E -__ZN3JSC3JIT24emitSlow_op_convert_thisEPNS_11InstructionERPNS_13SlowCaseEntryE __ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_16WriteBarrierBaseINS_7UnknownEEE __ZNK3JSC12PropertySlot14functionGetterEPNS_9ExecStateE -__ZN3JSC17ReadModifyDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC15ConditionalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC3JIT20compileBinaryArithOpENS_8OpcodeIDEjjjNS_12OperandTypesE -__ZN3JSC3JIT15emitSlow_op_addEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT28compileBinaryArithOpSlowCaseENS_8OpcodeIDERPNS_13SlowCaseEntryEjjjNS_12OperandTypesEbb -__ZNK3JSC10NumberNode8isNumberEv -__ZN3JSC3JIT17emit_op_nstricteqEPNS_11InstructionE -__ZN3JSC3JIT21emitSlow_op_nstricteqEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC15StringPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSCL22stringProtoFuncIndexOfEPNS_9ExecStateE -_cti_op_add -__ZN3JSC10ASTBuilder12makeMultNodeEPNS_14ExpressionNodeES2_b -__ZN3JSC14ExpressionNode14stripUnaryPlusEv -__ZN3JSC17BytecodeGenerator20emitInitLazyRegisterEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator29uncheckedRegisterForArgumentsEv __ZN3JSC17BytecodeGenerator20emitGetArgumentByValEPNS_10RegisterIDES2_S2_ -__ZN3JSC17BytecodeGenerator22emitGetArgumentsLengthEPNS_10RegisterIDES2_ -__ZN3JSC3JIT21emit_op_init_lazy_regEPNS_11InstructionE -__ZN3JSC3JIT11emit_op_mulEPNS_11InstructionE __ZN3JSC3JIT27emit_op_get_argument_by_valEPNS_11InstructionE -__ZN3JSC3JIT28emit_op_get_arguments_lengthEPNS_11InstructionE -__ZN3JSC3JIT15emitSlow_op_mulEPNS_11InstructionERPNS_13SlowCaseEntryE __ZN3JSC3JIT31emitSlow_op_get_argument_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT32emitSlow_op_get_arguments_lengthEPNS_11InstructionERPNS_13SlowCaseEntryE -_cti_op_call_arityCheck -_cti_op_convert_this __ZNK3JSC8JSString12toThisObjectEPNS_9ExecStateE -__ZN3JSC12StringObjectC1ERNS_12JSGlobalDataEPNS_9StructureEPNS_8JSStringE -__ZN3JSCL20stringProtoFuncSplitEPNS_9ExecStateE -__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE -__ZNK3JSC8JSObject11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE -__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE -__ZN3JSCL23stringProtoFuncToStringEPNS_9ExecStateE -__ZN3JSC11jsSubstringEPNS_12JSGlobalDataERKNS_7UStringEjj -__ZN3JSC7JSArray3putEPNS_9ExecStateEjNS_7JSValueE -__ZN3JSC7JSArray11putSlowCaseEPNS_9ExecStateEjNS_7JSValueE -__ZN3JSC14ArrayPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE __ZN3JSCL20arrayProtoFuncSpliceEPNS_9ExecStateE -__ZNK3JSC8JSObject3getEPNS_9ExecStateERKNS_10IdentifierE -__ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE -__ZN3JSC7JSArrayC1ERNS_12JSGlobalDataEPNS_9StructureEjNS_17ArrayCreationModeE __ZN3JSC7JSArray9setLengthEj __ZN3JSCL11getPropertyEPNS_9ExecStateEPNS_8JSObjectEj -__ZN3JSCL18arrayProtoFuncJoinEPNS_9ExecStateE -__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi -__ZN3JSC15JSStringBuilder5buildEPNS_9ExecStateE -__ZN3JSC3JIT20patchMethodCallProtoERNS_12JSGlobalDataEPNS_9CodeBlockERNS_18MethodCallLinkInfoEPNS_10JSFunctionEPNS_9StructureEPNS_8JSObjectENS_16ReturnAddressPtrE -__ZN3JSC27ctiPatchCallByReturnAddressEPNS_9CodeBlockENS_16ReturnAddressPtrENS_21MacroAssemblerCodePtrE -__ZN3JSC23CallFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator25emitJumpIfNotFunctionCallEPNS_10RegisterIDEPNS_5LabelE -__ZN3JSC3JIT16emit_op_jneq_ptrEPNS_11InstructionE -__ZN3JSC3JIT24emit_op_create_argumentsEPNS_11InstructionE -__ZN3JSC3JIT25emit_op_create_activationEPNS_11InstructionE -__ZN3JSC3JIT27emit_op_tear_off_activationEPNS_11InstructionE _cti_op_create_arguments __ZN3JSCL19arrayProtoFuncSliceEPNS_9ExecStateE __ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -_cti_op_push_activation -__ZN3JSC12JSActivationC1EPNS_9ExecStateEPNS_18FunctionExecutableE -_cti_op_tear_off_activation -__ZN3JSCL18arrayProtoFuncPushEPNS_9ExecStateE -__ZN3JSC5Lexer9setOffsetEi __ZN3WTF7HashMapIjPN3JSC16FunctionBodyNodeENS_7IntHashIjEENS_29UnsignedWithZeroKeyHashTraitsIjEENS_10HashTraitsIS3_EEE3setERKjRKS3_ -__ZN3WTF9HashTableIjSt4pairIjPN3JSC16FunctionBodyNodeEENS_18PairFirstExtractorIS5_EENS_7IntHashIjEENS_14PairHashTraitsINS_29UnsignedWithZeroKeyHashTraitsIjEENS_10HashTraitsIS4_EEEESC_E6rehashEi -__ZN3JSC17BytecodeGenerator19emitLazyNewFunctionEPNS_10RegisterIDEPNS_16FunctionBodyNodeE -__ZN3JSC17BytecodeGenerator23emitNewFunctionInternalEPNS_10RegisterIDEjb -__ZN3JSC3JIT16emit_op_new_funcEPNS_11InstructionE -__ZN3JSC8JSParser19parseWhileStatementINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3JSC9WhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -_JSValueMakeNumber +__ZN3WTF9HashTableIjSt4pairIjPN3JSC16FunctionBodyNodeEENS_18PairFirstExtractorIS5_EENS_7IntHashIjEENS_14PairHashTraitsINS_29UnsignedWithZeroKeyHashTraitsIjEENS_10HashTraitsIS4_EEEESC_E6rehashEi +__ZN3JSC17BytecodeGenerator19emitLazyNewFunctionEPNS_10RegisterIDEPNS_16FunctionBodyNodeE _JSObjectMakeArray -_JSValueMakeBoolean __ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE _JSValueUnprotect __ZN3WTF9HashTableIPN3JSC20MarkedArgumentBufferES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6expandEv -_cti_op_new_func -__ZN3JSC3JIT26privateCompileGetByIdProtoEPNS_17StructureStubInfoEPNS_9StructureES4_RKNS_10IdentifierERKNS_12PropertySlotEmNS_16ReturnAddressPtrEPNS_9ExecStateE -__ZN3JSC3JIT22compileGetDirectOffsetEPNS_8JSObjectENS_12X86Registers10RegisterIDEm -__ZN3JSC10ASTBuilder11makeSubNodeEPNS_14ExpressionNodeES2_b __ZN3JSC8JSParser22parseContinueStatementINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3JSC8JSParser19parseBreakStatementINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3JSC17BytecodeGenerator15emitNewFunctionEPNS_10RegisterIDEPNS_16FunctionBodyNodeE -__ZN3JSC15TypeOfValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSCeqERKNS_7UStringEPKc __ZN3WTF6VectorIPN3JSC14ExpressionNodeELm8EE14expandCapacityEm __ZN3WTF6VectorINS_6RefPtrIN3JSC5LabelEEELm8EE14expandCapacityEm -__ZN3JSC19ReverseBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC12ContinueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17BytecodeGenerator14continueTargetERKNS_10IdentifierE -__ZN3JSC17BytecodeGenerator14emitJumpScopesEPNS_5LabelEi -__ZN3JSC9BreakNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator11breakTargetERKNS_10IdentifierE -__ZN3WTF6VectorISt4pairIiiELm8EE14expandCapacityEm -__ZN3JSC14InstanceOfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator20emitCheckHasInstanceEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator14emitInstanceOfEPNS_10RegisterIDES2_S2_S2_ -__ZN3JSC17BytecodeGenerator19emitResolveWithBaseEPNS_10RegisterIDES2_RKNS_10IdentifierE __ZN3JSC23FunctionCallBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC3JIT11emit_op_subEPNS_11InstructionE -__ZN3JSC3JIT16emit_op_jnlesseqEPNS_11InstructionE -__ZN3JSC3JIT15emit_op_jlesseqEPNS_11InstructionEb -__ZN3JSC3JIT11emit_op_notEPNS_11InstructionE -__ZN3JSC3JIT26emit_op_check_has_instanceEPNS_11InstructionE -__ZN3JSC3JIT18emit_op_instanceofEPNS_11InstructionE -__ZN3JSC3JIT15emitSlow_op_subEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT20emitSlow_op_jnlesseqEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT19emitSlow_op_jlesseqEPNS_11InstructionERPNS_13SlowCaseEntryEb -__ZN3JSC3JIT15emitSlow_op_notEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT30emitSlow_op_check_has_instanceEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT22emitSlow_op_instanceofEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC7UString6numberEi _cti_op_is_function __ZN3JSC16jsIsFunctionTypeENS_7JSValueE -__ZN3JSC3JIT33privateCompilePatchGetArrayLengthENS_16ReturnAddressPtrE -__ZN3JSC14StructureChainC1ERNS_12JSGlobalDataEPNS_9StructureES4_ -__ZN3JSC14StructureChainC2ERNS_12JSGlobalDataEPNS_9StructureES4_ -__ZN3JSC3JIT31privateCompilePutByIdTransitionEPNS_17StructureStubInfoEPNS_9StructureES4_mPNS_14StructureChainENS_16ReturnAddressPtrEb -__ZN3JSC3JIT13testPrototypeENS_7JSValueERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListE -__ZN3JSC3JIT26privateCompileGetByIdChainEPNS_17StructureStubInfoEPNS_9StructureEPNS_14StructureChainEmRKNS_10IdentifierERKNS_12PropertySlotEmNS_16ReturnAddressPtrEPNS_9ExecStateE -__ZN3JSC17BytecodeGenerator10emitPreDecEPNS_10RegisterIDE -__ZN3JSC3JIT15emit_op_pre_decEPNS_11InstructionE -__ZN3JSC23MacroAssemblerX86Common4moveENS_12X86Registers10RegisterIDES2_ -__ZN3JSC3JIT19emitSlow_op_pre_decEPNS_11InstructionERPNS_13SlowCaseEntryE -_cti_op_get_by_id_proto_list -__ZN3JSC3JIT30privateCompileGetByIdChainListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureEPNS_14StructureChainEmRKNS_10IdentifierERKNS_12PropertySlotEmPNS_9ExecStateE -__ZN3WTF13StringBuilder15reserveCapacityEj -__ZN3WTF4dtoaEPcdRbRiRj -__ZNK3WTF13DecimalNumber28bufferLengthForStringDecimalEv -__ZN3JSC18globalFuncParseIntEPNS_9ExecStateE -__ZN3JSC7toInt32Ed -__ZN3JSCL8parseIntERKNS_7UStringEi -_cti_op_nstricteq __ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE -__ZN3JSC10ASTBuilder14makeDeleteNodeEPNS_14ExpressionNodeEiii -__ZN3JSC13DeleteDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator14emitDeleteByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE -__ZN3JSC3JIT17emit_op_del_by_idEPNS_11InstructionE -_cti_op_del_by_id -__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE _cti_op_not -__ZN3WTF13tryFastCallocEmm -__ZN3WTF9ByteArray6createEm -__ZN3JSC3JIT22emit_op_get_scoped_varEPNS_11InstructionE -__ZN3JSCL22stringProtoFuncReplaceEPNS_9ExecStateE -__ZNK3JSC7JSValue14toThisJSStringEPNS_9ExecStateE -__ZN3JSC9ExecState8argumentEi -__ZN3JSC6JSCell11getCallDataERNS_8CallDataE -__ZN3WTF6RefPtrINS_10StringImplEEaSERKS2_ __ZNK3JSC7UString20substringSharingImplEjj __ZN3JSC4Heap8allocateEm -__ZN3JSC24ApplyFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZNK3JSC14ExpressionNode13isSimpleArrayEv -__ZN3JSC17BytecodeGenerator26emitJumpIfNotFunctionApplyEPNS_10RegisterIDEPNS_5LabelE -__ZNK3JSC12JSActivation14isDynamicScopeERb -__ZN3JSC17BytecodeGenerator15emitLoadVarargsEPNS_10RegisterIDES2_S2_ -__ZN3JSC17BytecodeGenerator15emitCallVarargsEPNS_10RegisterIDES2_S2_S2_jjj -__ZN3JSC3JIT20emit_op_load_varargsEPNS_11InstructionE -__ZN3JSC3JIT20emit_op_call_varargsEPNS_11InstructionE -__ZN3JSC3JIT20compileOpCallVarargsEPNS_11InstructionE -__ZN3JSC3JIT24emitSlow_op_load_varargsEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT24emitSlow_op_call_varargsEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC3JIT28compileOpCallVarargsSlowCaseEPNS_11InstructionERPNS_13SlowCaseEntryE _cti_op_create_arguments_no_params __ZN3JSCL20arrayProtoFuncConcatEPNS_9ExecStateE -_cti_op_load_varargs __ZN3JSC7JSArray15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj -_cti_op_call_jitCompile __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE14callbackGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE __ZN3JSC11Stringifier6Holder18appendNextPropertyERS0_RNS_14UStringBuilderE __ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE __ZN3JSC11Stringifier18appendQuotedStringERNS_14UStringBuilderERKNS_7UStringE -__ZN3WTF10StringImpl4costEv __ZN3JSC7UStringC1EPKcj _JSObjectGetPrivateProperty _JSObjectSetPrivateProperty __ZN3JSC20JSCallbackObjectData18setPrivatePropertyERNS_12JSGlobalDataEPNS_6JSCellERKNS_10IdentifierENS_7JSValueE __ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC12WriteBarrierINS5_7UnknownEEEENS_18PairFirstExtractorIS9_EENS5_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSE_IS8_EEEESF_E6rehashEi -__ZN3JSC17BytecodeGenerator16emitPutScopedVarEmiPNS_10RegisterIDENS_7JSValueE -__ZN3JSC3JIT22emit_op_put_global_varEPNS_11InstructionE -__ZN3JSC13LiteralParser5Lexer9lexNumberERNS1_18LiteralParserTokenE -__ZN3JSC8JSParser17parseTryStatementINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3JSC7TryNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator9emitCatchEPNS_10RegisterIDEPNS_5LabelES4_ -__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14expandCapacityEm -__ZN3JSC17BytecodeGenerator16emitPushNewScopeEPNS_10RegisterIDERKNS_10IdentifierES2_ -__ZN3WTF6VectorIN3JSC18ControlFlowContextELm0EE14expandCapacityEm -__ZN3JSC17BytecodeGenerator12emitPopScopeEv -__ZN3JSC3JIT13emit_op_catchEPNS_11InstructionE -__ZN3JSC20MacroAssemblerX86_647loadPtrENS_22AbstractMacroAssemblerINS_12X86AssemblerEE15ImplicitAddressENS_12X86Registers10RegisterIDE -__ZN3JSC3JIT22emit_op_push_new_scopeEPNS_11InstructionE -__ZN3JSC3JIT18emit_op_jmp_scopesEPNS_11InstructionE -__ZN3JSC3JIT17emit_op_pop_scopeEPNS_11InstructionE -__ZN3WTF6VectorIN3JSC32CallReturnOffsetToBytecodeOffsetELm0EE15reserveCapacityEm _JSObjectDeletePrivateProperty -__ZN3WTF6VectorIjLm16EE6resizeEm -__ZN3WTFL7multaddERNS_6BigIntEii -__ZN3WTFL4multERNS_6BigIntERKS0_ -__ZN3WTF6VectorIjLm16EEaSERKS1_ -__ZN3JSC4Yarr22YarrPatternConstructor23setupDisjunctionOffsetsEPNS0_18PatternDisjunctionEjj -__ZN3JSC23MacroAssemblerX86Common4jumpEv -__ZN3WTF6VectorIN3JSC4Yarr11PatternTermELm0EE14expandCapacityEmPKS3_ __ZN3JSC4Yarr18PatternDisjunction17addNewAlternativeEv __ZN3JSC4Yarr22YarrPatternConstructor15copyDisjunctionEPNS0_18PatternDisjunctionEb __ZN3WTF6VectorIPN3JSC4Yarr18PatternDisjunctionELm4EE14expandCapacityEm __ZN3WTF6VectorIN3JSC4Yarr13YarrGenerator17BacktrackingState19ReturnAddressRecordELm4EE14expandCapacityEm __ZN3JSCL19regExpProtoFuncExecEPNS_9ExecStateE __ZN3JSC12RegExpObject4execEPNS_9ExecStateE -__ZNK3JSC17RegExpConstructor14arrayOfMatchesEPNS_9ExecStateE -__ZN3JSC18RegExpMatchesArrayC2EPNS_9ExecStateEPNS_24RegExpConstructorPrivateE -__ZN3JSC7JSArrayC2ERNS_12JSGlobalDataEPNS_9StructureEjNS_17ArrayCreationModeE -__ZN3JSC7JSArray15setSubclassDataEPv __ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE -__ZNK3JSC7JSArray12subclassDataEv __ZN3JSC18RegExpMatchesArray17fillArrayInstanceEPNS_9ExecStateE -__ZN3JSCL20stringProtoFuncMatchEPNS_9ExecStateE -__ZN3JSC4Yarr22YarrPatternConstructor25atomBuiltInCharacterClassENS0_23BuiltInCharacterClassIDEb -__ZN3JSC4Yarr12spacesCreateEv __ZN3JSC28globalFuncDecodeURIComponentEPNS_9ExecStateE __ZN3JSCL6decodeEPNS_9ExecStateEPKcb __ZN3WTF6VectorItLm64EE9tryAppendItEEbPKT_m __ZN3WTF7Unicode18UTF8SequenceLengthEc __ZN3WTF7Unicode18decodeUTF8SequenceEPKc __ZN3WTF6VectorItLm64EE18tryReserveCapacityEm -__ZN3JSCL24stringProtoFuncSubstringEPNS_9ExecStateE __ZN3JSC16globalFuncEscapeEPNS_9ExecStateE -__ZN3JSC16ArrayConstructor16getConstructDataERNS_13ConstructDataE -__ZN3JSCL29constructWithArrayConstructorEPNS_9ExecStateE -__ZN3JSCL27constructArrayWithSizeQuirkEPNS_9ExecStateERKNS_7ArgListE __ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17BytecodeGenerator11emitPostDecEPNS_10RegisterIDES2_ __ZN3JSC3JIT16emit_op_post_decEPNS_11InstructionE __ZN3JSC3JIT20emitSlow_op_post_decEPNS_11InstructionERPNS_13SlowCaseEntryE __ZN3JSC3JIT22emit_op_loop_if_lesseqEPNS_11InstructionE __ZN3JSC3JIT26emitSlow_op_loop_if_lesseqEPNS_11InstructionERPNS_13SlowCaseEntryE -_cti_op_pre_dec __ZN3JSC7JSArray19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE -__ZN3JSC10Identifier4fromEPNS_9ExecStateEj -__ZN3JSC7UString6numberEj __ZN3JSC17PropertyNameArray3addEPN3WTF10StringImplE __ZN3JSC9ExecState19arrayPrototypeTableEPS0_ -__ZN3JSC3JIT22emit_op_put_scoped_varEPNS_11InstructionE -__ZN3JSC12JSGlobalData15getHostFunctionEPFPvPNS_9ExecStateEEPFNS_21MacroAssemblerCodePtrEPS0_PNS_14ExecutablePoolEE -__ZN3JSC9JITThunks16hostFunctionStubEPNS_12JSGlobalDataEPFPvPNS_9ExecStateEEPFNS_21MacroAssemblerCodePtrES2_PNS_14ExecutablePoolEE __ZN3JSC20charAtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE __ZN3JSCL14stringCharLoadERNS_19SpecializedThunkJITE -__ZN3JSCL12charToStringERNS_19SpecializedThunkJITEPNS_12JSGlobalDataENS_12X86Registers10RegisterIDES5_S5_ -__ZN3JSC19SpecializedThunkJIT8finalizeENS_21MacroAssemblerCodePtrE -__ZN3JSC10JSFunctionC1EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEiRKNS_10IdentifierEPNS_16NativeExecutableE -__ZN3JSC10JSFunctionC2EPNS_9ExecStateEPNS_14JSGlobalObjectEPNS_9StructureEiRKNS_10IdentifierEPNS_16NativeExecutableE __ZN3JSCL21stringProtoFuncCharAtEPNS_9ExecStateE +__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm16EE14expandCapacityEm +__ZN3WTF6VectorINS_6RefPtrIN3JSC10RegisterIDEEELm16EE14expandCapacityEm __ZN3WTF14FastMallocZone9forceLockEP14_malloc_zone_t __ZN3WTF14FastMallocZone11forceUnlockEP14_malloc_zone_t +__ZN3JSC3JIT30emit_op_resolve_global_dynamicEPNS_11InstructionE +__ZN3JSC3JIT34emitSlow_op_resolve_global_dynamicEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3WTF6VectorIN3JSC11StringRangeELm16EE14expandCapacityEmPKS2_ +__ZN3WTF6VectorIN3JSC11StringRangeELm16EE15reserveCapacityEm +__ZN3WTF6VectorIN3JSC7UStringELm16EE14expandCapacityEmPKS2_ +__ZN3WTF6VectorIN3JSC7UStringELm16EE15reserveCapacityEm +__ZN3JSC10ASTBuilder17makeLeftShiftNodeEPNS_14ExpressionNodeES2_b +__ZN3JSC3JIT14emit_op_lshiftEPNS_11InstructionE +__ZN3JSC3JIT18emitSlow_op_lshiftEPNS_11InstructionERPNS_13SlowCaseEntryE +_cti_op_lshift +_cti_op_bitor __ZN3WTF6VectorIPN3JSC9StructureELm8EE14expandCapacityEm -__ZN3JSCL21stringProtoFuncSearchEPNS_9ExecStateE -__ZN3JSC3JIT30privateCompileGetByIdProtoListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureES6_RKNS_10IdentifierERKNS_12PropertySlotEmPNS_9ExecStateE -__ZN3WTF6VectorItLm0EE14expandCapacityEmPKt -__ZN3JSC4Yarr13YarrGenerator24matchCharacterClassRangeENS_12X86Registers10RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListES8_PKNS0_14CharacterRangeEjPjPKtj -__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_12X86Registers10RegisterIDES3_ii -__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_19RelationalConditionENS_12X86Registers10RegisterIDES3_ -__ZN3JSC4Yarr13YarrGenerator17BacktrackingState24takeBacktracksToJumpListERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListEPNS_14MacroAssemblerE _cti_op_get_by_id_proto_list_full __ZN3WTF6VectorIN3JSC4Yarr13YarrGenerator6YarrOpELm128EE14expandCapacityEmPKS4_ __ZN3WTF6VectorIN3JSC4Yarr13YarrGenerator6YarrOpELm128EE15reserveCapacityEm -__ZN3JSCL26stringProtoFuncLastIndexOfEPNS_9ExecStateE -__ZNK3JSC7JSValue20toIntegerPreserveNaNEPNS_9ExecStateE __ZN3JSC17RegExpConstructor16getConstructDataERNS_13ConstructDataE __ZN3JSCL30constructWithRegExpConstructorEPNS_9ExecStateE __ZN3JSC15constructRegExpEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListE -__ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE -__ZN3JSC16BooleanPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC3JIT22compileGetDirectOffsetENS_12X86Registers10RegisterIDES2_PNS_9StructureEm -__ZN3JSC3JIT15emit_op_resolveEPNS_11InstructionE +__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE _JSWeakObjectMapRemove __ZN3WTF7HashMapIPvPN3JSC7JSValueENS_7PtrHashIS1_EENS_10HashTraitsIS1_EENS7_IS4_EEE4takeERKS1_ _JSObjectSetPrivate -_cti_op_put_by_id_fail +_JSValueIsEqual +__ZN3JSC7JSValue13equalSlowCaseEPNS_9ExecStateES0_S0_ __ZN3JSC4Heap16allocateSlowCaseEm -__ZN3JSC9CodeBlock14visitAggregateERNS_9MarkStackE -__ZN3JSC13EvalCodeCache14visitAggregateERNS_9MarkStackE -__ZN3JSC17StructureStubInfo14visitAggregateERNS_9MarkStackE -__ZN3JSC14StructureChain13visitChildrenERNS_9MarkStackE -__ZN3JSC12JSActivation13visitChildrenERNS_9MarkStackE -__ZN3JSC15WeakHandleOwner26isReachableFromOpaqueRootsENS_6HandleINS_7UnknownEEEPvRNS_9MarkStackE __ZN3JSC9WeakGCMapIPvNS_8JSObjectENS_33DefaultWeakGCMapFinalizerCallbackIS1_S2_EEN3WTF7PtrHashIS1_EENS5_10HashTraitsIS1_EEE8finalizeENS_6HandleINS_7UnknownEEES1_ -__ZN3JSC20JSCallbackObjectData8finalizeENS_6HandleINS_7UnknownEEEPv -__ZN3WTF7HashMapISt4pairINS_6RefPtrINS_10StringImplEEEjEPN3JSC7JSValueENS6_24StructureTransitionTable4HashENS9_10HashTraitsENS_10HashTraitsIS8_EEE4takeERKS5_ -__ZN3JSC12RegExpObjectD1Ev -__ZN3JSC12JSActivationD1Ev -__ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEED1Ev -__ZN3JSC20JSCallbackObjectDataD0Ev -_JSClassRelease -__ZN3JSC15WeakHandleOwnerD2Ev -__ZN3JSC14ExecutablePool13systemReleaseERNS0_10AllocationE -__ZN3WTF11OSAllocator8decommitEPvm -__ZN3JSC18RegExpMatchesArrayD1Ev __ZN3JSC22JSPropertyNameIteratorD1Ev -__ZN3JSC14StructureChainD1Ev -__ZN3JSC18JSCallbackFunctionD1Ev -__ZN3JSC9WeakGCMapISt4pairIN3WTF6RefPtrINS2_10StringImplEEEjENS_9StructureENS_24StructureTransitionTable26WeakGCMapFinalizerCallbackENS8_4HashENS8_10HashTraitsEE8finalizeENS_6HandleINS_7UnknownEEEPv -__ZN3JSC9WeakGCMapISt4pairIN3WTF6RefPtrINS2_10StringImplEEEjENS_9StructureENS_24StructureTransitionTable26WeakGCMapFinalizerCallbackENS8_4HashENS8_10HashTraitsEED0Ev -__ZN3JSC9WeakGCMapISt4pairIN3WTF6RefPtrINS2_10StringImplEEEjENS_9StructureENS_24StructureTransitionTable26WeakGCMapFinalizerCallbackENS8_4HashENS8_10HashTraitsEED1Ev -__ZN3JSC18FunctionExecutableD1Ev +_JSStringGetMaximumUTF8CStringSize +_JSStringGetUTF8CString +__ZN3JSC10ASTBuilder14makeBitAndNodeEPNS_14ExpressionNodeES2_b +__ZN3JSC10ASTBuilder18makeRightShiftNodeEPNS_14ExpressionNodeES2_b +__ZN3JSC3JIT14emit_op_rshiftEPNS_11InstructionE +__ZN3JSC3JIT18emitSlow_op_rshiftEPNS_11InstructionERPNS_13SlowCaseEntryE _cti_op_put_by_id_transition_realloc -__ZN3JSC22createNotAnObjectErrorEPNS_9ExecStateENS_7JSValueE -__ZN3JSC11makeUStringIPKcNS_7UStringES2_EES3_T_T0_T1_ -__ZN3WTF13tryMakeStringIPKcN3JSC7UStringES2_EENS_10PassRefPtrINS_10StringImplEEET_T0_T1_ -__ZN3JSC15createTypeErrorEPNS_9ExecStateERKNS_7UStringE -__ZN3JSC13ErrorInstance6createEPNS_12JSGlobalDataEPNS_9StructureERKNS_7UStringE -__ZN3JSC13ErrorInstanceC2EPNS_12JSGlobalDataEPNS_9StructureERKNS_7UStringE -__ZN3JSC10throwErrorEPNS_9ExecStateEPNS_8JSObjectE -__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSCL23returnToThrowTrampolineEPNS_12JSGlobalDataENS_16ReturnAddressPtrERS2_ -_ctiVMThrowTrampoline -_cti_vm_throw -__ZN3JSC11Interpreter14throwExceptionERPNS_9ExecStateERNS_7JSValueEj -__ZNK3JSC13ErrorInstance15isErrorInstanceEv -__ZNK3JSC8JSObject13exceptionTypeEv -__ZN3JSC9CodeBlock24handlerForBytecodeOffsetEj -__ZN3JSC11Interpreter15unwindCallFrameERPNS_9ExecStateENS_7JSValueERjRPNS_9CodeBlockE -_ctiOpThrowNotCaught -__ZN3JSC14ErrorPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSCL22errorProtoFuncToStringEPNS_9ExecStateE -__ZN3WTF13tryMakeStringIN3JSC7UStringEPKcS2_EENS_10PassRefPtrINS_10StringImplEEET_T0_T1_ -__ZN3JSC13JSNotAnObjectD1Ev -__ZN3JSC13ErrorInstanceD1Ev -__ZN3WTF10StringImpl16findIgnoringCaseEPKcj +__ZNK3WTF6String5splitEtbRNS_6VectorIS0_Lm0EEE +__ZN3JSC24charCodeAtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE +_cti_op_get_by_val_string +__ZN3JSC17StringConstructor11getCallDataERNS_8CallDataE +__ZN3JSCL21callStringConstructorEPNS_9ExecStateE +__ZN3WTF6String6appendEt _cti_op_is_undefined -__ZN3JSC21ReadModifyResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17NumberConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE __ZN3JSC13jsAddSlowCaseEPNS_9ExecStateENS_7JSValueES2_ __ZNK3JSC8JSString11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE -__ZN3JSC3JIT19patchPutByIdReplaceEPNS_9CodeBlockEPNS_17StructureStubInfoEPNS_9StructureEmNS_16ReturnAddressPtrEb _cti_op_get_by_id_getter_stub -__ZN3JSC10ASTBuilder11makeDivNodeEPNS_14ExpressionNodeES2_b -__ZN3JSC3JIT11emit_op_divEPNS_11InstructionE -__ZN3JSC3JIT15emitSlow_op_divEPNS_11InstructionERPNS_13SlowCaseEntryE -_cti_op_lesseq __ZN3JSC9Structure24removePropertyTransitionERNS_12JSGlobalDataEPS0_RKNS_10IdentifierERm __ZN3JSC9Structure6removeERKNS_10IdentifierE __ZN3WTF6VectorIjLm0EE14expandCapacityEm @@ -1432,41 +1687,25 @@ __ZN3JSC9Structure31removePropertyWithoutTransitionERNS_12JSGlobalDataERKNS_10Id __ZN3JSC12GetterSetter13visitChildrenERNS_9MarkStackE __ZN3JSC9Arguments13visitChildrenERNS_9MarkStackE __ZN3JSC14JSGlobalObject17WeakMapsFinalizer8finalizeENS_6HandleINS_7UnknownEEEPv -__ZN3JSC12StringObjectD1Ev __ZN3JSC9ArgumentsD1Ev __ZN3JSC9ArgumentsD2Ev -__ZN3JSC19SourceProviderCacheD1Ev -__ZN3WTF20deleteAllPairSecondsIPN3JSC23SourceProviderCacheItemEKNS_7HashMapIiS3_NS_7IntHashIjEENS_10HashTraitsIiEENS7_IS3_EEEEEEvRT0_ -__ZN3WTF6VectorIN3JSC8LineInfoELm0EE14expandCapacityEm -__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14expandCapacityEm -__ZNK3WTF6String8toDoubleEPbS1_ -__ZN3WTF6String6appendEc -__ZN3WTF6String6numberEt -__ZNK3WTF6String8foldCaseEv -__ZN3WTF10StringImpl8foldCaseEv -__ZN3JSC15NumberPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateE -__ZN3JSC3JIT20emit_op_resolve_skipEPNS_11InstructionE -_cti_op_resolve_skip -__ZN3JSC19SourceProviderCache5clearEv -__ZN3WTF11OSAllocator18releaseDecommittedEPvm -__ZN3WTFeqERKNS_12AtomicStringEPKc +__ZNK3JSC19JSStaticScopeObject14isDynamicScopeERb +__ZN3JSC19globalFuncEncodeURIEPNS_9ExecStateE +__ZN3JSCL6encodeEPNS_9ExecStateEPKc +__ZNK3JSC7UString4utf8Eb +__ZN3JSCL17arrayProtoFuncMapEPNS_9ExecStateE _JSStringIsEqualToUTF8CString -__ZN3JSC12RegisterFile17GlobalObjectOwner8finalizeENS_6HandleINS_7UnknownEEEPv __ZN3JSC12GetterSetterD1Ev -__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE14expandCapacityEm -__ZNK3WTF6String18simplifyWhiteSpaceEv -__ZN3WTF10StringImpl18simplifyWhiteSpaceEv __ZN3JSC22JSPropertyNameIterator13visitChildrenERNS_9MarkStackE -__ZN3WTFL43initializeMainThreadToProcessMainThreadOnceEv -__ZN3WTF47initializeMainThreadToProcessMainThreadPlatformEv -__ZN3WTF6String6numberEd -__ZN3WTF10StringImpl5upperEv -__ZN3WTF6String6removeEji -__ZN3WTF6String6insertERKS0_j -__ZN3WTF6String6insertEPKtjj -__ZN3WTF10StringImpl7replaceEPS0_S1_ -__ZNK3WTF6String5splitEtbRNS_6VectorIS0_Lm0EEE +__ZNK3WTF6String19characterStartingAtEj +__ZN3JSC10ASTBuilder14makeBitXOrNodeEPNS_14ExpressionNodeES2_b +__ZN3JSC3JIT14emit_op_bitxorEPNS_11InstructionE +__ZN3JSC3JIT18emitSlow_op_bitxorEPNS_11InstructionERPNS_13SlowCaseEntryE +_cti_op_bitxor +__ZN3JSC8JSParser21parseDoWhileStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ +__ZN3JSCL16mathProtoFuncMinEPNS_9ExecStateE +__ZN3JSCL21arrayProtoFuncReverseEPNS_9ExecStateE +__ZN3JSC17ProgramExecutable13visitChildrenERNS_9MarkStackE __ZN3JSC12JSGlobalData18createContextGroupENS_15ThreadStackTypeE __ZN3JSC12JSGlobalData22clearBuiltinStructuresEv __ZN3JSC4Heap7destroyEv @@ -1502,7 +1741,6 @@ _JSReportExtraMemoryCost _JSValueIsObject _JSValueMakeNull _JSObjectSetPrototype -_JSStringCreateWithCharacters _JSValueGetType __ZN3JSC16JSCallbackObjectINS_14JSGlobalObjectEE3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE _JSGarbageCollect @@ -1513,36 +1751,19 @@ __ZN3WTF13StringBuilder6appendEc _JSEvaluateScript __ZNK3JSC14JSGlobalObject17supportsProfilingEv __ZNK3JSC14JSGlobalObject22supportsRichSourceInfoEv -__ZN3JSC8JSParser19parseThrowStatementINS_10ASTBuilderEEENT_9StatementERS3_ -__ZN3JSC9ThrowNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC3JIT13emit_op_throwEPNS_11InstructionE -_cti_op_throw -__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateEPNS_14JSGlobalObjectE __ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE -_JSValueIsEqual -__ZN3JSC7JSValue13equalSlowCaseEPNS_9ExecStateES0_S0_ -__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE -__ZN3JSC10throwErrorEPNS_9ExecStateENS_7JSValueE -__ZNK3JSC8JSString8toNumberEPNS_9ExecStateE -__ZN3JSC10jsToNumberERKNS_7UStringE _JSStringGetLength _JSStringGetCharactersPtr -_JSStringGetMaximumUTF8CStringSize -_JSStringGetUTF8CString _JSValueIsStrictEqual -__ZN3JSC21UStringSourceProviderD0Ev _JSCheckScriptSyntax __ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE __ZN3JSC17ProgramExecutable11checkSyntaxEPNS_9ExecStateE __ZN3WTF6VectorIN3JSC9LabelInfoELm0EE14expandCapacityEmPKS2_ __ZN3WTF6VectorIN3JSC9LabelInfoELm0EE15reserveCapacityEm __ZN3JSC17createSyntaxErrorEPNS_14JSGlobalObjectERKNS_7UStringE -__ZN3JSC12addErrorInfoEPNS_12JSGlobalDataEPNS_8JSObjectEiRKNS_10SourceCodeE -__ZN3JSC8JSObject17putWithAttributesEPNS_12JSGlobalDataERKNS_10IdentifierENS_7JSValueEj _JSObjectCallAsConstructor __ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE __ZN3JSC11Interpreter16executeConstructEPNS_9ExecStateEPNS_8JSObjectENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE -__ZN3JSC15ObjectPrototype18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE _JSObjectSetPropertyAtIndex _JSObjectMakeFunction __ZN3JSC17constructFunctionEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi @@ -1580,51 +1801,13 @@ __ZN3JSCL18regExpObjectSourceEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZN3WTF13tryMakeStringIPKcN3JSC7UStringEPcEENS_10PassRefPtrINS_10StringImplEEET_T0_T1_ __ZN13OpaqueJSClassD1Ev __ZN13OpaqueJSClassD2Ev -__ZN3JSC20EvalFunctionCallNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator12emitCallEvalEPNS_10RegisterIDES2_RNS_13CallArgumentsEjjj -__ZN3JSC3JIT25emit_op_resolve_with_baseEPNS_11InstructionE -__ZN3JSC3JIT17emit_op_call_evalEPNS_11InstructionE -__ZN3JSC3JIT21emitSlow_op_call_evalEPNS_11InstructionERPNS_13SlowCaseEntryE -_cti_op_resolve_with_base -__ZN3JSC12JSActivation18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -_cti_op_call_eval -__ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12RegisterFileEPNS_8RegisterEii -__ZN3JSC14EvalExecutableC1EPNS_9ExecStateERKNS_10SourceCodeEb -__ZN3JSC14EvalExecutable15compileInternalEPNS_9ExecStateEPNS_14ScopeChainNodeE -__ZN3JSC6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_14JSGlobalObjectEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPNS_18FunctionParametersENS_18JSParserStrictnessEPPNS_8JSObjectE -__ZN3JSCL19isNonASCIIIdentPartEi -__ZN3JSC8EvalNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEERNS5_7HashSetINS5_6RefPtrINS5_10StringImplEEENS_17IdentifierRepHashENS5_10HashTraitsISL_EEEERKNS_10SourceCodeEji -__ZN3JSC14ScopeChainNode10localDepthEv -__ZN3JSC17BytecodeGeneratorC1EPNS_8EvalNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE -__ZN3JSC17BytecodeGeneratorC2EPNS_8EvalNodeEPNS_14ScopeChainNodeEPN3WTF7HashMapINS5_6RefPtrINS5_10StringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS5_10HashTraitsIS9_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE -__ZN3JSC8EvalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZThn16_N3JSC8EvalNodeD0Ev -__ZN3JSC8EvalNodeD0Ev -__ZN3WTF7HashMapINS_6RefPtrINS_10StringImplEEEN3JSC12WriteBarrierINS4_14EvalExecutableEEENS_10StringHashENS_10HashTraitsIS3_EENS9_IS7_EEE3setEPS2_RKS7_ -__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC12WriteBarrierINS5_14EvalExecutableEEEENS_18PairFirstExtractorIS9_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSE_IS8_EEEESF_E6expandEv -__ZN3JSC11Interpreter7executeEPNS_14EvalExecutableEPNS_9ExecStateEPNS_8JSObjectEiPNS_14ScopeChainNodeE __ZN3JSC16JSCallbackObjectINS_14JSGlobalObjectEE20staticFunctionGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE -__ZN3JSC17ProgramExecutable13visitChildrenERNS_9MarkStackE __ZN3JSC19JSStaticScopeObject13visitChildrenERNS_9MarkStackE -__ZN3JSC14EvalExecutableD1Ev -__ZN3JSC13EvalCodeBlockD0Ev __ZN3JSC12DateInstanceD1Ev __ZN3JSC21JSCallbackConstructorD1Ev -__ZN3JSC17TypeOfResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC3JIT20emit_op_resolve_baseEPNS_11InstructionE -__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE -_cti_op_resolve __ZN3JSC16JSCallbackObjectINS_14JSGlobalObjectEE17staticValueGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE -_cti_op_resolve_base -_cti_op_typeof -__ZN3JSC20jsTypeStringForValueEPNS_9ExecStateENS_7JSValueE __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE11getCallDataERNS_8CallDataE __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE -_cti_op_push_new_scope -__ZN3JSC19JSStaticScopeObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC12JSActivation3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE -_cti_op_pop_scope -__ZN3JSCL20isNonASCIIIdentStartEi __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE4callEPNS_9ExecStateE __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE16getConstructDataERNS_13ConstructDataE __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE9constructEPNS_9ExecStateE @@ -1632,7 +1815,6 @@ _cti_op_instanceof __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE11hasInstanceEPNS_9ExecStateENS_7JSValueES5_ __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE _JSPropertyNameAccumulatorAddName -__ZN3JSC17ObjectConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE __ZN3JSCL41objectConstructorGetOwnPropertyDescriptorEPNS_9ExecStateE __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE __ZN3JSC18PropertyDescriptor15setConfigurableEb @@ -1641,85 +1823,43 @@ __ZNK3JSC18PropertyDescriptor20isAccessorDescriptorEv __ZNK3JSC18PropertyDescriptor8writableEv __ZNK3JSC18PropertyDescriptor10enumerableEv __ZNK3JSC18PropertyDescriptor12configurableEv -__ZN3JSC20createReferenceErrorEPNS_9ExecStateERKNS_7UStringE -__ZN3JSC12hasErrorInfoEPNS_9ExecStateEPNS_8JSObjectE -__ZN3JSC9CodeBlock27lineNumberForBytecodeOffsetEj -__ZN3JSC12addErrorInfoEPNS_9ExecStateEPNS_8JSObjectEiRKNS_10SourceCodeE __ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE -__ZN3JSC15constructNumberEPNS_9ExecStateEPNS_14JSGlobalObjectENS_7JSValueE __ZN3JSC3JIT19emit_op_to_jsnumberEPNS_11InstructionE __ZN3JSC3JIT23emitSlow_op_to_jsnumberEPNS_11InstructionERPNS_13SlowCaseEntryE _cti_op_to_jsnumber __ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE8toNumberEPNS_9ExecStateE -__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE __ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE9classNameEv -__ZN3JSC17StringConstructor11getCallDataERNS_8CallDataE -__ZN3JSCL21callStringConstructorEPNS_9ExecStateE __ZNK3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE8toStringEPNS_9ExecStateE -_cti_op_sub __ZN3JSC21JSCallbackConstructor16getConstructDataERNS_13ConstructDataE __ZN3JSCL19constructJSCallbackEPNS_9ExecStateE -_cti_op_to_primitive -__ZN3JSCL22objectProtoFuncValueOfEPNS_9ExecStateE -_cti_op_jmp_scopes __ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE __ZN3JSC16createRangeErrorEPNS_9ExecStateERKNS_7UStringE -__ZN3JSC9Structure27despecifyFunctionTransitionERNS_12JSGlobalDataEPS0_RKNS_10IdentifierE -__ZN3JSC13PropertyTableC2ERNS_12JSGlobalDataEPNS_6JSCellERKS0_ _cti_op_mul -__ZNK3JSC8JSObject9classNameEv __ZN3JSC12RegisterFile21releaseExcessCapacityEv __ZN3JSC16JSCallbackObjectINS_14JSGlobalObjectEED1Ev -__ZN3JSC19JSStaticScopeObjectD1Ev -__ZN3JSC12NumberObjectD1Ev _JSObjectHasProperty _JSObjectGetPrototype __ZN3JSC8JSObject15unwrappedObjectEv __ZN3JSC11createErrorEPNS_9ExecStateERKNS_7UStringE __ZN3JSC12JSGlobalData6createENS_15ThreadStackTypeE __ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_10JSFunctionEj -__ZNK3JSC7UString4utf8Eb __ZN3JSC12JSGlobalData13startSamplingEv __ZN3JSC11Interpreter13startSamplingEv __ZN3JSC15DateConstructor16getConstructDataERNS_13ConstructDataE __ZN3JSCL28constructWithDateConstructorEPNS_9ExecStateE __ZN3JSC21gregorianDateTimeToMSEPNS_9ExecStateERKNS_17GregorianDateTimeEdb __ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateE -_cti_op_negate __ZN3JSC12JSGlobalData12stopSamplingEv __ZN3JSC11Interpreter12stopSamplingEv -__ZN3JSC17BytecodeGenerator11emitPostIncEPNS_10RegisterIDES2_ -__ZN3JSC3JIT16emit_op_post_incEPNS_11InstructionE -__ZN3JSC3JIT20emitSlow_op_post_incEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3JSC10MathObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC17powThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE -__ZN3JSC12X86Assembler7cmpl_imEiiNS_12X86Registers10RegisterIDE -__ZN3JSC23MacroAssemblerX86Common26branchConvertDoubleToInt32ENS_12X86Registers13XMMRegisterIDENS1_10RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListES2_ -__ZN3JSC19SpecializedThunkJIT11returnInt32ENS_12X86Registers10RegisterIDE -__ZN3JSC19SpecializedThunkJIT12returnDoubleENS_12X86Registers13XMMRegisterIDE -__ZN3JSC19SpecializedThunkJITD1Ev __ZN3WTF9HashTableIjSt4pairIjN3JSC12WriteBarrierINS2_7UnknownEEEENS_18PairFirstExtractorIS6_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSC_IS5_EEEESD_E6rehashEi -__ZN3JSC3JIT11emit_op_neqEPNS_11InstructionE -__ZN3JSC3JIT15emitSlow_op_neqEPNS_11InstructionERPNS_13SlowCaseEntryE __ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE __ZN3JSC11Interpreter14dumpSampleDataEPNS_9ExecStateE -__ZN3JSCL22arrayProtoFuncToStringEPNS_9ExecStateE __ZN3JSC16ArrayConstructor11getCallDataERNS_8CallDataE __ZN3JSCL20callArrayConstructorEPNS_9ExecStateE -__ZN3JSC10ASTBuilder11makeModNodeEPNS_14ExpressionNodeES2_b -__ZN3JSC3JIT11emit_op_modEPNS_11InstructionE -__ZN3JSC3JIT15emitSlow_op_modEPNS_11InstructionERPNS_13SlowCaseEntryE __ZN3JSC17NumberConstructor11getCallDataERNS_8CallDataE __ZN3JSCL21callNumberConstructorEPNS_9ExecStateE -__ZN3JSCL16mathProtoFuncAbsEPNS_9ExecStateE __ZN3JSCL28numberConstructorPosInfinityEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE -__ZN3JSCL18mathProtoFuncFloorEPNS_9ExecStateE _cti_op_mod -_cti_timeout_check -__ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE -__ZN3WTF6VectorINS_6RefPtrIN3JSC10RegisterIDEEELm16EE14expandCapacityEm -__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm32EEELm32EE14expandCapacityEmPKS4_ -__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm32EEELm32EE15reserveCapacityEm __ZN3JSC3JIT13linkConstructEPNS_10JSFunctionEPNS_9CodeBlockES4_NS_21MacroAssemblerCodePtrEPNS_12CallLinkInfoEiPNS_12JSGlobalDataE __ZN3JSC14EvalExecutable13visitChildrenERNS_9MarkStackE __ZN3JSC17NumberConstructor16getConstructDataERNS_13ConstructDataE @@ -1738,63 +1878,34 @@ __ZN3JSCL25numberConstructorNaNValueEPNS_9ExecStateENS_7JSValueERKNS_10Identifie __ZN3JSCL28numberConstructorNegInfinityEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZN3JSC18BooleanConstructor11getCallDataERNS_8CallDataE __ZN3JSCL22callBooleanConstructorEPNS_9ExecStateE -__ZN3JSC8JSString17substringFromRopeEPNS_9ExecStateEjj __ZN3WTF6VectorIN3JSC8JSString12RopeIterator8WorkItemELm16EE14expandCapacityEmPKS4_ __ZN3WTF6VectorIN3JSC8JSString12RopeIterator8WorkItemELm16EE15reserveCapacityEm __ZN3JSC10JSFunction14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE -__ZN3JSCL24booleanProtoFuncToStringEPNS_9ExecStateE __ZN3JSC18globalFuncUnescapeEPNS_9ExecStateE -__ZN3WTF6VectorItLm64EE17tryExpandCapacityEm __ZNK3WTF13DecimalNumber19toStringExponentialEPtj __ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE -__ZN3JSCL21arrayProtoFuncReverseEPNS_9ExecStateE -__ZN3JSC9CommaNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC9CommaNodeD1Ev __ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateEj __ZN3JSC19FunctionConstructor16getConstructDataERNS_13ConstructDataE __ZN3JSCL32constructWithFunctionConstructorEPNS_9ExecStateE __ZN3JSC17constructFunctionEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListE -__ZN3JSC17StringConstructor16getConstructDataERNS_13ConstructDataE -__ZN3JSCL30constructWithStringConstructorEPNS_9ExecStateE -__ZN3JSC12StringObjectC1EPNS_9ExecStateEPNS_9StructureERKNS_7UStringE -__ZN3JSC12StringObjectC2EPNS_9ExecStateEPNS_9StructureERKNS_7UStringE __ZN3JSCL22numberProtoFuncValueOfEPNS_9ExecStateE __ZN3JSC12NumberObject11getJSNumberEv __ZN3JSC11makeUStringINS_7UStringEPKcS1_EES1_T_T0_T1_ __ZN3JSCL23booleanProtoFuncValueOfEPNS_9ExecStateE __ZN3JSC21ReadModifyBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC26fromCharCodeThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE -__ZN3JSCL18stringFromCharCodeEPNS_9ExecStateE -__ZN3JSCL18arrayProtoFuncSortEPNS_9ExecStateE -__ZN3JSC7JSArray4sortEPNS_9ExecStateE -__ZN3JSC7JSArray17compactForSortingEv -__ZN3JSC4Heap18pushTempSortVectorEPN3WTF6VectorISt4pairINS_7JSValueENS_7UStringEELm0EEE -__ZN3WTF6VectorIPNS0_ISt4pairIN3JSC7JSValueENS2_7UStringEELm0EEELm0EE15reserveCapacityEm -__ZN3JSC4Heap17popTempSortVectorEPN3WTF6VectorISt4pairINS_7JSValueENS_7UStringEELm0EEE __ZN3JSCltERKNS_7UStringES2_ -__ZN3JSCL27compareByStringPairForQSortEPKvS1_ -__ZN3WTF16codePointCompareEPKNS_10StringImplES2_ __ZN3JSC7JSArray4sortEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataE -__ZN3JSC11Interpreter20prepareForRepeatCallEPNS_18FunctionExecutableEPNS_9ExecStateEPNS_10JSFunctionEiPNS_14ScopeChainNodeE __ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE6insertEi -__ZN3JSC11Interpreter13endRepeatCallERNS_16CallFrameClosureE -__ZN3JSC11Interpreter7executeERNS_16CallFrameClosureE __ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE7balanceEi -__ZNK3JSC14ExpressionNode11isCommaNodeEv __ZNK3JSC7SubNode10isSubtractEv __ZN3JSC17BytecodeGenerator17argumentNumberForERKNS_10IdentifierE __ZN3JSC17BytecodeGenerator27setIsNumericCompareFunctionEb __ZN3JSC7JSArray11sortNumericEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataE __ZN3JSCL20dateProtoFuncGetTimeEPNS_9ExecStateE __ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE -__ZN3JSC24charCodeAtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE __ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE -__ZNK3JSC8NullNode6isNullEv -__ZN3JSC3JIT15emit_op_eq_nullEPNS_11InstructionE -_cti_op_is_number __ZNK3JSC7JSValue16synthesizeObjectEPNS_9ExecStateE __ZN3JSC36constructBooleanFromImmediateBooleanEPNS_9ExecStateEPNS_14JSGlobalObjectENS_7JSValueE -__ZN3JSC14throwTypeErrorEPNS_9ExecStateE __ZN3JSCL27dateProtoFuncGetUTCFullYearEPNS_9ExecStateE __ZNK3JSC12DateInstance29calculateGregorianDateTimeUTCEPNS_9ExecStateE __ZN3JSC23MacroAssemblerX86Common4moveENS_22AbstractMacroAssemblerINS_12X86AssemblerEE13TrustedImmPtrENS_12X86Registers10RegisterIDE @@ -1827,12 +1938,13 @@ __ZN3JSCL7dateUTCEPNS_9ExecStateE __ZN3JSC15globalFuncIsNaNEPNS_9ExecStateE _cti_op_is_object __ZN3JSC14jsIsObjectTypeENS_7JSValueE -_cti_op_less -__ZN3JSCL19jsStrDecimalLiteralERPKtS1_ -__ZN3WTF6VectorIcLm32EE14expandCapacityEm __ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateE _cti_op_pre_inc __ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateE +__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateE +__ZN3JSC7JSArray3popEv +__ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateE +__ZN3JSC7JSArray10shiftCountEPNS_9ExecStateEi __ZN3JSCL28dateProtoFuncSetMilliSecondsEPNS_9ExecStateE __ZN3JSCL23setNewValueFromTimeArgsEPNS_9ExecStateEib __ZN3JSCL31dateProtoFuncSetUTCMillisecondsEPNS_9ExecStateE @@ -1856,7 +1968,6 @@ __ZN3JSC17BytecodeGenerator13emitPushScopeEPNS_10RegisterIDE __ZN3JSC3JIT18emit_op_push_scopeEPNS_11InstructionE _cti_op_push_scope __ZN3JSC17DeleteResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC3JIT17emit_op_jneq_nullEPNS_11InstructionE __ZN3JSC3JIT26emit_op_ret_object_or_thisEPNS_11InstructionE __ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE __ZN3WTF9HashTableIPNS_10StringImplES2_NS_17IdentityExtractorIS2_EENS_7PtrHashIS2_EENS_10HashTraitsIS2_EES8_E6expandEv @@ -1868,71 +1979,32 @@ __ZN3JSC19FunctionConstructor11getCallDataERNS_8CallDataE __ZN3JSC15DateConstructor11getCallDataERNS_8CallDataE __ZN3JSCL25numberConstructorMaxValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZN3JSCL25numberConstructorMinValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE -__ZN3JSC18sqrtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE -__ZN3JSC9CodeBlock32expressionRangeForBytecodeOffsetEjRiS1_S1_ -__ZN3JSC11makeUStringINS_7UStringEPKcS1_S3_EES1_T_T0_T1_T2_ -__ZN3WTF13tryMakeStringIN3JSC7UStringEPKcS2_S4_EENS_10PassRefPtrINS_10StringImplEEET_T0_T1_T2_ -__ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE -__ZN3JSC26createNotAConstructorErrorEPNS_9ExecStateENS_7JSValueE _cti_op_post_inc _cti_op_post_dec -__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE __ZN3JSC10ASTBuilder18makeBitwiseNotNodeEPNS_14ExpressionNodeE __ZN3JSC3JIT14emit_op_bitnotEPNS_11InstructionE __ZN3JSC3JIT18emitSlow_op_bitnotEPNS_11InstructionERPNS_13SlowCaseEntryE _cti_op_jlesseq _cti_op_bitnot -__ZN3JSC12StringObjectC1EPNS_9ExecStateEPNS_9StructureE __ZN3WTF6VectorIjLm16EE15reserveCapacityEm -__ZNK3JSC8JSString8toObjectEPNS_9ExecStateEPNS_14JSGlobalObjectE -__ZN3JSC10ASTBuilder17makeLeftShiftNodeEPNS_14ExpressionNodeES2_b -__ZN3JSC3JIT14emit_op_lshiftEPNS_11InstructionE -__ZN3JSC3JIT18emitSlow_op_lshiftEPNS_11InstructionERPNS_13SlowCaseEntryE -_cti_op_lshift -__ZN3JSC10ASTBuilder18makeRightShiftNodeEPNS_14ExpressionNodeES2_b -__ZN3JSC3JIT14emit_op_rshiftEPNS_11InstructionE -__ZN3JSC3JIT18emitSlow_op_rshiftEPNS_11InstructionERPNS_13SlowCaseEntryE _cti_op_rshift __ZN3JSC10ASTBuilder19makeURightShiftNodeEPNS_14ExpressionNodeES2_b __ZN3JSC3JIT15emit_op_urshiftEPNS_11InstructionE __ZN3JSC3JIT19emitSlow_op_urshiftEPNS_11InstructionERPNS_13SlowCaseEntryE -__ZN3WTF6VectorIPNS_14StringImplBaseELm32EE14expandCapacityEm _cti_op_urshift -__ZN3JSC3JIT16emit_op_neq_nullEPNS_11InstructionE -__ZN3JSC10ASTBuilder14makeBitAndNodeEPNS_14ExpressionNodeES2_b -__ZN3JSC3JIT14emit_op_bitandEPNS_11InstructionE -__ZN3JSC3JIT18emitSlow_op_bitandEPNS_11InstructionERPNS_13SlowCaseEntryE _cti_op_bitand -__ZN3JSC10ASTBuilder13makeBitOrNodeEPNS_14ExpressionNodeES2_b -__ZN3JSC3JIT13emit_op_bitorEPNS_11InstructionE -__ZN3JSC3JIT17emitSlow_op_bitorEPNS_11InstructionERPNS_13SlowCaseEntryE -_cti_op_bitor -__ZN3JSC10ASTBuilder14makeBitXOrNodeEPNS_14ExpressionNodeES2_b -__ZN3JSC3JIT14emit_op_bitxorEPNS_11InstructionE -__ZN3JSC3JIT18emitSlow_op_bitxorEPNS_11InstructionERPNS_13SlowCaseEntryE -_cti_op_bitxor _cti_op_div __ZN3JSCL23callFunctionConstructorEPNS_9ExecStateE __ZN3JSC10JSFunction12lengthGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZN3JSC10JSFunction15argumentsGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZNK3JSC11Interpreter17retrieveArgumentsEPNS_9ExecStateEPNS_10JSFunctionE __ZN3JSCL21callFunctionPrototypeEPNS_9ExecStateE -__ZNK3JSC14ExpressionNode10isLocationEv -__ZN3JSC21FunctionCallValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC23createNotAFunctionErrorEPNS_9ExecStateENS_7JSValueE __ZN3JSC10JSFunction19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE __ZNK3JSC9CommaNode11isCommaNodeEv -__ZN3JSC20globalFuncParseFloatEPNS_9ExecStateE -__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14expandCapacityEm -__ZNK3JSC5Label4bindEii -__ZN3WTF6VectorIiLm0EEC2ERKS1_ -__ZN3JSC3JIT18emit_op_switch_immEPNS_11InstructionE -__ZN3WTF6VectorIN3JSC17CodeLocationLabelELm0EE14expandCapacityEm -_cti_op_switch_imm __ZN3JSC18globalFuncIsFiniteEPNS_9ExecStateE -__ZN3JSC28createUndefinedVariableErrorEPNS_9ExecStateERKNS_10IdentifierE -__ZN3JSC11makeUStringIPKcNS_7UStringEEES3_T_T0_ -__ZN3WTF13tryMakeStringIPKcN3JSC7UStringEEENS_10PassRefPtrINS_10StringImplEEET_T0_ +__ZN3JSCL19stringProtoFuncTrimEPNS_9ExecStateE +__ZN3JSCL10trimStringEPNS_9ExecStateENS_7JSValueEi +__ZN3JSC15isStrWhiteSpaceEt __ZN3JSC15AssignErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17BytecodeGenerator23emitThrowReferenceErrorERKNS_7UStringE __ZN3JSC3JIT29emit_op_throw_reference_errorEPNS_11InstructionE @@ -1947,11 +2019,8 @@ __ZN3JSCL17mathProtoFuncCeilEPNS_9ExecStateE __ZN3JSCL16mathProtoFuncCosEPNS_9ExecStateE __ZN3JSCL16mathProtoFuncExpEPNS_9ExecStateE __ZN3JSCL16mathProtoFuncLogEPNS_9ExecStateE -__ZN3JSCL16mathProtoFuncMaxEPNS_9ExecStateE -__ZN3JSCL16mathProtoFuncMinEPNS_9ExecStateE __ZN3JSCL16mathProtoFuncPowEPNS_9ExecStateE __ZN3JSCL19mathProtoFuncRandomEPNS_9ExecStateE -__ZN3JSCL18mathProtoFuncRoundEPNS_9ExecStateE __ZN3JSCL16mathProtoFuncSinEPNS_9ExecStateE __ZN3JSCL17mathProtoFuncSqrtEPNS_9ExecStateE __ZN3JSCL16mathProtoFuncTanEPNS_9ExecStateE @@ -1962,39 +2031,25 @@ __ZN3JSC9ExecState22objectConstructorTableEPS0_ _cti_to_object __ZN3JSC9ExecState20numberPrototypeTableEPS0_ __ZNK3JSC15DotAccessorNode17isDotAccessorNodeEv -__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPN3WTF10StringImplE __ZNK3JSC14ExpressionNode17isDotAccessorNodeEv __ZN3JSC9ExecState22stringConstructorTableEPS0_ __ZN3JSCL26stringFromCharCodeSlowCaseEPNS_9ExecStateE __ZN3JSCL25stringProtoFuncCharCodeAtEPNS_9ExecStateE __ZNK3JSC12JSActivation12toThisObjectEPNS_9ExecStateE -__ZN3JSCL26stringProtoFuncToLowerCaseEPNS_9ExecStateE -__ZN3JSCL26stringProtoFuncToUpperCaseEPNS_9ExecStateE __ZN3JSC12StringObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE __ZN3JSC9ExecState11stringTableEPS0_ __ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE -__ZN3JSC17BytecodeGenerator18pushFinallyContextEPNS_5LabelEPNS_10RegisterIDE -__ZN3JSC17BytecodeGenerator17popFinallyContextEv -__ZN3JSC17BytecodeGenerator19highestUsedRegisterEv -__ZN3JSC17BytecodeGenerator18emitJumpSubroutineEPNS_10RegisterIDEPNS_5LabelE -__ZN3JSC17BytecodeGenerator20emitSubroutineReturnEPNS_10RegisterIDE -__ZN3JSC3JIT11emit_op_jsrEPNS_11InstructionE -__ZN3WTF6VectorIN3JSC3JIT7JSRInfoELm0EE14expandCapacityEm -__ZN3JSC3JIT12emit_op_sretEPNS_11InstructionE _cti_op_check_has_instance __ZN3JSC23createInvalidParamErrorEPNS_9ExecStateEPKcNS_7JSValueE __ZN3JSC11makeUStringIPKcNS_7UStringES2_S2_S2_EES3_T_T0_T1_T2_T3_ __ZN3WTF13tryMakeStringIPKcN3JSC7UStringES2_S2_S2_EENS_10PassRefPtrINS_10StringImplEEET_T0_T1_T2_T3_ -_cti_op_is_string __ZN3JSC17RegExpConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE __ZN3JSC12RegExpObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE __ZN3JSCL21regExpObjectLastIndexEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE -__ZN3JSC4Yarr12digitsCreateEv __ZN3WTF6VectorIN3JSC4Yarr12ByteCompiler21ParenthesesStackEntryELm0EE14expandCapacityEm __ZN3JSC4Yarr12ByteCompiler16closeAlternativeEi __ZN3WTF6VectorIN3JSC4Yarr8ByteTermELm0EE14expandCapacityEmPKS3_ __ZN3WTF6VectorIPN3JSC4Yarr15ByteDisjunctionELm0EE14expandCapacityEm -__ZN3JSC3JIT16emit_op_jeq_nullEPNS_11InstructionE __ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE __ZN3JSC4Yarr11Interpreter20backtrackParenthesesERNS0_8ByteTermEPNS1_18DisjunctionContextE __ZN3JSC4Yarr11YarrPattern21newlineCharacterClassEv @@ -2005,13 +2060,10 @@ __ZN3JSC4Yarr15nonspacesCreateEv __ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE4JumpELm16EE14expandCapacityEmPKS5_ __ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE4JumpELm16EE14expandCapacityEm __ZN3JSC4Yarr15nondigitsCreateEv -__ZN3JSC4Yarr13YarrGenerator29generateAssertionWordBoundaryEm __ZN3JSCL24setRegExpObjectLastIndexEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE __ZN3JSC9ExecState11regExpTableEPS0_ __ZN3JSC9ExecState20regExpPrototypeTableEPS0_ -__ZN3JSC8JSParser21parseDoWhileStatementINS_13SyntaxCheckerEEENT_9StatementERS3_ __ZN3JSC9LabelNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC14PostfixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3WTF6VectorIiLm0EE15reserveCapacityEm __ZN3JSC3JIT19emit_op_switch_charEPNS_11InstructionE _cti_op_switch_char @@ -2020,14 +2072,11 @@ __ZNK3WTF9HashTableIPN3JSC20MarkedArgumentBufferES3_NS_17IdentityExtractorIS3_EE __ZN3JSCL20stringProtoFuncSliceEPNS_9ExecStateE _cti_op_get_by_id_proto_fail __ZN3JSCL28arrayProtoFuncToLocaleStringEPNS_9ExecStateE -__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateE -__ZN3JSC7JSArray3popEv __ZN3JSC16ErrorConstructor16getConstructDataERNS_13ConstructDataE __ZN3JSCL29constructWithErrorConstructorEPNS_9ExecStateE __ZN3JSCL22compareNumbersForQSortEPKvS1_ __ZN3JSCL25dateProtoFuncToDateStringEPNS_9ExecStateE __ZN3JSCL25dateProtoFuncToTimeStringEPNS_9ExecStateE -_cti_op_get_by_val_string __ZN3JSCL27dateProtoFuncToLocaleStringEPNS_9ExecStateE __ZN3JSCL16formatLocaleDateEPNS_9ExecStateEPNS_12DateInstanceEdNS_20LocaleDateTimeFormatE __ZN3JSCL31dateProtoFuncToLocaleDateStringEPNS_9ExecStateE @@ -2036,8 +2085,6 @@ __ZN3JSCL20callErrorConstructorEPNS_9ExecStateE __ZN3JSC17RegExpConstructor11getCallDataERNS_8CallDataE __ZN3JSCL21callRegExpConstructorEPNS_9ExecStateE __ZNK3JSC8JSObject15isErrorInstanceEv -__ZN3JSC3JIT26emit_op_tear_off_argumentsEPNS_11InstructionE -__ZN3JSC8jsStringEPNS_9ExecStateERKNS_7UStringE __ZN3JSC12JSActivation14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE __ZN3JSC17BytecodeGenerator14emitPutByIndexEPNS_10RegisterIDEjS2_ __ZN3JSC3JIT20emit_op_put_by_indexEPNS_11InstructionE @@ -2048,7 +2095,6 @@ __ZN3JSC17DeleteBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10Register __ZN3JSC17BytecodeGenerator15emitDeleteByValEPNS_10RegisterIDES2_S2_ _cti_op_del_by_val __ZN3JSC9Arguments14deletePropertyEPNS_9ExecStateEj -__ZN3JSC14LogicalNotNode30emitBytecodeInConditionContextERNS_17BytecodeGeneratorEPNS_5LabelES4_b _cti_op_tear_off_arguments __ZN3JSC9Arguments3putEPNS_9ExecStateEjNS_7JSValueE __ZN3JSCL29objectProtoFuncHasOwnPropertyEPNS_9ExecStateE @@ -2076,21 +2122,14 @@ __ZNK3JSC17RegExpConstructor14getLeftContextEPNS_9ExecStateE __ZN3JSCL29regExpConstructorRightContextEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZNK3JSC17RegExpConstructor15getRightContextEPNS_9ExecStateE __ZN3WTF6VectorIiLm32EE15reserveCapacityEm -__ZN3WTF6VectorIN3JSC11StringRangeELm16EE14expandCapacityEmPKS2_ -__ZN3WTF6VectorIN3JSC11StringRangeELm16EE15reserveCapacityEm -__ZN3WTF6VectorIN3JSC7UStringELm16EE14expandCapacityEmPKS2_ -__ZN3WTF6VectorIN3JSC7UStringELm16EE15reserveCapacityEm __ZN3JSCL24regExpConstructorDollar1EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZN3JSCL24regExpConstructorDollar2EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZN3WTF6VectorIPNS0_IN3JSC5LabelELm32EEELm32EE14expandCapacityEmPKS4_ __ZN3WTF6VectorIPNS0_IN3JSC5LabelELm32EEELm32EE15reserveCapacityEm __ZN3JSC8JSString16replaceCharacterEPNS_9ExecStateEtRKNS_7UStringE -__ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateE -__ZN3JSC7JSArray10shiftCountEPNS_9ExecStateEi __ZN3JSCL21arrayProtoFuncUnShiftEPNS_9ExecStateE __ZN3JSC7JSArray12unshiftCountEPNS_9ExecStateEi __ZN3JSC7JSArray26increaseVectorPrefixLengthEj -__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm16EE14expandCapacityEm __ZN3JSCL21stringProtoFuncConcatEPNS_9ExecStateE __ZN3JSCL24regExpConstructorDollar3EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZN3JSCL24regExpConstructorDollar4EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE @@ -2109,7 +2148,6 @@ __ZN3JSCL29setRegExpConstructorMultilineEPNS_9ExecStateEPNS_8JSObjectENS_7JSValu __ZN3JSCL22regExpProtoFuncCompileEPNS_9ExecStateE __ZN3JSC14globalFuncEvalEPNS_9ExecStateE __ZN3JSC11Interpreter7executeEPNS_14EvalExecutableEPNS_9ExecStateEPNS_8JSObjectEPNS_14ScopeChainNodeE -__ZNK3JSC19JSStaticScopeObject14isDynamicScopeERb __ZN3JSC9Arguments3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE __ZN3JSC17ConservativeRoots4growEv __ZN3JSCL27objectProtoFuncDefineSetterEPNS_9ExecStateE @@ -2134,8 +2172,6 @@ __ZN3JSCL21stringProtoFuncStrikeEPNS_9ExecStateE __ZN3JSCL18stringProtoFuncSubEPNS_9ExecStateE __ZN3JSCL18stringProtoFuncSupEPNS_9ExecStateE __ZN3JSC18PostfixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC19globalFuncEncodeURIEPNS_9ExecStateE -__ZN3JSCL6encodeEPNS_9ExecStateEPKc __ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE __ZN3JSCL35objectProtoFuncPropertyIsEnumerableEPNS_9ExecStateE __ZNK3JSC8JSObject20propertyIsEnumerableEPNS_9ExecStateERKNS_10IdentifierE @@ -2148,11 +2184,7 @@ __ZN3WTF6VectorISt4pairIPN3JSC14ExpressionNodeENS2_10ASTBuilder12BinaryOpInfoEEL __ZN3WTF6VectorISt4pairIPN3JSC14ExpressionNodeENS2_10ASTBuilder12BinaryOpInfoEELm10EE15reserveCapacityEm __ZN3WTF6VectorISt4pairIiiELm10EE14expandCapacityEm __ZN3JSC29callHostFunctionAsConstructorEPNS_9ExecStateE -__ZN3JSC3JIT30emit_op_resolve_global_dynamicEPNS_11InstructionE -__ZN3JSC3JIT34emitSlow_op_resolve_global_dynamicEPNS_11InstructionERPNS_13SlowCaseEntryE __ZNK3JSC9ArrayNode13isSimpleArrayEv -__ZN3JSCL17arrayProtoFuncMapEPNS_9ExecStateE -__ZN3JSCL21arrayProtoFuncForEachEPNS_9ExecStateE __ZN3JSCL20arrayProtoFuncFilterEPNS_9ExecStateE __ZN3JSCL19arrayProtoFuncEveryEPNS_9ExecStateE __ZN3JSCL18arrayProtoFuncSomeEPNS_9ExecStateE @@ -2160,56 +2192,305 @@ __ZN3JSCL21arrayProtoFuncIndexOfEPNS_9ExecStateE __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE __ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj __ZN3JSCL25arrayProtoFuncLastIndexOfEPNS_9ExecStateE -__ZNK3WTF6String7toFloatEPbS1_ -__ZN3WTF10StringImpl7toFloatEPbS1_ -__ZN3WTF17charactersToFloatEPKtmPbS2_ -__ZNK3JSC7UString5asciiEv -__ZN3JSC6JSLock12DropAllLocksC1ENS_14JSLockBehaviorE -__ZN3WTF10StringImpl8toDoubleEPbS1_ -__ZN3JSCL21stringProtoFuncSubstrEPNS_9ExecStateE -__ZN3WTF10StringImpl4findEPKcj -__ZN3WTF6String26fromUTF8WithLatin1FallbackEPKcm -__ZN3WTF10fastStrDupEPKc -__ZN3WTF17equalIgnoringCaseEPKtPKcj -__ZN3JSC10Identifier5equalEPKN3WTF10StringImplEPKc -__ZN3JSC11JSByteArray15createStructureERNS_12JSGlobalDataENS_7JSValueEPKNS_9ClassInfoE -__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEPNS_9StructureEPN3WTF9ByteArrayE -__ZN3JSC11JSByteArrayC2EPNS_9ExecStateEPNS_9StructureEPN3WTF9ByteArrayE -__ZN3JSC11JSByteArrayD1Ev -_cti_op_get_by_val_byte_array -__ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE -__ZN3JSC11JSByteArray3putEPNS_9ExecStateEjNS_7JSValueE -_cti_op_put_by_val_byte_array -__ZN3JSC16throwSyntaxErrorEPNS_9ExecStateE -__ZN3WTF10StringImpl16findIgnoringCaseEPS0_j -__ZNK3WTF6String6toUIntEPb -__ZN3WTF10StringImpl6toUIntEPb -__ZN3WTF16charactersToUIntEPKtmPb -__ZN3WTFeqERKNS_12AtomicStringERKNS_6VectorItLm0EEE -__ZN3WTF12AtomicString16fromUTF8InternalEPKcS2_ -__ZN3WTF7Unicode36calculateStringHashAndLengthFromUTF8EPKcS2_RjS3_ -__ZNK3WTF6String5splitERKS0_RNS_6VectorIS0_Lm0EEE -__ZN3WTF10StringImpl7replaceEtPS0_ -__ZN3WTFeqERKNS_7CStringES2_ -__ZN3WTF10StringImpl6secureEtNS0_21LastCharacterBehaviorE -__ZNK3WTF6String5upperEv -__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE -__ZNK3WTF6String6latin1Ev -__ZN3WTF6VectorIN3JSC14ExecutablePool10AllocationELm2EE15reserveCapacityEm -__ZN3WTF6String6numberEj -__ZNK3JSC8JSObject14isGlobalObjectEv -__ZN3WTF10StringImpl19characterStartingAtEj -__ZN3WTF6String6appendEt -__ZNK3WTF6String19characterStartingAtEj -__ZN3JSC11JSByteArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE -__ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE __ZN3WTF20equalIgnoringNullityEPNS_10StringImplES1_ _cti_op_get_by_id_array_fail __ZN3JSC17PrefixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3WTF21CrossThreadRefCountedINS_16OwnFastMallocPtrIKtEEE5derefEv __ZN3JSC12JSGlobalData10ClientDataD2Ev __ZN3JSC8DebuggerD2Ev __ZN3WTF14ThreadSpecificINS_13WTFThreadDataEE7destroyEPv __ZN3WTF13WTFThreadDataD1Ev __ZN3WTF17AtomicStringTable7destroyEPS0_ __ZN3JSC15IdentifierTableD1Ev +_cti_op_is_boolean +__ZN3JSC18RegExpMatchesArray14deletePropertyEPNS_9ExecStateEj +__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE +__ZN3JSC15WeakHandleOwner8finalizeENS_6HandleINS_7UnknownEEEPv +__ZN3WTF9dayInYearEdi +__ZN3WTF18monthFromDayInYearEib +__ZN3WTF23dayInMonthFromDayInYearEib +__ZNK3JSC4Heap11objectCountEv +__ZNK3JSC11MarkedSpace11objectCountEv +__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj +__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj +__ZN3JSC9Structure22getterSetterTransitionERNS_12JSGlobalDataEPS0_ +__ZN3JSCL28objectProtoFuncIsPrototypeOfEPNS_9ExecStateE +__ZN3JSCL21functionProtoFuncCallEPNS_9ExecStateE +__ZNK3JSC7ArgList8getSliceEiRS0_ +__ZN3JSCL36objectConstructorGetOwnPropertyNamesEPNS_9ExecStateE +__ZN3JSCL31objectConstructorGetPrototypeOfEPNS_9ExecStateE +__ZN3JSC22NativeErrorConstructor11getCallDataERNS_8CallDataE +__ZN3JSC10JSONObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE +__ZN3WTF10StringImpl23defaultWritingDirectionEPb +__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE +__ZN3JSC23throwStackOverflowErrorEPNS_9ExecStateE +__ZN3JSCL23arrayConstructorIsArrayEPNS_9ExecStateE +__ZN3JSCL21objectConstructorKeysEPNS_9ExecStateE +__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj +__ZN3JSCL24dateProtoFuncToISOStringEPNS_9ExecStateE +_cti_op_get_by_id_string_fail +__ZN3JSC22StringRecursionChecker11emptyStringEv +__ZN3JSC22StringRecursionChecker23throwStackOverflowErrorEv +__ZN3JSC9ExecState9jsonTableEPS0_ +__ZN3JSC10JSFunction12callerGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE +__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_10JSFunctionE +__ZN3WTF27releaseFastMallocFreeMemoryEv +__ZN3JSC17BytecodeGenerator21emitComplexJumpScopesEPNS_5LabelEPNS_18ControlFlowContextES4_ +__ZN3JSCL22functionProtoFuncApplyEPNS_9ExecStateE +__ZN3JSC7JSArray11fillArgListEPNS_9ExecStateERNS_20MarkedArgumentBufferE +__ZN3JSC9CodeBlock16createActivationEPNS_9ExecStateE +__ZN3JSCL22JSONProtoFuncStringifyEPNS_9ExecStateE +_cti_op_put_by_id_direct_fail +__ZN3JSCL18JSONProtoFuncParseEPNS_9ExecStateE +__ZN3JSC6Walker4walkENS_7JSValueE +__ZN3WTF6VectorIN3JSC5LocalINS1_7JSArrayEEELm16EE14expandCapacityEm +__ZN3WTF6VectorIjLm16EE14expandCapacityEm +__ZN3WTF6VectorIN3JSC11WalkerStateELm16EE14expandCapacityEm +__ZN3JSC11HandleStack4growEv +__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateEjNS_7JSValueE +__ZNK3JSC27PropertyNameForFunctionCall5valueEPNS_9ExecStateE +__ZN3WTF13StringBuilder6resizeEj +__ZN3JSC8JSParser17parseFunctionInfoILNS0_20FunctionRequirementsE1ELb0ENS_13SyntaxCheckerEEEbRT1_RPKNS_10IdentifierERNS4_19FormalParameterListERNS4_12FunctionBodyERiSE_SE_ +__ZN3JSCL19dateProtoFuncToJSONEPNS_9ExecStateE +__ZN3JSC9ExecState9dateTableEPS0_ +__ZN3JSC10Identifier4fromEPNS_9ExecStateEd +__ZN3WTF6VectorIN3JSC11Stringifier6HolderELm16EE15reserveCapacityEm +__ZN3JSCL23objectConstructorCreateEPNS_9ExecStateE +__ZN3JSCL16definePropertiesEPNS_9ExecStateEPNS_8JSObjectES3_ +__ZN3JSCL20toPropertyDescriptorEPNS_9ExecStateENS_7JSValueERNS_18PropertyDescriptorE +__ZN3WTF6VectorIN3JSC18PropertyDescriptorELm0EE14expandCapacityEm +__ZNK3JSC18PropertyDescriptor16isDataDescriptorEv +__ZN3JSC8JSObject17defineOwnPropertyEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorEb +__ZN3JSCL13putDescriptorEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERNS_18PropertyDescriptorEjRKS7_ +__ZNK3JSC18PropertyDescriptor19isGenericDescriptorEv +__ZN3JSC18PropertyDescriptor9setGetterENS_7JSValueE +__ZNK3JSC18PropertyDescriptor6getterEv +__ZNK3JSC18PropertyDescriptor6setterEv +__ZN3JSC18PropertyDescriptor11setWritableEb +__ZN3JSC18PropertyDescriptor9setSetterENS_7JSValueE +__ZN3JSCL33objectConstructorDefinePropertiesEPNS_9ExecStateE +__ZNK3JSC18PropertyDescriptor7equalToEPNS_9ExecStateERKS0_ +__ZNK3JSC18PropertyDescriptor15attributesEqualERKS0_ +__ZNK3JSC18PropertyDescriptor22attributesWithOverrideERKS0_ +__ZN3JSCL31objectConstructorDefinePropertyEPNS_9ExecStateE +__ZN3JSC7JSArray24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC9Arguments19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE +__ZN3JSC9ExecState21booleanPrototypeTableEPS0_ +__ZN3JSC9ExecState20dateConstructorTableEPS0_ +__ZN3JSC9ExecState22regExpConstructorTableEPS0_ +__ZN3JSC9ExecState19errorPrototypeTableEPS0_ +__ZN3JSC12JSActivation18getArgumentsGetterEv +__ZN3JSC12JSActivation15argumentsGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE +__ZN3JSCL20arrayProtoFuncReduceEPNS_9ExecStateE +__ZN3JSCL25arrayProtoFuncReduceRightEPNS_9ExecStateE +__ZN3JSC3JIT27emit_op_convert_this_strictEPNS_11InstructionE +__ZN3JSC3JIT31emitSlow_op_convert_this_strictEPNS_11InstructionERPNS_13SlowCaseEntryE +__ZN3JSC9Arguments33createStrictModeCalleeIfNecessaryEPNS_9ExecStateE +__ZN3JSC23createTypeErrorFunctionEPNS_9ExecStateERKNS_7UStringE +__ZN3JSC18PropertyDescriptor21setAccessorDescriptorENS_7JSValueES1_j +__ZN3JSC9Arguments24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC27StrictModeTypeErrorFunction11getCallDataERNS_8CallDataE +__ZN3JSC27StrictModeTypeErrorFunction18callThrowTypeErrorEPNS_9ExecStateE +__ZN3JSC14throwTypeErrorEPNS_9ExecStateERKNS_7UStringE +__ZN3JSC9Arguments33createStrictModeCallerIfNecessaryEPNS_9ExecStateE +_cti_op_resolve_base_strict_put +__ZN3JSC37createErrorForInvalidGlobalAssignmentEPNS_9ExecStateERKNS_7UStringE +__ZN3JSC19JSStaticScopeObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE +__ZN3JSC20StrictEvalActivationC1EPNS_9ExecStateE +__ZN3JSC15PrefixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC16PostfixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC10JSFunction24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSCL35createDescriptorForThrowingPropertyEPNS_9ExecStateERNS_18PropertyDescriptorEPKc +__ZN3JSC20StrictEvalActivationD1Ev +__ZN3JSC27StrictModeTypeErrorFunctionD1Ev +__ZN3JSC9Arguments15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj +_cti_op_loop_if_lesseq +__ZN3JSC23MacroAssemblerX86Common12branchTest32ENS0_15ResultConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_12TrustedImm32E +__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_19RelationalConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_12TrustedImm32E +__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_12X86Registers10RegisterIDEi +__ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE4JumpELm16EEC2ERKS6_ +__ZN3JSCL31dateProtoFuncToLocaleTimeStringEPNS_9ExecStateE +__ZN3JSCL20dateProtoFuncSetYearEPNS_9ExecStateE +__ZN3JSCL26dateProtoFuncSetUTCSecondsEPNS_9ExecStateE +__ZN3JSC21DebuggerStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC15DeleteValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE +__ZN3JSC28globalFuncEncodeURIComponentEPNS_9ExecStateE +__ZN3JSC15createEvalErrorEPNS_9ExecStateERKNS_7UStringE +__ZN3JSC13JSNotAnObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE +__ZN3JSC13JSNotAnObject3putEPNS_9ExecStateEjNS_7JSValueE +__ZN3WTF6String6numberEx +__ZN3JSC14ArrayPrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC13DatePrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC15StringPrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC12StringObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC8JSString27getStringPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC15RegExpPrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC12RegExpObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC17NumberConstructor24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC17RegExpConstructor24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC10MathObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC18RegExpMatchesArray24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSCL8callDateEPNS_9ExecStateE +__ZN3JSCL26callNativeErrorConstructorEPNS_9ExecStateE +__ZN3JSC17BytecodeGenerator35emitThrowExpressionTooDeepExceptionEv +__ZN3JSC22createOutOfMemoryErrorEPNS_14JSGlobalObjectE +__ZN3JSC11createErrorEPNS_14JSGlobalObjectERKNS_7UStringE +__ZN3JSC13UnaryPlusNode14stripUnaryPlusEv +__ZN3JSCL29objectProtoFuncToLocaleStringEPNS_9ExecStateE +__ZN3WTF6VectorIN3JSC8JSParser14ScopeLabelInfoELm2EE14expandCapacityEm +__ZN3JSCL34objectConstructorPreventExtensionsEPNS_9ExecStateE +__ZN3JSC10JSFunction17preventExtensionsERNS_12JSGlobalDataE +__ZN3JSC8JSObject17preventExtensionsERNS_12JSGlobalDataE +__ZN3JSC9Structure27preventExtensionsTransitionERNS_12JSGlobalDataEPS0_ +__ZN3JSCL21objectConstructorSealEPNS_9ExecStateE +__ZN3JSC8JSObject4sealERNS_12JSGlobalDataE +__ZN3JSC9Structure8isSealedERNS_12JSGlobalDataE +__ZN3JSC9Structure14sealTransitionERNS_12JSGlobalDataEPS0_ +__ZN3JSCL23objectConstructorFreezeEPNS_9ExecStateE +__ZN3JSC8JSObject6freezeERNS_12JSGlobalDataE +__ZN3JSC9Structure8isFrozenERNS_12JSGlobalDataE +__ZN3JSC9Structure16freezeTransitionERNS_12JSGlobalDataEPS0_ +__ZN3JSCL25objectConstructorIsSealedEPNS_9ExecStateE +__ZN3JSCL25objectConstructorIsFrozenEPNS_9ExecStateE +__ZN3JSCL29objectConstructorIsExtensibleEPNS_9ExecStateE +__ZN3JSC4Yarr25CharacterClassConstructor9addSortedERN3WTF6VectorItLm0EEEt +__ZNK3JSC19JSStaticScopeObject12toThisObjectEPNS_9ExecStateE +__ZN3JSCL23stringProtoFuncTrimLeftEPNS_9ExecStateE +__ZN3JSCL24stringProtoFuncTrimRightEPNS_9ExecStateE +__ZN3WTF6VectorIcLm0EE14expandCapacityEm +__ZN3JSCL28stringProtoFuncLocaleCompareEPNS_9ExecStateE +__ZN3WTF8Collator11userDefaultEv +__ZNK3WTF8Collator7collateEPKtmS2_m +__ZNK3WTF8Collator14createCollatorEv +__ZN3WTF8CollatorD1Ev +__ZN3WTF8Collator15releaseCollatorEv +__ZN3JSC3JIT30emit_op_ensure_property_existsEPNS_11InstructionE +_cti_op_ensure_property_exists +__ZNK3JSC20StrictEvalActivation12toThisObjectEPNS_9ExecStateE +__ZN3JSC15IdentifierArena21makeNumericIdentifierEPNS_12JSGlobalDataEd +__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE +__ZN3JSC6JSCell3putEPNS_9ExecStateEjNS_7JSValueE +__ZN3WTF16codePointCompareERKNS_6StringES2_ +__ZN3JSC3JIT25emit_op_profile_will_callEPNS_11InstructionE +__ZN3JSC3JIT24emit_op_profile_did_callEPNS_11InstructionE +__ZN3JSC8Profiler8profilerEv +__ZN3JSC8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE +__ZN3JSC16ProfileGenerator6createEPNS_9ExecStateERKNS_7UStringEj +__ZN3JSC16ProfileGeneratorC2EPNS_9ExecStateERKNS_7UStringEj +__ZN3JSC7Profile6createERKNS_7UStringEj +__ZN3JSC7ProfileC2ERKNS_7UStringEj +__ZN3JSC11ProfileNodeC1EPNS_9ExecStateERKNS_14CallIdentifierEPS0_S6_ +__ZN3JSC16ProfileGenerator24addParentForConsoleStartEPNS_9ExecStateE +__ZN3JSC8Profiler20createCallIdentifierEPNS_9ExecStateENS_7JSValueERKNS_7UStringEi +__ZN3JSC10JSFunction21calculatedDisplayNameEPNS_9ExecStateE +__ZN3JSC10JSFunction11displayNameEPNS_9ExecStateE +__ZN3JSC11ProfileNode10insertNodeEN3WTF10PassRefPtrIS0_EE +__ZN3WTF6VectorINS_6RefPtrIN3JSC16ProfileGeneratorEEELm0EE14expandCapacityEm +_cti_op_profile_did_call +__ZN3JSC8Profiler10didExecuteEPNS_9ExecStateENS_7JSValueE +__ZN3JSC16ProfileGenerator10didExecuteEPNS_9ExecStateERKNS_14CallIdentifierE +__ZN3JSC11ProfileNode10didExecuteEv +_cti_op_profile_will_call +__ZN3JSC8Profiler11willExecuteEPNS_9ExecStateENS_7JSValueE +__ZN3JSC16ProfileGenerator11willExecuteEPNS_9ExecStateERKNS_14CallIdentifierE +__ZN3JSC11ProfileNode11willExecuteEPNS_9ExecStateERKNS_14CallIdentifierE +__ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE +__ZN3JSC16ProfileGenerator13stopProfilingEv +__ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE +__ZNK3JSC11ProfileNode25traverseNextNodePostOrderEv +__ZN3JSC11ProfileNode13stopProfilingEv +__ZN3JSC11ProfileNode11removeChildEPS0_ +__ZN3JSC11ProfileNode8addChildEN3WTF10PassRefPtrIS0_EE +__ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12JSGlobalDataE +__ZN3WTF9HashTableIPN3JSC18FunctionExecutableES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi +__ZN3JSC7ProfileD0Ev +__ZN3WTF10RefCountedIN3JSC11ProfileNodeEE5derefEv +__ZN3JSC8Profiler11willExecuteEPNS_9ExecStateERKNS_7UStringEi +__ZN3JSC8Profiler10didExecuteEPNS_9ExecStateERKNS_7UStringEi +__ZNK3JSC16ProfileGenerator5titleEv +__ZN3JSC8Profiler13stopProfilingEPNS_14JSGlobalObjectE +__ZN3JSC34createTerminatedExecutionExceptionEPNS_12JSGlobalDataE +__ZNK3JSC24TerminatedExecutionError13exceptionTypeEv +__ZN3JSC24TerminatedExecutionErrorD1Ev +__ZN3WTF5Mutex7tryLockEv +__ZN3WTF6String6numberEm +__ZN3WTF5yieldEv +__ZN3WTF8CollatorC1EPKc +__ZN3WTF8Collator18setOrderLowerFirstEb +__ZN3JSC10JSONObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC9Structure27despecifyDictionaryFunctionERNS_12JSGlobalDataERKNS_10IdentifierE +__ZN3JSC17ObjectConstructor24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC15ObjectPrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC17StringConstructor24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC16BooleanPrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC15NumberPrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC15DateConstructor24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC14ErrorPrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSC16ArrayConstructor24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE +__ZN3JSCL7dateNowEPNS_9ExecStateE +__ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE +__ZN3WTF9HashTableIPN3JSC14JSGlobalObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi +__ZN3JSC7UString6numberEl +__ZN3JSC3JIT13emit_op_debugEPNS_11InstructionE +_cti_op_debug +__ZN3JSC11Interpreter5debugEPNS_9ExecStateENS_11DebugHookIDEii +__ZNK3JSC14SourceProvider13startPositionEv +__ZN3WTF9HashTableIPN3JSC18FunctionExecutableES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_ +__ZN3WTF9HashTableIPN3JSC14SourceProviderESt4pairIS3_PNS1_9ExecStateEENS_18PairFirstExtractorIS7_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSD_IS6_EEEESE_E4findIS3_NS_22IdentityHashTranslatorIS3_S7_SB_EEEENS_17HashTableIteratorIS3_S7_S9_SB_SG_SE_EERKT_ +__ZN3WTF9HashTableIPN3JSC14SourceProviderESt4pairIS3_PNS1_9ExecStateEENS_18PairFirstExtractorIS7_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSD_IS6_EEEESE_E6expandEv +__ZNK3JSC17DebuggerCallFrame4typeEv +__ZNK3JSC17DebuggerCallFrame22calculatedFunctionNameEv +__ZN3JSC12JSActivation19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE +__ZNK3JSC12JSActivation18isActivationObjectEv +__ZNK3JSC17DebuggerCallFrame10thisObjectEv +__ZN3WTF28setMainThreadCallbacksPausedEb +__ZNK3JSC17DebuggerCallFrame8evaluateERKNS_7UStringERNS_7JSValueE +__ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE +__ZN3JSC14JSGlobalObject11disableEvalEv +__ZN3WTF6VectorIN3JSC14ExecutablePool10AllocationELm2EE14expandCapacityEm +__ZNK3WTF6String8toIntPtrEPb +__ZN3WTF10StringImpl8toIntPtrEPb +__ZN3WTF18charactersToIntPtrEPKtmPb +__ZNK3JSC8JSObject18isActivationObjectEv +_cti_op_construct_jitCompile +__ZN3WTF10StringImpl7replaceEjjPS0_ +__ZNK3JSC4Heap8capacityEv +__ZNK3JSC11MarkedSpace8capacityEv +__ZNK3JSC4Heap4sizeEv +__ZN3WTF29cryptographicallyRandomValuesEPvm +__ZN3WTF6VectorIN3JSC8JSParser5ScopeELm10EE15reserveCapacityEm +__ZN3JSC8JSString16getIndexSlowCaseEPNS_9ExecStateEj +__ZNK3WTF6String12toUIntStrictEPbi +__ZN3WTF10StringImpl12toUIntStrictEPbi +__ZN3WTF37parseDateFromNullTerminatedCharactersEPKc +__ZNK3WTF6String8toUInt64EPb +__ZN3WTF10StringImpl8toUInt64EPb +__ZN3WTF18charactersToUInt64EPKtmPb +__ZN3WTF3MD5C1Ev +__ZN3WTF3MD58addBytesEPKhm +__ZN3WTF3MD58checksumERNS_6VectorIhLm16EEE +__ZN3WTFL12MD5TransformEPjPKj +__ZN3WTF6String6numberEl +__ZN3JSC4Heap17globalObjectCountEv +__ZN3JSC4Heap20protectedObjectCountEv +__ZN3JSC4Heap25protectedObjectTypeCountsEv +__ZN3JSC11TypeCounterclEPNS_6JSCellE +__ZN3WTF9HashTableIPN3JSC6JSCellES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi +__ZN3WTF9HashTableIPKcSt4pairIS2_jENS_18PairFirstExtractorIS4_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSA_IjEEEESB_E6expandEv +__ZNK3JSC6JSCell17isAPIValueWrapperEv +__ZNK3JSC6JSCell22isPropertyNameIteratorEv +__ZN3JSC4Heap16objectTypeCountsEv +__ZN3WTF9HashTableIPN3JSC6JSCellES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_ +__ZN3WTF20fastMallocStatisticsEv +__ZN3JSC22globalMemoryStatisticsEv +__ZN3JSC12RegisterFile18committedByteCountEv +__ZN3JSC19ExecutableAllocator18committedByteCountEv +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC14OffsetLocationEENS_18PairFirstExtractorIS7_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSC_IS6_EEEESD_E4findIPS2_NS_29RefPtrHashMapRawKeyTranslatorISI_S7_SF_SA_EEEENS_17HashTableIteratorIS3_S7_S9_SA_SF_SD_EERKT_ +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC14OffsetLocationEENS_18PairFirstExtractorIS7_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSC_IS6_EEEESD_E4findIS3_NS_22IdentityHashTranslatorIS3_S7_SA_EEEENS_17HashTableIteratorIS3_S7_S9_SA_SF_SD_EERKT_ +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC14OffsetLocationEENS_18PairFirstExtractorIS7_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSC_IS6_EEEESD_E6expandEv +__ZN3WTF9HashTableINS_6RefPtrINS_10StringImplEEESt4pairIS3_N3JSC14OffsetLocationEENS_18PairFirstExtractorIS7_EENS_10StringHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSC_IS6_EEEESD_EC2ERKSG_ +__ZN3JSC9Arguments11fillArgListEPNS_9ExecStateERNS_20MarkedArgumentBufferE +__ZN3WTF6VectorIiLm8EE14expandCapacityEm +__ZN3WTF6VectorIN3JSC10ASTBuilder14AssignmentInfoELm10EE14expandCapacityEm +_cti_op_put_by_id_direct_generic +__ZN3WTF9HashTableIPN3JSC16FunctionBodyNodeESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E4findIS3_NS_22IdentityHashTranslatorIS3_S5_S9_EEEENS_17HashTableIteratorIS3_S5_S7_S9_SE_SC_EERKT_ +__ZN3WTF9HashTableIPN3JSC16FunctionBodyNodeESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6expandEv diff --git a/JavaScriptCore.pri b/JavaScriptCore.pri index ed4cf2e..4a8ecd4 100644 --- a/JavaScriptCore.pri +++ b/JavaScriptCore.pri @@ -1,110 +1,47 @@ -# JavaScriptCore - Qt4 build info - -include(../common.pri) - -VPATH += $$PWD - -# Use a config-specific target to prevent parallel builds file clashes on Mac -mac: CONFIG(debug, debug|release): JAVASCRIPTCORE_TARGET = jscored -else: JAVASCRIPTCORE_TARGET = jscore - -# Output in JavaScriptCore/ -CONFIG(debug, debug|release) : JAVASCRIPTCORE_DESTDIR = debug -else: JAVASCRIPTCORE_DESTDIR = release - -CONFIG(standalone_package) { - isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = $$PWD/generated -} else { - isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = $$OUTPUT_DIR/JavaScriptCore/generated -} - -JAVASCRIPTCORE_INCLUDEPATH = \ - $$PWD \ - $$PWD/.. \ - $$PWD/../ThirdParty \ - $$PWD/assembler \ - $$PWD/bytecode \ - $$PWD/bytecompiler \ - $$PWD/heap \ - $$PWD/dfg \ - $$PWD/debugger \ - $$PWD/interpreter \ - $$PWD/jit \ - $$PWD/parser \ - $$PWD/profiler \ - $$PWD/runtime \ - $$PWD/wtf \ - $$PWD/wtf/gobject \ - $$PWD/wtf/symbian \ - $$PWD/wtf/unicode \ - $$PWD/yarr \ - $$PWD/API \ - $$PWD/ForwardingHeaders \ - $$JSC_GENERATED_SOURCES_DIR - -symbian { - PREPEND_INCLUDEPATH = $$JAVASCRIPTCORE_INCLUDEPATH $$PREPEND_INCLUDEPATH -} else { - INCLUDEPATH = $$JAVASCRIPTCORE_INCLUDEPATH $$INCLUDEPATH -} - -symbian { - LIBS += -lhal - INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE -} - -win32-*: DEFINES += _HAS_TR1=0 - -DEFINES += BUILDING_JavaScriptCore BUILDING_WTF - -# CONFIG += text_breaking_with_icu - -contains (CONFIG, text_breaking_with_icu) { - DEFINES += WTF_USE_QT_ICU_TEXT_BREAKING=1 +# ------------------------------------------------------------------- +# This file contains shared rules used both when building +# JavaScriptCore itself, and by targets that use JavaScriptCore. +# +# See 'Tools/qmake/README' for an overview of the build system +# ------------------------------------------------------------------- + +SOURCE_DIR = $${ROOT_WEBKIT_DIR}/Source/JavaScriptCore + +JAVASCRIPTCORE_GENERATED_SOURCES_DIR = $${ROOT_BUILD_DIR}/Source/JavaScriptCore/$${GENERATED_SOURCES_DESTDIR} + +INCLUDEPATH += \ + $$SOURCE_DIR \ + $$SOURCE_DIR/.. \ + $$SOURCE_DIR/../WTF \ + $$SOURCE_DIR/assembler \ + $$SOURCE_DIR/bytecode \ + $$SOURCE_DIR/bytecompiler \ + $$SOURCE_DIR/heap \ + $$SOURCE_DIR/dfg \ + $$SOURCE_DIR/debugger \ + $$SOURCE_DIR/interpreter \ + $$SOURCE_DIR/jit \ + $$SOURCE_DIR/llint \ + $$SOURCE_DIR/parser \ + $$SOURCE_DIR/profiler \ + $$SOURCE_DIR/runtime \ + $$SOURCE_DIR/tools \ + $$SOURCE_DIR/yarr \ + $$SOURCE_DIR/API \ + $$SOURCE_DIR/ForwardingHeaders \ + $$JAVASCRIPTCORE_GENERATED_SOURCES_DIR + +win32-* { + LIBS += -lwinmm + + win32-g++* { + LIBS += -lpthreadGC2 + } else:win32-msvc* { + LIBS += -lpthreadVC2 + } } wince* { INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/ce-compat - INCLUDEPATH += $$PWD/../JavaScriptCore/os-win32 + INCLUDEPATH += $$SOURCE_DIR/os-win32 } - - -defineTest(prependJavaScriptCoreLib) { - # Argument is the relative path to JavaScriptCore.pro's qmake output - pathToJavaScriptCoreOutput = $$ARGS/$$JAVASCRIPTCORE_DESTDIR - - win32-msvc*|wince* { - LIBS = -l$$JAVASCRIPTCORE_TARGET $$LIBS - LIBS = -L$$pathToJavaScriptCoreOutput $$LIBS - POST_TARGETDEPS += $${pathToJavaScriptCoreOutput}$${QMAKE_DIR_SEP}$${JAVASCRIPTCORE_TARGET}.lib - } else:symbian { - LIBS = -l$${JAVASCRIPTCORE_TARGET}.lib $$LIBS - # The default symbian build system does not use library paths at all. However when building with - # qmake's symbian makespec that uses Makefiles - QMAKE_LIBDIR += $$pathToJavaScriptCoreOutput - POST_TARGETDEPS += $${pathToJavaScriptCoreOutput}$${QMAKE_DIR_SEP}$${JAVASCRIPTCORE_TARGET}.lib - } else { - # Make sure jscore will be early in the list of libraries to workaround a bug in MinGW - # that can't resolve symbols from QtCore if libjscore comes after. - QMAKE_LIBDIR = $$pathToJavaScriptCoreOutput $$QMAKE_LIBDIR - LIBS = -l$$JAVASCRIPTCORE_TARGET $$LIBS - POST_TARGETDEPS += $${pathToJavaScriptCoreOutput}$${QMAKE_DIR_SEP}lib$${JAVASCRIPTCORE_TARGET}.a - } - - win32-* { - LIBS += -lwinmm - } - - # The following line is to prevent qmake from adding jscore to libQtWebKit's prl dependencies. - # The compromise we have to accept by disabling explicitlib is to drop support to link QtWebKit and QtScript - # statically in applications (which isn't used often because, among other things, of licensing obstacles). - CONFIG -= explicitlib - - export(QMAKE_LIBDIR) - export(LIBS) - export(POST_TARGETDEPS) - export(CONFIG) - - return(true) -} - diff --git a/JavaScriptCore.pro b/JavaScriptCore.pro index 3e0caf8..393728f 100644 --- a/JavaScriptCore.pro +++ b/JavaScriptCore.pro @@ -1,224 +1,19 @@ -# JavaScriptCore - qmake build info -CONFIG += building-libs -include($$PWD/../WebKit.pri) -include(JavaScriptCore.pri) +# ------------------------------------------------------------------- +# Main project file for JavaScriptSource +# +# See 'Tools/qmake/README' for an overview of the build system +# ------------------------------------------------------------------- -TEMPLATE = lib -CONFIG += staticlib -# Don't use JavaScriptCore as the target name. qmake would create a JavaScriptCore.vcproj for msvc -# which already exists as a directory -TARGET = $$JAVASCRIPTCORE_TARGET -DESTDIR = $$JAVASCRIPTCORE_DESTDIR -QT += core -QT -= gui +TEMPLATE = subdirs +CONFIG += ordered -CONFIG += depend_includepath +derived_sources.file = DerivedSources.pri +target.file = Target.pri -contains(QT_CONFIG, embedded):CONFIG += embedded +SUBDIRS += derived_sources target -# WebCore adds these config only when in a standalone build. -# qbase.pri takes care of that when in a QTDIR_build -# Here we add the config for both cases since we don't include qbase.pri -contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols -unix:contains(QT_CONFIG, reduce_relocations):CONFIG += bsymbolic_functions - -CONFIG(QTDIR_build) { - # Remove the following 2 lines if you want debug information in JavaScriptCore - CONFIG -= separate_debug_info - CONFIG += no_debug_info -} - -*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2 -*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3 - -# 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) { - QMAKE_CXXFLAGS += -fno-stack-protector - QMAKE_CFLAGS += -fno-stack-protector - } -} - -wince* { - SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.c -} - -include(yarr/yarr.pri) -include(wtf/wtf.pri) - -INSTALLDEPS += all - -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 \ - assembler/ARMAssembler.cpp \ - assembler/ARMv7Assembler.cpp \ - assembler/MacroAssemblerARM.cpp \ - assembler/MacroAssemblerSH4.h \ - assembler/MacroAssemblerSH4.cpp \ - assembler/SH4Assembler.h \ - bytecode/CodeBlock.cpp \ - bytecode/JumpTable.cpp \ - bytecode/Opcode.cpp \ - bytecode/SamplingTool.cpp \ - bytecode/StructureStubInfo.cpp \ - bytecompiler/BytecodeGenerator.cpp \ - bytecompiler/NodesCodegen.cpp \ - heap/ConservativeRoots.cpp \ - heap/HandleHeap.cpp \ - heap/HandleStack.cpp \ - heap/Heap.cpp \ - heap/MachineStackMarker.cpp \ - heap/MarkStack.cpp \ - heap/MarkStackPosix.cpp \ - heap/MarkStackSymbian.cpp \ - heap/MarkStackWin.cpp \ - heap/MarkedBlock.cpp \ - heap/MarkedSpace.cpp \ - debugger/DebuggerActivation.cpp \ - debugger/DebuggerCallFrame.cpp \ - debugger/Debugger.cpp \ - dfg/DFGByteCodeParser.cpp \ - dfg/DFGGraph.cpp \ - dfg/DFGJITCodeGenerator.cpp \ - dfg/DFGJITCompiler.cpp \ - dfg/DFGNonSpeculativeJIT.cpp \ - dfg/DFGOperations.cpp \ - dfg/DFGSpeculativeJIT.cpp \ - interpreter/CallFrame.cpp \ - interpreter/Interpreter.cpp \ - interpreter/RegisterFile.cpp \ - jit/ExecutableAllocatorFixedVMPool.cpp \ - jit/ExecutableAllocator.cpp \ - jit/JITArithmetic.cpp \ - jit/JITArithmetic32_64.cpp \ - jit/JITCall.cpp \ - jit/JITCall32_64.cpp \ - jit/JIT.cpp \ - jit/JITOpcodes.cpp \ - jit/JITOpcodes32_64.cpp \ - jit/JITPropertyAccess.cpp \ - jit/JITPropertyAccess32_64.cpp \ - jit/JITStubs.cpp \ - jit/ThunkGenerators.cpp \ - parser/JSParser.cpp \ - parser/Lexer.cpp \ - parser/Nodes.cpp \ - parser/ParserArena.cpp \ - parser/Parser.cpp \ - parser/SourceProviderCache.cpp \ - profiler/Profile.cpp \ - profiler/ProfileGenerator.cpp \ - profiler/ProfileNode.cpp \ - profiler/Profiler.cpp \ - 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/CommonIdentifiers.cpp \ - runtime/Completion.cpp \ - runtime/ConstructData.cpp \ - runtime/DateConstructor.cpp \ - runtime/DateConversion.cpp \ - runtime/DateInstance.cpp \ - runtime/DatePrototype.cpp \ - runtime/ErrorConstructor.cpp \ - runtime/Error.cpp \ - runtime/ErrorInstance.cpp \ - runtime/ErrorPrototype.cpp \ - runtime/ExceptionHelpers.cpp \ - runtime/Executable.cpp \ - runtime/FunctionConstructor.cpp \ - runtime/FunctionPrototype.cpp \ - runtime/GCActivityCallback.cpp \ - runtime/GetterSetter.cpp \ - runtime/Identifier.cpp \ - runtime/InitializeThreading.cpp \ - runtime/InternalFunction.cpp \ - runtime/JSActivation.cpp \ - runtime/JSAPIValueWrapper.cpp \ - runtime/JSArray.cpp \ - runtime/JSByteArray.cpp \ - runtime/JSCell.cpp \ - runtime/JSFunction.cpp \ - runtime/JSGlobalData.cpp \ - runtime/JSGlobalObject.cpp \ - runtime/JSGlobalObjectFunctions.cpp \ - runtime/JSLock.cpp \ - runtime/JSNotAnObject.cpp \ - runtime/JSObject.cpp \ - runtime/JSObjectWithGlobalObject.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/RegExpConstructor.cpp \ - runtime/RegExp.cpp \ - runtime/RegExpObject.cpp \ - runtime/RegExpPrototype.cpp \ - runtime/RegExpCache.cpp \ - runtime/RopeImpl.cpp \ - runtime/ScopeChain.cpp \ - runtime/SmallStrings.cpp \ - runtime/StrictEvalActivation.cpp \ - runtime/StringConstructor.cpp \ - runtime/StringObject.cpp \ - runtime/StringPrototype.cpp \ - runtime/StringRecursionChecker.cpp \ - runtime/StructureChain.cpp \ - runtime/Structure.cpp \ - runtime/TimeoutChecker.cpp \ - runtime/UString.cpp \ - yarr/YarrJIT.cpp \ - -*sh4* { - QMAKE_CXXFLAGS += -mieee -w - QMAKE_CFLAGS += -mieee -w -} - -# Generated files, simply list them for JavaScriptCore - -symbian: { - symbian-abld|symbian-sbsv2 { - MMP_RULES += ALWAYS_BUILD_AS_ARM - } else { - QMAKE_CFLAGS -= --thumb - QMAKE_CXXFLAGS -= --thumb - } - QMAKE_CXXFLAGS.ARMCC += -OTime -O3 -} - -lessThan(QT_GCC_MAJOR_VERSION, 5):lessThan(QT_GCC_MINOR_VERSION, 6) { - # Disable C++0x mode in JSC for those who enabled it in their Qt's mkspec. - *-g++*:QMAKE_CXXFLAGS -= -std=c++0x -std=gnu++0x -} +addStrictSubdirOrderBetween(derived_sources, target) +jsc.file = jsc.pro +jsc.makefile = Makefile.jsc +SUBDIRS += jsc diff --git a/KeywordLookupGenerator.py b/KeywordLookupGenerator.py index 6ba7e34..748acf9 100644 --- a/KeywordLookupGenerator.py +++ b/KeywordLookupGenerator.py @@ -1,4 +1,5 @@ -# Copyright (C) 2010 Apple Inc. All rights reserved. +# Copyright (C) 2011 Apple Inc. All rights reserved. +# Copyright (C) 2012 Sony Network Entertainment. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -27,6 +28,15 @@ import operator keywordsText = open(sys.argv[1]).read() +# A second argument signifies that the output +# should be redirected to a file +redirect_to_file = len(sys.argv) > 2 + +# Change stdout to point to the file if requested +if redirect_to_file: + file_output = open(sys.argv[-1], "w") + sys.stdout = file_output + # Observed weights of the most common keywords, rounded to 2.s.d keyWordWeights = { "catch": 0.01, @@ -103,11 +113,12 @@ class Trie: return self if len(self.keys) != 1: return self - (prefix, suffix) = self.keys.items()[0] - res = Trie(self.prefix + prefix) - res.value = suffix.value - res.keys = suffix.keys - return res + # Python 3: for() loop for compatibility. Use next() when Python 2.6 is the baseline. + for (prefix, suffix) in self.keys.items(): + res = Trie(self.prefix + prefix) + res.value = suffix.value + res.keys = suffix.keys + return res def fillOut(self, prefix=""): self.fullPrefix = prefix + self.prefix @@ -121,12 +132,12 @@ class Trie: self.keys = [(trie.prefix, trie) for trie in sorted(self.keys.values(), key=operator.attrgetter('weight'), reverse=True)] self.weight = weight - def printSubTreeAsC(self, indent): + def printSubTreeAsC(self, typeName, indent): str = makePadding(indent) if self.value != None: print(str + "if (!isIdentPart(code[%d])) {" % (len(self.fullPrefix))) - print(str + " internalShift<%d, DoNotBoundsCheck>();" % len(self.fullPrefix)) + print(str + " internalShift<%d>();" % len(self.fullPrefix)) print(str + " if (shouldCreateIdentifier)") print(str + (" data->ident = &m_globalData->propertyNames->%sKeyword;" % self.fullPrefix)) print(str + " return " + self.value + ";") @@ -145,15 +156,17 @@ class Trie: base = "code" if baseIndex > 0: base = "code + %d" % baseIndex - comparison = ("COMPARE_CHARACTERS%d(%s, " % (len(test), base)) + ", ".join(test) + ")" + comparison = ("COMPARE_%d%sS(%s, " % (len(test), typeName, base)) + ", ".join(test) + ")" if itemCount == 0: print(str + "if (" + comparison + ") {") else: - print(str + "else if (" + comparison + ") {") + print(str + "} else if (" + comparison + ") {") - trie.printSubTreeAsC(indent + 4) + trie.printSubTreeAsC(typeName, indent + 4) itemCount = itemCount + 1 - print(str + "}") + + if itemCount == len(self.keys): + print(str + "}") def maxLength(self): max = len(self.fullPrefix) @@ -165,16 +178,33 @@ class Trie: def printAsC(self): print("namespace JSC {") - print("static ALWAYS_INLINE bool isIdentPart(int c);") + print("") + print("static ALWAYS_INLINE bool isIdentPart(LChar c);") + print("static ALWAYS_INLINE bool isIdentPart(UChar c);") # max length + 1 so we don't need to do any bounds checking at all print("static const int maxTokenLength = %d;" % (self.maxLength() + 1)) - print("template ALWAYS_INLINE JSTokenType Lexer::parseKeyword(JSTokenData* data) {") + print("") + print("template <>") + print("template ALWAYS_INLINE JSTokenType Lexer::parseKeyword(JSTokenData* data)") + print("{") print(" ASSERT(m_codeEnd - m_code >= maxTokenLength);") + print("") print(" const UChar* code = m_code;") - self.printSubTreeAsC(4) + self.printSubTreeAsC("UCHAR", 4) print(" return IDENT;") print("}") + print("") + print("template <>") + print("template ALWAYS_INLINE JSTokenType Lexer::parseKeyword(JSTokenData* data)") + print("{") + print(" ASSERT(m_codeEnd - m_code >= maxTokenLength);") + print("") + print(" const LChar* code = m_code;") + self.printSubTreeAsC("CHAR", 4) + print(" return IDENT;") print("}") + print("") + print("} // namespace JSC") keywords = parseKeywords(keywordsText) trie = Trie("") @@ -184,47 +214,92 @@ trie.coalesce() trie.fillOut() print("// This file was generated by KeywordLookupGenerator.py. Do not edit.") print(""" - #if CPU(NEEDS_ALIGNED_ACCESS) -#define COMPARE_CHARACTERS2(address, char1, char2) \ +#define COMPARE_2CHARS(address, char1, char2) \\ + (((address)[0] == char1) && ((address)[1] == char2)) +#define COMPARE_4CHARS(address, char1, char2, char3, char4) \\ + (COMPARE_2CHARS(address, char1, char2) && COMPARE_2CHARS((address) + 2, char3, char4)) +#define COMPARE_2UCHARS(address, char1, char2) \\ (((address)[0] == char1) && ((address)[1] == char2)) -#define COMPARE_CHARACTERS4(address, char1, char2, char3, char4) \ - (COMPARE_CHARACTERS2(address, char1, char2) && COMPARE_CHARACTERS2((address) + 2, char3, char4)) +#define COMPARE_4UCHARS(address, char1, char2, char3, char4) \\ + (COMPARE_2UCHARS(address, char1, char2) && COMPARE_2UCHARS((address) + 2, char3, char4)) -#else +#else // CPU(NEEDS_ALIGNED_ACCESS) #if CPU(BIG_ENDIAN) -#define CHARPAIR_TOUINT32(a, b) ((((uint32_t)(a)) << 16) + (uint32_t)(b)) -#define CHARQUAD_TOUINT64(a, b, c, d) ((((uint64_t)(CHARPAIR_TOUINT32(a, b))) << 32) + CHARPAIR_TOUINT32(c, d)) -#else -#define CHARPAIR_TOUINT32(a, b) ((((uint32_t)(b)) << 16) + (uint32_t)(a)) -#define CHARQUAD_TOUINT64(a, b, c, d) ((((uint64_t)(CHARPAIR_TOUINT32(c, d))) << 32) + CHARPAIR_TOUINT32(a, b)) -#endif - -#define COMPARE_CHARACTERS2(address, char1, char2) \ - (((uint32_t*)(address))[0] == CHARPAIR_TOUINT32(char1, char2)) + +#define CHARPAIR_TOUINT16(a, b) \\ + ((((uint16_t)(a)) << 8) + (uint16_t)(b)) +#define CHARQUAD_TOUINT32(a, b, c, d) \\ + ((((uint32_t)(CHARPAIR_TOUINT16(a, b))) << 16) + CHARPAIR_TOUINT16(c, d)) +#define UCHARPAIR_TOUINT32(a, b) \\ + ((((uint32_t)(a)) << 16) + (uint32_t)(b)) +#define UCHARQUAD_TOUINT64(a, b, c, d) \\ + ((((uint64_t)(UCHARQUAD_TOUINT64(a, b))) << 32) + UCHARPAIR_TOUINT32(c, d)) + +#else // CPU(BIG_ENDIAN) + +#define CHARPAIR_TOUINT16(a, b) \\ + ((((uint16_t)(b)) << 8) + (uint16_t)(a)) +#define CHARQUAD_TOUINT32(a, b, c, d) \\ + ((((uint32_t)(CHARPAIR_TOUINT16(c, d))) << 16) + CHARPAIR_TOUINT16(a, b)) +#define UCHARPAIR_TOUINT32(a, b) \\ + ((((uint32_t)(b)) << 16) + (uint32_t)(a)) +#define UCHARQUAD_TOUINT64(a, b, c, d) \\ + ((((uint64_t)(UCHARPAIR_TOUINT32(c, d))) << 32) + UCHARPAIR_TOUINT32(a, b)) + +#endif // CPU(BIG_ENDIAN) + + +#define COMPARE_2CHARS(address, char1, char2) \\ + (((uint16_t*)(address))[0] == CHARPAIR_TOUINT16(char1, char2)) +#define COMPARE_2UCHARS(address, char1, char2) \\ + (((uint32_t*)(address))[0] == UCHARPAIR_TOUINT32(char1, char2)) + #if CPU(X86_64) -#define COMPARE_CHARACTERS4(address, char1, char2, char3, char4) \ - (((uint64_t*)(address))[0] == CHARQUAD_TOUINT64(char1, char2, char3, char4)) -#else -#define COMPARE_CHARACTERS4(address, char1, char2, char3, char4) \ - (COMPARE_CHARACTERS2(address, char1, char2) && COMPARE_CHARACTERS2((address) + 2, char3, char4)) -#endif - -#endif - -#define COMPARE_CHARACTERS3(address, char1, char2, char3) \ - (COMPARE_CHARACTERS2(address, char1, char2) && ((address)[2] == (char3))) -#define COMPARE_CHARACTERS5(address, char1, char2, char3, char4, char5) \ - (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && ((address)[4] == (char5))) -#define COMPARE_CHARACTERS6(address, char1, char2, char3, char4, char5, char6) \ - (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && COMPARE_CHARACTERS2(address + 4, char5, char6)) -#define COMPARE_CHARACTERS7(address, char1, char2, char3, char4, char5, char6, char7) \ - (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && COMPARE_CHARACTERS4(address + 3, char4, char5, char6, char7)) -#define COMPARE_CHARACTERS8(address, char1, char2, char3, char4, char5, char6, char7, char8) \ - (COMPARE_CHARACTERS4(address, char1, char2, char3, char4) && COMPARE_CHARACTERS4(address + 4, char5, char6, char7, char8)) +#define COMPARE_4CHARS(address, char1, char2, char3, char4) \\ + (((uint32_t*)(address))[0] == CHARQUAD_TOUINT32(char1, char2, char3, char4)) +#define COMPARE_4UCHARS(address, char1, char2, char3, char4) \\ + (((uint64_t*)(address))[0] == UCHARQUAD_TOUINT64(char1, char2, char3, char4)) + +#else // CPU(X86_64) + +#define COMPARE_4CHARS(address, char1, char2, char3, char4) \\ + (COMPARE_2CHARS(address, char1, char2) && COMPARE_2CHARS((address) + 2, char3, char4)) +#define COMPARE_4UCHARS(address, char1, char2, char3, char4) \\ + (COMPARE_2UCHARS(address, char1, char2) && COMPARE_2UCHARS((address) + 2, char3, char4)) + +#endif // CPU(X86_64) + +#endif // CPU(NEEDS_ALIGNED_ACCESS) + +#define COMPARE_3CHARS(address, char1, char2, char3) \\ + (COMPARE_2CHARS(address, char1, char2) && ((address)[2] == (char3))) +#define COMPARE_3UCHARS(address, char1, char2, char3) \\ + (COMPARE_2UCHARS(address, char1, char2) && ((address)[2] == (char3))) +#define COMPARE_5CHARS(address, char1, char2, char3, char4, char5) \\ + (COMPARE_4CHARS(address, char1, char2, char3, char4) && ((address)[4] == (char5))) +#define COMPARE_5UCHARS(address, char1, char2, char3, char4, char5) \\ + (COMPARE_4UCHARS(address, char1, char2, char3, char4) && ((address)[4] == (char5))) +#define COMPARE_6CHARS(address, char1, char2, char3, char4, char5, char6) \\ + (COMPARE_4CHARS(address, char1, char2, char3, char4) && COMPARE_2CHARS(address + 4, char5, char6)) +#define COMPARE_6UCHARS(address, char1, char2, char3, char4, char5, char6) \\ + (COMPARE_4UCHARS(address, char1, char2, char3, char4) && COMPARE_2UCHARS(address + 4, char5, char6)) +#define COMPARE_7CHARS(address, char1, char2, char3, char4, char5, char6, char7) \\ + (COMPARE_4CHARS(address, char1, char2, char3, char4) && COMPARE_4CHARS(address + 3, char4, char5, char6, char7)) +#define COMPARE_7UCHARS(address, char1, char2, char3, char4, char5, char6, char7) \\ + (COMPARE_4UCHARS(address, char1, char2, char3, char4) && COMPARE_4UCHARS(address + 3, char4, char5, char6, char7)) +#define COMPARE_8CHARS(address, char1, char2, char3, char4, char5, char6, char7, char8) \\ + (COMPARE_4CHARS(address, char1, char2, char3, char4) && COMPARE_4CHARS(address + 4, char5, char6, char7, char8)) +#define COMPARE_8UCHARS(address, char1, char2, char3, char4, char5, char6, char7, char8) \\ + (COMPARE_4UCHARS(address, char1, char2, char3, char4) && COMPARE_4UCHARS(address + 4, char5, char6, char7, char8)) """) trie.printAsC() + +# Close the redirected file if requested +if (redirect_to_file): + file_output.close() + sys.stdout = sys.__stdout__ diff --git a/PlatformBlackBerry.cmake b/PlatformBlackBerry.cmake new file mode 100644 index 0000000..abfae85 --- /dev/null +++ b/PlatformBlackBerry.cmake @@ -0,0 +1,5 @@ +LIST(INSERT JavaScriptCore_INCLUDE_DIRECTORIES 0 + "${BLACKBERRY_THIRD_PARTY_DIR}/icu" +) + +INSTALL(FILES "wtf/Forward.h" DESTINATION usr/include/browser/webkit/wtf) diff --git a/PlatformEfl.cmake b/PlatformEfl.cmake new file mode 100644 index 0000000..448834c --- /dev/null +++ b/PlatformEfl.cmake @@ -0,0 +1,22 @@ +LIST(APPEND JavaScriptCore_SOURCES + jit/ExecutableAllocatorFixedVMPool.cpp + jit/ExecutableAllocator.cpp +) + +LIST(APPEND JavaScriptCore_LIBRARIES + ${ICU_I18N_LIBRARIES} +) + +LIST(APPEND JavaScriptCore_INCLUDE_DIRECTORIES + ${ICU_INCLUDE_DIRS} +) + +IF (ENABLE_GLIB_SUPPORT) + LIST(APPEND JavaScriptCore_INCLUDE_DIRECTORIES + ${JAVASCRIPTCORE_DIR}/wtf/gobject + ) +ENDIF () + +LIST(APPEND JavaScriptCore_LINK_FLAGS + ${ECORE_LDFLAGS} +) diff --git a/PlatformWinCE.cmake b/PlatformWinCE.cmake new file mode 100644 index 0000000..e1a43ff --- /dev/null +++ b/PlatformWinCE.cmake @@ -0,0 +1,20 @@ +LIST(APPEND JavaScriptCore_SOURCES + jit/ExecutableAllocator.cpp +) + +IF (ENABLE_JIT AND WTF_CPU_ARM) + ADD_CUSTOM_COMMAND( + OUTPUT ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm + MAIN_DEPENDENCY ${JAVASCRIPTCORE_DIR}/create_jit_stubs + DEPENDS ${JAVASCRIPTCORE_DIR}/jit/JITStubs.cpp + COMMAND ${PERL_EXECUTABLE} ${JAVASCRIPTCORE_DIR}/create_jit_stubs --prefix=MSVC ${JAVASCRIPTCORE_DIR}/jit/JITStubs.cpp > ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm + VERBATIM) + + ADD_CUSTOM_COMMAND( + OUTPUT ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj + MAIN_DEPENDENCY ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm + COMMAND armasm -nologo ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.asm ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj + VERBATIM) + + LIST (APPEND JavaScriptCore_SOURCES ${DERIVED_SOURCES_DIR}/GeneratedJITStubs.obj) +ENDIF () diff --git a/Target.pri b/Target.pri new file mode 100644 index 0000000..017f316 --- /dev/null +++ b/Target.pri @@ -0,0 +1,256 @@ +# ------------------------------------------------------------------- +# Target file for the JavaScriptSource library +# +# See 'Tools/qmake/README' for an overview of the build system +# ------------------------------------------------------------------- + +TEMPLATE = lib +TARGET = JavaScriptCore + +include(JavaScriptCore.pri) + +WEBKIT += wtf +QT += core +QT -= gui + +CONFIG += staticlib + +*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2 +*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3 + +# 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) { + QMAKE_CXXFLAGS += -fno-stack-protector + QMAKE_CFLAGS += -fno-stack-protector + } +} + +wince* { + SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.c +} + +include(yarr/yarr.pri) + +INSTALLDEPS += all + +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 \ + assembler/ARMAssembler.cpp \ + assembler/ARMv7Assembler.cpp \ + assembler/MacroAssemblerARM.cpp \ + assembler/MacroAssemblerSH4.cpp \ + bytecode/CallLinkInfo.cpp \ + bytecode/CallLinkStatus.cpp \ + bytecode/CodeBlock.cpp \ + bytecode/DFGExitProfile.cpp \ + bytecode/ExecutionCounter.cpp \ + bytecode/GetByIdStatus.cpp \ + bytecode/JumpTable.cpp \ + bytecode/LazyOperandValueProfile.cpp \ + bytecode/MethodCallLinkInfo.cpp \ + bytecode/MethodCallLinkStatus.cpp \ + bytecode/MethodOfGettingAValueProfile.cpp \ + bytecode/Opcode.cpp \ + bytecode/PolymorphicPutByIdList.cpp \ + bytecode/PredictedType.cpp \ + bytecode/PutByIdStatus.cpp \ + bytecode/SamplingTool.cpp \ + bytecode/StructureStubInfo.cpp \ + bytecompiler/BytecodeGenerator.cpp \ + bytecompiler/NodesCodegen.cpp \ + heap/CopiedSpace.cpp \ + heap/ConservativeRoots.cpp \ + heap/DFGCodeBlocks.cpp \ + heap/WeakSet.cpp \ + heap/WeakHandleOwner.cpp \ + heap/WeakBlock.cpp \ + heap/HandleSet.cpp \ + heap/HandleStack.cpp \ + heap/BlockAllocator.cpp \ + heap/Heap.cpp \ + heap/MachineStackMarker.cpp \ + heap/MarkStack.cpp \ + heap/MarkedAllocator.cpp \ + heap/MarkedBlock.cpp \ + heap/MarkedSpace.cpp \ + heap/VTableSpectrum.cpp \ + heap/WriteBarrierSupport.cpp \ + debugger/DebuggerActivation.cpp \ + debugger/DebuggerCallFrame.cpp \ + debugger/Debugger.cpp \ + dfg/DFGAbstractState.cpp \ + dfg/DFGAssemblyHelpers.cpp \ + dfg/DFGByteCodeParser.cpp \ + dfg/DFGCapabilities.cpp \ + dfg/DFGCFAPhase.cpp \ + dfg/DFGCorrectableJumpPoint.cpp \ + dfg/DFGCSEPhase.cpp \ + dfg/DFGDriver.cpp \ + dfg/DFGFixupPhase.cpp \ + dfg/DFGGraph.cpp \ + dfg/DFGJITCompiler.cpp \ + dfg/DFGNodeFlags.cpp \ + dfg/DFGOperations.cpp \ + dfg/DFGOSREntry.cpp \ + dfg/DFGOSRExit.cpp \ + dfg/DFGOSRExitCompiler.cpp \ + dfg/DFGOSRExitCompiler64.cpp \ + dfg/DFGOSRExitCompiler32_64.cpp \ + dfg/DFGPhase.cpp \ + dfg/DFGPredictionPropagationPhase.cpp \ + dfg/DFGRedundantPhiEliminationPhase.cpp \ + dfg/DFGRepatch.cpp \ + dfg/DFGSpeculativeJIT.cpp \ + dfg/DFGSpeculativeJIT32_64.cpp \ + dfg/DFGSpeculativeJIT64.cpp \ + dfg/DFGThunks.cpp \ + dfg/DFGVirtualRegisterAllocationPhase.cpp \ + interpreter/AbstractPC.cpp \ + interpreter/CallFrame.cpp \ + interpreter/Interpreter.cpp \ + interpreter/RegisterFile.cpp \ + jit/ExecutableAllocatorFixedVMPool.cpp \ + jit/ExecutableAllocator.cpp \ + jit/HostCallReturnValue.cpp \ + jit/JITArithmetic.cpp \ + jit/JITArithmetic32_64.cpp \ + jit/JITCall.cpp \ + jit/JITCall32_64.cpp \ + jit/JIT.cpp \ + jit/JITExceptions.cpp \ + jit/JITOpcodes.cpp \ + jit/JITOpcodes32_64.cpp \ + jit/JITPropertyAccess.cpp \ + jit/JITPropertyAccess32_64.cpp \ + jit/JITStubs.cpp \ + jit/ThunkGenerators.cpp \ + parser/Lexer.cpp \ + parser/Nodes.cpp \ + parser/ParserArena.cpp \ + parser/Parser.cpp \ + parser/SourceProviderCache.cpp \ + profiler/Profile.cpp \ + profiler/ProfileGenerator.cpp \ + profiler/ProfileNode.cpp \ + profiler/Profiler.cpp \ + 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/CommonIdentifiers.cpp \ + runtime/Completion.cpp \ + runtime/ConstructData.cpp \ + runtime/DateConstructor.cpp \ + runtime/DateConversion.cpp \ + runtime/DateInstance.cpp \ + runtime/DatePrototype.cpp \ + runtime/ErrorConstructor.cpp \ + runtime/Error.cpp \ + runtime/ErrorInstance.cpp \ + runtime/ErrorPrototype.cpp \ + runtime/ExceptionHelpers.cpp \ + runtime/Executable.cpp \ + runtime/FunctionConstructor.cpp \ + runtime/FunctionPrototype.cpp \ + runtime/GCActivityCallback.cpp \ + runtime/GetterSetter.cpp \ + runtime/Options.cpp \ + runtime/Identifier.cpp \ + runtime/InitializeThreading.cpp \ + runtime/InternalFunction.cpp \ + runtime/JSActivation.cpp \ + runtime/JSAPIValueWrapper.cpp \ + runtime/JSArray.cpp \ + runtime/JSCell.cpp \ + runtime/JSDateMath.cpp \ + runtime/JSFunction.cpp \ + runtime/JSBoundFunction.cpp \ + runtime/JSGlobalData.cpp \ + runtime/JSGlobalObject.cpp \ + runtime/JSGlobalObjectFunctions.cpp \ + runtime/JSGlobalThis.cpp \ + runtime/JSLock.cpp \ + runtime/JSNotAnObject.cpp \ + runtime/JSObject.cpp \ + runtime/JSONObject.cpp \ + runtime/JSPropertyNameIterator.cpp \ + runtime/JSStaticScopeObject.cpp \ + runtime/JSString.cpp \ + runtime/JSStringJoiner.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/RegExpConstructor.cpp \ + runtime/RegExpCachedResult.cpp \ + runtime/RegExpMatchesArray.cpp \ + runtime/RegExp.cpp \ + runtime/RegExpObject.cpp \ + runtime/RegExpPrototype.cpp \ + runtime/RegExpCache.cpp \ + runtime/SamplingCounter.cpp \ + runtime/ScopeChain.cpp \ + runtime/SmallStrings.cpp \ + runtime/StrictEvalActivation.cpp \ + runtime/StringConstructor.cpp \ + runtime/StringObject.cpp \ + runtime/StringPrototype.cpp \ + runtime/StringRecursionChecker.cpp \ + runtime/StructureChain.cpp \ + runtime/Structure.cpp \ + runtime/TimeoutChecker.cpp \ + runtime/UString.cpp \ + tools/CodeProfile.cpp \ + tools/CodeProfiling.cpp \ + yarr/YarrJIT.cpp \ + +*sh4* { + QMAKE_CXXFLAGS += -mieee -w + QMAKE_CFLAGS += -mieee -w +} + +lessThan(QT_GCC_MAJOR_VERSION, 5) { + # GCC 4.5 and before + lessThan(QT_GCC_MINOR_VERSION, 6) { + # Disable C++0x mode in JSC for those who enabled it in their Qt's mkspec. + *-g++*:QMAKE_CXXFLAGS -= -std=c++0x -std=gnu++0x + } + + # GCC 4.6 and after. + greaterThan(QT_GCC_MINOR_VERSION, 5) { + if (!contains(QMAKE_CXXFLAGS, -std=c++0x) && !contains(QMAKE_CXXFLAGS, -std=gnu++0x)) { + # We need to deactivate those warnings because some names conflicts with upcoming c++0x types (e.g.nullptr). + QMAKE_CFLAGS_WARN_ON += -Wno-c++0x-compat + QMAKE_CXXFLAGS_WARN_ON += -Wno-c++0x-compat + QMAKE_CFLAGS += -Wno-c++0x-compat + QMAKE_CXXFLAGS += -Wno-c++0x-compat + } + } +} diff --git a/assembler/ARMAssembler.cpp b/assembler/ARMAssembler.cpp index f86444d..74809ca 100644 --- a/assembler/ARMAssembler.cpp +++ b/assembler/ARMAssembler.cpp @@ -276,45 +276,46 @@ void ARMAssembler::dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID bas dtr_ur(isLoad, srcDst, base, ARMRegisters::S0 | transferFlag); } } else { - offset = -offset; - if (offset <= 0xfff) - dtr_d(isLoad, srcDst, base, offset | transferFlag); - else if (offset <= 0xfffff) { - sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8)); - dtr_d(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff) | transferFlag); + if (offset >= -0xfff) + dtr_d(isLoad, srcDst, base, -offset | transferFlag); + else if (offset >= -0xfffff) { + sub_r(ARMRegisters::S0, base, OP2_IMM | (-offset >> 12) | (10 << 8)); + dtr_d(isLoad, srcDst, ARMRegisters::S0, (-offset & 0xfff) | transferFlag); } else { moveImm(offset, ARMRegisters::S0); - dtr_dr(isLoad, srcDst, base, ARMRegisters::S0 | transferFlag); + dtr_ur(isLoad, srcDst, base, ARMRegisters::S0 | transferFlag); } } } -void ARMAssembler::baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset) +void ARMAssembler::baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset, bool bytes) { ARMWord op2; + ARMWord transferFlag = bytes ? DT_BYTE : 0; ASSERT(scale >= 0 && scale <= 3); op2 = lsl(index, scale); if (offset >= 0 && offset <= 0xfff) { add_r(ARMRegisters::S0, base, op2); - dtr_u(isLoad, srcDst, ARMRegisters::S0, offset); + dtr_u(isLoad, srcDst, ARMRegisters::S0, offset | transferFlag); return; } if (offset <= 0 && offset >= -0xfff) { add_r(ARMRegisters::S0, base, op2); - dtr_d(isLoad, srcDst, ARMRegisters::S0, -offset); + dtr_d(isLoad, srcDst, ARMRegisters::S0, (-offset & 0xfff) | transferFlag); return; } ldr_un_imm(ARMRegisters::S0, offset); add_r(ARMRegisters::S0, ARMRegisters::S0, op2); - dtr_ur(isLoad, srcDst, base, ARMRegisters::S0); + dtr_ur(isLoad, srcDst, base, ARMRegisters::S0 | transferFlag); } void ARMAssembler::doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID base, int32_t offset) { - if (offset & 0x3) { + // VFP cannot directly access memory that is not four-byte-aligned + if (!(offset & 0x3)) { if (offset <= 0x3ff && offset >= 0) { fdtr_u(isLoad, srcDst, base, offset >> 2); return; @@ -343,14 +344,15 @@ void ARMAssembler::doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID b fdtr_u(isLoad, srcDst, ARMRegisters::S0, 0); } -void* ARMAssembler::executableCopy(JSGlobalData& globalData, ExecutablePool* allocator) +PassRefPtr ARMAssembler::executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort) { // 64-bit alignment is required for next constant pool and JIT code as well m_buffer.flushWithoutBarrier(true); if (!m_buffer.isAligned(8)) bkpt(0); - char* data = reinterpret_cast(m_buffer.executableCopy(globalData, allocator)); + RefPtr result = m_buffer.executableCopy(globalData, ownerUID, effort); + char* data = reinterpret_cast(result->start()); for (Jumps::Iterator iter = m_jumps.begin(); iter != m_jumps.end(); ++iter) { // The last bit is set if the constant must be placed on constant pool. @@ -370,9 +372,26 @@ void* ARMAssembler::executableCopy(JSGlobalData& globalData, ExecutablePool* all } } - return data; + return result; } +#if OS(LINUX) && COMPILER(RVCT) + +__asm void ARMAssembler::cacheFlush(void* code, size_t size) +{ + ARM + push {r7} + add r1, r1, r0 + mov r7, #0xf0000 + add r7, r7, #0x2 + mov r2, #0x0 + svc #0x0 + pop {r7} + bx lr +} + +#endif + } // namespace JSC #endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) diff --git a/assembler/ARMAssembler.h b/assembler/ARMAssembler.h index 1a216fe..dc2e557 100644 --- a/assembler/ARMAssembler.h +++ b/assembler/ARMAssembler.h @@ -30,6 +30,7 @@ #if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) #include "AssemblerBufferWithConstantPool.h" +#include "JITCompilationEffort.h" #include namespace JSC { @@ -161,7 +162,6 @@ namespace JSC { VMOV_ARM = 0x0e100a10, VCVT_F64_S32 = 0x0eb80bc0, VCVT_S32_F64 = 0x0ebd0b40, - VCVTR_S32_F64 = 0x0ebd0bc0, VMRS_APSR = 0x0ef1fa10, #if WTF_ARM_ARCH_AT_LEAST(5) CLZ = 0x016f0f10, @@ -173,6 +173,7 @@ namespace JSC { MOVW = 0x03000000, MOVT = 0x03400000, #endif + NOP = 0xe1a00000, }; enum { @@ -545,12 +546,6 @@ namespace JSC { emitDoublePrecisionInst(static_cast(cc) | VCVT_S32_F64, (sd >> 1), 0, dm); } - void vcvtr_s32_f64_r(int sd, int dm, Condition cc = AL) - { - ASSERT(!(sd & 0x1)); // sd must be divisible by 2 - emitDoublePrecisionInst(static_cast(cc) | VCVTR_S32_F64, (sd >> 1), 0, dm); - } - void vmrs_apsr(Condition cc = AL) { m_buffer.putInt(static_cast(cc) | VMRS_APSR); @@ -578,6 +573,11 @@ namespace JSC { m_buffer.putInt(OP_NOP_T2); } + void nop() + { + m_buffer.putInt(NOP); + } + void bx(int rm, Condition cc = AL) { #if WTF_ARM_ARCH_AT_LEAST(5) || defined(__ARM_ARCH_4T__) @@ -686,11 +686,9 @@ namespace JSC { return loadBranchTarget(ARMRegisters::pc, cc, useConstantPool); } - void* executableCopy(JSGlobalData&, ExecutablePool* allocator); + PassRefPtr executableCopy(JSGlobalData&, void* ownerUID, JITCompilationEffort); -#ifndef NDEBUG unsigned debugOffset() { return m_buffer.debugOffset(); } -#endif // Patching helpers @@ -743,8 +741,8 @@ namespace JSC { static void* readPointer(void* from) { ARMWord* insn = reinterpret_cast(from); - void* addr = reinterpret_cast(getLdrImmAddress(insn)); - return *addr; + ARMWord* addr = getLdrImmAddress(insn); + return *reinterpret_cast(addr); } // Patch pointers @@ -802,6 +800,11 @@ namespace JSC { patchPointerInternal(getAbsoluteJumpAddress(from), to); } + static void* readCallTarget(void* from) + { + return reinterpret_cast(readPointer(reinterpret_cast(getAbsoluteJumpAddress(from)))); + } + // Address operations static void* getRelocatedAddress(void* code, AssemblerLabel label) @@ -855,7 +858,7 @@ namespace JSC { // Memory load/store helpers void dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset, bool bytes = false); - void baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset); + void baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset, bool bytes = false); void doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID base, int32_t offset); // Constant pool hnadlers @@ -867,6 +870,42 @@ namespace JSC { return AL | B | (offset & BRANCH_MASK); } +#if OS(LINUX) && COMPILER(RVCT) + static __asm void cacheFlush(void* code, size_t); +#else + static void cacheFlush(void* code, size_t size) + { +#if OS(LINUX) && COMPILER(GCC) + uintptr_t currentPage = reinterpret_cast(code) & ~(pageSize() - 1); + uintptr_t lastPage = (reinterpret_cast(code) + size) & ~(pageSize() - 1); + do { + asm volatile( + "push {r7}\n" + "mov r0, %0\n" + "mov r1, %1\n" + "mov r7, #0xf0000\n" + "add r7, r7, #0x2\n" + "mov r2, #0x0\n" + "svc 0x0\n" + "pop {r7}\n" + : + : "r" (currentPage), "r" (currentPage + pageSize()) + : "r0", "r1", "r2"); + currentPage += pageSize(); + } while (lastPage >= currentPage); +#elif OS(WINCE) + CacheRangeFlush(code, size, CACHE_SYNC_ALL); +#elif OS(QNX) && ENABLE(ASSEMBLER_WX_EXCLUSIVE) + UNUSED_PARAM(code); + UNUSED_PARAM(size); +#elif OS(QNX) + msync(code, size, MS_INVALIDATE_ICACHE); +#else +#error "The cacheFlush support is missing on this platform." +#endif + } +#endif + private: ARMWord RM(int reg) { diff --git a/assembler/ARMv7Assembler.h b/assembler/ARMv7Assembler.h index f5101c7..a8b55d1 100644 --- a/assembler/ARMv7Assembler.h +++ b/assembler/ARMv7Assembler.h @@ -414,11 +414,6 @@ private: class ARMv7Assembler { public: - ~ARMv7Assembler() - { - ASSERT(m_jumpsToLink.isEmpty()); - } - typedef ARMRegisters::RegisterID RegisterID; typedef ARMRegisters::FPSingleRegisterID FPSingleRegisterID; typedef ARMRegisters::FPDoubleRegisterID FPDoubleRegisterID; @@ -467,26 +462,40 @@ public: class LinkRecord { public: LinkRecord(intptr_t from, intptr_t to, JumpType type, Condition condition) - : m_from(from) - , m_to(to) - , m_type(type) - , m_linkType(LinkInvalid) - , m_condition(condition) { + data.realTypes.m_from = from; + data.realTypes.m_to = to; + data.realTypes.m_type = type; + data.realTypes.m_linkType = LinkInvalid; + data.realTypes.m_condition = condition; } - intptr_t from() const { return m_from; } - void setFrom(intptr_t from) { m_from = from; } - intptr_t to() const { return m_to; } - JumpType type() const { return m_type; } - JumpLinkType linkType() const { return m_linkType; } - void setLinkType(JumpLinkType linkType) { ASSERT(m_linkType == LinkInvalid); m_linkType = linkType; } - Condition condition() const { return m_condition; } + void operator=(const LinkRecord& other) + { + data.copyTypes.content[0] = other.data.copyTypes.content[0]; + data.copyTypes.content[1] = other.data.copyTypes.content[1]; + data.copyTypes.content[2] = other.data.copyTypes.content[2]; + } + intptr_t from() const { return data.realTypes.m_from; } + void setFrom(intptr_t from) { data.realTypes.m_from = from; } + intptr_t to() const { return data.realTypes.m_to; } + JumpType type() const { return data.realTypes.m_type; } + JumpLinkType linkType() const { return data.realTypes.m_linkType; } + void setLinkType(JumpLinkType linkType) { ASSERT(data.realTypes.m_linkType == LinkInvalid); data.realTypes.m_linkType = linkType; } + Condition condition() const { return data.realTypes.m_condition; } private: - intptr_t m_from : 31; - intptr_t m_to : 31; - JumpType m_type : 8; - JumpLinkType m_linkType : 8; - Condition m_condition : 16; + union { + struct RealTypes { + intptr_t m_from : 31; + intptr_t m_to : 31; + JumpType m_type : 8; + JumpLinkType m_linkType : 8; + Condition m_condition : 16; + } realTypes; + struct CopyTypes { + uint32_t content[3]; + } copyTypes; + COMPILE_ASSERT(sizeof(RealTypes) == sizeof(CopyTypes), LinkRecordCopyStructSizeEqualsRealStruct); + } data; }; private: @@ -534,12 +543,18 @@ private: OP_BLX = 0x4700, OP_BX = 0x4700, OP_STR_reg_T1 = 0x5000, + OP_STRH_reg_T1 = 0x5200, + OP_STRB_reg_T1 = 0x5400, + OP_LDRSB_reg_T1 = 0x5600, OP_LDR_reg_T1 = 0x5800, OP_LDRH_reg_T1 = 0x5A00, OP_LDRB_reg_T1 = 0x5C00, + OP_LDRSH_reg_T1 = 0x5E00, OP_STR_imm_T1 = 0x6000, OP_LDR_imm_T1 = 0x6800, + OP_STRB_imm_T1 = 0x7000, OP_LDRB_imm_T1 = 0x7800, + OP_STRH_imm_T1 = 0x8000, OP_LDRH_imm_T1 = 0x8800, OP_STR_imm_T2 = 0x9000, OP_LDR_imm_T2 = 0x9800, @@ -569,18 +584,28 @@ private: OP_SUB_reg_T2 = 0xEBA0, OP_SUB_S_reg_T2 = 0xEBB0, OP_CMP_reg_T2 = 0xEBB0, + OP_VMOV_CtoD = 0xEC00, + OP_VMOV_DtoC = 0xEC10, + OP_FSTS = 0xED00, OP_VSTR = 0xED00, + OP_FLDS = 0xED10, OP_VLDR = 0xED10, - OP_VMOV_StoC = 0xEE00, - OP_VMOV_CtoS = 0xEE10, + OP_VMOV_CtoS = 0xEE00, + OP_VMOV_StoC = 0xEE10, OP_VMUL_T2 = 0xEE20, OP_VADD_T2 = 0xEE30, OP_VSUB_T2 = 0xEE30, OP_VDIV = 0xEE80, + OP_VABS_T2 = 0xEEB0, OP_VCMP = 0xEEB0, OP_VCVT_FPIVFP = 0xEEB0, + OP_VMOV_T2 = 0xEEB0, OP_VMOV_IMM_T2 = 0xEEB0, OP_VMRS = 0xEEB0, + OP_VNEG_T2 = 0xEEB0, + OP_VSQRT_T1 = 0xEEB0, + OP_VCVTSD_T1 = 0xEEB0, + OP_VCVTDS_T1 = 0xEEB0, OP_B_T3a = 0xF000, OP_B_T4a = 0xF000, OP_AND_imm_T1 = 0xF000, @@ -592,27 +617,38 @@ private: OP_ADD_imm_T3 = 0xF100, OP_ADD_S_imm_T3 = 0xF110, OP_CMN_imm = 0xF110, + OP_ADC_imm = 0xF140, OP_SUB_imm_T3 = 0xF1A0, OP_SUB_S_imm_T3 = 0xF1B0, OP_CMP_imm_T2 = 0xF1B0, OP_RSB_imm_T2 = 0xF1C0, + OP_RSB_S_imm_T2 = 0xF1D0, OP_ADD_imm_T4 = 0xF200, OP_MOV_imm_T3 = 0xF240, OP_SUB_imm_T4 = 0xF2A0, OP_MOVT = 0xF2C0, + OP_UBFX_T1 = 0xF3C0, OP_NOP_T2a = 0xF3AF, + OP_STRB_imm_T3 = 0xF800, + OP_STRB_reg_T2 = 0xF800, OP_LDRB_imm_T3 = 0xF810, OP_LDRB_reg_T2 = 0xF810, + OP_STRH_imm_T3 = 0xF820, + OP_STRH_reg_T2 = 0xF820, OP_LDRH_reg_T2 = 0xF830, OP_LDRH_imm_T3 = 0xF830, OP_STR_imm_T4 = 0xF840, OP_STR_reg_T2 = 0xF840, OP_LDR_imm_T4 = 0xF850, OP_LDR_reg_T2 = 0xF850, + OP_STRB_imm_T2 = 0xF880, OP_LDRB_imm_T2 = 0xF890, + OP_STRH_imm_T2 = 0xF8A0, OP_LDRH_imm_T2 = 0xF8B0, OP_STR_imm_T3 = 0xF8C0, OP_LDR_imm_T3 = 0xF8D0, + OP_LDRSB_reg_T2 = 0xF910, + OP_LDRSH_reg_T2 = 0xF930, OP_LSL_reg_T2 = 0xFA00, OP_LSR_reg_T2 = 0xFA20, OP_ASR_reg_T2 = 0xFA40, @@ -624,16 +660,26 @@ private: typedef enum { OP_VADD_T2b = 0x0A00, OP_VDIVb = 0x0A00, + OP_FLDSb = 0x0A00, OP_VLDRb = 0x0A00, OP_VMOV_IMM_T2b = 0x0A00, + OP_VMOV_T2b = 0x0A40, OP_VMUL_T2b = 0x0A00, + OP_FSTSb = 0x0A00, OP_VSTRb = 0x0A00, - OP_VMOV_CtoSb = 0x0A10, OP_VMOV_StoCb = 0x0A10, + OP_VMOV_CtoSb = 0x0A10, + OP_VMOV_DtoCb = 0x0A10, + OP_VMOV_CtoDb = 0x0A10, OP_VMRSb = 0x0A10, + OP_VABS_T2b = 0x0A40, OP_VCMPb = 0x0A40, OP_VCVT_FPIVFPb = 0x0A40, + OP_VNEG_T2b = 0x0A40, OP_VSUB_T2b = 0x0A40, + OP_VSQRT_T1b = 0x0A40, + OP_VCVTSD_T1b = 0x0A40, + OP_VCVTDS_T1b = 0x0A40, OP_NOP_T2b = 0x8000, OP_B_T3b = 0x8000, OP_B_T4b = 0x9000, @@ -699,6 +745,17 @@ private: public: + void adc(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) + { + // Rd can only be SP if Rn is also SP. + ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp)); + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); + ASSERT(imm.isEncodedImm()); + + m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADC_imm, rn, rd, imm); + } + void add(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) { // Rd can only be SP if Rn is also SP. @@ -708,6 +765,7 @@ public: ASSERT(imm.isValid()); if (rn == ARMRegisters::sp) { + ASSERT(!(imm.getUInt16() & 3)); if (!(rd & 8) && imm.isUInt10()) { m_formatter.oneWordOp5Reg3Imm8(OP_ADD_SP_imm_T1, rd, static_cast(imm.getUInt10() >> 2)); return; @@ -860,7 +918,7 @@ public: return m_formatter.label(); } - void bkpt(uint8_t imm=0) + void bkpt(uint8_t imm = 0) { m_formatter.oneWordOp8Imm8(OP_BKPT, imm); } @@ -1126,6 +1184,30 @@ public: else m_formatter.twoWordOp12Reg4FourFours(OP_LDRB_reg_T2, rn, FourFours(rt, 0, shift, rm)); } + + void ldrsb(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0) + { + ASSERT(rn != ARMRegisters::pc); + ASSERT(!BadReg(rm)); + ASSERT(shift <= 3); + + if (!shift && !((rt | rn | rm) & 8)) + m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRSB_reg_T1, rm, rn, rt); + else + m_formatter.twoWordOp12Reg4FourFours(OP_LDRSB_reg_T2, rn, FourFours(rt, 0, shift, rm)); + } + + void ldrsh(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0) + { + ASSERT(rn != ARMRegisters::pc); + ASSERT(!BadReg(rm)); + ASSERT(shift <= 3); + + if (!shift && !((rt | rn | rm) & 8)) + m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRSH_reg_T1, rm, rn, rt); + else + m_formatter.twoWordOp12Reg4FourFours(OP_LDRSH_reg_T2, rn, FourFours(rt, 0, shift, rm)); + } void lsl(RegisterID rd, RegisterID rm, int32_t shiftAmount) { @@ -1353,6 +1435,124 @@ public: m_formatter.twoWordOp12Reg4FourFours(OP_STR_reg_T2, rn, FourFours(rt, 0, shift, rm)); } + // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. + ALWAYS_INLINE void strb(RegisterID rt, RegisterID rn, ARMThumbImmediate imm) + { + ASSERT(rt != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); + ASSERT(imm.isUInt12()); + + if (!((rt | rn) & 8) && imm.isUInt7()) + m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STRB_imm_T1, imm.getUInt7() >> 2, rn, rt); + else + m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STRB_imm_T2, rn, rt, imm.getUInt12()); + } + + // If index is set, this is a regular offset or a pre-indexed store; + // if index is not set then is is a post-index store. + // + // If wback is set rn is updated - this is a pre or post index store, + // if wback is not set this is a regular offset memory access. + // + // (-255 <= offset <= 255) + // _reg = REG[rn] + // _tmp = _reg + offset + // MEM[index ? _tmp : _reg] = REG[rt] + // if (wback) REG[rn] = _tmp + ALWAYS_INLINE void strb(RegisterID rt, RegisterID rn, int offset, bool index, bool wback) + { + ASSERT(rt != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); + ASSERT(index || wback); + ASSERT(!wback | (rt != rn)); + + bool add = true; + if (offset < 0) { + add = false; + offset = -offset; + } + ASSERT((offset & ~0xff) == 0); + + offset |= (wback << 8); + offset |= (add << 9); + offset |= (index << 10); + offset |= (1 << 11); + + m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STRB_imm_T3, rn, rt, offset); + } + + // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. + ALWAYS_INLINE void strb(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0) + { + ASSERT(rn != ARMRegisters::pc); + ASSERT(!BadReg(rm)); + ASSERT(shift <= 3); + + if (!shift && !((rt | rn | rm) & 8)) + m_formatter.oneWordOp7Reg3Reg3Reg3(OP_STRB_reg_T1, rm, rn, rt); + else + m_formatter.twoWordOp12Reg4FourFours(OP_STRB_reg_T2, rn, FourFours(rt, 0, shift, rm)); + } + + // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. + ALWAYS_INLINE void strh(RegisterID rt, RegisterID rn, ARMThumbImmediate imm) + { + ASSERT(rt != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); + ASSERT(imm.isUInt12()); + + if (!((rt | rn) & 8) && imm.isUInt7()) + m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STRH_imm_T1, imm.getUInt7() >> 2, rn, rt); + else + m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STRH_imm_T2, rn, rt, imm.getUInt12()); + } + + // If index is set, this is a regular offset or a pre-indexed store; + // if index is not set then is is a post-index store. + // + // If wback is set rn is updated - this is a pre or post index store, + // if wback is not set this is a regular offset memory access. + // + // (-255 <= offset <= 255) + // _reg = REG[rn] + // _tmp = _reg + offset + // MEM[index ? _tmp : _reg] = REG[rt] + // if (wback) REG[rn] = _tmp + ALWAYS_INLINE void strh(RegisterID rt, RegisterID rn, int offset, bool index, bool wback) + { + ASSERT(rt != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); + ASSERT(index || wback); + ASSERT(!wback | (rt != rn)); + + bool add = true; + if (offset < 0) { + add = false; + offset = -offset; + } + ASSERT(!(offset & ~0xff)); + + offset |= (wback << 8); + offset |= (add << 9); + offset |= (index << 10); + offset |= (1 << 11); + + m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STRH_imm_T3, rn, rt, offset); + } + + // rt == ARMRegisters::pc only allowed if last instruction in IT (if then) block. + ALWAYS_INLINE void strh(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0) + { + ASSERT(rn != ARMRegisters::pc); + ASSERT(!BadReg(rm)); + ASSERT(shift <= 3); + + if (!shift && !((rt | rn | rm) & 8)) + m_formatter.oneWordOp7Reg3Reg3Reg3(OP_STRH_reg_T1, rm, rn, rt); + else + m_formatter.twoWordOp12Reg4FourFours(OP_STRH_reg_T2, rn, FourFours(rt, 0, shift, rm)); + } + ALWAYS_INLINE void sub(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) { // Rd can only be SP if Rn is also SP. @@ -1362,6 +1562,7 @@ public: ASSERT(imm.isValid()); if ((rn == ARMRegisters::sp) && (rd == ARMRegisters::sp) && imm.isUInt9()) { + ASSERT(!(imm.getUInt16() & 3)); m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, static_cast(imm.getUInt9() >> 2)); return; } else if (!((rd | rn) & 8)) { @@ -1423,6 +1624,7 @@ public: ASSERT(imm.isValid()); if ((rn == ARMRegisters::sp) && (rd == ARMRegisters::sp) && imm.isUInt9()) { + ASSERT(!(imm.getUInt16() & 3)); m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, static_cast(imm.getUInt9() >> 2)); return; } else if (!((rd | rn) & 8)) { @@ -1438,6 +1640,16 @@ public: m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_S_imm_T3, rn, rd, imm); } + ALWAYS_INLINE void sub_S(RegisterID rd, ARMThumbImmediate imm, RegisterID rn) + { + ASSERT(rd != ARMRegisters::pc); + ASSERT(rn != ARMRegisters::pc); + ASSERT(imm.isValid()); + ASSERT(imm.isUInt12()); + + m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_RSB_S_imm_T2, rn, rd, imm); + } + // Not allowed in an IT (if then) block? ALWAYS_INLINE void sub_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift) { @@ -1480,34 +1692,48 @@ public: m_formatter.oneWordOp10Reg3Reg3(OP_TST_reg_T1, rm, rn); } - void vadd_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) + ALWAYS_INLINE void ubfx(RegisterID rd, RegisterID rn, unsigned lsb, unsigned width) + { + ASSERT(lsb < 32); + ASSERT((width >= 1) && (width <= 32)); + ASSERT((lsb + width) <= 32); + m_formatter.twoWordOp12Reg40Imm3Reg4Imm20Imm5(OP_UBFX_T1, rd, rn, (lsb & 0x1c) << 10, (lsb & 0x3) << 6, (width - 1) & 0x1f); + } + + void vadd(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) { m_formatter.vfpOp(OP_VADD_T2, OP_VADD_T2b, true, rn, rd, rm); } - void vcmp_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rm) + void vcmp(FPDoubleRegisterID rd, FPDoubleRegisterID rm) { m_formatter.vfpOp(OP_VCMP, OP_VCMPb, true, VFPOperand(4), rd, rm); } - void vcmpz_F64(FPDoubleRegisterID rd) + void vcmpz(FPDoubleRegisterID rd) { m_formatter.vfpOp(OP_VCMP, OP_VCMPb, true, VFPOperand(5), rd, VFPOperand(0)); } - void vcvt_F64_S32(FPDoubleRegisterID rd, FPSingleRegisterID rm) + void vcvt_signedToFloatingPoint(FPDoubleRegisterID rd, FPSingleRegisterID rm) { // boolean values are 64bit (toInt, unsigned, roundZero) m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(false, false, false), rd, rm); } - void vcvtr_S32_F64(FPSingleRegisterID rd, FPDoubleRegisterID rm) + void vcvt_floatingPointToSigned(FPSingleRegisterID rd, FPDoubleRegisterID rm) { // boolean values are 64bit (toInt, unsigned, roundZero) m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(true, false, true), rd, rm); } + + void vcvt_floatingPointToUnsigned(FPSingleRegisterID rd, FPDoubleRegisterID rm) + { + // boolean values are 64bit (toInt, unsigned, roundZero) + m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(true, true, true), rd, rm); + } - void vdiv_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) + void vdiv(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) { m_formatter.vfpOp(OP_VDIV, OP_VDIVb, true, rn, rd, rm); } @@ -1516,17 +1742,41 @@ public: { m_formatter.vfpMemOp(OP_VLDR, OP_VLDRb, true, rn, rd, imm); } + + void flds(FPSingleRegisterID rd, RegisterID rn, int32_t imm) + { + m_formatter.vfpMemOp(OP_FLDS, OP_FLDSb, false, rn, rd, imm); + } void vmov(RegisterID rd, FPSingleRegisterID rn) { ASSERT(!BadReg(rd)); - m_formatter.vfpOp(OP_VMOV_CtoS, OP_VMOV_CtoSb, false, rn, rd, VFPOperand(0)); + m_formatter.vfpOp(OP_VMOV_StoC, OP_VMOV_StoCb, false, rn, rd, VFPOperand(0)); } void vmov(FPSingleRegisterID rd, RegisterID rn) { ASSERT(!BadReg(rn)); - m_formatter.vfpOp(OP_VMOV_StoC, OP_VMOV_StoCb, false, rd, rn, VFPOperand(0)); + m_formatter.vfpOp(OP_VMOV_CtoS, OP_VMOV_CtoSb, false, rd, rn, VFPOperand(0)); + } + + void vmov(RegisterID rd1, RegisterID rd2, FPDoubleRegisterID rn) + { + ASSERT(!BadReg(rd1)); + ASSERT(!BadReg(rd2)); + m_formatter.vfpOp(OP_VMOV_DtoC, OP_VMOV_DtoCb, true, rd2, VFPOperand(rd1 | 16), rn); + } + + void vmov(FPDoubleRegisterID rd, RegisterID rn1, RegisterID rn2) + { + ASSERT(!BadReg(rn1)); + ASSERT(!BadReg(rn2)); + m_formatter.vfpOp(OP_VMOV_CtoD, OP_VMOV_CtoDb, true, rn2, VFPOperand(rn1 | 16), rd); + } + + void vmov(FPDoubleRegisterID rd, FPDoubleRegisterID rn) + { + m_formatter.vfpOp(OP_VMOV_T2, OP_VMOV_T2b, true, VFPOperand(0), rd, rn); } void vmrs(RegisterID reg = ARMRegisters::pc) @@ -1535,7 +1785,7 @@ public: m_formatter.vfpOp(OP_VMRS, OP_VMRSb, false, VFPOperand(1), VFPOperand(0x10 | reg), VFPOperand(0)); } - void vmul_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) + void vmul(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) { m_formatter.vfpOp(OP_VMUL_T2, OP_VMUL_T2b, true, rn, rd, rm); } @@ -1545,11 +1795,41 @@ public: m_formatter.vfpMemOp(OP_VSTR, OP_VSTRb, true, rn, rd, imm); } - void vsub_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) + void fsts(FPSingleRegisterID rd, RegisterID rn, int32_t imm) + { + m_formatter.vfpMemOp(OP_FSTS, OP_FSTSb, false, rn, rd, imm); + } + + void vsub(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm) { m_formatter.vfpOp(OP_VSUB_T2, OP_VSUB_T2b, true, rn, rd, rm); } + void vabs(FPDoubleRegisterID rd, FPDoubleRegisterID rm) + { + m_formatter.vfpOp(OP_VABS_T2, OP_VABS_T2b, true, VFPOperand(16), rd, rm); + } + + void vneg(FPDoubleRegisterID rd, FPDoubleRegisterID rm) + { + m_formatter.vfpOp(OP_VNEG_T2, OP_VNEG_T2b, true, VFPOperand(1), rd, rm); + } + + void vsqrt(FPDoubleRegisterID rd, FPDoubleRegisterID rm) + { + m_formatter.vfpOp(OP_VSQRT_T1, OP_VSQRT_T1b, true, VFPOperand(17), rd, rm); + } + + void vcvtds(FPDoubleRegisterID rd, FPSingleRegisterID rm) + { + m_formatter.vfpOp(OP_VCVTDS_T1, OP_VCVTDS_T1b, false, VFPOperand(23), rd, rm); + } + + void vcvtsd(FPSingleRegisterID rd, FPDoubleRegisterID rm) + { + m_formatter.vfpOp(OP_VCVTSD_T1, OP_VCVTSD_T1b, true, VFPOperand(23), rd, rm); + } + void nop() { m_formatter.oneWordOp8Imm8(OP_NOP_T1, 0); @@ -1620,29 +1900,29 @@ public: if (jumpType == JumpCondition) { // 2-byte conditional T1 - const uint16_t* jumpT1Location = reinterpret_cast(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT1))); + const uint16_t* jumpT1Location = reinterpret_cast_ptr(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT1))); if (canBeJumpT1(jumpT1Location, to)) return LinkJumpT1; // 4-byte conditional T3 - const uint16_t* jumpT3Location = reinterpret_cast(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT3))); + const uint16_t* jumpT3Location = reinterpret_cast_ptr(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT3))); if (canBeJumpT3(jumpT3Location, to, mayTriggerErrata)) { if (!mayTriggerErrata) return LinkJumpT3; } // 4-byte conditional T4 with IT const uint16_t* conditionalJumpT4Location = - reinterpret_cast(from - (paddingSize - JUMP_ENUM_SIZE(LinkConditionalJumpT4))); + reinterpret_cast_ptr(from - (paddingSize - JUMP_ENUM_SIZE(LinkConditionalJumpT4))); if (canBeJumpT4(conditionalJumpT4Location, to, mayTriggerErrata)) { if (!mayTriggerErrata) return LinkConditionalJumpT4; } } else { // 2-byte unconditional T2 - const uint16_t* jumpT2Location = reinterpret_cast(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT2))); + const uint16_t* jumpT2Location = reinterpret_cast_ptr(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT2))); if (canBeJumpT2(jumpT2Location, to)) return LinkJumpT2; // 4-byte unconditional T4 - const uint16_t* jumpT4Location = reinterpret_cast(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT4))); + const uint16_t* jumpT4Location = reinterpret_cast_ptr(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT4))); if (canBeJumpT4(jumpT4Location, to, mayTriggerErrata)) { if (!mayTriggerErrata) return LinkJumpT4; @@ -1681,25 +1961,25 @@ public: { switch (record.linkType()) { case LinkJumpT1: - linkJumpT1(record.condition(), reinterpret_cast(from), to); + linkJumpT1(record.condition(), reinterpret_cast_ptr(from), to); break; case LinkJumpT2: - linkJumpT2(reinterpret_cast(from), to); + linkJumpT2(reinterpret_cast_ptr(from), to); break; case LinkJumpT3: - linkJumpT3(record.condition(), reinterpret_cast(from), to); + linkJumpT3(record.condition(), reinterpret_cast_ptr(from), to); break; case LinkJumpT4: - linkJumpT4(reinterpret_cast(from), to); + linkJumpT4(reinterpret_cast_ptr(from), to); break; case LinkConditionalJumpT4: - linkConditionalJumpT4(record.condition(), reinterpret_cast(from), to); + linkConditionalJumpT4(record.condition(), reinterpret_cast_ptr(from), to); break; case LinkConditionalBX: - linkConditionalBX(record.condition(), reinterpret_cast(from), to); + linkConditionalBX(record.condition(), reinterpret_cast_ptr(from), to); break; case LinkBX: - linkBX(reinterpret_cast(from), to); + linkBX(reinterpret_cast_ptr(from), to); break; default: ASSERT_NOT_REACHED(); @@ -1760,7 +2040,7 @@ public: linkJumpAbsolute(reinterpret_cast(from), to); - ExecutableAllocator::cacheFlush(reinterpret_cast(from) - 5, 5 * sizeof(uint16_t)); + cacheFlush(reinterpret_cast(from) - 5, 5 * sizeof(uint16_t)); } static void relinkCall(void* from, void* to) @@ -1770,6 +2050,11 @@ public: setPointer(reinterpret_cast(from) - 1, to); } + + static void* readCallTarget(void* from) + { + return readPointer(reinterpret_cast(from) - 1); + } static void repatchInt32(void* where, int32_t value) { @@ -1797,6 +2082,39 @@ public: return reinterpret_cast(readInt32(where)); } + unsigned debugOffset() { return m_formatter.debugOffset(); } + + static void cacheFlush(void* code, size_t size) + { +#if OS(IOS) + sys_cache_control(kCacheFunctionPrepareForExecution, code, size); +#elif OS(LINUX) + asm volatile( + "push {r7}\n" + "mov r0, %0\n" + "mov r1, %1\n" + "movw r7, #0x2\n" + "movt r7, #0xf\n" + "movs r2, #0x0\n" + "svc 0x0\n" + "pop {r7}\n" + : + : "r" (code), "r" (reinterpret_cast(code) + size) + : "r0", "r1", "r2"); +#elif OS(WINCE) + CacheRangeFlush(code, size, CACHE_SYNC_ALL); +#elif OS(QNX) +#if !ENABLE(ASSEMBLER_WX_EXCLUSIVE) + msync(code, size, MS_INVALIDATE_ICACHE); +#else + UNUSED_PARAM(code); + UNUSED_PARAM(size); +#endif +#else +#error "The cacheFlush support is missing on this platform." +#endif + } + private: // VFP operations commonly take one or more 5-bit operands, typically representing a // floating point register number. This will commonly be encoded in the instruction @@ -1856,6 +2174,7 @@ private: if (isRoundZero) op |= 0x10; } else { + ASSERT(!isRoundZero); // 'op' field in instruction is isUnsigned if (!isUnsigned) op |= 0x10; @@ -1875,7 +2194,7 @@ private: location[-2] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); location[-1] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-1] >> 8) & 0xf, hi16); - ExecutableAllocator::cacheFlush(location - 4, 4 * sizeof(uint16_t)); + cacheFlush(location - 4, 4 * sizeof(uint16_t)); } static int32_t readInt32(void* code) @@ -1901,8 +2220,9 @@ private: ASSERT(imm.isValid()); ASSERT(imm.isUInt7()); uint16_t* location = reinterpret_cast(code); + location[0] &= ~((static_cast(0x7f) >> 2) << 6); location[0] |= (imm.getUInt7() >> 2) << 6; - ExecutableAllocator::cacheFlush(location, sizeof(uint16_t)); + cacheFlush(location, sizeof(uint16_t)); } static void setPointer(void* code, void* value) @@ -2247,6 +2567,12 @@ private: m_buffer.putShort((reg2 << 12) | imm); } + ALWAYS_INLINE void twoWordOp12Reg40Imm3Reg4Imm20Imm5(OpcodeID1 op, RegisterID reg1, RegisterID reg2, uint16_t imm1, uint16_t imm2, uint16_t imm3) + { + m_buffer.putShort(op | reg1); + m_buffer.putShort((imm1 << 12) | (reg2 << 8) | (imm2 << 6) | imm3); + } + // Formats up instructions of the pattern: // 111111111B11aaaa:bbbb222SA2C2cccc // Where 1s in the pattern come from op1, 2s in the pattern come from op2, S is the provided size bit. @@ -2284,9 +2610,7 @@ private: bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); } void* data() const { return m_buffer.data(); } -#ifndef NDEBUG unsigned debugOffset() { return m_buffer.debugOffset(); } -#endif private: AssemblerBuffer m_buffer; diff --git a/assembler/AbstractMacroAssembler.h b/assembler/AbstractMacroAssembler.h index 7d9d092..e7cc70f 100644 --- a/assembler/AbstractMacroAssembler.h +++ b/assembler/AbstractMacroAssembler.h @@ -26,17 +26,31 @@ #ifndef AbstractMacroAssembler_h #define AbstractMacroAssembler_h +#include "AssemblerBuffer.h" #include "CodeLocation.h" #include "MacroAssemblerCodeRef.h" +#include #include #include #if ENABLE(ASSEMBLER) + +#if PLATFORM(QT) +#define ENABLE_JIT_CONSTANT_BLINDING 0 +#endif + +#ifndef ENABLE_JIT_CONSTANT_BLINDING +#define ENABLE_JIT_CONSTANT_BLINDING 1 +#endif + namespace JSC { class LinkBuffer; class RepatchBuffer; +namespace DFG { +class CorrectableJumpPoint; +} template class AbstractMacroAssembler { @@ -161,6 +175,19 @@ public: : m_value(value) { } + + // This is only here so that TrustedImmPtr(0) does not confuse the C++ + // overload handling rules. + explicit TrustedImmPtr(int value) + : m_value(0) + { + ASSERT_UNUSED(value, !value); + } + + explicit TrustedImmPtr(size_t value) + : m_value(reinterpret_cast(value)) + { + } intptr_t asIntptr() { @@ -170,11 +197,19 @@ public: const void* m_value; }; - struct ImmPtr : public TrustedImmPtr { + struct ImmPtr : +#if ENABLE(JIT_CONSTANT_BLINDING) + private TrustedImmPtr +#else + public TrustedImmPtr +#endif + { explicit ImmPtr(const void* value) : TrustedImmPtr(value) { } + + TrustedImmPtr asTrustedImmPtr() { return *this; } }; // TrustedImm32: @@ -216,7 +251,13 @@ public: }; - struct Imm32 : public TrustedImm32 { + struct Imm32 : +#if ENABLE(JIT_CONSTANT_BLINDING) + private TrustedImm32 +#else + public TrustedImm32 +#endif + { explicit Imm32(int32_t value) : TrustedImm32(value) { @@ -227,6 +268,8 @@ public: { } #endif + const TrustedImm32& asTrustedImm32() const { return *this; } + }; // Section 2: MacroAssembler code buffer handles @@ -244,6 +287,7 @@ public: class Label { template friend class AbstractMacroAssembler; + friend class DFG::CorrectableJumpPoint; friend class Jump; friend class MacroAssemblerCodeRef; friend class LinkBuffer; @@ -362,7 +406,7 @@ public: } Call(AssemblerLabel jmp, Flags flags) - : m_jmp(jmp) + : m_label(jmp) , m_flags(flags) { } @@ -374,10 +418,10 @@ public: static Call fromTailJump(Jump jump) { - return Call(jump.m_jmp, Linkable); + return Call(jump.m_label, Linkable); } - AssemblerLabel m_jmp; + AssemblerLabel m_label; private: Flags m_flags; }; @@ -392,6 +436,7 @@ public: template friend class AbstractMacroAssembler; friend class Call; + friend class DFG::CorrectableJumpPoint; friend class LinkBuffer; public: Jump() @@ -401,14 +446,20 @@ public: #if CPU(ARM_THUMB2) // Fixme: this information should be stored in the instruction stream, not in the Jump object. Jump(AssemblerLabel jmp, ARMv7Assembler::JumpType type, ARMv7Assembler::Condition condition = ARMv7Assembler::ConditionInvalid) - : m_jmp(jmp) + : m_label(jmp) , m_type(type) , m_condition(condition) { } +#elif CPU(SH4) + Jump(AssemblerLabel jmp, SH4Assembler::JumpType type = SH4Assembler::JumpFar) + : m_label(jmp) + , m_type(type) + { + } #else Jump(AssemblerLabel jmp) - : m_jmp(jmp) + : m_label(jmp) { } #endif @@ -416,29 +467,49 @@ public: void link(AbstractMacroAssembler* masm) const { #if CPU(ARM_THUMB2) - masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label(), m_type, m_condition); + masm->m_assembler.linkJump(m_label, masm->m_assembler.label(), m_type, m_condition); +#elif CPU(SH4) + masm->m_assembler.linkJump(m_label, masm->m_assembler.label(), m_type); #else - masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label()); + masm->m_assembler.linkJump(m_label, masm->m_assembler.label()); #endif } void linkTo(Label label, AbstractMacroAssembler* masm) const { #if CPU(ARM_THUMB2) - masm->m_assembler.linkJump(m_jmp, label.m_label, m_type, m_condition); + masm->m_assembler.linkJump(m_label, label.m_label, m_type, m_condition); #else - masm->m_assembler.linkJump(m_jmp, label.m_label); + masm->m_assembler.linkJump(m_label, label.m_label); #endif } - bool isSet() const { return m_jmp.isSet(); } + bool isSet() const { return m_label.isSet(); } private: - AssemblerLabel m_jmp; + AssemblerLabel m_label; #if CPU(ARM_THUMB2) ARMv7Assembler::JumpType m_type; ARMv7Assembler::Condition m_condition; #endif +#if CPU(SH4) + SH4Assembler::JumpType m_type; +#endif + }; + + struct PatchableJump { + PatchableJump() + { + } + + explicit PatchableJump(Jump jump) + : m_jump(jump) + { + } + + operator Jump&() { return m_jump; } + + Jump m_jump; }; // JumpList: @@ -506,72 +577,50 @@ public: return Label(this); } - ptrdiff_t differenceBetween(Label from, Jump to) - { - return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); - } - - ptrdiff_t differenceBetween(Label from, Call to) - { - return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); - } - - ptrdiff_t differenceBetween(Label from, Label to) + template + static ptrdiff_t differenceBetween(T from, U to) { return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); } - ptrdiff_t differenceBetween(Label from, DataLabelPtr to) + static ptrdiff_t differenceBetweenCodePtr(const MacroAssemblerCodePtr& a, const MacroAssemblerCodePtr& b) { - return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); + return reinterpret_cast(b.executableAddress()) - reinterpret_cast(a.executableAddress()); } - ptrdiff_t differenceBetween(Label from, DataLabel32 to) - { - return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); - } - - ptrdiff_t differenceBetween(Label from, DataLabelCompact to) - { - return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); - } + unsigned debugOffset() { return m_assembler.debugOffset(); } - ptrdiff_t differenceBetween(DataLabelPtr from, Jump to) + ALWAYS_INLINE static void cacheFlush(void* code, size_t size) { - return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); + AssemblerType::cacheFlush(code, size); } - - ptrdiff_t differenceBetween(DataLabelPtr from, DataLabelPtr to) +protected: + AbstractMacroAssembler() + : m_randomSource(cryptographicallyRandomNumber()) { - return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); } - ptrdiff_t differenceBetween(DataLabelPtr from, Call to) + AssemblerType m_assembler; + + uint32_t random() { - return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); + return m_randomSource.getUint32(); } - // Temporary interface; likely to be removed, since may be hard to port to all architectures. -#if CPU(X86) || CPU(X86_64) - void rewindToLabel(Label rewindTo) { m_assembler.rewindToLabel(rewindTo.m_label); } -#endif - - void beginUninterruptedSequence() { } - void endUninterruptedSequence() { } + WeakRandom m_randomSource; -#ifndef NDEBUG - unsigned debugOffset() { return m_assembler.debugOffset(); } +#if ENABLE(JIT_CONSTANT_BLINDING) + static bool scratchRegisterForBlinding() { return false; } + static bool shouldBlindForSpecificArch(uint32_t) { return true; } + static bool shouldBlindForSpecificArch(uint64_t) { return true; } #endif -protected: - AssemblerType m_assembler; - friend class LinkBuffer; friend class RepatchBuffer; static void linkJump(void* code, Jump jump, CodeLocationLabel target) { - AssemblerType::linkJump(code, jump.m_jmp, target.dataLocation()); + AssemblerType::linkJump(code, jump.m_label, target.dataLocation()); } static void linkPointer(void* code, AssemblerLabel label, void* value) @@ -586,7 +635,7 @@ protected: static unsigned getLinkerCallReturnOffset(Call call) { - return AssemblerType::getCallReturnOffset(call.m_jmp); + return AssemblerType::getCallReturnOffset(call.m_label); } static void repatchJump(CodeLocationJump jump, CodeLocationLabel destination) @@ -618,6 +667,18 @@ protected: { return AssemblerType::readPointer(dataLabelPtr.dataLocation()); } + + static void unreachableForPlatform() + { +#if COMPILER(CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-noreturn" + ASSERT_NOT_REACHED(); +#pragma clang diagnostic pop +#else + ASSERT_NOT_REACHED(); +#endif + } }; } // namespace JSC diff --git a/assembler/AssemblerBuffer.h b/assembler/AssemblerBuffer.h index b98503d..d1deef2 100644 --- a/assembler/AssemblerBuffer.h +++ b/assembler/AssemblerBuffer.h @@ -28,6 +28,8 @@ #if ENABLE(ASSEMBLER) +#include "JITCompilationEffort.h" +#include "JSGlobalData.h" #include "stdint.h" #include #include @@ -128,29 +130,24 @@ namespace JSC { return AssemblerLabel(m_index); } - void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator) + PassRefPtr executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort) { if (!m_index) return 0; - void* result = allocator->alloc(globalData, m_index); + RefPtr result = globalData.executableAllocator.allocate(globalData, m_index, ownerUID, effort); if (!result) return 0; - ExecutableAllocator::makeWritable(result, m_index); + ExecutableAllocator::makeWritable(result->start(), result->sizeInBytes()); - return memcpy(result, m_buffer, m_index); + memcpy(result->start(), m_buffer, m_index); + + return result.release(); } - void rewindToLabel(AssemblerLabel label) - { - m_index = label.m_offset; - } - -#ifndef NDEBUG unsigned debugOffset() { return m_index; } -#endif protected: void append(const char* data, int size) diff --git a/assembler/AssemblerBufferWithConstantPool.h b/assembler/AssemblerBufferWithConstantPool.h index cd9ff9c..e2ea261 100644 --- a/assembler/AssemblerBufferWithConstantPool.h +++ b/assembler/AssemblerBufferWithConstantPool.h @@ -83,7 +83,7 @@ namespace JSC { */ template -class AssemblerBufferWithConstantPool: public AssemblerBuffer { +class AssemblerBufferWithConstantPool : public AssemblerBuffer { typedef SegmentedVector LoadOffsets; using AssemblerBuffer::putIntegral; using AssemblerBuffer::putIntegralUnchecked; @@ -195,10 +195,10 @@ public: putIntegralUnchecked(value.low); } - void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator) + PassRefPtr executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort) { flushConstantPool(false); - return AssemblerBuffer::executableCopy(globalData, allocator); + return AssemblerBuffer::executableCopy(globalData, ownerUID, effort); } void putShortWithConstantInt(uint16_t insn, uint32_t constant, bool isReusable = false) diff --git a/assembler/LinkBuffer.h b/assembler/LinkBuffer.h index 59b5a1e..eff320d 100644 --- a/assembler/LinkBuffer.h +++ b/assembler/LinkBuffer.h @@ -31,7 +31,12 @@ #define DUMP_LINK_STATISTICS 0 #define DUMP_CODE 0 -#include +#define GLOBAL_THUNK_ID reinterpret_cast(static_cast(-1)) +#define REGEXP_CODE_ID reinterpret_cast(static_cast(-2)) + +#include "JITCompilationEffort.h" +#include "MacroAssembler.h" +#include #include namespace JSC { @@ -58,6 +63,7 @@ class LinkBuffer { typedef MacroAssemblerCodePtr CodePtr; typedef MacroAssembler::Label Label; typedef MacroAssembler::Jump Jump; + typedef MacroAssembler::PatchableJump PatchableJump; typedef MacroAssembler::JumpList JumpList; typedef MacroAssembler::Call Call; typedef MacroAssembler::DataLabelCompact DataLabelCompact; @@ -69,49 +75,49 @@ class LinkBuffer { #endif public: - LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, PassRefPtr executablePool) - : m_executablePool(executablePool) - , m_size(0) - , m_code(0) - , m_assembler(masm) - , m_globalData(&globalData) -#ifndef NDEBUG - , m_completed(false) + LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed) + : m_size(0) +#if ENABLE(BRANCH_COMPACTION) + , m_initialSize(0) #endif - { - linkCode(); - } - - LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, ExecutableAllocator& allocator) - : m_executablePool(allocator.poolForSize(globalData, masm->m_assembler.codeSize())) - , m_size(0) , m_code(0) , m_assembler(masm) , m_globalData(&globalData) #ifndef NDEBUG , m_completed(false) + , m_effort(effort) #endif { - linkCode(); + linkCode(ownerUID, effort); } ~LinkBuffer() { - ASSERT(m_completed); + ASSERT(m_completed || (!m_executableMemory && m_effort == JITCompilationCanFail)); + } + + bool didFailToAllocate() const + { + return !m_executableMemory; } + bool isValid() const + { + return !didFailToAllocate(); + } + // These methods are used to link or set values at code generation time. void link(Call call, FunctionPtr function) { ASSERT(call.isFlagSet(Call::Linkable)); - call.m_jmp = applyOffset(call.m_jmp); + call.m_label = applyOffset(call.m_label); MacroAssembler::linkCall(code(), call, function); } void link(Jump jump, CodeLocationLabel label) { - jump.m_jmp = applyOffset(jump.m_jmp); + jump.m_label = applyOffset(jump.m_label); MacroAssembler::linkJump(code(), jump, label); } @@ -139,14 +145,19 @@ public: { ASSERT(call.isFlagSet(Call::Linkable)); ASSERT(!call.isFlagSet(Call::Near)); - return CodeLocationCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_jmp))); + return CodeLocationCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label))); } CodeLocationNearCall locationOfNearCall(Call call) { ASSERT(call.isFlagSet(Call::Linkable)); ASSERT(call.isFlagSet(Call::Near)); - return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_jmp))); + return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label))); + } + + CodeLocationLabel locationOf(PatchableJump jump) + { + return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), applyOffset(jump.m_jump.m_label))); } CodeLocationLabel locationOf(Label label) @@ -173,26 +184,21 @@ public: // the start of the code. unsigned returnAddressOffset(Call call) { - call.m_jmp = applyOffset(call.m_jmp); + call.m_label = applyOffset(call.m_label); return MacroAssembler::getLinkerCallReturnOffset(call); } - // Upon completion of all patching either 'finalizeCode()' or 'finalizeCodeAddendum()' should be called - // once to complete generation of the code. 'finalizeCode()' is suited to situations - // where the executable pool must also be retained, the lighter-weight 'finalizeCodeAddendum()' is - // suited to adding to an existing allocation. - CodeRef finalizeCode() + uint32_t offsetOf(Label label) { - performFinalization(); - - return CodeRef(m_code, m_executablePool, m_size); + return applyOffset(label.m_label).m_offset; } - CodeLocationLabel finalizeCodeAddendum() + // Upon completion of all patching 'finalizeCode()' should be called once to complete generation of the code. + CodeRef finalizeCode() { performFinalization(); - return CodeLocationLabel(code()); + return CodeRef(m_executableMemory); } CodePtr trampolineAt(Label label) @@ -200,12 +206,15 @@ public: return CodePtr(MacroAssembler::AssemblerType_T::getRelocatedAddress(code(), applyOffset(label.m_label))); } -#ifndef NDEBUG void* debugAddress() { return m_code; } -#endif + + size_t debugSize() + { + return m_size; + } private: template T applyOffset(T src) @@ -216,26 +225,30 @@ private: return src; } - // Keep this private! - the underlying code should only be obtained externally via - // finalizeCode() or finalizeCodeAddendum(). + // Keep this private! - the underlying code should only be obtained externally via finalizeCode(). void* code() { return m_code; } - void linkCode() + void linkCode(void* ownerUID, JITCompilationEffort effort) { ASSERT(!m_code); #if !ENABLE(BRANCH_COMPACTION) - m_code = m_assembler->m_assembler.executableCopy(*m_globalData, m_executablePool.get()); + m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData, ownerUID, effort); + if (!m_executableMemory) + return; + m_code = m_executableMemory->start(); m_size = m_assembler->m_assembler.codeSize(); ASSERT(m_code); #else - size_t initialSize = m_assembler->m_assembler.codeSize(); - m_code = (uint8_t*)m_executablePool->alloc(*m_globalData, initialSize); - if (!m_code) + m_initialSize = m_assembler->m_assembler.codeSize(); + m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort); + if (!m_executableMemory) return; - ExecutableAllocator::makeWritable(m_code, initialSize); + m_code = (uint8_t*)m_executableMemory->start(); + ASSERT(m_code); + ExecutableAllocator::makeWritable(m_code, m_initialSize); uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode(); uint8_t* outData = reinterpret_cast(m_code); int readPtr = 0; @@ -248,9 +261,9 @@ private: // Copy the instructions from the last jump to the current one. size_t regionSize = jumpsToLink[i].from() - readPtr; - uint16_t* copySource = reinterpret_cast(inData + readPtr); - uint16_t* copyEnd = reinterpret_cast(inData + readPtr + regionSize); - uint16_t* copyDst = reinterpret_cast(outData + writePtr); + uint16_t* copySource = reinterpret_cast_ptr(inData + readPtr); + uint16_t* copyEnd = reinterpret_cast_ptr(inData + readPtr + regionSize); + uint16_t* copyDst = reinterpret_cast_ptr(outData + writePtr); ASSERT(!(regionSize % 2)); ASSERT(!(readPtr % 2)); ASSERT(!(writePtr % 2)); @@ -281,8 +294,8 @@ private: jumpsToLink[i].setFrom(writePtr); } // Copy everything after the last jump - memcpy(outData + writePtr, inData + readPtr, initialSize - readPtr); - m_assembler->recordLinkOffsets(readPtr, initialSize, readPtr - writePtr); + memcpy(outData + writePtr, inData + readPtr, m_initialSize - readPtr); + m_assembler->recordLinkOffsets(readPtr, m_initialSize, readPtr - writePtr); for (unsigned i = 0; i < jumpCount; ++i) { uint8_t* location = outData + jumpsToLink[i].from(); @@ -291,11 +304,11 @@ private: } jumpsToLink.clear(); - m_size = writePtr + initialSize - readPtr; - m_executablePool->tryShrink(m_code, initialSize, m_size); + m_size = writePtr + m_initialSize - readPtr; + m_executableMemory->shrink(m_size); #if DUMP_LINK_STATISTICS - dumpLinkStatistics(m_code, initialSize, m_size); + dumpLinkStatistics(m_code, m_initialSize, m_size); #endif #if DUMP_CODE dumpCode(m_code, m_size); @@ -307,11 +320,16 @@ private: { #ifndef NDEBUG ASSERT(!m_completed); + ASSERT(isValid()); m_completed = true; #endif +#if ENABLE(BRANCH_COMPACTION) + ExecutableAllocator::makeExecutable(code(), m_initialSize); +#else ExecutableAllocator::makeExecutable(code(), m_size); - ExecutableAllocator::cacheFlush(code(), m_size); +#endif + MacroAssembler::cacheFlush(code(), m_size); } #if DUMP_LINK_STATISTICS @@ -323,13 +341,13 @@ private: linkCount++; totalInitialSize += initialSize; totalFinalSize += finalSize; - printf("link %p: orig %u, compact %u (delta %u, %.2f%%)\n", - code, static_cast(initialSize), static_cast(finalSize), - static_cast(initialSize - finalSize), - 100.0 * (initialSize - finalSize) / initialSize); - printf("\ttotal %u: orig %u, compact %u (delta %u, %.2f%%)\n", - linkCount, totalInitialSize, totalFinalSize, totalInitialSize - totalFinalSize, - 100.0 * (totalInitialSize - totalFinalSize) / totalInitialSize); + dataLog("link %p: orig %u, compact %u (delta %u, %.2f%%)\n", + code, static_cast(initialSize), static_cast(finalSize), + static_cast(initialSize - finalSize), + 100.0 * (initialSize - finalSize) / initialSize); + dataLog("\ttotal %u: orig %u, compact %u (delta %u, %.2f%%)\n", + linkCount, totalInitialSize, totalFinalSize, totalInitialSize - totalFinalSize, + 100.0 * (totalInitialSize - totalFinalSize) / totalInitialSize); } #endif @@ -346,28 +364,49 @@ private: size_t tsize = size / sizeof(short); char nameBuf[128]; snprintf(nameBuf, sizeof(nameBuf), "_jsc_jit%u", codeCount++); - printf("\t.syntax unified\n" - "\t.section\t__TEXT,__text,regular,pure_instructions\n" - "\t.globl\t%s\n" - "\t.align 2\n" - "\t.code 16\n" - "\t.thumb_func\t%s\n" - "# %p\n" - "%s:\n", nameBuf, nameBuf, code, nameBuf); + dataLog("\t.syntax unified\n" + "\t.section\t__TEXT,__text,regular,pure_instructions\n" + "\t.globl\t%s\n" + "\t.align 2\n" + "\t.code 16\n" + "\t.thumb_func\t%s\n" + "# %p\n" + "%s:\n", nameBuf, nameBuf, code, nameBuf); for (unsigned i = 0; i < tsize; i++) - printf("\t.short\t0x%x\n", tcode[i]); + dataLog("\t.short\t0x%x\n", tcode[i]); +#elif CPU(ARM_TRADITIONAL) + // gcc -c jit.s + // objdump -D jit.o + static unsigned codeCount = 0; + unsigned int* tcode = static_cast(code); + size_t tsize = size / sizeof(unsigned int); + char nameBuf[128]; + snprintf(nameBuf, sizeof(nameBuf), "_jsc_jit%u", codeCount++); + dataLog("\t.globl\t%s\n" + "\t.align 4\n" + "\t.code 32\n" + "\t.text\n" + "# %p\n" + "%s:\n", nameBuf, code, nameBuf); + + for (unsigned i = 0; i < tsize; i++) + dataLog("\t.long\t0x%x\n", tcode[i]); #endif } #endif - RefPtr m_executablePool; + RefPtr m_executableMemory; size_t m_size; +#if ENABLE(BRANCH_COMPACTION) + size_t m_initialSize; +#endif void* m_code; MacroAssembler* m_assembler; JSGlobalData* m_globalData; #ifndef NDEBUG bool m_completed; + JITCompilationEffort m_effort; #endif }; diff --git a/assembler/MIPSAssembler.h b/assembler/MIPSAssembler.h index 4164fa9..7212a18 100644 --- a/assembler/MIPSAssembler.h +++ b/assembler/MIPSAssembler.h @@ -32,6 +32,7 @@ #if ENABLE(ASSEMBLER) && CPU(MIPS) #include "AssemblerBuffer.h" +#include "JITCompilationEffort.h" #include #include @@ -645,19 +646,17 @@ public: return m_buffer.codeSize(); } - void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator) + PassRefPtr executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort) { - void *result = m_buffer.executableCopy(globalData, allocator); + RefPtr result = m_buffer.executableCopy(globalData, ownerUID, effort); if (!result) return 0; - relocateJumps(m_buffer.data(), result); - return result; + relocateJumps(m_buffer.data(), result->start()); + return result.release(); } -#ifndef NDEBUG unsigned debugOffset() { return m_buffer.debugOffset(); } -#endif static unsigned getCallReturnOffset(AssemblerLabel call) { @@ -719,7 +718,7 @@ public: insn = insn - 6; int flushSize = linkWithOffset(insn, to); - ExecutableAllocator::cacheFlush(insn, flushSize); + cacheFlush(insn, flushSize); } static void relinkCall(void* from, void* to) @@ -731,7 +730,7 @@ public: else start = reinterpret_cast(reinterpret_cast(from) - 4 * sizeof(MIPSWord)); - ExecutableAllocator::cacheFlush(start, size); + cacheFlush(start, size); } static void repatchInt32(void* from, int32_t to) @@ -743,7 +742,7 @@ public: ASSERT((*insn & 0xfc000000) == 0x34000000); // ori *insn = (*insn & 0xffff0000) | (to & 0xffff); insn--; - ExecutableAllocator::cacheFlush(insn, 2 * sizeof(MIPSWord)); + cacheFlush(insn, 2 * sizeof(MIPSWord)); } static int32_t readInt32(void* from) @@ -753,7 +752,8 @@ public: int32_t result = (*insn & 0x0000ffff) << 16; insn++; ASSERT((*insn & 0xfc000000) == 0x34000000); // ori - result |= *insn & 0x0000ffff + result |= *insn & 0x0000ffff; + return result; } static void repatchCompact(void* where, int32_t value) @@ -768,7 +768,45 @@ public: static void* readPointer(void* from) { - return static_cast(readInt32(from)); + return reinterpret_cast(readInt32(from)); + } + + static void* readCallTarget(void* from) + { + MIPSWord* insn = reinterpret_cast(from); + insn -= 4; + ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui + int32_t result = (*insn & 0x0000ffff) << 16; + insn++; + ASSERT((*insn & 0xfc000000) == 0x34000000); // ori + result |= *insn & 0x0000ffff; + return reinterpret_cast(result); + } + + static void cacheFlush(void* code, size_t size) + { +#if GCC_VERSION_AT_LEAST(4, 3, 0) +#if WTF_MIPS_ISA_REV(2) && !GCC_VERSION_AT_LEAST(4, 4, 3) + int lineSize; + asm("rdhwr %0, $1" : "=r" (lineSize)); + // + // Modify "start" and "end" to avoid GCC 4.3.0-4.4.2 bug in + // mips_expand_synci_loop that may execute synci one more time. + // "start" points to the fisrt byte of the cache line. + // "end" points to the last byte of the line before the last cache line. + // Because size is always a multiple of 4, this is safe to set + // "end" to the last byte. + // + intptr_t start = reinterpret_cast(code) & (-lineSize); + intptr_t end = ((reinterpret_cast(code) + size - 1) & (-lineSize)) - 1; + __builtin___clear_cache(reinterpret_cast(start), reinterpret_cast(end)); +#else + intptr_t end = reinterpret_cast(code) + size; + __builtin___clear_cache(reinterpret_cast(code), reinterpret_cast(end)); +#endif +#else + _flush_cache(reinterpret_cast(code), size, BCACHE); +#endif } private: diff --git a/assembler/MacroAssembler.h b/assembler/MacroAssembler.h index c8506c7..516ffac 100644 --- a/assembler/MacroAssembler.h +++ b/assembler/MacroAssembler.h @@ -60,7 +60,6 @@ typedef MacroAssemblerSH4 MacroAssemblerBase; #error "The MacroAssembler is not supported on this platform." #endif - namespace JSC { class MacroAssembler : public MacroAssemblerBase { @@ -69,12 +68,88 @@ public: using MacroAssemblerBase::pop; using MacroAssemblerBase::jump; using MacroAssemblerBase::branch32; - using MacroAssemblerBase::branch16; #if CPU(X86_64) using MacroAssemblerBase::branchPtr; using MacroAssemblerBase::branchTestPtr; #endif + using MacroAssemblerBase::move; + +#if ENABLE(JIT_CONSTANT_BLINDING) + using MacroAssemblerBase::add32; + using MacroAssemblerBase::and32; + using MacroAssemblerBase::branchAdd32; + using MacroAssemblerBase::branchMul32; + using MacroAssemblerBase::branchSub32; + using MacroAssemblerBase::lshift32; + using MacroAssemblerBase::or32; + using MacroAssemblerBase::rshift32; + using MacroAssemblerBase::store32; + using MacroAssemblerBase::sub32; + using MacroAssemblerBase::urshift32; + using MacroAssemblerBase::xor32; +#endif + // Utilities used by the DFG JIT. +#if ENABLE(DFG_JIT) + using MacroAssemblerBase::invert; + + static DoubleCondition invert(DoubleCondition cond) + { + switch (cond) { + case DoubleEqual: + return DoubleNotEqualOrUnordered; + case DoubleNotEqual: + return DoubleEqualOrUnordered; + case DoubleGreaterThan: + return DoubleLessThanOrEqualOrUnordered; + case DoubleGreaterThanOrEqual: + return DoubleLessThanOrUnordered; + case DoubleLessThan: + return DoubleGreaterThanOrEqualOrUnordered; + case DoubleLessThanOrEqual: + return DoubleGreaterThanOrUnordered; + case DoubleEqualOrUnordered: + return DoubleNotEqual; + case DoubleNotEqualOrUnordered: + return DoubleEqual; + case DoubleGreaterThanOrUnordered: + return DoubleLessThanOrEqual; + case DoubleGreaterThanOrEqualOrUnordered: + return DoubleLessThan; + case DoubleLessThanOrUnordered: + return DoubleGreaterThanOrEqual; + case DoubleLessThanOrEqualOrUnordered: + return DoubleGreaterThan; + default: + ASSERT_NOT_REACHED(); + return DoubleEqual; // make compiler happy + } + } + + static bool isInvertible(ResultCondition cond) + { + switch (cond) { + case Zero: + case NonZero: + return true; + default: + return false; + } + } + + static ResultCondition invert(ResultCondition cond) + { + switch (cond) { + case Zero: + return NonZero; + case NonZero: + return Zero; + default: + ASSERT_NOT_REACHED(); + return Zero; // Make compiler happy for release builds. + } + } +#endif // Platform agnostic onvenience functions, // described in terms of other macro assembly methods. @@ -88,19 +163,24 @@ public: loadPtr(Address(stackPointerRegister, (index * sizeof(void*))), dest); } + Address addressForPoke(int index) + { + return Address(stackPointerRegister, (index * sizeof(void*))); + } + void poke(RegisterID src, int index = 0) { - storePtr(src, Address(stackPointerRegister, (index * sizeof(void*)))); + storePtr(src, addressForPoke(index)); } void poke(TrustedImm32 value, int index = 0) { - store32(value, Address(stackPointerRegister, (index * sizeof(void*)))); + store32(value, addressForPoke(index)); } void poke(TrustedImmPtr imm, int index = 0) { - storePtr(imm, Address(stackPointerRegister, (index * sizeof(void*)))); + storePtr(imm, addressForPoke(index)); } @@ -109,6 +189,10 @@ public: { branchPtr(cond, op1, imm).linkTo(target, this); } + void branchPtr(RelationalCondition cond, RegisterID op1, ImmPtr imm, Label target) + { + branchPtr(cond, op1, imm).linkTo(target, this); + } void branch32(RelationalCondition cond, RegisterID op1, RegisterID op2, Label target) { @@ -119,27 +203,78 @@ public: { branch32(cond, op1, imm).linkTo(target, this); } + + void branch32(RelationalCondition cond, RegisterID op1, Imm32 imm, Label target) + { + branch32(cond, op1, imm).linkTo(target, this); + } void branch32(RelationalCondition cond, RegisterID left, Address right, Label target) { branch32(cond, left, right).linkTo(target, this); } - void branch16(RelationalCondition cond, BaseIndex left, RegisterID right, Label target) + Jump branch32(RelationalCondition cond, TrustedImm32 left, RegisterID right) { - branch16(cond, left, right).linkTo(target, this); + return branch32(commute(cond), right, left); } - + + Jump branch32(RelationalCondition cond, Imm32 left, RegisterID right) + { + return branch32(commute(cond), right, left); + } + void branchTestPtr(ResultCondition cond, RegisterID reg, Label target) { branchTestPtr(cond, reg).linkTo(target, this); } +#if !CPU(ARM_THUMB2) + PatchableJump patchableBranchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) + { + return PatchableJump(branchPtrWithPatch(cond, left, dataLabel, initialRightValue)); + } + + PatchableJump patchableJump() + { + return PatchableJump(jump()); + } +#endif + void jump(Label target) { jump().linkTo(target, this); } + // Commute a relational condition, returns a new condition that will produce + // the same results given the same inputs but with their positions exchanged. + static RelationalCondition commute(RelationalCondition condition) + { + switch (condition) { + case Above: + return Below; + case AboveOrEqual: + return BelowOrEqual; + case Below: + return Above; + case BelowOrEqual: + return AboveOrEqual; + case GreaterThan: + return LessThan; + case GreaterThanOrEqual: + return LessThanOrEqual; + case LessThan: + return GreaterThan; + case LessThanOrEqual: + return GreaterThanOrEqual; + default: + break; + } + + ASSERT(condition == Equal || condition == NotEqual); + return condition; + } + // Ptr methods // On 32-bit platforms (i.e. x86), these methods directly map onto their 32-bit equivalents. @@ -165,6 +300,11 @@ public: add32(imm, src, dest); } + void addPtr(TrustedImm32 imm, AbsoluteAddress address) + { + add32(imm, address); + } + void andPtr(RegisterID src, RegisterID dest) { and32(src, dest); @@ -180,6 +320,11 @@ public: or32(src, dest); } + void orPtr(RegisterID op1, RegisterID op2, RegisterID dest) + { + or32(op1, op2, dest); + } + void orPtr(TrustedImmPtr imm, RegisterID dest) { or32(TrustedImm32(imm), dest); @@ -226,7 +371,7 @@ public: load32(address, dest); } - void loadPtr(void* address, RegisterID dest) + void loadPtr(const void* address, RegisterID dest) { load32(address, dest); } @@ -241,6 +386,11 @@ public: return load32WithCompactAddressOffsetPatch(address, dest); } + void move(ImmPtr imm, RegisterID dest) + { + move(Imm32(imm.asTrustedImmPtr()), dest); + } + void comparePtr(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest) { compare32(cond, left, right, dest); @@ -265,6 +415,11 @@ public: { store32(TrustedImm32(imm), address); } + + void storePtr(ImmPtr imm, Address address) + { + store32(Imm32(imm.asTrustedImmPtr()), address); + } void storePtr(TrustedImmPtr imm, void* address) { @@ -276,7 +431,6 @@ public: return store32WithAddressOffsetPatch(src, address); } - Jump branchPtr(RelationalCondition cond, RegisterID left, RegisterID right) { return branch32(cond, left, right); @@ -286,6 +440,11 @@ public: { return branch32(cond, left, TrustedImm32(right)); } + + Jump branchPtr(RelationalCondition cond, RegisterID left, ImmPtr right) + { + return branch32(cond, left, Imm32(right.asTrustedImmPtr())); + } Jump branchPtr(RelationalCondition cond, RegisterID left, Address right) { @@ -306,7 +465,7 @@ public: { return branch32(cond, left, TrustedImm32(right)); } - + Jump branchPtr(RelationalCondition cond, AbsoluteAddress left, TrustedImmPtr right) { return branch32(cond, left, TrustedImm32(right)); @@ -332,7 +491,6 @@ public: return branchTest32(cond, address, mask); } - Jump branchAddPtr(ResultCondition cond, RegisterID src, RegisterID dest) { return branchAdd32(cond, src, dest); @@ -347,12 +505,527 @@ public: { return MacroAssemblerBase::branchTest8(cond, Address(address.base, address.offset), mask); } +#else + +#if ENABLE(JIT_CONSTANT_BLINDING) + using MacroAssemblerBase::addPtr; + using MacroAssemblerBase::andPtr; + using MacroAssemblerBase::branchSubPtr; + using MacroAssemblerBase::convertInt32ToDouble; + using MacroAssemblerBase::storePtr; + using MacroAssemblerBase::subPtr; + using MacroAssemblerBase::xorPtr; + + bool shouldBlindDouble(double value) + { + // Don't trust NaN or +/-Infinity + if (!isfinite(value)) + return true; + + // Try to force normalisation, and check that there's no change + // in the bit pattern + if (bitwise_cast(value * 1.0) != bitwise_cast(value)) + return true; + + value = abs(value); + // Only allow a limited set of fractional components + double scaledValue = value * 8; + if (scaledValue / 8 != value) + return true; + double frac = scaledValue - floor(scaledValue); + if (frac != 0.0) + return true; + + return value > 0xff; + } + + bool shouldBlind(ImmPtr imm) + { +#if !defined(NDEBUG) + UNUSED_PARAM(imm); + // Debug always blind all constants, if only so we know + // if we've broken blinding during patch development. + return true; +#endif + + // First off we'll special case common, "safe" values to avoid hurting + // performance too much + uintptr_t value = imm.asTrustedImmPtr().asIntptr(); + switch (value) { + case 0xffff: + case 0xffffff: + case 0xffffffffL: + case 0xffffffffffL: + case 0xffffffffffffL: + case 0xffffffffffffffL: + case 0xffffffffffffffffL: + return false; + default: { + if (value <= 0xff) + return false; +#if CPU(X86_64) + JSValue jsValue = JSValue::decode(reinterpret_cast(value)); + if (jsValue.isInt32()) + return shouldBlind(Imm32(jsValue.asInt32())); + if (jsValue.isDouble() && !shouldBlindDouble(jsValue.asDouble())) + return false; + + if (!shouldBlindDouble(bitwise_cast(value))) + return false; +#endif + } + } + return shouldBlindForSpecificArch(value); + } + + struct RotatedImmPtr { + RotatedImmPtr(uintptr_t v1, uint8_t v2) + : value(v1) + , rotation(v2) + { + } + TrustedImmPtr value; + TrustedImm32 rotation; + }; + + RotatedImmPtr rotationBlindConstant(ImmPtr imm) + { + uint8_t rotation = random() % (sizeof(void*) * 8); + uintptr_t value = imm.asTrustedImmPtr().asIntptr(); + value = (value << rotation) | (value >> (sizeof(void*) * 8 - rotation)); + return RotatedImmPtr(value, rotation); + } + + void loadRotationBlindedConstant(RotatedImmPtr constant, RegisterID dest) + { + move(constant.value, dest); + rotateRightPtr(constant.rotation, dest); + } + + void convertInt32ToDouble(Imm32 imm, FPRegisterID dest) + { + if (shouldBlind(imm)) { + RegisterID scratchRegister = scratchRegisterForBlinding(); + loadXorBlindedConstant(xorBlindConstant(imm), scratchRegister); + convertInt32ToDouble(scratchRegister, dest); + } else + convertInt32ToDouble(imm.asTrustedImm32(), dest); + } + + void move(ImmPtr imm, RegisterID dest) + { + if (shouldBlind(imm)) + loadRotationBlindedConstant(rotationBlindConstant(imm), dest); + else + move(imm.asTrustedImmPtr(), dest); + } + + Jump branchPtr(RelationalCondition cond, RegisterID left, ImmPtr right) + { + if (shouldBlind(right)) { + RegisterID scratchRegister = scratchRegisterForBlinding(); + loadRotationBlindedConstant(rotationBlindConstant(right), scratchRegister); + return branchPtr(cond, left, scratchRegister); + } + return branchPtr(cond, left, right.asTrustedImmPtr()); + } + + void storePtr(ImmPtr imm, Address dest) + { + if (shouldBlind(imm)) { + RegisterID scratchRegister = scratchRegisterForBlinding(); + loadRotationBlindedConstant(rotationBlindConstant(imm), scratchRegister); + storePtr(scratchRegister, dest); + } else + storePtr(imm.asTrustedImmPtr(), dest); + } + #endif +#endif // !CPU(X86_64) + +#if ENABLE(JIT_CONSTANT_BLINDING) + bool shouldBlind(Imm32 imm) + { +#if !defined(NDEBUG) + UNUSED_PARAM(imm); + // Debug always blind all constants, if only so we know + // if we've broken blinding during patch development. + return true; +#else + + // First off we'll special case common, "safe" values to avoid hurting + // performance too much + uint32_t value = imm.asTrustedImm32().m_value; + switch (value) { + case 0xffff: + case 0xffffff: + case 0xffffffff: + return false; + default: + if (value <= 0xff) + return false; + } + return shouldBlindForSpecificArch(value); +#endif + } + + struct BlindedImm32 { + BlindedImm32(int32_t v1, int32_t v2) + : value1(v1) + , value2(v2) + { + } + TrustedImm32 value1; + TrustedImm32 value2; + }; + + uint32_t keyForConstant(uint32_t value, uint32_t& mask) + { + uint32_t key = random(); + if (value <= 0xff) + mask = 0xff; + else if (value <= 0xffff) + mask = 0xffff; + else if (value <= 0xffffff) + mask = 0xffffff; + else + mask = 0xffffffff; + return key & mask; + } + + uint32_t keyForConstant(uint32_t value) + { + uint32_t mask = 0; + return keyForConstant(value, mask); + } + + BlindedImm32 xorBlindConstant(Imm32 imm) + { + uint32_t baseValue = imm.asTrustedImm32().m_value; + uint32_t key = keyForConstant(baseValue); + return BlindedImm32(baseValue ^ key, key); + } + + BlindedImm32 additionBlindedConstant(Imm32 imm) + { + // The addition immediate may be used as a pointer offset. Keep aligned based on "imm". + static uint32_t maskTable[4] = { 0xfffffffc, 0xffffffff, 0xfffffffe, 0xffffffff }; + + uint32_t baseValue = imm.asTrustedImm32().m_value; + uint32_t key = keyForConstant(baseValue) & maskTable[baseValue & 3]; + if (key > baseValue) + key = key - baseValue; + return BlindedImm32(baseValue - key, key); + } + + BlindedImm32 andBlindedConstant(Imm32 imm) + { + uint32_t baseValue = imm.asTrustedImm32().m_value; + uint32_t mask = 0; + uint32_t key = keyForConstant(baseValue, mask); + ASSERT((baseValue & mask) == baseValue); + return BlindedImm32(((baseValue & key) | ~key) & mask, ((baseValue & ~key) | key) & mask); + } + + BlindedImm32 orBlindedConstant(Imm32 imm) + { + uint32_t baseValue = imm.asTrustedImm32().m_value; + uint32_t mask = 0; + uint32_t key = keyForConstant(baseValue, mask); + ASSERT((baseValue & mask) == baseValue); + return BlindedImm32((baseValue & key) & mask, (baseValue & ~key) & mask); + } + + void loadXorBlindedConstant(BlindedImm32 constant, RegisterID dest) + { + move(constant.value1, dest); + xor32(constant.value2, dest); + } + + void add32(Imm32 imm, RegisterID dest) + { + if (shouldBlind(imm)) { + BlindedImm32 key = additionBlindedConstant(imm); + add32(key.value1, dest); + add32(key.value2, dest); + } else + add32(imm.asTrustedImm32(), dest); + } + + void addPtr(Imm32 imm, RegisterID dest) + { + if (shouldBlind(imm)) { + BlindedImm32 key = additionBlindedConstant(imm); + addPtr(key.value1, dest); + addPtr(key.value2, dest); + } else + addPtr(imm.asTrustedImm32(), dest); + } + + void and32(Imm32 imm, RegisterID dest) + { + if (shouldBlind(imm)) { + BlindedImm32 key = andBlindedConstant(imm); + and32(key.value1, dest); + and32(key.value2, dest); + } else + and32(imm.asTrustedImm32(), dest); + } + + void andPtr(Imm32 imm, RegisterID dest) + { + if (shouldBlind(imm)) { + BlindedImm32 key = andBlindedConstant(imm); + andPtr(key.value1, dest); + andPtr(key.value2, dest); + } else + andPtr(imm.asTrustedImm32(), dest); + } + + void and32(Imm32 imm, RegisterID src, RegisterID dest) + { + if (shouldBlind(imm)) { + if (src == dest) + return and32(imm.asTrustedImm32(), dest); + loadXorBlindedConstant(xorBlindConstant(imm), dest); + and32(src, dest); + } else + and32(imm.asTrustedImm32(), src, dest); + } + + void move(Imm32 imm, RegisterID dest) + { + if (shouldBlind(imm)) + loadXorBlindedConstant(xorBlindConstant(imm), dest); + else + move(imm.asTrustedImm32(), dest); + } + + void or32(Imm32 imm, RegisterID src, RegisterID dest) + { + if (shouldBlind(imm)) { + if (src == dest) + return or32(imm, dest); + loadXorBlindedConstant(xorBlindConstant(imm), dest); + or32(src, dest); + } else + or32(imm.asTrustedImm32(), src, dest); + } + + void or32(Imm32 imm, RegisterID dest) + { + if (shouldBlind(imm)) { + BlindedImm32 key = orBlindedConstant(imm); + or32(key.value1, dest); + or32(key.value2, dest); + } else + or32(imm.asTrustedImm32(), dest); + } + + void poke(Imm32 value, int index = 0) + { + store32(value, addressForPoke(index)); + } + + void poke(ImmPtr value, int index = 0) + { + storePtr(value, addressForPoke(index)); + } + + void store32(Imm32 imm, Address dest) + { + if (shouldBlind(imm)) { +#if CPU(X86) || CPU(X86_64) + BlindedImm32 blind = xorBlindConstant(imm); + store32(blind.value1, dest); + xor32(blind.value2, dest); +#else + if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) { + loadXorBlindedConstant(xorBlindConstant(imm), scratchRegister); + store32(scratchRegister, dest); + } else { + // If we don't have a scratch register available for use, we'll just + // place a random number of nops. + uint32_t nopCount = random() & 3; + while (nopCount--) + nop(); + store32(imm.asTrustedImm32(), dest); + } +#endif + } else + store32(imm.asTrustedImm32(), dest); + } + + void sub32(Imm32 imm, RegisterID dest) + { + if (shouldBlind(imm)) { + BlindedImm32 key = additionBlindedConstant(imm); + sub32(key.value1, dest); + sub32(key.value2, dest); + } else + sub32(imm.asTrustedImm32(), dest); + } + + void subPtr(Imm32 imm, RegisterID dest) + { + if (shouldBlind(imm)) { + BlindedImm32 key = additionBlindedConstant(imm); + subPtr(key.value1, dest); + subPtr(key.value2, dest); + } else + subPtr(imm.asTrustedImm32(), dest); + } + + void xor32(Imm32 imm, RegisterID src, RegisterID dest) + { + if (shouldBlind(imm)) { + BlindedImm32 blind = xorBlindConstant(imm); + xor32(blind.value1, src, dest); + xor32(blind.value2, dest); + } else + xor32(imm.asTrustedImm32(), src, dest); + } + + void xor32(Imm32 imm, RegisterID dest) + { + if (shouldBlind(imm)) { + BlindedImm32 blind = xorBlindConstant(imm); + xor32(blind.value1, dest); + xor32(blind.value2, dest); + } else + xor32(imm.asTrustedImm32(), dest); + } + + Jump branch32(RelationalCondition cond, RegisterID left, Imm32 right) + { + if (shouldBlind(right)) { + if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) { + loadXorBlindedConstant(xorBlindConstant(right), scratchRegister); + return branch32(cond, left, scratchRegister); + } + // If we don't have a scratch register available for use, we'll just + // place a random number of nops. + uint32_t nopCount = random() & 3; + while (nopCount--) + nop(); + return branch32(cond, left, right.asTrustedImm32()); + } + + return branch32(cond, left, right.asTrustedImm32()); + } + + Jump branchAdd32(ResultCondition cond, RegisterID src, Imm32 imm, RegisterID dest) + { + if (src == dest) { + if (!scratchRegisterForBlinding()) { + // Release mode ASSERT, if this fails we will perform incorrect codegen. + CRASH(); + } + } + if (shouldBlind(imm)) { + if (src == dest) { + if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) { + move(src, scratchRegister); + src = scratchRegister; + } + } + loadXorBlindedConstant(xorBlindConstant(imm), dest); + return branchAdd32(cond, src, dest); + } + return branchAdd32(cond, src, imm.asTrustedImm32(), dest); + } + + Jump branchMul32(ResultCondition cond, Imm32 imm, RegisterID src, RegisterID dest) + { + if (src == dest) { + if (!scratchRegisterForBlinding()) { + // Release mode ASSERT, if this fails we will perform incorrect codegen. + CRASH(); + } + } + if (shouldBlind(imm)) { + if (src == dest) { + if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) { + move(src, scratchRegister); + src = scratchRegister; + } + } + loadXorBlindedConstant(xorBlindConstant(imm), dest); + return branchMul32(cond, src, dest); + } + return branchMul32(cond, imm.asTrustedImm32(), src, dest); + } + + // branchSub32 takes a scratch register as 32 bit platforms make use of this, + // with src == dst, and on x86-32 we don't have a platform scratch register. + Jump branchSub32(ResultCondition cond, RegisterID src, Imm32 imm, RegisterID dest, RegisterID scratch) + { + if (shouldBlind(imm)) { + ASSERT(scratch != dest); + ASSERT(scratch != src); + loadXorBlindedConstant(xorBlindConstant(imm), scratch); + return branchSub32(cond, src, scratch, dest); + } + return branchSub32(cond, src, imm.asTrustedImm32(), dest); + } + + // Immediate shifts only have 5 controllable bits + // so we'll consider them safe for now. + TrustedImm32 trustedImm32ForShift(Imm32 imm) + { + return TrustedImm32(imm.asTrustedImm32().m_value & 31); + } + + void lshift32(Imm32 imm, RegisterID dest) + { + lshift32(trustedImm32ForShift(imm), dest); + } + + void lshift32(RegisterID src, Imm32 amount, RegisterID dest) + { + lshift32(src, trustedImm32ForShift(amount), dest); + } + + void rshift32(Imm32 imm, RegisterID dest) + { + rshift32(trustedImm32ForShift(imm), dest); + } + + void rshift32(RegisterID src, Imm32 amount, RegisterID dest) + { + rshift32(src, trustedImm32ForShift(amount), dest); + } + + void urshift32(Imm32 imm, RegisterID dest) + { + urshift32(trustedImm32ForShift(imm), dest); + } + + void urshift32(RegisterID src, Imm32 amount, RegisterID dest) + { + urshift32(src, trustedImm32ForShift(amount), dest); + } +#endif }; } // namespace JSC +#else // ENABLE(ASSEMBLER) + +// If there is no assembler for this platform, at least allow code to make references to +// some of the things it would otherwise define, albeit without giving that code any way +// of doing anything useful. +class MacroAssembler { +private: + MacroAssembler() { } + +public: + + enum RegisterID { NoRegister }; + enum FPRegisterID { NoFPRegister }; +}; + #endif // ENABLE(ASSEMBLER) #endif // MacroAssembler_h diff --git a/assembler/MacroAssemblerARM.h b/assembler/MacroAssemblerARM.h index b365dce..829ec53 100644 --- a/assembler/MacroAssemblerARM.h +++ b/assembler/MacroAssemblerARM.h @@ -108,6 +108,11 @@ public: add32(ARMRegisters::S1, dest); } + void add32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + m_assembler.adds_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); + } + void and32(RegisterID src, RegisterID dest) { m_assembler.ands_r(dest, dest, src); @@ -122,6 +127,15 @@ public: m_assembler.ands_r(dest, dest, w); } + void and32(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + ARMWord w = m_assembler.getImm(imm.m_value, ARMRegisters::S0, true); + if (w & ARMAssembler::OP2_INV_IMM) + m_assembler.bics_r(dest, src, w & ~ARMAssembler::OP2_INV_IMM); + else + m_assembler.ands_r(dest, src, w); + } + void lshift32(RegisterID shift_amount, RegisterID dest) { ARMWord w = ARMAssembler::getOp2(0x1f); @@ -136,6 +150,11 @@ public: m_assembler.movs_r(dest, m_assembler.lsl(dest, imm.m_value & 0x1f)); } + void lshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + m_assembler.movs_r(dest, m_assembler.lsl(src, imm.m_value & 0x1f)); + } + void mul32(RegisterID src, RegisterID dest) { if (src == dest) { @@ -156,11 +175,6 @@ public: m_assembler.rsbs_r(srcDest, srcDest, ARMAssembler::getOp2(0)); } - void not32(RegisterID dest) - { - m_assembler.mvns_r(dest, dest); - } - void or32(RegisterID src, RegisterID dest) { m_assembler.orrs_r(dest, dest, src); @@ -171,6 +185,16 @@ public: m_assembler.orrs_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); } + void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + m_assembler.orrs_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); + } + + void or32(RegisterID op1, RegisterID op2, RegisterID dest) + { + m_assembler.orrs_r(dest, op1, op2); + } + void rshift32(RegisterID shift_amount, RegisterID dest) { ARMWord w = ARMAssembler::getOp2(0x1f); @@ -179,10 +203,15 @@ public: m_assembler.movs_r(dest, m_assembler.asr_r(dest, ARMRegisters::S0)); } - + void rshift32(TrustedImm32 imm, RegisterID dest) { - m_assembler.movs_r(dest, m_assembler.asr(dest, imm.m_value & 0x1f)); + rshift32(dest, imm, dest); + } + + void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + m_assembler.movs_r(dest, m_assembler.asr(src, imm.m_value & 0x1f)); } void urshift32(RegisterID shift_amount, RegisterID dest) @@ -198,6 +227,11 @@ public: { m_assembler.movs_r(dest, m_assembler.lsr(dest, imm.m_value & 0x1f)); } + + void urshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + m_assembler.movs_r(dest, m_assembler.lsr(src, imm.m_value & 0x1f)); + } void sub32(RegisterID src, RegisterID dest) { @@ -222,6 +256,11 @@ public: sub32(ARMRegisters::S1, dest); } + void sub32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + m_assembler.subs_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); + } + void xor32(RegisterID src, RegisterID dest) { m_assembler.eors_r(dest, dest, src); @@ -229,7 +268,18 @@ public: void xor32(TrustedImm32 imm, RegisterID dest) { - m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); + if (imm.m_value == -1) + m_assembler.mvns_r(dest, dest); + else + m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); + } + + void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + if (imm.m_value == -1) + m_assembler.mvns_r(dest, src); + else + m_assembler.eors_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0)); } void countLeadingZeros32(RegisterID src, RegisterID dest) @@ -248,6 +298,11 @@ public: m_assembler.dataTransfer32(true, dest, address.base, address.offset, true); } + void load8(BaseIndex address, RegisterID dest) + { + m_assembler.baseIndexTransfer32(true, dest, address.base, address.index, static_cast(address.scale), address.offset, true); + } + void load32(ImplicitAddress address, RegisterID dest) { m_assembler.dataTransfer32(true, dest, address.base, address.offset); @@ -267,6 +322,11 @@ public: } #endif + void load16Unaligned(BaseIndex address, RegisterID dest) + { + load16(address, dest); + } + DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest) { DataLabel32 dataLabel(this); @@ -404,6 +464,13 @@ public: return branch32(cond, ARMRegisters::S1, right); } + Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right) + { + ASSERT(!(right.m_value & 0xFFFFFF00)); + load8(left, ARMRegisters::S1); + return branch32(cond, ARMRegisters::S1, right); + } + Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right, int useConstantPool = 0) { m_assembler.cmp_r(left, right); @@ -416,7 +483,7 @@ public: m_assembler.ldr_un_imm(ARMRegisters::S0, right.m_value); m_assembler.cmp_r(left, ARMRegisters::S0); } else { - ARMWord tmp = m_assembler.getOp2(-right.m_value); + ARMWord tmp = (right.m_value == 0x80000000) ? ARMAssembler::INVALID_IMM : m_assembler.getOp2(-right.m_value); if (tmp != ARMAssembler::INVALID_IMM) m_assembler.cmn_r(left, tmp); else @@ -455,23 +522,6 @@ public: return branch32(cond, ARMRegisters::S1, right); } - Jump branch16(RelationalCondition cond, BaseIndex left, RegisterID right) - { - UNUSED_PARAM(cond); - UNUSED_PARAM(left); - UNUSED_PARAM(right); - ASSERT_NOT_REACHED(); - return jump(); - } - - Jump branch16(RelationalCondition cond, BaseIndex left, TrustedImm32 right) - { - load16(left, ARMRegisters::S0); - move(right, ARMRegisters::S1); - m_assembler.cmp_r(ARMRegisters::S0, ARMRegisters::S1); - return m_assembler.jmp(ARMCondition(cond)); - } - Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) { load8(address, ARMRegisters::S1); @@ -537,6 +587,13 @@ public: return Jump(m_assembler.jmp(ARMCondition(cond))); } + Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + add32(src, imm, dest); + return Jump(m_assembler.jmp(ARMCondition(cond))); + } + void mull32(RegisterID src1, RegisterID src2, RegisterID dest) { if (src1 == dest) { @@ -586,6 +643,20 @@ public: return Jump(m_assembler.jmp(ARMCondition(cond))); } + Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + sub32(src, imm, dest); + return Jump(m_assembler.jmp(ARMCondition(cond))); + } + + Jump branchSub32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + m_assembler.subs_r(dest, op1, op2); + return Jump(m_assembler.jmp(ARMCondition(cond))); + } + Jump branchNeg32(ResultCondition cond, RegisterID srcDest) { ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); @@ -646,6 +717,12 @@ public: m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond)); } + void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest) + { + load8(left, ARMRegisters::S1); + compare32(cond, ARMRegisters::S1, right, dest); + } + void test32(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest) { if (mask.m_value == -1) @@ -775,20 +852,21 @@ public: } // Floating point operators - bool supportsFloatingPoint() const + static bool supportsFloatingPoint() { return s_isVFPPresent; } - bool supportsFloatingPointTruncate() const + static bool supportsFloatingPointTruncate() { - return s_isVFPPresent; + return false; } - bool supportsFloatingPointSqrt() const + static bool supportsFloatingPointSqrt() { return s_isVFPPresent; } + static bool supportsFloatingPointAbs() { return false; } void loadDouble(ImplicitAddress address, FPRegisterID dest) { @@ -855,6 +933,11 @@ public: { m_assembler.vsqrt_f64_r(dest, src); } + + void absDouble(FPRegisterID, FPRegisterID) + { + ASSERT_NOT_REACHED(); + } void convertInt32ToDouble(RegisterID src, FPRegisterID dest) { @@ -891,17 +974,13 @@ public: // Truncates 'src' to an integer, and places the resulting 'dest'. // If the result is not representable as a 32 bit value, branch. // May also branch for some values that are representable in 32 bits - // (specifically, in this case, INT_MIN and INT_MAX). + // (specifically, in this case, INT_MIN). Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest) { - m_assembler.vcvtr_s32_f64_r(ARMRegisters::SD0 << 1, src); - // If VCVTR.S32.F64 can't fit the result into a 32-bit - // integer, it saturates at INT_MAX or INT_MIN. Testing this is - // probably quicker than testing FPSCR for exception. - m_assembler.vmov_arm_r(dest, ARMRegisters::SD0 << 1); - m_assembler.sub_r(ARMRegisters::S0, dest, ARMAssembler::getOp2(0x80000000)); - m_assembler.cmn_r(ARMRegisters::S0, ARMAssembler::getOp2(1), ARMCondition(NotEqual)); - return Jump(m_assembler.jmp(ARMCondition(Equal))); + UNUSED_PARAM(src); + UNUSED_PARAM(dest); + ASSERT_NOT_REACHED(); + return jump(); } // Convert 'src' to an integer, and places the resulting 'dest'. @@ -940,6 +1019,11 @@ public: m_assembler.nop(); } + static FunctionPtr readCallTarget(CodeLocationCall call) + { + return FunctionPtr(reinterpret_cast(ARMAssembler::readCallTarget(call.dataLocation()))); + } + protected: ARMAssembler::Condition ARMCondition(RelationalCondition cond) { @@ -1021,7 +1105,7 @@ private: static void linkCall(void* code, Call call, FunctionPtr function) { - ARMAssembler::linkCall(code, call.m_jmp, function.value()); + ARMAssembler::linkCall(code, call.m_label, function.value()); } static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) diff --git a/assembler/MacroAssemblerARMv7.h b/assembler/MacroAssemblerARMv7.h index 70b2552..b72717a 100644 --- a/assembler/MacroAssemblerARMv7.h +++ b/assembler/MacroAssemblerARMv7.h @@ -45,20 +45,18 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler { inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); } public: + MacroAssemblerARMv7() + : m_makeJumpPatchable(false) + { + } + typedef ARMv7Assembler::LinkRecord LinkRecord; typedef ARMv7Assembler::JumpType JumpType; typedef ARMv7Assembler::JumpLinkType JumpLinkType; // Magic number is the biggest useful offset we can get on ARMv7 with // a LDR_imm_T2 encoding static const int MaximumCompactPtrAlignedAddressOffset = 124; - - MacroAssemblerARMv7() - : m_inUninterruptedSequence(false) - { - } - void beginUninterruptedSequence() { m_inUninterruptedSequence = true; } - void endUninterruptedSequence() { m_inUninterruptedSequence = false; } Vector& jumpsToLink() { return m_assembler.jumpsToLink(); } void* unlinkedCode() { return m_assembler.unlinkedCode(); } bool canCompact(JumpType jumpType) { return m_assembler.canCompact(jumpType); } @@ -211,40 +209,80 @@ public: store32(dataTempRegister, address.m_ptr); } - void and32(RegisterID src, RegisterID dest) + void add64(TrustedImm32 imm, AbsoluteAddress address) + { + move(TrustedImmPtr(address.m_ptr), addressTempRegister); + + m_assembler.ldr(dataTempRegister, addressTempRegister, ARMThumbImmediate::makeUInt12(0)); + ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value); + if (armImm.isValid()) + m_assembler.add_S(dataTempRegister, dataTempRegister, armImm); + else { + move(imm, addressTempRegister); + m_assembler.add_S(dataTempRegister, dataTempRegister, addressTempRegister); + move(TrustedImmPtr(address.m_ptr), addressTempRegister); + } + m_assembler.str(dataTempRegister, addressTempRegister, ARMThumbImmediate::makeUInt12(0)); + + m_assembler.ldr(dataTempRegister, addressTempRegister, ARMThumbImmediate::makeUInt12(4)); + m_assembler.adc(dataTempRegister, dataTempRegister, ARMThumbImmediate::makeEncodedImm(imm.m_value >> 31)); + m_assembler.str(dataTempRegister, addressTempRegister, ARMThumbImmediate::makeUInt12(4)); + } + + void and32(RegisterID op1, RegisterID op2, RegisterID dest) { - m_assembler.ARM_and(dest, dest, src); + m_assembler.ARM_and(dest, op1, op2); } - void and32(TrustedImm32 imm, RegisterID dest) + void and32(TrustedImm32 imm, RegisterID src, RegisterID dest) { ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value); if (armImm.isValid()) - m_assembler.ARM_and(dest, dest, armImm); + m_assembler.ARM_and(dest, src, armImm); else { move(imm, dataTempRegister); - m_assembler.ARM_and(dest, dest, dataTempRegister); + m_assembler.ARM_and(dest, src, dataTempRegister); } } + void and32(RegisterID src, RegisterID dest) + { + and32(dest, src, dest); + } + + void and32(TrustedImm32 imm, RegisterID dest) + { + and32(imm, dest, dest); + } + void countLeadingZeros32(RegisterID src, RegisterID dest) { m_assembler.clz(dest, src); } - void lshift32(RegisterID shift_amount, RegisterID dest) + void lshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest) { // Clamp the shift to the range 0..31 ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f); ASSERT(armImm.isValid()); - m_assembler.ARM_and(dataTempRegister, shift_amount, armImm); + m_assembler.ARM_and(dataTempRegister, shiftAmount, armImm); + + m_assembler.lsl(dest, src, dataTempRegister); + } - m_assembler.lsl(dest, dest, dataTempRegister); + void lshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + m_assembler.lsl(dest, src, imm.m_value & 0x1f); + } + + void lshift32(RegisterID shiftAmount, RegisterID dest) + { + lshift32(dest, shiftAmount, dest); } void lshift32(TrustedImm32 imm, RegisterID dest) { - m_assembler.lsl(dest, dest, imm.m_value & 0x1f); + lshift32(dest, imm, dest); } void mul32(RegisterID src, RegisterID dest) @@ -263,55 +301,80 @@ public: m_assembler.neg(srcDest, srcDest); } - void not32(RegisterID srcDest) - { - m_assembler.mvn(srcDest, srcDest); - } - void or32(RegisterID src, RegisterID dest) { m_assembler.orr(dest, dest, src); } void or32(TrustedImm32 imm, RegisterID dest) + { + or32(imm, dest, dest); + } + + void or32(RegisterID op1, RegisterID op2, RegisterID dest) + { + m_assembler.orr(dest, op1, op2); + } + + void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) { ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value); if (armImm.isValid()) - m_assembler.orr(dest, dest, armImm); + m_assembler.orr(dest, src, armImm); else { move(imm, dataTempRegister); - m_assembler.orr(dest, dest, dataTempRegister); + m_assembler.orr(dest, src, dataTempRegister); } } - void rshift32(RegisterID shift_amount, RegisterID dest) + void rshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest) { // Clamp the shift to the range 0..31 ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f); ASSERT(armImm.isValid()); - m_assembler.ARM_and(dataTempRegister, shift_amount, armImm); + m_assembler.ARM_and(dataTempRegister, shiftAmount, armImm); - m_assembler.asr(dest, dest, dataTempRegister); + m_assembler.asr(dest, src, dataTempRegister); } - void rshift32(TrustedImm32 imm, RegisterID dest) + void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + m_assembler.asr(dest, src, imm.m_value & 0x1f); + } + + void rshift32(RegisterID shiftAmount, RegisterID dest) { - m_assembler.asr(dest, dest, imm.m_value & 0x1f); + rshift32(dest, shiftAmount, dest); } - void urshift32(RegisterID shift_amount, RegisterID dest) + void rshift32(TrustedImm32 imm, RegisterID dest) + { + rshift32(dest, imm, dest); + } + + void urshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest) { // Clamp the shift to the range 0..31 ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f); ASSERT(armImm.isValid()); - m_assembler.ARM_and(dataTempRegister, shift_amount, armImm); + m_assembler.ARM_and(dataTempRegister, shiftAmount, armImm); - m_assembler.lsr(dest, dest, dataTempRegister); + m_assembler.lsr(dest, src, dataTempRegister); + } + + void urshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + m_assembler.lsr(dest, src, imm.m_value & 0x1f); + } + + void urshift32(RegisterID shiftAmount, RegisterID dest) + { + urshift32(dest, shiftAmount, dest); } void urshift32(TrustedImm32 imm, RegisterID dest) { - m_assembler.lsr(dest, dest, imm.m_value & 0x1f); + urshift32(dest, imm, dest); } void sub32(RegisterID src, RegisterID dest) @@ -370,21 +433,39 @@ public: store32(dataTempRegister, address.m_ptr); } - void xor32(RegisterID src, RegisterID dest) + void xor32(RegisterID op1, RegisterID op2, RegisterID dest) { - m_assembler.eor(dest, dest, src); + m_assembler.eor(dest, op1, op2); } - void xor32(TrustedImm32 imm, RegisterID dest) + void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest) { + if (imm.m_value == -1) { + m_assembler.mvn(dest, src); + return; + } + ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value); if (armImm.isValid()) - m_assembler.eor(dest, dest, armImm); + m_assembler.eor(dest, src, armImm); else { move(imm, dataTempRegister); - m_assembler.eor(dest, dest, dataTempRegister); + m_assembler.eor(dest, src, dataTempRegister); } } + + void xor32(RegisterID src, RegisterID dest) + { + xor32(dest, src, dest); + } + + void xor32(TrustedImm32 imm, RegisterID dest) + { + if (imm.m_value == -1) + m_assembler.mvn(dest, dest); + else + xor32(imm, dest, dest); + } // Memory access operations: @@ -422,6 +503,12 @@ private: m_assembler.ldrh(dest, address.base, address.u.offset, true, false); } } + + void load16Signed(ArmAddress address, RegisterID dest) + { + ASSERT(address.type == ArmAddress::HasIndex); + m_assembler.ldrsh(dest, address.base, address.u.index, address.u.scale); + } void load8(ArmAddress address, RegisterID dest) { @@ -436,7 +523,14 @@ private: m_assembler.ldrb(dest, address.base, address.u.offset, true, false); } } + + void load8Signed(ArmAddress address, RegisterID dest) + { + ASSERT(address.type == ArmAddress::HasIndex); + m_assembler.ldrsb(dest, address.base, address.u.index, address.u.scale); + } +protected: void store32(RegisterID src, ArmAddress address) { if (address.type == ArmAddress::HasIndex) @@ -451,6 +545,35 @@ private: } } +private: + void store8(RegisterID src, ArmAddress address) + { + if (address.type == ArmAddress::HasIndex) + m_assembler.strb(src, address.base, address.u.index, address.u.scale); + else if (address.u.offset >= 0) { + ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.u.offset); + ASSERT(armImm.isValid()); + m_assembler.strb(src, address.base, armImm); + } else { + ASSERT(address.u.offset >= -255); + m_assembler.strb(src, address.base, address.u.offset, true, false); + } + } + + void store16(RegisterID src, ArmAddress address) + { + if (address.type == ArmAddress::HasIndex) + m_assembler.strh(src, address.base, address.u.index, address.u.scale); + else if (address.u.offset >= 0) { + ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.u.offset); + ASSERT(armImm.isValid()); + m_assembler.strh(src, address.base, armImm); + } else { + ASSERT(address.u.offset >= -255); + m_assembler.strh(src, address.base, address.u.offset, true, false); + } + } + public: void load32(ImplicitAddress address, RegisterID dest) { @@ -467,6 +590,11 @@ public: load32(setupArmAddress(address), dest); } + void load16Unaligned(BaseIndex address, RegisterID dest) + { + load16(setupArmAddress(address), dest); + } + void load32(const void* address, RegisterID dest) { move(TrustedImmPtr(address), addressTempRegister); @@ -478,6 +606,21 @@ public: load8(setupArmAddress(address), dest); } + void load8Signed(ImplicitAddress, RegisterID) + { + unreachableForPlatform(); + } + + void load8(BaseIndex address, RegisterID dest) + { + load8(setupArmAddress(address), dest); + } + + void load8Signed(BaseIndex address, RegisterID dest) + { + load8Signed(setupArmAddress(address), dest); + } + DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest) { DataLabel32 label = moveWithPatch(TrustedImm32(address.offset), dataTempRegister); @@ -485,13 +628,26 @@ public: return label; } + // FIXME: we should be able to plant a compact load relative to/from any base/dest register. DataLabelCompact load32WithCompactAddressOffsetPatch(Address address, RegisterID dest) { + RegisterID base = address.base; + + if (base >= ARMRegisters::r8) { + move(base, addressTempRegister); + base = addressTempRegister; + } + DataLabelCompact label(this); ASSERT(address.offset >= 0); ASSERT(address.offset <= MaximumCompactPtrAlignedAddressOffset); ASSERT(ARMThumbImmediate::makeUInt12(address.offset).isUInt7()); - m_assembler.ldrCompact(dest, address.base, ARMThumbImmediate::makeUInt12(address.offset)); + + if (dest >= ARMRegisters::r8) { + m_assembler.ldrCompact(addressTempRegister, base, ARMThumbImmediate::makeUInt12(address.offset)); + move(addressTempRegister, dest); + } else + m_assembler.ldrCompact(dest, base, ARMThumbImmediate::makeUInt12(address.offset)); return label; } @@ -500,6 +656,11 @@ public: m_assembler.ldrh(dest, makeBaseIndexBase(address), address.index, address.scale); } + void load16Signed(BaseIndex address, RegisterID dest) + { + load16Signed(setupArmAddress(address), dest); + } + void load16(ImplicitAddress address, RegisterID dest) { ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.offset); @@ -510,6 +671,11 @@ public: m_assembler.ldrh(dest, address.base, dataTempRegister); } } + + void load16Signed(ImplicitAddress, RegisterID) + { + unreachableForPlatform(); + } DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address) { @@ -534,6 +700,12 @@ public: store32(dataTempRegister, setupArmAddress(address)); } + void store32(TrustedImm32 imm, BaseIndex address) + { + move(imm, dataTempRegister); + store32(dataTempRegister, setupArmAddress(address)); + } + void store32(RegisterID src, const void* address) { move(TrustedImmPtr(address), addressTempRegister); @@ -546,27 +718,42 @@ public: store32(dataTempRegister, address); } + void store8(RegisterID src, BaseIndex address) + { + store8(src, setupArmAddress(address)); + } + + void store16(RegisterID src, BaseIndex address) + { + store16(src, setupArmAddress(address)); + } - // Floating-point operations: +#if ENABLE(JIT_CONSTANT_BLINDING) + static bool shouldBlindForSpecificArch(uint32_t value) + { + ARMThumbImmediate immediate = ARMThumbImmediate::makeEncodedImm(value); - bool supportsFloatingPoint() const { return true; } - // On x86(_64) the MacroAssembler provides an interface to truncate a double to an integer. - // If a value is not representable as an integer, and possibly for some values that are, - // (on x86 INT_MIN, since this is indistinguishable from results for out-of-range/NaN input) - // a branch will be taken. It is not clear whether this interface will be well suited to - // other platforms. On ARMv7 the hardware truncation operation produces multiple possible - // failure values (saturates to INT_MIN & INT_MAX, NaN reulsts in a value of 0). This is a - // temporary solution while we work out what this interface should be. Either we need to - // decide to make this interface work on all platforms, rework the interface to make it more - // generic, or decide that the MacroAssembler cannot practically be used to abstracted these - // operations, and make clients go directly to the m_assembler to plant truncation instructions. - // In short, FIXME:. - bool supportsFloatingPointTruncate() const { return false; } + // Couldn't be encoded as an immediate, so assume it's untrusted. + if (!immediate.isValid()) + return true; + + // If we can encode the immediate, we have less than 16 attacker + // controlled bits. + if (immediate.isEncodedImm()) + return false; - bool supportsFloatingPointSqrt() const - { - return false; + // Don't let any more than 12 bits of an instruction word + // be controlled by an attacker. + return !immediate.isUInt12(); } +#endif + + // Floating-point operations: + + static bool supportsFloatingPoint() { return true; } + static bool supportsFloatingPointTruncate() { return true; } + static bool supportsFloatingPointSqrt() { return true; } + static bool supportsFloatingPointAbs() { return true; } void loadDouble(ImplicitAddress address, FPRegisterID dest) { @@ -583,6 +770,43 @@ public: m_assembler.vldr(dest, base, offset); } + void loadFloat(ImplicitAddress address, FPRegisterID dest) + { + RegisterID base = address.base; + int32_t offset = address.offset; + + // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2. + if ((offset & 3) || (offset > (255 * 4)) || (offset < -(255 * 4))) { + add32(TrustedImm32(offset), base, addressTempRegister); + base = addressTempRegister; + offset = 0; + } + + m_assembler.flds(ARMRegisters::asSingle(dest), base, offset); + } + + void loadDouble(BaseIndex address, FPRegisterID dest) + { + move(address.index, addressTempRegister); + lshift32(TrustedImm32(address.scale), addressTempRegister); + add32(address.base, addressTempRegister); + loadDouble(Address(addressTempRegister, address.offset), dest); + } + + void loadFloat(BaseIndex address, FPRegisterID dest) + { + move(address.index, addressTempRegister); + lshift32(TrustedImm32(address.scale), addressTempRegister); + add32(address.base, addressTempRegister); + loadFloat(Address(addressTempRegister, address.offset), dest); + } + + void moveDouble(FPRegisterID src, FPRegisterID dest) + { + if (src != dest) + m_assembler.vmov(dest, src); + } + void loadDouble(const void* address, FPRegisterID dest) { move(TrustedImmPtr(address), addressTempRegister); @@ -604,9 +828,46 @@ public: m_assembler.vstr(src, base, offset); } + void storeFloat(FPRegisterID src, ImplicitAddress address) + { + RegisterID base = address.base; + int32_t offset = address.offset; + + // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2. + if ((offset & 3) || (offset > (255 * 4)) || (offset < -(255 * 4))) { + add32(TrustedImm32(offset), base, addressTempRegister); + base = addressTempRegister; + offset = 0; + } + + m_assembler.fsts(ARMRegisters::asSingle(src), base, offset); + } + + void storeDouble(FPRegisterID src, const void* address) + { + move(TrustedImmPtr(address), addressTempRegister); + storeDouble(src, addressTempRegister); + } + + void storeDouble(FPRegisterID src, BaseIndex address) + { + move(address.index, addressTempRegister); + lshift32(TrustedImm32(address.scale), addressTempRegister); + add32(address.base, addressTempRegister); + storeDouble(src, Address(addressTempRegister, address.offset)); + } + + void storeFloat(FPRegisterID src, BaseIndex address) + { + move(address.index, addressTempRegister); + lshift32(TrustedImm32(address.scale), addressTempRegister); + add32(address.base, addressTempRegister); + storeFloat(src, Address(addressTempRegister, address.offset)); + } + void addDouble(FPRegisterID src, FPRegisterID dest) { - m_assembler.vadd_F64(dest, dest, src); + m_assembler.vadd(dest, dest, src); } void addDouble(Address src, FPRegisterID dest) @@ -615,14 +876,30 @@ public: addDouble(fpTempRegister, dest); } + void addDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + m_assembler.vadd(dest, op1, op2); + } + + void addDouble(AbsoluteAddress address, FPRegisterID dest) + { + loadDouble(address.m_ptr, fpTempRegister); + m_assembler.vadd(dest, dest, fpTempRegister); + } + void divDouble(FPRegisterID src, FPRegisterID dest) { - m_assembler.vdiv_F64(dest, dest, src); + m_assembler.vdiv(dest, dest, src); + } + + void divDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + m_assembler.vdiv(dest, op1, op2); } void subDouble(FPRegisterID src, FPRegisterID dest) { - m_assembler.vsub_F64(dest, dest, src); + m_assembler.vsub(dest, dest, src); } void subDouble(Address src, FPRegisterID dest) @@ -631,9 +908,14 @@ public: subDouble(fpTempRegister, dest); } + void subDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + m_assembler.vsub(dest, op1, op2); + } + void mulDouble(FPRegisterID src, FPRegisterID dest) { - m_assembler.vmul_F64(dest, dest, src); + m_assembler.vmul(dest, dest, src); } void mulDouble(Address src, FPRegisterID dest) @@ -642,36 +924,61 @@ public: mulDouble(fpTempRegister, dest); } - void sqrtDouble(FPRegisterID, FPRegisterID) + void mulDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + m_assembler.vmul(dest, op1, op2); + } + + void sqrtDouble(FPRegisterID src, FPRegisterID dest) + { + m_assembler.vsqrt(dest, src); + } + + void absDouble(FPRegisterID src, FPRegisterID dest) + { + m_assembler.vabs(dest, src); + } + + void negateDouble(FPRegisterID src, FPRegisterID dest) { - ASSERT_NOT_REACHED(); + m_assembler.vneg(dest, src); } void convertInt32ToDouble(RegisterID src, FPRegisterID dest) { - m_assembler.vmov(fpTempRegisterAsSingle(), src); - m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle()); + m_assembler.vmov(fpTempRegister, src, src); + m_assembler.vcvt_signedToFloatingPoint(dest, fpTempRegisterAsSingle()); } void convertInt32ToDouble(Address address, FPRegisterID dest) { // Fixme: load directly into the fpr! load32(address, dataTempRegister); - m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister); - m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle()); + m_assembler.vmov(fpTempRegister, dataTempRegister, dataTempRegister); + m_assembler.vcvt_signedToFloatingPoint(dest, fpTempRegisterAsSingle()); } void convertInt32ToDouble(AbsoluteAddress address, FPRegisterID dest) { // Fixme: load directly into the fpr! load32(address.m_ptr, dataTempRegister); - m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister); - m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle()); + m_assembler.vmov(fpTempRegister, dataTempRegister, dataTempRegister); + m_assembler.vcvt_signedToFloatingPoint(dest, fpTempRegisterAsSingle()); + } + + void convertFloatToDouble(FPRegisterID src, FPRegisterID dst) + { + m_assembler.vcvtds(dst, ARMRegisters::asSingle(src)); + } + + void convertDoubleToFloat(FPRegisterID src, FPRegisterID dst) + { + m_assembler.vcvtsd(ARMRegisters::asSingle(dst), src); } Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right) { - m_assembler.vcmp_F64(left, right); + m_assembler.vcmp(left, right); m_assembler.vmrs(); if (cond == DoubleNotEqual) { @@ -693,23 +1000,72 @@ public: return makeBranch(cond); } - Jump branchTruncateDoubleToInt32(FPRegisterID, RegisterID) + enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful }; + Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed) { - ASSERT_NOT_REACHED(); - return jump(); + // Convert into dest. + m_assembler.vcvt_floatingPointToSigned(fpTempRegisterAsSingle(), src); + m_assembler.vmov(dest, fpTempRegisterAsSingle()); + + // Calculate 2x dest. If the value potentially underflowed, it will have + // clamped to 0x80000000, so 2x dest is zero in this case. In the case of + // overflow the result will be equal to -2. + Jump underflow = branchAdd32(Zero, dest, dest, dataTempRegister); + Jump noOverflow = branch32(NotEqual, dataTempRegister, TrustedImm32(-2)); + + // For BranchIfTruncateSuccessful, we branch if 'noOverflow' jumps. + underflow.link(this); + if (branchType == BranchIfTruncateSuccessful) + return noOverflow; + + // We'll reach the current point in the code on failure, so plant a + // jump here & link the success case. + Jump failure = jump(); + noOverflow.link(this); + return failure; } + Jump branchTruncateDoubleToUint32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed) + { + m_assembler.vcvt_floatingPointToSigned(fpTempRegisterAsSingle(), src); + m_assembler.vmov(dest, fpTempRegisterAsSingle()); + + Jump overflow = branch32(Equal, dest, TrustedImm32(0x7fffffff)); + Jump success = branch32(GreaterThanOrEqual, dest, TrustedImm32(0)); + overflow.link(this); + + if (branchType == BranchIfTruncateSuccessful) + return success; + + Jump failure = jump(); + success.link(this); + return failure; + } + + // Result is undefined if the value is outside of the integer range. + void truncateDoubleToInt32(FPRegisterID src, RegisterID dest) + { + m_assembler.vcvt_floatingPointToSigned(fpTempRegisterAsSingle(), src); + m_assembler.vmov(dest, fpTempRegisterAsSingle()); + } + + void truncateDoubleToUint32(FPRegisterID src, RegisterID dest) + { + m_assembler.vcvt_floatingPointToUnsigned(fpTempRegisterAsSingle(), src); + m_assembler.vmov(dest, fpTempRegisterAsSingle()); + } + // Convert 'src' to an integer, and places the resulting 'dest'. // If the result is not representable as a 32 bit value, branch. // May also branch for some values that are representable in 32 bits // (specifically, in this case, 0). void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID) { - m_assembler.vcvtr_S32_F64(fpTempRegisterAsSingle(), src); + m_assembler.vcvt_floatingPointToSigned(fpTempRegisterAsSingle(), src); m_assembler.vmov(dest, fpTempRegisterAsSingle()); // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump. - m_assembler.vcvt_F64_S32(fpTempRegister, fpTempRegisterAsSingle()); + m_assembler.vcvt_signedToFloatingPoint(fpTempRegister, fpTempRegisterAsSingle()); failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, fpTempRegister)); // If the result is zero, it might have been -0.0, and the double comparison won't catch this! @@ -718,7 +1074,7 @@ public: Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID) { - m_assembler.vcmpz_F64(reg); + m_assembler.vcmpz(reg); m_assembler.vmrs(); Jump unordered = makeBranch(ARMv7Assembler::ConditionVS); Jump result = makeBranch(ARMv7Assembler::ConditionNE); @@ -728,7 +1084,7 @@ public: Jump branchDoubleZeroOrNaN(FPRegisterID reg, FPRegisterID) { - m_assembler.vcmpz_F64(reg); + m_assembler.vcmpz(reg); m_assembler.vmrs(); Jump unordered = makeBranch(ARMv7Assembler::ConditionVS); Jump notEqual = makeBranch(ARMv7Assembler::ConditionNE); @@ -798,7 +1154,8 @@ public: void move(RegisterID src, RegisterID dest) { - m_assembler.mov(dest, src); + if (src != dest) + m_assembler.mov(dest, src); } void move(TrustedImmPtr imm, RegisterID dest) @@ -815,14 +1172,18 @@ public: void signExtend32ToPtr(RegisterID src, RegisterID dest) { - if (src != dest) - move(src, dest); + move(src, dest); } void zeroExtend32ToPtr(RegisterID src, RegisterID dest) { - if (src != dest) - move(src, dest); + move(src, dest); + } + + // Invert a relational condition, e.g. == becomes !=, < becomes >=, etc. + static RelationalCondition invert(RelationalCondition cond) + { + return static_cast(cond ^ 1); } void nop() @@ -944,22 +1305,6 @@ public: return branch32(cond, addressTempRegister, right); } - Jump branch16(RelationalCondition cond, BaseIndex left, RegisterID right) - { - load16(left, dataTempRegister); - m_assembler.lsl(addressTempRegister, right, 16); - m_assembler.lsl(dataTempRegister, dataTempRegister, 16); - return branch32(cond, dataTempRegister, addressTempRegister); - } - - Jump branch16(RelationalCondition cond, BaseIndex left, TrustedImm32 right) - { - // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/ - load16(left, addressTempRegister); - m_assembler.lsl(addressTempRegister, addressTempRegister, 16); - return branch32(cond, addressTempRegister, TrustedImm32(right.m_value << 16)); - } - Jump branch8(RelationalCondition cond, RegisterID left, TrustedImm32 right) { compare32(left, right); @@ -968,11 +1313,20 @@ public: Jump branch8(RelationalCondition cond, Address left, TrustedImm32 right) { + ASSERT(!(0xffffff00 & right.m_value)); // use addressTempRegister incase the branch8 we call uses dataTempRegister. :-/ load8(left, addressTempRegister); return branch8(cond, addressTempRegister, right); } + Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right) + { + ASSERT(!(0xffffff00 & right.m_value)); + // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/ + load8(left, addressTempRegister); + return branch32(cond, addressTempRegister, right); + } + Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask) { m_assembler.tst(reg, mask); @@ -999,17 +1353,11 @@ public: return branchTest32(cond, addressTempRegister, mask); } - Jump branchTest8(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) - { - test32(reg, mask); - return Jump(makeBranch(cond)); - } - Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) { // use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/ load8(address, addressTempRegister); - return branchTest8(cond, addressTempRegister, mask); + return branchTest32(cond, addressTempRegister, mask); } void jump(RegisterID target) @@ -1023,6 +1371,13 @@ public: load32(address, dataTempRegister); m_assembler.bx(dataTempRegister); } + + void jump(AbsoluteAddress address) + { + move(TrustedImmPtr(address.m_ptr), dataTempRegister); + load32(Address(dataTempRegister), dataTempRegister); + m_assembler.bx(dataTempRegister); + } // Arithmetic control flow operations: @@ -1035,21 +1390,57 @@ public: // * jo operations branch if the (signed) arithmetic // operation caused an overflow to occur. - Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest) + Jump branchAdd32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest) { - m_assembler.add_S(dest, dest, src); + m_assembler.add_S(dest, op1, op2); return Jump(makeBranch(cond)); } - Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest) + Jump branchAdd32(ResultCondition cond, RegisterID op1, TrustedImm32 imm, RegisterID dest) { ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value); if (armImm.isValid()) - m_assembler.add_S(dest, dest, armImm); + m_assembler.add_S(dest, op1, armImm); else { move(imm, dataTempRegister); - m_assembler.add_S(dest, dest, dataTempRegister); + m_assembler.add_S(dest, op1, dataTempRegister); + } + return Jump(makeBranch(cond)); + } + + Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest) + { + return branchAdd32(cond, dest, src, dest); + } + + Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest) + { + return branchAdd32(cond, dest, imm, dest); + } + + Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest) + { + // Move the high bits of the address into addressTempRegister, + // and load the value into dataTempRegister. + move(TrustedImmPtr(dest.m_ptr), addressTempRegister); + m_assembler.ldr(dataTempRegister, addressTempRegister, ARMThumbImmediate::makeUInt16(0)); + + // Do the add. + ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value); + if (armImm.isValid()) + m_assembler.add_S(dataTempRegister, dataTempRegister, armImm); + else { + // If the operand does not fit into an immediate then load it temporarily + // into addressTempRegister; since we're overwriting addressTempRegister + // we'll need to reload it with the high bits of the address afterwards. + move(imm, addressTempRegister); + m_assembler.add_S(dataTempRegister, dataTempRegister, addressTempRegister); + move(TrustedImmPtr(dest.m_ptr), addressTempRegister); } + + // Store the result. + m_assembler.str(dataTempRegister, addressTempRegister, ARMThumbImmediate::makeUInt16(0)); + return Jump(makeBranch(cond)); } @@ -1076,30 +1467,47 @@ public: return branchMul32(cond, dataTempRegister, src, dest); } + Jump branchNeg32(ResultCondition cond, RegisterID srcDest) + { + ARMThumbImmediate zero = ARMThumbImmediate::makeUInt12(0); + m_assembler.sub_S(srcDest, zero, srcDest); + return Jump(makeBranch(cond)); + } + Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest) { m_assembler.orr_S(dest, dest, src); return Jump(makeBranch(cond)); } - Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest) + Jump branchSub32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest) { - m_assembler.sub_S(dest, dest, src); + m_assembler.sub_S(dest, op1, op2); return Jump(makeBranch(cond)); } - Jump branchSub32(ResultCondition cond, TrustedImm32 imm, RegisterID dest) + Jump branchSub32(ResultCondition cond, RegisterID op1, TrustedImm32 imm, RegisterID dest) { ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value); if (armImm.isValid()) - m_assembler.sub_S(dest, dest, armImm); + m_assembler.sub_S(dest, op1, armImm); else { move(imm, dataTempRegister); - m_assembler.sub_S(dest, dest, dataTempRegister); + m_assembler.sub_S(dest, op1, dataTempRegister); } return Jump(makeBranch(cond)); } + Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest) + { + return branchSub32(cond, dest, src, dest); + } + + Jump branchSub32(ResultCondition cond, TrustedImm32 imm, RegisterID dest) + { + return branchSub32(cond, dest, imm, dest); + } + void relativeTableJump(RegisterID index, int scale) { ASSERT(scale >= 0 && scale <= 31); @@ -1115,9 +1523,9 @@ public: // Miscellaneous operations: - void breakpoint() + void breakpoint(uint8_t imm = 0) { - m_assembler.bkpt(0); + m_assembler.bkpt(imm); } ALWAYS_INLINE Call nearCall() @@ -1162,6 +1570,12 @@ public: compare32(cond, dataTempRegister, right, dest); } + void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest) + { + load8(left, addressTempRegister); + compare32(cond, addressTempRegister, right, dest); + } + void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest) { compare32(left, right); @@ -1217,6 +1631,22 @@ public: return branch32(cond, addressTempRegister, dataTempRegister); } + PatchableJump patchableBranchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) + { + m_makeJumpPatchable = true; + Jump result = branchPtrWithPatch(cond, left, dataLabel, initialRightValue); + m_makeJumpPatchable = false; + return PatchableJump(result); + } + + PatchableJump patchableJump() + { + m_makeJumpPatchable = true; + Jump result = jump(); + m_makeJumpPatchable = false; + return PatchableJump(result); + } + ALWAYS_INLINE DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address) { DataLabelPtr label = moveWithPatch(initialValue, dataTempRegister); @@ -1245,23 +1675,23 @@ public: return m_assembler.executableOffsetFor(location); } -protected: - bool inUninterruptedSequence() + static FunctionPtr readCallTarget(CodeLocationCall call) { - return m_inUninterruptedSequence; + return FunctionPtr(reinterpret_cast(ARMv7Assembler::readCallTarget(call.dataLocation()))); } +protected: ALWAYS_INLINE Jump jump() { moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister); - return Jump(m_assembler.bx(dataTempRegister), inUninterruptedSequence() ? ARMv7Assembler::JumpNoConditionFixedSize : ARMv7Assembler::JumpNoCondition); + return Jump(m_assembler.bx(dataTempRegister), m_makeJumpPatchable ? ARMv7Assembler::JumpNoConditionFixedSize : ARMv7Assembler::JumpNoCondition); } ALWAYS_INLINE Jump makeBranch(ARMv7Assembler::Condition cond) { m_assembler.it(cond, true, true); moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister); - return Jump(m_assembler.bx(dataTempRegister), inUninterruptedSequence() ? ARMv7Assembler::JumpConditionFixedSize : ARMv7Assembler::JumpCondition, cond); + return Jump(m_assembler.bx(dataTempRegister), m_makeJumpPatchable ? ARMv7Assembler::JumpConditionFixedSize : ARMv7Assembler::JumpCondition, cond); } ALWAYS_INLINE Jump makeBranch(RelationalCondition cond) { return makeBranch(armV7Condition(cond)); } ALWAYS_INLINE Jump makeBranch(ResultCondition cond) { return makeBranch(armV7Condition(cond)); } @@ -1338,14 +1768,14 @@ protected: { return static_cast(cond); } - + private: friend class LinkBuffer; friend class RepatchBuffer; static void linkCall(void* code, Call call, FunctionPtr function) { - ARMv7Assembler::linkCall(code, call.m_jmp, function.value()); + ARMv7Assembler::linkCall(code, call.m_label, function.value()); } static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) @@ -1357,8 +1787,8 @@ private: { ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); } - - bool m_inUninterruptedSequence; + + bool m_makeJumpPatchable; }; } // namespace JSC diff --git a/assembler/MacroAssemblerCodeRef.h b/assembler/MacroAssemblerCodeRef.h index 6d47cb9..ac62c42 100644 --- a/assembler/MacroAssemblerCodeRef.h +++ b/assembler/MacroAssemblerCodeRef.h @@ -27,11 +27,9 @@ #define MacroAssemblerCodeRef_h #include "ExecutableAllocator.h" -#include "PassRefPtr.h" -#include "RefPtr.h" -#include "UnusedParam.h" - -#if ENABLE(ASSEMBLER) +#include +#include +#include // 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). @@ -52,6 +50,32 @@ #define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes! #endif +#if CPU(X86) && OS(WINDOWS) +#define CALLING_CONVENTION_IS_STDCALL 1 +#ifndef CDECL +#if COMPILER(MSVC) +#define CDECL __cdecl +#else +#define CDECL __attribute__ ((__cdecl)) +#endif // COMPILER(MSVC) +#endif // CDECL +#else +#define CALLING_CONVENTION_IS_STDCALL 0 +#endif + +#if CPU(X86) +#define HAS_FASTCALL_CALLING_CONVENTION 1 +#ifndef FASTCALL +#if COMPILER(MSVC) +#define FASTCALL __fastcall +#else +#define FASTCALL __attribute__ ((fastcall)) +#endif // COMPILER(MSVC) +#endif // FASTCALL +#else +#define HAS_FASTCALL_CALLING_CONVENTION 0 +#endif // CPU(X86) + namespace JSC { // FunctionPtr: @@ -100,6 +124,84 @@ public: ASSERT_VALID_CODE_POINTER(m_value); } +// MSVC doesn't seem to treat functions with different calling conventions as +// different types; these methods already defined for fastcall, below. +#if CALLING_CONVENTION_IS_STDCALL && !OS(WINDOWS) + + template + FunctionPtr(returnType (CDECL *value)()) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } + + template + FunctionPtr(returnType (CDECL *value)(argType1)) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } + + template + FunctionPtr(returnType (CDECL *value)(argType1, argType2)) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } + + template + FunctionPtr(returnType (CDECL *value)(argType1, argType2, argType3)) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } + + template + FunctionPtr(returnType (CDECL *value)(argType1, argType2, argType3, argType4)) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } +#endif + +#if HAS_FASTCALL_CALLING_CONVENTION + + template + FunctionPtr(returnType (FASTCALL *value)()) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } + + template + FunctionPtr(returnType (FASTCALL *value)(argType1)) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } + + template + FunctionPtr(returnType (FASTCALL *value)(argType1, argType2)) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } + + template + FunctionPtr(returnType (FASTCALL *value)(argType1, argType2, argType3)) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } + + template + FunctionPtr(returnType (FASTCALL *value)(argType1, argType2, argType3, argType4)) + : m_value((void*)value) + { + ASSERT_VALID_CODE_POINTER(m_value); + } +#endif + template explicit FunctionPtr(FunctionType* value) // Using a C-ctyle cast here to avoid compiler error on RVTC: @@ -169,7 +271,19 @@ public: { ASSERT_VALID_CODE_POINTER(m_value); } + + static MacroAssemblerCodePtr createFromExecutableAddress(void* value) + { + ASSERT_VALID_CODE_POINTER(value); + MacroAssemblerCodePtr result; + result.m_value = value; + return result; + } + static MacroAssemblerCodePtr createLLIntCodePtr(void (*function)()) + { + return createFromExecutableAddress(bitwise_cast(function)); + } explicit MacroAssemblerCodePtr(ReturnAddressPtr ra) : m_value(ra.value()) { @@ -199,26 +313,67 @@ private: // pointer to the code, and a ref pointer to the pool from within which it // was allocated. class MacroAssemblerCodeRef { +private: + // This is private because it's dangerous enough that we want uses of it + // to be easy to find - hence the static create method below. + explicit MacroAssemblerCodeRef(MacroAssemblerCodePtr codePtr) + : m_codePtr(codePtr) + { + ASSERT(m_codePtr); + } + public: MacroAssemblerCodeRef() - : m_size(0) { } - MacroAssemblerCodeRef(void* code, PassRefPtr executablePool, size_t size) - : m_code(code) - , m_executablePool(executablePool) - , m_size(size) + MacroAssemblerCodeRef(PassRefPtr executableMemory) + : m_codePtr(executableMemory->start()) + , m_executableMemory(executableMemory) { + ASSERT(m_executableMemory->isManaged()); + ASSERT(m_executableMemory->start()); + ASSERT(m_codePtr); } + + // Use this only when you know that the codePtr refers to code that is + // already being kept alive through some other means. Typically this means + // that codePtr is immortal. + static MacroAssemblerCodeRef createSelfManagedCodeRef(MacroAssemblerCodePtr codePtr) + { + return MacroAssemblerCodeRef(codePtr); + } + + // Helper for creating self-managed code refs from LLInt. + static MacroAssemblerCodeRef createLLIntCodeRef(void (*function)()) + { + return createSelfManagedCodeRef(MacroAssemblerCodePtr::createFromExecutableAddress(bitwise_cast(function))); + } + + ExecutableMemoryHandle* executableMemory() const + { + return m_executableMemory.get(); + } + + MacroAssemblerCodePtr code() const + { + return m_codePtr; + } + + size_t size() const + { + if (!m_executableMemory) + return 0; + return m_executableMemory->sizeInBytes(); + } + + bool operator!() const { return !m_codePtr; } - MacroAssemblerCodePtr m_code; - RefPtr m_executablePool; - size_t m_size; +private: + MacroAssemblerCodePtr m_codePtr; + RefPtr m_executableMemory; }; } // namespace JSC -#endif // ENABLE(ASSEMBLER) - #endif // MacroAssemblerCodeRef_h diff --git a/assembler/MacroAssemblerMIPS.h b/assembler/MacroAssemblerMIPS.h index 9cdfffc..0a63c29 100644 --- a/assembler/MacroAssemblerMIPS.h +++ b/assembler/MacroAssemblerMIPS.h @@ -132,6 +132,11 @@ public: } } + void add32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + add32(imm, src, dest); + } + void add32(TrustedImm32 imm, Address address) { if (address.offset >= -32768 && address.offset <= 32767 @@ -291,14 +296,14 @@ public: m_assembler.subu(srcDest, MIPSRegisters::zero, srcDest); } - void not32(RegisterID srcDest) + void or32(RegisterID src, RegisterID dest) { - m_assembler.nor(srcDest, srcDest, MIPSRegisters::zero); + m_assembler.orInsn(dest, dest, src); } - void or32(RegisterID src, RegisterID dest) + void or32(RegisterID op1, RegisterID op2, RegisterID dest) { - m_assembler.orInsn(dest, dest, src); + m_assembler.orInsn(dest, op1, op2); } void or32(TrustedImm32 imm, RegisterID dest) @@ -330,6 +335,11 @@ public: m_assembler.sra(dest, dest, imm.m_value); } + void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + m_assembler.sra(dest, src, imm.m_value); + } + void urshift32(RegisterID shiftAmount, RegisterID dest) { m_assembler.srlv(dest, dest, shiftAmount); @@ -363,6 +373,24 @@ public: } } + void sub32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768 + && !m_fixedWidth) { + /* + addiu dest, src, imm + */ + m_assembler.addiu(dest, src, -imm.m_value); + } else { + /* + li immTemp, imm + subu dest, src, immTemp + */ + move(imm, immTempRegister); + m_assembler.subu(dest, src, immTempRegister); + } + } + void sub32(TrustedImm32 imm, Address address) { if (address.offset >= -32768 && address.offset <= 32767 @@ -448,6 +476,11 @@ public: void xor32(TrustedImm32 imm, RegisterID dest) { + if (imm.m_value == -1) { + m_assembler.nor(dest, dest, MIPSRegisters::zero); + return; + } + /* li immTemp, imm xor dest, dest, immTemp @@ -460,6 +493,11 @@ public: { m_assembler.sqrtd(dst, src); } + + void absDouble(FPRegisterID, FPRegisterID) + { + ASSERT_NOT_REACHED(); + } // Memory access operations: // @@ -486,6 +524,35 @@ public: } } + void load8(BaseIndex address, RegisterID dest) + { + if (address.offset >= -32768 && address.offset <= 32767 + && !m_fixedWidth) { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + lbu dest, address.offset(addrTemp) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.lbu(dest, addrTempRegister, address.offset); + } else { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + lui immTemp, (address.offset + 0x8000) >> 16 + addu addrTemp, addrTemp, immTemp + lbu dest, (address.offset & 0xffff)(at) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16); + m_assembler.addu(addrTempRegister, addrTempRegister, + immTempRegister); + m_assembler.lbu(dest, addrTempRegister, address.offset); + } + } + void load32(ImplicitAddress address, RegisterID dest) { if (address.offset >= -32768 && address.offset <= 32767 @@ -532,6 +599,11 @@ public: } } + void load16Unaligned(BaseIndex address, RegisterID dest) + { + load16(address, dest); + } + void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest) { if (address.offset >= -32768 && address.offset <= 32764 @@ -790,7 +862,7 @@ public: // Floating-point operations: - bool supportsFloatingPoint() const + static bool supportsFloatingPoint() { #if WTF_MIPS_DOUBLE_FLOAT return true; @@ -799,7 +871,7 @@ public: #endif } - bool supportsFloatingPointTruncate() const + static bool supportsFloatingPointTruncate() { #if WTF_MIPS_DOUBLE_FLOAT && WTF_MIPS_ISA_AT_LEAST(2) return true; @@ -808,7 +880,7 @@ public: #endif } - bool supportsFloatingPointSqrt() const + static bool supportsFloatingPointSqrt() { #if WTF_MIPS_DOUBLE_FLOAT && WTF_MIPS_ISA_AT_LEAST(2) return true; @@ -816,6 +888,7 @@ public: return false; #endif } + static bool supportsFloatingPointAbs() { return false; } // Stack manipulation operations: // @@ -921,6 +994,25 @@ public: return branch32(cond, dataTempRegister, immTempRegister); } + void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest) + { + // Make sure the immediate value is unsigned 8 bits. + ASSERT(!(right.m_value & 0xFFFFFF00)); + load8(left, dataTempRegister); + move(right, immTempRegister); + compare32(cond, dataTempRegister, immTempRegister, dest); + } + + Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right) + { + ASSERT(!(right.m_value & 0xFFFFFF00)); + load8(left, dataTempRegister); + // Be careful that the previous load8() uses immTempRegister. + // So, we need to put move() after load8(). + move(right, immTempRegister); + return branch32(cond, dataTempRegister, immTempRegister); + } + Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right) { if (cond == Equal) @@ -1021,22 +1113,6 @@ public: return branch32(cond, dataTempRegister, immTempRegister); } - Jump branch16(RelationalCondition cond, BaseIndex left, RegisterID right) - { - load16(left, dataTempRegister); - return branch32(cond, dataTempRegister, right); - } - - Jump branch16(RelationalCondition cond, BaseIndex left, TrustedImm32 right) - { - ASSERT(!(right.m_value & 0xFFFF0000)); - load16(left, dataTempRegister); - // Be careful that the previous load16() uses immTempRegister. - // So, we need to put move() after load16(). - move(right, immTempRegister); - return branch32(cond, dataTempRegister, immTempRegister); - } - Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask) { ASSERT((cond == Zero) || (cond == NonZero)); @@ -1159,6 +1235,13 @@ public: return branchAdd32(cond, immTempRegister, dest); } + Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest) + { + move(imm, immTempRegister); + move(src, dest); + return branchAdd32(cond, immTempRegister, dest); + } + Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); @@ -1264,6 +1347,13 @@ public: return branchSub32(cond, immTempRegister, dest); } + Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest) + { + move(imm, immTempRegister); + move(src, dest); + return branchSub32(cond, immTempRegister, dest); + } + Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero)); @@ -1776,6 +1866,11 @@ public: m_assembler.nop(); } + static FunctionPtr readCallTarget(CodeLocationCall call) + { + return FunctionPtr(reinterpret_cast(MIPSAssembler::readCallTarget(call.dataLocation()))); + } + private: // If m_fixedWidth is true, we will generate a fixed number of instructions. // Otherwise, we can emit any number of instructions. @@ -1786,7 +1881,7 @@ private: static void linkCall(void* code, Call call, FunctionPtr function) { - MIPSAssembler::linkCall(code, call.m_jmp, function.value()); + MIPSAssembler::linkCall(code, call.m_label, function.value()); } static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) diff --git a/assembler/MacroAssemblerSH4.cpp b/assembler/MacroAssemblerSH4.cpp index ee11f55..59de3ff 100644 --- a/assembler/MacroAssemblerSH4.cpp +++ b/assembler/MacroAssemblerSH4.cpp @@ -34,7 +34,7 @@ namespace JSC { void MacroAssemblerSH4::linkCall(void* code, Call call, FunctionPtr function) { - SH4Assembler::linkCall(code, call.m_jmp, function.value()); + SH4Assembler::linkCall(code, call.m_label, function.value()); } void MacroAssemblerSH4::repatchCall(CodeLocationCall call, CodeLocationLabel destination) diff --git a/assembler/MacroAssemblerSH4.h b/assembler/MacroAssemblerSH4.h index 8bed14c..c132ad6 100644 --- a/assembler/MacroAssemblerSH4.h +++ b/assembler/MacroAssemblerSH4.h @@ -29,8 +29,8 @@ #if ENABLE(ASSEMBLER) && CPU(SH4) -#include "AbstractMacroAssembler.h" #include "SH4Assembler.h" +#include "AbstractMacroAssembler.h" #include namespace JSC { @@ -45,7 +45,7 @@ public: static const RegisterID linkRegister = SH4Registers::pr; static const RegisterID scratchReg3 = SH4Registers::r13; - static const int MaximumCompactPtrAlignedAddressOffset = 0x7FFFFFFF; + static const int MaximumCompactPtrAlignedAddressOffset = 60; enum RelationalCondition { Equal = SH4Assembler::EQ, @@ -156,8 +156,27 @@ public: releaseScratch(scr); } + void and32(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + if (src != dest) { + move(imm, dest); + and32(src, dest); + return; + } + + and32(imm, dest); + } + void lshift32(RegisterID shiftamount, RegisterID dest) { + if (shiftamount == SH4Registers::r0) + m_assembler.andlImm8r(0x1f, shiftamount); + else { + RegisterID scr = claimScratch(); + m_assembler.loadConstant(0x1f, scr); + m_assembler.andlRegReg(scr, shiftamount); + releaseScratch(scr); + } m_assembler.shllRegReg(dest, shiftamount); } @@ -171,17 +190,28 @@ public: void lshift32(TrustedImm32 imm, RegisterID dest) { + if (!imm.m_value) + return; + if ((imm.m_value == 1) || (imm.m_value == 2) || (imm.m_value == 8) || (imm.m_value == 16)) { m_assembler.shllImm8r(imm.m_value, dest); return; } RegisterID scr = claimScratch(); - m_assembler.loadConstant(imm.m_value, scr); + m_assembler.loadConstant((imm.m_value & 0x1f) , scr); m_assembler.shllRegReg(dest, scr); releaseScratch(scr); } + void lshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest) + { + if (src != dest) + move(src, dest); + + lshift32(shiftamount, dest); + } + void mul32(RegisterID src, RegisterID dest) { m_assembler.imullRegReg(src, dest); @@ -198,11 +228,6 @@ public: releaseScratch(scr); } - void not32(RegisterID src, RegisterID dest) - { - m_assembler.notlReg(src, dest); - } - void or32(RegisterID src, RegisterID dest) { m_assembler.orlRegReg(src, dest); @@ -221,11 +246,51 @@ public: releaseScratch(scr); } + void or32(RegisterID op1, RegisterID op2, RegisterID dest) + { + if (op1 == op2) + move(op1, dest); + else if (op1 == dest) + or32(op2, dest); + else { + move(op2, dest); + or32(op1, dest); + } + } + + +void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + if (src != dest) { + move(imm, dest); + or32(src, dest); + return; + } + + or32(imm, dest); + } + + void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + if (src != dest) { + move(imm, dest); + xor32(src, dest); + return; + } + + xor32(imm, dest); + } + void rshift32(RegisterID shiftamount, RegisterID dest) { - compare32(32, shiftamount, Equal); - m_assembler.ensureSpace(m_assembler.maxInstructionSize + 4); - m_assembler.branch(BT_OPCODE, 1); + if (shiftamount == SH4Registers::r0) + m_assembler.andlImm8r(0x1f, shiftamount); + else { + RegisterID scr = claimScratch(); + m_assembler.loadConstant(0x1f, scr); + m_assembler.andlRegReg(scr, shiftamount); + releaseScratch(scr); + } m_assembler.neg(shiftamount, shiftamount); m_assembler.shaRegReg(dest, shiftamount); } @@ -236,6 +301,13 @@ public: rshift32(imm.m_value & 0x1f, dest); } + void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + if (src != dest) + move(src, dest); + rshift32(imm, dest); + } + void sub32(RegisterID src, RegisterID dest) { m_assembler.sublRegReg(src, dest); @@ -345,6 +417,11 @@ public: void xor32(TrustedImm32 imm, RegisterID srcDest) { + if (imm.m_value == -1) { + m_assembler.notlReg(srcDest, srcDest); + return; + } + if ((srcDest != SH4Registers::r0) || (imm.m_value > 255) || (imm.m_value < 0)) { RegisterID scr = claimScratch(); m_assembler.loadConstant((imm.m_value), scr); @@ -502,6 +579,16 @@ public: load8(address.base, address.offset, dest); } + void load8(BaseIndex address, RegisterID dest) + { + RegisterID scr = claimScratch(); + move(address.index, scr); + lshift32(TrustedImm32(address.scale), scr); + add32(address.base, scr); + load8(scr, address.offset, dest); + releaseScratch(scr); + } + void load32(BaseIndex address, RegisterID dest) { RegisterID scr = claimScratch(); @@ -512,9 +599,9 @@ public: releaseScratch(scr); } - void load32(void* address, RegisterID dest) + void load32(const void* address, RegisterID dest) { - m_assembler.loadConstant(reinterpret_cast(address), dest); + m_assembler.loadConstant(reinterpret_cast(const_cast(address)), dest); m_assembler.movlMemReg(dest, dest); } @@ -553,11 +640,13 @@ public: { if (!offset) { m_assembler.movbMemReg(base, dest); + m_assembler.extub(dest, dest); return; } if ((offset > 0) && (offset < 64) && (dest == SH4Registers::r0)) { m_assembler.movbMemReg(offset, base, dest); + m_assembler.extub(dest, dest); return; } @@ -565,6 +654,7 @@ public: m_assembler.loadConstant((offset), dest); m_assembler.addlRegReg(base, dest); m_assembler.movbMemReg(dest, dest); + m_assembler.extub(dest, dest); return; } @@ -572,6 +662,7 @@ public: m_assembler.loadConstant((offset), scr); m_assembler.addlRegReg(base, scr); m_assembler.movbMemReg(scr, dest); + m_assembler.extub(dest, dest); releaseScratch(scr); } @@ -590,11 +681,13 @@ public: { if (!address.offset) { m_assembler.movwMemReg(address.base, dest); + extuw(dest, dest); return; } if ((address.offset > 0) && (address.offset < 64) && (dest == SH4Registers::r0)) { m_assembler.movwMemReg(address.offset, address.base, dest); + extuw(dest, dest); return; } @@ -602,6 +695,7 @@ public: m_assembler.loadConstant((address.offset), dest); m_assembler.addlRegReg(address.base, dest); m_assembler.movwMemReg(dest, dest); + extuw(dest, dest); return; } @@ -609,18 +703,44 @@ public: m_assembler.loadConstant((address.offset), scr); m_assembler.addlRegReg(address.base, scr); m_assembler.movwMemReg(scr, dest); + extuw(dest, dest); releaseScratch(scr); } + void load16Unaligned(BaseIndex address, RegisterID dest) + { + + RegisterID scr = claimScratch(); + RegisterID scr1 = claimScratch(); + + move(address.index, scr); + lshift32(TrustedImm32(address.scale), scr); + + if (address.offset) + add32(TrustedImm32(address.offset), scr); + + add32(address.base, scr); + load8(scr, scr1); + add32(TrustedImm32(1), scr); + load8(scr, dest); + m_assembler.shllImm8r(8, dest); + or32(scr1, dest); + + releaseScratch(scr); + releaseScratch(scr1); + } + void load16(RegisterID src, RegisterID dest) { m_assembler.movwMemReg(src, dest); + extuw(dest, dest); } void load16(RegisterID r0, RegisterID src, RegisterID dest) { ASSERT(r0 == SH4Registers::r0); m_assembler.movwR0mr(src, dest); + extuw(dest, dest); } void load16(BaseIndex address, RegisterID dest) @@ -632,14 +752,13 @@ public: if (address.offset) add32(TrustedImm32(address.offset), scr); - if (scr == SH4Registers::r0) - m_assembler.movwR0mr(address.base, scr); + if (address.base == SH4Registers::r0) + load16(address.base, scr, dest); else { add32(address.base, scr); - load16(scr, scr); + load16(scr, dest); } - extuw(scr, dest); releaseScratch(scr); } @@ -711,7 +830,7 @@ public: RegisterID scr1 = claimScratch(); m_assembler.loadConstant((imm.m_value), scr); m_assembler.loadConstant(reinterpret_cast(address), scr1); - m_assembler.movlMemReg(scr, scr1); + m_assembler.movlRegMem(scr, scr1); releaseScratch(scr); releaseScratch(scr1); } @@ -720,7 +839,7 @@ public: { RegisterID scr = claimScratch(); m_assembler.loadConstant(reinterpret_cast(address), scr); - m_assembler.movlMemReg(src, scr); + m_assembler.movlRegMem(src, scr); releaseScratch(scr); } @@ -735,17 +854,6 @@ public: return label; } - DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest) - { - RegisterID scr = claimScratch(); - DataLabelCompact label(this); - m_assembler.loadConstantUnReusable(address.offset, scr); - m_assembler.addlRegReg(address.base, scr); - m_assembler.movlMemReg(scr, dest); - releaseScratch(scr); - return label; - } - DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address) { RegisterID scr = claimScratch(); @@ -757,11 +865,21 @@ public: return label; } + DataLabelCompact load32WithCompactAddressOffsetPatch(Address address, RegisterID dest) + { + DataLabelCompact dataLabel(this); + ASSERT(address.offset <= MaximumCompactPtrAlignedAddressOffset); + ASSERT(address.offset >= 0); + m_assembler.movlMemRegCompact(address.offset >> 2, address.base, dest); + return dataLabel; + } + // Floating-point operations - bool supportsFloatingPoint() const { return true; } - bool supportsFloatingPointTruncate() const { return true; } - bool supportsFloatingPointSqrt() const { return true; } + static bool supportsFloatingPoint() { return true; } + static bool supportsFloatingPointTruncate() { return true; } + static bool supportsFloatingPointSqrt() { return true; } + static bool supportsFloatingPointAbs() { return false; } void loadDouble(ImplicitAddress address, FPRegisterID dest) { @@ -865,6 +983,12 @@ public: void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest) { RegisterID scr = claimScratch(); + RegisterID scr1 = claimScratch(); + Jump m_jump; + JumpList end; + + if (dest != SH4Registers::r0) + move(SH4Registers::r0, scr1); move(address.index, scr); lshift32(TrustedImm32(address.scale), scr); @@ -873,13 +997,44 @@ public: if (address.offset) add32(TrustedImm32(address.offset), scr); - RegisterID scr1 = claimScratch(); + m_assembler.ensureSpace(m_assembler.maxInstructionSize + 68, sizeof(uint32_t)); + move(scr, SH4Registers::r0); + m_assembler.andlImm8r(0x3, SH4Registers::r0); + m_assembler.cmpEqImmR0(0x0, SH4Registers::r0); + m_jump = Jump(m_assembler.jne(), SH4Assembler::JumpNear); + if (dest != SH4Registers::r0) + move(scr1, SH4Registers::r0); + + load32(scr, dest); + end.append(Jump(m_assembler.bra(), SH4Assembler::JumpNear)); + m_assembler.nop(); + m_jump.link(this); + m_assembler.andlImm8r(0x1, SH4Registers::r0); + m_assembler.cmpEqImmR0(0x0, SH4Registers::r0); + + if (dest != SH4Registers::r0) + move(scr1, SH4Registers::r0); + + m_jump = Jump(m_assembler.jne(), SH4Assembler::JumpNear); load16(scr, scr1); add32(TrustedImm32(2), scr); load16(scr, dest); - move(TrustedImm32(16), scr); - m_assembler.shllRegReg(dest, scr); + m_assembler.shllImm8r(16, dest); or32(scr1, dest); + end.append(Jump(m_assembler.bra(), SH4Assembler::JumpNear)); + m_assembler.nop(); + m_jump.link(this); + load8(scr, scr1); + add32(TrustedImm32(1), scr); + load16(scr, dest); + m_assembler.shllImm8r(8, dest); + or32(dest, scr1); + add32(TrustedImm32(2), scr); + load8(scr, dest); + m_assembler.shllImm8r(8, dest); + m_assembler.shllImm8r(16, dest); + or32(scr1, dest); + end.link(this); releaseScratch(scr); releaseScratch(scr1); @@ -922,19 +1077,22 @@ public: if (cond == DoubleNotEqual) { RegisterID scr = claimScratch(); + JumpList end; m_assembler.loadConstant(0x7fbfffff, scratchReg3); m_assembler.dcnvds(right); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - m_assembler.branch(BT_OPCODE, 8); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcnvds(left); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - m_assembler.branch(BT_OPCODE, 4); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcmppeq(right, left); releaseScratch(scr); - return branchFalse(); + Jump m_jump = branchFalse(); + end.link(this); + return m_jump; } if (cond == DoubleGreaterThan) { @@ -959,113 +1117,135 @@ public: if (cond == DoubleEqualOrUnordered) { RegisterID scr = claimScratch(); + JumpList end; m_assembler.loadConstant(0x7fbfffff, scratchReg3); m_assembler.dcnvds(right); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - m_assembler.branch(BT_OPCODE, 5); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcnvds(left); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - m_assembler.branch(BT_OPCODE, 1); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcmppeq(left, right); + Jump m_jump = Jump(m_assembler.je()); + end.link(this); + m_assembler.extraInstrForBranch(scr); releaseScratch(scr); - return branchTrue(); + return m_jump; } if (cond == DoubleGreaterThanOrUnordered) { RegisterID scr = claimScratch(); + JumpList end; m_assembler.loadConstant(0x7fbfffff, scratchReg3); m_assembler.dcnvds(right); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - m_assembler.branch(BT_OPCODE, 5); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcnvds(left); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - m_assembler.branch(BT_OPCODE, 1); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(right, left); + Jump m_jump = Jump(m_assembler.je()); + end.link(this); + m_assembler.extraInstrForBranch(scr); releaseScratch(scr); - return branchTrue(); + return m_jump; } if (cond == DoubleGreaterThanOrEqualOrUnordered) { RegisterID scr = claimScratch(); + JumpList end; m_assembler.loadConstant(0x7fbfffff, scratchReg3); m_assembler.dcnvds(right); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - m_assembler.branch(BT_OPCODE, 5); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcnvds(left); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - m_assembler.branch(BT_OPCODE, 1); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(left, right); + Jump m_jump = Jump(m_assembler.jne()); + end.link(this); + m_assembler.extraInstrForBranch(scr); releaseScratch(scr); - return branchFalse(); + return m_jump; } if (cond == DoubleLessThanOrUnordered) { RegisterID scr = claimScratch(); + JumpList end; m_assembler.loadConstant(0x7fbfffff, scratchReg3); m_assembler.dcnvds(right); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - m_assembler.branch(BT_OPCODE, 5); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcnvds(left); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - m_assembler.branch(BT_OPCODE, 1); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(left, right); + Jump m_jump = Jump(m_assembler.je()); + end.link(this); + m_assembler.extraInstrForBranch(scr); releaseScratch(scr); - return branchTrue(); + return m_jump; } if (cond == DoubleLessThanOrEqualOrUnordered) { RegisterID scr = claimScratch(); + JumpList end; m_assembler.loadConstant(0x7fbfffff, scratchReg3); m_assembler.dcnvds(right); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - m_assembler.branch(BT_OPCODE, 5); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcnvds(left); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - m_assembler.branch(BT_OPCODE, 1); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(right, left); + Jump m_jump = Jump(m_assembler.jne()); + end.link(this); + m_assembler.extraInstrForBranch(scr); releaseScratch(scr); - return branchFalse(); + return m_jump; } ASSERT(cond == DoubleNotEqualOrUnordered); RegisterID scr = claimScratch(); + JumpList end; m_assembler.loadConstant(0x7fbfffff, scratchReg3); m_assembler.dcnvds(right); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - m_assembler.branch(BT_OPCODE, 5); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcnvds(left); m_assembler.stsfpulReg(scr); m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - m_assembler.branch(BT_OPCODE, 1); + end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcmppeq(right, left); + Jump m_jump = Jump(m_assembler.jne()); + end.link(this); + m_assembler.extraInstrForBranch(scr); releaseScratch(scr); - return branchFalse(); + return m_jump; } Jump branchTrue() { m_assembler.ensureSpace(m_assembler.maxInstructionSize + 6, sizeof(uint32_t)); Jump m_jump = Jump(m_assembler.je()); - m_assembler.loadConstantUnReusable(0x0, scratchReg3); - m_assembler.nop(); - m_assembler.nop(); + m_assembler.extraInstrForBranch(scratchReg3); return m_jump; } @@ -1073,9 +1253,7 @@ public: { m_assembler.ensureSpace(m_assembler.maxInstructionSize + 6, sizeof(uint32_t)); Jump m_jump = Jump(m_assembler.jne()); - m_assembler.loadConstantUnReusable(0x0, scratchReg3); - m_assembler.nop(); - m_assembler.nop(); + m_assembler.extraInstrForBranch(scratchReg3); return m_jump; } @@ -1100,6 +1278,11 @@ public: m_assembler.dmovRegReg(src, dest); m_assembler.dsqrt(dest); } + + void absDouble(FPRegisterID, FPRegisterID) + { + ASSERT_NOT_REACHED(); + } Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) { @@ -1125,6 +1308,14 @@ public: return jmp; } + void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest) + { + RegisterID addressTempRegister = claimScratch(); + load8(left, addressTempRegister); + compare32(cond, addressTempRegister, right, dest); + releaseScratch(addressTempRegister); + } + Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest) { m_assembler.ftrcdrmfpul(src); @@ -1188,14 +1379,16 @@ public: DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest) { + m_assembler.ensureSpace(m_assembler.maxInstructionSize, sizeof(uint32_t)); DataLabelPtr dataLabel(this); - m_assembler.loadConstantUnReusable(reinterpret_cast(initialValue.m_value), dest, true); + m_assembler.loadConstantUnReusable(reinterpret_cast(initialValue.m_value), dest); return dataLabel; } void move(RegisterID src, RegisterID dest) { - m_assembler.movlRegReg(src, dest); + if (src != dest) + m_assembler.movlRegReg(src, dest); } void move(TrustedImmPtr imm, RegisterID dest) @@ -1340,25 +1533,9 @@ public: return branchTrue(); } - Jump branch16(RelationalCondition cond, BaseIndex left, RegisterID right) - { - RegisterID scr = claimScratch(); - - move(left.index, scr); - lshift32(TrustedImm32(left.scale), scr); - - if (left.offset) - add32(TrustedImm32(left.offset), scr); - add32(left.base, scr); - load16(scr, scr); - extuw(scr, scr); - releaseScratch(scr); - - return branch32(cond, scr, right); - } - - Jump branch16(RelationalCondition cond, BaseIndex left, TrustedImm32 right) + Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right) { + ASSERT(!(right.m_value & 0xFFFFFF00)); RegisterID scr = claimScratch(); move(left.index, scr); @@ -1367,8 +1544,7 @@ public: if (left.offset) add32(TrustedImm32(left.offset), scr); add32(left.base, scr); - load16(scr, scr); - extuw(scr, scr); + load8(scr, scr); RegisterID scr1 = claimScratch(); m_assembler.loadConstant(right.m_value, scr1); releaseScratch(scr); @@ -1498,6 +1674,33 @@ public: return branchAdd32(cond, scratchReg3, dest); } + Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + + if (src != dest) + move(src, dest); + + if (cond == Overflow) { + move(imm, scratchReg3); + m_assembler.addvlRegReg(scratchReg3, dest); + return branchTrue(); + } + + add32(imm, dest); + + if (cond == Signed) { + m_assembler.cmppz(dest); + return branchFalse(); + } + + compare32(0, dest, Equal); + + if (cond == NotEqual) + return branchFalse(); + return branchTrue(); + } + Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); @@ -1575,6 +1778,21 @@ public: return branchSub32(cond, scratchReg3, dest); } + Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest) + { + move(imm, scratchReg3); + if (src != dest) + move(src, dest); + return branchSub32(cond, scratchReg3, dest); + } + + Jump branchSub32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest) + { + if (src1 != dest) + move(src1, dest); + return branchSub32(cond, src2, dest); + } + Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero)); @@ -1614,16 +1832,16 @@ public: m_assembler.neg(dst, dst); } - void not32(RegisterID dst) - { - m_assembler.notlReg(dst, dst); - } - void urshift32(RegisterID shiftamount, RegisterID dest) { - compare32(32, shiftamount, Equal); - m_assembler.ensureSpace(m_assembler.maxInstructionSize + 4); - m_assembler.branch(BT_OPCODE, 1); + if (shiftamount == SH4Registers::r0) + m_assembler.andlImm8r(0x1f, shiftamount); + else { + RegisterID scr = claimScratch(); + m_assembler.loadConstant(0x1f, scr); + m_assembler.andlRegReg(scr, shiftamount); + releaseScratch(scr); + } m_assembler.neg(shiftamount, shiftamount); m_assembler.shllRegReg(dest, shiftamount); } @@ -1631,11 +1849,19 @@ public: void urshift32(TrustedImm32 imm, RegisterID dest) { RegisterID scr = claimScratch(); - m_assembler.loadConstant(-(imm.m_value), scr); + m_assembler.loadConstant(-(imm.m_value & 0x1f), scr); m_assembler.shaRegReg(dest, scr); releaseScratch(scr); } + void urshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest) + { + if (src != dest) + move(src, dest); + + urshift32(shiftamount, dest); + } + Call call() { return Call(m_assembler.call(), Call::Linkable); @@ -1740,6 +1966,11 @@ public: m_assembler.nop(); } + static FunctionPtr readCallTarget(CodeLocationCall call) + { + return FunctionPtr(reinterpret_cast(SH4Assembler::readCallTarget(call.dataLocation()))); + } + protected: SH4Assembler::Condition SH4Condition(RelationalCondition cond) { diff --git a/assembler/MacroAssemblerX86.h b/assembler/MacroAssemblerX86.h index a1657e6..088fe19 100644 --- a/assembler/MacroAssemblerX86.h +++ b/assembler/MacroAssemblerX86.h @@ -34,22 +34,22 @@ namespace JSC { class MacroAssemblerX86 : public MacroAssemblerX86Common { public: - MacroAssemblerX86() - : m_isSSE2Present(isSSE2Present()) - { - } - static const Scale ScalePtr = TimesFour; using MacroAssemblerX86Common::add32; using MacroAssemblerX86Common::and32; + using MacroAssemblerX86Common::branchAdd32; + using MacroAssemblerX86Common::branchSub32; using MacroAssemblerX86Common::sub32; using MacroAssemblerX86Common::or32; using MacroAssemblerX86Common::load32; using MacroAssemblerX86Common::store32; using MacroAssemblerX86Common::branch32; using MacroAssemblerX86Common::call; + using MacroAssemblerX86Common::jump; + using MacroAssemblerX86Common::addDouble; using MacroAssemblerX86Common::loadDouble; + using MacroAssemblerX86Common::storeDouble; using MacroAssemblerX86Common::convertInt32ToDouble; void add32(TrustedImm32 imm, RegisterID src, RegisterID dest) @@ -62,11 +62,12 @@ public: m_assembler.addl_im(imm.m_value, address.m_ptr); } - void addWithCarry32(TrustedImm32 imm, AbsoluteAddress address) + void add64(TrustedImm32 imm, AbsoluteAddress address) { - m_assembler.adcl_im(imm.m_value, address.m_ptr); + m_assembler.addl_im(imm.m_value, address.m_ptr); + m_assembler.adcl_im(imm.m_value >> 31, reinterpret_cast(address.m_ptr) + sizeof(int32_t)); } - + void and32(TrustedImm32 imm, AbsoluteAddress address) { m_assembler.andl_im(imm.m_value, address.m_ptr); @@ -82,15 +83,20 @@ public: m_assembler.subl_im(imm.m_value, address.m_ptr); } - void load32(void* address, RegisterID dest) + void load32(const void* address, RegisterID dest) { m_assembler.movl_mr(address, dest); } - void loadDouble(const void* address, FPRegisterID dest) + void addDouble(AbsoluteAddress address, FPRegisterID dest) + { + m_assembler.addsd_mr(address.m_ptr, dest); + } + + void storeDouble(FPRegisterID src, const void* address) { ASSERT(isSSE2Present()); - m_assembler.movsd_mr(address, dest); + m_assembler.movsd_rm(src, address); } void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest) @@ -108,6 +114,18 @@ public: m_assembler.movl_rm(src, address); } + Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest) + { + m_assembler.addl_im(imm.m_value, dest.m_ptr); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + + Jump branchSub32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest) + { + m_assembler.subl_im(imm.m_value, dest.m_ptr); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + Jump branch32(RelationalCondition cond, AbsoluteAddress left, RegisterID right) { m_assembler.cmpl_rm(right, left.m_ptr); @@ -125,6 +143,12 @@ public: return Call(m_assembler.call(), Call::Linkable); } + // Address is a memory location containing the address to jump to + void jump(AbsoluteAddress address) + { + m_assembler.jmp_m(address.m_ptr); + } + Call tailRecursiveCall() { return Call::fromTailJump(jump()); @@ -162,20 +186,25 @@ public: return DataLabelPtr(this); } - bool supportsFloatingPoint() const { return m_isSSE2Present; } + static bool supportsFloatingPoint() { return isSSE2Present(); } // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate() - bool supportsFloatingPointTruncate() const { return m_isSSE2Present; } - bool supportsFloatingPointSqrt() const { return m_isSSE2Present; } + static bool supportsFloatingPointTruncate() { return isSSE2Present(); } + static bool supportsFloatingPointSqrt() { return isSSE2Present(); } + static bool supportsFloatingPointAbs() { return isSSE2Present(); } + + static FunctionPtr readCallTarget(CodeLocationCall call) + { + intptr_t offset = reinterpret_cast(call.dataLocation())[-1]; + return FunctionPtr(reinterpret_cast(reinterpret_cast(call.dataLocation()) + offset)); + } private: - const bool m_isSSE2Present; - friend class LinkBuffer; friend class RepatchBuffer; static void linkCall(void* code, Call call, FunctionPtr function) { - X86Assembler::linkCall(code, call.m_jmp, function.value()); + X86Assembler::linkCall(code, call.m_label, function.value()); } static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) diff --git a/assembler/MacroAssemblerX86Common.h b/assembler/MacroAssemblerX86Common.h index 933b36b..e398dcd 100644 --- a/assembler/MacroAssemblerX86Common.h +++ b/assembler/MacroAssemblerX86Common.h @@ -34,12 +34,18 @@ namespace JSC { class MacroAssemblerX86Common : public AbstractMacroAssembler { +protected: +#if CPU(X86_64) + static const X86Registers::RegisterID scratchRegister = X86Registers::r11; +#endif + static const int DoubleConditionBitInvert = 0x10; static const int DoubleConditionBitSpecial = 0x20; static const int DoubleConditionBits = DoubleConditionBitInvert | DoubleConditionBitSpecial; public: typedef X86Assembler::FPRegisterID FPRegisterID; + typedef X86Assembler::XMMRegisterID XMMRegisterID; static const int MaximumCompactPtrAlignedAddressOffset = 127; @@ -85,6 +91,13 @@ public: static const RegisterID stackPointerRegister = X86Registers::esp; +#if ENABLE(JIT_CONSTANT_BLINDING) + static bool shouldBlindForSpecificArch(uint32_t value) { return value >= 0x00ffffff; } +#if CPU(X86_64) + static bool shouldBlindForSpecificArch(uintptr_t value) { return value >= 0x00ffffff; } +#endif +#endif + // Integer arithmetic operations: // // Operations are typically two operand - operation(source, srcDst) @@ -116,6 +129,11 @@ public: { m_assembler.addl_rm(src, dest.offset, dest.base); } + + void add32(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + m_assembler.leal_mr(imm.m_value, src, dest); + } void and32(RegisterID src, RegisterID dest) { @@ -222,16 +240,6 @@ public: m_assembler.negl_m(srcDest.offset, srcDest.base); } - void not32(RegisterID srcDest) - { - m_assembler.notl_r(srcDest); - } - - void not32(Address srcDest) - { - m_assembler.notl_m(srcDest.offset, srcDest.base); - } - void or32(RegisterID src, RegisterID dest) { m_assembler.orl_rr(src, dest); @@ -374,7 +382,6 @@ public: m_assembler.subl_rm(src, dest.offset, dest.base); } - void xor32(RegisterID src, RegisterID dest) { m_assembler.xorl_rr(src, dest); @@ -382,11 +389,17 @@ public: void xor32(TrustedImm32 imm, Address dest) { - m_assembler.xorl_im(imm.m_value, dest.offset, dest.base); + if (imm.m_value == -1) + m_assembler.notl_m(dest.offset, dest.base); + else + m_assembler.xorl_im(imm.m_value, dest.offset, dest.base); } void xor32(TrustedImm32 imm, RegisterID dest) { + if (imm.m_value == -1) + m_assembler.notl_r(dest); + else m_assembler.xorl_ir(imm.m_value, dest); } @@ -423,6 +436,23 @@ public: m_assembler.sqrtsd_rr(src, dst); } + void absDouble(FPRegisterID src, FPRegisterID dst) + { + ASSERT(src != dst); + static const double negativeZeroConstant = -0.0; + loadDouble(&negativeZeroConstant, dst); + m_assembler.andnpd_rr(src, dst); + } + + void negateDouble(FPRegisterID src, FPRegisterID dst) + { + ASSERT(src != dst); + static const double negativeZeroConstant = -0.0; + loadDouble(&negativeZeroConstant, dst); + m_assembler.xorpd_rr(src, dst); + } + + // Memory access operations: // // Loads are of the form load(address, destination) and stores of the form @@ -445,6 +475,11 @@ public: load32(address, dest); } + void load16Unaligned(BaseIndex address, RegisterID dest) + { + load16(address, dest); + } + DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest) { m_assembler.movl_mr_disp32(address.offset, address.base, dest); @@ -470,6 +505,26 @@ public: return DataLabelCompact(this); } + void load8(BaseIndex address, RegisterID dest) + { + m_assembler.movzbl_mr(address.offset, address.base, address.index, address.scale, dest); + } + + void load8(ImplicitAddress address, RegisterID dest) + { + m_assembler.movzbl_mr(address.offset, address.base, dest); + } + + void load8Signed(BaseIndex address, RegisterID dest) + { + m_assembler.movsbl_mr(address.offset, address.base, address.index, address.scale, dest); + } + + void load8Signed(ImplicitAddress address, RegisterID dest) + { + m_assembler.movsbl_mr(address.offset, address.base, dest); + } + void load16(BaseIndex address, RegisterID dest) { m_assembler.movzwl_mr(address.offset, address.base, address.index, address.scale, dest); @@ -480,6 +535,16 @@ public: m_assembler.movzwl_mr(address.offset, address.base, dest); } + void load16Signed(BaseIndex address, RegisterID dest) + { + m_assembler.movswl_mr(address.offset, address.base, address.index, address.scale, dest); + } + + void load16Signed(Address address, RegisterID dest) + { + m_assembler.movswl_mr(address.offset, address.base, dest); + } + DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address) { m_assembler.movl_rm_disp32(src, address.offset, address.base); @@ -500,6 +565,77 @@ public: { m_assembler.movl_i32m(imm.m_value, address.offset, address.base); } + + void store32(TrustedImm32 imm, BaseIndex address) + { + m_assembler.movl_i32m(imm.m_value, address.offset, address.base, address.index, address.scale); + } + + void store8(TrustedImm32 imm, Address address) + { + ASSERT(-128 <= imm.m_value && imm.m_value < 128); + m_assembler.movb_i8m(imm.m_value, address.offset, address.base); + } + + void store8(TrustedImm32 imm, BaseIndex address) + { + ASSERT(-128 <= imm.m_value && imm.m_value < 128); + m_assembler.movb_i8m(imm.m_value, address.offset, address.base, address.index, address.scale); + } + + void store8(RegisterID src, BaseIndex address) + { +#if CPU(X86) + // On 32-bit x86 we can only store from the first 4 registers; + // esp..edi are mapped to the 'h' registers! + if (src >= 4) { + // Pick a temporary register. + RegisterID temp; + if (address.base != X86Registers::eax && address.index != X86Registers::eax) + temp = X86Registers::eax; + else if (address.base != X86Registers::ebx && address.index != X86Registers::ebx) + temp = X86Registers::ebx; + else { + ASSERT(address.base != X86Registers::ecx && address.index != X86Registers::ecx); + temp = X86Registers::ecx; + } + + // Swap to the temporary register to perform the store. + swap(src, temp); + m_assembler.movb_rm(temp, address.offset, address.base, address.index, address.scale); + swap(src, temp); + return; + } +#endif + m_assembler.movb_rm(src, address.offset, address.base, address.index, address.scale); + } + + void store16(RegisterID src, BaseIndex address) + { +#if CPU(X86) + // On 32-bit x86 we can only store from the first 4 registers; + // esp..edi are mapped to the 'h' registers! + if (src >= 4) { + // Pick a temporary register. + RegisterID temp; + if (address.base != X86Registers::eax && address.index != X86Registers::eax) + temp = X86Registers::eax; + else if (address.base != X86Registers::ebx && address.index != X86Registers::ebx) + temp = X86Registers::ebx; + else { + ASSERT(address.base != X86Registers::ecx && address.index != X86Registers::ecx); + temp = X86Registers::ecx; + } + + // Swap to the temporary register to perform the store. + swap(src, temp); + m_assembler.movw_rm(temp, address.offset, address.base, address.index, address.scale); + swap(src, temp); + return; + } +#endif + m_assembler.movw_rm(src, address.offset, address.base, address.index, address.scale); + } // Floating-point operation: @@ -513,17 +649,63 @@ public: m_assembler.movsd_rr(src, dest); } + void loadDouble(const void* address, FPRegisterID dest) + { +#if CPU(X86) + ASSERT(isSSE2Present()); + m_assembler.movsd_mr(address, dest); +#else + move(TrustedImmPtr(address), scratchRegister); + loadDouble(scratchRegister, dest); +#endif + } + void loadDouble(ImplicitAddress address, FPRegisterID dest) { ASSERT(isSSE2Present()); m_assembler.movsd_mr(address.offset, address.base, dest); } + + void loadDouble(BaseIndex address, FPRegisterID dest) + { + ASSERT(isSSE2Present()); + m_assembler.movsd_mr(address.offset, address.base, address.index, address.scale, dest); + } + void loadFloat(BaseIndex address, FPRegisterID dest) + { + ASSERT(isSSE2Present()); + m_assembler.movss_mr(address.offset, address.base, address.index, address.scale, dest); + } void storeDouble(FPRegisterID src, ImplicitAddress address) { ASSERT(isSSE2Present()); m_assembler.movsd_rm(src, address.offset, address.base); } + + void storeDouble(FPRegisterID src, BaseIndex address) + { + ASSERT(isSSE2Present()); + m_assembler.movsd_rm(src, address.offset, address.base, address.index, address.scale); + } + + void storeFloat(FPRegisterID src, BaseIndex address) + { + ASSERT(isSSE2Present()); + m_assembler.movss_rm(src, address.offset, address.base, address.index, address.scale); + } + + void convertDoubleToFloat(FPRegisterID src, FPRegisterID dst) + { + ASSERT(isSSE2Present()); + m_assembler.cvtsd2ss_rr(src, dst); + } + + void convertFloatToDouble(FPRegisterID src, FPRegisterID dst) + { + ASSERT(isSSE2Present()); + m_assembler.cvtss2sd_rr(src, dst); + } void addDouble(FPRegisterID src, FPRegisterID dest) { @@ -664,6 +846,27 @@ public: return branch32(branchType ? NotEqual : Equal, dest, TrustedImm32(0x80000000)); } + Jump branchTruncateDoubleToUint32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed) + { + ASSERT(isSSE2Present()); + m_assembler.cvttsd2si_rr(src, dest); + return branch32(branchType ? GreaterThanOrEqual : LessThan, dest, TrustedImm32(0)); + } + + void truncateDoubleToInt32(FPRegisterID src, RegisterID dest) + { + ASSERT(isSSE2Present()); + m_assembler.cvttsd2si_rr(src, dest); + } + +#if CPU(X86_64) + void truncateDoubleToUint32(FPRegisterID src, RegisterID dest) + { + ASSERT(isSSE2Present()); + m_assembler.cvttsd2siq_rr(src, dest); + } +#endif + // Convert 'src' to an integer, and places the resulting 'dest'. // If the result is not representable as a 32 bit value, branch. // May also branch for some values that are representable in 32 bits @@ -697,6 +900,36 @@ public: return branchDouble(DoubleEqualOrUnordered, reg, scratch); } + void lshiftPacked(TrustedImm32 imm, XMMRegisterID reg) + { + ASSERT(isSSE2Present()); + m_assembler.psllq_i8r(imm.m_value, reg); + } + + void rshiftPacked(TrustedImm32 imm, XMMRegisterID reg) + { + ASSERT(isSSE2Present()); + m_assembler.psrlq_i8r(imm.m_value, reg); + } + + void orPacked(XMMRegisterID src, XMMRegisterID dst) + { + ASSERT(isSSE2Present()); + m_assembler.por_rr(src, dst); + } + + void moveInt32ToPacked(RegisterID src, XMMRegisterID dst) + { + ASSERT(isSSE2Present()); + m_assembler.movd_rr(src, dst); + } + + void movePackedToInt32(XMMRegisterID src, RegisterID dst) + { + ASSERT(isSSE2Present()); + m_assembler.movd_rr(src, dst); + } + // Stack manipulation operations: // // The ABI is assumed to provide a stack abstraction to memory, @@ -839,15 +1072,6 @@ public: return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branch32(RelationalCondition cond, TrustedImm32 left, RegisterID right) - { - if (((cond == Equal) || (cond == NotEqual)) && !left.m_value) - m_assembler.testl_rr(right, right); - else - m_assembler.cmpl_ir(left.m_value, right); - return Jump(m_assembler.jCC(x86Condition(commute(cond)))); - } - Jump branch32(RelationalCondition cond, RegisterID left, Address right) { m_assembler.cmpl_mr(right.offset, right.base, left); @@ -877,20 +1101,6 @@ public: return branch32(cond, left, right); } - Jump branch16(RelationalCondition cond, BaseIndex left, RegisterID right) - { - m_assembler.cmpw_rm(right, left.offset, left.base, left.index, left.scale); - return Jump(m_assembler.jCC(x86Condition(cond))); - } - - Jump branch16(RelationalCondition cond, BaseIndex left, TrustedImm32 right) - { - ASSERT(!(right.m_value & 0xFFFF0000)); - - m_assembler.cmpw_im(right.m_value, left.offset, left.base, left.index, left.scale); - return Jump(m_assembler.jCC(x86Condition(cond))); - } - Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask) { m_assembler.testl_rr(reg, mask); @@ -902,8 +1112,6 @@ public: // if we are only interested in the low seven bits, this can be tested with a testb if (mask.m_value == -1) m_assembler.testl_rr(reg, reg); - else if ((mask.m_value & ~0x7f) == 0) - m_assembler.testb_i8r(mask.m_value, reg); else m_assembler.testl_i32r(mask.m_value, reg); return Jump(m_assembler.jCC(x86Condition(cond))); @@ -927,17 +1135,6 @@ public: return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchTest8(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) - { - // Byte in TrustedImm32 is not well defined, so be a little permisive here, but don't accept nonsense values. - ASSERT(mask.m_value >= -128 && mask.m_value <= 255); - if (mask.m_value == -1) - m_assembler.testb_rr(reg, reg); - else - m_assembler.testb_i8r(mask.m_value, reg); - return Jump(m_assembler.jCC(x86Condition(cond))); - } - Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) { // Byte in TrustedImm32 is not well defined, so be a little permisive here, but don't accept nonsense values. @@ -960,6 +1157,14 @@ public: return Jump(m_assembler.jCC(x86Condition(cond))); } + Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right) + { + ASSERT(!(right.m_value & 0xFFFFFF00)); + + m_assembler.cmpb_im(right.m_value, left.offset, left.base, left.index, left.scale); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + Jump jump() { return Jump(m_assembler.jmp()); @@ -1148,11 +1353,16 @@ public: m_assembler.ret(); } + void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest) + { + m_assembler.cmpb_im(right.m_value, left.offset, left.base); + set32(x86Condition(cond), dest); + } + void compare32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest) { m_assembler.cmpl_rr(right, left); - m_assembler.setCC_r(x86Condition(cond), dest); - m_assembler.movzbl_rr(dest, dest); + set32(x86Condition(cond), dest); } void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest) @@ -1161,12 +1371,11 @@ public: m_assembler.testl_rr(left, left); else m_assembler.cmpl_ir(right.m_value, left); - m_assembler.setCC_r(x86Condition(cond), dest); - m_assembler.movzbl_rr(dest, dest); + set32(x86Condition(cond), dest); } // FIXME: - // The mask should be optional... paerhaps the argument order should be + // The mask should be optional... perhaps the argument order should be // dest-src, operations always have a dest? ... possibly not true, considering // asm ops like test, or pseudo ops like pop(). @@ -1176,8 +1385,7 @@ public: m_assembler.cmpb_im(0, address.offset, address.base); else m_assembler.testb_im(mask.m_value, address.offset, address.base); - m_assembler.setCC_r(x86Condition(cond), dest); - m_assembler.movzbl_rr(dest, dest); + set32(x86Condition(cond), dest); } void test32(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest) @@ -1186,8 +1394,7 @@ public: m_assembler.cmpl_im(0, address.offset, address.base); else m_assembler.testl_i32m(mask.m_value, address.offset, address.base); - m_assembler.setCC_r(x86Condition(cond), dest); - m_assembler.movzbl_rr(dest, dest); + set32(x86Condition(cond), dest); } // Invert a relational condition, e.g. == becomes !=, < becomes >=, etc. @@ -1196,25 +1403,6 @@ public: return static_cast(cond ^ 1); } - // Commute a relational condition, returns a new condition that will produce - // the same results given the same inputs but with their positions exchanged. - static RelationalCondition commute(RelationalCondition cond) - { - // Equality is commutative! - if (cond == Equal || cond == NotEqual) - return cond; - - // Based on the values of x86 condition codes, remap > with < and >= with <= - if (cond >= LessThan) { - ASSERT(cond == LessThan || cond == LessThanOrEqual || cond == GreaterThan || cond == GreaterThanOrEqual); - return static_cast(X86Assembler::ConditionL + X86Assembler::ConditionG - cond); - } - - // As above, for unsigned conditions. - ASSERT(cond == Below || cond == BelowOrEqual || cond == Above || cond == AboveOrEqual); - return static_cast(X86Assembler::ConditionB + X86Assembler::ConditionA - cond); - } - void nop() { m_assembler.nop(); @@ -1231,6 +1419,23 @@ protected: return static_cast(cond); } + void set32(X86Assembler::Condition cond, RegisterID dest) + { +#if CPU(X86) + // On 32-bit x86 we can only set the first 4 registers; + // esp..edi are mapped to the 'h' registers! + if (dest >= 4) { + m_assembler.xchgl_rr(dest, X86Registers::eax); + m_assembler.setCC_r(cond, X86Registers::eax); + m_assembler.movzbl_rr(X86Registers::eax, X86Registers::eax); + m_assembler.xchgl_rr(dest, X86Registers::eax); + return; + } +#endif + m_assembler.setCC_r(cond, dest); + m_assembler.movzbl_rr(dest, dest); + } + private: // Only MacroAssemblerX86 should be using the following method; SSE2 is always available on // x86_64, and clients & subclasses of MacroAssembler should be using 'supportsFloatingPoint()'. diff --git a/assembler/MacroAssemblerX86_64.h b/assembler/MacroAssemblerX86_64.h index b95bc2e..41479f9 100644 --- a/assembler/MacroAssemblerX86_64.h +++ b/assembler/MacroAssemblerX86_64.h @@ -35,19 +35,18 @@ namespace JSC { class MacroAssemblerX86_64 : public MacroAssemblerX86Common { -protected: - static const X86Registers::RegisterID scratchRegister = X86Registers::r11; - public: static const Scale ScalePtr = TimesEight; using MacroAssemblerX86Common::add32; using MacroAssemblerX86Common::and32; + using MacroAssemblerX86Common::branchAdd32; using MacroAssemblerX86Common::or32; using MacroAssemblerX86Common::sub32; using MacroAssemblerX86Common::load32; using MacroAssemblerX86Common::store32; using MacroAssemblerX86Common::call; + using MacroAssemblerX86Common::jump; using MacroAssemblerX86Common::addDouble; using MacroAssemblerX86Common::loadDouble; using MacroAssemblerX86Common::convertInt32ToDouble; @@ -76,23 +75,16 @@ public: sub32(imm, Address(scratchRegister)); } - void load32(void* address, RegisterID dest) + void load32(const void* address, RegisterID dest) { if (dest == X86Registers::eax) m_assembler.movl_mEAX(address); else { - move(X86Registers::eax, dest); - m_assembler.movl_mEAX(address); - swap(X86Registers::eax, dest); + move(TrustedImmPtr(address), dest); + load32(dest, dest); } } - void loadDouble(const void* address, FPRegisterID dest) - { - move(TrustedImmPtr(address), scratchRegister); - loadDouble(scratchRegister, dest); - } - void addDouble(AbsoluteAddress address, FPRegisterID dest) { move(TrustedImmPtr(address.m_ptr), scratchRegister); @@ -107,10 +99,8 @@ public: void store32(TrustedImm32 imm, void* address) { - move(X86Registers::eax, scratchRegister); - move(imm, X86Registers::eax); - m_assembler.movl_EAXm(address); - move(scratchRegister, X86Registers::eax); + move(TrustedImmPtr(address), scratchRegister); + store32(imm, scratchRegister); } Call call() @@ -121,6 +111,13 @@ public: return result; } + // Address is a memory location containing the address to jump to + void jump(AbsoluteAddress address) + { + move(TrustedImmPtr(address.m_ptr), scratchRegister); + jump(Address(scratchRegister)); + } + Call tailRecursiveCall() { DataLabelPtr label = moveWithPatch(TrustedImmPtr(0), scratchRegister); @@ -170,7 +167,12 @@ public: move(TrustedImmPtr(address.m_ptr), scratchRegister); addPtr(imm, Address(scratchRegister)); } - + + void add64(TrustedImm32 imm, AbsoluteAddress address) + { + addPtr(imm, address); + } + void andPtr(RegisterID src, RegisterID dest) { m_assembler.andq_rr(src, dest); @@ -214,6 +216,11 @@ public: move(src, dest); orPtr(imm, dest); } + + void rotateRightPtr(TrustedImm32 imm, RegisterID srcDst) + { + m_assembler.rorq_i8r(imm.m_value, srcDst); + } void subPtr(RegisterID src, RegisterID dest) { @@ -235,13 +242,17 @@ public: { m_assembler.xorq_rr(src, dest); } + + void xorPtr(RegisterID src, Address dest) + { + m_assembler.xorq_rm(src, dest.offset, dest.base); + } void xorPtr(TrustedImm32 imm, RegisterID srcDest) { m_assembler.xorq_ir(imm.m_value, srcDest); } - void loadPtr(ImplicitAddress address, RegisterID dest) { m_assembler.movq_mr(address.offset, address.base, dest); @@ -257,9 +268,8 @@ public: if (dest == X86Registers::eax) m_assembler.movq_mEAX(address); else { - move(X86Registers::eax, dest); - m_assembler.movq_mEAX(address); - swap(X86Registers::eax, dest); + move(TrustedImmPtr(address), dest); + loadPtr(dest, dest); } } @@ -290,9 +300,8 @@ public: if (src == X86Registers::eax) m_assembler.movq_EAXm(address); else { - swap(X86Registers::eax, src); - m_assembler.movq_EAXm(address); - swap(X86Registers::eax, src); + move(TrustedImmPtr(address), scratchRegister); + storePtr(src, scratchRegister); } } @@ -302,6 +311,12 @@ public: storePtr(scratchRegister, address); } + void storePtr(TrustedImmPtr imm, BaseIndex address) + { + move(imm, scratchRegister); + m_assembler.movq_rm(scratchRegister, address.offset, address.base, address.index, address.scale); + } + DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address) { m_assembler.movq_rm_disp32(src, address.offset, address.base); @@ -327,6 +342,20 @@ public: m_assembler.setCC_r(x86Condition(cond), dest); m_assembler.movzbl_rr(dest, dest); } + + void comparePtr(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest) + { + m_assembler.cmpq_rr(right, left); + m_assembler.setCC_r(x86Condition(cond), dest); + m_assembler.movzbl_rr(dest, dest); + } + + Jump branchAdd32(ResultCondition cond, TrustedImm32 src, AbsoluteAddress dest) + { + move(TrustedImmPtr(dest.m_ptr), scratchRegister); + add32(src, Address(scratchRegister)); + return Jump(m_assembler.jCC(x86Condition(cond))); + } Jump branchPtr(RelationalCondition cond, RegisterID left, RegisterID right) { @@ -336,6 +365,10 @@ public: Jump branchPtr(RelationalCondition cond, RegisterID left, TrustedImmPtr right) { + if (((cond == Equal) || (cond == NotEqual)) && !right.m_value) { + m_assembler.testq_rr(left, left); + return Jump(m_assembler.jCC(x86Condition(cond))); + } move(right, scratchRegister); return branchPtr(cond, left, scratchRegister); } @@ -369,7 +402,7 @@ public: m_assembler.testq_rr(reg, mask); return Jump(m_assembler.jCC(x86Condition(cond))); } - + Jump branchTestPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) { // if we are only interested in the low seven bits, this can be tested with a testb @@ -382,6 +415,23 @@ public: return Jump(m_assembler.jCC(x86Condition(cond))); } + void testPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest) + { + if (mask.m_value == -1) + m_assembler.testq_rr(reg, reg); + else if ((mask.m_value & ~0x7f) == 0) + m_assembler.testb_i8r(mask.m_value, reg); + else + m_assembler.testq_i32r(mask.m_value, reg); + set32(x86Condition(cond), dest); + } + + void testPtr(ResultCondition cond, RegisterID reg, RegisterID mask, RegisterID dest) + { + m_assembler.testq_rr(reg, mask); + set32(x86Condition(cond), dest); + } + Jump branchTestPtr(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1)) { loadPtr(address.m_ptr, scratchRegister); @@ -407,6 +457,12 @@ public: } + Jump branchAddPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest) + { + addPtr(imm, dest); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + Jump branchAddPtr(ResultCondition cond, RegisterID src, RegisterID dest) { addPtr(src, dest); @@ -419,6 +475,12 @@ public: return Jump(m_assembler.jCC(x86Condition(cond))); } + Jump branchSubPtr(ResultCondition cond, RegisterID src1, TrustedImm32 src2, RegisterID dest) + { + move(src1, dest); + return branchSubPtr(cond, src2, dest); + } + DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest) { m_assembler.movq_i64r(initialValue.asIntptr(), dest); @@ -452,10 +514,18 @@ public: return MacroAssemblerX86Common::branchTest8(cond, BaseIndex(scratchRegister, address.base, TimesOne), mask); } - bool supportsFloatingPoint() const { return true; } + static bool supportsFloatingPoint() { return true; } // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate() - bool supportsFloatingPointTruncate() const { return true; } - bool supportsFloatingPointSqrt() const { return true; } + static bool supportsFloatingPointTruncate() { return true; } + static bool supportsFloatingPointSqrt() { return true; } + static bool supportsFloatingPointAbs() { return true; } + + static FunctionPtr readCallTarget(CodeLocationCall call) + { + return FunctionPtr(X86Assembler::readPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation())); + } + + static RegisterID scratchRegisterForBlinding() { return scratchRegister; } private: friend class LinkBuffer; @@ -464,9 +534,9 @@ private: static void linkCall(void* code, Call call, FunctionPtr function) { if (!call.isFlagSet(Call::Near)) - X86Assembler::linkPointer(code, call.m_jmp.labelAtOffset(-REPTACH_OFFSET_CALL_R11), function.value()); + X86Assembler::linkPointer(code, call.m_label.labelAtOffset(-REPTACH_OFFSET_CALL_R11), function.value()); else - X86Assembler::linkCall(code, call.m_jmp, function.value()); + X86Assembler::linkCall(code, call.m_label, function.value()); } static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) diff --git a/assembler/RepatchBuffer.h b/assembler/RepatchBuffer.h index 6ea6d8d..a87294b 100644 --- a/assembler/RepatchBuffer.h +++ b/assembler/RepatchBuffer.h @@ -26,8 +26,9 @@ #ifndef RepatchBuffer_h #define RepatchBuffer_h -#if ENABLE(ASSEMBLER) +#if ENABLE(JIT) +#include "CodeBlock.h" #include #include diff --git a/assembler/SH4Assembler.h b/assembler/SH4Assembler.h index 1d089e5..59d0422 100644 --- a/assembler/SH4Assembler.h +++ b/assembler/SH4Assembler.h @@ -31,9 +31,12 @@ #include "AssemblerBuffer.h" #include "AssemblerBufferWithConstantPool.h" +#include "JITCompilationEffort.h" #include #include +#include #include +#include #include #ifndef NDEBUG @@ -151,6 +154,7 @@ enum { TST_OPCODE = 0x2008, TSTIMM_OPCODE = 0xc800, TSTB_OPCODE = 0xcc00, + EXTUB_OPCODE = 0x600c, EXTUW_OPCODE = 0x600d, XOR_OPCODE = 0x200a, XORIMM_OPCODE = 0xca00, @@ -322,6 +326,10 @@ public: padForAlign32 = 0x00090009, }; + enum JumpType { JumpFar, + JumpNear + }; + SH4Assembler() { m_claimscratchReg = 0x0; @@ -757,6 +765,12 @@ public: oneShortOp(opc); } + void extub(RegisterID src, RegisterID dst) + { + uint16_t opc = getOpcodeGroup1(EXTUB_OPCODE, dst, src); + oneShortOp(opc); + } + void extuw(RegisterID src, RegisterID dst) { uint16_t opc = getOpcodeGroup1(EXTUW_OPCODE, dst, src); @@ -1063,6 +1077,11 @@ public: oneShortOp(getOpcodeGroup4(MOVL_READ_OFFRM_OPCODE, dst, base, offset)); } + void movlMemRegCompact(int offset, RegisterID base, RegisterID dst) + { + oneShortOp(getOpcodeGroup4(MOVL_READ_OFFRM_OPCODE, dst, base, offset)); + } + void movbMemReg(int offset, RegisterID base, RegisterID dst) { ASSERT(dst == SH4Registers::r0); @@ -1173,6 +1192,13 @@ public: return label; } + void extraInstrForBranch(RegisterID dst) + { + loadConstantUnReusable(0x0, dst); + nop(); + nop(); + } + AssemblerLabel jmp(RegisterID dst) { jmpReg(dst); @@ -1200,6 +1226,13 @@ public: return label; } + AssemblerLabel bra() + { + AssemblerLabel label = m_buffer.label(); + branch(BRA_OPCODE, 0); + return label; + } + void ret() { m_buffer.ensureSpace(maxInstructionSize + 2); @@ -1232,7 +1265,7 @@ public: uint32_t address = (offset << 2) + ((reinterpret_cast(instructionPtr) + 4) &(~0x3)); *reinterpret_cast(address) = newAddress; } - + static uint32_t readPCrelativeAddress(int offset, uint16_t* instructionPtr) { uint32_t address = (offset << 2) + ((reinterpret_cast(instructionPtr) + 4) &(~0x3)); @@ -1354,7 +1387,7 @@ public: static void* readPointer(void* code) { - return static_cast(readInt32(code)); + return reinterpret_cast(readInt32(code)); } static void repatchInt32(void* where, int32_t value) @@ -1365,7 +1398,10 @@ public: static void repatchCompact(void* where, int32_t value) { - repatchInt32(where, value); + ASSERT(value >= 0); + ASSERT(value <= 60); + *reinterpret_cast(where) = ((*reinterpret_cast(where) & 0xfff0) | (value >> 2)); + cacheFlush(reinterpret_cast(where), sizeof(uint16_t)); } static void relinkCall(void* from, void* to) @@ -1406,7 +1442,7 @@ public: // Linking & patching - void linkJump(AssemblerLabel from, AssemblerLabel to) + void linkJump(AssemblerLabel from, AssemblerLabel to, JumpType type = JumpFar) { ASSERT(to.isSet()); ASSERT(from.isSet()); @@ -1415,6 +1451,14 @@ public: uint16_t instruction = *instructionPtr; int offsetBits; + if (type == JumpNear) { + ASSERT((instruction == BT_OPCODE) || (instruction == BF_OPCODE) || (instruction == BRA_OPCODE)); + int offset = (codeSize() - from.m_offset) - 4; + *instructionPtr++ = instruction | (offset >> 1); + printInstr(*instructionPtr, from.m_offset + 2); + return; + } + if (((instruction & 0xff00) == BT_OPCODE) || ((instruction & 0xff00) == BF_OPCODE)) { /* BT label => BF 2 nop LDR reg @@ -1490,9 +1534,27 @@ public: return readPCrelativeAddress((*(reinterpret_cast(code)) & 0xff), reinterpret_cast(code)); } - void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator) + static void* readCallTarget(void* from) + { + uint16_t* instructionPtr = static_cast(from); + instructionPtr -= 3; + return reinterpret_cast(readPCrelativeAddress((*instructionPtr & 0xff), instructionPtr)); + } + + PassRefPtr executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort) { - return m_buffer.executableCopy(globalData, allocator); + return m_buffer.executableCopy(globalData, ownerUID, effort); + } + + static void cacheFlush(void* code, size_t size) + { +#if !OS(LINUX) +#error "The cacheFlush support is missing on this platform." +#elif defined CACHEFLUSH_D_L2 + syscall(__NR_cacheflush, reinterpret_cast(code), size, CACHEFLUSH_D_WB | CACHEFLUSH_I | CACHEFLUSH_D_L2); +#else + syscall(__NR_cacheflush, reinterpret_cast(code), size, CACHEFLUSH_D_WB | CACHEFLUSH_I); +#endif } void prefix(uint16_t pre) @@ -1801,6 +1863,9 @@ public: case MOVW_READ_R0RM_OPCODE: format = " MOV.W @(R0, R%d), R%d\n"; break; + case EXTUB_OPCODE: + format = " EXTU.B R%d, R%d\n"; + break; case EXTUW_OPCODE: format = " EXTU.W R%d, R%d\n"; break; @@ -1999,7 +2064,7 @@ public: static void vprintfStdoutInstr(const char* format, va_list args) { if (getenv("JavaScriptCoreDumpJIT")) - vfprintf(stdout, format, args); + WTF::dataLogV(format, args); } static void printBlockInstr(uint16_t* first, unsigned int offset, int nbInstr) diff --git a/assembler/X86Assembler.h b/assembler/X86Assembler.h index 41dd50f..ff8d25b 100644 --- a/assembler/X86Assembler.h +++ b/assembler/X86Assembler.h @@ -29,6 +29,7 @@ #if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64)) #include "AssemblerBuffer.h" +#include "JITCompilationEffort.h" #include #include #include @@ -134,6 +135,7 @@ private: OP_TEST_EbGb = 0x84, OP_TEST_EvGv = 0x85, OP_XCHG_EvGv = 0x87, + OP_MOV_EbGb = 0x88, OP_MOV_EvGv = 0x89, OP_MOV_GvEv = 0x8B, OP_LEA = 0x8D, @@ -145,13 +147,16 @@ private: OP_MOV_EAXIv = 0xB8, OP_GROUP2_EvIb = 0xC1, OP_RET = 0xC3, + OP_GROUP11_EvIb = 0xC6, OP_GROUP11_EvIz = 0xC7, OP_INT3 = 0xCC, OP_GROUP2_Ev1 = 0xD1, OP_GROUP2_EvCL = 0xD3, + OP_ESCAPE_DD = 0xDD, OP_CALL_rel32 = 0xE8, OP_JMP_rel32 = 0xE9, PRE_SSE_F2 = 0xF2, + PRE_SSE_F3 = 0xF3, OP_HLT = 0xF4, OP_GROUP3_EbIb = 0xF6, OP_GROUP3_Ev = 0xF7, @@ -162,14 +167,19 @@ private: typedef enum { OP2_MOVSD_VsdWsd = 0x10, OP2_MOVSD_WsdVsd = 0x11, + OP2_MOVSS_VsdWsd = 0x10, + OP2_MOVSS_WsdVsd = 0x11, OP2_CVTSI2SD_VsdEd = 0x2A, OP2_CVTTSD2SI_GdWsd = 0x2C, OP2_UCOMISD_VsdWsd = 0x2E, OP2_ADDSD_VsdWsd = 0x58, OP2_MULSD_VsdWsd = 0x59, + OP2_CVTSD2SS_VsdWsd = 0x5A, + OP2_CVTSS2SD_VsdWsd = 0x5A, OP2_SUBSD_VsdWsd = 0x5C, OP2_DIVSD_VsdWsd = 0x5E, OP2_SQRTSD_VsdWsd = 0x51, + OP2_ANDNPD_VpdWpd = 0x55, OP2_XORPD_VpdWpd = 0x57, OP2_MOVD_VdEd = 0x6E, OP2_MOVD_EdVd = 0x7E, @@ -177,8 +187,13 @@ private: OP_SETCC = 0x90, OP2_IMUL_GvEv = 0xAF, OP2_MOVZX_GvEb = 0xB6, + OP2_MOVSX_GvEb = 0xBE, OP2_MOVZX_GvEw = 0xB7, + OP2_MOVSX_GvEw = 0xBF, OP2_PEXTRW_GdUdIb = 0xC5, + OP2_PSLLQ_UdqIb = 0x73, + OP2_PSRLQ_UdqIb = 0x73, + OP2_POR_VdqWdq = 0XEB, } TwoByteOpcodeID; TwoByteOpcodeID jccRel32(Condition cond) @@ -201,7 +216,12 @@ private: GROUP1_OP_CMP = 7, GROUP1A_OP_POP = 0, - + + GROUP2_OP_ROL = 0, + GROUP2_OP_ROR = 1, + GROUP2_OP_RCL = 2, + GROUP2_OP_RCR = 3, + GROUP2_OP_SHL = 4, GROUP2_OP_SHR = 5, GROUP2_OP_SAR = 7, @@ -216,6 +236,11 @@ private: GROUP5_OP_PUSH = 6, GROUP11_MOV = 0, + + GROUP14_OP_PSLLQ = 6, + GROUP14_OP_PSRLQ = 2, + + ESCAPE_DD_FSTP_doubleReal = 3, } GroupOpcodeID; class X86InstructionFormatter; @@ -616,6 +641,22 @@ public: m_formatter.immediate32(imm); } } + + void xorq_rm(RegisterID src, int offset, RegisterID base) + { + m_formatter.oneByteOp64(OP_XOR_EvGv, src, base, offset); + } + + void rorq_i8r(int imm, RegisterID dst) + { + if (imm == 1) + m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_ROR, dst); + else { + m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_ROR, dst); + m_formatter.immediate8(imm); + } + } + #endif void sarl_i8r(int imm, RegisterID dst) @@ -841,6 +882,19 @@ public: } #endif + void cmpw_ir(int imm, RegisterID dst) + { + if (CAN_SIGN_EXTEND_8_32(imm)) { + m_formatter.prefix(PRE_OPERAND_SIZE); + m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst); + m_formatter.immediate8(imm); + } else { + m_formatter.prefix(PRE_OPERAND_SIZE); + m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst); + m_formatter.immediate16(imm); + } + } + void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) { m_formatter.prefix(PRE_OPERAND_SIZE); @@ -879,7 +933,7 @@ public: void testb_rr(RegisterID src, RegisterID dst) { - m_formatter.oneByteOp(OP_TEST_EbGb, src, dst); + m_formatter.oneByteOp8(OP_TEST_EbGb, src, dst); } void testb_im(int imm, int offset, RegisterID base) @@ -969,6 +1023,11 @@ public: m_formatter.oneByteOp(OP_CDQ); } + void fstpl(int offset, RegisterID base) + { + m_formatter.oneByteOp(OP_ESCAPE_DD, ESCAPE_DD_FSTP_doubleReal, base, offset); + } + void xchgl_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst); @@ -1042,6 +1101,37 @@ public: m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset); m_formatter.immediate32(imm); } + + void movl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale) + { + m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset); + m_formatter.immediate32(imm); + } + + void movb_i8m(int imm, int offset, RegisterID base) + { + ASSERT(-128 <= imm && imm < 128); + m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, offset); + m_formatter.immediate8(imm); + } + + void movb_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale) + { + ASSERT(-128 <= imm && imm < 128); + m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, index, scale, offset); + m_formatter.immediate8(imm); + } + + void movb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) + { + m_formatter.oneByteOp8(OP_MOV_EbGb, src, base, index, scale, offset); + } + + void movw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) + { + m_formatter.prefix(PRE_OPERAND_SIZE); + m_formatter.oneByteOp8(OP_MOV_EvGv, src, base, index, scale, offset); + } void movl_EAXm(const void* addr) { @@ -1158,6 +1248,36 @@ public: m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset); } + void movswl_mr(int offset, RegisterID base, RegisterID dst) + { + m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, offset); + } + + void movswl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) + { + m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, index, scale, offset); + } + + void movzbl_mr(int offset, RegisterID base, RegisterID dst) + { + m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, offset); + } + + void movzbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) + { + m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, index, scale, offset); + } + + void movsbl_mr(int offset, RegisterID base, RegisterID dst) + { + m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, offset); + } + + void movsbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) + { + m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, index, scale, offset); + } + void movzbl_rr(RegisterID src, RegisterID dst) { // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register @@ -1215,6 +1335,13 @@ public: { m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset); } + +#if !CPU(X86_64) + void jmp_m(const void* address) + { + m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, address); + } +#endif AssemblerLabel jne() { @@ -1324,6 +1451,14 @@ public: m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset); } +#if !CPU(X86_64) + void addsd_mr(const void* address, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, address); + } +#endif + void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); @@ -1350,12 +1485,38 @@ public: m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src); } + void cvtsd2ss_rr(XMMRegisterID src, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp(OP2_CVTSD2SS_VsdWsd, dst, (RegisterID)src); + } + + void cvtss2sd_rr(XMMRegisterID src, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_F3); + m_formatter.twoByteOp(OP2_CVTSS2SD_VsdWsd, dst, (RegisterID)src); + } + +#if CPU(X86_64) + void cvttsd2siq_rr(XMMRegisterID src, RegisterID dst) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp64(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src); + } +#endif + void movd_rr(XMMRegisterID src, RegisterID dst) { m_formatter.prefix(PRE_SSE_66); m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst); } + void movd_rr(RegisterID src, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_66); + m_formatter.twoByteOp(OP2_MOVD_VdEd, (RegisterID)dst, src); + } + #if CPU(X86_64) void movq_rr(XMMRegisterID src, RegisterID dst) { @@ -1381,19 +1542,48 @@ public: m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset); } - + + void movsd_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset); + } + + void movss_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale) + { + m_formatter.prefix(PRE_SSE_F3); + m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset); + } + void movsd_mr(int offset, RegisterID base, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset); } + void movsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset); + } + + void movss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_F3); + m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset); + } + #if !CPU(X86_64) void movsd_mr(const void* address, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address); } + void movsd_rm(XMMRegisterID src, const void* address) + { + m_formatter.prefix(PRE_SSE_F2); + m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, address); + } #endif void mulsd_rr(XMMRegisterID src, XMMRegisterID dst) @@ -1415,6 +1605,26 @@ public: m_formatter.immediate8(whichWord); } + void psllq_i8r(int imm, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_66); + m_formatter.twoByteOp8(OP2_PSLLQ_UdqIb, GROUP14_OP_PSLLQ, (RegisterID)dst); + m_formatter.immediate8(imm); + } + + void psrlq_i8r(int imm, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_66); + m_formatter.twoByteOp8(OP2_PSRLQ_UdqIb, GROUP14_OP_PSRLQ, (RegisterID)dst); + m_formatter.immediate8(imm); + } + + void por_rr(XMMRegisterID src, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_66); + m_formatter.twoByteOp(OP2_POR_VdqWdq, (RegisterID)dst, (RegisterID)src); + } + void subsd_rr(XMMRegisterID src, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); @@ -1457,6 +1667,12 @@ public: m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src); } + void andnpd_rr(XMMRegisterID src, XMMRegisterID dst) + { + m_formatter.prefix(PRE_SSE_66); + m_formatter.twoByteOp(OP2_ANDNPD_VpdWpd, (RegisterID)dst, (RegisterID)src); + } + void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); @@ -1588,22 +1804,21 @@ public: return b.m_offset - a.m_offset; } - void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator) + PassRefPtr executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort) { - return m_formatter.executableCopy(globalData, allocator); + return m_formatter.executableCopy(globalData, ownerUID, effort); } - void rewindToLabel(AssemblerLabel rewindTo) { m_formatter.rewindToLabel(rewindTo); } - -#ifndef NDEBUG unsigned debugOffset() { return m_formatter.debugOffset(); } -#endif void nop() { m_formatter.oneByteOp(OP_NOP); } + // This is a no-op on x86 + ALWAYS_INLINE static void cacheFlush(void*, size_t) { } + private: static void setPointer(void* where, void* value) @@ -1868,6 +2083,22 @@ private: registerModRM(groupOp, rm); } + void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID rm) + { + m_buffer.ensureSpace(maxInstructionSize); + emitRexIf(byteRegRequiresRex(reg) || byteRegRequiresRex(rm), reg, 0, rm); + m_buffer.putByteUnchecked(opcode); + registerModRM(reg, rm); + } + + void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset) + { + m_buffer.ensureSpace(maxInstructionSize); + emitRexIf(byteRegRequiresRex(reg) || regRequiresRex(index) || regRequiresRex(base), reg, index, base); + m_buffer.putByteUnchecked(opcode); + memoryModRM(reg, base, index, scale, offset); + } + void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm) { m_buffer.ensureSpace(maxInstructionSize); @@ -1924,16 +2155,12 @@ private: bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); } void* data() const { return m_buffer.data(); } - void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator) + PassRefPtr executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort) { - return m_buffer.executableCopy(globalData, allocator); + return m_buffer.executableCopy(globalData, ownerUID, effort); } - void rewindToLabel(AssemblerLabel rewindTo) { m_buffer.rewindToLabel(rewindTo); } - -#ifndef NDEBUG unsigned debugOffset() { return m_buffer.debugOffset(); } -#endif private: diff --git a/bytecode/BytecodeConventions.h b/bytecode/BytecodeConventions.h new file mode 100644 index 0000000..f33b060 --- /dev/null +++ b/bytecode/BytecodeConventions.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 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 BytecodeConventions_h +#define BytecodeConventions_h + +// Register numbers used in bytecode operations have different meaning according to their ranges: +// 0x80000000-0xFFFFFFFF Negative indices from the CallFrame pointer are entries in the call frame, see RegisterFile.h. +// 0x00000000-0x3FFFFFFF Forwards indices from the CallFrame pointer are local vars and temporaries with the function's callframe. +// 0x40000000-0x7FFFFFFF Positive indices from 0x40000000 specify entries in the constant pool on the CodeBlock. +static const int FirstConstantRegisterIndex = 0x40000000; + +#endif // BytecodeConventions_h + diff --git a/bytecode/CallLinkInfo.cpp b/bytecode/CallLinkInfo.cpp new file mode 100644 index 0000000..4c108ec --- /dev/null +++ b/bytecode/CallLinkInfo.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2012 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 "CallLinkInfo.h" + +#include "DFGOperations.h" +#include "RepatchBuffer.h" + +#if ENABLE(JIT) +namespace JSC { + +void CallLinkInfo::unlink(JSGlobalData& globalData, RepatchBuffer& repatchBuffer) +{ + ASSERT(isLinked()); + + if (isDFG) { +#if ENABLE(DFG_JIT) + repatchBuffer.relink(CodeLocationCall(callReturnLocation), callType == Construct ? DFG::operationLinkConstruct : DFG::operationLinkCall); +#else + ASSERT_NOT_REACHED(); +#endif + } else + repatchBuffer.relink(CodeLocationNearCall(callReturnLocation), callType == Construct ? globalData.jitStubs->ctiVirtualConstructLink() : globalData.jitStubs->ctiVirtualCallLink()); + hasSeenShouldRepatch = false; + callee.clear(); + + // It will be on a list if the callee has a code block. + if (isOnList()) + remove(); +} + +} // namespace JSC +#endif // ENABLE(JIT) + diff --git a/bytecode/CallLinkInfo.h b/bytecode/CallLinkInfo.h new file mode 100644 index 0000000..44d50a9 --- /dev/null +++ b/bytecode/CallLinkInfo.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2012 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 CallLinkInfo_h +#define CallLinkInfo_h + +#include "CodeLocation.h" +#include "JITWriteBarrier.h" +#include "JSFunction.h" +#include "Opcode.h" +#include "WriteBarrier.h" +#include +#include + +namespace JSC { + +#if ENABLE(JIT) + +class RepatchBuffer; + +struct CallLinkInfo : public BasicRawSentinelNode { + enum CallType { None, Call, CallVarargs, Construct }; + static CallType callTypeFor(OpcodeID opcodeID) + { + if (opcodeID == op_call || opcodeID == op_call_eval) + return Call; + if (opcodeID == op_construct) + return Construct; + ASSERT(opcodeID == op_call_varargs); + return CallVarargs; + } + + CallLinkInfo() + : hasSeenShouldRepatch(false) + , isDFG(false) + , callType(None) + { + } + + ~CallLinkInfo() + { + if (isOnList()) + remove(); + } + + CodeLocationLabel callReturnLocation; // it's a near call in the old JIT, or a normal call in DFG + CodeLocationDataLabelPtr hotPathBegin; + CodeLocationNearCall hotPathOther; + JITWriteBarrier callee; + WriteBarrier lastSeenCallee; + bool hasSeenShouldRepatch : 1; + bool isDFG : 1; + CallType callType : 6; + unsigned bytecodeIndex; + + bool isLinked() { return callee; } + void unlink(JSGlobalData&, RepatchBuffer&); + + bool seenOnce() + { + return hasSeenShouldRepatch; + } + + void setSeen() + { + hasSeenShouldRepatch = true; + } +}; + +inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo) +{ + return callLinkInfo->callReturnLocation.executableAddress(); +} + +inline unsigned getCallLinkInfoBytecodeIndex(CallLinkInfo* callLinkInfo) +{ + return callLinkInfo->bytecodeIndex; +} +#endif // ENABLE(JIT) + +} // namespace JSC + +#endif // CallLinkInfo_h diff --git a/bytecode/CallLinkStatus.cpp b/bytecode/CallLinkStatus.cpp new file mode 100644 index 0000000..7f9e9ee --- /dev/null +++ b/bytecode/CallLinkStatus.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2012 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 "CallLinkStatus.h" + +#include "CodeBlock.h" +#include "LLIntCallLinkInfo.h" + +namespace JSC { + +CallLinkStatus CallLinkStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex) +{ + UNUSED_PARAM(profiledBlock); + UNUSED_PARAM(bytecodeIndex); +#if ENABLE(LLINT) + Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex; + LLIntCallLinkInfo* callLinkInfo = instruction[4].u.callLinkInfo; + + return CallLinkStatus(callLinkInfo->lastSeenCallee.get(), false); +#else + return CallLinkStatus(0, false); +#endif +} + +CallLinkStatus CallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex) +{ + UNUSED_PARAM(profiledBlock); + UNUSED_PARAM(bytecodeIndex); +#if ENABLE(JIT) && ENABLE(VALUE_PROFILER) + if (!profiledBlock->numberOfCallLinkInfos()) + return computeFromLLInt(profiledBlock, bytecodeIndex); + + if (profiledBlock->couldTakeSlowCase(bytecodeIndex)) + return CallLinkStatus(0, true); + + JSFunction* target = profiledBlock->getCallLinkInfo(bytecodeIndex).lastSeenCallee.get(); + if (!target) + return computeFromLLInt(profiledBlock, bytecodeIndex); + + return CallLinkStatus(target, false); +#else + return CallLinkStatus(0, false); +#endif +} + +} // namespace JSC + diff --git a/bytecode/CallLinkStatus.h b/bytecode/CallLinkStatus.h new file mode 100644 index 0000000..5f72019 --- /dev/null +++ b/bytecode/CallLinkStatus.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2012 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 CallLinkStatus_h +#define CallLinkStatus_h + +namespace JSC { + +class JSFunction; +class CodeBlock; + +class CallLinkStatus { +public: + CallLinkStatus() + : m_callTarget(0) + , m_couldTakeSlowPath(false) + { + } + + CallLinkStatus(JSFunction* callTarget, bool couldTakeSlowPath) + : m_callTarget(callTarget) + , m_couldTakeSlowPath(couldTakeSlowPath) + { + } + + static CallLinkStatus computeFor(CodeBlock*, unsigned bytecodeIndex); + + bool isSet() const { return !!m_callTarget || m_couldTakeSlowPath; } + + bool operator!() const { return !isSet(); } + + bool couldTakeSlowPath() const { return m_couldTakeSlowPath; } + + JSFunction* callTarget() const { return m_callTarget; } + +private: + static CallLinkStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex); + + JSFunction* m_callTarget; + bool m_couldTakeSlowPath; +}; + +} // namespace JSC + +#endif // CallLinkStatus_h + diff --git a/bytecode/CallReturnOffsetToBytecodeOffset.h b/bytecode/CallReturnOffsetToBytecodeOffset.h new file mode 100644 index 0000000..3a7448e --- /dev/null +++ b/bytecode/CallReturnOffsetToBytecodeOffset.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2012 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 CallReturnOffsetToBytecodeOffset_h +#define CallReturnOffsetToBytecodeOffset_h + +#include + +namespace JSC { + +#if ENABLE(JIT) +// This structure is used to map from a call return location +// (given as an offset in bytes into the JIT code) back to +// the bytecode index of the corresponding bytecode operation. +// This is then used to look up the corresponding handler. +// FIXME: This should be made inlining aware! Currently it isn't +// because we never inline code that has exception handlers. +struct CallReturnOffsetToBytecodeOffset { + CallReturnOffsetToBytecodeOffset(unsigned callReturnOffset, unsigned bytecodeOffset) + : callReturnOffset(callReturnOffset) + , bytecodeOffset(bytecodeOffset) + { + } + + unsigned callReturnOffset; + unsigned bytecodeOffset; +}; + +inline unsigned getCallReturnOffset(CallReturnOffsetToBytecodeOffset* pc) +{ + return pc->callReturnOffset; +} +#endif + +} // namespace JSC + +#endif // CallReturnOffsetToBytecodeOffset_h + diff --git a/bytecode/CodeBlock.cpp b/bytecode/CodeBlock.cpp index fc99e90..7b828ac 100644 --- a/bytecode/CodeBlock.cpp +++ b/bytecode/CodeBlock.cpp @@ -31,23 +31,34 @@ #include "CodeBlock.h" #include "BytecodeGenerator.h" +#include "DFGCapabilities.h" +#include "DFGNode.h" +#include "DFGRepatch.h" #include "Debugger.h" #include "Interpreter.h" #include "JIT.h" +#include "JITStubs.h" #include "JSActivation.h" #include "JSFunction.h" #include "JSStaticScopeObject.h" #include "JSValue.h" +#include "LowLevelInterpreter.h" #include "RepatchBuffer.h" #include "UStringConcatenate.h" #include #include +#if ENABLE(DFG_JIT) +#include "DFGOperations.h" +#endif + #define DUMP_CODE_BLOCK_STATISTICS 0 namespace JSC { -#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING) +#if ENABLE(DFG_JIT) +using namespace DFG; +#endif static UString escapeQuotes(const UString& str) { @@ -66,9 +77,9 @@ static UString valueToSourceString(ExecState* exec, JSValue val) return "0"; if (val.isString()) - return makeUString("\"", escapeQuotes(val.toString(exec)), "\""); + return makeUString("\"", escapeQuotes(val.toString(exec)->value(exec)), "\""); - return val.toString(exec); + return val.description(); } static CString constantName(ExecState* exec, int k, JSValue value) @@ -144,7 +155,7 @@ void CodeBlock::printUnaryOp(ExecState* exec, int location, Vector: int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] %s\t\t %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data()); } void CodeBlock::printBinaryOp(ExecState* exec, int location, Vector::const_iterator& it, const char* op) const @@ -152,14 +163,14 @@ void CodeBlock::printBinaryOp(ExecState* exec, int location, Vector int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + dataLog("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); } void CodeBlock::printConditionalJump(ExecState* exec, const Vector::const_iterator&, Vector::const_iterator& it, int location, const char* op) const { int r0 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(exec, r0).data(), offset, location + offset); + dataLog("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(exec, r0).data(), offset, location + offset); } void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vector::const_iterator& it, const char* op) const @@ -167,8 +178,17 @@ void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vectoru.operand; int r1 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); - it += 4; + dataLog("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); + it += 5; +} + +void CodeBlock::printCallOp(ExecState* exec, int location, Vector::const_iterator& it, const char* op) const +{ + int func = (++it)->u.operand; + int argCount = (++it)->u.operand; + int registerOffset = (++it)->u.operand; + dataLog("[%4d] %s\t %s, %d, %d\n", location, op, registerName(exec, func).data(), argCount, registerOffset); + it += 2; } void CodeBlock::printPutByIdOp(ExecState* exec, int location, Vector::const_iterator& it, const char* op) const @@ -176,7 +196,7 @@ void CodeBlock::printPutByIdOp(ExecState* exec, int location, Vectoru.operand; int id0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); + dataLog("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); it += 5; } @@ -192,8 +212,6 @@ static bool isPropertyAccess(OpcodeID opcodeID) case op_get_by_id_self: case op_get_by_id_proto: case op_get_by_id_chain: - case op_get_by_id_self_list: - case op_get_by_id_proto_list: case op_put_by_id_transition: case op_put_by_id_replace: case op_get_by_id: @@ -208,7 +226,7 @@ static bool isPropertyAccess(OpcodeID opcodeID) } } -static unsigned instructionOffsetForNth(ExecState* exec, const Vector& instructions, int nth, bool (*predicate)(OpcodeID)) +static unsigned instructionOffsetForNth(ExecState* exec, const RefCountedArray& instructions, int nth, bool (*predicate)(OpcodeID)) { size_t i = 0; while (i < instructions.size()) { @@ -226,50 +244,48 @@ static unsigned instructionOffsetForNth(ExecState* exec, const Vectorinterpreter; - unsigned instructionOffset = vPC - m_instructions.begin(); + unsigned instructionOffset = vPC - instructions().begin(); if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id)) { printStructure("get_by_id", vPC, 4); @@ -297,15 +313,15 @@ void CodeBlock::printStructures(const Instruction* vPC) const return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) { - printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data()); + dataLog(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data()); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) { - printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data(), pointerToSourceString(vPC[6].u.structureChain).utf8().data()); + dataLog(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data(), pointerToSourceString(vPC[6].u.structureChain).utf8().data()); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) { - printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structureChain).utf8().data()); + dataLog(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structureChain).utf8().data()); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id)) { @@ -331,125 +347,118 @@ void CodeBlock::printStructures(const Instruction* vPC) const void CodeBlock::dump(ExecState* exec) const { - if (m_instructions.isEmpty()) { - printf("No instructions available.\n"); - return; - } - size_t instructionCount = 0; - for (size_t i = 0; i < m_instructions.size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(m_instructions[i].u.opcode)]) + for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)]) ++instructionCount; - printf("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s)\n\n", - static_cast(instructionCount), - static_cast(m_instructions.size() * sizeof(Instruction)), - this, m_numParameters, m_numCalleeRegisters); + dataLog("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s); %d variable(s)\n\n", + static_cast(instructions().size()), + static_cast(instructions().size() * sizeof(Instruction)), + this, m_numParameters, m_numCalleeRegisters, m_numVars); - Vector::const_iterator begin = m_instructions.begin(); - Vector::const_iterator end = m_instructions.end(); + Vector::const_iterator begin = instructions().begin(); + Vector::const_iterator end = instructions().end(); for (Vector::const_iterator it = begin; it != end; ++it) dump(exec, begin, it); if (!m_identifiers.isEmpty()) { - printf("\nIdentifiers:\n"); + dataLog("\nIdentifiers:\n"); size_t i = 0; do { - printf(" id%u = %s\n", static_cast(i), m_identifiers[i].ustring().utf8().data()); + dataLog(" id%u = %s\n", static_cast(i), m_identifiers[i].ustring().utf8().data()); ++i; } while (i != m_identifiers.size()); } if (!m_constantRegisters.isEmpty()) { - printf("\nConstants:\n"); - unsigned registerIndex = m_numVars; + dataLog("\nConstants:\n"); size_t i = 0; do { - printf(" k%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].get()).utf8().data()); + dataLog(" k%u = %s\n", static_cast(i), valueToSourceString(exec, m_constantRegisters[i].get()).utf8().data()); ++i; - ++registerIndex; } while (i < m_constantRegisters.size()); } if (m_rareData && !m_rareData->m_regexps.isEmpty()) { - printf("\nm_regexps:\n"); + dataLog("\nm_regexps:\n"); size_t i = 0; do { - printf(" re%u = %s\n", static_cast(i), regexpToSourceString(m_rareData->m_regexps[i].get()).utf8().data()); + dataLog(" re%u = %s\n", static_cast(i), regexpToSourceString(m_rareData->m_regexps[i].get()).utf8().data()); ++i; } while (i < m_rareData->m_regexps.size()); } #if ENABLE(JIT) if (!m_globalResolveInfos.isEmpty() || !m_structureStubInfos.isEmpty()) - printf("\nStructures:\n"); + dataLog("\nStructures:\n"); if (!m_globalResolveInfos.isEmpty()) { size_t i = 0; do { - printGlobalResolveInfo(m_globalResolveInfos[i], instructionOffsetForNth(exec, m_instructions, i + 1, isGlobalResolve)); + printGlobalResolveInfo(m_globalResolveInfos[i], instructionOffsetForNth(exec, instructions(), i + 1, isGlobalResolve)); ++i; } while (i < m_globalResolveInfos.size()); } if (!m_structureStubInfos.isEmpty()) { size_t i = 0; do { - printStructureStubInfo(m_structureStubInfos[i], instructionOffsetForNth(exec, m_instructions, i + 1, isPropertyAccess)); + printStructureStubInfo(m_structureStubInfos[i], instructionOffsetForNth(exec, instructions(), i + 1, isPropertyAccess)); ++i; } while (i < m_structureStubInfos.size()); } #endif -#if ENABLE(INTERPRETER) +#if ENABLE(CLASSIC_INTERPRETER) if (!m_globalResolveInstructions.isEmpty() || !m_propertyAccessInstructions.isEmpty()) - printf("\nStructures:\n"); + dataLog("\nStructures:\n"); if (!m_globalResolveInstructions.isEmpty()) { size_t i = 0; do { - printStructures(&m_instructions[m_globalResolveInstructions[i]]); + printStructures(&instructions()[m_globalResolveInstructions[i]]); ++i; } while (i < m_globalResolveInstructions.size()); } if (!m_propertyAccessInstructions.isEmpty()) { size_t i = 0; do { - printStructures(&m_instructions[m_propertyAccessInstructions[i]]); + printStructures(&instructions()[m_propertyAccessInstructions[i]]); ++i; } while (i < m_propertyAccessInstructions.size()); } #endif if (m_rareData && !m_rareData->m_exceptionHandlers.isEmpty()) { - printf("\nException Handlers:\n"); + dataLog("\nException Handlers:\n"); unsigned i = 0; do { - printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target); + dataLog("\t %d: { start: [%4d] end: [%4d] target: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target); ++i; } while (i < m_rareData->m_exceptionHandlers.size()); } if (m_rareData && !m_rareData->m_immediateSwitchJumpTables.isEmpty()) { - printf("Immediate Switch Jump Tables:\n"); + dataLog("Immediate Switch Jump Tables:\n"); unsigned i = 0; do { - printf(" %1d = {\n", i); + dataLog(" %1d = {\n", i); int entry = 0; Vector::const_iterator end = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.end(); for (Vector::const_iterator iter = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) { if (!*iter) continue; - printf("\t\t%4d => %04d\n", entry + m_rareData->m_immediateSwitchJumpTables[i].min, *iter); + dataLog("\t\t%4d => %04d\n", entry + m_rareData->m_immediateSwitchJumpTables[i].min, *iter); } - printf(" }\n"); + dataLog(" }\n"); ++i; } while (i < m_rareData->m_immediateSwitchJumpTables.size()); } if (m_rareData && !m_rareData->m_characterSwitchJumpTables.isEmpty()) { - printf("\nCharacter Switch Jump Tables:\n"); + dataLog("\nCharacter Switch Jump Tables:\n"); unsigned i = 0; do { - printf(" %1d = {\n", i); + dataLog(" %1d = {\n", i); int entry = 0; Vector::const_iterator end = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.end(); for (Vector::const_iterator iter = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) { @@ -457,27 +466,27 @@ void CodeBlock::dump(ExecState* exec) const continue; ASSERT(!((i + m_rareData->m_characterSwitchJumpTables[i].min) & ~0xFFFF)); UChar ch = static_cast(entry + m_rareData->m_characterSwitchJumpTables[i].min); - printf("\t\t\"%s\" => %04d\n", UString(&ch, 1).utf8().data(), *iter); + dataLog("\t\t\"%s\" => %04d\n", UString(&ch, 1).utf8().data(), *iter); } - printf(" }\n"); + dataLog(" }\n"); ++i; } while (i < m_rareData->m_characterSwitchJumpTables.size()); } if (m_rareData && !m_rareData->m_stringSwitchJumpTables.isEmpty()) { - printf("\nString Switch Jump Tables:\n"); + dataLog("\nString Switch Jump Tables:\n"); unsigned i = 0; do { - printf(" %1d = {\n", i); + dataLog(" %1d = {\n", i); StringJumpTable::StringOffsetTable::const_iterator end = m_rareData->m_stringSwitchJumpTables[i].offsetTable.end(); for (StringJumpTable::StringOffsetTable::const_iterator iter = m_rareData->m_stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter) - printf("\t\t\"%s\" => %04d\n", UString(iter->first).utf8().data(), iter->second.branchOffset); - printf(" }\n"); + dataLog("\t\t\"%s\" => %04d\n", UString(iter->first).utf8().data(), iter->second.branchOffset); + dataLog(" }\n"); ++i; } while (i < m_rareData->m_stringSwitchJumpTables.size()); } - printf("\n"); + dataLog("\n"); } void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& begin, Vector::const_iterator& it) const @@ -485,74 +494,73 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& int location = it - begin; switch (exec->interpreter()->getOpcodeID(it->u.opcode)) { case op_enter: { - printf("[%4d] enter\n", location); + dataLog("[%4d] enter\n", location); break; } case op_create_activation: { int r0 = (++it)->u.operand; - printf("[%4d] create_activation %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] create_activation %s\n", location, registerName(exec, r0).data()); break; } case op_create_arguments: { int r0 = (++it)->u.operand; - printf("[%4d] create_arguments\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] create_arguments\t %s\n", location, registerName(exec, r0).data()); break; } case op_init_lazy_reg: { int r0 = (++it)->u.operand; - printf("[%4d] init_lazy_reg\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] init_lazy_reg\t %s\n", location, registerName(exec, r0).data()); break; } case op_get_callee: { int r0 = (++it)->u.operand; - printf("[%4d] op_get_callee %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] op_get_callee %s\n", location, registerName(exec, r0).data()); break; } case op_create_this: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] create_this %s %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] create_this %s %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); break; } case op_convert_this: { int r0 = (++it)->u.operand; - printf("[%4d] convert_this %s\n", location, registerName(exec, r0).data()); - break; - } - case op_convert_this_strict: { - int r0 = (++it)->u.operand; - printf("[%4d] convert_this_strict %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] convert_this\t %s\n", location, registerName(exec, r0).data()); break; } case op_new_object: { int r0 = (++it)->u.operand; - printf("[%4d] new_object\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] new_object\t %s\n", location, registerName(exec, r0).data()); break; } case op_new_array: { int dst = (++it)->u.operand; int argv = (++it)->u.operand; int argc = (++it)->u.operand; - printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc); + dataLog("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc); break; } case op_new_array_buffer: { int dst = (++it)->u.operand; int argv = (++it)->u.operand; int argc = (++it)->u.operand; - printf("[%4d] new_array_buffer %s, %d, %d\n", location, registerName(exec, dst).data(), argv, argc); + dataLog("[%4d] new_array_buffer %s, %d, %d\n", location, registerName(exec, dst).data(), argv, argc); break; } case op_new_regexp: { int r0 = (++it)->u.operand; int re0 = (++it)->u.operand; - printf("[%4d] new_regexp\t %s, %s\n", location, registerName(exec, r0).data(), regexpName(re0, regexp(re0)).data()); + dataLog("[%4d] new_regexp\t %s, ", location, registerName(exec, r0).data()); + if (r0 >=0 && r0 < (int)numberOfRegExps()) + dataLog("%s\n", regexpName(re0, regexp(re0)).data()); + else + dataLog("bad_regexp(%d)\n", re0); break; } case op_mov: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] mov\t\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] mov\t\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); break; } case op_not: { @@ -591,14 +599,22 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& printBinaryOp(exec, location, it, "lesseq"); break; } + case op_greater: { + printBinaryOp(exec, location, it, "greater"); + break; + } + case op_greatereq: { + printBinaryOp(exec, location, it, "greatereq"); + break; + } case op_pre_inc: { int r0 = (++it)->u.operand; - printf("[%4d] pre_inc\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] pre_inc\t\t %s\n", location, registerName(exec, r0).data()); break; } case op_pre_dec: { int r0 = (++it)->u.operand; - printf("[%4d] pre_dec\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] pre_dec\t\t %s\n", location, registerName(exec, r0).data()); break; } case op_post_inc: { @@ -668,13 +684,9 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& ++it; break; } - case op_bitnot: { - printUnaryOp(exec, location, it, "bitnot"); - break; - } case op_check_has_instance: { int base = (++it)->u.operand; - printf("[%4d] check_has_instance\t\t %s\n", location, registerName(exec, base).data()); + dataLog("[%4d] check_has_instance\t\t %s\n", location, registerName(exec, base).data()); break; } case op_instanceof: { @@ -682,7 +694,7 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; int r3 = (++it)->u.operand; - printf("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data()); + dataLog("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data()); break; } case op_typeof: { @@ -720,21 +732,23 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& case op_resolve: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] resolve\t\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] resolve\t\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + it++; break; } case op_resolve_skip: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; int skipLevels = (++it)->u.operand; - printf("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), skipLevels); + dataLog("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), skipLevels); + it++; break; } case op_resolve_global: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] resolve_global\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); - it += 2; + dataLog("[%4d] resolve_global\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + it += 3; break; } case op_resolve_global_dynamic: { @@ -743,53 +757,66 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& JSValue scope = JSValue((++it)->u.jsCell.get()); ++it; int depth = (++it)->u.operand; - printf("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth); + dataLog("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth); + ++it; break; } case op_get_scoped_var: { int r0 = (++it)->u.operand; int index = (++it)->u.operand; int skipLevels = (++it)->u.operand; - printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(exec, r0).data(), index, skipLevels); + dataLog("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(exec, r0).data(), index, skipLevels); + it++; break; } case op_put_scoped_var: { int index = (++it)->u.operand; int skipLevels = (++it)->u.operand; int r0 = (++it)->u.operand; - printf("[%4d] put_scoped_var\t %d, %d, %s\n", location, index, skipLevels, registerName(exec, r0).data()); + dataLog("[%4d] put_scoped_var\t %d, %d, %s\n", location, index, skipLevels, registerName(exec, r0).data()); break; } case op_get_global_var: { int r0 = (++it)->u.operand; int index = (++it)->u.operand; - printf("[%4d] get_global_var\t %s, %d\n", location, registerName(exec, r0).data(), index); + dataLog("[%4d] get_global_var\t %s, %d\n", location, registerName(exec, r0).data(), index); + it++; break; } case op_put_global_var: { int index = (++it)->u.operand; int r0 = (++it)->u.operand; - printf("[%4d] put_global_var\t %d, %s\n", location, index, registerName(exec, r0).data()); + dataLog("[%4d] put_global_var\t %d, %s\n", location, index, registerName(exec, r0).data()); break; } case op_resolve_base: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; int isStrict = (++it)->u.operand; - printf("[%4d] resolve_base%s\t %s, %s\n", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] resolve_base%s\t %s, %s\n", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + it++; break; } case op_ensure_property_exists: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] ensure_property_exists\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] ensure_property_exists\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); break; } case op_resolve_with_base: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); + it++; + break; + } + case op_resolve_with_this: { + int r0 = (++it)->u.operand; + int r1 = (++it)->u.operand; + int id0 = (++it)->u.operand; + dataLog("[%4d] resolve_with_this %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); + it++; break; } case op_get_by_id: { @@ -800,18 +827,10 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& printGetByIdOp(exec, location, it, "get_by_id_self"); break; } - case op_get_by_id_self_list: { - printGetByIdOp(exec, location, it, "get_by_id_self_list"); - break; - } case op_get_by_id_proto: { printGetByIdOp(exec, location, it, "get_by_id_proto"); break; } - case op_get_by_id_proto_list: { - printGetByIdOp(exec, location, it, "op_get_by_id_proto_list"); - break; - } case op_get_by_id_chain: { printGetByIdOp(exec, location, it, "get_by_id_chain"); break; @@ -820,18 +839,10 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& printGetByIdOp(exec, location, it, "get_by_id_getter_self"); break; } - case op_get_by_id_getter_self_list: { - printGetByIdOp(exec, location, it, "get_by_id_getter_self_list"); - break; - } case op_get_by_id_getter_proto: { printGetByIdOp(exec, location, it, "get_by_id_getter_proto"); break; } - case op_get_by_id_getter_proto_list: { - printGetByIdOp(exec, location, it, "get_by_id_getter_proto_list"); - break; - } case op_get_by_id_getter_chain: { printGetByIdOp(exec, location, it, "get_by_id_getter_chain"); break; @@ -840,18 +851,10 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& printGetByIdOp(exec, location, it, "get_by_id_custom_self"); break; } - case op_get_by_id_custom_self_list: { - printGetByIdOp(exec, location, it, "get_by_id_custom_self_list"); - break; - } case op_get_by_id_custom_proto: { printGetByIdOp(exec, location, it, "get_by_id_custom_proto"); break; } - case op_get_by_id_custom_proto_list: { - printGetByIdOp(exec, location, it, "get_by_id_custom_proto_list"); - break; - } case op_get_by_id_custom_chain: { printGetByIdOp(exec, location, it, "get_by_id_custom_chain"); break; @@ -885,47 +888,51 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& printPutByIdOp(exec, location, it, "put_by_id_transition"); break; } - case op_put_by_id_generic: { - printPutByIdOp(exec, location, it, "put_by_id_generic"); + case op_put_by_id_transition_direct: { + printPutByIdOp(exec, location, it, "put_by_id_transition_direct"); break; } - case op_put_getter: { - int r0 = (++it)->u.operand; - int id0 = (++it)->u.operand; - int r1 = (++it)->u.operand; - printf("[%4d] put_getter\t %s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); + case op_put_by_id_transition_normal: { + printPutByIdOp(exec, location, it, "put_by_id_transition_normal"); + break; + } + case op_put_by_id_generic: { + printPutByIdOp(exec, location, it, "put_by_id_generic"); break; } - case op_put_setter: { + case op_put_getter_setter: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] put_setter\t %s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); + int r2 = (++it)->u.operand; + dataLog("[%4d] put_getter_setter\t %s, %s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); break; } case op_method_check: { - printf("[%4d] method_check\n", location); + dataLog("[%4d] method_check\n", location); break; } case op_del_by_id: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] del_by_id\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] del_by_id\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); break; } case op_get_by_val: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + dataLog("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + it++; break; } case op_get_argument_by_val: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%4d] get_argument_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + dataLog("[%4d] get_argument_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + ++it; break; } case op_get_by_pname: { @@ -935,38 +942,38 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& int r3 = (++it)->u.operand; int r4 = (++it)->u.operand; int r5 = (++it)->u.operand; - printf("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), registerName(exec, r4).data(), registerName(exec, r5).data()); + dataLog("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), registerName(exec, r4).data(), registerName(exec, r5).data()); break; } case op_put_by_val: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%4d] put_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + dataLog("[%4d] put_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); break; } case op_del_by_val: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%4d] del_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + dataLog("[%4d] del_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); break; } case op_put_by_index: { int r0 = (++it)->u.operand; unsigned n0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] put_by_index\t %s, %u, %s\n", location, registerName(exec, r0).data(), n0, registerName(exec, r1).data()); + dataLog("[%4d] put_by_index\t %s, %u, %s\n", location, registerName(exec, r0).data(), n0, registerName(exec, r1).data()); break; } case op_jmp: { int offset = (++it)->u.operand; - printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, location + offset); + dataLog("[%4d] jmp\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_loop: { int offset = (++it)->u.operand; - printf("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset); + dataLog("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_jtrue: { @@ -997,155 +1004,190 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + break; + } + case op_jless: { + int r0 = (++it)->u.operand; + int r1 = (++it)->u.operand; + int offset = (++it)->u.operand; + dataLog("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + break; + } + case op_jlesseq: { + int r0 = (++it)->u.operand; + int r1 = (++it)->u.operand; + int offset = (++it)->u.operand; + dataLog("[%4d] jlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + break; + } + case op_jgreater: { + int r0 = (++it)->u.operand; + int r1 = (++it)->u.operand; + int offset = (++it)->u.operand; + dataLog("[%4d] jgreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + break; + } + case op_jgreatereq: { + int r0 = (++it)->u.operand; + int r1 = (++it)->u.operand; + int offset = (++it)->u.operand; + dataLog("[%4d] jgreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_jnless: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_jnlesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } - case op_loop_if_less: { + case op_jngreater: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jngreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } - case op_jless: { + case op_jngreatereq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jngreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } - case op_jlesseq: { + case op_loop_if_less: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_loop_if_lesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + break; + } + case op_loop_if_greater: { + int r0 = (++it)->u.operand; + int r1 = (++it)->u.operand; + int offset = (++it)->u.operand; + dataLog("[%4d] loop_if_greater\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + break; + } + case op_loop_if_greatereq: { + int r0 = (++it)->u.operand; + int r1 = (++it)->u.operand; + int offset = (++it)->u.operand; + dataLog("[%4d] loop_if_greatereq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + break; + } + case op_loop_hint: { + dataLog("[%4d] loop_hint\n", location); break; } case op_switch_imm: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); + dataLog("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); break; } case op_switch_char: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); + dataLog("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); break; } case op_switch_string: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); + dataLog("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); break; } case op_new_func: { int r0 = (++it)->u.operand; int f0 = (++it)->u.operand; int shouldCheck = (++it)->u.operand; - printf("[%4d] new_func\t\t %s, f%d, %s\n", location, registerName(exec, r0).data(), f0, shouldCheck ? "" : ""); + dataLog("[%4d] new_func\t\t %s, f%d, %s\n", location, registerName(exec, r0).data(), f0, shouldCheck ? "" : ""); break; } case op_new_func_exp: { int r0 = (++it)->u.operand; int f0 = (++it)->u.operand; - printf("[%4d] new_func_exp\t %s, f%d\n", location, registerName(exec, r0).data(), f0); + dataLog("[%4d] new_func_exp\t %s, f%d\n", location, registerName(exec, r0).data(), f0); break; } case op_call: { - int func = (++it)->u.operand; - int argCount = (++it)->u.operand; - int registerOffset = (++it)->u.operand; - printf("[%4d] call\t\t %s, %d, %d\n", location, registerName(exec, func).data(), argCount, registerOffset); + printCallOp(exec, location, it, "call"); break; } case op_call_eval: { - int func = (++it)->u.operand; - int argCount = (++it)->u.operand; - int registerOffset = (++it)->u.operand; - printf("[%4d] call_eval\t %s, %d, %d\n", location, registerName(exec, func).data(), argCount, registerOffset); + printCallOp(exec, location, it, "call_eval"); break; } case op_call_varargs: { - int func = (++it)->u.operand; - int argCount = (++it)->u.operand; - int registerOffset = (++it)->u.operand; - printf("[%4d] call_varargs\t %s, %s, %d\n", location, registerName(exec, func).data(), registerName(exec, argCount).data(), registerOffset); - break; - } - case op_load_varargs: { - printUnaryOp(exec, location, it, "load_varargs"); + int callee = (++it)->u.operand; + int thisValue = (++it)->u.operand; + int arguments = (++it)->u.operand; + int firstFreeRegister = (++it)->u.operand; + dataLog("[%4d] call_varargs\t %s, %s, %s, %d\n", location, registerName(exec, callee).data(), registerName(exec, thisValue).data(), registerName(exec, arguments).data(), firstFreeRegister); break; } case op_tear_off_activation: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] tear_off_activation\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] tear_off_activation\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); break; } case op_tear_off_arguments: { int r0 = (++it)->u.operand; - printf("[%4d] tear_off_arguments\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] tear_off_arguments %s\n", location, registerName(exec, r0).data()); break; } case op_ret: { int r0 = (++it)->u.operand; - printf("[%4d] ret\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] ret\t\t %s\n", location, registerName(exec, r0).data()); break; } case op_call_put_result: { int r0 = (++it)->u.operand; - printf("[%4d] op_call_put_result\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] op_call_put_result\t\t %s\n", location, registerName(exec, r0).data()); + it++; break; } case op_ret_object_or_this: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] constructor_ret\t\t %s %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] constructor_ret\t\t %s %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); break; } case op_construct: { - int func = (++it)->u.operand; - int argCount = (++it)->u.operand; - int registerOffset = (++it)->u.operand; - printf("[%4d] construct\t %s, %d, %d\n", location, registerName(exec, func).data(), argCount, registerOffset); + printCallOp(exec, location, it, "construct"); break; } case op_strcat: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int count = (++it)->u.operand; - printf("[%4d] strcat\t\t %s, %s, %d\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), count); + dataLog("[%4d] strcat\t\t %s, %s, %d\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), count); break; } case op_to_primitive: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] to_primitive\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] to_primitive\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); break; } case op_get_pnames: { @@ -1154,7 +1196,7 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& int r2 = it[3].u.operand; int r3 = it[4].u.operand; int offset = it[5].u.operand; - printf("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), offset, location + offset); + dataLog("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), offset, location + offset); it += OPCODE_LENGTH(op_get_pnames) - 1; break; } @@ -1165,85 +1207,72 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& int size = it[4].u.operand; int iter = it[5].u.operand; int offset = it[6].u.operand; - printf("[%4d] next_pname\t %s, %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, dest).data(), registerName(exec, base).data(), registerName(exec, i).data(), registerName(exec, size).data(), registerName(exec, iter).data(), offset, location + offset); + dataLog("[%4d] next_pname\t %s, %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, dest).data(), registerName(exec, base).data(), registerName(exec, i).data(), registerName(exec, size).data(), registerName(exec, iter).data(), offset, location + offset); it += OPCODE_LENGTH(op_next_pname) - 1; break; } case op_push_scope: { int r0 = (++it)->u.operand; - printf("[%4d] push_scope\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] push_scope\t %s\n", location, registerName(exec, r0).data()); break; } case op_pop_scope: { - printf("[%4d] pop_scope\n", location); + dataLog("[%4d] pop_scope\n", location); break; } case op_push_new_scope: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] push_new_scope \t%s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); + dataLog("[%4d] push_new_scope \t%s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); break; } case op_jmp_scopes: { int scopeDelta = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, location + offset); + dataLog("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, location + offset); break; } case op_catch: { int r0 = (++it)->u.operand; - printf("[%4d] catch\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] catch\t\t %s\n", location, registerName(exec, r0).data()); break; } case op_throw: { int r0 = (++it)->u.operand; - printf("[%4d] throw\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] throw\t\t %s\n", location, registerName(exec, r0).data()); break; } case op_throw_reference_error: { int k0 = (++it)->u.operand; - printf("[%4d] throw_reference_error\t %s\n", location, constantName(exec, k0, getConstant(k0)).data()); - break; - } - case op_jsr: { - int retAddrDst = (++it)->u.operand; - int offset = (++it)->u.operand; - printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(exec, retAddrDst).data(), offset, location + offset); - break; - } - case op_sret: { - int retAddrSrc = (++it)->u.operand; - printf("[%4d] sret\t\t %s\n", location, registerName(exec, retAddrSrc).data()); + dataLog("[%4d] throw_reference_error\t %s\n", location, constantName(exec, k0, getConstant(k0)).data()); break; } case op_debug: { int debugHookID = (++it)->u.operand; int firstLine = (++it)->u.operand; int lastLine = (++it)->u.operand; - printf("[%4d] debug\t\t %s, %d, %d\n", location, debugHookName(debugHookID), firstLine, lastLine); + dataLog("[%4d] debug\t\t %s, %d, %d\n", location, debugHookName(debugHookID), firstLine, lastLine); break; } case op_profile_will_call: { int function = (++it)->u.operand; - printf("[%4d] profile_will_call %s\n", location, registerName(exec, function).data()); + dataLog("[%4d] profile_will_call %s\n", location, registerName(exec, function).data()); break; } case op_profile_did_call: { int function = (++it)->u.operand; - printf("[%4d] profile_did_call\t %s\n", location, registerName(exec, function).data()); + dataLog("[%4d] profile_did_call\t %s\n", location, registerName(exec, function).data()); break; } case op_end: { int r0 = (++it)->u.operand; - printf("[%4d] end\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] end\t\t %s\n", location, registerName(exec, r0).data()); break; } } } -#endif // !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING) - #if DUMP_CODE_BLOCK_STATISTICS static HashSet liveCodeBlockSet; #endif @@ -1342,44 +1371,101 @@ void CodeBlock::dumpStatistics() totalSize += symbolTableTotalSize; totalSize += (liveCodeBlockSet.size() * sizeof(CodeBlock)); - printf("Number of live CodeBlocks: %d\n", liveCodeBlockSet.size()); - printf("Size of a single CodeBlock [sizeof(CodeBlock)]: %zu\n", sizeof(CodeBlock)); - printf("Size of all CodeBlocks: %zu\n", totalSize); - printf("Average size of a CodeBlock: %zu\n", totalSize / liveCodeBlockSet.size()); + dataLog("Number of live CodeBlocks: %d\n", liveCodeBlockSet.size()); + dataLog("Size of a single CodeBlock [sizeof(CodeBlock)]: %zu\n", sizeof(CodeBlock)); + dataLog("Size of all CodeBlocks: %zu\n", totalSize); + dataLog("Average size of a CodeBlock: %zu\n", totalSize / liveCodeBlockSet.size()); - printf("Number of FunctionCode CodeBlocks: %zu (%.3f%%)\n", isFunctionCode, static_cast(isFunctionCode) * 100.0 / liveCodeBlockSet.size()); - printf("Number of GlobalCode CodeBlocks: %zu (%.3f%%)\n", isGlobalCode, static_cast(isGlobalCode) * 100.0 / liveCodeBlockSet.size()); - printf("Number of EvalCode CodeBlocks: %zu (%.3f%%)\n", isEvalCode, static_cast(isEvalCode) * 100.0 / liveCodeBlockSet.size()); + dataLog("Number of FunctionCode CodeBlocks: %zu (%.3f%%)\n", isFunctionCode, static_cast(isFunctionCode) * 100.0 / liveCodeBlockSet.size()); + dataLog("Number of GlobalCode CodeBlocks: %zu (%.3f%%)\n", isGlobalCode, static_cast(isGlobalCode) * 100.0 / liveCodeBlockSet.size()); + dataLog("Number of EvalCode CodeBlocks: %zu (%.3f%%)\n", isEvalCode, static_cast(isEvalCode) * 100.0 / liveCodeBlockSet.size()); - printf("Number of CodeBlocks with rare data: %zu (%.3f%%)\n", hasRareData, static_cast(hasRareData) * 100.0 / liveCodeBlockSet.size()); + dataLog("Number of CodeBlocks with rare data: %zu (%.3f%%)\n", hasRareData, static_cast(hasRareData) * 100.0 / liveCodeBlockSet.size()); - #define PRINT_STATS(name) printf("Number of CodeBlocks with " #name ": %zu\n", name##IsNotEmpty); printf("Size of all " #name ": %zu\n", name##TotalSize); + #define PRINT_STATS(name) dataLog("Number of CodeBlocks with " #name ": %zu\n", name##IsNotEmpty); dataLog("Size of all " #name ": %zu\n", name##TotalSize); FOR_EACH_MEMBER_VECTOR(PRINT_STATS) FOR_EACH_MEMBER_VECTOR_RARE_DATA(PRINT_STATS) #undef PRINT_STATS - printf("Number of CodeBlocks with evalCodeCache: %zu\n", evalCodeCacheIsNotEmpty); - printf("Number of CodeBlocks with symbolTable: %zu\n", symbolTableIsNotEmpty); + dataLog("Number of CodeBlocks with evalCodeCache: %zu\n", evalCodeCacheIsNotEmpty); + dataLog("Number of CodeBlocks with symbolTable: %zu\n", symbolTableIsNotEmpty); - printf("Size of all symbolTables: %zu\n", symbolTableTotalSize); + dataLog("Size of all symbolTables: %zu\n", symbolTableTotalSize); #else - printf("Dumping CodeBlock statistics is not enabled.\n"); + dataLog("Dumping CodeBlock statistics is not enabled.\n"); #endif } -CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr sourceProvider, unsigned sourceOffset, SymbolTable* symTab, bool isConstructor) +CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab) + : m_globalObject(other.m_globalObject) + , m_heap(other.m_heap) + , m_numCalleeRegisters(other.m_numCalleeRegisters) + , m_numVars(other.m_numVars) + , m_numCapturedVars(other.m_numCapturedVars) + , m_isConstructor(other.m_isConstructor) + , m_ownerExecutable(*other.m_globalData, other.m_ownerExecutable.get(), other.m_ownerExecutable.get()) + , m_globalData(other.m_globalData) + , m_instructions(other.m_instructions) + , m_thisRegister(other.m_thisRegister) + , m_argumentsRegister(other.m_argumentsRegister) + , m_activationRegister(other.m_activationRegister) + , m_needsFullScopeChain(other.m_needsFullScopeChain) + , m_usesEval(other.m_usesEval) + , m_isNumericCompareFunction(other.m_isNumericCompareFunction) + , m_isStrictMode(other.m_isStrictMode) + , m_codeType(other.m_codeType) + , m_source(other.m_source) + , m_sourceOffset(other.m_sourceOffset) +#if ENABLE(JIT) + , m_globalResolveInfos(other.m_globalResolveInfos) +#endif +#if ENABLE(VALUE_PROFILER) + , m_executionEntryCount(0) +#endif + , m_jumpTargets(other.m_jumpTargets) + , m_loopTargets(other.m_loopTargets) + , m_identifiers(other.m_identifiers) + , m_constantRegisters(other.m_constantRegisters) + , m_functionDecls(other.m_functionDecls) + , m_functionExprs(other.m_functionExprs) + , m_symbolTable(symTab) + , m_speculativeSuccessCounter(0) + , m_speculativeFailCounter(0) + , m_forcedOSRExitCounter(0) + , m_optimizationDelayCounter(0) + , m_reoptimizationRetryCounter(0) +#if ENABLE(JIT) + , m_canCompileWithDFGState(CompileWithDFGUnset) +#endif +{ + setNumParameters(other.numParameters()); + optimizeAfterWarmUp(); + jitAfterWarmUp(); + + if (other.m_rareData) { + createRareDataIfNecessary(); + + m_rareData->m_exceptionHandlers = other.m_rareData->m_exceptionHandlers; + m_rareData->m_regexps = other.m_rareData->m_regexps; + m_rareData->m_constantBuffers = other.m_rareData->m_constantBuffers; + m_rareData->m_immediateSwitchJumpTables = other.m_rareData->m_immediateSwitchJumpTables; + m_rareData->m_characterSwitchJumpTables = other.m_rareData->m_characterSwitchJumpTables; + m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables; + m_rareData->m_expressionInfo = other.m_rareData->m_expressionInfo; + m_rareData->m_lineInfo = other.m_rareData->m_lineInfo; + } +} + +CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr sourceProvider, unsigned sourceOffset, SymbolTable* symTab, bool isConstructor, PassOwnPtr alternative) : m_globalObject(globalObject->globalData(), ownerExecutable, globalObject) , m_heap(&m_globalObject->globalData().heap) , m_numCalleeRegisters(0) , m_numVars(0) - , m_numParameters(0) , m_isConstructor(isConstructor) + , m_numParameters(0) , m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable) , m_globalData(0) -#ifndef NDEBUG - , m_instructionCount(0) -#endif , m_argumentsRegister(-1) , m_needsFullScopeChain(ownerExecutable->needsActivation()) , m_usesEval(ownerExecutable->usesEval()) @@ -1388,9 +1474,20 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlo , m_codeType(codeType) , m_source(sourceProvider) , m_sourceOffset(sourceOffset) +#if ENABLE(VALUE_PROFILER) + , m_executionEntryCount(0) +#endif , m_symbolTable(symTab) + , m_alternative(alternative) + , m_speculativeSuccessCounter(0) + , m_speculativeFailCounter(0) + , m_optimizationDelayCounter(0) + , m_reoptimizationRetryCounter(0) { ASSERT(m_source); + + optimizeAfterWarmUp(); + jitAfterWarmUp(); #if DUMP_CODE_BLOCK_STATISTICS liveCodeBlockSet.add(this); @@ -1399,7 +1496,34 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlo CodeBlock::~CodeBlock() { +#if ENABLE(DFG_JIT) + // Remove myself from the set of DFG code blocks. Note that I may not be in this set + // (because I'm not a DFG code block), in which case this is a no-op anyway. + m_globalData->heap.m_dfgCodeBlocks.m_set.remove(this); +#endif + +#if ENABLE(VERBOSE_VALUE_PROFILE) + dumpValueProfiles(); +#endif + +#if ENABLE(LLINT) + while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end()) + m_incomingLLIntCalls.begin()->remove(); +#endif // ENABLE(LLINT) #if ENABLE(JIT) + // We may be destroyed before any CodeBlocks that refer to us are destroyed. + // Consider that two CodeBlocks become unreachable at the same time. There + // is no guarantee about the order in which the CodeBlocks are destroyed. + // So, if we don't remove incoming calls, and get destroyed before the + // CodeBlock(s) that have calls into us, then the CallLinkInfo vector's + // destructor will try to remove nodes from our (no longer valid) linked list. + while (m_incomingCalls.begin() != m_incomingCalls.end()) + m_incomingCalls.begin()->remove(); + + // Note that our outgoing calls will be removed from other CodeBlocks' + // m_incomingCalls linked lists through the execution of the ~CallLinkInfo + // destructors. + for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i) m_structureStubInfos[i].deref(); #endif // ENABLE(JIT) @@ -1409,6 +1533,24 @@ CodeBlock::~CodeBlock() #endif } +void CodeBlock::setNumParameters(int newValue) +{ + m_numParameters = newValue; + +#if ENABLE(VALUE_PROFILER) + m_argumentValueProfiles.resize(newValue); +#endif +} + +void CodeBlock::addParameter() +{ + m_numParameters++; + +#if ENABLE(VALUE_PROFILER) + m_argumentValueProfiles.append(ValueProfile()); +#endif +} + void CodeBlock::visitStructures(SlotVisitor& visitor, Instruction* vPC) const { Interpreter* interpreter = m_globalData->interpreter; @@ -1429,13 +1571,15 @@ void CodeBlock::visitStructures(SlotVisitor& visitor, Instruction* vPC) const } if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain)) { visitor.append(&vPC[4].u.structure); - visitor.append(&vPC[5].u.structureChain); + if (vPC[5].u.structureChain) + visitor.append(&vPC[5].u.structureChain); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) { visitor.append(&vPC[4].u.structure); visitor.append(&vPC[5].u.structure); - visitor.append(&vPC[6].u.structureChain); + if (vPC[6].u.structureChain) + visitor.append(&vPC[6].u.structureChain); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) && vPC[4].u.structure) { @@ -1451,17 +1595,6 @@ void CodeBlock::visitStructures(SlotVisitor& visitor, Instruction* vPC) const visitor.append(&vPC[3].u.structure); return; } - if ((vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto_list)) - || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self_list)) - || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_proto_list)) - || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_self_list)) - || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_proto_list)) - || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_self_list))) { - PolymorphicAccessStructureList* polymorphicStructures = vPC[4].u.polymorphicStructures; - polymorphicStructures->visitAggregate(visitor, vPC[5].u.operand); - delete polymorphicStructures; - return; - } // These instructions don't ref their Structures. ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_get_array_length) || vPC[0].u.opcode == interpreter->getOpcode(op_get_string_length)); @@ -1475,6 +1608,308 @@ void EvalCodeCache::visitAggregate(SlotVisitor& visitor) } void CodeBlock::visitAggregate(SlotVisitor& visitor) +{ +#if ENABLE(PARALLEL_GC) && ENABLE(DFG_JIT) + if (!!m_dfgData) { + // I may be asked to scan myself more than once, and it may even happen concurrently. + // To this end, use a CAS loop to check if I've been called already. Only one thread + // may proceed past this point - whichever one wins the CAS race. + unsigned oldValue; + do { + oldValue = m_dfgData->visitAggregateHasBeenCalled; + if (oldValue) { + // Looks like someone else won! Return immediately to ensure that we don't + // trace the same CodeBlock concurrently. Doing so is hazardous since we will + // be mutating the state of ValueProfiles, which contain JSValues, which can + // have word-tearing on 32-bit, leading to awesome timing-dependent crashes + // that are nearly impossible to track down. + + // Also note that it must be safe to return early as soon as we see the + // value true (well, (unsigned)1), since once a GC thread is in this method + // and has won the CAS race (i.e. was responsible for setting the value true) + // it will definitely complete the rest of this method before declaring + // termination. + return; + } + } while (!WTF::weakCompareAndSwap(&m_dfgData->visitAggregateHasBeenCalled, 0, 1)); + } +#endif // ENABLE(PARALLEL_GC) && ENABLE(DFG_JIT) + + if (!!m_alternative) + m_alternative->visitAggregate(visitor); + + // There are three things that may use unconditional finalizers: lazy bytecode freeing, + // inline cache clearing, and jettisoning. The probability of us wanting to do at + // least one of those things is probably quite close to 1. So we add one no matter what + // and when it runs, it figures out whether it has any work to do. + visitor.addUnconditionalFinalizer(this); + + if (shouldImmediatelyAssumeLivenessDuringScan()) { + // This code block is live, so scan all references strongly and return. + stronglyVisitStrongReferences(visitor); + stronglyVisitWeakReferences(visitor); + return; + } + +#if ENABLE(DFG_JIT) + // We get here if we're live in the sense that our owner executable is live, + // but we're not yet live for sure in another sense: we may yet decide that this + // code block should be jettisoned based on its outgoing weak references being + // stale. Set a flag to indicate that we're still assuming that we're dead, and + // perform one round of determining if we're live. The GC may determine, based on + // either us marking additional objects, or by other objects being marked for + // other reasons, that this iteration should run again; it will notify us of this + // decision by calling harvestWeakReferences(). + + m_dfgData->livenessHasBeenProved = false; + m_dfgData->allTransitionsHaveBeenMarked = false; + + performTracingFixpointIteration(visitor); + + // GC doesn't have enough information yet for us to decide whether to keep our DFG + // data, so we need to register a handler to run again at the end of GC, when more + // information is available. + if (!(m_dfgData->livenessHasBeenProved && m_dfgData->allTransitionsHaveBeenMarked)) + visitor.addWeakReferenceHarvester(this); + +#else // ENABLE(DFG_JIT) + ASSERT_NOT_REACHED(); +#endif // ENABLE(DFG_JIT) +} + +void CodeBlock::performTracingFixpointIteration(SlotVisitor& visitor) +{ + UNUSED_PARAM(visitor); + +#if ENABLE(DFG_JIT) + // Evaluate our weak reference transitions, if there are still some to evaluate. + if (!m_dfgData->allTransitionsHaveBeenMarked) { + bool allAreMarkedSoFar = true; + for (unsigned i = 0; i < m_dfgData->transitions.size(); ++i) { + if ((!m_dfgData->transitions[i].m_codeOrigin + || Heap::isMarked(m_dfgData->transitions[i].m_codeOrigin.get())) + && Heap::isMarked(m_dfgData->transitions[i].m_from.get())) { + // If the following three things are live, then the target of the + // transition is also live: + // - This code block. We know it's live already because otherwise + // we wouldn't be scanning ourselves. + // - The code origin of the transition. Transitions may arise from + // code that was inlined. They are not relevant if the user's + // object that is required for the inlinee to run is no longer + // live. + // - The source of the transition. The transition checks if some + // heap location holds the source, and if so, stores the target. + // Hence the source must be live for the transition to be live. + visitor.append(&m_dfgData->transitions[i].m_to); + } else + allAreMarkedSoFar = false; + } + + if (allAreMarkedSoFar) + m_dfgData->allTransitionsHaveBeenMarked = true; + } + + // Check if we have any remaining work to do. + if (m_dfgData->livenessHasBeenProved) + return; + + // Now check all of our weak references. If all of them are live, then we + // have proved liveness and so we scan our strong references. If at end of + // GC we still have not proved liveness, then this code block is toast. + bool allAreLiveSoFar = true; + for (unsigned i = 0; i < m_dfgData->weakReferences.size(); ++i) { + if (!Heap::isMarked(m_dfgData->weakReferences[i].get())) { + allAreLiveSoFar = false; + break; + } + } + + // If some weak references are dead, then this fixpoint iteration was + // unsuccessful. + if (!allAreLiveSoFar) + return; + + // All weak references are live. Record this information so we don't + // come back here again, and scan the strong references. + m_dfgData->livenessHasBeenProved = true; + stronglyVisitStrongReferences(visitor); +#endif // ENABLE(DFG_JIT) +} + +void CodeBlock::visitWeakReferences(SlotVisitor& visitor) +{ + performTracingFixpointIteration(visitor); +} + +void CodeBlock::finalizeUnconditionally() +{ +#if ENABLE(JIT) +#if ENABLE(JIT_VERBOSE_OSR) + static const bool verboseUnlinking = true; +#else + static const bool verboseUnlinking = false; +#endif +#endif // ENABLE(JIT) + +#if ENABLE(LLINT) + Interpreter* interpreter = m_globalData->interpreter; + // interpreter->classicEnabled() returns true if the old C++ interpreter is enabled. If that's enabled + // then we're not using LLInt. + if (!interpreter->classicEnabled() && !!numberOfInstructions()) { + for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) { + Instruction* curInstruction = &instructions()[m_propertyAccessInstructions[i]]; + switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) { + case op_get_by_id: + case op_put_by_id: + if (!curInstruction[4].u.structure || Heap::isMarked(curInstruction[4].u.structure.get())) + break; + if (verboseUnlinking) + dataLog("Clearing LLInt property access with structure %p.\n", curInstruction[4].u.structure.get()); + curInstruction[4].u.structure.clear(); + curInstruction[5].u.operand = 0; + break; + case op_put_by_id_transition_direct: + case op_put_by_id_transition_normal: + if (Heap::isMarked(curInstruction[4].u.structure.get()) + && Heap::isMarked(curInstruction[6].u.structure.get()) + && Heap::isMarked(curInstruction[7].u.structureChain.get())) + break; + if (verboseUnlinking) { + dataLog("Clearing LLInt put transition with structures %p -> %p, chain %p.\n", + curInstruction[4].u.structure.get(), + curInstruction[6].u.structure.get(), + curInstruction[7].u.structureChain.get()); + } + curInstruction[4].u.structure.clear(); + curInstruction[6].u.structure.clear(); + curInstruction[7].u.structureChain.clear(); + curInstruction[0].u.opcode = interpreter->getOpcode(op_put_by_id); + break; + default: + ASSERT_NOT_REACHED(); + } + } + for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) { + Instruction* curInstruction = &instructions()[m_globalResolveInstructions[i]]; + ASSERT(interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global + || interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global_dynamic); + if (!curInstruction[3].u.structure || Heap::isMarked(curInstruction[3].u.structure.get())) + continue; + if (verboseUnlinking) + dataLog("Clearing LLInt global resolve cache with structure %p.\n", curInstruction[3].u.structure.get()); + curInstruction[3].u.structure.clear(); + curInstruction[4].u.operand = 0; + } + for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) { + if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) { + if (verboseUnlinking) + dataLog("Clearing LLInt call from %p.\n", this); + m_llintCallLinkInfos[i].unlink(); + } + if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get())) + m_llintCallLinkInfos[i].lastSeenCallee.clear(); + } + } +#endif // ENABLE(LLINT) + +#if ENABLE(DFG_JIT) + // Check if we're not live. If we are, then jettison. + if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_dfgData->livenessHasBeenProved)) { + if (verboseUnlinking) + dataLog("Code block %p has dead weak references, jettisoning during GC.\n", this); + + // Make sure that the baseline JIT knows that it should re-warm-up before + // optimizing. + alternative()->optimizeAfterWarmUp(); + + jettison(); + return; + } +#endif // ENABLE(DFG_JIT) + +#if ENABLE(JIT) + // Handle inline caches. + if (!!getJITCode()) { + RepatchBuffer repatchBuffer(this); + for (unsigned i = 0; i < numberOfCallLinkInfos(); ++i) { + if (callLinkInfo(i).isLinked() && !Heap::isMarked(callLinkInfo(i).callee.get())) { + if (verboseUnlinking) + dataLog("Clearing call from %p to %p.\n", this, callLinkInfo(i).callee.get()); + callLinkInfo(i).unlink(*m_globalData, repatchBuffer); + } + if (!!callLinkInfo(i).lastSeenCallee + && !Heap::isMarked(callLinkInfo(i).lastSeenCallee.get())) + callLinkInfo(i).lastSeenCallee.clear(); + } + for (size_t size = m_globalResolveInfos.size(), i = 0; i < size; ++i) { + if (m_globalResolveInfos[i].structure && !Heap::isMarked(m_globalResolveInfos[i].structure.get())) { + if (verboseUnlinking) + dataLog("Clearing resolve info in %p.\n", this); + m_globalResolveInfos[i].structure.clear(); + } + } + + for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i) { + StructureStubInfo& stubInfo = m_structureStubInfos[i]; + + AccessType accessType = static_cast(stubInfo.accessType); + + if (stubInfo.visitWeakReferences()) + continue; + + if (verboseUnlinking) + dataLog("Clearing structure cache (kind %d) in %p.\n", stubInfo.accessType, this); + + if (isGetByIdAccess(accessType)) { + if (getJITCode().jitType() == JITCode::DFGJIT) + DFG::dfgResetGetByID(repatchBuffer, stubInfo); + else + JIT::resetPatchGetById(repatchBuffer, &stubInfo); + } else { + ASSERT(isPutByIdAccess(accessType)); + if (getJITCode().jitType() == JITCode::DFGJIT) + DFG::dfgResetPutByID(repatchBuffer, stubInfo); + else + JIT::resetPatchPutById(repatchBuffer, &stubInfo); + } + + stubInfo.reset(); + } + + for (size_t size = m_methodCallLinkInfos.size(), i = 0; i < size; ++i) { + if (!m_methodCallLinkInfos[i].cachedStructure) + continue; + + ASSERT(m_methodCallLinkInfos[i].seenOnce()); + ASSERT(!!m_methodCallLinkInfos[i].cachedPrototypeStructure); + + if (!Heap::isMarked(m_methodCallLinkInfos[i].cachedStructure.get()) + || !Heap::isMarked(m_methodCallLinkInfos[i].cachedPrototypeStructure.get()) + || !Heap::isMarked(m_methodCallLinkInfos[i].cachedFunction.get()) + || !Heap::isMarked(m_methodCallLinkInfos[i].cachedPrototype.get())) { + if (verboseUnlinking) + dataLog("Clearing method call in %p.\n", this); + m_methodCallLinkInfos[i].reset(repatchBuffer, getJITType()); + + StructureStubInfo& stubInfo = getStubInfo(m_methodCallLinkInfos[i].bytecodeIndex); + + AccessType accessType = static_cast(stubInfo.accessType); + + if (accessType != access_unset) { + ASSERT(isGetByIdAccess(accessType)); + if (getJITCode().jitType() == JITCode::DFGJIT) + DFG::dfgResetGetByID(repatchBuffer, stubInfo); + else + JIT::resetPatchGetById(repatchBuffer, &stubInfo); + stubInfo.reset(); + } + } + } + } +#endif +} + +void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor) { visitor.append(&m_globalObject); visitor.append(&m_ownerExecutable); @@ -1490,44 +1925,60 @@ void CodeBlock::visitAggregate(SlotVisitor& visitor) visitor.append(&m_functionExprs[i]); for (size_t i = 0; i < m_functionDecls.size(); ++i) visitor.append(&m_functionDecls[i]); -#if ENABLE(JIT_OPTIMIZE_CALL) - if (visitor.shouldUnlinkCalls()) - unlinkCalls(); - for (unsigned i = 0; i < numberOfCallLinkInfos(); ++i) - if (callLinkInfo(i).isLinked()) - visitor.append(&callLinkInfo(i).callee); -#endif -#if ENABLE(INTERPRETER) - for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) - visitStructures(visitor, &m_instructions[m_propertyAccessInstructions[i]]); - for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) - visitStructures(visitor, &m_instructions[m_globalResolveInstructions[i]]); -#endif -#if ENABLE(JIT) - for (size_t size = m_globalResolveInfos.size(), i = 0; i < size; ++i) { - if (m_globalResolveInfos[i].structure) - visitor.append(&m_globalResolveInfos[i].structure); +#if ENABLE(CLASSIC_INTERPRETER) + if (m_globalData->interpreter->classicEnabled() && !!numberOfInstructions()) { + for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) + visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]); + for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) + visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]); } +#endif - for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i) - m_structureStubInfos[i].visitAggregate(visitor); - - for (size_t size = m_methodCallLinkInfos.size(), i = 0; i < size; ++i) { - if (m_methodCallLinkInfos[i].cachedStructure) { - // Both members must be filled at the same time - visitor.append(&m_methodCallLinkInfos[i].cachedStructure); - ASSERT(!!m_methodCallLinkInfos[i].cachedPrototypeStructure); - visitor.append(&m_methodCallLinkInfos[i].cachedPrototypeStructure); - visitor.append(&m_methodCallLinkInfos[i].cachedFunction); - visitor.append(&m_methodCallLinkInfos[i].cachedPrototype); +#if ENABLE(DFG_JIT) + if (hasCodeOrigins()) { + // Make sure that executables that we have inlined don't die. + // FIXME: If they would have otherwise died, we should probably trigger recompilation. + for (size_t i = 0; i < inlineCallFrames().size(); ++i) { + InlineCallFrame& inlineCallFrame = inlineCallFrames()[i]; + visitor.append(&inlineCallFrame.executable); + visitor.append(&inlineCallFrame.callee); } } + + m_lazyOperandValueProfiles.computeUpdatedPredictions(); +#endif + +#if ENABLE(VALUE_PROFILER) + for (unsigned profileIndex = 0; profileIndex < numberOfArgumentValueProfiles(); ++profileIndex) + valueProfileForArgument(profileIndex)->computeUpdatedPrediction(); + for (unsigned profileIndex = 0; profileIndex < numberOfValueProfiles(); ++profileIndex) + valueProfile(profileIndex)->computeUpdatedPrediction(); #endif } +void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor) +{ + UNUSED_PARAM(visitor); + +#if ENABLE(DFG_JIT) + if (!m_dfgData) + return; + + for (unsigned i = 0; i < m_dfgData->transitions.size(); ++i) { + if (!!m_dfgData->transitions[i].m_codeOrigin) + visitor.append(&m_dfgData->transitions[i].m_codeOrigin); // Almost certainly not necessary, since the code origin should also be a weak reference. Better to be safe, though. + visitor.append(&m_dfgData->transitions[i].m_from); + visitor.append(&m_dfgData->transitions[i].m_to); + } + + for (unsigned i = 0; i < m_dfgData->weakReferences.size(); ++i) + visitor.append(&m_dfgData->weakReferences[i]); +#endif +} + HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset) { - ASSERT(bytecodeOffset < m_instructionCount); + ASSERT(bytecodeOffset < instructions().size()); if (!m_rareData) return 0; @@ -1545,7 +1996,7 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset) int CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset) { - ASSERT(bytecodeOffset < m_instructionCount); + ASSERT(bytecodeOffset < instructions().size()); if (!m_rareData) return m_ownerExecutable->source().firstLine(); @@ -1569,7 +2020,7 @@ int CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset) void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset) { - ASSERT(bytecodeOffset < m_instructionCount); + ASSERT(bytecodeOffset < instructions().size()); if (!m_rareData) { startOffset = 0; @@ -1604,7 +2055,7 @@ void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& d return; } -#if ENABLE(INTERPRETER) +#if ENABLE(CLASSIC_INTERPRETER) bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset) { if (m_globalResolveInstructions.isEmpty()) @@ -1649,9 +2100,7 @@ bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset) void CodeBlock::shrinkToFit() { - m_instructions.shrinkToFit(); - -#if ENABLE(INTERPRETER) +#if ENABLE(CLASSIC_INTERPRETER) m_propertyAccessInstructions.shrinkToFit(); m_globalResolveInstructions.shrinkToFit(); #endif @@ -1682,14 +2131,32 @@ void CodeBlock::createActivation(CallFrame* callFrame) ASSERT(codeType() == FunctionCode); ASSERT(needsFullScopeChain()); ASSERT(!callFrame->uncheckedR(activationRegister()).jsValue()); - JSActivation* activation = new (callFrame) JSActivation(callFrame, static_cast(ownerExecutable())); + JSActivation* activation = JSActivation::create(callFrame->globalData(), callFrame, static_cast(ownerExecutable())); callFrame->uncheckedR(activationRegister()) = JSValue(activation); callFrame->setScopeChain(callFrame->scopeChain()->push(activation)); } - + +unsigned CodeBlock::addOrFindConstant(JSValue v) +{ + unsigned numberOfConstants = numberOfConstantRegisters(); + for (unsigned i = 0; i < numberOfConstants; ++i) { + if (getConstant(FirstConstantRegisterIndex + i) == v) + return i; + } + return addConstant(v); +} + #if ENABLE(JIT) void CodeBlock::unlinkCalls() { + if (!!m_alternative) + m_alternative->unlinkCalls(); +#if ENABLE(LLINT) + for (size_t i = 0; i < m_llintCallLinkInfos.size(); ++i) { + if (m_llintCallLinkInfos[i].isLinked()) + m_llintCallLinkInfos[i].unlink(); + } +#endif if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size())) return; if (!m_globalData->canUseJIT()) @@ -1698,17 +2165,359 @@ void CodeBlock::unlinkCalls() for (size_t i = 0; i < m_callLinkInfos.size(); i++) { if (!m_callLinkInfos[i].isLinked()) continue; - repatchBuffer.relink(m_callLinkInfos[i].callReturnLocation, m_callLinkInfos[i].isCall ? m_globalData->jitStubs->ctiVirtualCallLink() : m_globalData->jitStubs->ctiVirtualConstructLink()); - m_callLinkInfos[i].unlink(); + m_callLinkInfos[i].unlink(*m_globalData, repatchBuffer); } } + +void CodeBlock::unlinkIncomingCalls() +{ +#if ENABLE(LLINT) + while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end()) + m_incomingLLIntCalls.begin()->unlink(); +#endif + if (m_incomingCalls.isEmpty()) + return; + RepatchBuffer repatchBuffer(this); + while (m_incomingCalls.begin() != m_incomingCalls.end()) + m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer); +} + +unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddress) +{ +#if ENABLE(LLINT) + if (returnAddress.value() >= bitwise_cast(&llint_begin) + && returnAddress.value() <= bitwise_cast(&llint_end)) { + ASSERT(exec->codeBlock()); + ASSERT(exec->codeBlock() == this); + ASSERT(JITCode::isBaselineCode(getJITType())); + Instruction* instruction = exec->currentVPC(); + ASSERT(instruction); + + // The LLInt stores the PC after the call instruction rather than the PC of + // the call instruction. This requires some correcting. We rely on the fact + // that the preceding instruction must be one of the call instructions, so + // either it's a call_varargs or it's a call, construct, or eval. + ASSERT(OPCODE_LENGTH(op_call_varargs) <= OPCODE_LENGTH(op_call)); + ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct)); + ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_eval)); + if (instruction[-OPCODE_LENGTH(op_call_varargs)].u.pointer == bitwise_cast(llint_op_call_varargs)) { + // We know that the preceding instruction must be op_call_varargs because there is no way that + // the pointer to the call_varargs could be an operand to the call. + instruction -= OPCODE_LENGTH(op_call_varargs); + ASSERT(instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast(llint_op_call) + && instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast(llint_op_construct) + && instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast(llint_op_call_eval)); + } else { + // Must be that the last instruction was some op_call. + ASSERT(instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast(llint_op_call) + || instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast(llint_op_construct) + || instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast(llint_op_call_eval)); + instruction -= OPCODE_LENGTH(op_call); + } + + return bytecodeOffset(instruction); + } +#else + UNUSED_PARAM(exec); +#endif + if (!m_rareData) + return 1; + Vector& callIndices = m_rareData->m_callReturnIndexVector; + if (!callIndices.size()) + return 1; + return binarySearch(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset; +} #endif void CodeBlock::clearEvalCache() { + if (!!m_alternative) + m_alternative->clearEvalCache(); if (!m_rareData) return; m_rareData->m_evalCodeCache.clear(); } +template +inline void replaceExistingEntries(Vector& target, Vector& source) +{ + ASSERT(target.size() <= source.size()); + for (size_t i = 0; i < target.size(); ++i) + target[i] = source[i]; +} + +void CodeBlock::copyPostParseDataFrom(CodeBlock* alternative) +{ + if (!alternative) + return; + + replaceExistingEntries(m_constantRegisters, alternative->m_constantRegisters); + replaceExistingEntries(m_functionDecls, alternative->m_functionDecls); + replaceExistingEntries(m_functionExprs, alternative->m_functionExprs); + if (!!m_rareData && !!alternative->m_rareData) + replaceExistingEntries(m_rareData->m_constantBuffers, alternative->m_rareData->m_constantBuffers); +} + +void CodeBlock::copyPostParseDataFromAlternative() +{ + copyPostParseDataFrom(m_alternative.get()); +} + +#if ENABLE(JIT) +CodeBlock* ProgramCodeBlock::replacement() +{ + return &static_cast(ownerExecutable())->generatedBytecode(); +} + +CodeBlock* EvalCodeBlock::replacement() +{ + return &static_cast(ownerExecutable())->generatedBytecode(); +} + +CodeBlock* FunctionCodeBlock::replacement() +{ + return &static_cast(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall); +} + +JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode) +{ + if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType())) + return 0; + JSObject* error = static_cast(ownerExecutable())->compileOptimized(exec, scopeChainNode); + return error; +} + +JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode) +{ + if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType())) + return 0; + JSObject* error = static_cast(ownerExecutable())->compileOptimized(exec, scopeChainNode); + return error; +} + +JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode) +{ + if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType())) + return 0; + JSObject* error = static_cast(ownerExecutable())->compileOptimizedFor(exec, scopeChainNode, m_isConstructor ? CodeForConstruct : CodeForCall); + return error; +} + +bool ProgramCodeBlock::canCompileWithDFGInternal() +{ + return DFG::canCompileProgram(this); +} + +bool EvalCodeBlock::canCompileWithDFGInternal() +{ + return DFG::canCompileEval(this); +} + +bool FunctionCodeBlock::canCompileWithDFGInternal() +{ + if (m_isConstructor) + return DFG::canCompileFunctionForConstruct(this); + return DFG::canCompileFunctionForCall(this); +} + +void ProgramCodeBlock::jettison() +{ + ASSERT(JITCode::isOptimizingJIT(getJITType())); + ASSERT(this == replacement()); + static_cast(ownerExecutable())->jettisonOptimizedCode(*globalData()); +} + +void EvalCodeBlock::jettison() +{ + ASSERT(JITCode::isOptimizingJIT(getJITType())); + ASSERT(this == replacement()); + static_cast(ownerExecutable())->jettisonOptimizedCode(*globalData()); +} + +void FunctionCodeBlock::jettison() +{ + ASSERT(JITCode::isOptimizingJIT(getJITType())); + ASSERT(this == replacement()); + static_cast(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall); +} + +bool ProgramCodeBlock::jitCompileImpl(JSGlobalData& globalData) +{ + ASSERT(getJITType() == JITCode::InterpreterThunk); + ASSERT(this == replacement()); + return static_cast(ownerExecutable())->jitCompile(globalData); +} + +bool EvalCodeBlock::jitCompileImpl(JSGlobalData& globalData) +{ + ASSERT(getJITType() == JITCode::InterpreterThunk); + ASSERT(this == replacement()); + return static_cast(ownerExecutable())->jitCompile(globalData); +} + +bool FunctionCodeBlock::jitCompileImpl(JSGlobalData& globalData) +{ + ASSERT(getJITType() == JITCode::InterpreterThunk); + ASSERT(this == replacement()); + return static_cast(ownerExecutable())->jitCompileFor(globalData, m_isConstructor ? CodeForConstruct : CodeForCall); +} +#endif + +#if ENABLE(VALUE_PROFILER) +bool CodeBlock::shouldOptimizeNow() +{ +#if ENABLE(JIT_VERBOSE_OSR) + dataLog("Considering optimizing %p...\n", this); +#endif + +#if ENABLE(VERBOSE_VALUE_PROFILE) + dumpValueProfiles(); +#endif + + if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay) + return true; + + unsigned numberOfLiveNonArgumentValueProfiles = 0; + unsigned numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full. + for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) { + ValueProfile* profile = getFromAllValueProfiles(i); + unsigned numSamples = profile->totalNumberOfSamples(); + if (numSamples > ValueProfile::numberOfBuckets) + numSamples = ValueProfile::numberOfBuckets; // We don't want profiles that are extremely hot to be given more weight. + numberOfSamplesInProfiles += numSamples; + if (profile->m_bytecodeOffset < 0) { + profile->computeUpdatedPrediction(); + continue; + } + if (profile->numberOfSamples() || profile->m_prediction != PredictNone) + numberOfLiveNonArgumentValueProfiles++; + profile->computeUpdatedPrediction(); + } + +#if ENABLE(JIT_VERBOSE_OSR) + dataLog("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles()); +#endif + + if ((!numberOfValueProfiles() || (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles() >= Options::desiredProfileLivenessRate) + && (!totalNumberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / totalNumberOfValueProfiles() >= Options::desiredProfileFullnessRate) + && static_cast(m_optimizationDelayCounter) + 1 >= Options::minimumOptimizationDelay) + return true; + + ASSERT(m_optimizationDelayCounter < std::numeric_limits::max()); + m_optimizationDelayCounter++; + optimizeAfterWarmUp(); + return false; +} +#endif + +#if ENABLE(DFG_JIT) +void CodeBlock::tallyFrequentExitSites() +{ + ASSERT(getJITType() == JITCode::DFGJIT); + ASSERT(alternative()->getJITType() == JITCode::BaselineJIT); + ASSERT(!!m_dfgData); + + CodeBlock* profiledBlock = alternative(); + + for (unsigned i = 0; i < m_dfgData->osrExit.size(); ++i) { + DFG::OSRExit& exit = m_dfgData->osrExit[i]; + + if (!exit.considerAddingAsFrequentExitSite(this, profiledBlock)) + continue; + +#if DFG_ENABLE(DEBUG_VERBOSE) + dataLog("OSR exit #%u (bc#%u, @%u, %s) for code block %p occurred frequently; counting as frequent exit site.\n", i, exit.m_codeOrigin.bytecodeIndex, exit.m_nodeIndex, DFG::exitKindToString(exit.m_kind), this); +#endif + } +} +#endif // ENABLE(DFG_JIT) + +#if ENABLE(VERBOSE_VALUE_PROFILE) +void CodeBlock::dumpValueProfiles() +{ + dataLog("ValueProfile for %p:\n", this); + for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) { + ValueProfile* profile = getFromAllValueProfiles(i); + if (profile->m_bytecodeOffset < 0) { + ASSERT(profile->m_bytecodeOffset == -1); + dataLog(" arg = %u: ", i); + } else + dataLog(" bc = %d: ", profile->m_bytecodeOffset); + if (!profile->numberOfSamples() && profile->m_prediction == PredictNone) { + dataLog("\n"); + continue; + } + profile->dump(WTF::dataFile()); + dataLog("\n"); + } + dataLog("RareCaseProfile for %p:\n", this); + for (unsigned i = 0; i < numberOfRareCaseProfiles(); ++i) { + RareCaseProfile* profile = rareCaseProfile(i); + dataLog(" bc = %d: %u\n", profile->m_bytecodeOffset, profile->m_counter); + } + dataLog("SpecialFastCaseProfile for %p:\n", this); + for (unsigned i = 0; i < numberOfSpecialFastCaseProfiles(); ++i) { + RareCaseProfile* profile = specialFastCaseProfile(i); + dataLog(" bc = %d: %u\n", profile->m_bytecodeOffset, profile->m_counter); + } +} +#endif + +size_t CodeBlock::predictedMachineCodeSize() +{ + // This will be called from CodeBlock::CodeBlock before either m_globalData or the + // instructions have been initialized. It's OK to return 0 because what will really + // matter is the recomputation of this value when the slow path is triggered. + if (!m_globalData) + return 0; + + if (!m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT) + return 0; // It's as good of a prediction as we'll get. + + // Be conservative: return a size that will be an overestimation 84% of the time. + double multiplier = m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT.mean() + + m_globalData->machineCodeBytesPerBytecodeWordForBaselineJIT.standardDeviation(); + + // Be paranoid: silently reject bogus multipiers. Silently doing the "wrong" thing + // here is OK, since this whole method is just a heuristic. + if (multiplier < 0 || multiplier > 1000) + return 0; + + double doubleResult = multiplier * m_instructions.size(); + + // Be even more paranoid: silently reject values that won't fit into a size_t. If + // the function is so huge that we can't even fit it into virtual memory then we + // should probably have some other guards in place to prevent us from even getting + // to this point. + if (doubleResult > std::numeric_limits::max()) + return 0; + + return static_cast(doubleResult); +} + +bool CodeBlock::usesOpcode(OpcodeID opcodeID) +{ + Interpreter* interpreter = globalData()->interpreter; + Instruction* instructionsBegin = instructions().begin(); + unsigned instructionCount = instructions().size(); + + for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount; ) { + switch (interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode)) { +#define DEFINE_OP(curOpcode, length) \ + case curOpcode: \ + if (curOpcode == opcodeID) \ + return true; \ + bytecodeOffset += length; \ + break; + FOR_EACH_OPCODE_ID(DEFINE_OP) +#undef DEFINE_OP + default: + ASSERT_NOT_REACHED(); + break; + } + } + + return false; +} + } // namespace JSC diff --git a/bytecode/CodeBlock.h b/bytecode/CodeBlock.h index 7aa356e..778376f 100644 --- a/bytecode/CodeBlock.h +++ b/bytecode/CodeBlock.h @@ -30,206 +30,111 @@ #ifndef CodeBlock_h #define CodeBlock_h +#include "BytecodeConventions.h" +#include "CallLinkInfo.h" +#include "CallReturnOffsetToBytecodeOffset.h" +#include "CodeOrigin.h" +#include "CodeType.h" +#include "CompactJITCodeMap.h" +#include "DFGCodeBlocks.h" +#include "DFGExitProfile.h" +#include "DFGOSREntry.h" +#include "DFGOSRExit.h" #include "EvalCodeCache.h" +#include "ExecutionCounter.h" +#include "ExpressionRangeInfo.h" +#include "GlobalResolveInfo.h" +#include "HandlerInfo.h" +#include "MethodCallLinkInfo.h" +#include "Options.h" #include "Instruction.h" #include "JITCode.h" #include "JITWriteBarrier.h" #include "JSGlobalObject.h" #include "JumpTable.h" +#include "LLIntCallLinkInfo.h" +#include "LazyOperandValueProfile.h" +#include "LineInfo.h" #include "Nodes.h" #include "RegExpObject.h" +#include "StructureStubInfo.h" #include "UString.h" +#include "UnconditionalFinalizer.h" +#include "ValueProfile.h" +#include #include #include #include +#include #include - -#if ENABLE(JIT) #include "StructureStubInfo.h" -#endif - -// Register numbers used in bytecode operations have different meaning according to their ranges: -// 0x80000000-0xFFFFFFFF Negative indices from the CallFrame pointer are entries in the call frame, see RegisterFile.h. -// 0x00000000-0x3FFFFFFF Forwards indices from the CallFrame pointer are local vars and temporaries with the function's callframe. -// 0x40000000-0x7FFFFFFF Positive indices from 0x40000000 specify entries in the constant pool on the CodeBlock. -static const int FirstConstantRegisterIndex = 0x40000000; namespace JSC { - enum HasSeenShouldRepatch { - hasSeenShouldRepatch - }; - + class DFGCodeBlocks; class ExecState; - - enum CodeType { GlobalCode, EvalCode, FunctionCode }; + class LLIntOffsetsExtractor; inline int unmodifiedArgumentsRegister(int argumentsRegister) { return argumentsRegister - 1; } static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits::max(); } - struct HandlerInfo { - uint32_t start; - uint32_t end; - uint32_t target; - uint32_t scopeDepth; -#if ENABLE(JIT) - CodeLocationLabel nativeCode; -#endif - }; - - struct ExpressionRangeInfo { - enum { - MaxOffset = (1 << 7) - 1, - MaxDivot = (1 << 25) - 1 - }; - uint32_t instructionOffset : 25; - uint32_t divotPoint : 25; - uint32_t startOffset : 7; - uint32_t endOffset : 7; - }; - - struct LineInfo { - uint32_t instructionOffset; - int32_t lineNumber; - }; - -#if ENABLE(JIT) - struct CallLinkInfo { - CallLinkInfo() - : hasSeenShouldRepatch(false) - , isCall(false) - { - } - - CodeLocationNearCall callReturnLocation; - CodeLocationDataLabelPtr hotPathBegin; - CodeLocationNearCall hotPathOther; - JITWriteBarrier callee; - bool hasSeenShouldRepatch : 1; - bool isCall : 1; - - bool isLinked() { return callee; } - void unlink() - { - hasSeenShouldRepatch = false; - callee.clear(); - } - - bool seenOnce() - { - return hasSeenShouldRepatch; - } - - void setSeen() - { - hasSeenShouldRepatch = true; - } - }; - - struct MethodCallLinkInfo { - MethodCallLinkInfo() - { - } - - bool seenOnce() - { - ASSERT(!cachedStructure); - return cachedPrototypeStructure.isFlagged(); - } - - void setSeen() - { - ASSERT(!cachedStructure && !cachedPrototypeStructure); - // We use the values of cachedStructure & cachedPrototypeStructure to indicate the - // current state. - // - In the initial state, both are null. - // - Once this transition has been taken once, cachedStructure is - // null and cachedPrototypeStructure is set to a nun-null value. - // - Once the call is linked both structures are set to non-null values. - cachedPrototypeStructure.setFlagOnBarrier(); - } - - CodeLocationCall callReturnLocation; - JITWriteBarrier cachedStructure; - JITWriteBarrier cachedPrototypeStructure; - // We'd like this to actually be JSFunction, but InternalFunction and JSFunction - // don't have a common parent class and we allow specialisation on both - JITWriteBarrier cachedFunction; - JITWriteBarrier cachedPrototype; - }; - - struct GlobalResolveInfo { - GlobalResolveInfo(unsigned bytecodeOffset) - : offset(0) - , bytecodeOffset(bytecodeOffset) - { - } - - WriteBarrier structure; - unsigned offset; - unsigned bytecodeOffset; - }; - - // This structure is used to map from a call return location - // (given as an offset in bytes into the JIT code) back to - // the bytecode index of the corresponding bytecode operation. - // This is then used to look up the corresponding handler. - struct CallReturnOffsetToBytecodeOffset { - CallReturnOffsetToBytecodeOffset(unsigned callReturnOffset, unsigned bytecodeOffset) - : callReturnOffset(callReturnOffset) - , bytecodeOffset(bytecodeOffset) - { - } - - unsigned callReturnOffset; - unsigned bytecodeOffset; - }; - - // valueAtPosition helpers for the binarySearch algorithm. - - inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo) - { - return structureStubInfo->callReturnLocation.executableAddress(); - } - - inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo) - { - return callLinkInfo->callReturnLocation.executableAddress(); - } - - inline void* getMethodCallLinkInfoReturnLocation(MethodCallLinkInfo* methodCallLinkInfo) - { - return methodCallLinkInfo->callReturnLocation.executableAddress(); - } - - inline unsigned getCallReturnOffset(CallReturnOffsetToBytecodeOffset* pc) - { - return pc->callReturnOffset; - } -#endif - - class CodeBlock { + class CodeBlock : public UnconditionalFinalizer, public WeakReferenceHarvester { WTF_MAKE_FAST_ALLOCATED; friend class JIT; + friend class LLIntOffsetsExtractor; + public: + enum CopyParsedBlockTag { CopyParsedBlock }; protected: - CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr, unsigned sourceOffset, SymbolTable* symbolTable, bool isConstructor); + CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable*); + + CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr, unsigned sourceOffset, SymbolTable*, bool isConstructor, PassOwnPtr alternative); WriteBarrier m_globalObject; Heap* m_heap; public: - virtual ~CodeBlock(); + JS_EXPORT_PRIVATE virtual ~CodeBlock(); + + int numParameters() const { return m_numParameters; } + void setNumParameters(int newValue); + void addParameter(); + + int* addressOfNumParameters() { return &m_numParameters; } + static ptrdiff_t offsetOfNumParameters() { return OBJECT_OFFSETOF(CodeBlock, m_numParameters); } + CodeBlock* alternative() { return m_alternative.get(); } + PassOwnPtr releaseAlternative() { return m_alternative.release(); } + void setAlternative(PassOwnPtr alternative) { m_alternative = alternative; } + + CodeSpecializationKind specializationKind() + { + if (m_isConstructor) + return CodeForConstruct; + return CodeForCall; + } + +#if ENABLE(JIT) + CodeBlock* baselineVersion() + { + CodeBlock* result = replacement(); + if (!result) + return 0; // This can happen if we're in the process of creating the baseline version. + while (result->alternative()) + result = result->alternative(); + ASSERT(result); + ASSERT(JITCode::isBaselineCode(result->getJITType())); + return result; + } +#endif + void visitAggregate(SlotVisitor&); static void dumpStatistics(); -#if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING void dump(ExecState*) const; void printStructures(const Instruction*) const; void printStructure(const char* name, const Instruction*, int operand) const; -#endif bool isStrictMode() const { return m_isStrictMode; } @@ -260,55 +165,264 @@ namespace JSC { return *(binarySearch(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress.value())); } + StructureStubInfo& getStubInfo(unsigned bytecodeIndex) + { + return *(binarySearch(m_structureStubInfos.begin(), m_structureStubInfos.size(), bytecodeIndex)); + } + CallLinkInfo& getCallLinkInfo(ReturnAddressPtr returnAddress) { return *(binarySearch(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress.value())); } + + CallLinkInfo& getCallLinkInfo(unsigned bytecodeIndex) + { + return *(binarySearch(m_callLinkInfos.begin(), m_callLinkInfos.size(), bytecodeIndex)); + } MethodCallLinkInfo& getMethodCallLinkInfo(ReturnAddressPtr returnAddress) { return *(binarySearch(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), returnAddress.value())); } - unsigned bytecodeOffset(ReturnAddressPtr returnAddress) + MethodCallLinkInfo& getMethodCallLinkInfo(unsigned bytecodeIndex) + { + return *(binarySearch(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), bytecodeIndex)); + } + + unsigned bytecodeOffset(ExecState*, ReturnAddressPtr); + + unsigned bytecodeOffsetForCallAtIndex(unsigned index) { if (!m_rareData) return 1; Vector& callIndices = m_rareData->m_callReturnIndexVector; if (!callIndices.size()) return 1; - return binarySearch(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset; + ASSERT(index < m_rareData->m_callReturnIndexVector.size()); + return m_rareData->m_callReturnIndexVector[index].bytecodeOffset; } void unlinkCalls(); + + bool hasIncomingCalls() { return m_incomingCalls.begin() != m_incomingCalls.end(); } + + void linkIncomingCall(CallLinkInfo* incoming) + { + m_incomingCalls.push(incoming); + } +#if ENABLE(LLINT) + void linkIncomingCall(LLIntCallLinkInfo* incoming) + { + m_incomingLLIntCalls.push(incoming); + } +#endif // ENABLE(LLINT) + + void unlinkIncomingCalls(); +#endif // ENABLE(JIT) + +#if ENABLE(DFG_JIT) || ENABLE(LLINT) + void setJITCodeMap(PassOwnPtr jitCodeMap) + { + m_jitCodeMap = jitCodeMap; + } + CompactJITCodeMap* jitCodeMap() + { + return m_jitCodeMap.get(); + } +#endif + +#if ENABLE(DFG_JIT) + void createDFGDataIfNecessary() + { + if (!!m_dfgData) + return; + + m_dfgData = adoptPtr(new DFGData); + } + + DFG::OSREntryData* appendDFGOSREntryData(unsigned bytecodeIndex, unsigned machineCodeOffset) + { + createDFGDataIfNecessary(); + DFG::OSREntryData entry; + entry.m_bytecodeIndex = bytecodeIndex; + entry.m_machineCodeOffset = machineCodeOffset; + m_dfgData->osrEntry.append(entry); + return &m_dfgData->osrEntry.last(); + } + unsigned numberOfDFGOSREntries() const + { + if (!m_dfgData) + return 0; + return m_dfgData->osrEntry.size(); + } + DFG::OSREntryData* dfgOSREntryData(unsigned i) { return &m_dfgData->osrEntry[i]; } + DFG::OSREntryData* dfgOSREntryDataForBytecodeIndex(unsigned bytecodeIndex) + { + return binarySearch(m_dfgData->osrEntry.begin(), m_dfgData->osrEntry.size(), bytecodeIndex); + } + + void appendOSRExit(const DFG::OSRExit& osrExit) + { + createDFGDataIfNecessary(); + m_dfgData->osrExit.append(osrExit); + } + + DFG::OSRExit& lastOSRExit() + { + return m_dfgData->osrExit.last(); + } + + void appendSpeculationRecovery(const DFG::SpeculationRecovery& recovery) + { + createDFGDataIfNecessary(); + m_dfgData->speculationRecovery.append(recovery); + } + + unsigned numberOfOSRExits() + { + if (!m_dfgData) + return 0; + return m_dfgData->osrExit.size(); + } + + unsigned numberOfSpeculationRecoveries() + { + if (!m_dfgData) + return 0; + return m_dfgData->speculationRecovery.size(); + } + + DFG::OSRExit& osrExit(unsigned index) + { + return m_dfgData->osrExit[index]; + } + + DFG::SpeculationRecovery& speculationRecovery(unsigned index) + { + return m_dfgData->speculationRecovery[index]; + } + + void appendWeakReference(JSCell* target) + { + createDFGDataIfNecessary(); + m_dfgData->weakReferences.append(WriteBarrier(*globalData(), ownerExecutable(), target)); + } + + void shrinkWeakReferencesToFit() + { + if (!m_dfgData) + return; + m_dfgData->weakReferences.shrinkToFit(); + } + + void appendWeakReferenceTransition(JSCell* codeOrigin, JSCell* from, JSCell* to) + { + createDFGDataIfNecessary(); + m_dfgData->transitions.append( + WeakReferenceTransition(*globalData(), ownerExecutable(), codeOrigin, from, to)); + } + + void shrinkWeakReferenceTransitionsToFit() + { + if (!m_dfgData) + return; + m_dfgData->transitions.shrinkToFit(); + } #endif -#if ENABLE(INTERPRETER) unsigned bytecodeOffset(Instruction* returnAddress) { + ASSERT(returnAddress >= instructions().begin() && returnAddress < instructions().end()); return static_cast(returnAddress) - instructions().begin(); } -#endif void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; } bool isNumericCompareFunction() { return m_isNumericCompareFunction; } - Vector& instructions() { return m_instructions; } - void discardBytecode() { m_instructions.clear(); } + unsigned numberOfInstructions() const { return m_instructions.size(); } + RefCountedArray& instructions() { return m_instructions; } + const RefCountedArray& instructions() const { return m_instructions; } + + size_t predictedMachineCodeSize(); + + bool usesOpcode(OpcodeID); -#ifndef NDEBUG - unsigned instructionCount() { return m_instructionCount; } - void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; } -#endif + unsigned instructionCount() { return m_instructions.size(); } #if ENABLE(JIT) - JITCode& getJITCode() { return m_isConstructor ? ownerExecutable()->generatedJITCodeForConstruct() : ownerExecutable()->generatedJITCodeForCall(); } - ExecutablePool* executablePool() { return getJITCode().getExecutablePool(); } + void setJITCode(const JITCode& code, MacroAssemblerCodePtr codeWithArityCheck) + { + m_jitCode = code; + m_jitCodeWithArityCheck = codeWithArityCheck; +#if ENABLE(DFG_JIT) + if (m_jitCode.jitType() == JITCode::DFGJIT) { + createDFGDataIfNecessary(); + m_globalData->heap.m_dfgCodeBlocks.m_set.add(this); + } +#endif + } + JITCode& getJITCode() { return m_jitCode; } + MacroAssemblerCodePtr getJITCodeWithArityCheck() { return m_jitCodeWithArityCheck; } + JITCode::JITType getJITType() { return m_jitCode.jitType(); } + ExecutableMemoryHandle* executableMemory() { return getJITCode().getExecutableMemory(); } + virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*) = 0; + virtual void jettison() = 0; + enum JITCompilationResult { AlreadyCompiled, CouldNotCompile, CompiledSuccessfully }; + JITCompilationResult jitCompile(JSGlobalData& globalData) + { + if (getJITType() != JITCode::InterpreterThunk) { + ASSERT(getJITType() == JITCode::BaselineJIT); + return AlreadyCompiled; + } +#if ENABLE(JIT) + if (jitCompileImpl(globalData)) + return CompiledSuccessfully; + return CouldNotCompile; +#else + UNUSED_PARAM(globalData); + return CouldNotCompile; +#endif + } + virtual CodeBlock* replacement() = 0; + + enum CompileWithDFGState { + CompileWithDFGFalse, + CompileWithDFGTrue, + CompileWithDFGUnset + }; + + virtual bool canCompileWithDFGInternal() = 0; + bool canCompileWithDFG() + { + bool result = canCompileWithDFGInternal(); + m_canCompileWithDFGState = result ? CompileWithDFGTrue : CompileWithDFGFalse; + return result; + } + CompileWithDFGState canCompileWithDFGState() { return m_canCompileWithDFGState; } + + bool hasOptimizedReplacement() + { + ASSERT(JITCode::isBaselineCode(getJITType())); + bool result = replacement()->getJITType() > getJITType(); +#if !ASSERT_DISABLED + if (result) + ASSERT(replacement()->getJITType() == JITCode::DFGJIT); + else { + ASSERT(JITCode::isBaselineCode(replacement()->getJITType())); + ASSERT(replacement() == this); + } +#endif + return result; + } +#else + JITCode::JITType getJITType() { return JITCode::BaselineJIT; } #endif ScriptExecutable* ownerExecutable() const { return m_ownerExecutable.get(); } void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; } + JSGlobalData* globalData() { return m_globalData; } void setThisRegister(int thisRegister) { m_thisRegister = thisRegister; } int thisRegister() const { return m_thisRegister; } @@ -354,43 +468,168 @@ namespace JSC { void clearEvalCache(); -#if ENABLE(INTERPRETER) void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { - if (!m_globalData->canUseJIT()) - m_propertyAccessInstructions.append(propertyAccessInstruction); + m_propertyAccessInstructions.append(propertyAccessInstruction); } void addGlobalResolveInstruction(unsigned globalResolveInstruction) { - if (!m_globalData->canUseJIT()) - m_globalResolveInstructions.append(globalResolveInstruction); + m_globalResolveInstructions.append(globalResolveInstruction); } bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset); +#if ENABLE(LLINT) + LLIntCallLinkInfo* addLLIntCallLinkInfo() + { + m_llintCallLinkInfos.append(LLIntCallLinkInfo()); + return &m_llintCallLinkInfos.last(); + } #endif #if ENABLE(JIT) + void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); } size_t numberOfStructureStubInfos() const { return m_structureStubInfos.size(); } - void addStructureStubInfo(const StructureStubInfo& stubInfo) - { - if (m_globalData->canUseJIT()) - m_structureStubInfos.append(stubInfo); - } StructureStubInfo& structureStubInfo(int index) { return m_structureStubInfos[index]; } void addGlobalResolveInfo(unsigned globalResolveInstruction) { - if (m_globalData->canUseJIT()) - m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction)); + m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction)); } GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; } bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset); + void setNumberOfCallLinkInfos(size_t size) { m_callLinkInfos.grow(size); } size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); } - void addCallLinkInfo() { m_callLinkInfos.append(CallLinkInfo()); } CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; } void addMethodCallLinkInfos(unsigned n) { ASSERT(m_globalData->canUseJIT()); m_methodCallLinkInfos.grow(n); } MethodCallLinkInfo& methodCallLinkInfo(int index) { return m_methodCallLinkInfos[index]; } + size_t numberOfMethodCallLinkInfos() { return m_methodCallLinkInfos.size(); } +#endif + +#if ENABLE(VALUE_PROFILER) + unsigned numberOfArgumentValueProfiles() + { + ASSERT(m_numParameters >= 0); + ASSERT(m_argumentValueProfiles.size() == static_cast(m_numParameters)); + return m_argumentValueProfiles.size(); + } + ValueProfile* valueProfileForArgument(unsigned argumentIndex) + { + ValueProfile* result = &m_argumentValueProfiles[argumentIndex]; + ASSERT(result->m_bytecodeOffset == -1); + return result; + } + + ValueProfile* addValueProfile(int bytecodeOffset) + { + ASSERT(bytecodeOffset != -1); + ASSERT(m_valueProfiles.isEmpty() || m_valueProfiles.last().m_bytecodeOffset < bytecodeOffset); + m_valueProfiles.append(ValueProfile(bytecodeOffset)); + return &m_valueProfiles.last(); + } + unsigned numberOfValueProfiles() { return m_valueProfiles.size(); } + ValueProfile* valueProfile(int index) + { + ValueProfile* result = &m_valueProfiles[index]; + ASSERT(result->m_bytecodeOffset != -1); + return result; + } + ValueProfile* valueProfileForBytecodeOffset(int bytecodeOffset) + { + ValueProfile* result = WTF::genericBinarySearch(m_valueProfiles, m_valueProfiles.size(), bytecodeOffset); + ASSERT(result->m_bytecodeOffset != -1); + ASSERT(instructions()[bytecodeOffset + opcodeLength( + m_globalData->interpreter->getOpcodeID( + instructions()[ + bytecodeOffset].u.opcode)) - 1].u.profile == result); + return result; + } + PredictedType valueProfilePredictionForBytecodeOffset(int bytecodeOffset) + { + return valueProfileForBytecodeOffset(bytecodeOffset)->computeUpdatedPrediction(); + } + + unsigned totalNumberOfValueProfiles() + { + return numberOfArgumentValueProfiles() + numberOfValueProfiles(); + } + ValueProfile* getFromAllValueProfiles(unsigned index) + { + if (index < numberOfArgumentValueProfiles()) + return valueProfileForArgument(index); + return valueProfile(index - numberOfArgumentValueProfiles()); + } + + RareCaseProfile* addRareCaseProfile(int bytecodeOffset) + { + m_rareCaseProfiles.append(RareCaseProfile(bytecodeOffset)); + return &m_rareCaseProfiles.last(); + } + unsigned numberOfRareCaseProfiles() { return m_rareCaseProfiles.size(); } + RareCaseProfile* rareCaseProfile(int index) { return &m_rareCaseProfiles[index]; } + RareCaseProfile* rareCaseProfileForBytecodeOffset(int bytecodeOffset) + { + return WTF::genericBinarySearch(m_rareCaseProfiles, m_rareCaseProfiles.size(), bytecodeOffset); + } + + bool likelyToTakeSlowCase(int bytecodeOffset) + { + if (!numberOfRareCaseProfiles()) + return false; + unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter; + return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold; + } + + bool couldTakeSlowCase(int bytecodeOffset) + { + if (!numberOfRareCaseProfiles()) + return false; + unsigned value = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter; + return value >= Options::couldTakeSlowCaseMinimumCount && static_cast(value) / m_executionEntryCount >= Options::couldTakeSlowCaseThreshold; + } + + RareCaseProfile* addSpecialFastCaseProfile(int bytecodeOffset) + { + m_specialFastCaseProfiles.append(RareCaseProfile(bytecodeOffset)); + return &m_specialFastCaseProfiles.last(); + } + unsigned numberOfSpecialFastCaseProfiles() { return m_specialFastCaseProfiles.size(); } + RareCaseProfile* specialFastCaseProfile(int index) { return &m_specialFastCaseProfiles[index]; } + RareCaseProfile* specialFastCaseProfileForBytecodeOffset(int bytecodeOffset) + { + return WTF::genericBinarySearch(m_specialFastCaseProfiles, m_specialFastCaseProfiles.size(), bytecodeOffset); + } + + bool likelyToTakeSpecialFastCase(int bytecodeOffset) + { + if (!numberOfRareCaseProfiles()) + return false; + unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter; + return specialFastCaseCount >= Options::likelyToTakeSlowCaseMinimumCount && static_cast(specialFastCaseCount) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold; + } + + bool likelyToTakeDeepestSlowCase(int bytecodeOffset) + { + if (!numberOfRareCaseProfiles()) + return false; + unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter; + unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter; + unsigned value = slowCaseCount - specialFastCaseCount; + return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold; + } + + bool likelyToTakeAnySlowCase(int bytecodeOffset) + { + if (!numberOfRareCaseProfiles()) + return false; + unsigned slowCaseCount = rareCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter; + unsigned specialFastCaseCount = specialFastCaseProfileForBytecodeOffset(bytecodeOffset)->m_counter; + unsigned value = slowCaseCount + specialFastCaseCount; + return value >= Options::likelyToTakeSlowCaseMinimumCount && static_cast(value) / m_executionEntryCount >= Options::likelyToTakeSlowCaseThreshold; + } + + unsigned executionEntryCount() const { return m_executionEntryCount; } #endif + unsigned globalResolveInfoCount() const { #if ENABLE(JIT) @@ -440,6 +679,57 @@ namespace JSC { } #endif +#if ENABLE(DFG_JIT) + SegmentedVector& inlineCallFrames() + { + createRareDataIfNecessary(); + return m_rareData->m_inlineCallFrames; + } + + Vector& codeOrigins() + { + createRareDataIfNecessary(); + return m_rareData->m_codeOrigins; + } + + // Having code origins implies that there has been some inlining. + bool hasCodeOrigins() + { + return m_rareData && !!m_rareData->m_codeOrigins.size(); + } + + bool codeOriginForReturn(ReturnAddressPtr returnAddress, CodeOrigin& codeOrigin) + { + if (!hasCodeOrigins()) + return false; + unsigned offset = getJITCode().offsetOf(returnAddress.value()); + CodeOriginAtCallReturnOffset* entry = binarySearch(codeOrigins().begin(), codeOrigins().size(), offset, WTF::KeyMustNotBePresentInArray); + if (entry->callReturnOffset != offset) + return false; + codeOrigin = entry->codeOrigin; + return true; + } + + CodeOrigin codeOrigin(unsigned index) + { + ASSERT(m_rareData); + return m_rareData->m_codeOrigins[index].codeOrigin; + } + + bool addFrequentExitSite(const DFG::FrequentExitSite& site) + { + ASSERT(JITCode::isBaselineCode(getJITType())); + return m_exitProfile.add(site); + } + + DFG::ExitProfile& exitProfile() { return m_exitProfile; } + + CompressedLazyOperandValueProfileHolder& lazyOperandValueProfiles() + { + return m_lazyOperandValueProfiles; + } +#endif + // Constant Pool size_t numberOfIdentifiers() const { return m_identifiers.size(); } @@ -447,11 +737,14 @@ namespace JSC { Identifier& identifier(int index) { return m_identifiers[index]; } size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); } - void addConstant(JSValue v) + unsigned addConstant(JSValue v) { + unsigned result = m_constantRegisters.size(); m_constantRegisters.append(WriteBarrier()); m_constantRegisters.last().set(m_globalObject->globalData(), m_ownerExecutable.get(), v); + return result; } + unsigned addOrFindConstant(JSValue); WriteBarrier& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; } ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; } ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); } @@ -481,6 +774,12 @@ namespace JSC { m_rareData->m_regexps.append(WriteBarrier(*m_globalData, ownerExecutable(), r)); return size; } + unsigned numberOfRegExps() const + { + if (!m_rareData) + return 0; + return m_rareData->m_regexps.size(); + } RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); } unsigned addConstantBuffer(unsigned length) @@ -498,6 +797,14 @@ namespace JSC { } JSGlobalObject* globalObject() { return m_globalObject.get(); } + + JSGlobalObject* globalObjectFor(CodeOrigin codeOrigin) + { + if (!codeOrigin.inlineCallFrame) + return globalObject(); + // FIXME: if we ever inline based on executable not function, this code will need to change. + return codeOrigin.inlineCallFrame->callee->scope()->globalObject.get(); + } // Jump Tables @@ -520,17 +827,263 @@ namespace JSC { EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; } void shrinkToFit(); + + void copyPostParseDataFrom(CodeBlock* alternative); + void copyPostParseDataFromAlternative(); + + // Functions for controlling when JITting kicks in, in a mixed mode + // execution world. + + bool checkIfJITThresholdReached() + { + return m_llintExecuteCounter.checkIfThresholdCrossedAndSet(this); + } + + void dontJITAnytimeSoon() + { + m_llintExecuteCounter.deferIndefinitely(); + } + + void jitAfterWarmUp() + { + m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITAfterWarmUp, this); + } + + void jitSoon() + { + m_llintExecuteCounter.setNewThreshold(Options::thresholdForJITSoon, this); + } + + int32_t llintExecuteCounter() const + { + return m_llintExecuteCounter.m_counter; + } + + // Functions for controlling when tiered compilation kicks in. This + // controls both when the optimizing compiler is invoked and when OSR + // entry happens. Two triggers exist: the loop trigger and the return + // trigger. In either case, when an addition to m_jitExecuteCounter + // causes it to become non-negative, the optimizing compiler is + // invoked. This includes a fast check to see if this CodeBlock has + // already been optimized (i.e. replacement() returns a CodeBlock + // that was optimized with a higher tier JIT than this one). In the + // case of the loop trigger, if the optimized compilation succeeds + // (or has already succeeded in the past) then OSR is attempted to + // redirect program flow into the optimized code. + + // These functions are called from within the optimization triggers, + // and are used as a single point at which we define the heuristics + // for how much warm-up is mandated before the next optimization + // trigger files. All CodeBlocks start out with optimizeAfterWarmUp(), + // as this is called from the CodeBlock constructor. + + // When we observe a lot of speculation failures, we trigger a + // reoptimization. But each time, we increase the optimization trigger + // to avoid thrashing. + unsigned reoptimizationRetryCounter() const + { + ASSERT(m_reoptimizationRetryCounter <= Options::reoptimizationRetryCounterMax); + return m_reoptimizationRetryCounter; + } + + void countReoptimization() + { + m_reoptimizationRetryCounter++; + if (m_reoptimizationRetryCounter > Options::reoptimizationRetryCounterMax) + m_reoptimizationRetryCounter = Options::reoptimizationRetryCounterMax; + } + + int32_t counterValueForOptimizeAfterWarmUp() + { + return Options::thresholdForOptimizeAfterWarmUp << reoptimizationRetryCounter(); + } + + int32_t counterValueForOptimizeAfterLongWarmUp() + { + return Options::thresholdForOptimizeAfterLongWarmUp << reoptimizationRetryCounter(); + } + + int32_t* addressOfJITExecuteCounter() + { + return &m_jitExecuteCounter.m_counter; + } + + static ptrdiff_t offsetOfJITExecuteCounter() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_counter); } + static ptrdiff_t offsetOfJITExecutionActiveThreshold() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_activeThreshold); } + static ptrdiff_t offsetOfJITExecutionTotalCount() { return OBJECT_OFFSETOF(CodeBlock, m_jitExecuteCounter) + OBJECT_OFFSETOF(ExecutionCounter, m_totalCount); } + int32_t jitExecuteCounter() const { return m_jitExecuteCounter.m_counter; } + + unsigned optimizationDelayCounter() const { return m_optimizationDelayCounter; } + + // Check if the optimization threshold has been reached, and if not, + // adjust the heuristics accordingly. Returns true if the threshold has + // been reached. + bool checkIfOptimizationThresholdReached() + { + return m_jitExecuteCounter.checkIfThresholdCrossedAndSet(this); + } + + // Call this to force the next optimization trigger to fire. This is + // rarely wise, since optimization triggers are typically more + // expensive than executing baseline code. + void optimizeNextInvocation() + { + m_jitExecuteCounter.setNewThreshold(0, this); + } + + // Call this to prevent optimization from happening again. Note that + // optimization will still happen after roughly 2^29 invocations, + // so this is really meant to delay that as much as possible. This + // is called if optimization failed, and we expect it to fail in + // the future as well. + void dontOptimizeAnytimeSoon() + { + m_jitExecuteCounter.deferIndefinitely(); + } + + // Call this to reinitialize the counter to its starting state, + // forcing a warm-up to happen before the next optimization trigger + // fires. This is called in the CodeBlock constructor. It also + // makes sense to call this if an OSR exit occurred. Note that + // OSR exit code is code generated, so the value of the execute + // counter that this corresponds to is also available directly. + void optimizeAfterWarmUp() + { + m_jitExecuteCounter.setNewThreshold(counterValueForOptimizeAfterWarmUp(), this); + } + + // Call this to force an optimization trigger to fire only after + // a lot of warm-up. + void optimizeAfterLongWarmUp() + { + m_jitExecuteCounter.setNewThreshold(counterValueForOptimizeAfterLongWarmUp(), this); + } + + // Call this to cause an optimization trigger to fire soon, but + // not necessarily the next one. This makes sense if optimization + // succeeds. Successfuly optimization means that all calls are + // relinked to the optimized code, so this only affects call + // frames that are still executing this CodeBlock. The value here + // is tuned to strike a balance between the cost of OSR entry + // (which is too high to warrant making every loop back edge to + // trigger OSR immediately) and the cost of executing baseline + // code (which is high enough that we don't necessarily want to + // have a full warm-up). The intuition for calling this instead of + // optimizeNextInvocation() is for the case of recursive functions + // with loops. Consider that there may be N call frames of some + // recursive function, for a reasonably large value of N. The top + // one triggers optimization, and then returns, and then all of + // the others return. We don't want optimization to be triggered on + // each return, as that would be superfluous. It only makes sense + // to trigger optimization if one of those functions becomes hot + // in the baseline code. + void optimizeSoon() + { + m_jitExecuteCounter.setNewThreshold(Options::thresholdForOptimizeSoon << reoptimizationRetryCounter(), this); + } + + // The speculative JIT tracks its success rate, so that we can + // decide when to reoptimize. It's interesting to note that these + // counters may overflow without any protection. The success + // counter will overflow before the fail one does, becuase the + // fail one is used as a trigger to reoptimize. So the worst case + // is that the success counter overflows and we reoptimize without + // needing to. But this is harmless. If a method really did + // execute 2^32 times then compiling it again probably won't hurt + // anyone. + + void countSpeculationSuccess() + { + m_speculativeSuccessCounter++; + } + + void countSpeculationFailure() + { + m_speculativeFailCounter++; + } + + uint32_t speculativeSuccessCounter() const { return m_speculativeSuccessCounter; } + uint32_t speculativeFailCounter() const { return m_speculativeFailCounter; } + uint32_t forcedOSRExitCounter() const { return m_forcedOSRExitCounter; } + + uint32_t* addressOfSpeculativeSuccessCounter() { return &m_speculativeSuccessCounter; } + uint32_t* addressOfSpeculativeFailCounter() { return &m_speculativeFailCounter; } + uint32_t* addressOfForcedOSRExitCounter() { return &m_forcedOSRExitCounter; } + + static ptrdiff_t offsetOfSpeculativeSuccessCounter() { return OBJECT_OFFSETOF(CodeBlock, m_speculativeSuccessCounter); } + static ptrdiff_t offsetOfSpeculativeFailCounter() { return OBJECT_OFFSETOF(CodeBlock, m_speculativeFailCounter); } + static ptrdiff_t offsetOfForcedOSRExitCounter() { return OBJECT_OFFSETOF(CodeBlock, m_forcedOSRExitCounter); } + +#if ENABLE(JIT) + // The number of failures that triggers the use of the ratio. + unsigned largeFailCountThreshold() { return Options::largeFailCountThresholdBase << baselineVersion()->reoptimizationRetryCounter(); } + unsigned largeFailCountThresholdForLoop() { return Options::largeFailCountThresholdBaseForLoop << baselineVersion()->reoptimizationRetryCounter(); } + + bool shouldReoptimizeNow() + { + return (Options::desiredSpeculativeSuccessFailRatio * + speculativeFailCounter() >= speculativeSuccessCounter() + && speculativeFailCounter() >= largeFailCountThreshold()) + || forcedOSRExitCounter() >= + Options::forcedOSRExitCountForReoptimization; + } + + bool shouldReoptimizeFromLoopNow() + { + return (Options::desiredSpeculativeSuccessFailRatio * + speculativeFailCounter() >= speculativeSuccessCounter() + && speculativeFailCounter() >= largeFailCountThresholdForLoop()) + || forcedOSRExitCounter() >= + Options::forcedOSRExitCountForReoptimization; + } +#endif + +#if ENABLE(VALUE_PROFILER) + bool shouldOptimizeNow(); +#else + bool shouldOptimizeNow() { return false; } +#endif + +#if ENABLE(JIT) + void reoptimize() + { + ASSERT(replacement() != this); + ASSERT(replacement()->alternative() == this); + replacement()->tallyFrequentExitSites(); + replacement()->jettison(); + countReoptimization(); + optimizeAfterWarmUp(); + } +#endif + +#if ENABLE(VERBOSE_VALUE_PROFILE) + void dumpValueProfiles(); +#endif + // FIXME: Make these remaining members private. int m_numCalleeRegisters; int m_numVars; int m_numCapturedVars; - int m_numParameters; bool m_isConstructor; + protected: +#if ENABLE(JIT) + virtual bool jitCompileImpl(JSGlobalData&) = 0; +#endif + virtual void visitWeakReferences(SlotVisitor&); + virtual void finalizeUnconditionally(); + private: -#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING) + friend class DFGCodeBlocks; + +#if ENABLE(DFG_JIT) + void tallyFrequentExitSites(); +#else + void tallyFrequentExitSites() { } +#endif + void dump(ExecState*, const Vector::const_iterator& begin, Vector::const_iterator&) const; CString registerName(ExecState*, int r) const; @@ -538,23 +1091,49 @@ namespace JSC { void printBinaryOp(ExecState*, int location, Vector::const_iterator&, const char* op) const; void printConditionalJump(ExecState*, const Vector::const_iterator&, Vector::const_iterator&, int location, const char* op) const; void printGetByIdOp(ExecState*, int location, Vector::const_iterator&, const char* op) const; + void printCallOp(ExecState*, int location, Vector::const_iterator&, const char* op) const; void printPutByIdOp(ExecState*, int location, Vector::const_iterator&, const char* op) const; -#endif void visitStructures(SlotVisitor&, Instruction* vPC) const; + +#if ENABLE(DFG_JIT) + bool shouldImmediatelyAssumeLivenessDuringScan() + { + // Null m_dfgData means that this is a baseline JIT CodeBlock. Baseline JIT + // CodeBlocks don't need to be jettisoned when their weak references go + // stale. So if a basline JIT CodeBlock gets scanned, we can assume that + // this means that it's live. + if (!m_dfgData) + return true; + + // For simplicity, we don't attempt to jettison code blocks during GC if + // they are executing. Instead we strongly mark their weak references to + // allow them to continue to execute soundly. + if (m_dfgData->mayBeExecuting) + return true; + + return false; + } +#else + bool shouldImmediatelyAssumeLivenessDuringScan() { return true; } +#endif + + void performTracingFixpointIteration(SlotVisitor&); + + void stronglyVisitStrongReferences(SlotVisitor&); + void stronglyVisitWeakReferences(SlotVisitor&); void createRareDataIfNecessary() { if (!m_rareData) m_rareData = adoptPtr(new RareData); } + + int m_numParameters; WriteBarrier m_ownerExecutable; JSGlobalData* m_globalData; - Vector m_instructions; -#ifndef NDEBUG - unsigned m_instructionCount; -#endif + RefCountedArray m_instructions; int m_thisRegister; int m_argumentsRegister; @@ -570,18 +1149,77 @@ namespace JSC { RefPtr m_source; unsigned m_sourceOffset; -#if ENABLE(INTERPRETER) Vector m_propertyAccessInstructions; Vector m_globalResolveInstructions; +#if ENABLE(LLINT) + SegmentedVector m_llintCallLinkInfos; + SentinelLinkedList > m_incomingLLIntCalls; #endif #if ENABLE(JIT) Vector m_structureStubInfos; Vector m_globalResolveInfos; Vector m_callLinkInfos; Vector m_methodCallLinkInfos; + JITCode m_jitCode; + MacroAssemblerCodePtr m_jitCodeWithArityCheck; + SentinelLinkedList > m_incomingCalls; +#endif +#if ENABLE(DFG_JIT) || ENABLE(LLINT) + OwnPtr m_jitCodeMap; +#endif +#if ENABLE(DFG_JIT) + struct WeakReferenceTransition { + WeakReferenceTransition() { } + + WeakReferenceTransition(JSGlobalData& globalData, JSCell* owner, JSCell* codeOrigin, JSCell* from, JSCell* to) + : m_from(globalData, owner, from) + , m_to(globalData, owner, to) + { + if (!!codeOrigin) + m_codeOrigin.set(globalData, owner, codeOrigin); + } + + WriteBarrier m_codeOrigin; + WriteBarrier m_from; + WriteBarrier m_to; + }; + + struct DFGData { + DFGData() + : mayBeExecuting(false) + , isJettisoned(false) + { + } + + Vector osrEntry; + SegmentedVector osrExit; + Vector speculationRecovery; + Vector transitions; + Vector > weakReferences; + bool mayBeExecuting; + bool isJettisoned; + bool livenessHasBeenProved; // Initialized and used on every GC. + bool allTransitionsHaveBeenMarked; // Initialized and used on every GC. + unsigned visitAggregateHasBeenCalled; // Unsigned to make it work seamlessly with the broadest set of CAS implementations. + }; + + OwnPtr m_dfgData; + + // This is relevant to non-DFG code blocks that serve as the profiled code block + // for DFG code blocks. + DFG::ExitProfile m_exitProfile; + CompressedLazyOperandValueProfileHolder m_lazyOperandValueProfiles; +#endif +#if ENABLE(VALUE_PROFILER) + Vector m_argumentValueProfiles; + SegmentedVector m_valueProfiles; + SegmentedVector m_rareCaseProfiles; + SegmentedVector m_specialFastCaseProfiles; + unsigned m_executionEntryCount; #endif Vector m_jumpTargets; + Vector m_loopTargets; // Constant Pool Vector m_identifiers; @@ -592,6 +1230,18 @@ namespace JSC { SymbolTable* m_symbolTable; + OwnPtr m_alternative; + + ExecutionCounter m_llintExecuteCounter; + + ExecutionCounter m_jitExecuteCounter; + int32_t m_totalJITExecutions; + uint32_t m_speculativeSuccessCounter; + uint32_t m_speculativeFailCounter; + uint32_t m_forcedOSRExitCounter; + uint16_t m_optimizationDelayCounter; + uint16_t m_reoptimizationRetryCounter; + struct RareData { WTF_MAKE_FAST_ALLOCATED; public: @@ -616,21 +1266,34 @@ namespace JSC { Vector m_lineInfo; #if ENABLE(JIT) Vector m_callReturnIndexVector; +#endif +#if ENABLE(DFG_JIT) + SegmentedVector m_inlineCallFrames; + Vector m_codeOrigins; #endif }; #if COMPILER(MSVC) friend void WTF::deleteOwnedPtr(RareData*); #endif OwnPtr m_rareData; +#if ENABLE(JIT) + CompileWithDFGState m_canCompileWithDFGState; +#endif }; // Program code is not marked by any function, so we make the global object // responsible for marking it. class GlobalCodeBlock : public CodeBlock { - public: - GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr sourceProvider, unsigned sourceOffset) - : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, &m_unsharedSymbolTable, false) + protected: + GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other) + : CodeBlock(CopyParsedBlock, other, &m_unsharedSymbolTable) + , m_unsharedSymbolTable(other.m_unsharedSymbolTable) + { + } + + GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr sourceProvider, unsigned sourceOffset, PassOwnPtr alternative) + : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, &m_unsharedSymbolTable, false, alternative) { } @@ -640,16 +1303,37 @@ namespace JSC { class ProgramCodeBlock : public GlobalCodeBlock { public: - ProgramCodeBlock(ProgramExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr sourceProvider) - : GlobalCodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, 0) + ProgramCodeBlock(CopyParsedBlockTag, ProgramCodeBlock& other) + : GlobalCodeBlock(CopyParsedBlock, other) { } + + ProgramCodeBlock(ProgramExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr sourceProvider, PassOwnPtr alternative) + : GlobalCodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, 0, alternative) + { + } + +#if ENABLE(JIT) + protected: + virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*); + virtual void jettison(); + virtual bool jitCompileImpl(JSGlobalData&); + virtual CodeBlock* replacement(); + virtual bool canCompileWithDFGInternal(); +#endif }; class EvalCodeBlock : public GlobalCodeBlock { public: - EvalCodeBlock(EvalExecutable* ownerExecutable, JSGlobalObject* globalObject, PassRefPtr sourceProvider, int baseScopeDepth) - : GlobalCodeBlock(ownerExecutable, EvalCode, globalObject, sourceProvider, 0) + EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other) + : GlobalCodeBlock(CopyParsedBlock, other) + , m_baseScopeDepth(other.m_baseScopeDepth) + , m_variables(other.m_variables) + { + } + + EvalCodeBlock(EvalExecutable* ownerExecutable, JSGlobalObject* globalObject, PassRefPtr sourceProvider, int baseScopeDepth, PassOwnPtr alternative) + : GlobalCodeBlock(ownerExecutable, EvalCode, globalObject, sourceProvider, 0, alternative) , m_baseScopeDepth(baseScopeDepth) { } @@ -663,6 +1347,15 @@ namespace JSC { ASSERT(m_variables.isEmpty()); m_variables.swap(variables); } + +#if ENABLE(JIT) + protected: + virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*); + virtual void jettison(); + virtual bool jitCompileImpl(JSGlobalData&); + virtual CodeBlock* replacement(); + virtual bool canCompileWithDFGInternal(); +#endif private: int m_baseScopeDepth; @@ -671,20 +1364,54 @@ namespace JSC { class FunctionCodeBlock : public CodeBlock { public: + FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other) + : CodeBlock(CopyParsedBlock, other, other.sharedSymbolTable()) + { + // The fact that we have to do this is yucky, but is necessary because of the + // class hierarchy issues described in the comment block for the main + // constructor, below. + sharedSymbolTable()->ref(); + } + // Rather than using the usual RefCounted::create idiom for SharedSymbolTable we just use new // as we need to initialise the CodeBlock before we could initialise any RefPtr to hold the shared // symbol table, so we just pass as a raw pointer with a ref count of 1. We then manually deref // in the destructor. - FunctionCodeBlock(FunctionExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr sourceProvider, unsigned sourceOffset, bool isConstructor) - : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, SharedSymbolTable::create().leakRef(), isConstructor) + FunctionCodeBlock(FunctionExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr sourceProvider, unsigned sourceOffset, bool isConstructor, PassOwnPtr alternative = nullptr) + : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, SharedSymbolTable::create().leakRef(), isConstructor, alternative) { } ~FunctionCodeBlock() { sharedSymbolTable()->deref(); } + +#if ENABLE(JIT) + protected: + virtual JSObject* compileOptimized(ExecState*, ScopeChainNode*); + virtual void jettison(); + virtual bool jitCompileImpl(JSGlobalData&); + virtual CodeBlock* replacement(); + virtual bool canCompileWithDFGInternal(); +#endif }; + inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCallFrame) + { + ASSERT(inlineCallFrame); + ExecutableBase* executable = inlineCallFrame->executable.get(); + ASSERT(executable->structure()->classInfo() == &FunctionExecutable::s_info); + return static_cast(executable)->baselineCodeBlockFor(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct); + } + + inline CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigin& codeOrigin, CodeBlock* baselineCodeBlock) + { + if (codeOrigin.inlineCallFrame) + return baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame); + return baselineCodeBlock; + } + + inline Register& ExecState::r(int index) { CodeBlock* codeBlock = this->codeBlock(); @@ -698,6 +1425,35 @@ namespace JSC { ASSERT(index < FirstConstantRegisterIndex); return this[index]; } + +#if ENABLE(DFG_JIT) + inline bool ExecState::isInlineCallFrame() + { + if (LIKELY(!codeBlock() || codeBlock()->getJITType() != JITCode::DFGJIT)) + return false; + return isInlineCallFrameSlow(); + } +#endif + +#if ENABLE(DFG_JIT) + inline void DFGCodeBlocks::mark(void* candidateCodeBlock) + { + // We have to check for 0 and -1 because those are used by the HashMap as markers. + uintptr_t value = reinterpret_cast(candidateCodeBlock); + + // This checks for both of those nasty cases in one go. + // 0 + 1 = 1 + // -1 + 1 = 0 + if (value + 1 <= 1) + return; + + HashSet::iterator iter = m_set.find(static_cast(candidateCodeBlock)); + if (iter == m_set.end()) + return; + + (*iter)->m_dfgData->mayBeExecuting = true; + } +#endif } // namespace JSC diff --git a/bytecode/CodeOrigin.h b/bytecode/CodeOrigin.h new file mode 100644 index 0000000..eda1764 --- /dev/null +++ b/bytecode/CodeOrigin.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2011 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 CodeOrigin_h +#define CodeOrigin_h + +#include "ValueRecovery.h" +#include "WriteBarrier.h" +#include +#include + +namespace JSC { + +struct InlineCallFrame; +class ExecutableBase; +class JSFunction; + +struct CodeOrigin { + // Bytecode offset that you'd use to re-execute this instruction. + unsigned bytecodeIndex : 29; + // Bytecode offset corresponding to the opcode that gives the result (needed to handle + // op_call/op_call_put_result and op_method_check/op_get_by_id). + unsigned valueProfileOffset : 3; + + InlineCallFrame* inlineCallFrame; + + CodeOrigin() + : bytecodeIndex(std::numeric_limits::max()) + , valueProfileOffset(0) + , inlineCallFrame(0) + { + } + + explicit CodeOrigin(unsigned bytecodeIndex, InlineCallFrame* inlineCallFrame = 0, unsigned valueProfileOffset = 0) + : bytecodeIndex(bytecodeIndex) + , valueProfileOffset(valueProfileOffset) + , inlineCallFrame(inlineCallFrame) + { + ASSERT(bytecodeIndex < (1u << 29)); + ASSERT(valueProfileOffset < (1u << 3)); + } + + bool isSet() const { return bytecodeIndex != std::numeric_limits::max(); } + + unsigned bytecodeIndexForValueProfile() const + { + return bytecodeIndex + valueProfileOffset; + } + + // The inline depth is the depth of the inline stack, so 1 = not inlined, + // 2 = inlined one deep, etc. + unsigned inlineDepth() const; + + // If the code origin corresponds to inlined code, gives you the heap object that + // would have owned the code if it had not been inlined. Otherwise returns 0. + ExecutableBase* codeOriginOwner() const; + + static unsigned inlineDepthForCallFrame(InlineCallFrame*); + + bool operator==(const CodeOrigin& other) const; + + bool operator!=(const CodeOrigin& other) const { return !(*this == other); } + + // Get the inline stack. This is slow, and is intended for debugging only. + Vector inlineStack() const; +}; + +struct InlineCallFrame { + Vector arguments; + WriteBarrier executable; + WriteBarrier callee; + CodeOrigin caller; + unsigned stackOffset : 31; + bool isCall : 1; +}; + +struct CodeOriginAtCallReturnOffset { + CodeOrigin codeOrigin; + unsigned callReturnOffset; +}; + +inline unsigned CodeOrigin::inlineDepthForCallFrame(InlineCallFrame* inlineCallFrame) +{ + unsigned result = 1; + for (InlineCallFrame* current = inlineCallFrame; current; current = current->caller.inlineCallFrame) + result++; + return result; +} + +inline unsigned CodeOrigin::inlineDepth() const +{ + return inlineDepthForCallFrame(inlineCallFrame); +} + +inline bool CodeOrigin::operator==(const CodeOrigin& other) const +{ + return bytecodeIndex == other.bytecodeIndex + && inlineCallFrame == other.inlineCallFrame; +} + +// Get the inline stack. This is slow, and is intended for debugging only. +inline Vector CodeOrigin::inlineStack() const +{ + Vector result(inlineDepth()); + result.last() = *this; + unsigned index = result.size() - 2; + for (InlineCallFrame* current = inlineCallFrame; current; current = current->caller.inlineCallFrame) + result[index--] = current->caller; + return result; +} + +inline unsigned getCallReturnOffsetForCodeOrigin(CodeOriginAtCallReturnOffset* data) +{ + return data->callReturnOffset; +} + +inline ExecutableBase* CodeOrigin::codeOriginOwner() const +{ + if (!inlineCallFrame) + return 0; + return inlineCallFrame->executable.get(); +} + +} // namespace JSC + +#endif // CodeOrigin_h + diff --git a/bytecode/CodeType.h b/bytecode/CodeType.h new file mode 100644 index 0000000..d33677a --- /dev/null +++ b/bytecode/CodeType.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2012 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 CodeType_h +#define CodeType_h + +#include + +namespace JSC { + +enum CodeType { GlobalCode, EvalCode, FunctionCode }; + +inline const char* codeTypeToString(CodeType codeType) +{ + switch (codeType) { + case GlobalCode: + return "GlobalCode"; + case EvalCode: + return "EvalCode"; + case FunctionCode: + return "FunctionCode"; + default: + ASSERT_NOT_REACHED(); + return 0; + } +} + +} // namespace JSC + +#endif // CodeType_h + diff --git a/bytecode/DFGExitProfile.cpp b/bytecode/DFGExitProfile.cpp new file mode 100644 index 0000000..69fdc37 --- /dev/null +++ b/bytecode/DFGExitProfile.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2011 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 "DFGExitProfile.h" + +#include + +namespace JSC { namespace DFG { + +ExitProfile::ExitProfile() { } +ExitProfile::~ExitProfile() { } + +bool ExitProfile::add(const FrequentExitSite& site) +{ + // If we've never seen any frequent exits then create the list and put this site + // into it. + if (!m_frequentExitSites) { + m_frequentExitSites = adoptPtr(new Vector()); + m_frequentExitSites->append(site); + return true; + } + + // Don't add it if it's already there. This is O(n), but that's OK, because we + // know that the total number of places where code exits tends to not be large, + // and this code is only used when recompilation is triggered. + for (unsigned i = 0; i < m_frequentExitSites->size(); ++i) { + if (m_frequentExitSites->at(i) == site) + return false; + } + + m_frequentExitSites->append(site); + return true; +} + +QueryableExitProfile::QueryableExitProfile(const ExitProfile& profile) +{ + if (!profile.m_frequentExitSites) + return; + + for (unsigned i = 0; i < profile.m_frequentExitSites->size(); ++i) + m_frequentExitSites.add(profile.m_frequentExitSites->at(i)); +} + +QueryableExitProfile::~QueryableExitProfile() { } + +} } // namespace JSC::DFG diff --git a/bytecode/DFGExitProfile.h b/bytecode/DFGExitProfile.h new file mode 100644 index 0000000..31db084 --- /dev/null +++ b/bytecode/DFGExitProfile.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2011 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 DFGExitProfile_h +#define DFGExitProfile_h + +#include +#include +#include + +namespace JSC { namespace DFG { + +enum ExitKind { + ExitKindUnset, + BadType, // We exited because a type prediction was wrong. + BadCache, // We exited because an inline cache was wrong. + Overflow, // We exited because of overflow. + NegativeZero, // We exited because we encountered negative zero. + InadequateCoverage, // We exited because we ended up in code that didn't have profiling coverage. + Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME. +}; + +inline const char* exitKindToString(ExitKind kind) +{ + switch (kind) { + case ExitKindUnset: + return "Unset"; + case BadType: + return "BadType"; + case BadCache: + return "BadCache"; + case Overflow: + return "Overflow"; + case NegativeZero: + return "NegativeZero"; + case InadequateCoverage: + return "InadequateCoverage"; + default: + return "Unknown"; + } +} + +inline bool exitKindIsCountable(ExitKind kind) +{ + switch (kind) { + case ExitKindUnset: + ASSERT_NOT_REACHED(); + case BadType: + case Uncountable: + return false; + default: + return true; + } +} + +class FrequentExitSite { +public: + FrequentExitSite() + : m_bytecodeOffset(0) // 0 = empty value + , m_kind(ExitKindUnset) + { + } + + FrequentExitSite(WTF::HashTableDeletedValueType) + : m_bytecodeOffset(1) // 1 = deleted value + , m_kind(ExitKindUnset) + { + } + + explicit FrequentExitSite(unsigned bytecodeOffset, ExitKind kind) + : m_bytecodeOffset(bytecodeOffset) + , m_kind(kind) + { + ASSERT(exitKindIsCountable(kind)); + } + + bool operator!() const + { + return m_kind == ExitKindUnset; + } + + bool operator==(const FrequentExitSite& other) const + { + return m_bytecodeOffset == other.m_bytecodeOffset + && m_kind == other.m_kind; + } + + unsigned hash() const + { + return WTF::intHash(m_bytecodeOffset) + m_kind; + } + + unsigned bytecodeOffset() const { return m_bytecodeOffset; } + ExitKind kind() const { return m_kind; } + + bool isHashTableDeletedValue() const + { + return m_kind == ExitKindUnset && m_bytecodeOffset; + } + +private: + unsigned m_bytecodeOffset; + ExitKind m_kind; +}; + +struct FrequentExitSiteHash { + static unsigned hash(const FrequentExitSite& key) { return key.hash(); } + static bool equal(const FrequentExitSite& a, const FrequentExitSite& b) { return a == b; } + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +} } // namespace JSC::DFG + +namespace WTF { + +template struct DefaultHash; +template<> struct DefaultHash { + typedef JSC::DFG::FrequentExitSiteHash Hash; +}; + +template struct HashTraits; +template<> struct HashTraits : SimpleClassHashTraits { }; + +} // namespace WTF + +namespace JSC { namespace DFG { + +class QueryableExitProfile; + +class ExitProfile { +public: + ExitProfile(); + ~ExitProfile(); + + // Add a new frequent exit site. Return true if this is a new one, or false + // if we already knew about it. This is an O(n) operation, because it errs + // on the side of keeping the data structure compact. Also, this will only + // be called a fixed number of times per recompilation. Recompilation is + // rare to begin with, and implies doing O(n) operations on the CodeBlock + // anyway. + bool add(const FrequentExitSite&); + +private: + friend class QueryableExitProfile; + + OwnPtr > m_frequentExitSites; +}; + +class QueryableExitProfile { +public: + explicit QueryableExitProfile(const ExitProfile&); + ~QueryableExitProfile(); + + bool hasExitSite(const FrequentExitSite& site) const + { + return m_frequentExitSites.find(site) != m_frequentExitSites.end(); + } + + bool hasExitSite(unsigned bytecodeIndex, ExitKind kind) const + { + return hasExitSite(FrequentExitSite(bytecodeIndex, kind)); + } +private: + HashSet m_frequentExitSites; +}; + +} } // namespace JSC::DFG + +#endif // DFGExitProfile_h diff --git a/bytecode/DataFormat.h b/bytecode/DataFormat.h new file mode 100644 index 0000000..4f01548 --- /dev/null +++ b/bytecode/DataFormat.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2011 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 DataFormat_h +#define DataFormat_h + +#include + +namespace JSC { + +// === DataFormat === +// +// This enum tracks the current representation in which a value is being held. +// Values may be unboxed primitives (int32, double, or cell), or boxed as a JSValue. +// For boxed values, we may know the type of boxing that has taken place. +// (May also need bool, array, object, string types!) +enum DataFormat { + DataFormatNone = 0, + DataFormatInteger = 1, + DataFormatDouble = 2, + DataFormatBoolean = 3, + DataFormatCell = 4, + DataFormatStorage = 5, + DataFormatJS = 8, + DataFormatJSInteger = DataFormatJS | DataFormatInteger, + DataFormatJSDouble = DataFormatJS | DataFormatDouble, + DataFormatJSCell = DataFormatJS | DataFormatCell, + DataFormatJSBoolean = DataFormatJS | DataFormatBoolean +}; + +inline const char* dataFormatToString(DataFormat dataFormat) +{ + switch (dataFormat) { + case DataFormatNone: + return "None"; + case DataFormatInteger: + return "Integer"; + case DataFormatDouble: + return "Double"; + case DataFormatCell: + return "Cell"; + case DataFormatBoolean: + return "Boolean"; + case DataFormatStorage: + return "Storage"; + case DataFormatJS: + return "JS"; + case DataFormatJSInteger: + return "JSInteger"; + case DataFormatJSDouble: + return "JSDouble"; + case DataFormatJSCell: + return "JSCell"; + case DataFormatJSBoolean: + return "JSBoolean"; + default: + return "Unknown"; + } +} + +#if USE(JSVALUE64) +inline bool needDataFormatConversion(DataFormat from, DataFormat to) +{ + ASSERT(from != DataFormatNone); + ASSERT(to != DataFormatNone); + switch (from) { + case DataFormatInteger: + case DataFormatDouble: + return to != from; + case DataFormatCell: + case DataFormatJS: + case DataFormatJSInteger: + case DataFormatJSDouble: + case DataFormatJSCell: + case DataFormatJSBoolean: + switch (to) { + case DataFormatInteger: + case DataFormatDouble: + return true; + case DataFormatCell: + case DataFormatJS: + case DataFormatJSInteger: + case DataFormatJSDouble: + case DataFormatJSCell: + case DataFormatJSBoolean: + return false; + default: + // This captures DataFormatBoolean, which is currently unused. + ASSERT_NOT_REACHED(); + } + case DataFormatStorage: + ASSERT(to == DataFormatStorage); + return false; + default: + // This captures DataFormatBoolean, which is currently unused. + ASSERT_NOT_REACHED(); + } + return true; +} + +#elif USE(JSVALUE32_64) +inline bool needDataFormatConversion(DataFormat from, DataFormat to) +{ + ASSERT(from != DataFormatNone); + ASSERT(to != DataFormatNone); + switch (from) { + case DataFormatInteger: + case DataFormatCell: + case DataFormatBoolean: + return ((to & DataFormatJS) || to == DataFormatDouble); + case DataFormatDouble: + case DataFormatJSDouble: + return (to != DataFormatDouble && to != DataFormatJSDouble); + case DataFormatJS: + case DataFormatJSInteger: + case DataFormatJSCell: + case DataFormatJSBoolean: + return (!(to & DataFormatJS) || to == DataFormatJSDouble); + case DataFormatStorage: + ASSERT(to == DataFormatStorage); + return false; + default: + ASSERT_NOT_REACHED(); + } + return true; +} +#endif + +inline bool isJSFormat(DataFormat format, DataFormat expectedFormat) +{ + ASSERT(expectedFormat & DataFormatJS); + return (format | DataFormatJS) == expectedFormat; +} + +inline bool isJSInteger(DataFormat format) +{ + return isJSFormat(format, DataFormatJSInteger); +} + +inline bool isJSDouble(DataFormat format) +{ + return isJSFormat(format, DataFormatJSDouble); +} + +inline bool isJSCell(DataFormat format) +{ + return isJSFormat(format, DataFormatJSCell); +} + +inline bool isJSBoolean(DataFormat format) +{ + return isJSFormat(format, DataFormatJSBoolean); +} + +} + +#endif // DataFormat_h diff --git a/bytecode/EvalCodeCache.h b/bytecode/EvalCodeCache.h index 1e181b9..fba1d32 100644 --- a/bytecode/EvalCodeCache.h +++ b/bytecode/EvalCodeCache.h @@ -41,27 +41,36 @@ namespace JSC { - class MarkStack; - typedef MarkStack SlotVisitor; + class SlotVisitor; class EvalCodeCache { public: - EvalExecutable* get(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) + EvalExecutable* tryGet(bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain) { - EvalExecutable* evalExecutable = 0; - if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject()) - evalExecutable = m_cacheMap.get(evalSource.impl()).get(); - - if (!evalExecutable) { - evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext); - exceptionValue = evalExecutable->compile(exec, scopeChain); - if (exceptionValue) - return 0; + return m_cacheMap.get(evalSource.impl()).get(); + return 0; + } + + EvalExecutable* getSlow(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) + { + EvalExecutable* evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext); + exceptionValue = evalExecutable->compile(exec, scopeChain); + if (exceptionValue) + return 0; + + if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) + m_cacheMap.set(evalSource.impl(), WriteBarrier(exec->globalData(), owner, evalExecutable)); + + return evalExecutable; + } + + EvalExecutable* get(ExecState* exec, ScriptExecutable* owner, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) + { + EvalExecutable* evalExecutable = tryGet(inStrictContext, evalSource, scopeChain); - if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) - m_cacheMap.set(evalSource.impl(), WriteBarrier(exec->globalData(), owner, evalExecutable)); - } + if (!evalExecutable) + evalExecutable = getSlow(exec, owner, inStrictContext, evalSource, scopeChain, exceptionValue); return evalExecutable; } diff --git a/bytecode/ExecutionCounter.cpp b/bytecode/ExecutionCounter.cpp new file mode 100644 index 0000000..ea33500 --- /dev/null +++ b/bytecode/ExecutionCounter.cpp @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2012 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 "ExecutionCounter.h" + +#include "CodeBlock.h" +#include "ExecutableAllocator.h" + +namespace JSC { + +ExecutionCounter::ExecutionCounter() +{ + reset(); +} + +bool ExecutionCounter::checkIfThresholdCrossedAndSet(CodeBlock* codeBlock) +{ + if (hasCrossedThreshold(codeBlock)) + return true; + + if (setThreshold(codeBlock)) + return true; + + return false; +} + +void ExecutionCounter::setNewThreshold(int32_t threshold, CodeBlock* codeBlock) +{ + reset(); + m_activeThreshold = threshold; + setThreshold(codeBlock); +} + +void ExecutionCounter::deferIndefinitely() +{ + m_totalCount = 0; + m_activeThreshold = std::numeric_limits::max(); + m_counter = std::numeric_limits::min(); +} + +double ExecutionCounter::applyMemoryUsageHeuristics(int32_t value, CodeBlock* codeBlock) +{ +#if ENABLE(JIT) + double multiplier = + ExecutableAllocator::memoryPressureMultiplier( + codeBlock->predictedMachineCodeSize()); +#else + // This code path will probably not be taken, but if it is, we fake it. + double multiplier = 1.0; + UNUSED_PARAM(codeBlock); +#endif + ASSERT(multiplier >= 1.0); + return multiplier * value; +} + +int32_t ExecutionCounter::applyMemoryUsageHeuristicsAndConvertToInt( + int32_t value, CodeBlock* codeBlock) +{ + double doubleResult = applyMemoryUsageHeuristics(value, codeBlock); + + ASSERT(doubleResult >= 0); + + if (doubleResult > std::numeric_limits::max()) + return std::numeric_limits::max(); + + return static_cast(doubleResult); +} + +bool ExecutionCounter::hasCrossedThreshold(CodeBlock* codeBlock) const +{ + // This checks if the current count rounded up to the threshold we were targeting. + // For example, if we are using half of available executable memory and have + // m_activeThreshold = 1000, applyMemoryUsageHeuristics(m_activeThreshold) will be + // 2000, but we will pretend as if the threshold was crossed if we reach 2000 - + // 1000 / 2, or 1500. The reasoning here is that we want to avoid thrashing. If + // this method returns false, then the JIT's threshold for when it will again call + // into the slow path (which will call this method a second time) will be set + // according to the difference between the current count and the target count + // according to *current* memory usage. But by the time we call into this again, we + // may have JIT'ed more code, and so the target count will increase slightly. This + // may lead to a repeating pattern where the target count is slightly incremented, + // the JIT immediately matches that increase, calls into the slow path again, and + // again the target count is slightly incremented. Instead of having this vicious + // cycle, we declare victory a bit early if the difference between the current + // total and our target according to memory heuristics is small. Our definition of + // small is arbitrarily picked to be half of the original threshold (i.e. + // m_activeThreshold). + + double modifiedThreshold = applyMemoryUsageHeuristics(m_activeThreshold, codeBlock); + + return static_cast(m_totalCount) + m_counter >= + modifiedThreshold - static_cast(m_activeThreshold) / 2; +} + +bool ExecutionCounter::setThreshold(CodeBlock* codeBlock) +{ + if (m_activeThreshold == std::numeric_limits::max()) { + deferIndefinitely(); + return false; + } + + ASSERT(!hasCrossedThreshold(codeBlock)); + + // Compute the true total count. + double trueTotalCount = static_cast(m_totalCount) + m_counter; + + // Correct the threshold for current memory usage. + double threshold = applyMemoryUsageHeuristics(m_activeThreshold, codeBlock); + + // Threshold must be non-negative and not NaN. + ASSERT(threshold >= 0); + + // Adjust the threshold according to the number of executions we have already + // seen. This shouldn't go negative, but it might, because of round-off errors. + threshold -= trueTotalCount; + + if (threshold <= 0) { + m_counter = 0; + m_totalCount = trueTotalCount; + return true; + } + + if (threshold > std::numeric_limits::max()) + threshold = std::numeric_limits::max(); + + m_counter = static_cast(-threshold); + + m_totalCount = trueTotalCount + threshold; + + return false; +} + +void ExecutionCounter::reset() +{ + m_counter = 0; + m_totalCount = 0; + m_activeThreshold = 0; +} + +} // namespace JSC + diff --git a/bytecode/ExecutionCounter.h b/bytecode/ExecutionCounter.h new file mode 100644 index 0000000..d2ffbb6 --- /dev/null +++ b/bytecode/ExecutionCounter.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2012 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 ExecutionCounter_h +#define ExecutionCounter_h + +#include + +namespace JSC { + +class CodeBlock; + +class ExecutionCounter { +public: + ExecutionCounter(); + bool checkIfThresholdCrossedAndSet(CodeBlock*); + void setNewThreshold(int32_t threshold, CodeBlock*); + void deferIndefinitely(); + static double applyMemoryUsageHeuristics(int32_t value, CodeBlock*); + static int32_t applyMemoryUsageHeuristicsAndConvertToInt(int32_t value, CodeBlock*); + + static int32_t formattedTotalCount(float value) + { + union { + int32_t i; + float f; + } u; + u.f = value; + return u.i; + } + +private: + bool hasCrossedThreshold(CodeBlock*) const; + bool setThreshold(CodeBlock*); + void reset(); + +public: + + // NB. These are intentionally public because it will be modified from machine code. + + // This counter is incremented by the JIT or LLInt. It starts out negative and is + // counted up until it becomes non-negative. At the start of a counting period, + // the threshold we wish to reach is m_totalCount + m_counter, in the sense that + // we will add X to m_totalCount and subtract X from m_counter. + int32_t m_counter; + + // Counts the total number of executions we have seen plus the ones we've set a + // threshold for in m_counter. Because m_counter's threshold is negative, the + // total number of actual executions can always be computed as m_totalCount + + // m_counter. + float m_totalCount; + + // This is the threshold we were originally targetting, without any correction for + // the memory usage heuristics. + int32_t m_activeThreshold; +}; + +} // namespace JSC + +#endif // ExecutionCounter_h + diff --git a/bytecode/ExpressionRangeInfo.h b/bytecode/ExpressionRangeInfo.h new file mode 100644 index 0000000..f4949a6 --- /dev/null +++ b/bytecode/ExpressionRangeInfo.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 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 ExpressionRangeInfo_h +#define ExpressionRangeInfo_h + +#include + +namespace JSC { + +struct ExpressionRangeInfo { + enum { + MaxOffset = (1 << 7) - 1, + MaxDivot = (1 << 25) - 1 + }; + uint32_t instructionOffset : 25; + uint32_t divotPoint : 25; + uint32_t startOffset : 7; + uint32_t endOffset : 7; +}; + +} // namespace JSC + +#endif // ExpressionRangeInfo_h + diff --git a/bytecode/GetByIdStatus.cpp b/bytecode/GetByIdStatus.cpp new file mode 100644 index 0000000..11aead3 --- /dev/null +++ b/bytecode/GetByIdStatus.cpp @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2012 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 "GetByIdStatus.h" + +#include "CodeBlock.h" +#include "LowLevelInterpreter.h" + +namespace JSC { + +GetByIdStatus GetByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident) +{ + UNUSED_PARAM(profiledBlock); + UNUSED_PARAM(bytecodeIndex); + UNUSED_PARAM(ident); +#if ENABLE(LLINT) + Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex; + + if (instruction[0].u.opcode == llint_op_method_check) + instruction++; + + Structure* structure = instruction[4].u.structure.get(); + if (!structure) + return GetByIdStatus(NoInformation, StructureSet(), notFound, false); + + size_t offset = structure->get(*profiledBlock->globalData(), ident); + if (offset == notFound) + return GetByIdStatus(NoInformation, StructureSet(), notFound, false); + + return GetByIdStatus(SimpleDirect, StructureSet(structure), offset, false); +#else + return GetByIdStatus(NoInformation, StructureSet(), notFound, false); +#endif +} + +GetByIdStatus GetByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident) +{ + UNUSED_PARAM(profiledBlock); + UNUSED_PARAM(bytecodeIndex); + UNUSED_PARAM(ident); +#if ENABLE(JIT) && ENABLE(VALUE_PROFILER) + if (!profiledBlock->numberOfStructureStubInfos()) + return computeFromLLInt(profiledBlock, bytecodeIndex, ident); + + // First check if it makes either calls, in which case we want to be super careful, or + // if it's not set at all, in which case we punt. + StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex); + if (!stubInfo.seen) + return computeFromLLInt(profiledBlock, bytecodeIndex, ident); + + PolymorphicAccessStructureList* list; + int listSize; + switch (stubInfo.accessType) { + case access_get_by_id_self_list: + list = stubInfo.u.getByIdSelfList.structureList; + listSize = stubInfo.u.getByIdSelfList.listSize; + break; + case access_get_by_id_proto_list: + list = stubInfo.u.getByIdProtoList.structureList; + listSize = stubInfo.u.getByIdProtoList.listSize; + break; + default: + list = 0; + listSize = 0; + break; + } + for (int i = 0; i < listSize; ++i) { + if (!list->list[i].isDirect) + return GetByIdStatus(MakesCalls, StructureSet(), notFound, true); + } + + // Next check if it takes slow case, in which case we want to be kind of careful. + if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex)) + return GetByIdStatus(TakesSlowPath, StructureSet(), notFound, true); + + // Finally figure out if we can derive an access strategy. + GetByIdStatus result; + result.m_wasSeenInJIT = true; + switch (stubInfo.accessType) { + case access_unset: + return computeFromLLInt(profiledBlock, bytecodeIndex, ident); + + case access_get_by_id_self: { + Structure* structure = stubInfo.u.getByIdSelf.baseObjectStructure.get(); + result.m_offset = structure->get(*profiledBlock->globalData(), ident); + + if (result.m_offset != notFound) + result.m_structureSet.add(structure); + + if (result.m_offset != notFound) + ASSERT(result.m_structureSet.size()); + break; + } + + case access_get_by_id_self_list: { + PolymorphicAccessStructureList* list = stubInfo.u.getByIdProtoList.structureList; + unsigned size = stubInfo.u.getByIdProtoList.listSize; + for (unsigned i = 0; i < size; ++i) { + ASSERT(list->list[i].isDirect); + + Structure* structure = list->list[i].base.get(); + if (result.m_structureSet.contains(structure)) + continue; + + size_t myOffset = structure->get(*profiledBlock->globalData(), ident); + + if (myOffset == notFound) { + result.m_offset = notFound; + break; + } + + if (!i) + result.m_offset = myOffset; + else if (result.m_offset != myOffset) { + result.m_offset = notFound; + break; + } + + result.m_structureSet.add(structure); + } + + if (result.m_offset != notFound) + ASSERT(result.m_structureSet.size()); + break; + } + + default: + ASSERT(result.m_offset == notFound); + break; + } + + if (result.m_offset == notFound) { + result.m_state = TakesSlowPath; + result.m_structureSet.clear(); + } else + result.m_state = SimpleDirect; + + return result; +#else // ENABLE(JIT) + return GetByIdStatus(NoInformation, StructureSet(), notFound, false); +#endif // ENABLE(JIT) +} + +} // namespace JSC + diff --git a/bytecode/GetByIdStatus.h b/bytecode/GetByIdStatus.h new file mode 100644 index 0000000..39476c0 --- /dev/null +++ b/bytecode/GetByIdStatus.h @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2012 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 GetByIdStatus_h +#define GetByIdStatus_h + +#include "StructureSet.h" +#include + +namespace JSC { + +class CodeBlock; +class Identifier; + +class GetByIdStatus { +public: + enum State { + NoInformation, // It's uncached so we have no information. + SimpleDirect, // It's cached for a direct access to a known object property. + TakesSlowPath, // It's known to often take slow path. + MakesCalls // It's known to take paths that make calls. + }; + + GetByIdStatus() + : m_state(NoInformation) + , m_offset(notFound) + { + } + + GetByIdStatus(State state, const StructureSet& structureSet, size_t offset, bool wasSeenInJIT) + : m_state(state) + , m_structureSet(structureSet) + , m_offset(offset) + , m_wasSeenInJIT(wasSeenInJIT) + { + ASSERT((state == SimpleDirect) == (offset != notFound)); + } + + static GetByIdStatus computeFor(CodeBlock*, unsigned bytecodeIndex, Identifier&); + + State state() const { return m_state; } + + bool isSet() const { return m_state != NoInformation; } + bool operator!() const { return !isSet(); } + bool isSimpleDirect() const { return m_state == SimpleDirect; } + bool takesSlowPath() const { return m_state == TakesSlowPath || m_state == MakesCalls; } + bool makesCalls() const { return m_state == MakesCalls; } + + const StructureSet& structureSet() const { return m_structureSet; } + size_t offset() const { return m_offset; } + + bool wasSeenInJIT() const { return m_wasSeenInJIT; } + +private: + static GetByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, Identifier&); + + State m_state; + StructureSet m_structureSet; + size_t m_offset; + bool m_wasSeenInJIT; +}; + +} // namespace JSC + +#endif // PropertyAccessStatus_h + diff --git a/bytecode/GlobalResolveInfo.h b/bytecode/GlobalResolveInfo.h new file mode 100644 index 0000000..5576cfa --- /dev/null +++ b/bytecode/GlobalResolveInfo.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2012 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 GlobalResolveInfo_h +#define GlobalResolveInfo_h + +#include "WriteBarrier.h" + +namespace JSC { + +struct GlobalResolveInfo { + GlobalResolveInfo(unsigned bytecodeOffset) + : offset(0) + , bytecodeOffset(bytecodeOffset) + { + } + + WriteBarrier structure; + unsigned offset; + unsigned bytecodeOffset; +}; + +} // namespace JSC + +#endif // GlobalResolveInfo_h + diff --git a/bytecode/HandlerInfo.h b/bytecode/HandlerInfo.h new file mode 100644 index 0000000..8396c96 --- /dev/null +++ b/bytecode/HandlerInfo.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2012 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 HandlerInfo_h +#define HandlerInfo_h + +#include "CodeLocation.h" +#include + +namespace JSC { + +struct HandlerInfo { + uint32_t start; + uint32_t end; + uint32_t target; + uint32_t scopeDepth; +#if ENABLE(JIT) + CodeLocationLabel nativeCode; +#endif +}; + +} // namespace JSC + +#endif // HandlerInfo_h + diff --git a/bytecode/Instruction.h b/bytecode/Instruction.h index b3bb5b7..c4989d2 100644 --- a/bytecode/Instruction.h +++ b/bytecode/Instruction.h @@ -44,15 +44,15 @@ namespace JSC { // If the JIT is not in use we don't actually need the variable (that said, if the JIT is not in use we don't // curently actually use PolymorphicAccessStructureLists, which we should). Anyway, this seems like the best // solution for now - will need to something smarter if/when we actually want mixed-mode operation. -#if ENABLE(JIT) - typedef CodeLocationLabel PolymorphicAccessStructureListStubRoutineType; -#else - typedef void* PolymorphicAccessStructureListStubRoutineType; -#endif class JSCell; class Structure; class StructureChain; + struct LLIntCallLinkInfo; + struct ValueProfile; + +#if ENABLE(JIT) + typedef MacroAssemblerCodeRef PolymorphicAccessStructureListStubRoutineType; // Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream. struct PolymorphicAccessStructureList { @@ -60,6 +60,7 @@ namespace JSC { public: struct PolymorphicStubInfo { bool isChain; + bool isDirect; PolymorphicAccessStructureListStubRoutineType stubRoutine; WriteBarrier base; union { @@ -72,47 +73,54 @@ namespace JSC { u.proto.clear(); } - void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base) + void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, bool isDirect) { stubRoutine = _stubRoutine; base.set(globalData, owner, _base); u.proto.clear(); isChain = false; + this->isDirect = isDirect; } - void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto) + void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto, bool isDirect) { stubRoutine = _stubRoutine; base.set(globalData, owner, _base); u.proto.set(globalData, owner, _proto); isChain = false; + this->isDirect = isDirect; } - void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain) + void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain, bool isDirect) { stubRoutine = _stubRoutine; base.set(globalData, owner, _base); u.chain.set(globalData, owner, _chain); isChain = true; + this->isDirect = isDirect; } } list[POLYMORPHIC_LIST_CACHE_SIZE]; - PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase) + PolymorphicAccessStructureList() { - list[0].set(globalData, owner, stubRoutine, firstBase); + } + + PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, bool isDirect) + { + list[0].set(globalData, owner, stubRoutine, firstBase, isDirect); } - PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto) + PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto, bool isDirect) { - list[0].set(globalData, owner, stubRoutine, firstBase, firstProto); + list[0].set(globalData, owner, stubRoutine, firstBase, firstProto, isDirect); } - PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain) + PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain, bool isDirect) { - list[0].set(globalData, owner, stubRoutine, firstBase, firstChain); + list[0].set(globalData, owner, stubRoutine, firstBase, firstChain, isDirect); } - void visitAggregate(SlotVisitor& visitor, int count) + bool visitWeak(int count) { for (int i = 0; i < count; ++i) { PolymorphicStubInfo& info = list[i]; @@ -122,19 +130,31 @@ namespace JSC { continue; } - visitor.append(&info.base); - if (info.u.proto && !info.isChain) - visitor.append(&info.u.proto); - if (info.u.chain && info.isChain) - visitor.append(&info.u.chain); + if (!Heap::isMarked(info.base.get())) + return false; + if (info.u.proto && !info.isChain + && !Heap::isMarked(info.u.proto.get())) + return false; + if (info.u.chain && info.isChain + && !Heap::isMarked(info.u.chain.get())) + return false; } + + return true; } }; +#endif + struct Instruction { + Instruction() + { + u.jsCell.clear(); + } + Instruction(Opcode opcode) { -#if !ENABLE(COMPUTED_GOTO_INTERPRETER) +#if !ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) // We have to initialize one of the pointer members to ensure that // the entire struct is initialized, when opcode is not a pointer. u.jsCell.clear(); @@ -165,8 +185,12 @@ namespace JSC { u.jsCell.clear(); u.jsCell.set(globalData, owner, jsCell); } - Instruction(PolymorphicAccessStructureList* polymorphicStructures) { u.polymorphicStructures = polymorphicStructures; } + Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; } + + Instruction(LLIntCallLinkInfo* callLinkInfo) { u.callLinkInfo = callLinkInfo; } + + Instruction(ValueProfile* profile) { u.profile = profile; } union { Opcode opcode; @@ -174,8 +198,10 @@ namespace JSC { WriteBarrierBase structure; WriteBarrierBase structureChain; WriteBarrierBase jsCell; - PolymorphicAccessStructureList* polymorphicStructures; PropertySlot::GetValueFunc getterFunc; + LLIntCallLinkInfo* callLinkInfo; + ValueProfile* profile; + void* pointer; } u; private: diff --git a/bytecode/LLIntCallLinkInfo.h b/bytecode/LLIntCallLinkInfo.h new file mode 100644 index 0000000..bfb9510 --- /dev/null +++ b/bytecode/LLIntCallLinkInfo.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 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 LLIntCallLinkInfo_h +#define LLIntCallLinkInfo_h + +#include "JSFunction.h" +#include "MacroAssemblerCodeRef.h" +#include + +namespace JSC { + +struct Instruction; + +struct LLIntCallLinkInfo : public BasicRawSentinelNode { + LLIntCallLinkInfo() + { + } + + ~LLIntCallLinkInfo() + { + if (isOnList()) + remove(); + } + + bool isLinked() { return callee; } + + void unlink() + { + callee.clear(); + machineCodeTarget = MacroAssemblerCodePtr(); + if (isOnList()) + remove(); + } + + WriteBarrier callee; + WriteBarrier lastSeenCallee; + MacroAssemblerCodePtr machineCodeTarget; +}; + +} // namespace JSC + +#endif // LLIntCallLinkInfo_h + diff --git a/bytecode/LazyOperandValueProfile.cpp b/bytecode/LazyOperandValueProfile.cpp new file mode 100644 index 0000000..f199b69 --- /dev/null +++ b/bytecode/LazyOperandValueProfile.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2012 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 "LazyOperandValueProfile.h" + +#if ENABLE(VALUE_PROFILER) + +namespace JSC { + +CompressedLazyOperandValueProfileHolder::CompressedLazyOperandValueProfileHolder() { } +CompressedLazyOperandValueProfileHolder::~CompressedLazyOperandValueProfileHolder() { } + +void CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions() +{ + if (!m_data) + return; + + for (unsigned i = 0; i < m_data->size(); ++i) + m_data->at(i).computeUpdatedPrediction(); +} + +LazyOperandValueProfile* CompressedLazyOperandValueProfileHolder::add( + const LazyOperandValueProfileKey& key) +{ + if (!m_data) + m_data = adoptPtr(new LazyOperandValueProfile::List()); + else { + for (unsigned i = 0; i < m_data->size(); ++i) { + if (m_data->at(i).key() == key) + return &m_data->at(i); + } + } + + m_data->append(LazyOperandValueProfile(key)); + return &m_data->last(); +} + +LazyOperandValueProfileParser::LazyOperandValueProfileParser( + CompressedLazyOperandValueProfileHolder& holder) + : m_holder(holder) +{ + if (!m_holder.m_data) + return; + + LazyOperandValueProfile::List& data = *m_holder.m_data; + for (unsigned i = 0; i < data.size(); ++i) + m_map.add(data[i].key(), &data[i]); +} + +LazyOperandValueProfileParser::~LazyOperandValueProfileParser() { } + +LazyOperandValueProfile* LazyOperandValueProfileParser::getIfPresent( + const LazyOperandValueProfileKey& key) const +{ + HashMap::const_iterator iter = + m_map.find(key); + + if (iter == m_map.end()) + return 0; + + return iter->second; +} + +PredictedType LazyOperandValueProfileParser::prediction( + const LazyOperandValueProfileKey& key) const +{ + LazyOperandValueProfile* profile = getIfPresent(key); + if (!profile) + return PredictNone; + + return profile->computeUpdatedPrediction(); +} + +} // namespace JSC + +#endif // ENABLE(VALUE_PROFILER) + diff --git a/bytecode/LazyOperandValueProfile.h b/bytecode/LazyOperandValueProfile.h new file mode 100644 index 0000000..d0260f9 --- /dev/null +++ b/bytecode/LazyOperandValueProfile.h @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2012 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 LazyOperandValueProfile_h +#define LazyOperandValueProfile_h + +#include + +#if ENABLE(VALUE_PROFILER) + +#include "ValueProfile.h" +#include +#include +#include +#include + +namespace JSC { + +class ScriptExecutable; + +class LazyOperandValueProfileKey { +public: + LazyOperandValueProfileKey() + : m_bytecodeOffset(0) // 0 = empty value + , m_operand(-1) // not a valid operand index in our current scheme + { + } + + LazyOperandValueProfileKey(WTF::HashTableDeletedValueType) + : m_bytecodeOffset(1) // 1 = deleted value + , m_operand(-1) // not a valid operand index in our current scheme + { + } + + LazyOperandValueProfileKey(unsigned bytecodeOffset, int operand) + : m_bytecodeOffset(bytecodeOffset) + , m_operand(operand) + { + ASSERT(operand != -1); + } + + bool operator!() const + { + return m_operand == -1; + } + + bool operator==(const LazyOperandValueProfileKey& other) const + { + return m_bytecodeOffset == other.m_bytecodeOffset + && m_operand == other.m_operand; + } + + unsigned hash() const + { + return WTF::intHash(m_bytecodeOffset) + m_operand; + } + + unsigned bytecodeOffset() const + { + ASSERT(!!*this); + return m_bytecodeOffset; + } + int operand() const + { + ASSERT(!!*this); + return m_operand; + } + + bool isHashTableDeletedValue() const + { + return m_operand == -1 && m_bytecodeOffset; + } +private: + unsigned m_bytecodeOffset; + int m_operand; +}; + +struct LazyOperandValueProfileKeyHash { + static unsigned hash(const LazyOperandValueProfileKey& key) { return key.hash(); } + static bool equal( + const LazyOperandValueProfileKey& a, + const LazyOperandValueProfileKey& b) { return a == b; } + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +} // namespace JSC + +namespace WTF { + +template struct DefaultHash; +template<> struct DefaultHash { + typedef JSC::LazyOperandValueProfileKeyHash Hash; +}; + +template struct HashTraits; +template<> struct HashTraits : public GenericHashTraits { + static void constructDeletedValue(JSC::LazyOperandValueProfileKey& slot) { new (NotNull, &slot) JSC::LazyOperandValueProfileKey(HashTableDeletedValue); } + static bool isDeletedValue(const JSC::LazyOperandValueProfileKey& value) { return value.isHashTableDeletedValue(); } +}; + +} // namespace WTF + +namespace JSC { + +struct LazyOperandValueProfile : public MinimalValueProfile { + LazyOperandValueProfile() + : MinimalValueProfile() + , m_operand(-1) + { + } + + explicit LazyOperandValueProfile(const LazyOperandValueProfileKey& key) + : MinimalValueProfile(key.bytecodeOffset()) + , m_operand(key.operand()) + { + } + + LazyOperandValueProfileKey key() const + { + return LazyOperandValueProfileKey(m_bytecodeOffset, m_operand); + } + + int m_operand; + + typedef SegmentedVector List; +}; + +class LazyOperandValueProfileParser; + +class CompressedLazyOperandValueProfileHolder { + WTF_MAKE_NONCOPYABLE(CompressedLazyOperandValueProfileHolder); +public: + CompressedLazyOperandValueProfileHolder(); + ~CompressedLazyOperandValueProfileHolder(); + + void computeUpdatedPredictions(); + + LazyOperandValueProfile* add(const LazyOperandValueProfileKey& key); + +private: + friend class LazyOperandValueProfileParser; + OwnPtr m_data; +}; + +class LazyOperandValueProfileParser { + WTF_MAKE_NONCOPYABLE(LazyOperandValueProfileParser); +public: + explicit LazyOperandValueProfileParser( + CompressedLazyOperandValueProfileHolder& holder); + ~LazyOperandValueProfileParser(); + + LazyOperandValueProfile* getIfPresent( + const LazyOperandValueProfileKey& key) const; + + PredictedType prediction(const LazyOperandValueProfileKey& key) const; +private: + CompressedLazyOperandValueProfileHolder& m_holder; + HashMap m_map; +}; + +} // namespace JSC + +#endif // ENABLE(VALUE_PROFILER) + +#endif // LazyOperandValueProfile_h + + diff --git a/bytecode/LineInfo.h b/bytecode/LineInfo.h new file mode 100644 index 0000000..e9e7013 --- /dev/null +++ b/bytecode/LineInfo.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2012 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 LineInfo_h +#define LineInfo_h + +#include + +namespace JSC { + +struct LineInfo { + uint32_t instructionOffset; + int32_t lineNumber; +}; + +} // namespace JSC + +#endif // LineInfo_h + diff --git a/bytecode/MethodCallLinkInfo.cpp b/bytecode/MethodCallLinkInfo.cpp new file mode 100644 index 0000000..1fcf585 --- /dev/null +++ b/bytecode/MethodCallLinkInfo.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2012 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 "MethodCallLinkInfo.h" + +#if ENABLE(JIT) + +#include "JITStubs.h" +#include "RepatchBuffer.h" + +namespace JSC { + +void MethodCallLinkInfo::reset(RepatchBuffer& repatchBuffer, JITCode::JITType jitType) +{ + cachedStructure.clearToMaxUnsigned(); + cachedPrototype.clear(); + cachedPrototypeStructure.clearToMaxUnsigned(); + cachedFunction.clear(); + + ASSERT_UNUSED(jitType, jitType == JITCode::BaselineJIT); + + repatchBuffer.relink(callReturnLocation, cti_op_get_by_id_method_check); +} + +} // namespace JSC + +#endif // ENABLE(JIT) diff --git a/bytecode/MethodCallLinkInfo.h b/bytecode/MethodCallLinkInfo.h new file mode 100644 index 0000000..2243bc2 --- /dev/null +++ b/bytecode/MethodCallLinkInfo.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2012 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 MethodCallLinkInfo_h +#define MethodCallLinkInfo_h + +#include "CodeLocation.h" +#include "JITCode.h" +#include "JITWriteBarrier.h" +#include + +namespace JSC { + +#if ENABLE(JIT) + +class RepatchBuffer; + +struct MethodCallLinkInfo { + MethodCallLinkInfo() + : seen(false) + { + } + + bool seenOnce() + { + return seen; + } + + void setSeen() + { + seen = true; + } + + void reset(RepatchBuffer&, JITCode::JITType); + + unsigned bytecodeIndex; + CodeLocationCall callReturnLocation; + JITWriteBarrier cachedStructure; + JITWriteBarrier cachedPrototypeStructure; + // We'd like this to actually be JSFunction, but InternalFunction and JSFunction + // don't have a common parent class and we allow specialisation on both + JITWriteBarrier cachedFunction; + JITWriteBarrier cachedPrototype; + bool seen; +}; + +inline void* getMethodCallLinkInfoReturnLocation(MethodCallLinkInfo* methodCallLinkInfo) +{ + return methodCallLinkInfo->callReturnLocation.executableAddress(); +} + +inline unsigned getMethodCallLinkInfoBytecodeIndex(MethodCallLinkInfo* methodCallLinkInfo) +{ + return methodCallLinkInfo->bytecodeIndex; +} + +#endif // ENABLE(JIT) + +} // namespace JSC + +#endif // MethodCallLinkInfo_h diff --git a/bytecode/MethodCallLinkStatus.cpp b/bytecode/MethodCallLinkStatus.cpp new file mode 100644 index 0000000..795b41b --- /dev/null +++ b/bytecode/MethodCallLinkStatus.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 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 "MethodCallLinkStatus.h" + +#include "CodeBlock.h" + +namespace JSC { + +MethodCallLinkStatus MethodCallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex) +{ + UNUSED_PARAM(profiledBlock); + UNUSED_PARAM(bytecodeIndex); +#if ENABLE(JIT) && ENABLE(VALUE_PROFILER) + // NOTE: This does not have an LLInt fall-back because LLInt does not do any method + // call link caching. + if (!profiledBlock->numberOfMethodCallLinkInfos()) + return MethodCallLinkStatus(); + + MethodCallLinkInfo& methodCall = profiledBlock->getMethodCallLinkInfo(bytecodeIndex); + + if (!methodCall.seen || !methodCall.cachedStructure) + return MethodCallLinkStatus(); + + if (methodCall.cachedPrototype.get() == profiledBlock->globalObject()->methodCallDummy()) { + return MethodCallLinkStatus( + methodCall.cachedStructure.get(), + 0, + methodCall.cachedFunction.get(), + 0); + } + + return MethodCallLinkStatus( + methodCall.cachedStructure.get(), + methodCall.cachedPrototypeStructure.get(), + methodCall.cachedFunction.get(), + methodCall.cachedPrototype.get()); +#else // ENABLE(JIT) + return MethodCallLinkStatus(); +#endif // ENABLE(JIT) +} + +} // namespace JSC diff --git a/bytecode/MethodCallLinkStatus.h b/bytecode/MethodCallLinkStatus.h new file mode 100644 index 0000000..c3d11a1 --- /dev/null +++ b/bytecode/MethodCallLinkStatus.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2012 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 MethodCallLinkStatus_h +#define MethodCallLinkStatus_h + +namespace JSC { + +class CodeBlock; +class JSObject; +class Structure; + +class MethodCallLinkStatus { +public: + MethodCallLinkStatus() + : m_structure(0) + , m_prototypeStructure(0) + , m_function(0) + , m_prototype(0) + { + } + + MethodCallLinkStatus( + Structure* structure, + Structure* prototypeStructure, + JSObject* function, + JSObject* prototype) + : m_structure(structure) + , m_prototypeStructure(prototypeStructure) + , m_function(function) + , m_prototype(prototype) + { + if (!m_function) { + ASSERT(!m_structure); + ASSERT(!m_prototypeStructure); + ASSERT(!m_prototype); + } else + ASSERT(m_structure); + + ASSERT(!m_prototype == !m_prototypeStructure); + } + + static MethodCallLinkStatus computeFor(CodeBlock*, unsigned bytecodeIndex); + + bool isSet() const { return !!m_function; } + bool operator!() const { return !m_function; } + + bool needsPrototypeCheck() const { return !!m_prototype; } + + Structure* structure() { return m_structure; } + Structure* prototypeStructure() { return m_prototypeStructure; } + JSObject* function() const { return m_function; } + JSObject* prototype() const { return m_prototype; } + +private: + Structure* m_structure; + Structure* m_prototypeStructure; + JSObject* m_function; + JSObject* m_prototype; +}; + +} // namespace JSC + +#endif // MethodCallLinkStatus_h + diff --git a/bytecode/MethodOfGettingAValueProfile.cpp b/bytecode/MethodOfGettingAValueProfile.cpp new file mode 100644 index 0000000..857ed9c --- /dev/null +++ b/bytecode/MethodOfGettingAValueProfile.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2012 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 "MethodOfGettingAValueProfile.h" + +#if ENABLE(DFG_JIT) + +#include "CodeBlock.h" + +namespace JSC { + +MethodOfGettingAValueProfile MethodOfGettingAValueProfile::fromLazyOperand( + CodeBlock* codeBlock, const LazyOperandValueProfileKey& key) +{ + MethodOfGettingAValueProfile result; + result.m_kind = LazyOperand; + result.u.lazyOperand.codeBlock = codeBlock; + result.u.lazyOperand.bytecodeOffset = key.bytecodeOffset(); + result.u.lazyOperand.operand = key.operand(); + return result; +} + +EncodedJSValue* MethodOfGettingAValueProfile::getSpecFailBucket(unsigned index) const +{ + switch (m_kind) { + case None: + return 0; + + case Ready: + return u.profile->specFailBucket(index); + + case LazyOperand: + return u.lazyOperand.codeBlock->lazyOperandValueProfiles().add( + LazyOperandValueProfileKey( + u.lazyOperand.bytecodeOffset, u.lazyOperand.operand))->specFailBucket(index); + + default: + ASSERT_NOT_REACHED(); + return 0; + } +} + +} // namespace JSC + +#endif // ENABLE(DFG_JIT) + diff --git a/bytecode/MethodOfGettingAValueProfile.h b/bytecode/MethodOfGettingAValueProfile.h new file mode 100644 index 0000000..0f5c2be --- /dev/null +++ b/bytecode/MethodOfGettingAValueProfile.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2012 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 MethodOfGettingAValueProfile_h +#define MethodOfGettingAValueProfile_h + +#include + +// This is guarded by ENABLE_DFG_JIT only because it uses some value profiles +// that are currently only used if the DFG is enabled (i.e. they are not +// available in the profile-only configuration). Hopefully someday all of +// these #if's will disappear... +#if ENABLE(DFG_JIT) + +#include "JSValue.h" + +namespace JSC { + +class CodeBlock; +class LazyOperandValueProfileKey; +struct ValueProfile; + +class MethodOfGettingAValueProfile { +public: + MethodOfGettingAValueProfile() + : m_kind(None) + { + } + + explicit MethodOfGettingAValueProfile(ValueProfile* profile) + { + if (profile) { + m_kind = Ready; + u.profile = profile; + } else + m_kind = None; + } + + static MethodOfGettingAValueProfile fromLazyOperand( + CodeBlock*, const LazyOperandValueProfileKey&); + + bool operator!() const { return m_kind == None; } + + // This logically has a pointer to a "There exists X such that + // ValueProfileBase". But since C++ does not have existential + // templates, I cannot return it. So instead, for any methods that + // users of this class would like to call, we'll just have to provide + // a method here that does it through an indirection. Or we could + // possibly just make ValueProfile less template-based. But last I + // tried that, it felt more yucky than this class. + + EncodedJSValue* getSpecFailBucket(unsigned index) const; + +private: + enum Kind { + None, + Ready, + LazyOperand + }; + + Kind m_kind; + union { + ValueProfile* profile; + struct { + CodeBlock* codeBlock; + unsigned bytecodeOffset; + int operand; + } lazyOperand; + } u; +}; + +} // namespace JSC + +#endif // ENABLE(DFG_JIT) + +#endif // MethodOfGettingAValueProfile_h + diff --git a/bytecode/Opcode.cpp b/bytecode/Opcode.cpp index 0bb714b..a277140 100644 --- a/bytecode/Opcode.cpp +++ b/bytecode/Opcode.cpp @@ -39,16 +39,12 @@ using namespace std; namespace JSC { -#if ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS) - const char* const opcodeNames[] = { #define OPCODE_NAME_ENTRY(opcode, size) #opcode, FOR_EACH_OPCODE_ID(OPCODE_NAME_ENTRY) #undef OPCODE_NAME_ENTRY }; -#endif - #if ENABLE(OPCODE_STATS) long long OpcodeStats::opcodeCounts[numOpcodeIDs]; @@ -118,19 +114,19 @@ OpcodeStats::~OpcodeStats() *(currentPairIndex++) = make_pair(i, j); qsort(sortedPairIndices, numOpcodeIDs * numOpcodeIDs, sizeof(pair), compareOpcodePairIndices); - printf("\nExecuted opcode statistics\n"); + dataLog("\nExecuted opcode statistics\n"); - printf("Total instructions executed: %lld\n\n", totalInstructions); + dataLog("Total instructions executed: %lld\n\n", totalInstructions); - printf("All opcodes by frequency:\n\n"); + dataLog("All opcodes by frequency:\n\n"); for (int i = 0; i < numOpcodeIDs; ++i) { int index = sortedIndices[i]; - printf("%s:%s %lld - %.2f%%\n", opcodeNames[index], padOpcodeName((OpcodeID)index, 28), opcodeCounts[index], ((double) opcodeCounts[index]) / ((double) totalInstructions) * 100.0); + dataLog("%s:%s %lld - %.2f%%\n", opcodeNames[index], padOpcodeName((OpcodeID)index, 28), opcodeCounts[index], ((double) opcodeCounts[index]) / ((double) totalInstructions) * 100.0); } - printf("\n"); - printf("2-opcode sequences by frequency: %lld\n\n", totalInstructions); + dataLog("\n"); + dataLog("2-opcode sequences by frequency: %lld\n\n", totalInstructions); for (int i = 0; i < numOpcodeIDs * numOpcodeIDs; ++i) { pair indexPair = sortedPairIndices[i]; @@ -139,11 +135,11 @@ OpcodeStats::~OpcodeStats() if (!count) break; - printf("%s%s %s:%s %lld %.2f%%\n", opcodeNames[indexPair.first], padOpcodeName((OpcodeID)indexPair.first, 28), opcodeNames[indexPair.second], padOpcodeName((OpcodeID)indexPair.second, 28), count, ((double) count) / ((double) totalInstructionPairs) * 100.0); + dataLog("%s%s %s:%s %lld %.2f%%\n", opcodeNames[indexPair.first], padOpcodeName((OpcodeID)indexPair.first, 28), opcodeNames[indexPair.second], padOpcodeName((OpcodeID)indexPair.second, 28), count, ((double) count) / ((double) totalInstructionPairs) * 100.0); } - printf("\n"); - printf("Most common opcodes and sequences:\n"); + dataLog("\n"); + dataLog("Most common opcodes and sequences:\n"); for (int i = 0; i < numOpcodeIDs; ++i) { int index = sortedIndices[i]; @@ -151,7 +147,7 @@ OpcodeStats::~OpcodeStats() double opcodeProportion = ((double) opcodeCount) / ((double) totalInstructions); if (opcodeProportion < 0.0001) break; - printf("\n%s:%s %lld - %.2f%%\n", opcodeNames[index], padOpcodeName((OpcodeID)index, 28), opcodeCount, opcodeProportion * 100.0); + dataLog("\n%s:%s %lld - %.2f%%\n", opcodeNames[index], padOpcodeName((OpcodeID)index, 28), opcodeCount, opcodeProportion * 100.0); for (int j = 0; j < numOpcodeIDs * numOpcodeIDs; ++j) { pair indexPair = sortedPairIndices[j]; @@ -164,11 +160,11 @@ OpcodeStats::~OpcodeStats() if (indexPair.first != index && indexPair.second != index) continue; - printf(" %s%s %s:%s %lld - %.2f%%\n", opcodeNames[indexPair.first], padOpcodeName((OpcodeID)indexPair.first, 28), opcodeNames[indexPair.second], padOpcodeName((OpcodeID)indexPair.second, 28), pairCount, pairProportion * 100.0); + dataLog(" %s%s %s:%s %lld - %.2f%%\n", opcodeNames[indexPair.first], padOpcodeName((OpcodeID)indexPair.first, 28), opcodeNames[indexPair.second], padOpcodeName((OpcodeID)indexPair.second, 28), pairCount, pairProportion * 100.0); } } - printf("\n"); + dataLog("\n"); } void OpcodeStats::recordInstruction(int opcode) diff --git a/bytecode/Opcode.h b/bytecode/Opcode.h index 18902eb..a564de2 100644 --- a/bytecode/Opcode.h +++ b/bytecode/Opcode.h @@ -45,7 +45,6 @@ namespace JSC { macro(op_create_this, 3) \ macro(op_get_callee, 2) \ macro(op_convert_this, 2) \ - macro(op_convert_this_strict, 2) \ \ macro(op_new_object, 2) \ macro(op_new_array, 4) \ @@ -62,6 +61,8 @@ namespace JSC { macro(op_nstricteq, 4) \ macro(op_less, 4) \ macro(op_lesseq, 4) \ + macro(op_greater, 4) \ + macro(op_greatereq, 4) \ \ macro(op_pre_inc, 2) \ macro(op_pre_dec, 2) \ @@ -81,7 +82,6 @@ namespace JSC { macro(op_bitand, 5) \ macro(op_bitxor, 5) \ macro(op_bitor, 5) \ - macro(op_bitnot, 3) \ \ macro(op_check_has_instance, 2) \ macro(op_instanceof, 5) \ @@ -94,50 +94,46 @@ namespace JSC { macro(op_is_function, 3) \ macro(op_in, 4) \ \ - macro(op_resolve, 3) \ - macro(op_resolve_skip, 4) \ - macro(op_resolve_global, 5) \ - macro(op_resolve_global_dynamic, 6) \ - macro(op_get_scoped_var, 4) \ + macro(op_resolve, 4) /* has value profiling */ \ + macro(op_resolve_skip, 5) /* has value profiling */ \ + macro(op_resolve_global, 6) /* has value profiling */ \ + macro(op_resolve_global_dynamic, 7) /* has value profiling */ \ + macro(op_get_scoped_var, 5) /* has value profiling */ \ macro(op_put_scoped_var, 4) \ - macro(op_get_global_var, 3) \ + macro(op_get_global_var, 4) /* has value profiling */ \ macro(op_put_global_var, 3) \ - macro(op_resolve_base, 4) \ + macro(op_resolve_base, 5) /* has value profiling */ \ macro(op_ensure_property_exists, 3) \ - macro(op_resolve_with_base, 4) \ - macro(op_get_by_id, 8) \ - macro(op_get_by_id_self, 8) \ - macro(op_get_by_id_self_list, 8) \ - macro(op_get_by_id_proto, 8) \ - macro(op_get_by_id_proto_list, 8) \ - macro(op_get_by_id_chain, 8) \ - macro(op_get_by_id_getter_self, 8) \ - macro(op_get_by_id_getter_self_list, 8) \ - macro(op_get_by_id_getter_proto, 8) \ - macro(op_get_by_id_getter_proto_list, 8) \ - macro(op_get_by_id_getter_chain, 8) \ - macro(op_get_by_id_custom_self, 8) \ - macro(op_get_by_id_custom_self_list, 8) \ - macro(op_get_by_id_custom_proto, 8) \ - macro(op_get_by_id_custom_proto_list, 8) \ - macro(op_get_by_id_custom_chain, 8) \ - macro(op_get_by_id_generic, 8) \ - macro(op_get_array_length, 8) \ - macro(op_get_string_length, 8) \ + macro(op_resolve_with_base, 5) /* has value profiling */ \ + macro(op_resolve_with_this, 5) /* has value profiling */ \ + macro(op_get_by_id, 9) /* has value profiling */ \ + macro(op_get_by_id_self, 9) /* has value profiling */ \ + macro(op_get_by_id_proto, 9) /* has value profiling */ \ + macro(op_get_by_id_chain, 9) /* has value profiling */ \ + macro(op_get_by_id_getter_self, 9) /* has value profiling */ \ + macro(op_get_by_id_getter_proto, 9) /* has value profiling */ \ + macro(op_get_by_id_getter_chain, 9) /* has value profiling */ \ + macro(op_get_by_id_custom_self, 9) /* has value profiling */ \ + macro(op_get_by_id_custom_proto, 9) /* has value profiling */ \ + macro(op_get_by_id_custom_chain, 9) /* has value profiling */ \ + macro(op_get_by_id_generic, 9) /* has value profiling */ \ + macro(op_get_array_length, 9) /* has value profiling */ \ + macro(op_get_string_length, 9) /* has value profiling */ \ macro(op_get_arguments_length, 4) \ macro(op_put_by_id, 9) \ macro(op_put_by_id_transition, 9) \ + macro(op_put_by_id_transition_direct, 9) \ + macro(op_put_by_id_transition_normal, 9) \ macro(op_put_by_id_replace, 9) \ macro(op_put_by_id_generic, 9) \ macro(op_del_by_id, 4) \ - macro(op_get_by_val, 4) \ - macro(op_get_argument_by_val, 4) \ + macro(op_get_by_val, 5) /* has value profiling */ \ + macro(op_get_argument_by_val, 5) /* must be the same size as op_get_by_val */ \ macro(op_get_by_pname, 7) \ macro(op_put_by_val, 4) \ macro(op_del_by_val, 4) \ macro(op_put_by_index, 4) \ - macro(op_put_getter, 4) \ - macro(op_put_setter, 4) \ + macro(op_put_getter_setter, 5) \ \ macro(op_jmp, 2) \ macro(op_jtrue, 3) \ @@ -145,34 +141,40 @@ namespace JSC { macro(op_jeq_null, 3) \ macro(op_jneq_null, 3) \ macro(op_jneq_ptr, 4) \ - macro(op_jnless, 4) \ - macro(op_jnlesseq, 4) \ macro(op_jless, 4) \ macro(op_jlesseq, 4) \ + macro(op_jgreater, 4) \ + macro(op_jgreatereq, 4) \ + macro(op_jnless, 4) \ + macro(op_jnlesseq, 4) \ + macro(op_jngreater, 4) \ + macro(op_jngreatereq, 4) \ macro(op_jmp_scopes, 3) \ macro(op_loop, 2) \ macro(op_loop_if_true, 3) \ macro(op_loop_if_false, 3) \ macro(op_loop_if_less, 4) \ macro(op_loop_if_lesseq, 4) \ + macro(op_loop_if_greater, 4) \ + macro(op_loop_if_greatereq, 4) \ + macro(op_loop_hint, 1) \ macro(op_switch_imm, 4) \ macro(op_switch_char, 4) \ macro(op_switch_string, 4) \ \ macro(op_new_func, 4) \ macro(op_new_func_exp, 3) \ - macro(op_call, 4) \ - macro(op_call_eval, 4) \ - macro(op_call_varargs, 4) \ - macro(op_load_varargs, 4) \ + macro(op_call, 6) \ + macro(op_call_eval, 6) \ + macro(op_call_varargs, 5) \ macro(op_tear_off_activation, 3) \ macro(op_tear_off_arguments, 2) \ macro(op_ret, 2) \ - macro(op_call_put_result, 2) \ + macro(op_call_put_result, 3) /* has value profiling */ \ macro(op_ret_object_or_this, 3) \ macro(op_method_check, 1) \ \ - macro(op_construct, 4) \ + macro(op_construct, 6) \ macro(op_strcat, 4) \ macro(op_to_primitive, 3) \ \ @@ -187,9 +189,6 @@ namespace JSC { macro(op_throw, 2) \ macro(op_throw_reference_error, 2) \ \ - macro(op_jsr, 3) \ - macro(op_sret, 2) \ - \ macro(op_debug, 4) \ macro(op_profile_will_call, 2) \ macro(op_profile_did_call, 2) \ @@ -200,6 +199,7 @@ namespace JSC { typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID; #undef OPCODE_ID_ENUM + const int maxOpcodeLength = 9; const int numOpcodeIDs = op_end + 1; #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length; @@ -216,7 +216,7 @@ namespace JSC { FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID); #undef VERIFY_OPCODE_ID -#if ENABLE(COMPUTED_GOTO_INTERPRETER) +#if ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER) || ENABLE(LLINT) #if COMPILER(RVCT) || COMPILER(INTEL) typedef void* Opcode; #else @@ -226,8 +226,6 @@ namespace JSC { typedef OpcodeID Opcode; #endif -#if ENABLE(OPCODE_SAMPLING) || ENABLE(CODEBLOCK_SAMPLING) || ENABLE(OPCODE_STATS) - #define PADDING_STRING " " #define PADDING_STRING_LENGTH static_cast(strlen(PADDING_STRING)) @@ -243,8 +241,6 @@ namespace JSC { #undef PADDING_STRING_LENGTH #undef PADDING_STRING -#endif - #if ENABLE(OPCODE_STATS) struct OpcodeStats { diff --git a/bytecode/Operands.h b/bytecode/Operands.h new file mode 100644 index 0000000..a05159f --- /dev/null +++ b/bytecode/Operands.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2011, 2012 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 Operands_h +#define Operands_h + +#include "CallFrame.h" +#include "JSObject.h" +#include "ScopeChain.h" +#include + +namespace JSC { + +// argument 0 is 'this'. +inline bool operandIsArgument(int operand) { return operand < 0; } +inline int operandToArgument(int operand) { return -operand + CallFrame::thisArgumentOffset(); } +inline int argumentToOperand(int argument) { return -argument + CallFrame::thisArgumentOffset(); } + +template struct OperandValueTraits; + +template +struct OperandValueTraits { + static T defaultValue() { return T(); } + static void dump(const T& value, FILE* out) { value.dump(out); } +}; + +template > +class Operands { +public: + Operands() { } + + explicit Operands(size_t numArguments, size_t numLocals) + { + m_arguments.fill(Traits::defaultValue(), numArguments); + m_locals.fill(Traits::defaultValue(), numLocals); + } + + size_t numberOfArguments() const { return m_arguments.size(); } + size_t numberOfLocals() const { return m_locals.size(); } + + T& argument(size_t idx) { return m_arguments[idx]; } + const T& argument(size_t idx) const { return m_arguments[idx]; } + + T& local(size_t idx) { return m_locals[idx]; } + const T& local(size_t idx) const { return m_locals[idx]; } + + void ensureLocals(size_t size) + { + if (size <= m_locals.size()) + return; + + size_t oldSize = m_locals.size(); + m_locals.resize(size); + for (size_t i = oldSize; i < m_locals.size(); ++i) + m_locals[i] = Traits::defaultValue(); + } + + void setLocal(size_t idx, const T& value) + { + ensureLocals(idx + 1); + + m_locals[idx] = value; + } + + T getLocal(size_t idx) + { + if (idx >= m_locals.size()) + return Traits::defaultValue(); + return m_locals[idx]; + } + + void setArgumentFirstTime(size_t idx, const T& value) + { + ASSERT(m_arguments[idx] == Traits::defaultValue()); + argument(idx) = value; + } + + void setLocalFirstTime(size_t idx, const T& value) + { + ASSERT(idx >= m_locals.size() || m_locals[idx] == Traits::defaultValue()); + setLocal(idx, value); + } + + T& operand(int operand) + { + if (operandIsArgument(operand)) { + int argument = operandToArgument(operand); + return m_arguments[argument]; + } + + return m_locals[operand]; + } + + const T& operand(int operand) const { return const_cast(const_cast(this)->operand(operand)); } + + void setOperand(int operand, const T& value) + { + if (operandIsArgument(operand)) { + int argument = operandToArgument(operand); + m_arguments[argument] = value; + return; + } + + setLocal(operand, value); + } + + void clear() + { + for (size_t i = 0; i < m_arguments.size(); ++i) + m_arguments[i] = Traits::defaultValue(); + for (size_t i = 0; i < m_locals.size(); ++i) + m_locals[i] = Traits::defaultValue(); + } + +private: + Vector m_arguments; + Vector m_locals; +}; + +template +void dumpOperands(Operands& operands, FILE* out) +{ + for (size_t argument = 0; argument < operands.numberOfArguments(); ++argument) { + if (argument) + fprintf(out, " "); + Traits::dump(operands.argument(argument), out); + } + fprintf(out, " : "); + for (size_t local = 0; local < operands.numberOfLocals(); ++local) { + if (local) + fprintf(out, " "); + Traits::dump(operands.local(local), out); + } +} + +} // namespace JSC + +#endif // Operands_h + diff --git a/bytecode/PolymorphicPutByIdList.cpp b/bytecode/PolymorphicPutByIdList.cpp new file mode 100644 index 0000000..170615b --- /dev/null +++ b/bytecode/PolymorphicPutByIdList.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2012 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 "PolymorphicPutByIdList.h" + +#if ENABLE(JIT) + +#include "StructureStubInfo.h" + +namespace JSC { + +PutByIdAccess PutByIdAccess::fromStructureStubInfo( + StructureStubInfo& stubInfo, + MacroAssemblerCodePtr initialSlowPath) +{ + PutByIdAccess result; + + switch (stubInfo.accessType) { + case access_put_by_id_replace: + result.m_type = Replace; + result.m_oldStructure.copyFrom(stubInfo.u.putByIdReplace.baseObjectStructure); + result.m_stubRoutine = MacroAssemblerCodeRef::createSelfManagedCodeRef(initialSlowPath); + break; + + case access_put_by_id_transition_direct: + case access_put_by_id_transition_normal: + result.m_type = Transition; + result.m_oldStructure.copyFrom(stubInfo.u.putByIdTransition.previousStructure); + result.m_newStructure.copyFrom(stubInfo.u.putByIdTransition.structure); + result.m_chain.copyFrom(stubInfo.u.putByIdTransition.chain); + result.m_stubRoutine = stubInfo.stubRoutine; + break; + + default: + ASSERT_NOT_REACHED(); + } + + return result; +} + +bool PutByIdAccess::visitWeak() const +{ + switch (m_type) { + case Replace: + if (!Heap::isMarked(m_oldStructure.get())) + return false; + break; + case Transition: + if (!Heap::isMarked(m_oldStructure.get())) + return false; + if (!Heap::isMarked(m_newStructure.get())) + return false; + if (!Heap::isMarked(m_chain.get())) + return false; + break; + default: + ASSERT_NOT_REACHED(); + return false; + } + return true; +} + +PolymorphicPutByIdList::PolymorphicPutByIdList( + PutKind putKind, + StructureStubInfo& stubInfo, + MacroAssemblerCodePtr initialSlowPath) + : m_kind(putKind) +{ + m_list.append(PutByIdAccess::fromStructureStubInfo(stubInfo, initialSlowPath)); +} + +PolymorphicPutByIdList* PolymorphicPutByIdList::from( + PutKind putKind, + StructureStubInfo& stubInfo, + MacroAssemblerCodePtr initialSlowPath) +{ + if (stubInfo.accessType == access_put_by_id_list) + return stubInfo.u.putByIdList.list; + + ASSERT(stubInfo.accessType == access_put_by_id_replace + || stubInfo.accessType == access_put_by_id_transition_normal + || stubInfo.accessType == access_put_by_id_transition_direct); + + PolymorphicPutByIdList* result = + new PolymorphicPutByIdList(putKind, stubInfo, initialSlowPath); + + stubInfo.initPutByIdList(result); + + return result; +} + +PolymorphicPutByIdList::~PolymorphicPutByIdList() { } + +bool PolymorphicPutByIdList::isFull() const +{ + ASSERT(size() <= POLYMORPHIC_LIST_CACHE_SIZE); + return size() == POLYMORPHIC_LIST_CACHE_SIZE; +} + +bool PolymorphicPutByIdList::isAlmostFull() const +{ + ASSERT(size() <= POLYMORPHIC_LIST_CACHE_SIZE); + return size() >= POLYMORPHIC_LIST_CACHE_SIZE - 1; +} + +void PolymorphicPutByIdList::addAccess(const PutByIdAccess& putByIdAccess) +{ + ASSERT(!isFull()); + // Make sure that the resizing optimizes for space, not time. + m_list.resize(m_list.size() + 1); + m_list.last() = putByIdAccess; +} + +bool PolymorphicPutByIdList::visitWeak() const +{ + for (unsigned i = 0; i < size(); ++i) { + if (!at(i).visitWeak()) + return false; + } + return true; +} + +} // namespace JSC + +#endif // ENABLE(JIT) diff --git a/bytecode/PolymorphicPutByIdList.h b/bytecode/PolymorphicPutByIdList.h new file mode 100644 index 0000000..60b632d --- /dev/null +++ b/bytecode/PolymorphicPutByIdList.h @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2012 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 PolymorphicPutByIdList_h +#define PolymorphicPutByIdList_h + +#include + +#if ENABLE(JIT) + +#include "CodeOrigin.h" +#include "MacroAssembler.h" +#include "Opcode.h" +#include "PutKind.h" +#include "Structure.h" +#include + +namespace JSC { + +struct StructureStubInfo; + +class PutByIdAccess { +public: + enum AccessType { + Invalid, + Transition, + Replace + }; + + PutByIdAccess() + : m_type(Invalid) + { + } + + static PutByIdAccess transition( + JSGlobalData& globalData, + JSCell* owner, + Structure* oldStructure, + Structure* newStructure, + StructureChain* chain, + MacroAssemblerCodeRef stubRoutine) + { + PutByIdAccess result; + result.m_type = Transition; + result.m_oldStructure.set(globalData, owner, oldStructure); + result.m_newStructure.set(globalData, owner, newStructure); + result.m_chain.set(globalData, owner, chain); + result.m_stubRoutine = stubRoutine; + return result; + } + + static PutByIdAccess replace( + JSGlobalData& globalData, + JSCell* owner, + Structure* structure, + MacroAssemblerCodeRef stubRoutine) + { + PutByIdAccess result; + result.m_type = Replace; + result.m_oldStructure.set(globalData, owner, structure); + result.m_stubRoutine = stubRoutine; + return result; + } + + static PutByIdAccess fromStructureStubInfo( + StructureStubInfo&, + MacroAssemblerCodePtr initialSlowPath); + + bool isSet() const { return m_type != Invalid; } + bool operator!() const { return !isSet(); } + + AccessType type() const { return m_type; } + + bool isTransition() const { return m_type == Transition; } + bool isReplace() const { return m_type == Replace; } + + Structure* oldStructure() const + { + // Using this instead of isSet() to make this assertion robust against the possibility + // of additional access types being added. + ASSERT(isTransition() || isReplace()); + + return m_oldStructure.get(); + } + + Structure* structure() const + { + ASSERT(isReplace()); + return m_oldStructure.get(); + } + + Structure* newStructure() const + { + ASSERT(isTransition()); + return m_newStructure.get(); + } + + StructureChain* chain() const + { + ASSERT(isTransition()); + return m_chain.get(); + } + + MacroAssemblerCodeRef stubRoutine() const + { + ASSERT(isTransition() || isReplace()); + return m_stubRoutine; + } + + bool visitWeak() const; + +private: + AccessType m_type; + WriteBarrier m_oldStructure; + WriteBarrier m_newStructure; + WriteBarrier m_chain; + MacroAssemblerCodeRef m_stubRoutine; +}; + +class PolymorphicPutByIdList { + WTF_MAKE_FAST_ALLOCATED; +public: + // Initialize from a stub info; this will place one element in the list and it will + // be created by converting the stub info's put by id access information into our + // PutByIdAccess. + PolymorphicPutByIdList( + PutKind, + StructureStubInfo&, + MacroAssemblerCodePtr initialSlowPath); + + // Either creates a new polymorphic put list, or returns the one that is already + // in place. + static PolymorphicPutByIdList* from( + PutKind, + StructureStubInfo&, + MacroAssemblerCodePtr initialSlowPath); + + ~PolymorphicPutByIdList(); + + MacroAssemblerCodePtr currentSlowPathTarget() const + { + return m_list.last().stubRoutine().code(); + } + + void addAccess(const PutByIdAccess&); + + bool isEmpty() const { return m_list.isEmpty(); } + unsigned size() const { return m_list.size(); } + bool isFull() const; + bool isAlmostFull() const; // True if adding an element would make isFull() true. + const PutByIdAccess& at(unsigned i) const { return m_list[i]; } + const PutByIdAccess& operator[](unsigned i) const { return m_list[i]; } + + PutKind kind() const { return m_kind; } + + bool visitWeak() const; + +private: + Vector m_list; + PutKind m_kind; +}; + +} // namespace JSC + +#endif // ENABLE(JIT) + +#endif // PolymorphicPutByIdList_h + diff --git a/bytecode/PredictedType.cpp b/bytecode/PredictedType.cpp new file mode 100644 index 0000000..e8a7177 --- /dev/null +++ b/bytecode/PredictedType.cpp @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2011 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. + * 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. + */ + +#include "config.h" +#include "PredictedType.h" + +#include "JSArray.h" +#include "JSFunction.h" +#include "ValueProfile.h" +#include + +namespace JSC { + +const char* predictionToString(PredictedType value) +{ + if (value == PredictNone) + return "None"; + + static const int size = 256; + static char description[size]; + BoundsCheckedPointer ptr(description, size); + + bool isTop = true; + + if (value & PredictCellOther) + ptr.strcat("Othercell"); + else + isTop = false; + + if (value & PredictObjectOther) + ptr.strcat("Otherobj"); + else + isTop = false; + + if (value & PredictFinalObject) + ptr.strcat("Final"); + else + isTop = false; + + if (value & PredictArray) + ptr.strcat("Array"); + else + isTop = false; + + if (value & PredictInt8Array) + ptr.strcat("Int8array"); + else + isTop = false; + + if (value & PredictInt16Array) + ptr.strcat("Int16array"); + else + isTop = false; + + if (value & PredictInt32Array) + ptr.strcat("Int32array"); + else + isTop = false; + + if (value & PredictUint8Array) + ptr.strcat("Uint8array"); + else + isTop = false; + + if (value & PredictUint8ClampedArray) + ptr.strcat("Uint8clampedarray"); + else + isTop = false; + + if (value & PredictUint16Array) + ptr.strcat("Uint16array"); + else + isTop = false; + + if (value & PredictUint32Array) + ptr.strcat("Uint32array"); + else + isTop = false; + + if (value & PredictFloat32Array) + ptr.strcat("Float32array"); + else + isTop = false; + + if (value & PredictFloat64Array) + ptr.strcat("Float64array"); + else + isTop = false; + + if (value & PredictFunction) + ptr.strcat("Function"); + else + isTop = false; + + if (value & PredictString) + ptr.strcat("String"); + else + isTop = false; + + if (value & PredictInt32) + ptr.strcat("Int"); + else + isTop = false; + + if (value & PredictDoubleReal) + ptr.strcat("Doublereal"); + else + isTop = false; + + if (value & PredictDoubleNaN) + ptr.strcat("Doublenan"); + else + isTop = false; + + if (value & PredictBoolean) + ptr.strcat("Bool"); + else + isTop = false; + + if (value & PredictOther) + ptr.strcat("Other"); + else + isTop = false; + + if (isTop) { + ptr = description; + ptr.strcat("Top"); + } + + if (value & PredictEmpty) + ptr.strcat("Empty"); + + *ptr++ = 0; + + return description; +} + +const char* predictionToAbbreviatedString(PredictedType prediction) +{ + if (isFinalObjectPrediction(prediction)) + return ""; + if (isArrayPrediction(prediction)) + return ""; + if (isStringPrediction(prediction)) + return ""; + if (isFunctionPrediction(prediction)) + return ""; + if (isInt8ArrayPrediction(prediction)) + return ""; + if (isInt16ArrayPrediction(prediction)) + return ""; + if (isInt32ArrayPrediction(prediction)) + return ""; + if (isUint8ArrayPrediction(prediction)) + return ""; + if (isUint16ArrayPrediction(prediction)) + return ""; + if (isUint32ArrayPrediction(prediction)) + return ""; + if (isFloat32ArrayPrediction(prediction)) + return ""; + if (isFloat64ArrayPrediction(prediction)) + return ""; + if (isObjectPrediction(prediction)) + return ""; + if (isCellPrediction(prediction)) + return ""; + if (isInt32Prediction(prediction)) + return ""; + if (isDoublePrediction(prediction)) + return ""; + if (isNumberPrediction(prediction)) + return ""; + if (isBooleanPrediction(prediction)) + return ""; + if (isOtherPrediction(prediction)) + return ""; + return ""; +} + +PredictedType predictionFromClassInfo(const ClassInfo* classInfo) +{ + if (classInfo == &JSFinalObject::s_info) + return PredictFinalObject; + + if (classInfo == &JSArray::s_info) + return PredictArray; + + if (classInfo == &JSString::s_info) + return PredictString; + + if (classInfo->isSubClassOf(&JSFunction::s_info)) + return PredictFunction; + + + if (classInfo->typedArrayStorageType != TypedArrayNone) { + switch (classInfo->typedArrayStorageType) { + case TypedArrayInt8: + return PredictInt8Array; + case TypedArrayInt16: + return PredictInt16Array; + case TypedArrayInt32: + return PredictInt32Array; + case TypedArrayUint8: + return PredictUint8Array; + case TypedArrayUint8Clamped: + return PredictUint8ClampedArray; + case TypedArrayUint16: + return PredictUint16Array; + case TypedArrayUint32: + return PredictUint32Array; + case TypedArrayFloat32: + return PredictFloat32Array; + case TypedArrayFloat64: + return PredictFloat64Array; + default: + break; + } + } + + if (classInfo->isSubClassOf(&JSObject::s_info)) + return PredictObjectOther; + + return PredictCellOther; +} + +PredictedType predictionFromStructure(Structure* structure) +{ + return predictionFromClassInfo(structure->classInfo()); +} + +PredictedType predictionFromCell(JSCell* cell) +{ + return predictionFromStructure(cell->structure()); +} + +PredictedType predictionFromValue(JSValue value) +{ + if (value.isEmpty()) + return PredictEmpty; + if (value.isInt32()) + return PredictInt32; + if (value.isDouble()) { + double number = value.asNumber(); + if (number == number) + return PredictDoubleReal; + return PredictDoubleNaN; + } + if (value.isCell()) + return predictionFromCell(value.asCell()); + if (value.isBoolean()) + return PredictBoolean; + ASSERT(value.isUndefinedOrNull()); + return PredictOther; +} + +} // namespace JSC + diff --git a/bytecode/PredictedType.h b/bytecode/PredictedType.h new file mode 100644 index 0000000..54b3081 --- /dev/null +++ b/bytecode/PredictedType.h @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2011 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. + * 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. + */ + +#ifndef PredictedType_h +#define PredictedType_h + +#include "JSValue.h" + +namespace JSC { + +class Structure; + +typedef uint32_t PredictedType; +static const PredictedType PredictNone = 0x00000000; // We don't know anything yet. +static const PredictedType PredictFinalObject = 0x00000001; // It's definitely a JSFinalObject. +static const PredictedType PredictArray = 0x00000002; // It's definitely a JSArray. +static const PredictedType PredictFunction = 0x00000008; // It's definitely a JSFunction or one of its subclasses. +static const PredictedType PredictInt8Array = 0x00000010; // It's definitely an Int8Array or one of its subclasses. +static const PredictedType PredictInt16Array = 0x00000020; // It's definitely an Int16Array or one of its subclasses. +static const PredictedType PredictInt32Array = 0x00000040; // It's definitely an Int32Array or one of its subclasses. +static const PredictedType PredictUint8Array = 0x00000080; // It's definitely an Uint8Array or one of its subclasses. +static const PredictedType PredictUint8ClampedArray = 0x00000100; // It's definitely an Uint8ClampedArray or one of its subclasses. +static const PredictedType PredictUint16Array = 0x00000200; // It's definitely an Uint16Array or one of its subclasses. +static const PredictedType PredictUint32Array = 0x00000400; // It's definitely an Uint32Array or one of its subclasses. +static const PredictedType PredictFloat32Array = 0x00000800; // It's definitely an Uint16Array or one of its subclasses. +static const PredictedType PredictFloat64Array = 0x00001000; // It's definitely an Uint16Array or one of its subclasses. +static const PredictedType PredictObjectOther = 0x00002000; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction. +static const PredictedType PredictObjectMask = 0x00003fff; // Bitmask used for testing for any kind of object prediction. +static const PredictedType PredictString = 0x00004000; // It's definitely a JSString. +static const PredictedType PredictCellOther = 0x00008000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString. +static const PredictedType PredictCell = 0x0000ffff; // It's definitely a JSCell. +static const PredictedType PredictInt32 = 0x00010000; // It's definitely an Int32. +static const PredictedType PredictDoubleReal = 0x00020000; // It's definitely a non-NaN double. +static const PredictedType PredictDoubleNaN = 0x00040000; // It's definitely a NaN. +static const PredictedType PredictDouble = 0x00060000; // It's either a non-NaN or a NaN double. +static const PredictedType PredictNumber = 0x00070000; // It's either an Int32 or a Double. +static const PredictedType PredictBoolean = 0x00080000; // It's definitely a Boolean. +static const PredictedType PredictOther = 0x08000000; // It's definitely none of the above. +static const PredictedType PredictTop = 0x0fffffff; // It can be any of the above. +static const PredictedType PredictEmpty = 0x10000000; // It's definitely an empty value marker. +static const PredictedType PredictEmptyOrTop = 0x1fffffff; // It can be any of the above. +static const PredictedType FixedIndexedStorageMask = PredictInt8Array | PredictInt16Array | PredictInt32Array | PredictUint8Array | PredictUint8ClampedArray | PredictUint16Array | PredictUint32Array | PredictFloat32Array | PredictFloat64Array; + +typedef bool (*PredictionChecker)(PredictedType); + +inline bool isCellPrediction(PredictedType value) +{ + return !!(value & PredictCell) && !(value & ~PredictCell); +} + +inline bool isObjectPrediction(PredictedType value) +{ + return !!(value & PredictObjectMask) && !(value & ~PredictObjectMask); +} + +inline bool isFinalObjectPrediction(PredictedType value) +{ + return value == PredictFinalObject; +} + +inline bool isFinalObjectOrOtherPrediction(PredictedType value) +{ + return !!(value & (PredictFinalObject | PredictOther)) && !(value & ~(PredictFinalObject | PredictOther)); +} + +inline bool isFixedIndexedStorageObjectPrediction(PredictedType value) +{ + return !!value && (value & FixedIndexedStorageMask) == value; +} + +inline bool isStringPrediction(PredictedType value) +{ + return value == PredictString; +} + +inline bool isArrayPrediction(PredictedType value) +{ + return value == PredictArray; +} + +inline bool isFunctionPrediction(PredictedType value) +{ + return value == PredictFunction; +} + +inline bool isInt8ArrayPrediction(PredictedType value) +{ + return value == PredictInt8Array; +} + +inline bool isInt16ArrayPrediction(PredictedType value) +{ + return value == PredictInt16Array; +} + +inline bool isInt32ArrayPrediction(PredictedType value) +{ + return value == PredictInt32Array; +} + +inline bool isUint8ArrayPrediction(PredictedType value) +{ + return value == PredictUint8Array; +} + +inline bool isUint8ClampedArrayPrediction(PredictedType value) +{ + return value == PredictUint8ClampedArray; +} + +inline bool isUint16ArrayPrediction(PredictedType value) +{ + return value == PredictUint16Array; +} + +inline bool isUint32ArrayPrediction(PredictedType value) +{ + return value == PredictUint32Array; +} + +inline bool isFloat32ArrayPrediction(PredictedType value) +{ + return value == PredictFloat32Array; +} + +inline bool isFloat64ArrayPrediction(PredictedType value) +{ + return value == PredictFloat64Array; +} + +inline bool isActionableIntMutableArrayPrediction(PredictedType value) +{ + return isInt8ArrayPrediction(value) + || isInt16ArrayPrediction(value) + || isInt32ArrayPrediction(value) + || isUint8ArrayPrediction(value) + || isUint8ClampedArrayPrediction(value) + || isUint16ArrayPrediction(value) + || isUint32ArrayPrediction(value); +} + +inline bool isActionableFloatMutableArrayPrediction(PredictedType value) +{ + return isFloat32ArrayPrediction(value) + || isFloat64ArrayPrediction(value); +} + +inline bool isActionableTypedMutableArrayPrediction(PredictedType value) +{ + return isActionableIntMutableArrayPrediction(value) + || isActionableFloatMutableArrayPrediction(value); +} + +inline bool isActionableMutableArrayPrediction(PredictedType value) +{ + return isArrayPrediction(value) + || isActionableTypedMutableArrayPrediction(value); +} + +inline bool isActionableArrayPrediction(PredictedType value) +{ + return isStringPrediction(value) + || isActionableMutableArrayPrediction(value); +} + +inline bool isArrayOrOtherPrediction(PredictedType value) +{ + return !!(value & (PredictArray | PredictOther)) && !(value & ~(PredictArray | PredictOther)); +} + +inline bool isInt32Prediction(PredictedType value) +{ + return value == PredictInt32; +} + +inline bool isDoubleRealPrediction(PredictedType value) +{ + return value == PredictDoubleReal; +} + +inline bool isDoublePrediction(PredictedType value) +{ + return !!value && (value & PredictDouble) == value; +} + +inline bool isNumberPrediction(PredictedType value) +{ + return !!(value & PredictNumber) && !(value & ~PredictNumber); +} + +inline bool isBooleanPrediction(PredictedType value) +{ + return value == PredictBoolean; +} + +inline bool isOtherPrediction(PredictedType value) +{ + return value == PredictOther; +} + +inline bool isEmptyPrediction(PredictedType value) +{ + return value == PredictEmpty; +} + +const char* predictionToString(PredictedType value); +const char* predictionToAbbreviatedString(PredictedType value); + +// Merge two predictions. Note that currently this just does left | right. It may +// seem tempting to do so directly, but you would be doing so at your own peril, +// since the merging protocol PredictedType may change at any time (and has already +// changed several times in its history). +inline PredictedType mergePredictions(PredictedType left, PredictedType right) +{ + return left | right; +} + +template +inline bool mergePrediction(T& left, PredictedType right) +{ + PredictedType newPrediction = static_cast(mergePredictions(static_cast(left), right)); + bool result = newPrediction != static_cast(left); + left = newPrediction; + return result; +} + +PredictedType predictionFromClassInfo(const ClassInfo*); +PredictedType predictionFromStructure(Structure*); +PredictedType predictionFromCell(JSCell*); +PredictedType predictionFromValue(JSValue); + +} // namespace JSC + +#endif // PredictedType_h diff --git a/bytecode/PutByIdStatus.cpp b/bytecode/PutByIdStatus.cpp new file mode 100644 index 0000000..209d4cd --- /dev/null +++ b/bytecode/PutByIdStatus.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2012 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 "PutByIdStatus.h" + +#include "CodeBlock.h" +#include "LowLevelInterpreter.h" +#include "Structure.h" +#include "StructureChain.h" + +namespace JSC { + +PutByIdStatus PutByIdStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident) +{ + UNUSED_PARAM(profiledBlock); + UNUSED_PARAM(bytecodeIndex); + UNUSED_PARAM(ident); +#if ENABLE(LLINT) + Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex; + + Structure* structure = instruction[4].u.structure.get(); + if (!structure) + return PutByIdStatus(NoInformation, 0, 0, 0, notFound); + + if (instruction[0].u.opcode == llint_op_put_by_id) { + size_t offset = structure->get(*profiledBlock->globalData(), ident); + if (offset == notFound) + return PutByIdStatus(NoInformation, 0, 0, 0, notFound); + + return PutByIdStatus(SimpleReplace, structure, 0, 0, offset); + } + + ASSERT(instruction[0].u.opcode == llint_op_put_by_id_transition_direct + || instruction[0].u.opcode == llint_op_put_by_id_transition_normal); + + Structure* newStructure = instruction[6].u.structure.get(); + StructureChain* chain = instruction[7].u.structureChain.get(); + ASSERT(newStructure); + ASSERT(chain); + + size_t offset = newStructure->get(*profiledBlock->globalData(), ident); + if (offset == notFound) + return PutByIdStatus(NoInformation, 0, 0, 0, notFound); + + return PutByIdStatus(SimpleTransition, structure, newStructure, chain, offset); +#else + return PutByIdStatus(NoInformation, 0, 0, 0, notFound); +#endif +} + +PutByIdStatus PutByIdStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex, Identifier& ident) +{ + UNUSED_PARAM(profiledBlock); + UNUSED_PARAM(bytecodeIndex); + UNUSED_PARAM(ident); +#if ENABLE(JIT) && ENABLE(VALUE_PROFILER) + if (!profiledBlock->numberOfStructureStubInfos()) + return computeFromLLInt(profiledBlock, bytecodeIndex, ident); + + if (profiledBlock->likelyToTakeSlowCase(bytecodeIndex)) + return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound); + + StructureStubInfo& stubInfo = profiledBlock->getStubInfo(bytecodeIndex); + if (!stubInfo.seen) + return computeFromLLInt(profiledBlock, bytecodeIndex, ident); + + switch (stubInfo.accessType) { + case access_unset: + return computeFromLLInt(profiledBlock, bytecodeIndex, ident); + + case access_put_by_id_replace: { + size_t offset = stubInfo.u.putByIdReplace.baseObjectStructure->get( + *profiledBlock->globalData(), ident); + if (offset != notFound) { + return PutByIdStatus( + SimpleReplace, + stubInfo.u.putByIdReplace.baseObjectStructure.get(), + 0, 0, + offset); + } + return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound); + } + + case access_put_by_id_transition_normal: + case access_put_by_id_transition_direct: { + size_t offset = stubInfo.u.putByIdTransition.structure->get( + *profiledBlock->globalData(), ident); + if (offset != notFound) { + return PutByIdStatus( + SimpleTransition, + stubInfo.u.putByIdTransition.previousStructure.get(), + stubInfo.u.putByIdTransition.structure.get(), + stubInfo.u.putByIdTransition.chain.get(), + offset); + } + return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound); + } + + default: + return PutByIdStatus(TakesSlowPath, 0, 0, 0, notFound); + } +#else // ENABLE(JIT) + return PutByIdStatus(NoInformation, 0, 0, 0, notFound); +#endif // ENABLE(JIT) +} + +} // namespace JSC + diff --git a/bytecode/PutByIdStatus.h b/bytecode/PutByIdStatus.h new file mode 100644 index 0000000..a6d95a4 --- /dev/null +++ b/bytecode/PutByIdStatus.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2012 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 PutByIdStatus_h +#define PutByIdStatus_h + +#include + +namespace JSC { + +class CodeBlock; +class Identifier; +class Structure; +class StructureChain; + +class PutByIdStatus { +public: + enum State { + // It's uncached so we have no information. + NoInformation, + // It's cached as a direct store into an object property for cases where the object + // already has the property. + SimpleReplace, + // It's cached as a transition from one structure that lacks the property to one that + // includes the property, and a direct store to this new property. + SimpleTransition, + // It's known to often take slow path. + TakesSlowPath + }; + + PutByIdStatus() + : m_state(NoInformation) + , m_oldStructure(0) + , m_newStructure(0) + , m_structureChain(0) + , m_offset(notFound) + { + } + + PutByIdStatus( + State state, + Structure* oldStructure, + Structure* newStructure, + StructureChain* structureChain, + size_t offset) + : m_state(state) + , m_oldStructure(oldStructure) + , m_newStructure(newStructure) + , m_structureChain(structureChain) + , m_offset(offset) + { + ASSERT((m_state == NoInformation || m_state == TakesSlowPath) == !m_oldStructure); + ASSERT((m_state != SimpleTransition) == !m_newStructure); + ASSERT((m_state != SimpleTransition) == !m_structureChain); + ASSERT((m_state == NoInformation || m_state == TakesSlowPath) == (m_offset == notFound)); + } + + static PutByIdStatus computeFor(CodeBlock*, unsigned bytecodeIndex, Identifier&); + + State state() const { return m_state; } + + bool isSet() const { return m_state != NoInformation; } + bool operator!() const { return m_state == NoInformation; } + bool isSimpleReplace() const { return m_state == SimpleReplace; } + bool isSimpleTransition() const { return m_state == SimpleTransition; } + bool takesSlowPath() const { return m_state == TakesSlowPath; } + + Structure* oldStructure() const { return m_oldStructure; } + Structure* newStructure() const { return m_newStructure; } + StructureChain* structureChain() const { return m_structureChain; } + size_t offset() const { return m_offset; } + +private: + static PutByIdStatus computeFromLLInt(CodeBlock*, unsigned bytecodeIndex, Identifier&); + + State m_state; + Structure* m_oldStructure; + Structure* m_newStructure; + StructureChain* m_structureChain; + size_t m_offset; +}; + +} // namespace JSC + +#endif // PutByIdStatus_h + diff --git a/bytecode/PutKind.h b/bytecode/PutKind.h new file mode 100644 index 0000000..7a1dd64 --- /dev/null +++ b/bytecode/PutKind.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2012 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 PutKind_h +#define PutKind_h + +namespace JSC { + +enum PutKind { Direct, NotDirect }; + +} // namespace JSC + +#endif // PutKind_h + diff --git a/bytecode/SamplingTool.cpp b/bytecode/SamplingTool.cpp index f47e698..f07dc79 100644 --- a/bytecode/SamplingTool.cpp +++ b/bytecode/SamplingTool.cpp @@ -67,14 +67,14 @@ void SamplingFlags::stop() total += s_flagCounts[i]; if (total) { - printf("\nSamplingFlags: sample counts with flags set: (%lld total)\n", total); + dataLog("\nSamplingFlags: sample counts with flags set: (%lld total)\n", total); for (unsigned i = 0; i <= 32; ++i) { if (s_flagCounts[i]) - printf(" [ %02d ] : %lld\t\t(%03.2f%%)\n", i, s_flagCounts[i], (100.0 * s_flagCounts[i]) / total); + dataLog(" [ %02d ] : %lld\t\t(%03.2f%%)\n", i, s_flagCounts[i], (100.0 * s_flagCounts[i]) / total); } - printf("\n"); + dataLog("\n"); } else - printf("\nSamplingFlags: no samples.\n\n"); + dataLog("\nSamplingFlags: no samples.\n\n"); } uint64_t SamplingFlags::s_flagCounts[33]; @@ -83,6 +83,93 @@ void SamplingFlags::start() {} void SamplingFlags::stop() {} #endif +#if ENABLE(SAMPLING_REGIONS) +volatile uintptr_t SamplingRegion::s_currentOrReserved; +Spectrum* SamplingRegion::s_spectrum; +unsigned long SamplingRegion::s_noneOfTheAbove; +unsigned SamplingRegion::s_numberOfSamplesSinceDump; + +SamplingRegion::Locker::Locker() +{ + uintptr_t previous; + while (true) { + previous = s_currentOrReserved; + if (previous & 1) { +#if OS(UNIX) + sched_yield(); +#endif + continue; + } + if (WTF::weakCompareAndSwapUIntPtr(&s_currentOrReserved, previous, previous | 1)) + break; + } +} + +SamplingRegion::Locker::~Locker() +{ + // We don't need the CAS, but we do it out of an + // abundance of caution (and because it gives us a memory fence, which is + // never bad). + uintptr_t previous; + do { + previous = s_currentOrReserved; + } while (!WTF::weakCompareAndSwapUIntPtr(&s_currentOrReserved, previous, previous & ~1)); +} + +void SamplingRegion::sample() +{ + // Make sure we lock s_current. + Locker locker; + + // Create a spectrum if we don't have one already. + if (!s_spectrum) + s_spectrum = new Spectrum(); + + ASSERT(s_currentOrReserved & 1); + + // Walk the region stack, and record each region we see. + SamplingRegion* region = bitwise_cast(s_currentOrReserved & ~1); + if (region) { + for (; region; region = region->m_previous) + s_spectrum->add(region->m_name); + } else + s_noneOfTheAbove++; + + if (s_numberOfSamplesSinceDump++ == SamplingThread::s_hertz) { + s_numberOfSamplesSinceDump = 0; + dumpInternal(); + } +} + +void SamplingRegion::dump() +{ + Locker locker; + + dumpInternal(); +} + +void SamplingRegion::dumpInternal() +{ + if (!s_spectrum) { + dataLog("\nSamplingRegion: was never sampled.\n\n"); + return; + } + + Vector::KeyAndCount> list = s_spectrum->buildList(); + + unsigned long total = s_noneOfTheAbove; + for (unsigned i = list.size(); i--;) + total += list[i].count; + + dataLog("\nSamplingRegion: sample counts for regions: (%lu samples)\n", total); + + for (unsigned i = list.size(); i--;) + dataLog(" %3.2lf%% %s\n", (100.0 * list[i].count) / total, list[i].key); +} +#else // ENABLE(SAMPLING_REGIONS) +void SamplingRegion::dump() { } +#endif // ENABLE(SAMPLING_REGIONS) + /* Start with flag 16 set. By doing this the monitoring of lower valued flags will be masked out @@ -123,7 +210,7 @@ bool SamplingThread::s_running = false; unsigned SamplingThread::s_hertz = 10000; ThreadIdentifier SamplingThread::s_samplingThread; -void* SamplingThread::threadStartFunc(void*) +void SamplingThread::threadStartFunc(void*) { while (s_running) { sleepForMicroseconds(hertz2us(s_hertz)); @@ -131,12 +218,13 @@ void* SamplingThread::threadStartFunc(void*) #if ENABLE(SAMPLING_FLAGS) SamplingFlags::sample(); #endif +#if ENABLE(SAMPLING_REGIONS) + SamplingRegion::sample(); +#endif #if ENABLE(OPCODE_SAMPLING) SamplingTool::sample(); #endif } - - return 0; } @@ -153,7 +241,7 @@ void SamplingThread::stop() { ASSERT(s_running); s_running = false; - waitForThreadCompletion(s_samplingThread, 0); + waitForThreadCompletion(s_samplingThread); } @@ -209,12 +297,13 @@ void SamplingTool::sample() s_samplingTool->doRun(); } -void SamplingTool::notifyOfScope(ScriptExecutable* script) +void SamplingTool::notifyOfScope(JSGlobalData& globalData, ScriptExecutable* script) { #if ENABLE(CODEBLOCK_SAMPLING) MutexLocker locker(m_scriptSampleMapMutex); - m_scopeSampleMap->set(script, new ScriptSampleRecord(script)); + m_scopeSampleMap->set(script, adoptPtr(new ScriptSampleRecord(globalData, script))); #else + UNUSED_PARAM(globalData); UNUSED_PARAM(script); #endif } @@ -282,10 +371,10 @@ void SamplingTool::dump(ExecState* exec) // (2) Print Opcode sampling results. - printf("\nBytecode samples [*]\n"); - printf(" sample %% of %% of | cti cti %%\n"); - printf("opcode count VM total | count of self\n"); - printf("------------------------------------------------------- | ----------------\n"); + dataLog("\nBytecode samples [*]\n"); + dataLog(" sample %% of %% of | cti cti %%\n"); + dataLog("opcode count VM total | count of self\n"); + dataLog("------------------------------------------------------- | ----------------\n"); for (int i = 0; i < numOpcodeIDs; ++i) { long long count = opcodeSampleInfo[i].count; @@ -300,18 +389,18 @@ void SamplingTool::dump(ExecState* exec) double percentOfTotal = (static_cast(count) * 100) / m_sampleCount; long long countInCTIFunctions = opcodeSampleInfo[i].countInCTIFunctions; double percentInCTIFunctions = (static_cast(countInCTIFunctions) * 100) / count; - fprintf(stdout, "%s:%s%-6lld %.3f%%\t%.3f%%\t | %-6lld %.3f%%\n", opcodeName, opcodePadding, count, percentOfVM, percentOfTotal, countInCTIFunctions, percentInCTIFunctions); + debugDebugPrintf("%s:%s%-6lld %.3f%%\t%.3f%%\t | %-6lld %.3f%%\n", opcodeName, opcodePadding, count, percentOfVM, percentOfTotal, countInCTIFunctions, percentInCTIFunctions); } - printf("\n[*] Samples inside host code are not charged to any Bytecode.\n\n"); - printf("\tSamples inside VM:\t\t%lld / %lld (%.3f%%)\n", m_opcodeSampleCount, m_sampleCount, (static_cast(m_opcodeSampleCount) * 100) / m_sampleCount); - printf("\tSamples inside host code:\t%lld / %lld (%.3f%%)\n\n", m_sampleCount - m_opcodeSampleCount, m_sampleCount, (static_cast(m_sampleCount - m_opcodeSampleCount) * 100) / m_sampleCount); - printf("\tsample count:\tsamples inside this opcode\n"); - printf("\t%% of VM:\tsample count / all opcode samples\n"); - printf("\t%% of total:\tsample count / all samples\n"); - printf("\t--------------\n"); - printf("\tcti count:\tsamples inside a CTI function called by this opcode\n"); - printf("\tcti %% of self:\tcti count / sample count\n"); + dataLog("\n[*] Samples inside host code are not charged to any Bytecode.\n\n"); + dataLog("\tSamples inside VM:\t\t%lld / %lld (%.3f%%)\n", m_opcodeSampleCount, m_sampleCount, (static_cast(m_opcodeSampleCount) * 100) / m_sampleCount); + dataLog("\tSamples inside host code:\t%lld / %lld (%.3f%%)\n\n", m_sampleCount - m_opcodeSampleCount, m_sampleCount, (static_cast(m_sampleCount - m_opcodeSampleCount) * 100) / m_sampleCount); + dataLog("\tsample count:\tsamples inside this opcode\n"); + dataLog("\t%% of VM:\tsample count / all opcode samples\n"); + dataLog("\t%% of total:\tsample count / all samples\n"); + dataLog("\t--------------\n"); + dataLog("\tcti count:\tsamples inside a CTI function called by this opcode\n"); + dataLog("\tcti %% of self:\tcti count / sample count\n"); #if ENABLE(CODEBLOCK_SAMPLING) @@ -321,13 +410,13 @@ void SamplingTool::dump(ExecState* exec) Vector codeBlockSamples(scopeCount); ScriptSampleRecordMap::iterator iter = m_scopeSampleMap->begin(); for (int i = 0; i < scopeCount; ++i, ++iter) - codeBlockSamples[i] = iter->second; + codeBlockSamples[i] = iter->second.get(); qsort(codeBlockSamples.begin(), scopeCount, sizeof(ScriptSampleRecord*), compareScriptSampleRecords); // (4) Print data from 'codeBlockSamples' array. - printf("\nCodeBlock samples\n\n"); + dataLog("\nCodeBlock samples\n\n"); for (int i = 0; i < scopeCount; ++i) { ScriptSampleRecord* record = codeBlockSamples[i]; @@ -337,21 +426,21 @@ void SamplingTool::dump(ExecState* exec) if (blockPercent >= 1) { //Instruction* code = codeBlock->instructions().begin(); - printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().utf8().data(), codeBlock->lineNumberForBytecodeOffset(0), record->m_sampleCount, m_sampleCount, blockPercent); + dataLog("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().utf8().data(), codeBlock->lineNumberForBytecodeOffset(0), record->m_sampleCount, m_sampleCount, blockPercent); if (i < 10) { HashMap lineCounts; codeBlock->dump(exec); - printf(" Opcode and line number samples [*]\n\n"); + dataLog(" Opcode and line number samples [*]\n\n"); for (unsigned op = 0; op < record->m_size; ++op) { int count = record->m_samples[op]; if (count) { - printf(" [% 4d] has sample count: % 4d\n", op, count); + dataLog(" [% 4d] has sample count: % 4d\n", op, count); unsigned line = codeBlock->lineNumberForBytecodeOffset(op); lineCounts.set(line, (lineCounts.contains(line) ? lineCounts.get(line) : 0) + count); } } - printf("\n"); + dataLog("\n"); int linesCount = lineCounts.size(); Vector lineCountInfo(linesCount); @@ -364,12 +453,12 @@ void SamplingTool::dump(ExecState* exec) qsort(lineCountInfo.begin(), linesCount, sizeof(LineCountInfo), compareLineCountInfoSampling); for (lineno = 0; lineno < linesCount; ++lineno) { - printf(" Line #%d has sample count %d.\n", lineCountInfo[lineno].line, lineCountInfo[lineno].count); + dataLog(" Line #%d has sample count %d.\n", lineCountInfo[lineno].line, lineCountInfo[lineno].count); } - printf("\n"); - printf(" [*] Samples inside host code are charged to the calling Bytecode.\n"); - printf(" Samples on a call / return boundary are not charged to a specific opcode or line.\n\n"); - printf(" Samples on a call / return boundary: %d / %d (%.3f%%)\n\n", record->m_sampleCount - record->m_opcodeSampleCount, record->m_sampleCount, (static_cast(record->m_sampleCount - record->m_opcodeSampleCount) * 100) / record->m_sampleCount); + dataLog("\n"); + dataLog(" [*] Samples inside host code are charged to the calling Bytecode.\n"); + dataLog(" Samples on a call / return boundary are not charged to a specific opcode or line.\n\n"); + dataLog(" Samples on a call / return boundary: %d / %d (%.3f%%)\n\n", record->m_sampleCount - record->m_opcodeSampleCount, record->m_sampleCount, (static_cast(record->m_sampleCount - record->m_opcodeSampleCount) * 100) / record->m_sampleCount); } } } @@ -386,21 +475,4 @@ void SamplingTool::dump(ExecState*) #endif -void AbstractSamplingCounter::dump() -{ -#if ENABLE(SAMPLING_COUNTERS) - if (s_abstractSamplingCounterChain != &s_abstractSamplingCounterChainEnd) { - printf("\nSampling Counter Values:\n"); - for (AbstractSamplingCounter* currCounter = s_abstractSamplingCounterChain; (currCounter != &s_abstractSamplingCounterChainEnd); currCounter = currCounter->m_next) - printf("\t%s\t: %lld\n", currCounter->m_name, currCounter->m_counter); - printf("\n\n"); - } - s_completed = true; -#endif -} - -AbstractSamplingCounter AbstractSamplingCounter::s_abstractSamplingCounterChainEnd; -AbstractSamplingCounter* AbstractSamplingCounter::s_abstractSamplingCounterChain = &s_abstractSamplingCounterChainEnd; -bool AbstractSamplingCounter::s_completed = false; - } // namespace JSC diff --git a/bytecode/SamplingTool.h b/bytecode/SamplingTool.h index 1d77b31..52a6e35 100644 --- a/bytecode/SamplingTool.h +++ b/bytecode/SamplingTool.h @@ -32,8 +32,11 @@ #include "Strong.h" #include "Nodes.h" #include "Opcode.h" +#include "SamplingCounter.h" #include +#include #include +#include #include namespace JSC { @@ -42,8 +45,8 @@ namespace JSC { class SamplingFlags { public: - static void start(); - static void stop(); + JS_EXPORT_PRIVATE static void start(); + JS_EXPORT_PRIVATE static void stop(); #if ENABLE(SAMPLING_FLAGS) static void setFlag(unsigned flag) @@ -86,12 +89,95 @@ namespace JSC { #endif private: - static uint32_t s_flags; + JS_EXPORTDATA static uint32_t s_flags; #if ENABLE(SAMPLING_FLAGS) static uint64_t s_flagCounts[33]; #endif }; +#if ENABLE(SAMPLING_REGIONS) + class SamplingRegion { + public: + // Create a scoped sampling region using a C string constant name that describes + // what you are doing. This must be a string constant that persists for the + // lifetime of the process and is immutable. + SamplingRegion(const char* name) + { + if (!isMainThread()) { + m_name = 0; + return; + } + + m_name = name; + exchangeCurrent(this, &m_previous); + ASSERT(!m_previous || m_previous > this); + } + + ~SamplingRegion() + { + if (!m_name) + return; + + ASSERT(bitwise_cast(s_currentOrReserved & ~1) == this); + exchangeCurrent(m_previous); + } + + static void sample(); + + JS_EXPORT_PRIVATE static void dump(); + + private: + const char* m_name; + SamplingRegion* m_previous; + + static void exchangeCurrent(SamplingRegion* current, SamplingRegion** previousPtr = 0) + { + uintptr_t previous; + while (true) { + previous = s_currentOrReserved; + + // If it's reserved (i.e. sampling thread is reading it), loop around. + if (previous & 1) { +#if OS(UNIX) + sched_yield(); +#endif + continue; + } + + // If we're going to CAS, then make sure previous is set. + if (previousPtr) + *previousPtr = bitwise_cast(previous); + + if (WTF::weakCompareAndSwapUIntPtr(&s_currentOrReserved, previous, bitwise_cast(current))) + break; + } + } + + static void dumpInternal(); + + class Locker { + public: + Locker(); + ~Locker(); + }; + + static volatile uintptr_t s_currentOrReserved; + + // rely on identity hashing of string constants + static Spectrum* s_spectrum; + + static unsigned long s_noneOfTheAbove; + + static unsigned s_numberOfSamplesSinceDump; + }; +#else // ENABLE(SAMPLING_REGIONS) + class SamplingRegion { + public: + SamplingRegion(const char*) { } + JS_EXPORT_PRIVATE void dump(); + }; +#endif // ENABLE(SAMPLING_REGIONS) + class CodeBlock; class ExecState; class Interpreter; @@ -125,7 +211,7 @@ namespace JSC { unsigned m_size; }; - typedef WTF::HashMap ScriptSampleRecordMap; + typedef HashMap > ScriptSampleRecordMap; class SamplingThread { public: @@ -134,10 +220,10 @@ namespace JSC { static unsigned s_hertz; static ThreadIdentifier s_samplingThread; - static void start(unsigned hertz=10000); - static void stop(); + JS_EXPORT_PRIVATE static void start(unsigned hertz=10000); + JS_EXPORT_PRIVATE static void stop(); - static void* threadStartFunc(void*); + static void threadStartFunc(void*); }; class SamplingTool { @@ -201,24 +287,17 @@ namespace JSC { , m_sampleCount(0) , m_opcodeSampleCount(0) #if ENABLE(CODEBLOCK_SAMPLING) - , m_scopeSampleMap(new ScriptSampleRecordMap()) + , m_scopeSampleMap(adoptPtr(new ScriptSampleRecordMap)) #endif { memset(m_opcodeSamples, 0, sizeof(m_opcodeSamples)); memset(m_opcodeSamplesInCTIFunctions, 0, sizeof(m_opcodeSamplesInCTIFunctions)); } - ~SamplingTool() - { -#if ENABLE(CODEBLOCK_SAMPLING) - deleteAllValues(*m_scopeSampleMap); -#endif - } - - void setup(); + JS_EXPORT_PRIVATE void setup(); void dump(ExecState*); - void notifyOfScope(ScriptExecutable* scope); + void notifyOfScope(JSGlobalData&, ScriptExecutable* scope); void sample(CodeBlock* codeBlock, Instruction* vPC) { @@ -279,143 +358,6 @@ namespace JSC { #endif }; - // AbstractSamplingCounter: - // - // Implements a named set of counters, printed on exit if ENABLE(SAMPLING_COUNTERS). - // See subclasses below, SamplingCounter, GlobalSamplingCounter and DeletableSamplingCounter. - class AbstractSamplingCounter { - friend class DeletableSamplingCounter; - public: - void count(uint32_t count = 1) - { - m_counter += count; - } - - static void dump(); - - int64_t* addressOfCounter() { return &m_counter; } - - protected: - // Effectively the contructor, however called lazily in the case of GlobalSamplingCounter. - void init(const char* name) - { - m_counter = 0; - m_name = name; - - // Set m_next to point to the head of the chain, and inform whatever is - // currently at the head that this node will now hold the pointer to it. - m_next = s_abstractSamplingCounterChain; - s_abstractSamplingCounterChain->m_referer = &m_next; - // Add this node to the head of the list. - s_abstractSamplingCounterChain = this; - m_referer = &s_abstractSamplingCounterChain; - } - - int64_t m_counter; - const char* m_name; - AbstractSamplingCounter* m_next; - // This is a pointer to the pointer to this node in the chain; used to - // allow fast linked list deletion. - AbstractSamplingCounter** m_referer; - // Null object used to detect end of static chain. - static AbstractSamplingCounter s_abstractSamplingCounterChainEnd; - static AbstractSamplingCounter* s_abstractSamplingCounterChain; - static bool s_completed; - }; - -#if ENABLE(SAMPLING_COUNTERS) - // SamplingCounter: - // - // This class is suitable and (hopefully!) convenient for cases where a counter is - // required within the scope of a single function. It can be instantiated as a - // static variable since it contains a constructor but not a destructor (static - // variables in WebKit cannot have destructors). - // - // For example: - // - // void someFunction() - // { - // static SamplingCounter countMe("This is my counter. There are many like it, but this one is mine."); - // countMe.count(); - // // ... - // } - // - class SamplingCounter : public AbstractSamplingCounter { - public: - SamplingCounter(const char* name) { init(name); } - }; - - // GlobalSamplingCounter: - // - // This class is suitable for use where a counter is to be declared globally, - // since it contains neither a constructor nor destructor. Instead, ensure - // that 'name()' is called to provide the counter with a name (and also to - // allow it to be printed out on exit). - // - // GlobalSamplingCounter globalCounter; - // - // void firstFunction() - // { - // // Put this within a function that is definitely called! - // // (Or alternatively alongside all calls to 'count()'). - // globalCounter.name("I Name You Destroyer."); - // globalCounter.count(); - // // ... - // } - // - // void secondFunction() - // { - // globalCounter.count(); - // // ... - // } - // - class GlobalSamplingCounter : public AbstractSamplingCounter { - public: - void name(const char* name) - { - // Global objects should be mapped in zero filled memory, so this should - // be a safe (albeit not necessarily threadsafe) check for 'first call'. - if (!m_next) - init(name); - } - }; - - // DeletableSamplingCounter: - // - // The above classes (SamplingCounter, GlobalSamplingCounter), are intended for - // use within a global or static scope, and as such cannot have a destructor. - // This means there is no convenient way for them to remove themselves from the - // static list of counters, and should an instance of either class be freed - // before 'dump()' has walked over the list it will potentially walk over an - // invalid pointer. - // - // This class is intended for use where the counter may possibly be deleted before - // the program exits. Should this occur, the counter will print it's value to - // stderr, and remove itself from the static list. Example: - // - // DeletableSamplingCounter* counter = new DeletableSamplingCounter("The Counter With No Name"); - // counter->count(); - // delete counter; - // - class DeletableSamplingCounter : public AbstractSamplingCounter { - public: - DeletableSamplingCounter(const char* name) { init(name); } - - ~DeletableSamplingCounter() - { - if (!s_completed) - fprintf(stderr, "DeletableSamplingCounter \"%s\" deleted early (with count %lld)\n", m_name, m_counter); - // Our m_referer pointer should know where the pointer to this node is, - // and m_next should know that this node is the previous node in the list. - ASSERT(*m_referer == this); - ASSERT(m_next->m_referer == &m_next); - // Remove this node from the list, and inform m_next that we have done so. - m_next->m_referer = m_referer; - *m_referer = m_next; - } - }; -#endif - } // namespace JSC #endif // SamplingTool_h diff --git a/bytecode/StructureSet.h b/bytecode/StructureSet.h new file mode 100644 index 0000000..bfc30fc --- /dev/null +++ b/bytecode/StructureSet.h @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2011 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 StructureSet_h +#define StructureSet_h + +#include "PredictedType.h" +#include "Structure.h" +#include +#include + +namespace JSC { + +namespace DFG { +class StructureAbstractValue; +} + +class StructureSet { +public: + StructureSet() { } + + StructureSet(Structure* structure) + { + m_structures.append(structure); + } + + void clear() + { + m_structures.clear(); + } + + void add(Structure* structure) + { + ASSERT(!contains(structure)); + m_structures.append(structure); + } + + bool addAll(const StructureSet& other) + { + bool changed = false; + for (size_t i = 0; i < other.size(); ++i) { + if (contains(other[i])) + continue; + add(other[i]); + changed = true; + } + return changed; + } + + void remove(Structure* structure) + { + for (size_t i = 0; i < m_structures.size(); ++i) { + if (m_structures[i] != structure) + continue; + + m_structures[i] = m_structures.last(); + m_structures.removeLast(); + return; + } + } + + bool contains(Structure* structure) const + { + for (size_t i = 0; i < m_structures.size(); ++i) { + if (m_structures[i] == structure) + return true; + } + return false; + } + + bool isSubsetOf(const StructureSet& other) const + { + for (size_t i = 0; i < m_structures.size(); ++i) { + if (!other.contains(m_structures[i])) + return false; + } + return true; + } + + bool isSupersetOf(const StructureSet& other) const + { + return other.isSubsetOf(*this); + } + + size_t size() const { return m_structures.size(); } + + bool allAreUsingInlinePropertyStorage() const + { + for (size_t i = 0; i < m_structures.size(); ++i) { + if (!m_structures[i]->isUsingInlineStorage()) + return false; + } + return true; + } + + Structure* at(size_t i) const { return m_structures.at(i); } + + Structure* operator[](size_t i) const { return at(i); } + + Structure* last() const { return m_structures.last(); } + + PredictedType predictionFromStructures() const + { + PredictedType result = PredictNone; + + for (size_t i = 0; i < m_structures.size(); ++i) + mergePrediction(result, predictionFromStructure(m_structures[i])); + + return result; + } + + bool operator==(const StructureSet& other) const + { + if (m_structures.size() != other.m_structures.size()) + return false; + + for (size_t i = 0; i < m_structures.size(); ++i) { + if (!other.contains(m_structures[i])) + return false; + } + + return true; + } + + void dump(FILE* out) + { + fprintf(out, "["); + for (size_t i = 0; i < m_structures.size(); ++i) { + if (i) + fprintf(out, ", "); + fprintf(out, "%p", m_structures[i]); + } + fprintf(out, "]"); + } + +private: + friend class DFG::StructureAbstractValue; + + Vector m_structures; +}; + +} // namespace JSC + +#endif // StructureSet_h diff --git a/bytecode/StructureStubInfo.cpp b/bytecode/StructureStubInfo.cpp index 9dd41a6..f66860a 100644 --- a/bytecode/StructureStubInfo.cpp +++ b/bytecode/StructureStubInfo.cpp @@ -27,6 +27,7 @@ #include "StructureStubInfo.h" #include "JSObject.h" +#include "PolymorphicPutByIdList.h" #include "ScopeChain.h" namespace JSC { @@ -45,13 +46,16 @@ void StructureStubInfo::deref() delete polymorphicStructures; return; } + case access_put_by_id_list: + delete u.putByIdList.list; + return; case access_get_by_id_self: case access_get_by_id_proto: case access_get_by_id_chain: - case access_put_by_id_transition: + case access_put_by_id_transition_normal: + case access_put_by_id_transition_direct: case access_put_by_id_replace: - case access_get_by_id: - case access_put_by_id: + case access_unset: case access_get_by_id_generic: case access_put_by_id_generic: case access_get_array_length: @@ -63,49 +67,56 @@ void StructureStubInfo::deref() } } -void StructureStubInfo::visitAggregate(SlotVisitor& visitor) +bool StructureStubInfo::visitWeakReferences() { switch (accessType) { case access_get_by_id_self: - visitor.append(&u.getByIdSelf.baseObjectStructure); - return; + if (!Heap::isMarked(u.getByIdSelf.baseObjectStructure.get())) + return false; + break; case access_get_by_id_proto: - visitor.append(&u.getByIdProto.baseObjectStructure); - visitor.append(&u.getByIdProto.prototypeStructure); - return; + if (!Heap::isMarked(u.getByIdProto.baseObjectStructure.get()) + || !Heap::isMarked(u.getByIdProto.prototypeStructure.get())) + return false; + break; case access_get_by_id_chain: - visitor.append(&u.getByIdChain.baseObjectStructure); - visitor.append(&u.getByIdChain.chain); - return; + if (!Heap::isMarked(u.getByIdChain.baseObjectStructure.get()) + || !Heap::isMarked(u.getByIdChain.chain.get())) + return false; + break; case access_get_by_id_self_list: { PolymorphicAccessStructureList* polymorphicStructures = u.getByIdSelfList.structureList; - polymorphicStructures->visitAggregate(visitor, u.getByIdSelfList.listSize); - return; + if (!polymorphicStructures->visitWeak(u.getByIdSelfList.listSize)) + return false; + break; } case access_get_by_id_proto_list: { PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList; - polymorphicStructures->visitAggregate(visitor, u.getByIdProtoList.listSize); - return; + if (!polymorphicStructures->visitWeak(u.getByIdProtoList.listSize)) + return false; + break; } - case access_put_by_id_transition: - visitor.append(&u.putByIdTransition.previousStructure); - visitor.append(&u.putByIdTransition.structure); - visitor.append(&u.putByIdTransition.chain); - return; + case access_put_by_id_transition_normal: + case access_put_by_id_transition_direct: + if (!Heap::isMarked(u.putByIdTransition.previousStructure.get()) + || !Heap::isMarked(u.putByIdTransition.structure.get()) + || !Heap::isMarked(u.putByIdTransition.chain.get())) + return false; + break; case access_put_by_id_replace: - visitor.append(&u.putByIdReplace.baseObjectStructure); - return; - case access_get_by_id: - case access_put_by_id: - case access_get_by_id_generic: - case access_put_by_id_generic: - case access_get_array_length: - case access_get_string_length: - // These instructions don't need to mark anything - return; + if (!Heap::isMarked(u.putByIdReplace.baseObjectStructure.get())) + return false; + break; + case access_put_by_id_list: + if (!u.putByIdList.list->visitWeak()) + return false; + break; default: - ASSERT_NOT_REACHED(); + // The rest of the instructions don't require references, so there is no need to + // do anything. + break; } + return true; } #endif diff --git a/bytecode/StructureStubInfo.h b/bytecode/StructureStubInfo.h index 7f11edd..03c64bf 100644 --- a/bytecode/StructureStubInfo.h +++ b/bytecode/StructureStubInfo.h @@ -26,8 +26,11 @@ #ifndef StructureStubInfo_h #define StructureStubInfo_h +#include + #if ENABLE(JIT) +#include "CodeOrigin.h" #include "Instruction.h" #include "MacroAssembler.h" #include "Opcode.h" @@ -35,25 +38,59 @@ namespace JSC { + class PolymorphicPutByIdList; + enum AccessType { access_get_by_id_self, access_get_by_id_proto, access_get_by_id_chain, access_get_by_id_self_list, access_get_by_id_proto_list, - access_put_by_id_transition, + access_put_by_id_transition_normal, + access_put_by_id_transition_direct, access_put_by_id_replace, - access_get_by_id, - access_put_by_id, + access_put_by_id_list, + access_unset, access_get_by_id_generic, access_put_by_id_generic, access_get_array_length, access_get_string_length, }; + inline bool isGetByIdAccess(AccessType accessType) + { + switch (accessType) { + case access_get_by_id_self: + case access_get_by_id_proto: + case access_get_by_id_chain: + case access_get_by_id_self_list: + case access_get_by_id_proto_list: + case access_get_by_id_generic: + case access_get_array_length: + case access_get_string_length: + return true; + default: + return false; + } + } + + inline bool isPutByIdAccess(AccessType accessType) + { + switch (accessType) { + case access_put_by_id_transition_normal: + case access_put_by_id_transition_direct: + case access_put_by_id_replace: + case access_put_by_id_list: + case access_put_by_id_generic: + return true; + default: + return false; + } + } + struct StructureStubInfo { - StructureStubInfo(AccessType accessType) - : accessType(accessType) + StructureStubInfo() + : accessType(access_unset) , seen(false) { } @@ -85,8 +122,8 @@ namespace JSC { { accessType = access_get_by_id_self_list; - u.getByIdProtoList.structureList = structureList; - u.getByIdProtoList.listSize = listSize; + u.getByIdSelfList.structureList = structureList; + u.getByIdSelfList.listSize = listSize; } void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize) @@ -99,9 +136,12 @@ namespace JSC { // PutById* - void initPutByIdTransition(JSGlobalData& globalData, JSCell* owner, Structure* previousStructure, Structure* structure, StructureChain* chain) + void initPutByIdTransition(JSGlobalData& globalData, JSCell* owner, Structure* previousStructure, Structure* structure, StructureChain* chain, bool isDirect) { - accessType = access_put_by_id_transition; + if (isDirect) + accessType = access_put_by_id_transition_direct; + else + accessType = access_put_by_id_transition_normal; u.putByIdTransition.previousStructure.set(globalData, owner, previousStructure); u.putByIdTransition.structure.set(globalData, owner, structure); @@ -114,10 +154,24 @@ namespace JSC { u.putByIdReplace.baseObjectStructure.set(globalData, owner, baseObjectStructure); } + + void initPutByIdList(PolymorphicPutByIdList* list) + { + accessType = access_put_by_id_list; + u.putByIdList.list = list; + } + + void reset() + { + deref(); + accessType = access_unset; + stubRoutine = MacroAssemblerCodeRef(); + } void deref(); - void visitAggregate(SlotVisitor&); + bool visitWeakReferences(); + bool seenOnce() { return seen; @@ -127,11 +181,70 @@ namespace JSC { { seen = true; } + + unsigned bytecodeIndex; + + int8_t accessType; + int8_t seen; - int accessType : 31; - int seen : 1; +#if ENABLE(DFG_JIT) + CodeOrigin codeOrigin; +#endif // ENABLE(DFG_JIT) union { + struct { + int8_t registersFlushed; + int8_t baseGPR; +#if USE(JSVALUE32_64) + int8_t valueTagGPR; +#endif + int8_t valueGPR; + int8_t scratchGPR; + int16_t deltaCallToDone; + int16_t deltaCallToStructCheck; + int16_t deltaCallToSlowCase; + int16_t deltaCheckImmToCall; +#if USE(JSVALUE64) + int16_t deltaCallToLoadOrStore; +#else + int16_t deltaCallToTagLoadOrStore; + int16_t deltaCallToPayloadLoadOrStore; +#endif + } dfg; + struct { + union { + struct { + int16_t structureToCompare; + int16_t structureCheck; +#if USE(JSVALUE64) + int16_t displacementLabel; +#else + int16_t displacementLabel1; + int16_t displacementLabel2; +#endif + int16_t putResult; + int16_t coldPathBegin; + } get; + struct { + int16_t structureToCompare; +#if USE(JSVALUE64) + int16_t displacementLabel; +#else + int16_t displacementLabel1; + int16_t displacementLabel2; +#endif + } put; + } u; + int16_t methodCheckProtoObj; + int16_t methodCheckProtoStructureToCompare; + int16_t methodCheckPutFunction; + } baseline; + } patch; + + union { + struct { + // It would be unwise to put anything here, as it will surely be overwritten. + } unset; struct { WriteBarrierBase baseObjectStructure; } getByIdSelf; @@ -159,15 +272,28 @@ namespace JSC { struct { WriteBarrierBase baseObjectStructure; } putByIdReplace; + struct { + PolymorphicPutByIdList* list; + } putByIdList; } u; - CodeLocationLabel stubRoutine; + MacroAssemblerCodeRef stubRoutine; CodeLocationCall callReturnLocation; CodeLocationLabel hotPathBegin; }; + inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo) + { + return structureStubInfo->callReturnLocation.executableAddress(); + } + + inline unsigned getStructureStubInfoBytecodeIndex(StructureStubInfo* structureStubInfo) + { + return structureStubInfo->bytecodeIndex; + } + } // namespace JSC -#endif +#endif // ENABLE(JIT) #endif // StructureStubInfo_h diff --git a/bytecode/ValueProfile.h b/bytecode/ValueProfile.h new file mode 100644 index 0000000..73e363a --- /dev/null +++ b/bytecode/ValueProfile.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2011, 2012 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. + * 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. + */ + +#ifndef ValueProfile_h +#define ValueProfile_h + +#include + +#if ENABLE(VALUE_PROFILER) + +#include "JSArray.h" +#include "PredictedType.h" +#include "Structure.h" +#include "WriteBarrier.h" + +namespace JSC { + +template +struct ValueProfileBase { + static const unsigned numberOfBuckets = numberOfBucketsArgument; + static const unsigned numberOfSpecFailBuckets = 1; + static const unsigned bucketIndexMask = numberOfBuckets - 1; + static const unsigned totalNumberOfBuckets = numberOfBuckets + numberOfSpecFailBuckets; + + ValueProfileBase() + : m_bytecodeOffset(-1) + , m_prediction(PredictNone) + , m_numberOfSamplesInPrediction(0) + { + for (unsigned i = 0; i < totalNumberOfBuckets; ++i) + m_buckets[i] = JSValue::encode(JSValue()); + } + + ValueProfileBase(int bytecodeOffset) + : m_bytecodeOffset(bytecodeOffset) + , m_prediction(PredictNone) + , m_numberOfSamplesInPrediction(0) + { + for (unsigned i = 0; i < totalNumberOfBuckets; ++i) + m_buckets[i] = JSValue::encode(JSValue()); + } + + EncodedJSValue* specFailBucket(unsigned i) + { + ASSERT(numberOfBuckets + i < totalNumberOfBuckets); + return m_buckets + numberOfBuckets + i; + } + + const ClassInfo* classInfo(unsigned bucket) const + { + JSValue value = JSValue::decode(m_buckets[bucket]); + if (!!value) { + if (!value.isCell()) + return 0; + return value.asCell()->structure()->classInfo(); + } + return 0; + } + + unsigned numberOfSamples() const + { + unsigned result = 0; + for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { + if (!!JSValue::decode(m_buckets[i])) + result++; + } + return result; + } + + unsigned totalNumberOfSamples() const + { + return numberOfSamples() + m_numberOfSamplesInPrediction; + } + + bool isLive() const + { + for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { + if (!!JSValue::decode(m_buckets[i])) + return true; + } + return false; + } + + void dump(FILE* out) + { + fprintf(out, + "samples = %u, prediction = %s", + totalNumberOfSamples(), + predictionToString(m_prediction)); + bool first = true; + for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { + JSValue value = JSValue::decode(m_buckets[i]); + if (!!value) { + if (first) { + fprintf(out, ": "); + first = false; + } else + fprintf(out, ", "); + fprintf(out, "%s", value.description()); + } + } + } + + // Updates the prediction and returns the new one. + PredictedType computeUpdatedPrediction() + { + for (unsigned i = 0; i < totalNumberOfBuckets; ++i) { + JSValue value = JSValue::decode(m_buckets[i]); + if (!value) + continue; + + m_numberOfSamplesInPrediction++; + mergePrediction(m_prediction, predictionFromValue(value)); + + m_buckets[i] = JSValue::encode(JSValue()); + } + + return m_prediction; + } + + int m_bytecodeOffset; // -1 for prologue + + PredictedType m_prediction; + unsigned m_numberOfSamplesInPrediction; + + EncodedJSValue m_buckets[totalNumberOfBuckets]; +}; + +struct MinimalValueProfile : public ValueProfileBase<0> { + MinimalValueProfile(): ValueProfileBase<0>() { } + MinimalValueProfile(int bytecodeOffset): ValueProfileBase<0>(bytecodeOffset) { } +}; + +template +struct ValueProfileWithLogNumberOfBuckets : public ValueProfileBase<1 << logNumberOfBucketsArgument> { + static const unsigned logNumberOfBuckets = logNumberOfBucketsArgument; + + ValueProfileWithLogNumberOfBuckets() + : ValueProfileBase<1 << logNumberOfBucketsArgument>() + { + } + ValueProfileWithLogNumberOfBuckets(int bytecodeOffset) + : ValueProfileBase<1 << logNumberOfBucketsArgument>(bytecodeOffset) + { + } +}; + +struct ValueProfile : public ValueProfileWithLogNumberOfBuckets<0> { + ValueProfile(): ValueProfileWithLogNumberOfBuckets<0>() { } + ValueProfile(int bytecodeOffset): ValueProfileWithLogNumberOfBuckets<0>(bytecodeOffset) { } +}; + +template +inline int getValueProfileBytecodeOffset(T* valueProfile) +{ + return valueProfile->m_bytecodeOffset; +} + +// This is a mini value profile to catch pathologies. It is a counter that gets +// incremented when we take the slow path on any instruction. +struct RareCaseProfile { + RareCaseProfile(int bytecodeOffset) + : m_bytecodeOffset(bytecodeOffset) + , m_counter(0) + { + } + + int m_bytecodeOffset; + uint32_t m_counter; +}; + +inline int getRareCaseProfileBytecodeOffset(RareCaseProfile* rareCaseProfile) +{ + return rareCaseProfile->m_bytecodeOffset; +} + +} // namespace JSC + +#endif // ENABLE(VALUE_PROFILER) + +#endif // ValueProfile_h + diff --git a/bytecode/ValueRecovery.h b/bytecode/ValueRecovery.h new file mode 100644 index 0000000..007c6d3 --- /dev/null +++ b/bytecode/ValueRecovery.h @@ -0,0 +1,348 @@ +/* + * Copyright (C) 2011 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 ValueRecovery_h +#define ValueRecovery_h + +#include "DataFormat.h" +#include "JSValue.h" +#include "MacroAssembler.h" +#include "VirtualRegister.h" +#include +#include + +namespace JSC { + +// Describes how to recover a given bytecode virtual register at a given +// code point. +enum ValueRecoveryTechnique { + // It's already in the register file at the right location. + AlreadyInRegisterFile, + // It's already in the register file but unboxed. + AlreadyInRegisterFileAsUnboxedInt32, + AlreadyInRegisterFileAsUnboxedCell, + AlreadyInRegisterFileAsUnboxedBoolean, + AlreadyInRegisterFileAsUnboxedDouble, + // It's in a register. + InGPR, + UnboxedInt32InGPR, + UnboxedBooleanInGPR, +#if USE(JSVALUE32_64) + InPair, +#endif + InFPR, + UInt32InGPR, + // It's in the register file, but at a different location. + DisplacedInRegisterFile, + // It's in the register file, at a different location, and it's unboxed. + Int32DisplacedInRegisterFile, + DoubleDisplacedInRegisterFile, + CellDisplacedInRegisterFile, + BooleanDisplacedInRegisterFile, + // It's a constant. + Constant, + // Don't know how to recover it. + DontKnow +}; + +class ValueRecovery { +public: + ValueRecovery() + : m_technique(DontKnow) + { + } + + static ValueRecovery alreadyInRegisterFile() + { + ValueRecovery result; + result.m_technique = AlreadyInRegisterFile; + return result; + } + + static ValueRecovery alreadyInRegisterFileAsUnboxedInt32() + { + ValueRecovery result; + result.m_technique = AlreadyInRegisterFileAsUnboxedInt32; + return result; + } + + static ValueRecovery alreadyInRegisterFileAsUnboxedCell() + { + ValueRecovery result; + result.m_technique = AlreadyInRegisterFileAsUnboxedCell; + return result; + } + + static ValueRecovery alreadyInRegisterFileAsUnboxedBoolean() + { + ValueRecovery result; + result.m_technique = AlreadyInRegisterFileAsUnboxedBoolean; + return result; + } + + static ValueRecovery alreadyInRegisterFileAsUnboxedDouble() + { + ValueRecovery result; + result.m_technique = AlreadyInRegisterFileAsUnboxedDouble; + return result; + } + + static ValueRecovery inGPR(MacroAssembler::RegisterID gpr, DataFormat dataFormat) + { + ASSERT(dataFormat != DataFormatNone); +#if USE(JSVALUE32_64) + ASSERT(dataFormat == DataFormatInteger || dataFormat == DataFormatCell || dataFormat == DataFormatBoolean); +#endif + ValueRecovery result; + if (dataFormat == DataFormatInteger) + result.m_technique = UnboxedInt32InGPR; + else if (dataFormat == DataFormatBoolean) + result.m_technique = UnboxedBooleanInGPR; + else + result.m_technique = InGPR; + result.m_source.gpr = gpr; + return result; + } + + static ValueRecovery uint32InGPR(MacroAssembler::RegisterID gpr) + { + ValueRecovery result; + result.m_technique = UInt32InGPR; + result.m_source.gpr = gpr; + return result; + } + +#if USE(JSVALUE32_64) + static ValueRecovery inPair(MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR) + { + ValueRecovery result; + result.m_technique = InPair; + result.m_source.pair.tagGPR = tagGPR; + result.m_source.pair.payloadGPR = payloadGPR; + return result; + } +#endif + + static ValueRecovery inFPR(MacroAssembler::FPRegisterID fpr) + { + ValueRecovery result; + result.m_technique = InFPR; + result.m_source.fpr = fpr; + return result; + } + + static ValueRecovery displacedInRegisterFile(VirtualRegister virtualReg, DataFormat dataFormat) + { + ValueRecovery result; + switch (dataFormat) { + case DataFormatInteger: + result.m_technique = Int32DisplacedInRegisterFile; + break; + + case DataFormatDouble: + result.m_technique = DoubleDisplacedInRegisterFile; + break; + + case DataFormatCell: + result.m_technique = CellDisplacedInRegisterFile; + break; + + case DataFormatBoolean: + result.m_technique = BooleanDisplacedInRegisterFile; + break; + + default: + ASSERT(dataFormat != DataFormatNone && dataFormat != DataFormatStorage); + result.m_technique = DisplacedInRegisterFile; + break; + } + result.m_source.virtualReg = virtualReg; + return result; + } + + static ValueRecovery constant(JSValue value) + { + ValueRecovery result; + result.m_technique = Constant; + result.m_source.constant = JSValue::encode(value); + return result; + } + + ValueRecoveryTechnique technique() const { return m_technique; } + + bool isConstant() const { return m_technique == Constant; } + + bool isInRegisters() const + { + switch (m_technique) { + case InGPR: + case UnboxedInt32InGPR: + case UnboxedBooleanInGPR: +#if USE(JSVALUE32_64) + case InPair: +#endif + case InFPR: + return true; + default: + return false; + } + } + + bool isAlreadyInRegisterFile() const + { + switch (technique()) { + case AlreadyInRegisterFile: + case AlreadyInRegisterFileAsUnboxedInt32: + case AlreadyInRegisterFileAsUnboxedCell: + case AlreadyInRegisterFileAsUnboxedBoolean: + case AlreadyInRegisterFileAsUnboxedDouble: + return true; + default: + return false; + } + } + + MacroAssembler::RegisterID gpr() const + { + ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR); + return m_source.gpr; + } + +#if USE(JSVALUE32_64) + MacroAssembler::RegisterID tagGPR() const + { + ASSERT(m_technique == InPair); + return m_source.pair.tagGPR; + } + + MacroAssembler::RegisterID payloadGPR() const + { + ASSERT(m_technique == InPair); + return m_source.pair.payloadGPR; + } +#endif + + MacroAssembler::FPRegisterID fpr() const + { + ASSERT(m_technique == InFPR); + return m_source.fpr; + } + + VirtualRegister virtualRegister() const + { + ASSERT(m_technique == DisplacedInRegisterFile || m_technique == Int32DisplacedInRegisterFile || m_technique == DoubleDisplacedInRegisterFile || m_technique == CellDisplacedInRegisterFile || m_technique == BooleanDisplacedInRegisterFile); + return m_source.virtualReg; + } + + JSValue constant() const + { + ASSERT(m_technique == Constant); + return JSValue::decode(m_source.constant); + } + + void dump(FILE* out) const + { + switch (technique()) { + case AlreadyInRegisterFile: + fprintf(out, "-"); + break; + case AlreadyInRegisterFileAsUnboxedInt32: + fprintf(out, "(int32)"); + break; + case AlreadyInRegisterFileAsUnboxedCell: + fprintf(out, "(cell)"); + break; + case AlreadyInRegisterFileAsUnboxedBoolean: + fprintf(out, "(bool)"); + break; + case AlreadyInRegisterFileAsUnboxedDouble: + fprintf(out, "(double)"); + break; + case InGPR: + fprintf(out, "%%r%d", gpr()); + break; + case UnboxedInt32InGPR: + fprintf(out, "int32(%%r%d)", gpr()); + break; + case UnboxedBooleanInGPR: + fprintf(out, "bool(%%r%d)", gpr()); + break; + case UInt32InGPR: + fprintf(out, "uint32(%%r%d)", gpr()); + break; + case InFPR: + fprintf(out, "%%fr%d", fpr()); + break; +#if USE(JSVALUE32_64) + case InPair: + fprintf(out, "pair(%%r%d, %%r%d)", tagGPR(), payloadGPR()); + break; +#endif + case DisplacedInRegisterFile: + fprintf(out, "*%d", virtualRegister()); + break; + case Int32DisplacedInRegisterFile: + fprintf(out, "*int32(%d)", virtualRegister()); + break; + case DoubleDisplacedInRegisterFile: + fprintf(out, "*double(%d)", virtualRegister()); + break; + case CellDisplacedInRegisterFile: + fprintf(out, "*cell(%d)", virtualRegister()); + break; + case BooleanDisplacedInRegisterFile: + fprintf(out, "*bool(%d)", virtualRegister()); + break; + case Constant: + fprintf(out, "[%s]", constant().description()); + break; + case DontKnow: + fprintf(out, "!"); + break; + default: + fprintf(out, "?%d", technique()); + break; + } + } + +private: + ValueRecoveryTechnique m_technique; + union { + MacroAssembler::RegisterID gpr; + MacroAssembler::FPRegisterID fpr; +#if USE(JSVALUE32_64) + struct { + MacroAssembler::RegisterID tagGPR; + MacroAssembler::RegisterID payloadGPR; + } pair; +#endif + VirtualRegister virtualReg; + EncodedJSValue constant; + } m_source; +}; + +} // namespace JSC + +#endif // ValueRecovery_h diff --git a/bytecode/VirtualRegister.h b/bytecode/VirtualRegister.h new file mode 100644 index 0000000..b95f8b8 --- /dev/null +++ b/bytecode/VirtualRegister.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2011 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 VirtualRegister_h +#define VirtualRegister_h + +#include + +namespace JSC { + +// Type for a virtual register number (spill location). +// Using an enum to make this type-checked at compile time, to avert programmer errors. +enum VirtualRegister { InvalidVirtualRegister = -1 }; +COMPILE_ASSERT(sizeof(VirtualRegister) == sizeof(int), VirtualRegister_is_32bit); + +} // namespace JSC + +#endif // VirtualRegister_h diff --git a/bytecompiler/BytecodeGenerator.cpp b/bytecompiler/BytecodeGenerator.cpp index c09a837..f43b4e6 100644 --- a/bytecompiler/BytecodeGenerator.cpp +++ b/bytecompiler/BytecodeGenerator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009, 2012 Apple Inc. All rights reserved. * Copyright (C) 2008 Cameron Zwarich * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,9 @@ #include "BatchedTransitionOptimizer.h" #include "JSFunction.h" #include "Interpreter.h" +#include "LowLevelInterpreter.h" #include "ScopeChain.h" +#include "StrongInlines.h" #include "UString.h" using namespace std; @@ -115,40 +117,39 @@ namespace JSC { expected by the callee. */ -#ifndef NDEBUG static bool s_dumpsGeneratedCode = false; -#endif + +void Label::setLocation(unsigned location) +{ + m_location = location; + + unsigned size = m_unresolvedJumps.size(); + for (unsigned i = 0; i < size; ++i) + m_generator->m_instructions[m_unresolvedJumps[i].second].u.operand = m_location - m_unresolvedJumps[i].first; +} void BytecodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode) { -#ifndef NDEBUG s_dumpsGeneratedCode = dumpsGeneratedCode; -#else - UNUSED_PARAM(dumpsGeneratedCode); -#endif } bool BytecodeGenerator::dumpsGeneratedCode() { -#ifndef NDEBUG return s_dumpsGeneratedCode; -#else - return false; -#endif } JSObject* BytecodeGenerator::generate() { + SamplingRegion samplingRegion("Bytecode Generation"); + m_codeBlock->setThisRegister(m_thisRegister.index()); m_scopeNode->emitBytecode(*this); - -#ifndef NDEBUG - m_codeBlock->setInstructionCount(m_codeBlock->instructions().size()); + + m_codeBlock->instructions() = RefCountedArray(m_instructions); if (s_dumpsGeneratedCode) m_codeBlock->dump(m_scopeChain->globalObject->globalExec()); -#endif if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode) symbolTable().clear(); @@ -164,10 +165,10 @@ bool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, Registe { int index = m_calleeRegisters.size(); SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0); - pair result = symbolTable().add(ident.impl(), newEntry); + SymbolTable::AddResult result = symbolTable().add(ident.impl(), newEntry); - if (!result.second) { - r0 = ®isterFor(result.first->second.getIndex()); + if (!result.isNewEntry) { + r0 = ®isterFor(result.iterator->second.getIndex()); return false; } @@ -175,21 +176,14 @@ bool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, Registe return true; } -bool BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, RegisterID*& r0) +int BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant) { - int index = m_nextGlobalIndex; + int index = symbolTable().size(); SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0); - pair result = symbolTable().add(ident.impl(), newEntry); - - if (!result.second) - index = result.first->second.getIndex(); - else { - --m_nextGlobalIndex; - m_globals.append(index + m_globalVarStorageOffset); - } - - r0 = ®isterFor(index); - return result.second; + SymbolTable::AddResult result = symbolTable().add(ident.impl(), newEntry); + if (!result.isNewEntry) + index = result.iterator->second.getIndex(); + return index; } void BytecodeGenerator::preserveLastVar() @@ -198,20 +192,19 @@ void BytecodeGenerator::preserveLastVar() m_lastVar = &m_calleeRegisters.last(); } -BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock) +BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock, CompilationKind compilationKind) : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger()) - , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling()) - , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo()) + , m_shouldEmitProfileHooks(scopeChain->globalObject->globalObjectMethodTable()->supportsProfiling(scopeChain->globalObject.get())) + , m_shouldEmitRichSourceInfo(scopeChain->globalObject->globalObjectMethodTable()->supportsRichSourceInfo(scopeChain->globalObject.get())) , m_scopeChain(*scopeChain->globalData, scopeChain) , m_symbolTable(symbolTable) , m_scopeNode(programNode) , m_codeBlock(codeBlock) - , m_thisRegister(RegisterFile::ProgramCodeThisRegister) + , m_thisRegister(CallFrame::thisArgumentOffset()) , m_finallyDepth(0) , m_dynamicScopeDepth(0) , m_baseScopeDepth(0) , m_codeType(GlobalCode) - , m_nextGlobalIndex(-1) , m_nextConstantOffset(0) , m_globalConstantIndex(0) , m_hasCreatedActivation(true) @@ -222,10 +215,11 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* s #ifndef NDEBUG , m_lastOpcodePosition(0) #endif - , m_stack(m_globalData->stack()) + , m_stack(wtfThreadData().stack()) , m_usesExceptions(false) , m_expressionTooDeep(false) { + m_globalData->startedCompiling(m_codeBlock); if (m_shouldEmitDebugHooks) m_codeBlock->setNeedsFullScopeChain(true); @@ -234,96 +228,45 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* s // FIXME: Move code that modifies the global object to Interpreter::execute. - m_codeBlock->m_numParameters = 1; // Allocate space for "this" + m_codeBlock->setNumParameters(1); // Allocate space for "this" + codeBlock->m_numCapturedVars = codeBlock->m_numVars; + + if (compilationKind == OptimizingCompilation) + return; JSGlobalObject* globalObject = scopeChain->globalObject.get(); ExecState* exec = globalObject->globalExec(); - RegisterFile* registerFile = &exec->globalData().interpreter->registerFile(); - // Shift register indexes in generated code to elide registers allocated by intermediate stack frames. - m_globalVarStorageOffset = -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters - registerFile->size(); - - // Add previously defined symbols to bookkeeping. - m_globals.grow(symbolTable->size()); - SymbolTable::iterator end = symbolTable->end(); - for (SymbolTable::iterator it = symbolTable->begin(); it != end; ++it) - registerFor(it->second.getIndex()).setIndex(it->second.getIndex() + m_globalVarStorageOffset); - BatchedTransitionOptimizer optimizer(*m_globalData, globalObject); const VarStack& varStack = programNode->varStack(); const FunctionStack& functionStack = programNode->functionStack(); - bool canOptimizeNewGlobals = symbolTable->size() + functionStack.size() + varStack.size() < registerFile->maxGlobals(); - if (canOptimizeNewGlobals) { - // Shift new symbols so they get stored prior to existing symbols. - m_nextGlobalIndex -= symbolTable->size(); - - HashSet newGlobals; - Vector, 16> functionInfo(functionStack.size()); - for (size_t i = 0; i < functionStack.size(); ++i) { - FunctionBodyNode* function = functionStack[i]; - globalObject->removeDirect(*m_globalData, function->ident()); // Make sure our new function is not shadowed by an old property. - SymbolTableEntry entry = symbolTable->inlineGet(function->ident().impl()); - - if (entry.isNull()) - newGlobals.add(function->ident().impl()); - functionInfo[i] = make_pair(entry.getIndex(), entry.isReadOnly()); - } - - Vector shouldCreateVar(varStack.size()); - for (size_t i = 0; i < varStack.size(); ++i) { - if (newGlobals.contains(varStack[i].first->impl()) || globalObject->hasProperty(exec, *varStack[i].first)) { - shouldCreateVar[i] = false; - continue; - } - shouldCreateVar[i] = true; - newGlobals.add(varStack[i].first->impl()); - } - int expectedSize = symbolTable->size() + newGlobals.size(); - globalObject->resizeRegisters(symbolTable->size(), expectedSize); - - for (size_t i = 0; i < functionStack.size(); ++i) { - FunctionBodyNode* function = functionStack[i]; - if (functionInfo[i].second) - continue; - RegisterID* dst = addGlobalVar(function->ident(), false); - JSValue value = new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain); - globalObject->registerAt(dst->index() - m_globalVarStorageOffset).set(*m_globalData, globalObject, value); - } + size_t newGlobals = varStack.size() + functionStack.size(); + if (!newGlobals) + return; + globalObject->resizeRegisters(symbolTable->size() + newGlobals); - for (size_t i = 0; i < varStack.size(); ++i) { - if (!shouldCreateVar[i]) - continue; - addGlobalVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant); - } - if (symbolTable->size() != expectedSize) - CRASH(); + for (size_t i = 0; i < functionStack.size(); ++i) { + FunctionBodyNode* function = functionStack[i]; + globalObject->removeDirect(*m_globalData, function->ident()); // Newly declared functions overwrite existing properties. - preserveLastVar(); - } else { - for (size_t i = 0; i < functionStack.size(); ++i) { - FunctionBodyNode* function = functionStack[i]; - globalObject->putWithAttributes(exec, function->ident(), new (exec) JSFunction(exec, makeFunction(exec, function), scopeChain), DontDelete); - } - for (size_t i = 0; i < varStack.size(); ++i) { - if (globalObject->symbolTableHasProperty(*varStack[i].first) || globalObject->hasProperty(exec, *varStack[i].first)) - continue; - int attributes = DontDelete; - if (varStack[i].second & DeclarationStacks::IsConstant) - attributes |= ReadOnly; - globalObject->putWithAttributes(exec, *varStack[i].first, jsUndefined(), attributes); - } + JSValue value = JSFunction::create(exec, makeFunction(exec, function), scopeChain); + int index = addGlobalVar(function->ident(), false); + globalObject->registerAt(index).set(*m_globalData, globalObject, value); + } - preserveLastVar(); + for (size_t i = 0; i < varStack.size(); ++i) { + if (globalObject->hasProperty(exec, *varStack[i].first)) + continue; + addGlobalVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant); } - codeBlock->m_numCapturedVars = codeBlock->m_numVars; } -BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, ScopeChainNode* scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock) +BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, ScopeChainNode* scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock, CompilationKind) : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger()) - , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling()) - , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo()) + , m_shouldEmitProfileHooks(scopeChain->globalObject->globalObjectMethodTable()->supportsProfiling(scopeChain->globalObject.get())) + , m_shouldEmitRichSourceInfo(scopeChain->globalObject->globalObjectMethodTable()->supportsRichSourceInfo(scopeChain->globalObject.get())) , m_scopeChain(*scopeChain->globalData, scopeChain) , m_symbolTable(symbolTable) , m_scopeNode(functionBody) @@ -343,10 +286,11 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, ScopeChainN #ifndef NDEBUG , m_lastOpcodePosition(0) #endif - , m_stack(m_globalData->stack()) + , m_stack(wtfThreadData().stack()) , m_usesExceptions(false) , m_expressionTooDeep(false) { + m_globalData->startedCompiling(m_codeBlock); if (m_shouldEmitDebugHooks) m_codeBlock->setNeedsFullScopeChain(true); @@ -445,21 +389,20 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, ScopeChainN if (!functionBody->captures(ident)) addVar(ident, varStack[i].second & DeclarationStacks::IsConstant); } - + if (m_shouldEmitDebugHooks) codeBlock->m_numCapturedVars = codeBlock->m_numVars; FunctionParameters& parameters = *functionBody->parameters(); - size_t parameterCount = parameters.size(); - int nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1; - m_parameters.grow(1 + parameterCount); // reserve space for "this" + m_parameters.grow(parameters.size() + 1); // reserve space for "this" // Add "this" as a parameter - m_thisRegister.setIndex(nextParameterIndex); - ++m_codeBlock->m_numParameters; + int nextParameterIndex = CallFrame::thisArgumentOffset(); + m_thisRegister.setIndex(nextParameterIndex--); + m_codeBlock->addParameter(); - for (size_t i = 0; i < parameterCount; ++i) - addParameter(parameters[i], ++nextParameterIndex); + for (size_t i = 0; i < parameters.size(); ++i) + addParameter(parameters[i], nextParameterIndex--); preserveLastVar(); @@ -475,24 +418,21 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, ScopeChainN emitOpcode(op_create_this); instructions().append(m_thisRegister.index()); instructions().append(funcProto->index()); - } else if (functionBody->usesThis() || m_shouldEmitDebugHooks) { - if (codeBlock->isStrictMode()) - emitOpcode(op_convert_this_strict); - else - emitOpcode(op_convert_this); + } else if (!codeBlock->isStrictMode() && (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks)) { + emitOpcode(op_convert_this); instructions().append(m_thisRegister.index()); } } -BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock) +BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock, CompilationKind) : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger()) - , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling()) - , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo()) + , m_shouldEmitProfileHooks(scopeChain->globalObject->globalObjectMethodTable()->supportsProfiling(scopeChain->globalObject.get())) + , m_shouldEmitRichSourceInfo(scopeChain->globalObject->globalObjectMethodTable()->supportsRichSourceInfo(scopeChain->globalObject.get())) , m_scopeChain(*scopeChain->globalData, scopeChain) , m_symbolTable(symbolTable) , m_scopeNode(evalNode) , m_codeBlock(codeBlock) - , m_thisRegister(RegisterFile::ProgramCodeThisRegister) + , m_thisRegister(CallFrame::thisArgumentOffset()) , m_finallyDepth(0) , m_dynamicScopeDepth(0) , m_baseScopeDepth(codeBlock->baseScopeDepth()) @@ -507,16 +447,17 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, ScopeChainNode* scopeCh #ifndef NDEBUG , m_lastOpcodePosition(0) #endif - , m_stack(m_globalData->stack()) + , m_stack(wtfThreadData().stack()) , m_usesExceptions(false) , m_expressionTooDeep(false) { + m_globalData->startedCompiling(m_codeBlock); if (m_shouldEmitDebugHooks || m_baseScopeDepth) m_codeBlock->setNeedsFullScopeChain(true); emitOpcode(op_enter); codeBlock->setGlobalData(m_globalData); - m_codeBlock->m_numParameters = 1; // Allocate space for "this" + m_codeBlock->setNumParameters(1); const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack(); for (size_t i = 0; i < functionStack.size(); ++i) @@ -533,6 +474,11 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, ScopeChainNode* scopeCh preserveLastVar(); } +BytecodeGenerator::~BytecodeGenerator() +{ + m_globalData->finishedCompiling(m_codeBlock); +} + RegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg) { emitOpcode(op_init_lazy_reg); @@ -552,13 +498,16 @@ void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex // To maintain the calling convention, we have to allocate unique space for // each parameter, even if the parameter doesn't make it into the symbol table. - ++m_codeBlock->m_numParameters; + m_codeBlock->addParameter(); } RegisterID* BytecodeGenerator::registerFor(const Identifier& ident) { if (ident == propertyNames().thisIdentifier) return &m_thisRegister; + + if (m_codeType == GlobalCode) + return 0; if (!shouldOptimizeLocals()) return 0; @@ -573,6 +522,21 @@ RegisterID* BytecodeGenerator::registerFor(const Identifier& ident) return createLazyRegisterIfNecessary(®isterFor(entry.getIndex())); } +RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident) +{ + if (m_codeType == EvalCode) + return 0; + + if (m_codeType == GlobalCode) + return 0; + + SymbolTableEntry entry = symbolTable().get(ident.impl()); + if (entry.isNull()) + return 0; + + return createLazyRegisterIfNecessary(®isterFor(entry.getIndex())); +} + bool BytecodeGenerator::willResolveToArguments(const Identifier& ident) { if (ident != propertyNames().arguments) @@ -608,18 +572,6 @@ RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg) return reg; } -RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident) -{ - if (m_codeType == EvalCode) - return 0; - - SymbolTableEntry entry = symbolTable().get(ident.impl()); - if (entry.isNull()) - return 0; - - return createLazyRegisterIfNecessary(®isterFor(entry.getIndex())); -} - bool BytecodeGenerator::isLocal(const Identifier& ident) { if (ident == propertyNames().thisIdentifier) @@ -678,7 +630,7 @@ PassRefPtr