diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-17 16:21:14 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-17 16:21:14 +0200 |
commit | 8995b83bcbfbb68245f779b64e5517627c6cc6ea (patch) | |
tree | 17985605dab9263cc2444bd4d45f189e142cca7c /Source/JavaScriptCore | |
parent | b9c9652036d5e9f1e29c574f40bc73a35c81ace6 (diff) | |
download | qtwebkit-8995b83bcbfbb68245f779b64e5517627c6cc6ea.tar.gz |
Imported WebKit commit cf4f8fc6f19b0629f51860cb2d4b25e139d07e00 (http://svn.webkit.org/repository/webkit/trunk@131592)
New snapshot that includes the build fixes for Mac OS X 10.6 and earlier as well
as the previously cherry-picked changes
Diffstat (limited to 'Source/JavaScriptCore')
257 files changed, 32243 insertions, 23290 deletions
diff --git a/Source/JavaScriptCore/API/JSCallbackConstructor.cpp b/Source/JavaScriptCore/API/JSCallbackConstructor.cpp index 8fd2b61f1..c43182e8f 100644 --- a/Source/JavaScriptCore/API/JSCallbackConstructor.cpp +++ b/Source/JavaScriptCore/API/JSCallbackConstructor.cpp @@ -36,10 +36,10 @@ namespace JSC { -const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) }; +const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) }; JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Structure* structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback) - : JSNonFinalObject(globalObject->globalData(), structure) + : JSDestructibleObject(globalObject->globalData(), structure) , m_class(jsClass) , m_callback(callback) { diff --git a/Source/JavaScriptCore/API/JSCallbackConstructor.h b/Source/JavaScriptCore/API/JSCallbackConstructor.h index 25fde1324..2bb4d07af 100644 --- a/Source/JavaScriptCore/API/JSCallbackConstructor.h +++ b/Source/JavaScriptCore/API/JSCallbackConstructor.h @@ -27,13 +27,13 @@ #define JSCallbackConstructor_h #include "JSObjectRef.h" -#include <runtime/JSObject.h> +#include "runtime/JSDestructibleObject.h" namespace JSC { -class JSCallbackConstructor : public JSNonFinalObject { +class JSCallbackConstructor : public JSDestructibleObject { public: - typedef JSNonFinalObject Base; + typedef JSDestructibleObject Base; static JSCallbackConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSClassRef classRef, JSObjectCallAsConstructorCallback callback) { diff --git a/Source/JavaScriptCore/API/JSCallbackFunction.cpp b/Source/JavaScriptCore/API/JSCallbackFunction.cpp index 0f63d3c16..aada87bfa 100644 --- a/Source/JavaScriptCore/API/JSCallbackFunction.cpp +++ b/Source/JavaScriptCore/API/JSCallbackFunction.cpp @@ -38,7 +38,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSCallbackFunction); ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSCallbackFunction); const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackFunction) }; diff --git a/Source/JavaScriptCore/API/JSCallbackObject.cpp b/Source/JavaScriptCore/API/JSCallbackObject.cpp index 921d37897..76866feb0 100644 --- a/Source/JavaScriptCore/API/JSCallbackObject.cpp +++ b/Source/JavaScriptCore/API/JSCallbackObject.cpp @@ -32,15 +32,24 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject<JSNonFinalObject>); -ASSERT_CLASS_FITS_IN_CELL(JSCallbackObject<JSGlobalObject>); - // Define the two types of JSCallbackObjects we support. -template <> const ClassInfo JSCallbackObject<JSNonFinalObject>::s_info = { "CallbackObject", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; -template <> const ClassInfo JSCallbackObject<JSGlobalObject>::s_info = { "CallbackGlobalObject", &JSGlobalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; +template <> const ClassInfo JSCallbackObject<JSDestructibleObject>::s_info = { "CallbackObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; +template <> const ClassInfo JSCallbackObject<JSGlobalObject>::s_info = { "CallbackGlobalObject", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; + +template<> const bool JSCallbackObject<JSDestructibleObject>::needsDestruction = true; +template<> const bool JSCallbackObject<JSGlobalObject>::needsDestruction = false; + +template<> +JSCallbackObject<JSGlobalObject>* JSCallbackObject<JSGlobalObject>::create(JSGlobalData& globalData, JSClassRef classRef, Structure* structure) +{ + JSCallbackObject<JSGlobalObject>* callbackObject = new (NotNull, allocateCell<JSCallbackObject<JSGlobalObject> >(globalData.heap)) JSCallbackObject(globalData, classRef, structure); + callbackObject->finishCreation(globalData); + globalData.heap.addFinalizer(callbackObject, destroy); + return callbackObject; +} template <> -Structure* JSCallbackObject<JSNonFinalObject>::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) +Structure* JSCallbackObject<JSDestructibleObject>::createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(ObjectType, StructureFlags), &s_info); } diff --git a/Source/JavaScriptCore/API/JSCallbackObject.h b/Source/JavaScriptCore/API/JSCallbackObject.h index 5022aaf40..3acf2ef10 100644 --- a/Source/JavaScriptCore/API/JSCallbackObject.h +++ b/Source/JavaScriptCore/API/JSCallbackObject.h @@ -83,13 +83,13 @@ struct JSCallbackObjectData : WeakHandleOwner { PrivatePropertyMap::const_iterator location = m_propertyMap.find(propertyName.impl()); if (location == m_propertyMap.end()) return JSValue(); - return location->second.get(); + return location->value.get(); } void setPrivateProperty(JSGlobalData& globalData, JSCell* owner, const Identifier& propertyName, JSValue value) { WriteBarrier<Unknown> empty; - m_propertyMap.add(propertyName.impl(), empty).iterator->second.set(globalData, owner, value); + m_propertyMap.add(propertyName.impl(), empty).iterator->value.set(globalData, owner, value); } void deletePrivateProperty(const Identifier& propertyName) @@ -100,8 +100,8 @@ struct JSCallbackObjectData : WeakHandleOwner { void visitChildren(SlotVisitor& visitor) { for (PrivatePropertyMap::iterator ptr = m_propertyMap.begin(); ptr != m_propertyMap.end(); ++ptr) { - if (ptr->second) - visitor.append(&ptr->second); + if (ptr->value) + visitor.append(&ptr->value); } } @@ -133,12 +133,10 @@ public: callbackObject->finishCreation(exec); return callbackObject; } - static JSCallbackObject* create(JSGlobalData& globalData, JSClassRef classRef, Structure* structure) - { - JSCallbackObject* callbackObject = new (NotNull, allocateCell<JSCallbackObject>(globalData.heap)) JSCallbackObject(globalData, classRef, structure); - callbackObject->finishCreation(globalData); - return callbackObject; - } + static JSCallbackObject<Parent>* create(JSGlobalData&, JSClassRef, Structure*); + + static const bool needsDestruction; + static void destroy(JSCell*); void setPrivate(void* data); void* getPrivate(); @@ -173,8 +171,6 @@ protected: private: static String className(const JSObject*); - static void destroy(JSCell*); - static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType); static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); diff --git a/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h b/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h index 688e7b8b9..1a063e620 100644 --- a/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h +++ b/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h @@ -471,8 +471,8 @@ void JSCallbackObject<Parent>::getOwnNonIndexPropertyNames(JSObject* object, Exe typedef OpaqueJSClassStaticValuesTable::const_iterator iterator; iterator end = staticValues->end(); for (iterator it = staticValues->begin(); it != end; ++it) { - StringImpl* name = it->first.get(); - StaticValueEntry* entry = it->second.get(); + StringImpl* name = it->key.get(); + StaticValueEntry* entry = it->value.get(); if (entry->getProperty && (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties))) propertyNames.add(Identifier(exec, name)); } @@ -482,8 +482,8 @@ void JSCallbackObject<Parent>::getOwnNonIndexPropertyNames(JSObject* object, Exe typedef OpaqueJSClassStaticFunctionsTable::const_iterator iterator; iterator end = staticFunctions->end(); for (iterator it = staticFunctions->begin(); it != end; ++it) { - StringImpl* name = it->first.get(); - StaticFunctionEntry* entry = it->second.get(); + StringImpl* name = it->key.get(); + StaticFunctionEntry* entry = it->value.get(); if (!(entry->attributes & kJSPropertyAttributeDontEnum) || (mode == IncludeDontEnumProperties)) propertyNames.add(Identifier(exec, name)); } diff --git a/Source/JavaScriptCore/API/JSClassRef.cpp b/Source/JavaScriptCore/API/JSClassRef.cpp index a95d42e39..976203f08 100644 --- a/Source/JavaScriptCore/API/JSClassRef.cpp +++ b/Source/JavaScriptCore/API/JSClassRef.cpp @@ -93,13 +93,13 @@ OpaqueJSClass::~OpaqueJSClass() if (m_staticValues) { OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end(); for (OpaqueJSClassStaticValuesTable::const_iterator it = m_staticValues->begin(); it != end; ++it) - ASSERT(!it->first->isIdentifier()); + ASSERT(!it->key->isIdentifier()); } if (m_staticFunctions) { OpaqueJSClassStaticFunctionsTable::const_iterator end = m_staticFunctions->end(); for (OpaqueJSClassStaticFunctionsTable::const_iterator it = m_staticFunctions->begin(); it != end; ++it) - ASSERT(!it->first->isIdentifier()); + ASSERT(!it->key->isIdentifier()); } #endif @@ -133,8 +133,8 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSC 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()); - staticValues->add(StringImpl::create(it->first->characters(), it->first->length()), adoptPtr(new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes))); + ASSERT(!it->key->isIdentifier()); + staticValues->add(StringImpl::create(it->key->characters(), it->key->length()), adoptPtr(new StaticValueEntry(it->value->getProperty, it->value->setProperty, it->value->attributes))); } } @@ -142,15 +142,15 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(JSC::JSGlobalData&, OpaqueJSC 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()); - staticFunctions->add(StringImpl::create(it->first->characters(), it->first->length()), adoptPtr(new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes))); + ASSERT(!it->key->isIdentifier()); + staticFunctions->add(StringImpl::create(it->key->characters(), it->key->length()), adoptPtr(new StaticFunctionEntry(it->value->callAsFunction, it->value->attributes))); } } } OpaqueJSClassContextData& OpaqueJSClass::contextData(ExecState* exec) { - OwnPtr<OpaqueJSClassContextData>& contextData = exec->globalData().opaqueJSClassData.add(this, nullptr).iterator->second; + OwnPtr<OpaqueJSClassContextData>& contextData = exec->globalData().opaqueJSClassData.add(this, nullptr).iterator->value; if (!contextData) contextData = adoptPtr(new OpaqueJSClassContextData(exec->globalData(), this)); return *contextData; @@ -199,7 +199,7 @@ JSObject* OpaqueJSClass::prototype(ExecState* exec) return prototype; // Recursive, but should be good enough for our purposes - JSObject* prototype = JSCallbackObject<JSNonFinalObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData); // set jsClassData as the object's private data, so it can clear our reference on destruction + JSObject* prototype = JSCallbackObject<JSDestructibleObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), prototypeClass, &jsClassData); // set jsClassData as the object's private data, so it can clear our reference on destruction if (parentClass) { if (JSObject* parentPrototype = parentClass->prototype(exec)) prototype->setPrototype(exec->globalData(), parentPrototype); diff --git a/Source/JavaScriptCore/API/JSObjectRef.cpp b/Source/JavaScriptCore/API/JSObjectRef.cpp index 7a8956e4a..491fa988f 100644 --- a/Source/JavaScriptCore/API/JSObjectRef.cpp +++ b/Source/JavaScriptCore/API/JSObjectRef.cpp @@ -83,7 +83,7 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data) if (!jsClass) return toRef(constructEmptyObject(exec)); - JSCallbackObject<JSNonFinalObject>* object = JSCallbackObject<JSNonFinalObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), jsClass, data); + JSCallbackObject<JSDestructibleObject>* object = JSCallbackObject<JSDestructibleObject>::create(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->callbackObjectStructure(), jsClass, data); if (JSObject* prototype = jsClass->prototype(exec)) object->setPrototype(exec->globalData(), prototype); @@ -341,8 +341,8 @@ void* JSObjectGetPrivate(JSObjectRef object) if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) return jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivate(); - if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) - return jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->getPrivate(); + if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) + return jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivate(); return 0; } @@ -355,8 +355,8 @@ bool JSObjectSetPrivate(JSObjectRef object, void* data) jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivate(data); return true; } - if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) { - jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->setPrivate(data); + if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) { + jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivate(data); return true; } @@ -372,8 +372,8 @@ JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSSt Identifier name(propertyName->identifier(&exec->globalData())); if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) result = jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name); - else if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) - result = jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->getPrivateProperty(name); + else if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) + result = jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->getPrivateProperty(name); return toRef(exec, result); } @@ -388,8 +388,8 @@ bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRe jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue); return true; } - if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) { - jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue); + if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) { + jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->setPrivateProperty(exec->globalData(), name, jsValue); return true; } return false; @@ -405,8 +405,8 @@ bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStrin jsCast<JSCallbackObject<JSGlobalObject>*>(jsObject)->deletePrivateProperty(name); return true; } - if (jsObject->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) { - jsCast<JSCallbackObject<JSNonFinalObject>*>(jsObject)->deletePrivateProperty(name); + if (jsObject->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) { + jsCast<JSCallbackObject<JSDestructibleObject>*>(jsObject)->deletePrivateProperty(name); return true; } return false; diff --git a/Source/JavaScriptCore/API/JSValueRef.cpp b/Source/JavaScriptCore/API/JSValueRef.cpp index bb92454bd..de84508c1 100644 --- a/Source/JavaScriptCore/API/JSValueRef.cpp +++ b/Source/JavaScriptCore/API/JSValueRef.cpp @@ -131,8 +131,8 @@ bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsCla if (JSObject* o = jsValue.getObject()) { if (o->inherits(&JSCallbackObject<JSGlobalObject>::s_info)) return jsCast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass); - if (o->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)) - return jsCast<JSCallbackObject<JSNonFinalObject>*>(o)->inherits(jsClass); + if (o->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)) + return jsCast<JSCallbackObject<JSDestructibleObject>*>(o)->inherits(jsClass); } return false; } @@ -235,11 +235,12 @@ JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) ExecState* exec = toJS(ctx); APIEntryShim entryShim(exec); String str = string->string(); - if (str.is8Bit()) { - LiteralParser<LChar> parser(exec, str.characters8(), str.length(), StrictJSON); + unsigned length = str.length(); + if (length && str.is8Bit()) { + LiteralParser<LChar> parser(exec, str.characters8(), length, StrictJSON); return toRef(exec, parser.tryLiteralParse()); } - LiteralParser<UChar> parser(exec, str.characters16(), str.length(), StrictJSON); + LiteralParser<UChar> parser(exec, str.characters(), length, StrictJSON); return toRef(exec, parser.tryLiteralParse()); } diff --git a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp b/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp index bfb006021..bdfce08ee 100644 --- a/Source/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp +++ b/Source/JavaScriptCore/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<JSGlobalObject>::s_info) || obj->inherits(&JSCallbackObject<JSNonFinalObject>::s_info)); + ASSERT(obj->inherits(&JSCallbackObject<JSGlobalObject>::s_info) || obj->inherits(&JSCallbackObject<JSDestructibleObject>::s_info)); map->map().set(exec->globalData(), key, obj); } diff --git a/Source/JavaScriptCore/API/OpaqueJSString.cpp b/Source/JavaScriptCore/API/OpaqueJSString.cpp index 457cb27f7..ac7cfd16a 100644 --- a/Source/JavaScriptCore/API/OpaqueJSString.cpp +++ b/Source/JavaScriptCore/API/OpaqueJSString.cpp @@ -35,21 +35,26 @@ using namespace JSC; PassRefPtr<OpaqueJSString> OpaqueJSString::create(const String& string) { if (!string.isNull()) - return adoptRef(new OpaqueJSString(string.characters(), string.length())); + return adoptRef(new OpaqueJSString(string)); return 0; } String OpaqueJSString::string() const { - if (this && m_characters) - return String(m_characters, m_length); - return String(); + if (!this) + return String(); + + // Return a copy of the wrapped string, because the caller may make it an Identifier. + return m_string.isolatedCopy(); } Identifier OpaqueJSString::identifier(JSGlobalData* globalData) const { - if (!this || !m_characters) + if (!this || !m_string.length()) return Identifier(globalData, static_cast<const char*>(0)); - return Identifier(globalData, m_characters, m_length); + if (m_string.is8Bit()) + return Identifier(globalData, m_string.characters8(), m_string.length()); + + return Identifier(globalData, m_string.characters16(), m_string.length()); } diff --git a/Source/JavaScriptCore/API/OpaqueJSString.h b/Source/JavaScriptCore/API/OpaqueJSString.h index 35543cdd6..36680388d 100644 --- a/Source/JavaScriptCore/API/OpaqueJSString.h +++ b/Source/JavaScriptCore/API/OpaqueJSString.h @@ -48,8 +48,8 @@ struct OpaqueJSString : public ThreadSafeRefCounted<OpaqueJSString> { JS_EXPORT_PRIVATE static PassRefPtr<OpaqueJSString> create(const String&); - UChar* characters() { return this ? m_characters : 0; } - unsigned length() { return this ? m_length : 0; } + const UChar* characters() { return !!this ? m_string.characters() : 0; } + unsigned length() { return !!this ? m_string.length() : 0; } String string() const; JSC::Identifier identifier(JSC::JSGlobalData*) const; @@ -58,25 +58,24 @@ private: friend class WTF::ThreadSafeRefCounted<OpaqueJSString>; OpaqueJSString() - : m_characters(0) - , m_length(0) { } - OpaqueJSString(const UChar* characters, unsigned length) - : m_length(length) + OpaqueJSString(const String& string) { - m_characters = new UChar[length]; - memcpy(m_characters, characters, length * sizeof(UChar)); + // Make a copy of the source string. + if (string.is8Bit()) + m_string = String(string.characters8(), string.length()); + else + m_string = String(string.characters16(), string.length()); } - ~OpaqueJSString() + OpaqueJSString(const UChar* characters, unsigned length) { - delete[] m_characters; + m_string = String(characters, length); } - UChar* m_characters; - unsigned m_length; + String m_string; }; #endif diff --git a/Source/JavaScriptCore/API/tests/minidom.c b/Source/JavaScriptCore/API/tests/minidom.c index 43ae2c1a8..bd3e119e5 100644 --- a/Source/JavaScriptCore/API/tests/minidom.c +++ b/Source/JavaScriptCore/API/tests/minidom.c @@ -30,6 +30,7 @@ #include "JSStringRef.h" #include <stdio.h> #include <stdlib.h> +#include <wtf/Platform.h> #include <wtf/Assertions.h> #include <wtf/UnusedParam.h> diff --git a/Source/JavaScriptCore/API/tests/testapi.c b/Source/JavaScriptCore/API/tests/testapi.c index 91978bbfd..b52a2b440 100644 --- a/Source/JavaScriptCore/API/tests/testapi.c +++ b/Source/JavaScriptCore/API/tests/testapi.c @@ -29,6 +29,7 @@ #include "JSObjectRefPrivate.h" #include <math.h> #define ASSERT_DISABLED 0 +#include <wtf/Platform.h> #include <wtf/Assertions.h> #include <wtf/UnusedParam.h> @@ -1131,6 +1132,22 @@ int main(int argc, char* argv[]) ASSERT(JSValueGetType(context, jsCFEmptyString) == kJSTypeString); ASSERT(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString); + JSStringRef nullString = JSStringCreateWithUTF8CString(0); + const JSChar* characters = JSStringGetCharactersPtr(nullString); + if (characters) { + printf("FAIL: Didn't return null when accessing character pointer of a null String.\n"); + failed = 1; + } else + printf("PASS: returned null when accessing character pointer of a null String.\n"); + + size_t length = JSStringGetLength(nullString); + if (length) { + printf("FAIL: Didn't return 0 length for null String.\n"); + failed = 1; + } else + printf("PASS: returned 0 length for null String.\n"); + JSStringRelease(nullString); + JSObjectRef propertyCatchalls = JSObjectMake(context, PropertyCatchalls_class(context), NULL); JSStringRef propertyCatchallsString = JSStringCreateWithUTF8CString("PropertyCatchalls"); JSObjectSetProperty(context, globalObject, propertyCatchallsString, propertyCatchalls, kJSPropertyAttributeNone, NULL); @@ -1208,6 +1225,15 @@ int main(int argc, char* argv[]) } else printf("PASS: Retrieved private property.\n"); + JSStringRef nullJSON = JSStringCreateWithUTF8CString(0); + JSValueRef nullJSONObject = JSValueMakeFromJSONString(context, nullJSON); + if (nullJSONObject) { + printf("FAIL: Did not parse null String as JSON correctly\n"); + failed = 1; + } else + printf("PASS: Parsed null String as JSON correctly.\n"); + JSStringRelease(nullJSON); + JSStringRef validJSON = JSStringCreateWithUTF8CString("{\"aProperty\":true}"); JSValueRef jsonObject = JSValueMakeFromJSONString(context, validJSON); JSStringRelease(validJSON); diff --git a/Source/JavaScriptCore/CMakeLists.txt b/Source/JavaScriptCore/CMakeLists.txt index 9a2e7b56c..4656c5aab 100644 --- a/Source/JavaScriptCore/CMakeLists.txt +++ b/Source/JavaScriptCore/CMakeLists.txt @@ -37,6 +37,7 @@ SET(JavaScriptCore_SOURCES API/JSWeakObjectMapRefPrivate.cpp API/OpaqueJSString.cpp + assembler/MacroAssembler.cpp assembler/LinkBuffer.cpp bytecode/ArrayProfile.cpp @@ -57,6 +58,7 @@ SET(JavaScriptCore_SOURCES bytecode/PutByIdStatus.cpp bytecode/ResolveGlobalStatus.cpp bytecode/SamplingTool.cpp + bytecode/SpecialPointer.cpp bytecode/StructureStubClearingWatchpoint.cpp bytecode/StructureStubInfo.cpp bytecode/Watchpoint.cpp @@ -105,12 +107,15 @@ SET(JavaScriptCore_SOURCES heap/BlockAllocator.cpp heap/CopiedSpace.cpp + heap/CopyVisitor.cpp heap/ConservativeRoots.cpp heap/DFGCodeBlocks.cpp + heap/GCThread.cpp heap/GCThreadSharedData.cpp heap/HandleSet.cpp heap/HandleStack.cpp heap/Heap.cpp + heap/HeapStatistics.cpp heap/HeapTimer.cpp heap/IncrementalSweeper.cpp heap/JITStubRoutineSet.cpp @@ -131,7 +136,7 @@ SET(JavaScriptCore_SOURCES interpreter/AbstractPC.cpp interpreter/CallFrame.cpp interpreter/Interpreter.cpp - interpreter/RegisterFile.cpp + interpreter/JSStack.cpp interpreter/VMInspector.cpp jit/ExecutableAllocator.cpp @@ -189,6 +194,7 @@ SET(JavaScriptCore_SOURCES runtime/GCActivityCallback.cpp runtime/GetterSetter.cpp runtime/Identifier.cpp + runtime/IndexingType.cpp runtime/InitializeThreading.cpp runtime/InternalFunction.cpp runtime/JSActivation.cpp @@ -201,7 +207,7 @@ SET(JavaScriptCore_SOURCES runtime/JSGlobalData.cpp runtime/JSGlobalObject.cpp runtime/JSGlobalObjectFunctions.cpp - runtime/JSGlobalThis.cpp + runtime/JSProxy.cpp runtime/JSLock.cpp runtime/JSNotAnObject.cpp runtime/JSObject.cpp diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index a5b548cab..69429a65d 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,2587 +1,1847 @@ -2012-09-25 Gavin Barraclough <barraclough@apple.com> +2012-10-16 Csaba Osztrogonác <ossy@webkit.org> - REGRESSION (r129456): http/tests/security/xss-eval.html is failing on JSC platforms - https://bugs.webkit.org/show_bug.cgi?id=97529 + Unreviewed, rolling out r131516 and r131550. + http://trac.webkit.org/changeset/131516 + http://trac.webkit.org/changeset/131550 + https://bugs.webkit.org/show_bug.cgi?id=99349 - Reviewed by Filip Pizlo. - - A recent patch changed JSC's EvalError behaviour; bring this more into line with other browsers. - - JSC currently throws an EvalError if you try to call eval with a this object that doesn't - match the given eval function. This does not match other browsers, which generally just - ignore the this value that was passed, and eval the string in the eval function's environment. - - * runtime/JSGlobalObjectFunctions.cpp: - (JSC::globalFuncEval): - - Remove EvalError, ignore passed this value. - -2012-09-25 Filip Pizlo <fpizlo@apple.com> - - DFG ArrayPush, ArrayPop don't handle clobbering or having a bad time correctly - https://bugs.webkit.org/show_bug.cgi?id=97535 - - Reviewed by Oliver Hunt. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleIntrinsic): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - -2012-09-25 Geoffrey Garen <ggaren@apple.com> - - JSC should dump object size inference statistics - https://bugs.webkit.org/show_bug.cgi?id=97618 - - Reviewed by Filip Pizlo. - - Added an option to dump object size inference statistics. - - To see statistics on live objects: - - jsc --showHeapStatistics=1 - - To see cumulative statistics on all objects ever allocated: - - jsc --showHeapStatistics=1 --objectsAreImmortal=1 - - (This is useful for showing GC churn caused by over-allocation.) - - To support this second mode, I refactored Zombies to separate out their - immortality feature so I could reuse it. - - * heap/Heap.cpp: - (JSC::MarkObject): Helper for making things immortal. We have to checked - for being zapped because blocks start out in this state. - - (JSC::StorageStatistics): Gather statistics by walking the heap. Ignore - arrays and hash tables for now because they're not our focus. (We'll - remove these exceptions in future.) - - (JSC::Heap::collect): Moved zombify to the end so it wouldn't interfere - with statistics gathering. - - (JSC::Heap::showStatistics): - (JSC::Heap::markAllObjects): Factored out helper, so statistics could - take advantage of immortal objects. - - (Zombify): Don't mark immortal objects -- that's another class's job now. - - (JSC::Zombify::operator()): - (JSC::Heap::zombifyDeadObjects): Take advantage of forEachDeadCell instead - of rolling our own. - - * heap/Heap.h: - (Heap): - * heap/MarkedSpace.h: - (MarkedSpace): - (JSC::MarkedSpace::forEachDeadCell): Added, so clients don't have to do - the iteration logic themselves. - - * runtime/Options.cpp: - (JSC::Options::initialize): - * runtime/Options.h: New options, listed above. Make sure to initialize - based on environment variable first, so we can override with specific settings. - -2012-09-25 Filip Pizlo <fpizlo@apple.com> - - We shouldn't use the optimized versions of shift/unshift if the user is doing crazy things to the array - https://bugs.webkit.org/show_bug.cgi?id=97603 - <rdar://problem/12370864> - - Reviewed by Gavin Barraclough. - - You changed the length behind our backs? No optimizations for you then! - - * runtime/ArrayPrototype.cpp: - (JSC::shift): - (JSC::unshift): - * runtime/JSArray.cpp: - (JSC::JSArray::shiftCount): - -2012-09-25 Filip Pizlo <fpizlo@apple.com> - - JSC bindings appear to sometimes ignore the possibility of arrays being in sparse mode - https://bugs.webkit.org/show_bug.cgi?id=95610 - - Reviewed by Oliver Hunt. - - Add better support for quickly accessing the indexed storage from bindings. - - * runtime/JSObject.h: - (JSC::JSObject::tryGetIndexQuickly): - (JSObject): - (JSC::JSObject::getDirectIndex): - (JSC::JSObject::getIndex): - -2012-09-25 Filip Pizlo <fpizlo@apple.com> - - Structure check hoisting phase doesn't know about the side-effecting nature of Arrayify - https://bugs.webkit.org/show_bug.cgi?id=97537 - - Reviewed by Mark Hahnenberg. - - No tests because if we use Arrayify then we also use PutByVal(BlankToXYZ), and the latter is - already known to be side-effecting. So this bug shouldn't have had any symptoms, as far as I - can tell. - - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - -2012-09-25 Gavin Barraclough <barraclough@apple.com> - - Regression: put beyond vector length prefers prototype setters to sparse properties - https://bugs.webkit.org/show_bug.cgi?id=97593 - - Reviewed by Geoff Garen & Filip Pizlo. - - * runtime/JSObject.cpp: - (JSC::JSObject::putByIndexBeyondVectorLength): - - Check for self properties in the sparse map - if present, don't examine the protochain. - -2012-09-24 Gavin Barraclough <barraclough@apple.com> - - https://bugs.webkit.org/show_bug.cgi?id=97530 - Regression, freeze applied to numeric properties of non-array objects - - Reviewed by Filip Pizlo. - - Object.freeze has a fast implementation in JSObject, but this hasn't been updated to take into account numeric properties in butterflies. - For now, just fall back to the generic implementation if the object has numeric properties. - - * runtime/ObjectConstructor.cpp: - (JSC::objectConstructorFreeze): - - fallback if the object has a non-zero indexed property vector length. - -2012-09-24 Gavin Barraclough <barraclough@apple.com> - - Bug in numeric accessors on global environment - https://bugs.webkit.org/show_bug.cgi?id=97526 - - Reviewed by Geoff Garen. - - I've hit this assert in test262 in browser, but haven't yet worked out how to repro in a test case :-/ - The sparsemap is failing to map back from the global object to the window shell. - A test case would need to resolve a numeric property name against the global environment. - - (JSC::SparseArrayEntry::get): - (JSC::SparseArrayEntry::put): - - Add missing toThisObject calls. - -2012-09-24 Filip Pizlo <fpizlo@apple.com> - - SerializedScriptValue isn't aware of indexed storage, but should be - https://bugs.webkit.org/show_bug.cgi?id=97515 - <rdar://problem/12361874> - - Reviewed by Sam Weinig. - - Export a method that WebCore now uses. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * runtime/JSObject.h: - (JSObject): - -2012-09-24 Gavin Barraclough <barraclough@apple.com> - - Remove JSObject::unwrappedGlobalObject(), JSObject::unwrappedObject() - https://bugs.webkit.org/show_bug.cgi?id=97519 - - Reviewed by Geoff Garen. - - unwrappedGlobalObject() was only needed because globalObject() doesn't always return a helpful result - - specifically for WebCore's window shell the structure's globalObject is set to null. We can fix this by - simply keeping the structure up to date as the window navigates, obviating the need for this function. - - The only other use of unwrappedObject() came from globalFuncEval(), and this can be trivially removed - by flipping the way we perform this globalObject check (which we may also be able to remove!) - instead - of getting the globalObject from the provided this value & comparing to the expected globalObject, we - can get the this value from the expected globalObject, and compare to that provided. - - * runtime/JSGlobalObject.cpp: - - Call globalObject() instead of unwrappedGlobalObject(). - * runtime/JSGlobalObjectFunctions.cpp: - (JSC::globalFuncEval): - - Changed to compare this object values, instead of globalObjects - - this means we only need to be able to map globalObject -> this, - and not vice versa. - * runtime/JSObject.cpp: - (JSC::JSObject::allowsAccessFrom): - (JSC::JSObject::createInheritorID): - - Call globalObject() instead of unwrappedGlobalObject(). - * runtime/JSObject.h: - (JSObject): - - Removed unwrappedGlobalObject(), unwrappedObject(). - -2012-09-24 Mark Lam <mark.lam@apple.com> - - Deleting the classic interpreter and cleaning up some build options. - https://bugs.webkit.org/show_bug.cgi?id=96969. - - Reviewed by Geoffrey Garen. + It caused zillion different problem on different platforms + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/CodeBlock.cpp: + (JSC): + (JSC::isGlobalResolve): + (JSC::instructionOffsetForNth): + (JSC::printGlobalResolveInfo): + (JSC::CodeBlock::printStructures): (JSC::CodeBlock::dump): + (JSC::CodeBlock::CodeBlock): + (JSC::CodeBlock::visitStructures): (JSC::CodeBlock::finalizeUnconditionally): - (JSC::CodeBlock::stronglyVisitStrongReferences): + (JSC::CodeBlock::hasGlobalResolveInfoAtBytecodeOffset): + (JSC::CodeBlock::globalResolveInfoForBytecodeOffset): + (JSC::CodeBlock::shrinkToFit): + * bytecode/CodeBlock.h: + (CodeBlock): + (JSC::CodeBlock::addGlobalResolveInstruction): + (JSC::CodeBlock::addGlobalResolveInfo): + (JSC::CodeBlock::globalResolveInfo): + (JSC::CodeBlock::numberOfGlobalResolveInfos): + (JSC::CodeBlock::globalResolveInfoCount): + * bytecode/GlobalResolveInfo.h: Copied from Source/JavaScriptCore/bytecode/ResolveGlobalStatus.cpp. (JSC): - * bytecode/Instruction.h: - (JSC::Instruction::Instruction): - * interpreter/AbstractPC.cpp: - (JSC::AbstractPC::AbstractPC): - * interpreter/AbstractPC.h: - (AbstractPC): - * interpreter/CallFrame.h: - (ExecState): - * interpreter/Interpreter.cpp: + (JSC::GlobalResolveInfo::GlobalResolveInfo): + (GlobalResolveInfo): + (JSC::getGlobalResolveInfoBytecodeOffset): + * bytecode/Opcode.h: (JSC): - (JSC::Interpreter::Interpreter): - (JSC::Interpreter::~Interpreter): - (JSC::Interpreter::initialize): - (JSC::Interpreter::isOpcode): - (JSC::Interpreter::unwindCallFrame): - (JSC::getLineNumberForCallFrame): - (JSC::getCallerInfo): - (JSC::getSourceURLFromCallFrame): - (JSC::Interpreter::execute): - (JSC::Interpreter::executeCall): - (JSC::Interpreter::executeConstruct): - (JSC::Interpreter::retrieveArgumentsFromVMCode): - (JSC::Interpreter::retrieveCallerFromVMCode): - (JSC::Interpreter::retrieveLastCaller): - * interpreter/Interpreter.h: - (JSC::Interpreter::getOpcodeID): - (Interpreter): - * jit/ExecutableAllocatorFixedVMPool.cpp: - (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator): - * offlineasm/asm.rb: - * offlineasm/offsets.rb: - * runtime/Executable.cpp: - (JSC::EvalExecutable::compileInternal): - (JSC::ProgramExecutable::compileInternal): - (JSC::FunctionExecutable::compileForCallInternal): - (JSC::FunctionExecutable::compileForConstructInternal): - * runtime/Executable.h: - (JSC::NativeExecutable::create): - (NativeExecutable): - (JSC::NativeExecutable::finishCreation): - * runtime/JSGlobalData.cpp: + (JSC::padOpcodeName): + * bytecode/ResolveGlobalStatus.cpp: (JSC): - (JSC::JSGlobalData::JSGlobalData): - (JSC::JSGlobalData::getHostFunction): - * runtime/JSGlobalData.h: - (JSGlobalData): - (JSC::JSGlobalData::canUseJIT): - (JSC::JSGlobalData::canUseRegExpJIT): - * runtime/Options.cpp: - (JSC::Options::initialize): - -2012-09-24 Filip Pizlo <fpizlo@apple.com> - - Nested try/finally should not confuse the finally unpopper in BytecodeGenerator::emitComplexJumpScopes - https://bugs.webkit.org/show_bug.cgi?id=97508 - <rdar://problem/12361132> - - Reviewed by Sam Weinig. - - We're reusing some vector for multiple iterations of a loop, but we were forgetting to clear its - contents from one iteration to the next. Hence if you did multiple iterations of finally unpopping - (like in a nested try/finally and a jump out of both of them) then you'd get a corrupted try - context stack afterwards. - + (JSC::computeForStructure): + (JSC::computeForLLInt): + (JSC::ResolveGlobalStatus::computeFor): + * bytecode/ResolveGlobalStatus.h: + (JSC): + (ResolveGlobalStatus): + * bytecode/ResolveOperation.h: Removed. * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitComplexJumpScopes): - -2012-09-24 Filip Pizlo <fpizlo@apple.com> - - ValueToInt32 bool case does bad things to registers - https://bugs.webkit.org/show_bug.cgi?id=97505 - <rdar://problem/12356331> - - Reviewed by Mark Hahnenberg. - - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileValueToInt32): - -2012-09-24 Mark Lam <mark.lam@apple.com> - - Add cloopDo instruction for debugging the llint C++ backend. - https://bugs.webkit.org/show_bug.cgi?id=97502. - - Reviewed by Geoffrey Garen. - - * offlineasm/cloop.rb: - * offlineasm/instructions.rb: - * offlineasm/parser.rb: - -2012-09-24 Filip Pizlo <fpizlo@apple.com> - - JSArray::putByIndex asserts with readonly property on prototype - https://bugs.webkit.org/show_bug.cgi?id=97435 - <rdar://problem/12357084> - - Reviewed by Geoffrey Garen. - - Boy, there were some problems: - - - putDirectIndex() should know that it can set the index quickly even if it's a hole and we're - in SlowPut mode, since that's the whole point of PutDirect. - - - We should have a fast path for putByIndex(). - - - The LiteralParser should not use push(), since that may throw if we're having a bad time. - - * interpreter/Interpreter.cpp: - (JSC::eval): - * runtime/JSObject.h: - (JSC::JSObject::putByIndexInline): - (JSObject): - (JSC::JSObject::putDirectIndex): - * runtime/LiteralParser.cpp: - (JSC::::parse): - -2012-09-24 Mark Lam <mark.lam@apple.com> - - Added a missing "if VALUE_PROFILER" around an access to ArrayProfile record. - https://bugs.webkit.org/show_bug.cgi?id=97496. - - Reviewed by Filip Pizlo. - - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-09-24 Geoffrey Garen <ggaren@apple.com> - - Inlined activation tear-off in the DFG - https://bugs.webkit.org/show_bug.cgi?id=97487 - - Reviewed by Filip Pizlo. - - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: Activation tear-off is always inlined now, so I - removed its out-of-line implementation. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): Inlined the variable copy and update - of JSVariableObject::m_registers. This usually turns into < 10 instructions, - which is close to pure win as compared to the operation function call. - - * runtime/JSActivation.h: - (JSActivation): - (JSC::JSActivation::registersOffset): - (JSC::JSActivation::tearOff): - (JSC::JSActivation::isTornOff): + (JSC::ResolveResult::checkValidity): + (JSC::ResolveResult::registerPointer): (JSC): - (JSC::JSActivation::storageOffset): - (JSC::JSActivation::storage): Tiny bit of refactoring so the JIT can - share the pointer math helper functions we use internally. - -2012-09-24 Balazs Kilvady <kilvadyb@homejinni.com> - - MIPS: store8 functions added to MacroAssembler. - - MIPS store8 functions - https://bugs.webkit.org/show_bug.cgi?id=97243 - - Reviewed by Oliver Hunt. - - Add MIPS store8 functions. - - * assembler/MIPSAssembler.h: - (JSC::MIPSAssembler::lhu): New function. - (MIPSAssembler): - (JSC::MIPSAssembler::sb): New function. - (JSC::MIPSAssembler::sh): New function. - * assembler/MacroAssemblerMIPS.h: - (JSC::MacroAssemblerMIPS::store8): New function. - (MacroAssemblerMIPS): - (JSC::MacroAssemblerMIPS::store16): New function. - -2012-09-23 Geoffrey Garen <ggaren@apple.com> - - PutScopedVar should not be marked as clobbering the world - https://bugs.webkit.org/show_bug.cgi?id=97416 - - Reviewed by Filip Pizlo. - - No performance change. - - PutScopedVar doesn't have arbitrary side-effects, so it shouldn't be marked - as such. - - * dfg/DFGNodeType.h: - (DFG): - -2012-09-23 Geoffrey Garen <ggaren@apple.com> - - I accidentally the whole 32-bit :(. - - Unbreak the DFG in 32-bit with the 32-bit path I forgot in my last patch. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-09-23 Byungwoo Lee <bw80.lee@gmail.com> - - Fix build warnings : -Wunused-parameter, -Wparentheses, -Wuninitialized. - https://bugs.webkit.org/show_bug.cgi?id=97306 - - Reviewed by Benjamin Poulain. - - Fix build warning about -Wunused-parameter on MachineStackMarker.cpp, - LLIntSlowPaths.cpp, DatePrototype.cpp, Options.cpp by using - UNUSED_PARAM() macro or remove parameter name. - - * heap/MachineStackMarker.cpp: - (JSC::pthreadSignalHandlerSuspendResume): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::entryOSR): - * runtime/DatePrototype.cpp: - (JSC::formatLocaleDate): - * runtime/Options.cpp: - (JSC::computeNumberOfGCMarkers): - -2012-09-23 Gavin Barraclough <barraclough@apple.com> - - Sorting a non-array creates propreties (spec-violation) - https://bugs.webkit.org/show_bug.cgi?id=25477 - - Reviewed by Oliver Hunt. - - We're just calling get() to get properties, which is converting missing properties to - undefined. Hole values should be retained, and moved to the end of the array. - - * runtime/ArrayPrototype.cpp: - (JSC::getOrHole): - - Helper function, returns JSValue() instead of undefined for missing properties. - (JSC::arrayProtoFuncSort): - - Implemented per 15.4.4.11, see comments above. - -2012-09-23 Geoffrey Garen <ggaren@apple.com> - - CSE for access to closure variables (get_/put_scoped_var) - https://bugs.webkit.org/show_bug.cgi?id=97414 - - Reviewed by Oliver Hunt. - - I separated loading a scope from loading its storage pointer, so we can - CSE the storage pointer load. Then, I copied the global var CSE and adjusted - it for closure vars. - + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::resolve): + (JSC::BytecodeGenerator::resolveConstDecl): + (JSC::BytecodeGenerator::shouldAvoidResolveGlobal): + (JSC::BytecodeGenerator::emitResolve): + (JSC::BytecodeGenerator::emitResolveBase): + (JSC::BytecodeGenerator::emitResolveBaseForPut): + (JSC::BytecodeGenerator::emitResolveWithBase): + (JSC::BytecodeGenerator::emitResolveWithThis): + (JSC::BytecodeGenerator::emitGetStaticVar): + (JSC::BytecodeGenerator::emitInitGlobalConst): + (JSC::BytecodeGenerator::emitPutStaticVar): + * bytecompiler/BytecodeGenerator.h: + (JSC::ResolveResult::registerResolve): + (JSC::ResolveResult::dynamicResolve): + (JSC::ResolveResult::lexicalResolve): + (JSC::ResolveResult::indexedGlobalResolve): + (JSC::ResolveResult::dynamicIndexedGlobalResolve): + (JSC::ResolveResult::globalResolve): + (JSC::ResolveResult::dynamicGlobalResolve): + (JSC::ResolveResult::type): + (JSC::ResolveResult::index): + (JSC::ResolveResult::depth): + (JSC::ResolveResult::globalObject): + (ResolveResult): + (JSC::ResolveResult::isStatic): + (JSC::ResolveResult::isIndexed): + (JSC::ResolveResult::isScoped): + (JSC::ResolveResult::isGlobal): + (JSC::ResolveResult::ResolveResult): + (BytecodeGenerator): + * bytecompiler/NodesCodegen.cpp: + (JSC::ResolveNode::isPure): + (JSC::FunctionCallResolveNode::emitBytecode): + (JSC::PostfixNode::emitResolve): + (JSC::PrefixNode::emitResolve): + (JSC::ReadModifyResolveNode::emitBytecode): + (JSC::AssignResolveNode::emitBytecode): + (JSC::ConstDeclNode::emitCodeSingle): + (JSC::ForInNode::emitBytecode): * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): Renamed GetScopeChain => GetScope to - reflect renames from a few weeks ago. - - Added a case for the storage pointer load, similar to object storage pointer load. - + (JSC::DFG::AbstractState::execute): * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): Added an independent node for - the storage pointer. - - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::scopedVarLoadElimination): - (CSEPhase): - (JSC::DFG::CSEPhase::scopedVarStoreElimination): - (JSC::DFG::CSEPhase::getScopeLoadElimination): - (JSC::DFG::CSEPhase::getScopeRegistersLoadElimination): - (JSC::DFG::CSEPhase::setLocalStoreElimination): - (JSC::DFG::CSEPhase::performNodeCSE): Copied globalVarLoad/StoreElimination - and adapted the same logic to closure vars. - + (ByteCodeParser): + (InlineStackEntry): + (JSC::DFG::ByteCodeParser::handleGetByOffset): + (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + (JSC::DFG::canInlineOpcode): + * dfg/DFGGraph.h: + (ResolveGlobalData): + (DFG): + (Graph): * dfg/DFGNode.h: - (JSC::DFG::Node::hasScopeChainDepth): - (JSC::DFG::Node::scope): - (Node): + (JSC::DFG::Node::hasIdentifier): * dfg/DFGNodeType.h: - (DFG): GetScopedVar and GetGlobalVar are no longer MustGenerate. I'm not - sure why they ever were. But these are simple load operations so, if they're - unused, they're truly dead. - + (DFG): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::OSRExit): + * dfg/DFGOSRExit.h: + (OSRExit): + * dfg/DFGOSRExitCompiler.cpp: + * dfg/DFGOSRExitCompiler32_64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGOSRExitCompiler64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + (JSC): * dfg/DFGPredictionPropagationPhase.cpp: (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGRepatch.cpp: + (JSC::DFG::tryCacheGetByID): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): Updated for renames and split-out - node for getting the storage pointer. - -2012-09-21 Geoffrey Garen <ggaren@apple.com> - - Unreviewed, rolled out a line I committed by accident. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::execute): - -2012-09-21 Geoffrey Garen <ggaren@apple.com> - - Optimized closures that capture arguments - https://bugs.webkit.org/show_bug.cgi?id=97358 - - Reviewed by Oliver Hunt. - - Previously, the activation object was responsible for capturing all - arguments in a way that was convenient for the arguments object. Now, - we move all captured variables into a contiguous region in the stack, - allocate an activation for exactly that size, and make the arguments - object responsible for knowing all the places to which arguments could - have moved. - - This seems like the right tradeoff because - - (a) Closures are common and long-lived, so we want them to be small. - - (b) Our primary strategy for optimizing the arguments object is to make - it go away. If you're allocating arguments objects, you're already having - a bad time. - - (c) It's common to use either the arguments object or named argument - closure, but not both. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - (JSC::CodeBlock::CodeBlock): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::argumentsRegister): - (JSC::CodeBlock::activationRegister): - (JSC::CodeBlock::isCaptured): - (JSC::CodeBlock::argumentIndexAfterCapture): m_numCapturedVars is gone - now -- we have an explicit range instead. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::BytecodeGenerator): Move captured arguments - into the captured region of local variables for space efficiency. Record - precise data about where they moved for the sake of the arguments object. - - Some of this data was previously wrong, but it didn't cause any problems - because the arguments weren't actually moving. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::flushArgumentsAndCapturedVariables): Don't - assume that captured vars are in any particular location -- always ask - the CodeBlock. This is better encapsulation. - - (JSC::DFG::ByteCodeParser::parseCodeBlock): - * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): I rename things sometimes. - - * runtime/Arguments.cpp: - (JSC::Arguments::tearOff): Account for a particularly nasty edge case. - - (JSC::Arguments::didTearOffActivation): Don't allocate our slow arguments - data on tear-off. We need to allocate it eagerly instead, since we need - to know about displaced, captured arguments during access before tear-off. - - * runtime/Arguments.h: - (JSC::Arguments::allocateSlowArguments): - (JSC::Arguments::argument): Tell our slow arguments array where all arguments - are, even if they are not captured. This simplifies some things, so we don't - have to account explicitly for the full matrix of (not torn off, torn off) - * (captured, not captured). - - (JSC::Arguments::finishCreation): Allocate our slow arguments array eagerly - because we need to know about displaced, captured arguments during access - before tear-off. - - * runtime/Executable.cpp: - (JSC::FunctionExecutable::FunctionExecutable): - (JSC::FunctionExecutable::compileForCallInternal): - (JSC::FunctionExecutable::compileForConstructInternal): - * runtime/Executable.h: - (JSC::FunctionExecutable::parameterCount): - (FunctionExecutable): - * runtime/JSActivation.cpp: - (JSC::JSActivation::visitChildren): - * runtime/JSActivation.h: - (JSActivation): - (JSC::JSActivation::create): - (JSC::JSActivation::JSActivation): - (JSC::JSActivation::registerOffset): - (JSC::JSActivation::tearOff): - (JSC::JSActivation::allocationSize): - (JSC::JSActivation::isValid): This is really the point of the patch. All - the pointer math in Activations basically boils away, since we always - copy a contiguous region of captured variables now. - - * runtime/SymbolTable.h: - (JSC::SlowArgument::SlowArgument): - (SlowArgument): - (SharedSymbolTable): - (JSC::SharedSymbolTable::captureCount): - (JSC::SharedSymbolTable::SharedSymbolTable): AllOfTheThings capture mode - is gone now -- that's the point of the patch. indexIfCaptured gets renamed - to index because we always have an index, even if not captured. (The only - time when the index is meaningless is when we're Deleted.) - -2012-09-21 Gavin Barraclough <barraclough@apple.com> + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + (JIT): + (JSC::JIT::emit_op_get_global_var_watchable): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_resolve): + (JSC): + (JSC::JIT::emit_op_resolve_base): + (JSC::JIT::emit_op_resolve_skip): + (JSC::JIT::emit_op_resolve_global): + (JSC::JIT::emitSlow_op_resolve_global): + (JSC::JIT::emit_op_resolve_with_base): + (JSC::JIT::emit_op_resolve_with_this): + (JSC::JIT::emit_op_resolve_global_dynamic): + (JSC::JIT::emitSlow_op_resolve_global_dynamic): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_resolve): + (JSC): + (JSC::JIT::emit_op_resolve_base): + (JSC::JIT::emit_op_resolve_skip): + (JSC::JIT::emit_op_resolve_global): + (JSC::JIT::emitSlow_op_resolve_global): + (JSC::JIT::emit_op_resolve_with_base): + (JSC::JIT::emit_op_resolve_with_this): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_scoped_var): + (JSC): + (JSC::JIT::emit_op_put_scoped_var): + (JSC::JIT::emit_op_get_global_var): + (JSC::JIT::emit_op_put_global_var): + (JSC::JIT::emit_op_put_global_var_check): + (JSC::JIT::emitSlow_op_put_global_var_check): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_scoped_var): + (JSC): + (JSC::JIT::emit_op_put_scoped_var): + (JSC::JIT::emit_op_get_global_var): + (JSC::JIT::emit_op_put_global_var): + (JSC::JIT::emit_op_put_global_var_check): + (JSC::JIT::emitSlow_op_put_global_var_check): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + (JSC): + * jit/JITStubs.h: + * llint/LLIntSlowPaths.cpp: + (LLInt): + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LLIntSlowPaths.h: + (LLInt): + * llint/LowLevelInterpreter.asm: + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/JSScope.cpp: + (JSC::JSScope::resolve): + (JSC::JSScope::resolveSkip): + (JSC::JSScope::resolveGlobal): + (JSC::JSScope::resolveGlobalDynamic): + (JSC::JSScope::resolveBase): + (JSC::JSScope::resolveWithBase): + (JSC::JSScope::resolveWithThis): + * runtime/JSScope.h: + (JSScope): + * runtime/JSVariableObject.cpp: + * runtime/JSVariableObject.h: + * runtime/Structure.h: - Eeeep - broke early boyer in bug#97382 - https://bugs.webkit.org/show_bug.cgi?id=97383 +2012-10-16 Dongwoo Joshua Im <dw.im@samsung.com> - Rubber stamped by Sam Weinig. + [GTK] Fix build break - ResolveOperations.h is not in WebKit. + https://bugs.webkit.org/show_bug.cgi?id=99538 - missed a child3 -> child2! + Unreviewed build fix. - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileInstanceOf): + There are some files including ResolveOperations.h which is not exist at all. -2012-09-21 Gavin Barraclough <barraclough@apple.com> + * GNUmakefile.list.am: s/ResolveOperations.h/ResolveOperation.h/ + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: s/ResolveOperations.h/ResolveOperation.h/ - Unreviewed windows build fix. +2012-10-16 Jian Li <jianli@chromium.org> - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + Rename feature define ENABLE_WIDGET_REGION to ENABLE_DRAGGBALE_REGION + https://bugs.webkit.org/show_bug.cgi?id=98975 -2012-09-21 Gavin Barraclough <barraclough@apple.com> + Reviewed by Adam Barth. - Pedantic test in Mozilla's JavaScript test suite fails. function-001.js function-001-n.js - https://bugs.webkit.org/show_bug.cgi?id=27219 + Renaming is needed to better match with the draggable region code. - Reviewed by Sam Weinig. + * Configurations/FeatureDefines.xcconfig: - These tests are just wrong. - See ECMA 262 A.5, FunctionDelcaration does not require a semicolon. +2012-10-15 Oliver Hunt <oliver@apple.com> - * tests/mozilla/expected.html: - * tests/mozilla/js1_2/function/function-001-n.js: - * tests/mozilla/js1_3/Script/function-001-n.js: - * tests/mozilla/js1_3/regress/function-001-n.js: + Bytecode should not have responsibility for determining how to perform non-local resolves + https://bugs.webkit.org/show_bug.cgi?id=99349 -2012-09-21 Gavin Barraclough <barraclough@apple.com> + Reviewed by Gavin Barraclough. - Remove redundant argument to op_instanceof - https://bugs.webkit.org/show_bug.cgi?id=97382 + This patch removes lexical analysis from the bytecode generation. This allows + us to delay lookup of a non-local variables until the lookup is actually necessary, + and simplifies a lot of the resolve logic in BytecodeGenerator. - Reviewed by Geoff Garen. + Once a lookup is performed we cache the lookup information in a set of out-of-line + buffers in CodeBlock. This allows subsequent lookups to avoid unnecessary hashing, + etc, and allows the respective JITs to recreated optimal lookup code. - No longer needed after my last change. + This is currently still a performance regression in LLInt, but most of the remaining + regression is caused by a lot of indirection that I'll remove in future work, as well + as some work necessary to allow LLInt to perform in line instruction repatching. + We will also want to improve the behaviour of the baseline JIT for some of the lookup + operations, however this patch was getting quite large already so I'm landing it now + that we've reached the bar of "performance-neutral". + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::printStructures): (JSC::CodeBlock::dump): + (JSC::CodeBlock::CodeBlock): + (JSC::CodeBlock::visitStructures): + (JSC): + (JSC::CodeBlock::finalizeUnconditionally): + (JSC::CodeBlock::shrinkToFit): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::addResolve): + (JSC::CodeBlock::addPutToBase): + (CodeBlock): + (JSC::CodeBlock::resolveOperations): + (JSC::CodeBlock::putToBaseOperation): + (JSC::CodeBlock::numberOfResolveOperations): + (JSC::CodeBlock::numberOfPutToBaseOperations): + (JSC::CodeBlock::addPropertyAccessInstruction): + (JSC::CodeBlock::globalObjectConstant): + (JSC::CodeBlock::setGlobalObjectConstant): + * bytecode/GlobalResolveInfo.h: Removed. * bytecode/Opcode.h: (JSC): (JSC::padOpcodeName): + * bytecode/ResolveGlobalStatus.cpp: + (JSC::computeForStructure): + (JSC::ResolveGlobalStatus::computeFor): + * bytecode/ResolveGlobalStatus.h: + (JSC): + (ResolveGlobalStatus): + * bytecode/ResolveOperation.h: Added. + The new types and logic we use to perform the cached lookups. + (JSC): + (ResolveOperation): + (JSC::ResolveOperation::getAndReturnScopedVar): + (JSC::ResolveOperation::checkForDynamicEntriesBeforeGlobalScope): + (JSC::ResolveOperation::getAndReturnGlobalVar): + (JSC::ResolveOperation::getAndReturnGlobalProperty): + (JSC::ResolveOperation::resolveFail): + (JSC::ResolveOperation::skipTopScopeNode): + (JSC::ResolveOperation::skipScopes): + (JSC::ResolveOperation::returnGlobalObjectAsBase): + (JSC::ResolveOperation::setBaseToGlobal): + (JSC::ResolveOperation::setBaseToUndefined): + (JSC::ResolveOperation::setBaseToScope): + (JSC::ResolveOperation::returnScopeAsBase): + (JSC::PutToBaseOperation::PutToBaseOperation): * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitInstanceOf): + (JSC::ResolveResult::checkValidity): + (JSC): + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::resolve): + (JSC::BytecodeGenerator::resolveConstDecl): + (JSC::BytecodeGenerator::shouldAvoidResolveGlobal): + (JSC::BytecodeGenerator::emitResolve): + (JSC::BytecodeGenerator::emitResolveBase): + (JSC::BytecodeGenerator::emitResolveBaseForPut): + (JSC::BytecodeGenerator::emitResolveWithBaseForPut): + (JSC::BytecodeGenerator::emitResolveWithThis): + (JSC::BytecodeGenerator::emitGetLocalVar): + (JSC::BytecodeGenerator::emitInitGlobalConst): + (JSC::BytecodeGenerator::emitPutToBase): * bytecompiler/BytecodeGenerator.h: + (JSC::ResolveResult::registerResolve): + (JSC::ResolveResult::dynamicResolve): + (ResolveResult): + (JSC::ResolveResult::ResolveResult): + (JSC): + (NonlocalResolveInfo): + (JSC::NonlocalResolveInfo::NonlocalResolveInfo): + (JSC::NonlocalResolveInfo::~NonlocalResolveInfo): + (JSC::NonlocalResolveInfo::resolved): + (JSC::NonlocalResolveInfo::put): (BytecodeGenerator): + (JSC::BytecodeGenerator::getResolveOperations): + (JSC::BytecodeGenerator::getResolveWithThisOperations): + (JSC::BytecodeGenerator::getResolveBaseOperations): + (JSC::BytecodeGenerator::getResolveBaseForPutOperations): + (JSC::BytecodeGenerator::getResolveWithBaseForPutOperations): + (JSC::BytecodeGenerator::getPutToBaseOperation): * bytecompiler/NodesCodegen.cpp: - (JSC::InstanceOfNode::emitBytecode): + (JSC::ResolveNode::isPure): + (JSC::FunctionCallResolveNode::emitBytecode): + (JSC::PostfixNode::emitResolve): + (JSC::PrefixNode::emitResolve): + (JSC::ReadModifyResolveNode::emitBytecode): + (JSC::AssignResolveNode::emitBytecode): + (JSC::ConstDeclNode::emitCodeSingle): + (JSC::ForInNode::emitBytecode): * dfg/DFGAbstractState.cpp: (JSC::DFG::AbstractState::execute): * dfg/DFGByteCodeParser.cpp: + (ByteCodeParser): + (InlineStackEntry): + (JSC::DFG::ByteCodeParser::handleGetByOffset): + (DFG): + (JSC::DFG::ByteCodeParser::parseResolveOperations): (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileResolveOperations): + (DFG): + (JSC::DFG::canCompilePutToBaseOperation): + (JSC::DFG::canCompileOpcode): + (JSC::DFG::canInlineOpcode): + * dfg/DFGGraph.h: + (ResolveGlobalData): + (ResolveOperationData): + (DFG): + (PutToBaseOperationData): + (Graph): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasIdentifier): + (JSC::DFG::Node::resolveOperationsDataIndex): + (Node): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::OSRExit): + * dfg/DFGOSRExit.h: + (OSRExit): + * dfg/DFGOSRExitCompiler.cpp: + * dfg/DFGOSRExitCompiler32_64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGOSRExitCompiler64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGRepatch.cpp: + (JSC::DFG::tryCacheGetByID): * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileInstanceOf): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): + (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::resolveOperations): + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::putToBaseOperation): + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + (JIT): * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_instanceof): - (JSC::JIT::emitSlow_op_instanceof): + (JSC::JIT::emit_op_put_to_base): + (JSC): + (JSC::JIT::emit_resolve_operations): + (JSC::JIT::emitSlow_link_resolve_operations): + (JSC::JIT::emit_op_resolve): + (JSC::JIT::emitSlow_op_resolve): + (JSC::JIT::emit_op_resolve_base): + (JSC::JIT::emitSlow_op_resolve_base): + (JSC::JIT::emit_op_resolve_with_base): + (JSC::JIT::emitSlow_op_resolve_with_base): + (JSC::JIT::emit_op_resolve_with_this): + (JSC::JIT::emitSlow_op_resolve_with_this): + (JSC::JIT::emitSlow_op_put_to_base): * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_instanceof): - (JSC::JIT::emitSlow_op_instanceof): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-09-21 Gavin Barraclough <barraclough@apple.com> - - Unreviewed windows build fix. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-09-21 Gavin Barraclough <barraclough@apple.com> - - instanceof should not get the prototype for non-default HasInstance - https://bugs.webkit.org/show_bug.cgi?id=68656 - - Reviewed by Oliver Hunt. - - Instanceof is currently implemented as a sequance of three opcodes: - check_has_instance - get_by_id(prototype) - op_instanceof - There are three interesting types of base value that instanceof can be applied to: - (A) Objects supporting default instanceof behaviour (functions, other than those created with bind) - (B) Objects overriding the default instancecof behaviour with a custom one (API objects, bound functions) - (C) Values that do not respond to the [[HasInstance]] trap. - Currently check_has_instance handles case (C), leaving the op_instanceof opcode to handle (A) & (B). There are - two problems with this apporach. Firstly, this is suboptimal for case (A), since we have to check for - hasInstance support twice (once in check_has_instance, then for default behaviour in op_instanceof). Secondly, - this means that in cases (B) we also perform the get_by_id, which is both suboptimal and an observable spec - violation. - - The fix here is to move handing of non-default instanceof (cases (B)) to the check_has_instance op, leaving - op_instanceof to handle only cases (A). - - * API/JSCallbackObject.h: - (JSCallbackObject): - * API/JSCallbackObjectFunctions.h: - (JSC::::customHasInstance): - * API/JSValueRef.cpp: - (JSValueIsInstanceOfConstructor): - - renamed hasInstance to customHasInstance - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - - added additional parameters to check_has_instance opcode - * bytecode/Opcode.h: + (JSC::JIT::emit_op_put_to_base): (JSC): - (JSC::padOpcodeName): - - added additional parameters to check_has_instance opcode - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitCheckHasInstance): - - added additional parameters to check_has_instance opcode - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - - added additional parameters to check_has_instance opcode - * bytecompiler/NodesCodegen.cpp: - (JSC::InstanceOfNode::emitBytecode): - - added additional parameters to check_has_instance opcode - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - - added additional parameters to check_has_instance opcode - * interpreter/Interpreter.cpp: - (JSC::isInvalidParamForIn): - (JSC::Interpreter::privateExecute): - - Add handling for non-default instanceof to op_check_has_instance - * jit/JITInlineMethods.h: - (JSC::JIT::emitArrayProfilingSiteForBytecodeIndex): - - Fixed no-LLInt no_DFG build - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_check_has_instance): - (JSC::JIT::emitSlow_op_check_has_instance): - - check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance. - (JSC::JIT::emit_op_instanceof): - (JSC::JIT::emitSlow_op_instanceof): - - no need to check for ImplementsDefaultHasInstance. - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_check_has_instance): - (JSC::JIT::emitSlow_op_check_has_instance): - - check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance. - (JSC::JIT::emit_op_instanceof): - (JSC::JIT::emitSlow_op_instanceof): - - no need to check for ImplementsDefaultHasInstance. + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_init_global_const): + (JSC::JIT::emit_op_init_global_const_check): + (JSC::JIT::emitSlow_op_init_global_const_check): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_init_global_const): + (JSC::JIT::emit_op_init_global_const_check): + (JSC::JIT::emitSlow_op_init_global_const_check): * jit/JITStubs.cpp: (JSC::DEFINE_STUB_FUNCTION): + (JSC): * jit/JITStubs.h: - - Add handling for non-default instanceof to op_check_has_instance * llint/LLIntSlowPaths.cpp: + (LLInt): (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LLIntSlowPaths.h: + (LLInt): + * llint/LowLevelInterpreter.asm: * llint/LowLevelInterpreter32_64.asm: * llint/LowLevelInterpreter64.asm: - - move check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance. - * runtime/ClassInfo.h: - (MethodTable): - (JSC): - - renamed hasInstance to customHasInstance - * runtime/CommonSlowPaths.h: - (CommonSlowPaths): - - removed opInstanceOfSlow (this was whittled down to one function call!) - * runtime/JSBoundFunction.cpp: - (JSC::JSBoundFunction::customHasInstance): - * runtime/JSBoundFunction.h: - (JSBoundFunction): - - renamed hasInstance to customHasInstance, reimplemented. - * runtime/JSCell.cpp: - (JSC::JSCell::customHasInstance): - * runtime/JSCell.h: - (JSCell): - * runtime/JSObject.cpp: - (JSC::JSObject::hasInstance): + * runtime/JSScope.cpp: + (JSC::LookupResult::base): + (JSC::LookupResult::value): + (JSC::LookupResult::setBase): + (JSC::LookupResult::setValue): + (LookupResult): + (JSC): + (JSC::setPutPropertyAccessOffset): + (JSC::executeResolveOperations): + (JSC::JSScope::resolveContainingScopeInternal): + (JSC::JSScope::resolveContainingScope): + (JSC::JSScope::resolve): + (JSC::JSScope::resolveBase): + (JSC::JSScope::resolveWithBase): + (JSC::JSScope::resolveWithThis): + (JSC::JSScope::resolvePut): + (JSC::JSScope::resolveGlobal): + * runtime/JSScope.h: + (JSScope): + * runtime/JSVariableObject.cpp: (JSC): - (JSC::JSObject::defaultHasInstance): - * runtime/JSObject.h: - (JSObject): - -2012-09-21 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, fix ARM build. - - * assembler/MacroAssemblerARMv7.h: - (JSC::MacroAssemblerARMv7::store8): - (MacroAssemblerARMv7): - * offlineasm/armv7.rb: + * runtime/JSVariableObject.h: + (JSVariableObject): + * runtime/Structure.h: + (JSC::Structure::propertyAccessesAreCacheable): + (Structure): -2012-09-21 Filip Pizlo <fpizlo@apple.com> +2012-10-16 Filip Pizlo <fpizlo@apple.com> - REGRESSION (r128400): Opening Google Web Fonts page hangs or crashes - https://bugs.webkit.org/show_bug.cgi?id=97328 + Accidental switch fall-through in DFG::FixupPhase + https://bugs.webkit.org/show_bug.cgi?id=96956 + <rdar://problem/12313242> Reviewed by Mark Hahnenberg. - It's a bad idea to emit stub code that reallocates property storage when we're in indexed - storage mode. DFGRepatch.cpp knew this and had the appropriate check in one of the places, - but it didn't have it in all of the places. - - This change also adds some more handy disassembly support, which I used to find the bug. - - * assembler/LinkBuffer.h: - (JSC): - * dfg/DFGRepatch.cpp: - (JSC::DFG::generateProtoChainAccessStub): - (JSC::DFG::tryCacheGetByID): - (JSC::DFG::tryBuildGetByIDList): - (JSC::DFG::emitPutReplaceStub): - (JSC::DFG::emitPutTransitionStub): - (JSC::DFG::tryCachePutByID): - * jit/JITStubRoutine.h: - (JSC): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): -2012-09-21 Filip Pizlo <fpizlo@apple.com> +2012-10-16 Filip Pizlo <fpizlo@apple.com> - DFG CSE assumes that a holy PutByVal does not interfere with GetArrayLength, when it clearly does - https://bugs.webkit.org/show_bug.cgi?id=97373 + GetScopedVar CSE matches dead GetScopedVar's leading to IR corruption + https://bugs.webkit.org/show_bug.cgi?id=99470 + <rdar://problem/12363698> Reviewed by Mark Hahnenberg. - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::pureCSE): - (JSC::DFG::CSEPhase::getArrayLengthElimination): - (JSC::DFG::CSEPhase::putStructureStoreElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGGraph.h: - (Graph): - -2012-09-21 Chris Rogers <crogers@google.com> + All it takes is to follow the "if (!shouldGenerate) continue" idiom and everything will be OK. - Add Web Audio support for deprecated/legacy APIs - https://bugs.webkit.org/show_bug.cgi?id=97050 - - Reviewed by Eric Carlson. - - * Configurations/FeatureDefines.xcconfig: + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::globalVarLoadElimination): + (JSC::DFG::CSEPhase::scopedVarLoadElimination): + (JSC::DFG::CSEPhase::globalVarWatchpointElimination): + (JSC::DFG::CSEPhase::getByValLoadElimination): + (JSC::DFG::CSEPhase::checkStructureElimination): + (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): + (JSC::DFG::CSEPhase::getByOffsetLoadElimination): -2012-09-21 Gavin Barraclough <barraclough@apple.com> +2012-10-16 Dima Gorbik <dgorbik@apple.com> - Global Math object should be configurable but isn't - https://bugs.webkit.org/show_bug.cgi?id=55343 + Remove Platform.h include from the header files. + https://bugs.webkit.org/show_bug.cgi?id=98665 - Reviewed by Oliver Hunt. + Reviewed by Eric Seidel. - This has no performance impact. + We don't want other clients that include WebKit headers to know about Platform.h. - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::reset): - - Make 'Math' a regular property. + * API/tests/minidom.c: + * API/tests/testapi.c: -2012-09-21 Chao-ying Fu <fu@mips.com> +2012-10-16 Balazs Kilvady <kilvadyb@homejinni.com> - Add MIPS or32 function - https://bugs.webkit.org/show_bug.cgi?id=97157 + Add missing MIPS functions to assembler. + https://bugs.webkit.org/show_bug.cgi?id=98856 - Reviewed by Gavin Barraclough. + Reviewed by Oliver Hunt. - Add a missing or32 function. + Implement missing functions in MacroAssemblerMIPS and MIPSAssembler. + * assembler/MIPSAssembler.h: + (JSC::MIPSAssembler::lb): + (MIPSAssembler): + (JSC::MIPSAssembler::lh): + (JSC::MIPSAssembler::cvtds): + (JSC::MIPSAssembler::cvtsd): + (JSC::MIPSAssembler::vmov): * assembler/MacroAssemblerMIPS.h: - (JSC::MacroAssemblerMIPS::or32): New function. (MacroAssemblerMIPS): + (JSC::MacroAssemblerMIPS::load8Signed): + (JSC::MacroAssemblerMIPS::load16Signed): + (JSC::MacroAssemblerMIPS::moveDoubleToInts): + (JSC::MacroAssemblerMIPS::moveIntsToDouble): + (JSC::MacroAssemblerMIPS::loadFloat): + (JSC::MacroAssemblerMIPS::loadDouble): + (JSC::MacroAssemblerMIPS::storeFloat): + (JSC::MacroAssemblerMIPS::storeDouble): + (JSC::MacroAssemblerMIPS::addDouble): + (JSC::MacroAssemblerMIPS::convertFloatToDouble): + (JSC::MacroAssemblerMIPS::convertDoubleToFloat): -2012-09-20 Filip Pizlo <fpizlo@apple.com> +2012-10-16 Balazs Kilvady <kilvadyb@homejinni.com> - CHECK_ARRAY_CONSISTENCY isn't being used or tested, so we should remove it - https://bugs.webkit.org/show_bug.cgi?id=97260 - - Rubber stamped by Geoffrey Garen. - - Supporting it will become difficult as we add more indexing types. It makes more - sense to kill, especially since we don't appear to use it or test it, ever. - - * runtime/ArrayConventions.h: - (JSC): - * runtime/ArrayPrototype.cpp: - (JSC::arrayProtoFuncSplice): - * runtime/ArrayStorage.h: - (JSC::ArrayStorage::copyHeaderFromDuringGC): - (ArrayStorage): - * runtime/FunctionPrototype.cpp: - (JSC::functionProtoFuncBind): - * runtime/JSArray.cpp: - (JSC::createArrayButterflyInDictionaryIndexingMode): - (JSC::JSArray::setLength): - (JSC::JSArray::pop): - (JSC::JSArray::push): - (JSC::JSArray::sortNumeric): - (JSC::JSArray::sort): - (JSC::JSArray::compactForSorting): - * runtime/JSArray.h: - (JSArray): - (JSC::createArrayButterfly): - (JSC::JSArray::tryCreateUninitialized): - (JSC::constructArray): - * runtime/JSObject.cpp: - (JSC::JSObject::putByIndex): - (JSC::JSObject::createArrayStorage): - (JSC::JSObject::deletePropertyByIndex): - (JSC): - * runtime/JSObject.h: - (JSC::JSObject::initializeIndex): - (JSObject): - -2012-09-20 Mark Lam <mark.lam@apple.com> - - Fixed a missing semicolon in the C++ llint backend. - https://bugs.webkit.org/show_bug.cgi?id=97252. - - Reviewed by Geoff Garen. - - * offlineasm/cloop.rb: - -2012-09-20 Geoffrey Garen <ggaren@apple.com> - - Refactored the interpreter and JIT so they don't dictate closure layout - https://bugs.webkit.org/show_bug.cgi?id=97221 + MIPS assembler coding-style fix. + https://bugs.webkit.org/show_bug.cgi?id=99359 Reviewed by Oliver Hunt. - Capture may change the location of an argument for space efficiency. This - patch removes static assumptions about argument location from the interpreter - and JIT. - - * bytecode/CodeBlock.h: - (JSC::CodeBlock::argumentIndexAfterCapture): - (JSC::ExecState::argumentAfterCapture): Factored out a helper function - so the compiler could share this logic. - - * bytecompiler/NodesCodegen.cpp: - (JSC::BracketAccessorNode::emitBytecode): Don't emit optimized bracket - access on arguments if a parameter has been captured by name. This case is - rare and, where I've seen it in the wild, the optimization mostly failed - anyway due to arguments escape, so I didn't feel like writing and testing - five copies of the code that would handle it in the baseline engines. + Coding style fix of existing MIPS assembler header files. - The DFG can still synthesize this optimization even if we don't emit the - optimized bytecode for it. + * assembler/MIPSAssembler.h: + (JSC::MIPSAssembler::addiu): + (JSC::MIPSAssembler::addu): + (JSC::MIPSAssembler::subu): + (JSC::MIPSAssembler::mul): + (JSC::MIPSAssembler::andInsn): + (JSC::MIPSAssembler::andi): + (JSC::MIPSAssembler::nor): + (JSC::MIPSAssembler::orInsn): + (JSC::MIPSAssembler::ori): + (JSC::MIPSAssembler::xorInsn): + (JSC::MIPSAssembler::xori): + (JSC::MIPSAssembler::slt): + (JSC::MIPSAssembler::sltu): + (JSC::MIPSAssembler::sltiu): + (JSC::MIPSAssembler::sll): + (JSC::MIPSAssembler::sllv): + (JSC::MIPSAssembler::sra): + (JSC::MIPSAssembler::srav): + (JSC::MIPSAssembler::srl): + (JSC::MIPSAssembler::srlv): + (JSC::MIPSAssembler::lbu): + (JSC::MIPSAssembler::lw): + (JSC::MIPSAssembler::lwl): + (JSC::MIPSAssembler::lwr): + (JSC::MIPSAssembler::lhu): + (JSC::MIPSAssembler::sb): + (JSC::MIPSAssembler::sh): + (JSC::MIPSAssembler::sw): + (JSC::MIPSAssembler::addd): + (JSC::MIPSAssembler::subd): + (JSC::MIPSAssembler::muld): + (JSC::MIPSAssembler::divd): + (JSC::MIPSAssembler::lwc1): + (JSC::MIPSAssembler::ldc1): + (JSC::MIPSAssembler::swc1): + (JSC::MIPSAssembler::sdc1): + (MIPSAssembler): + (JSC::MIPSAssembler::relocateJumps): + (JSC::MIPSAssembler::linkWithOffset): + * assembler/MacroAssemblerMIPS.h: + (JSC::MacroAssemblerMIPS::add32): + (JSC::MacroAssemblerMIPS::and32): + (JSC::MacroAssemblerMIPS::sub32): + (MacroAssemblerMIPS): + (JSC::MacroAssemblerMIPS::load8): + (JSC::MacroAssemblerMIPS::load32): + (JSC::MacroAssemblerMIPS::load32WithUnalignedHalfWords): + (JSC::MacroAssemblerMIPS::load16): + (JSC::MacroAssemblerMIPS::store8): + (JSC::MacroAssemblerMIPS::store16): + (JSC::MacroAssemblerMIPS::store32): + (JSC::MacroAssemblerMIPS::nearCall): + (JSC::MacroAssemblerMIPS::test8): + (JSC::MacroAssemblerMIPS::test32): + +2012-10-16 Yuqiang Xian <yuqiang.xian@intel.com> + + Refactor MacroAssembler interfaces to differentiate the pointer operands from the 64-bit integer operands + https://bugs.webkit.org/show_bug.cgi?id=99154 - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - * dfg/DFGAssemblyHelpers.h: - (JSC::DFG::AssemblyHelpers::symbolTableFor): - (AssemblyHelpers): Use the right helper function to account for the fact - that a parameter may have been captured by name and moved. + Reviewed by Gavin Barraclough. - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): ASSERT that we haven't inlined - a .apply on captured arguments. Once we do start inlining such things, - we'll need to do a little bit of math here to get them right. + In current JavaScriptCore implementation for JSVALUE64 platform (i.e., + the X64 platform), we assume that the JSValue size is same to the + pointer size, and thus EncodedJSValue is simply type defined as a + "void*". In the JIT compiler, we also take this assumption and invoke + the same macro assembler interfaces for both JSValue and pointer + operands. We need to differentiate the operations on pointers from the + operations on JSValues, and let them invoking different macro + assembler interfaces. For example, we now use the interface of + "loadPtr" to load either a pointer or a JSValue, and we need to switch + to using "loadPtr" to load a pointer and some new "load64" interface + to load a JSValue. This would help us supporting other JSVALUE64 + platforms where pointer size is not necessarily 64-bits, for example + x32 (bug #99153). + + The major modification I made is to introduce the "*64" interfaces in + the MacroAssembler for those operations on JSValues, keep the "*Ptr" + interfaces for those operations on real pointers, and go through all + the JIT compiler code to correct the usage. + + This is the first part of the work, i.e, to add the *64 interfaces to + the MacroAssembler. + + * assembler/AbstractMacroAssembler.h: Add the Imm64 interfaces. + (AbstractMacroAssembler): + (JSC::AbstractMacroAssembler::TrustedImm64::TrustedImm64): + (TrustedImm64): + (JSC::AbstractMacroAssembler::Imm64::Imm64): + (Imm64): + (JSC::AbstractMacroAssembler::Imm64::asTrustedImm64): + * assembler/MacroAssembler.h: map <foo>Ptr methods to <foo>64 for X86_64. + (MacroAssembler): + (JSC::MacroAssembler::peek64): + (JSC::MacroAssembler::poke): + (JSC::MacroAssembler::poke64): + (JSC::MacroAssembler::addPtr): + (JSC::MacroAssembler::andPtr): + (JSC::MacroAssembler::negPtr): + (JSC::MacroAssembler::orPtr): + (JSC::MacroAssembler::rotateRightPtr): + (JSC::MacroAssembler::subPtr): + (JSC::MacroAssembler::xorPtr): + (JSC::MacroAssembler::loadPtr): + (JSC::MacroAssembler::loadPtrWithAddressOffsetPatch): + (JSC::MacroAssembler::loadPtrWithCompactAddressOffsetPatch): + (JSC::MacroAssembler::storePtr): + (JSC::MacroAssembler::storePtrWithAddressOffsetPatch): + (JSC::MacroAssembler::movePtrToDouble): + (JSC::MacroAssembler::moveDoubleToPtr): + (JSC::MacroAssembler::comparePtr): + (JSC::MacroAssembler::testPtr): + (JSC::MacroAssembler::branchPtr): + (JSC::MacroAssembler::branchTestPtr): + (JSC::MacroAssembler::branchAddPtr): + (JSC::MacroAssembler::branchSubPtr): + (JSC::MacroAssembler::shouldBlindDouble): + (JSC::MacroAssembler::shouldBlind): + (JSC::MacroAssembler::RotatedImm64::RotatedImm64): + (RotatedImm64): + (JSC::MacroAssembler::rotationBlindConstant): + (JSC::MacroAssembler::loadRotationBlindedConstant): + (JSC::MacroAssembler::move): + (JSC::MacroAssembler::and64): + (JSC::MacroAssembler::store64): + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::shouldBlindForSpecificArch): + (MacroAssemblerX86Common): + (JSC::MacroAssemblerX86Common::move): + * assembler/MacroAssemblerX86_64.h: Add the <foo>64 methods for X86_64. + (JSC::MacroAssemblerX86_64::branchAdd32): + (JSC::MacroAssemblerX86_64::add64): + (MacroAssemblerX86_64): + (JSC::MacroAssemblerX86_64::and64): + (JSC::MacroAssemblerX86_64::neg64): + (JSC::MacroAssemblerX86_64::or64): + (JSC::MacroAssemblerX86_64::rotateRight64): + (JSC::MacroAssemblerX86_64::sub64): + (JSC::MacroAssemblerX86_64::xor64): + (JSC::MacroAssemblerX86_64::load64): + (JSC::MacroAssemblerX86_64::load64WithAddressOffsetPatch): + (JSC::MacroAssemblerX86_64::load64WithCompactAddressOffsetPatch): + (JSC::MacroAssemblerX86_64::store64): + (JSC::MacroAssemblerX86_64::store64WithAddressOffsetPatch): + (JSC::MacroAssemblerX86_64::move64ToDouble): + (JSC::MacroAssemblerX86_64::moveDoubleTo64): + (JSC::MacroAssemblerX86_64::compare64): + (JSC::MacroAssemblerX86_64::branch64): + (JSC::MacroAssemblerX86_64::branchTest64): + (JSC::MacroAssemblerX86_64::test64): + (JSC::MacroAssemblerX86_64::branchAdd64): + (JSC::MacroAssemblerX86_64::branchSub64): + (JSC::MacroAssemblerX86_64::branchPtrWithPatch): + (JSC::MacroAssemblerX86_64::storePtrWithPatch): + +2012-10-15 Mark Hahnenberg <mhahnenberg@apple.com> + + Make CopiedSpace and MarkedSpace regions independent + https://bugs.webkit.org/show_bug.cgi?id=99222 - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): Added support for bracket access on - an arguments object where arguments have also been captured by name. We - load the true index of the argument from a side vector. Arguments elision - is very powerful in the DFG, so I wanted to keep it working, even in this - rare case. + Reviewed by Filip Pizlo. - * interpreter/Interpreter.cpp: - (JSC::loadVarargs): Use the right helper function to account for the fact - that a parameter may have been captured by name and moved. + Right now CopiedSpace and MarkedSpace have the same block size and share the same regions, + but there's no reason that they can't have different block sizes while still sharing the + same underlying regions. We should factor the two "used" lists of regions apart so that + MarkedBlocks and CopiedBlocks can be different sizes. Regions will still be a uniform size + so that when they become empty they may be shared between the CopiedSpace and the MarkedSpace, + since benchmarks indicate that sharing is a boon for performance. - * jit/JITCall.cpp: - (JSC::JIT::compileLoadVarargs): - * jit/JITCall32_64.cpp: - (JSC::JIT::compileLoadVarargs): Don't use the inline copy loop if some - of our arguments have moved, since it would copy stale values. (We still - optimize the actual call, and elide the arguments object.) + * heap/BlockAllocator.cpp: + (JSC::BlockAllocator::BlockAllocator): + * heap/BlockAllocator.h: + (JSC): + (Region): + (JSC::Region::create): We now have a fixed size for Regions so that empty regions can continue to + be shared between the MarkedSpace and CopiedSpace. Once they are used for a specific type of block, + however, they can only be used for that type of block until they become empty again. + (JSC::Region::createCustomSize): + (JSC::Region::Region): + (JSC::Region::~Region): + (JSC::Region::reset): + (BlockAllocator): + (JSC::BlockAllocator::RegionSet::RegionSet): + (RegionSet): + (JSC::BlockAllocator::tryAllocateFromRegion): We change this function so that it correctly + moves blocks between empty, partial, and full lists. + (JSC::BlockAllocator::allocate): + (JSC::BlockAllocator::allocateCustomSize): + (JSC::BlockAllocator::deallocate): Ditto. + (JSC::CopiedBlock): + (JSC::MarkedBlock): + (JSC::BlockAllocator::regionSetFor): We use this so that we can use the same allocate/deallocate + functions with different RegionSets. We specialize the function for each type of block that we + want to allocate. + * heap/CopiedBlock.h: + (CopiedBlock): + * heap/CopiedSpace.h: + (CopiedSpace): + * heap/HeapBlock.h: + (HeapBlock): + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::MarkedBlock): For oversize MarkedBlocks, if the block size gets too big we can + underflow the endAtom, which will cause us to segfault when we try to sweep a block. If we're a + custom size MarkedBlock we need to calculate endAtom so it doesn't underflow. -2012-09-20 Gabor Rapcsanyi <rgabor@webkit.org> +2012-10-14 Filip Pizlo <fpizlo@apple.com> - [Qt] r129045 broke the ARM build - https://bugs.webkit.org/show_bug.cgi?id=97195 + JIT::JIT fails to initialize all of its fields + https://bugs.webkit.org/show_bug.cgi?id=99283 - Reviewed by Zoltan Herczeg. + Reviewed by Andreas Kling. - Implementing missing store8 function. + There were two groups of such fields, all of which are eventually initialized + prior to use inside of privateCompile(). But it's safer to make sure that they + are initialized in the constructor as well, since we may use the JIT to do a + stub compile without calling into privateCompile(). + + Unsigned index fields for dynamic repatching meta-data: this change + initializes them to UINT_MAX, so we should crash if we try to use those + indices without initializing them. + + Boolean flags for value profiling: this change initializes them to false, so + we at worst turn off value profiling. - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::store8): - (MacroAssemblerARM): + * jit/JIT.cpp: + (JSC::JIT::JIT): -2012-09-19 Geoffrey Garen <ggaren@apple.com> +2012-10-15 Mark Hahnenberg <mhahnenberg@apple.com> - OSR exit sometimes neglects to create the arguments object - https://bugs.webkit.org/show_bug.cgi?id=97162 + We should avoid weakCompareAndSwap when parallel GC is disabled + https://bugs.webkit.org/show_bug.cgi?id=99331 Reviewed by Filip Pizlo. - No performance change. - - I don't know of any case where this is a real problem in TOT, but it - will become a problem if we start compiling eval, with, or catch, and/or - sometimes stop doing arguments optimizations in the bytecode. - - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): Account for a - CreateArguments that has transformed into PhantomArguments. We used to - clear our reference to the CreateArguments node, but now we hold onto it, - so we need to account for it transforming. - - Don't replace a SetLocal(CreateArguments) with a SetLocal(JSValue()) - because that doesn't leave enough information behind for OSR exit to do - the right thing. Instead, maintain our reference to CreateArguments, and - rely on CreateArguments transforming into PhantomArguments after - optimization. SetLocal(PhantomArguments) is efficient, and it's a marker - for OSR exit to create the arguments object. - - Don't ASSERT that all PhantomArguments are unreferenced because we now - leave them in the graph as SetLocal(PhantomArguments), and that's harmless. - - * dfg/DFGArgumentsSimplificationPhase.h: - (NullableHashTraits): - (JSC::DFG::NullableHashTraits::emptyValue): Export our special hash table - for inline call frames so the OSR exit compiler can use it. - - * dfg/DFGOSRExitCompiler32_64.cpp: - (JSC::DFG::OSRExitCompiler::compileExit): - * dfg/DFGOSRExitCompiler64.cpp: - (JSC::DFG::OSRExitCompiler::compileExit): Don't load the 'arguments' - register to decide if we need to create the arguments object. Optimization - may have eliminated the initializing store to this register, in which - case we'll load garbage. Instead, use the global knowledge that all call - frames that optimized out 'arguments' now need to create it, and use a hash - table to make sure we do so only once per call frame. - - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): SetLocal(PhantomArguments) is unique - because we haven't just changed a value's format or elided a load or store; - instead, we've replaced an object with JSValue(). We could try to account - for this in a general way, but for now it's a special-case optimization, - so we give it a specific OSR hint instead. - -2012-09-19 Filip Pizlo <fpizlo@apple.com> - - REGRESSION(r128802): It made some JS tests crash - https://bugs.webkit.org/show_bug.cgi?id=97001 + CopiedBlock::reportLiveBytes and didEvacuateBytes uses weakCompareAndSwap, which some platforms + don't support. For platforms that don't have parallel GC enabled, we should just use a normal store. - Reviewed by Mark Hahnenberg. - - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::visitChildren): - -2012-09-19 Filip Pizlo <fpizlo@apple.com> + * heap/CopiedBlock.h: + (JSC::CopiedBlock::reportLiveBytes): + (JSC::CopiedBlock::didEvacuateBytes): - DFG should not assume that a ByVal access is generic just because it was unprofiled - https://bugs.webkit.org/show_bug.cgi?id=97088 +2012-10-15 Carlos Garcia Campos <cgarcia@igalia.com> - Reviewed by Geoffrey Garen. - - We were not disambiguating between "Undecided" in the sense that the array profile - has no useful information versus "Undecided" in the sense that the array profile - knows that the access has not executed. That's an important distinction, since - the former form of "Undecided" means that we should consult value profiling, while - the latter means that we should force exit unless the value profiling indicates - that the access must be generic (base is not cell or property is not int). + Unreviewed. Fix make distcheck. - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGArrayMode.cpp: - (JSC::DFG::fromObserved): - (JSC::DFG::refineArrayMode): - (JSC::DFG::modeAlreadyChecked): - (JSC::DFG::modeToString): - * dfg/DFGArrayMode.h: - (JSC::DFG::canCSEStorage): - (JSC::DFG::modeIsSpecific): - (JSC::DFG::modeSupportsLength): - (JSC::DFG::benefitsFromStructureCheck): + * GNUmakefile.list.am: Add missing header file. -2012-09-19 Filip Pizlo <fpizlo@apple.com> +2012-10-14 Filip Pizlo <fpizlo@apple.com> - DFG should not emit PutByVal hole case unless it has to - https://bugs.webkit.org/show_bug.cgi?id=97080 + DFG should handle polymorphic array modes by eagerly transforming arrays into the most general applicable form + https://bugs.webkit.org/show_bug.cgi?id=99269 Reviewed by Geoffrey Garen. - This causes us to generate less code for typical PutByVal's. But if profiling tells us - that the hole case is being hit, we generate the same code as we would have generated - before. This seems like a slight speed-up across the board. + This kills off a bunch of code for "polymorphic" array modes in the DFG. It should + also be a performance win for code that uses a lot of array storage arrays. - * assembler/MacroAssemblerARMv7.h: - (JSC::MacroAssemblerARMv7::store8): - (MacroAssemblerARMv7): - * assembler/MacroAssemblerX86.h: - (MacroAssemblerX86): - (JSC::MacroAssemblerX86::store8): - * assembler/MacroAssemblerX86_64.h: - (MacroAssemblerX86_64): - (JSC::MacroAssemblerX86_64::store8): - * assembler/X86Assembler.h: - (X86Assembler): - (JSC::X86Assembler::movb_i8m): - * bytecode/ArrayProfile.h: - (JSC::ArrayProfile::ArrayProfile): - (JSC::ArrayProfile::addressOfMayStoreToHole): - (JSC::ArrayProfile::mayStoreToHole): - (ArrayProfile): - * dfg/DFGArrayMode.cpp: - (JSC::DFG::fromObserved): - (JSC::DFG::modeAlreadyChecked): - (JSC::DFG::modeToString): - * dfg/DFGArrayMode.h: - (DFG): - (JSC::DFG::mayStoreToHole): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JIT.h: - (JIT): - * jit/JITInlineMethods.h: - (JSC::JIT::emitArrayProfileStoreToHoleSpecialCase): - (JSC): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::emit_op_put_by_val): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::emit_op_put_by_val): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-09-18 Filip Pizlo <fpizlo@apple.com> - - DFG should not call out to C++ every time that it tries to put to an object that doesn't yet have array storage - https://bugs.webkit.org/show_bug.cgi?id=96983 - - Reviewed by Oliver Hunt. - - Introduce more polymorphism into the DFG's array mode support. Use that to - introduce the notion of effectul array modes, where the check for the mode - will perform actions necessary to ensure that we have the mode we want, if - the object is not already in that mode. Also added profiling support for - checking if an object is of a type that would not allow us to create array - storage (like a typed array or a string for example). - - This is a ~2x speed-up on loops that transform an object that did not have - indexed storage into one that does. - - * JSCTypedArrayStubs.h: - (JSC): - * bytecode/ArrayProfile.cpp: - (JSC::ArrayProfile::computeUpdatedPrediction): - * bytecode/ArrayProfile.h: - (JSC::ArrayProfile::ArrayProfile): - (JSC::ArrayProfile::mayInterceptIndexedAccesses): - (ArrayProfile): * dfg/DFGAbstractState.cpp: (JSC::DFG::AbstractState::execute): * dfg/DFGArrayMode.cpp: (JSC::DFG::fromObserved): - (DFG): (JSC::DFG::modeAlreadyChecked): (JSC::DFG::modeToString): * dfg/DFGArrayMode.h: (DFG): (JSC::DFG::modeUsesButterfly): - (JSC::DFG::isSlowPutAccess): + (JSC::DFG::modeIsJSArray): + (JSC::DFG::mayStoreToTail): + (JSC::DFG::mayStoreToHole): + (JSC::DFG::canCSEStorage): + (JSC::DFG::modeSupportsLength): (JSC::DFG::benefitsFromStructureCheck): - (JSC::DFG::isEffectful): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::getArrayMode): - (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks): - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): (JSC::DFG::FixupPhase::checkArray): + (JSC::DFG::FixupPhase::blessArrayOperation): * dfg/DFGGraph.h: (JSC::DFG::Graph::byValIsPure): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasArrayMode): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode): (JSC::DFG::SpeculativeJIT::checkArray): (JSC::DFG::SpeculativeJIT::arrayify): (DFG): + (JSC::DFG::SpeculativeJIT::compileGetArrayLength): * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::putByValWillNeedExtraRegister): (SpeculativeJIT): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): - * runtime/Arguments.h: - (Arguments): - * runtime/JSNotAnObject.h: - (JSNotAnObject): - * runtime/JSObject.h: - (JSObject): - (JSC::JSObject::ensureArrayStorage): - * runtime/JSString.h: - (JSC::JSString::createStructure): -2012-09-18 Filip Pizlo <fpizlo@apple.com> +2012-10-14 Filip Pizlo <fpizlo@apple.com> - Include PhantomArguments in DFGDisassembly - https://bugs.webkit.org/show_bug.cgi?id=97043 + REGRESSION(126886): Fat binary builds don't know how to handle architecture variants to which the LLInt is agnostic + https://bugs.webkit.org/show_bug.cgi?id=99270 Reviewed by Geoffrey Garen. - * dfg/DFGNode.h: - (JSC::DFG::Node::willHaveCodeGenOrOSR): + The fix is to hash cons the offsets based on configuration index, not the offsets + themselves. -2012-09-18 Filip Pizlo <fpizlo@apple.com> + * offlineasm/offsets.rb: - REGRESSION(r128802): It made some JS tests crash - https://bugs.webkit.org/show_bug.cgi?id=97001 +2012-10-13 Filip Pizlo <fpizlo@apple.com> - Reviewed by Mark Hahnenberg. + IndexingType should not have a bit for each type + https://bugs.webkit.org/show_bug.cgi?id=98997 - IndexingHeaderInlineMethods was incorrectly assuming that if the HasArrayStorage bit is clear, then that means that indexing payload capacity is zero. + Reviewed by Oliver Hunt. - * runtime/IndexingHeaderInlineMethods.h: - (JSC::IndexingHeader::preCapacity): - (JSC::IndexingHeader::indexingPayloadSizeInBytes): + Somewhat incidentally, the introduction of butterflies led to each indexing + type being represented by a unique bit. This is superficially nice since it + allows you to test if a structure corresponds to a particular indexing type + by saying !!(structure->indexingType() & TheType). But the downside is that + given the 8 bits we have for the m_indexingType field, that leaves only a + small number of possible indexing types if we have one per bit. + + This changeset changes the indexing type to be: + + Bit #1: Tells you if you're an array. + + Bits #2 - #5: 16 possible indexing types, including the blank type for + objects that don't have indexed properties. + + Bits #6-8: Auxiliary bits that we could use for other things. Currently we + just use one of those bits, for MayHaveIndexedAccessors. + + This is performance-neutral, and is primarily intended to give us more + breathing room for introducing new inferred array modes. -2012-09-18 Mark Hahnenberg <mhahnenberg@apple.com> + * assembler/AbstractMacroAssembler.h: + (JSC::AbstractMacroAssembler::JumpList::jumps): + * assembler/MacroAssembler.h: + (MacroAssembler): + (JSC::MacroAssembler::patchableBranch32): + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::patchableBranch32): + (MacroAssemblerARMv7): + * dfg/DFGArrayMode.cpp: + (JSC::DFG::modeAlreadyChecked): + * dfg/DFGRepatch.cpp: + (JSC::DFG::tryCacheGetByID): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::speculationCheck): + (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): + (JSC::DFG::SpeculativeJIT::jumpSlowForUnwantedArrayMode): + (DFG): + (JSC::DFG::SpeculativeJIT::checkArray): + (JSC::DFG::SpeculativeJIT::arrayify): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateJSArray): + (JSC::JIT::chooseArrayMode): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emitContiguousGetByVal): + (JSC::JIT::emitArrayStorageGetByVal): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::emitContiguousPutByVal): + (JSC::JIT::emitArrayStoragePutByVal): + (JSC::JIT::privateCompilePatchGetArrayLength): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emitContiguousGetByVal): + (JSC::JIT::emitArrayStorageGetByVal): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::emitContiguousPutByVal): + (JSC::JIT::emitArrayStoragePutByVal): + (JSC::JIT::privateCompilePatchGetArrayLength): + * llint/LowLevelInterpreter.asm: + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/IndexingType.h: + (JSC): + (JSC::hasIndexedProperties): + (JSC::hasContiguous): + (JSC::hasFastArrayStorage): + (JSC::hasArrayStorage): + (JSC::shouldUseSlowPut): + * runtime/JSGlobalObject.cpp: + (JSC): + * runtime/StructureTransitionTable.h: + (JSC::newIndexingType): - Use WTF::HasTrivialDestructor instead of compiler-specific versions in JSC::NeedsDestructor - https://bugs.webkit.org/show_bug.cgi?id=96980 +2012-10-14 Filip Pizlo <fpizlo@apple.com> - Reviewed by Benjamin Poulain. + DFG structure check hoisting should attempt to ignore side effects and make transformations that are sound even in their presence + https://bugs.webkit.org/show_bug.cgi?id=99262 - * runtime/JSCell.h: - (JSC): - (NeedsDestructor): + Reviewed by Oliver Hunt. -2012-09-18 Filip Pizlo <fpizlo@apple.com> + This hugely simplifies the structure check hoisting phase. It will no longer be necessary + to modify it when the effectfulness of operations changes. This also enables the hoister + to hoist effectful things in the future. + + The downside is that the hoister may end up adding strictly more checks than were present + in the original code, if the code truly has a lot of side-effects. I don't see evidence + of this happening. This patch does have some speed-ups and some slow-downs, but is + neutral in the average, and the slow-downs do not appear to have more structure checks + than ToT. - DFGOperations doesn't use NativeCallFrameTracer in enough places - https://bugs.webkit.org/show_bug.cgi?id=96987 + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): + (StructureCheckHoistingPhase): + (CheckData): + (JSC::DFG::StructureCheckHoistingPhase::CheckData::CheckData): - Reviewed by Mark Hahnenberg. +2012-10-14 Filip Pizlo <fpizlo@apple.com> - Anything that can GC should use it. + Fix the build of universal binary with ARMv7s of JavaScriptCore - * dfg/DFGOperations.cpp: + * llint/LLIntOfflineAsmConfig.h: + * llint/LowLevelInterpreter.asm: -2012-09-18 Mark Lam <mark.lam@apple.com> +2012-10-13 Filip Pizlo <fpizlo@apple.com> - Not reviewed. Attempt at greening the WinCairo bot. Touching - LowLevelInterpreter.asm to trigger a rebuild of LLIntDesiredOffsets. - https://bugs.webkit.org/show_bug.cgi?id=96992. + Array length array profiling is broken in the baseline JIT + https://bugs.webkit.org/show_bug.cgi?id=99258 - * llint/LowLevelInterpreter.asm: + Reviewed by Oliver Hunt. -2012-09-18 Peter Gal <galpeter@inf.u-szeged.hu> + The code generator for array length stubs calls into + emitArrayProfilingSiteForBytecodeIndex(), which emits profiling only if + canBeOptimized() returns true. But m_canBeOptimized is only initialized during + full method compiles, so in a stub compile it may (or may not) be false, meaning + that we may, or may not, get meaningful profiling info. + + This appeared to not affect too many programs since the LLInt has good array + length array profiling. - [Qt] REGRESSION(r128790): It broke the ARM build - https://bugs.webkit.org/show_bug.cgi?id=96968 + * jit/JIT.h: + (JSC::JIT::compilePatchGetArrayLength): - Reviewed by Filip Pizlo. +2012-10-14 Patrick Gansterer <paroga@webkit.org> - Implement the missing or32 method in the MacroAssemblerARM.h. + Build fix for WinCE after r131089. - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::or32): - (MacroAssemblerARM): + WinCE does not support getenv(). -2012-09-18 Mark Lam <mark.lam@apple.com> + * runtime/Options.cpp: + (JSC::overrideOptionWithHeuristic): - Fix for WinCairo builds. - https://bugs.webkit.org/show_bug.cgi?id=96992. +2012-10-12 Kangil Han <kangil.han@samsung.com> - Reviewed by Filip Pizlo. + Fix build error on DFGSpeculativeJIT32_64.cpp + https://bugs.webkit.org/show_bug.cgi?id=99234 - Adding additional vcproj build targets in LLIntDesiredOffsets.vcproj, - LLIntOffsetsExtractor.vcproj, and LLIntAssembly.vcproj to match those - in jsc.vcproj. + Reviewed by Anders Carlsson. - * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj: - * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj: - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj: - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops: Added property svn:eol-style. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops: Added property svn:eol-style. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugAll.vsprops: Added. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugCairoCFLite.vsprops: Added. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.vsprops: Added. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops: Added property svn:eol-style. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleaseCairoCFLite.vsprops: Added. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleasePGO.vsprops: Added. + Seems BUG 98608 causes build error on 32bit machine so fix it. -2012-09-18 Filip Pizlo <fpizlo@apple.com> + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): - Unreviewed, fix sloppy English in comment. +2012-10-12 Filip Pizlo <fpizlo@apple.com> - * runtime/JSGlobalObject.cpp: - (JSC): + Contiguous array allocation should always be inlined + https://bugs.webkit.org/show_bug.cgi?id=98608 -2012-09-17 Csaba Osztrogonác <ossy@webkit.org> + Reviewed by Oliver Hunt and Mark Hahnenberg. - Unreviewed, rolling out r128826 and r128813. + This inlines contiguous array allocation in the most obvious way possible. - * API/JSCallbackConstructor.cpp: - (JSC): - (JSC::JSCallbackConstructor::JSCallbackConstructor): - * API/JSCallbackConstructor.h: - (JSCallbackConstructor): - * API/JSCallbackObject.cpp: - (JSC): - (JSC::::createStructure): - * API/JSCallbackObject.h: - (JSC::JSCallbackObject::create): - (JSCallbackObject): - * API/JSClassRef.cpp: - (OpaqueJSClass::prototype): - * API/JSObjectRef.cpp: - (JSObjectMake): - (JSObjectGetPrivate): - (JSObjectSetPrivate): - (JSObjectGetPrivateProperty): - (JSObjectSetPrivateProperty): - (JSObjectDeletePrivateProperty): - * API/JSValueRef.cpp: - (JSValueIsObjectOfClass): - * API/JSWeakObjectMapRefPrivate.cpp: - * GNUmakefile.list.am: - * JSCTypedArrayStubs.h: - (JSC): - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: + * assembler/MacroAssembler.h: + (JSC::MacroAssembler::branchSubPtr): + (MacroAssembler): + * assembler/MacroAssemblerX86_64.h: + (JSC::MacroAssemblerX86_64::branchSubPtr): + (MacroAssemblerX86_64): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGCCallHelpers.h: + (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): + (CCallHelpers): + * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: Added. + (DFG): + (CallArrayAllocatorSlowPathGenerator): + (JSC::DFG::CallArrayAllocatorSlowPathGenerator::CallArrayAllocatorSlowPathGenerator): + (JSC::DFG::CallArrayAllocatorSlowPathGenerator::generateInternal): + (CallArrayAllocatorWithVariableSizeSlowPathGenerator): + (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::CallArrayAllocatorWithVariableSizeSlowPathGenerator): + (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::generateInternal): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::emitAllocateJSArray): + (DFG): + (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): + (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage): (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject): - * heap/Heap.cpp: - (JSC::Heap::isSafeToSweepStructures): - (JSC): - * heap/Heap.h: - (JSC::Heap::allocatorForObjectWithDestructor): - (Heap): - (JSC::Heap::allocateWithDestructor): - (JSC::Heap::allocateStructure): - (JSC): - * heap/IncrementalSweeper.cpp: - (JSC::IncrementalSweeper::IncrementalSweeper): - (JSC::IncrementalSweeper::sweepNextBlock): - (JSC::IncrementalSweeper::startSweeping): - (JSC::IncrementalSweeper::willFinishSweeping): - (JSC::IncrementalSweeper::structuresCanBeSwept): - (JSC): - * heap/IncrementalSweeper.h: - (IncrementalSweeper): - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::tryAllocateHelper): - (JSC::MarkedAllocator::allocateBlock): - * heap/MarkedAllocator.h: - (JSC::MarkedAllocator::cellsNeedDestruction): - (JSC::MarkedAllocator::onlyContainsStructures): - (MarkedAllocator): - (JSC::MarkedAllocator::MarkedAllocator): - (JSC::MarkedAllocator::init): - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::create): - (JSC::MarkedBlock::MarkedBlock): - (JSC): - (JSC::MarkedBlock::specializedSweep): - (JSC::MarkedBlock::sweep): - (JSC::MarkedBlock::sweepHelper): - * heap/MarkedBlock.h: - (JSC): - (MarkedBlock): - (JSC::MarkedBlock::cellsNeedDestruction): - (JSC::MarkedBlock::onlyContainsStructures): - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::MarkedSpace): - (JSC::MarkedSpace::resetAllocators): - (JSC::MarkedSpace::canonicalizeCellLivenessData): - (JSC::MarkedSpace::isPagedOut): - (JSC::MarkedSpace::freeBlock): - * heap/MarkedSpace.h: - (MarkedSpace): - (Subspace): - (JSC::MarkedSpace::allocatorFor): - (JSC::MarkedSpace::destructorAllocatorFor): - (JSC::MarkedSpace::allocateWithDestructor): - (JSC::MarkedSpace::allocateStructure): - (JSC::MarkedSpace::forEachBlock): - * heap/SlotVisitor.cpp: - * jit/JIT.h: - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - (JSC::JIT::emitAllocateJSFinalObject): - (JSC::JIT::emitAllocateJSArray): - * jsc.cpp: - (GlobalObject::create): - * runtime/Arguments.cpp: - (JSC): - * runtime/Arguments.h: - (Arguments): - (JSC::Arguments::Arguments): - * runtime/ErrorPrototype.cpp: - (JSC): - * runtime/Executable.h: - * runtime/InternalFunction.cpp: - (JSC): - (JSC::InternalFunction::InternalFunction): - * runtime/InternalFunction.h: - (InternalFunction): - * runtime/JSCell.h: - (JSC): - (JSC::allocateCell): - * runtime/JSDestructibleObject.h: Removed. - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::reset): - (JSC): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::createRareDataIfNeeded): - (JSC::JSGlobalObject::create): - * runtime/JSGlobalThis.h: - (JSGlobalThis): - (JSC::JSGlobalThis::JSGlobalThis): - * runtime/JSPropertyNameIterator.h: - * runtime/JSScope.cpp: - (JSC): - * runtime/JSString.h: - (JSC): - * runtime/JSWrapperObject.h: - (JSWrapperObject): - (JSC::JSWrapperObject::JSWrapperObject): - * runtime/MathObject.cpp: - (JSC): - * runtime/NameInstance.h: - (NameInstance): - * runtime/RegExp.h: - * runtime/RegExpObject.cpp: - (JSC): - * runtime/SparseArrayValueMap.h: - * runtime/Structure.h: - (JSC::Structure): - (JSC::JSCell::classInfo): - (JSC): - * runtime/StructureChain.h: - * runtime/SymbolTable.h: - * testRegExp.cpp: - (GlobalObject::create): - -2012-09-17 Geoffrey Garen <ggaren@apple.com> - - Refactored the arguments object so it doesn't dictate closure layout - https://bugs.webkit.org/show_bug.cgi?id=96955 + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): - Reviewed by Oliver Hunt. +2012-10-12 Mark Hahnenberg <mhahnenberg@apple.com> - * bytecode/CodeBlock.h: - (JSC::ExecState::argumentAfterCapture): Helper function for accessing an - argument that has been moved for capture. + Race condition during CopyingPhase can lead to deadlock + https://bugs.webkit.org/show_bug.cgi?id=99226 - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::BytecodeGenerator): Generate metadata for arguments - that are captured. We don't move any arguments yet, but we do use this - metadata to tell the arguments object if an argument is stored in the - activation. + Reviewed by Filip Pizlo. - * dfg/DFGOperations.cpp: - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): - (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): Updated for the arguments object not - malloc'ing a separate backing store, and for a rename from deletedArguments - to slowArguments. + The main thread calls startCopying() for each of the GCThreads at the beginning of the copy phase. + It then proceeds to start copying. If copying completes before one of the GCThreads wakes up, the + main thread will set m_currentPhase back to NoPhase, the GCThread will wake up, see that there's + nothing to do, and then it will go back to sleep without ever calling CopyVisitor::doneCopying() + to return its borrowed block to the CopiedSpace. CopiedSpace::doneCopying() will then sleep forever + waiting on the block. - * interpreter/CallFrame.h: - (ExecState): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::unwindCallFrame): - (JSC::Interpreter::privateExecute): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): Updated for small interface changes. + The fix for this is to make sure we call CopiedSpace::doneCopying() on the main thread before we + call GCThreadSharedData::didFinishCopying(), which sets the m_currentPhase flag to NoPhase. This + way we will wait until all threads have woken up and given back their borrowed blocks before + clearing the flag. - * runtime/Arguments.cpp: - (JSC::Arguments::visitChildren): - (JSC::Arguments::copyToArguments): - (JSC::Arguments::fillArgList): - (JSC::Arguments::getOwnPropertySlotByIndex): - (JSC::Arguments::createStrictModeCallerIfNecessary): - (JSC::Arguments::createStrictModeCalleeIfNecessary): - (JSC::Arguments::getOwnPropertySlot): - (JSC::Arguments::getOwnPropertyDescriptor): - (JSC::Arguments::getOwnPropertyNames): - (JSC::Arguments::putByIndex): - (JSC::Arguments::put): - (JSC::Arguments::deletePropertyByIndex): - (JSC::Arguments::deleteProperty): - (JSC::Arguments::defineOwnProperty): - (JSC::Arguments::tearOff): Moved all data inline into the object, for speed, - and refactored all internal argument accesses to use helper functions, so - we can change the implementation without changing lots of code. - - (JSC::Arguments::didTearOffActivation): This function needs to account - for arguments that were moved by the activation object. We do this accounting - through a side vector that tells us where our arguments will be in the - activation. + * heap/Heap.cpp: + (JSC::Heap::copyBackingStores): - (JSC::Arguments::tearOffForInlineCallFrame): - * runtime/Arguments.h: - (Arguments): - (JSC::Arguments::length): - (JSC::Arguments::isTornOff): - (JSC::Arguments::Arguments): - (JSC::Arguments::allocateSlowArguments): - (JSC::Arguments::tryDeleteArgument): - (JSC::Arguments::trySetArgument): - (JSC::Arguments::tryGetArgument): - (JSC::Arguments::isDeletedArgument): - (JSC::Arguments::isArgument): - (JSC::Arguments::argument): - (JSC::Arguments::finishCreation): - - * runtime/JSActivation.h: - (JSC::JSActivation::create): - (JSActivation): - (JSC::JSActivation::captureStart): - (JSC::JSActivation::storageSize): - (JSC::JSActivation::registerOffset): - (JSC::JSActivation::isValid): The activation object is no longer responsible - for copying extra arguments provided by the caller. The argumnents object - does this instead. This means we can allocate and initialize an activation - without worrying about the call frame's argument count. - - * runtime/SymbolTable.h: - (JSC::SlowArgument::SlowArgument): - (SlowArgument): - (JSC): - (JSC::SharedSymbolTable::parameterCount): - (SharedSymbolTable): - (JSC::SharedSymbolTable::slowArguments): - (JSC::SharedSymbolTable::setSlowArguments): Added data structures to back - the algorithms above. +2012-10-12 Anders Carlsson <andersca@apple.com> -2012-09-17 Filip Pizlo <fpizlo@apple.com> + Move macros from Parser.h to Parser.cpp + https://bugs.webkit.org/show_bug.cgi?id=99217 - 32-bit LLInt get_by_val does vector length checks incorrectly - https://bugs.webkit.org/show_bug.cgi?id=96893 - <rdar://problem/12311678> + Reviewed by Andreas Kling. - Reviewed by Mark Hahnenberg. + There are a bunch of macros in Parser.h that are only used in Parser.cpp. Move them to Parser.cpp + so they won't pollute the global namespace. + * parser/Parser.cpp: + * parser/Parser.h: + (JSC): - * llint/LowLevelInterpreter32_64.asm: +2012-10-12 Mark Hahnenberg <mhahnenberg@apple.com> -2012-09-17 Filip Pizlo <fpizlo@apple.com> + Another build fix after r131213 - We don't have a bad enough time if an object's prototype chain crosses global objects - https://bugs.webkit.org/show_bug.cgi?id=96962 + Added some symbol magic to placate the linker on some platforms. - Reviewed by Geoffrey Garen. + * JavaScriptCore.order: - * runtime/JSGlobalObject.cpp: - (JSC): +2012-10-12 Mark Hahnenberg <mhahnenberg@apple.com> -2012-09-17 Filip Pizlo <fpizlo@apple.com> + Build fix after r131213 - Unreviewed, fix a broken assertion in offlineasm. + Removed an unused variable that was making compilers unhappy. - * offlineasm/armv7.rb: - * offlineasm/backends.rb: + * heap/GCThread.cpp: + (JSC::GCThread::GCThread): + * heap/GCThread.h: + (GCThread): + * heap/GCThreadSharedData.cpp: + (JSC::GCThreadSharedData::GCThreadSharedData): -2012-09-16 Mark Hahnenberg <mhahnenberg@apple.com> +2012-10-09 Mark Hahnenberg <mhahnenberg@apple.com> - Delayed structure sweep can leak structures without bound - https://bugs.webkit.org/show_bug.cgi?id=96546 + Copying collection shouldn't require O(live bytes) memory overhead + https://bugs.webkit.org/show_bug.cgi?id=98792 - Reviewed by Gavin Barraclough. + Reviewed by Filip Pizlo. - This patch gets rid of the separate Structure allocator in the MarkedSpace and adds two new destructor-only - allocators. We now have separate allocators for our three types of objects: those objects with no destructors, - those objects with destructors and with immortal structures, and those objects with destructors that don't have - immortal structures. All of the objects of the third type (destructors without immortal structures) now - inherit from a new class named JSDestructibleObject (which in turn is a subclass of JSNonFinalObject), which stores - the ClassInfo for these classes at a fixed offset for safe retrieval during sweeping/destruction. + Currently our copying collection occurs simultaneously with the marking phase. We'd like + to be able to reuse CopiedBlocks as soon as they become fully evacuated, but this is not + currently possible because we don't know the liveness statistics of each old CopiedBlock + until marking/copying has already finished. Instead, we have to allocate additional memory + from the OS to use as our working set of CopiedBlocks while copying. We then return the + fully evacuated old CopiedBlocks back to the block allocator, thus giving our copying phase + an O(live bytes) overhead. + + To fix this, we should instead split the copying phase apart from the marking phase. This + way we have full liveness data for each CopiedBlock during the copying phase so that we + can reuse them the instant they become fully evacuated. With the additional liveness data + that each CopiedBlock accumulates, we can add some additional heuristics to the collector. + For example, we can calculate our global Heap fragmentation and only choose to do a copying + phase if that fragmentation exceeds some limit. As another example, we can skip copying + blocks that are already above a particular fragmentation limit, which allows older objects + to coalesce into blocks that are rarely copied. - * API/JSCallbackConstructor.cpp: Use JSDestructibleObject for JSCallbackConstructor. - (JSC): - (JSC::JSCallbackConstructor::JSCallbackConstructor): - * API/JSCallbackConstructor.h: - (JSCallbackConstructor): - * API/JSCallbackObject.cpp: Inherit from JSDestructibleObject for normal JSCallbackObjects and use a finalizer for - JSCallbackObject<JSGlobalObject>, since JSGlobalObject also uses a finalizer. - (JSC): - (JSC::::create): We need to move the create function for JSCallbackObject<JSGlobalObject> out of line so we can add - the finalizer for it. We don't want to add the finalizer is something like finishCreation in case somebody decides - to subclass this. We use this same technique for many other subclasses of JSGlobalObject. - (JSC::::createStructure): - * API/JSCallbackObject.h: - (JSCallbackObject): - (JSC): - * API/JSClassRef.cpp: Change all the JSCallbackObject<JSNonFinalObject> to use JSDestructibleObject instead. - (OpaqueJSClass::prototype): - * API/JSObjectRef.cpp: Ditto. - (JSObjectMake): - (JSObjectGetPrivate): - (JSObjectSetPrivate): - (JSObjectGetPrivateProperty): - (JSObjectSetPrivateProperty): - (JSObjectDeletePrivateProperty): - * API/JSValueRef.cpp: Ditto. - (JSValueIsObjectOfClass): - * API/JSWeakObjectMapRefPrivate.cpp: Ditto. - * JSCTypedArrayStubs.h: - (JSC): * JavaScriptCore.xcodeproj/project.pbxproj: - * dfg/DFGSpeculativeJIT.h: Use the proper allocator type when doing inline allocation in the DFG. - (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): - (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject): + * heap/CopiedBlock.h: + (CopiedBlock): + (JSC::CopiedBlock::CopiedBlock): Added support for tracking live bytes in a CopiedBlock in a + thread-safe fashion. + (JSC::CopiedBlock::reportLiveBytes): Adds a number of live bytes to the block in a thread-safe + fashion using compare and swap. + (JSC): + (JSC::CopiedBlock::didSurviveGC): Called when a block survives a single GC without being + evacuated. This could be called for a couple reasons: (a) the block was pinned or (b) we + decided not to do any copying. A block can become pinned for a few reasons: (1) a pointer into + the block was found during the conservative scan. (2) the block was deemed full enough to + not warrant any copying. (3) The block is oversize and was found to be live. + (JSC::CopiedBlock::didEvacuateBytes): Called when some number of bytes are copied from this + block. If the number of live bytes ever hits zero, the block will return itself to the + BlockAllocator to be recycled. + (JSC::CopiedBlock::canBeRecycled): Indicates that a block has no live bytes and can be + immediately recycled. This is used for blocks that are found to have zero live bytes at the + beginning of the copying phase. + (JSC::CopiedBlock::shouldEvacuate): This function returns true if the current fragmentation + of the block is above our fragmentation threshold, and false otherwise. + (JSC::CopiedBlock::isPinned): Added an accessor for the pinned flag + (JSC::CopiedBlock::liveBytes): + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::CopiedSpace): + (JSC::CopiedSpace::doneFillingBlock): Changed so that we can exchange our filled block for a + fresh block. This avoids the situation where a thread returns its borrowed block, it's the last + borrowed block, so CopiedSpace thinks that copying has completed, and it starts doing all of the + copying phase cleanup. In actuality, the thread wanted another block after returning the current + block. So we allow the thread to atomically exchange its block for another block. + (JSC::CopiedSpace::startedCopying): Added the calculation of global Heap fragmentation to + determine if the copying phase should commence. We include the MarkedSpace in our fragmentation + calculation by assuming that the MarkedSpace is 0% fragmented since we can reuse any currently + free memory in it (i.e. we ignore any internal fragmentation in the MarkedSpace). While we're + calculating the fragmentation of CopiedSpace, we also return any free blocks we find along the + way (meaning liveBytes() == 0). + (JSC): + (JSC::CopiedSpace::doneCopying): We still have to iterate over all the blocks, regardless of + whether the copying phase took place or not so that we can reset all of the live bytes counters + and un-pin any pinned blocks. + * heap/CopiedSpace.h: + (CopiedSpace): + (JSC::CopiedSpace::shouldDoCopyPhase): + * heap/CopiedSpaceInlineMethods.h: + (JSC::CopiedSpace::recycleEvacuatedBlock): This function is distinct from recycling a borrowed block + because a borrowed block hasn't been added to the CopiedSpace yet, but an evacuated block is still + currently in CopiedSpace, so we have to make sure we properly remove all traces of the block from + CopiedSpace before returning it to BlockAllocator. + (JSC::CopiedSpace::recycleBorrowedBlock): Renamed to indicate the distinction mentioned above. + * heap/CopyVisitor.cpp: Added. + (JSC): + (JSC::CopyVisitor::CopyVisitor): + (JSC::CopyVisitor::copyFromShared): Main function for any thread participating in the copying phase. + Grabs chunks of MarkedBlocks from the shared list and copies the backing store of anybody who needs + it until there are no more chunks to copy. + * heap/CopyVisitor.h: Added. + (JSC): + (CopyVisitor): + * heap/CopyVisitorInlineMethods.h: Added. + (JSC): + (GCCopyPhaseFunctor): + (JSC::GCCopyPhaseFunctor::GCCopyPhaseFunctor): + (JSC::GCCopyPhaseFunctor::operator()): + (JSC::CopyVisitor::checkIfShouldCopy): We don't have to check shouldEvacuate() because all of those + checks are done during the marking phase. + (JSC::CopyVisitor::allocateNewSpace): + (JSC::CopyVisitor::allocateNewSpaceSlow): + (JSC::CopyVisitor::startCopying): Initialization function for a thread that is about to start copying. + (JSC::CopyVisitor::doneCopying): + (JSC::CopyVisitor::didCopy): This callback is called by an object that has just successfully copied its + backing store. It indicates to the CopiedBlock that somebody has just finished evacuating some number of + bytes from it, and, if the CopiedBlock now has no more live bytes, can be recycled immediately. + * heap/GCThread.cpp: Added. + (JSC): + (JSC::GCThread::GCThread): This is a new class that encapsulates a single thread responsible for participating + in a specific set of GC phases. Currently, that set of phases includes Mark, Copy, and Exit. Each thread + monitors a shared variable in its associated GCThreadSharedData. The main thread updates this m_currentPhase + variable as collection progresses through the various phases. Parallel marking still works exactly like it + has. In other words, the "run loop" for each of the GC threads sits above any individual phase, thus keeping + the separate phases of the collector orthogonal. + (JSC::GCThread::threadID): + (JSC::GCThread::initializeThreadID): + (JSC::GCThread::slotVisitor): + (JSC::GCThread::copyVisitor): + (JSC::GCThread::waitForNextPhase): + (JSC::GCThread::gcThreadMain): + (JSC::GCThread::gcThreadStartFunc): + * heap/GCThread.h: Added. + (JSC): + (GCThread): + * heap/GCThreadSharedData.cpp: The GCThreadSharedData now has a list of GCThread objects rather than raw + ThreadIdentifiers. + (JSC::GCThreadSharedData::resetChildren): + (JSC::GCThreadSharedData::childVisitCount): + (JSC::GCThreadSharedData::GCThreadSharedData): + (JSC::GCThreadSharedData::~GCThreadSharedData): + (JSC::GCThreadSharedData::reset): + (JSC::GCThreadSharedData::didStartMarking): Callback to let the GCThreadSharedData know that marking has + started and updates the m_currentPhase variable and notifies the GCThreads accordingly. + (JSC::GCThreadSharedData::didFinishMarking): Ditto for finishing marking. + (JSC::GCThreadSharedData::didStartCopying): Ditto for starting the copying phase. + (JSC::GCThreadSharedData::didFinishCopying): Ditto for finishing copying. + * heap/GCThreadSharedData.h: + (JSC): + (GCThreadSharedData): + (JSC::GCThreadSharedData::getNextBlocksToCopy): Atomically gets the next chunk of work for a copying thread. * heap/Heap.cpp: + (JSC::Heap::Heap): + (JSC::Heap::markRoots): (JSC): - * heap/Heap.h: Add accessors for the various types of allocators now. Also remove the isSafeToSweepStructures function - since it's always safe to sweep Structures now. - (JSC::Heap::allocatorForObjectWithNormalDestructor): - (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor): + (JSC::Heap::copyBackingStores): Responsible for setting up the copying phase, notifying the copying threads, + and doing any copying work if necessary. + (JSC::Heap::collect): + * heap/Heap.h: (Heap): - (JSC::Heap::allocateWithNormalDestructor): (JSC): - (JSC::Heap::allocateWithImmortalStructureDestructor): - * heap/IncrementalSweeper.cpp: Remove all the logic to detect when it's safe to sweep Structures from the - IncrementalSweeper since it's always safe to sweep Structures now. + (JSC::CopyFunctor::CopyFunctor): + (CopyFunctor): + (JSC::CopyFunctor::operator()): + * heap/IncrementalSweeper.cpp: Changed the incremental sweeper to have a reference to the list of MarkedBlocks + that need sweeping, since this now resides in the Heap so that it can be easily shared by the GCThreads. (JSC::IncrementalSweeper::IncrementalSweeper): - (JSC::IncrementalSweeper::sweepNextBlock): (JSC::IncrementalSweeper::startSweeping): - (JSC::IncrementalSweeper::willFinishSweeping): - (JSC): * heap/IncrementalSweeper.h: - (IncrementalSweeper): - * heap/MarkedAllocator.cpp: Remove the logic that was preventing us from sweeping Structures if it wasn't safe. Add - tracking of the specific destructor type of allocator. - (JSC::MarkedAllocator::tryAllocateHelper): - (JSC::MarkedAllocator::allocateBlock): - * heap/MarkedAllocator.h: - (JSC::MarkedAllocator::destructorType): - (MarkedAllocator): - (JSC::MarkedAllocator::MarkedAllocator): - (JSC::MarkedAllocator::init): - * heap/MarkedBlock.cpp: Add all the destructor type stuff to MarkedBlocks so that we do the right thing when sweeping. - We also use the stored destructor type to determine the right thing to do in all JSCell::classInfo() calls. - (JSC::MarkedBlock::create): - (JSC::MarkedBlock::MarkedBlock): - (JSC): - (JSC::MarkedBlock::specializedSweep): - (JSC::MarkedBlock::sweep): - (JSC::MarkedBlock::sweepHelper): - * heap/MarkedBlock.h: - (JSC): - (JSC::MarkedBlock::allocator): - (JSC::MarkedBlock::destructorType): - * heap/MarkedSpace.cpp: Add the new destructor allocators to MarkedSpace. - (JSC::MarkedSpace::MarkedSpace): - (JSC::MarkedSpace::resetAllocators): - (JSC::MarkedSpace::canonicalizeCellLivenessData): - (JSC::MarkedSpace::isPagedOut): - (JSC::MarkedSpace::freeBlock): - * heap/MarkedSpace.h: - (MarkedSpace): - (JSC::MarkedSpace::immortalStructureDestructorAllocatorFor): - (JSC::MarkedSpace::normalDestructorAllocatorFor): - (JSC::MarkedSpace::allocateWithImmortalStructureDestructor): - (JSC::MarkedSpace::allocateWithNormalDestructor): - (JSC::MarkedSpace::forEachBlock): - * heap/SlotVisitor.cpp: Add include because the symbol was needed in an inlined function. - * jit/JIT.h: Make sure we use the correct allocator when doing inline allocations in the baseline JIT. - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - (JSC::JIT::emitAllocateJSFinalObject): - (JSC::JIT::emitAllocateJSArray): - * jsc.cpp: - (GlobalObject::create): Add finalizer here since JSGlobalObject needs to use a finalizer instead of inheriting from - JSDestructibleObject. - * runtime/Arguments.cpp: Inherit from JSDestructibleObject. - (JSC): - * runtime/Arguments.h: - (Arguments): - (JSC::Arguments::Arguments): - * runtime/ErrorPrototype.cpp: Added an assert to make sure we have a trivial destructor. - (JSC): - * runtime/Executable.h: Indicate that all of the Executable* classes have immortal Structures. - (JSC): - * runtime/InternalFunction.cpp: Inherit from JSDestructibleObject. - (JSC): - (JSC::InternalFunction::InternalFunction): - * runtime/InternalFunction.h: - (InternalFunction): - * runtime/JSCell.h: Added the NEEDS_DESTRUCTOR macro to make it easier for classes to indicate that instead of being - allocated in a destructor MarkedAllocator that they will handle their destruction themselves through the - use of a finalizer. - (JSC): - (HasImmortalStructure): New template to help us determine at compile-time if a particular class - should be allocated in the immortal structure MarkedAllocator. The default value is false. In order - to be allocated in the immortal structure allocator, classes must specialize this template. Also added - a macro to make it easier for classes to specialize the template. - (JSC::allocateCell): Use the appropriate allocator depending on the destructor type. - * runtime/JSDestructibleObject.h: Added. New class that stores the ClassInfo of any subclass so that it can be - accessed safely when the object is being destroyed. - (JSC): - (JSDestructibleObject): - (JSC::JSDestructibleObject::classInfo): - (JSC::JSDestructibleObject::JSDestructibleObject): - (JSC::JSCell::classInfo): Checks the current MarkedBlock to see where it should get the ClassInfo from so that it's always safe. - * runtime/JSGlobalObject.cpp: JSGlobalObject now uses a finalizer instead of a destructor so that it can avoid forcing all - of its relatives in the inheritance hierarchy (e.g. JSScope) to use destructors as well. - (JSC::JSGlobalObject::reset): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::createRareDataIfNeeded): Since we always create a finalizer now, we don't have to worry about adding one - for the m_rareData field when it's created. - (JSC::JSGlobalObject::create): (JSC): - * runtime/JSGlobalThis.h: Inherit from JSDestructibleObject. - (JSGlobalThis): - (JSC::JSGlobalThis::JSGlobalThis): - * runtime/JSPropertyNameIterator.h: Has an immortal Structure. - (JSC): - * runtime/JSScope.cpp: - (JSC): - * runtime/JSString.h: Has an immortal Structure. - (JSC): - * runtime/JSWrapperObject.h: Inherit from JSDestructibleObject. - (JSWrapperObject): - (JSC::JSWrapperObject::JSWrapperObject): - * runtime/MathObject.cpp: Cleaning up some of the inheritance stuff. - (JSC): - * runtime/NameInstance.h: Inherit from JSDestructibleObject. - (NameInstance): - * runtime/RegExp.h: Has immortal Structure. - (JSC): - * runtime/RegExpObject.cpp: Inheritance cleanup. - (JSC): - * runtime/SparseArrayValueMap.h: Has immortal Structure. - (JSC): - * runtime/Structure.h: Has immortal Structure. + (IncrementalSweeper): + * heap/SlotVisitor.cpp: + (JSC::SlotVisitor::setup): + (JSC::SlotVisitor::drainFromShared): We no longer do any copying-related work here. (JSC): - * runtime/StructureChain.h: Ditto. + * heap/SlotVisitor.h: + (SlotVisitor): + * heap/SlotVisitorInlineMethods.h: (JSC): - * runtime/SymbolTable.h: Ditto. - (SharedSymbolTable): + (JSC::SlotVisitor::copyLater): Notifies the CopiedBlock that there are some live bytes that may need + to be copied. + * runtime/Butterfly.h: (JSC): - -2012-09-17 Filip Pizlo <fpizlo@apple.com> - - If a prototype has indexed setters and its instances have indexed storage, then all put_by_val's should have a bad time - https://bugs.webkit.org/show_bug.cgi?id=96596 - - Reviewed by Gavin Barraclough. - - Added comprehensive support for accessors and read-only indexed properties on the - prototype chain. This is done without any performance regression on benchmarks that - we're aware of, by having the entire VM's strategy with respect to arrays tilted - heavily in favor of: - - - The prototype chain of JSArrays never having any accessors or read-only indexed - properties. If that changes, you're going to have a bad time. - - - Prototypes of non-JSArray objects either having no indexed accessors or read-only - indexed properties, or, having those indexed accessor thingies inserted before - any instance object (i.e. object with that prototype as its prototype) is created. - If you add indexed accessors or read-only indexed properties to an object that is - already used as a prototype, you're going to have a bad time. - - See below for the exact definition of having a bad time. - - Put another way, "fair" uses of indexed accessors and read-only indexed properties - are: - - - Put indexed accessors and read-only indexed properties on an object that is never - used as a prototype. This will slow down accesses to that object, but will not - have any effect on any other object. - - - Put those indexed accessor thingies on an object before it is used as a prototype - and then start instantiating objects that claim that object as their prototype. - This will slightly slow down indexed stores to the instance objects, and greatly - slow down all indexed accesses to the prototype, but will have no other effect. - - In short, "fair" uses only affect the object itself and any instance objects. But - if you start using indexed accessors in more eclectic ways, you're going to have - a bad time. - - Specifically, if an object that may be used as a prototype has an indexed accessor - added, the VM performs a whole-heap scan to find all objects that belong to the - same global object as the prototype you modified. If any of those objects has - indexed storage, their indexed storage is put into slow-put mode, just as if their - prototype chain had indexed accessors. This will happen even for objects that do - not currently have indexed accessors in their prototype chain. As well, all JSArray - allocations are caused to create arrays with slow-put storage, and all future - allocations of indexed storage for non-JSArray objects are also flipped to slow-put - mode. Note there are two aspects to having a bad time: (i) the whole-heap scan and - (ii) the poisoning of all indexed storage in the entire global object. (i) is - necessary for correctness. If we detect that an object that may be used as a - prototype has had an indexed accessor or indexed read-only property inserted into - it, then we need to ensure that henceforth all instances of that object inspect - the prototype chain whenever an indexed hole is stored to. But by default, indexed - stores do no such checking because doing so would be unnecessarily slow. So, we must - find all instances of the affected object and flip them into a different array - storage mode that omits all hole optimizations. Since prototypes never keep a list - of instance objects, the only way to find those objects is a whole-heap scan. But - (i) alone would be a potential disaster, if a program frequently allocated an - object without indexed accessors, then allocated a bunch of objects that used that - one as their prototype, and then added indexed accessors to the prototype. So, to - prevent massive heap scan storms in such awkward programs, having a bad time also - implies (ii): henceforth *all* objects belonging to that global object will use - slow put indexed storage, so that we don't ever have to scan the heap again. Note - that here we are using the global object as just an approximation of a program - module; it may be worth investigating in the future if other approximations can be - used instead. - - * bytecode/ArrayProfile.h: + (Butterfly): + * runtime/ButterflyInlineMethods.h: + (JSC::Butterfly::createUninitializedDuringCollection): Uses the new CopyVisitor. + * runtime/ClassInfo.h: + (MethodTable): Added new "virtual" function copyBackingStore to method table. (JSC): - (JSC::arrayModeFromStructure): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGArrayMode.cpp: - (JSC::DFG::fromObserved): - (JSC::DFG::modeAlreadyChecked): - (JSC::DFG::modeToString): - * dfg/DFGArrayMode.h: - (DFG): - (JSC::DFG::isSlowPutAccess): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::checkArray): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JIT.h: - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateJSArray): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_new_array): - * runtime/ArrayPrototype.cpp: - (JSC::ArrayPrototype::finishCreation): - (JSC::arrayProtoFuncSort): - * runtime/IndexingType.h: + * runtime/JSCell.cpp: + (JSC::JSCell::copyBackingStore): Default implementation that does nothing. (JSC): - (JSC::hasIndexedProperties): - (JSC::hasIndexingHeader): - (JSC::hasArrayStorage): - (JSC::shouldUseSlowPut): - * runtime/JSArray.cpp: - (JSC::JSArray::pop): - (JSC::JSArray::push): - (JSC::JSArray::fillArgList): - (JSC::JSArray::copyToArguments): - * runtime/JSArray.h: - (JSC::JSArray::createStructure): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - (JSC::JSGlobalObject::reset): + * runtime/JSCell.h: (JSC): - (JSC::JSGlobalObject::haveABadTime): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::addressOfArrayStructure): - (JSC::JSGlobalObject::havingABadTimeWatchpoint): - (JSC::JSGlobalObject::isHavingABadTime): + (JSCell): * runtime/JSObject.cpp: - (JSC::JSObject::visitButterfly): - (JSC::JSObject::getOwnPropertySlotByIndex): - (JSC::JSObject::put): - (JSC::JSObject::putByIndex): - (JSC::JSObject::enterDictionaryIndexingMode): - (JSC::JSObject::notifyPresenceOfIndexedAccessors): + (JSC::JSObject::copyButterfly): Does the actual copying of the butterfly. (JSC): - (JSC::JSObject::createArrayStorage): - (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode): - (JSC::JSObject::switchToSlowPutArrayStorage): - (JSC::JSObject::setPrototype): - (JSC::JSObject::resetInheritorID): - (JSC::JSObject::inheritorID): - (JSC::JSObject::allowsAccessFrom): - (JSC::JSObject::deletePropertyByIndex): - (JSC::JSObject::getOwnPropertyNames): - (JSC::JSObject::unwrappedGlobalObject): - (JSC::JSObject::notifyUsedAsPrototype): - (JSC::JSObject::createInheritorID): - (JSC::JSObject::defineOwnIndexedProperty): - (JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype): - (JSC::JSObject::attemptToInterceptPutByIndexOnHole): - (JSC::JSObject::putByIndexBeyondVectorLength): - (JSC::JSObject::putDirectIndexBeyondVectorLength): - (JSC::JSObject::getNewVectorLength): - (JSC::JSObject::getOwnPropertyDescriptor): + (JSC::JSObject::visitButterfly): Calls copyLater for the butterfly. + (JSC::JSObject::copyBackingStore): * runtime/JSObject.h: - (JSC::JSObject::mayBeUsedAsPrototype): (JSObject): - (JSC::JSObject::mayInterceptIndexedAccesses): - (JSC::JSObject::getArrayLength): - (JSC::JSObject::getVectorLength): - (JSC::JSObject::canGetIndexQuickly): - (JSC::JSObject::getIndexQuickly): - (JSC::JSObject::canSetIndexQuickly): - (JSC::JSObject::setIndexQuickly): - (JSC::JSObject::initializeIndex): - (JSC::JSObject::completeInitialization): - (JSC::JSObject::inSparseIndexingMode): - (JSC::JSObject::arrayStorage): - (JSC::JSObject::arrayStorageOrNull): - (JSC::JSObject::ensureArrayStorage): - (JSC): - (JSC::JSValue::putByIndex): - * runtime/JSValue.cpp: - (JSC::JSValue::putToPrimitive): - (JSC::JSValue::putToPrimitiveByIndex): - (JSC): - * runtime/JSValue.h: - (JSValue): - * runtime/ObjectPrototype.cpp: - (JSC::ObjectPrototype::finishCreation): - * runtime/SparseArrayValueMap.cpp: - (JSC::SparseArrayValueMap::putEntry): - (JSC::SparseArrayEntry::put): - (JSC): - * runtime/SparseArrayValueMap.h: - (JSC): - (SparseArrayEntry): - * runtime/Structure.cpp: - (JSC::Structure::anyObjectInChainMayInterceptIndexedAccesses): + (JSC::JSCell::methodTable): + (JSC::JSCell::inherits): + * runtime/Options.h: Added two new constants, minHeapUtilization and minCopiedBlockUtilization, + to govern the amount of fragmentation we allow before doing copying. (JSC): - (JSC::Structure::suggestedIndexingTransition): - * runtime/Structure.h: - (Structure): - (JSC::Structure::mayInterceptIndexedAccesses): - * runtime/StructureTransitionTable.h: - (JSC::newIndexingType): -2012-09-17 Filip Pizlo <fpizlo@apple.com> +2012-10-12 Filip Pizlo <fpizlo@apple.com> - Array profiling has convergence issues - https://bugs.webkit.org/show_bug.cgi?id=96891 + DFG array allocation calls should not return an encoded JSValue + https://bugs.webkit.org/show_bug.cgi?id=99196 - Reviewed by Gavin Barraclough. + Reviewed by Mark Hahnenberg. - Now each array profiling site merges in the indexing type it observed into - the m_observedArrayModes bitset. The ArrayProfile also uses this to detect - cases where the structure must have gone polymorphic (if the bitset is - polymorphic then the structure must be). This achieves something like the - best of both worlds: on the one hand, we get a probabilistic structure that - we can use to optimize the monomorphic structure case, but on the other hand, - we get an accurate view of the set of types that were encountered. + The array allocation operations now return a pointer instead. This makes it + easier to share code between 32-bit and 64-bit. - * assembler/MacroAssemblerARMv7.h: - (JSC::MacroAssemblerARMv7::or32): - (MacroAssemblerARMv7): - * assembler/MacroAssemblerX86.h: - (JSC::MacroAssemblerX86::or32): - (MacroAssemblerX86): - * assembler/MacroAssemblerX86_64.h: - (JSC::MacroAssemblerX86_64::or32): - (MacroAssemblerX86_64): - * assembler/X86Assembler.h: - (X86Assembler): - (JSC::X86Assembler::orl_rm): - * bytecode/ArrayProfile.cpp: - (JSC::ArrayProfile::computeUpdatedPrediction): - * bytecode/ArrayProfile.h: - (JSC::ArrayProfile::addressOfArrayModes): - (JSC::ArrayProfile::structureIsPolymorphic): - * jit/JIT.h: - (JIT): - * jit/JITInlineMethods.h: - (JSC): - (JSC::JIT::emitArrayProfilingSite): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::emit_op_get_by_val): - (JSC::JIT::emit_op_put_by_val): - (JSC::JIT::privateCompilePatchGetArrayLength): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::emit_op_get_by_val): - (JSC::JIT::emit_op_put_by_val): - (JSC::JIT::privateCompilePatchGetArrayLength): - * llint/LowLevelInterpreter.asm: - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-09-17 Mark Lam <mark.lam@apple.com> + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): - Not reviewed. Added svn:eol-style native to unbreak some build bots. - https://bugs.webkit.org/show_bug.cgi?id=96175. +2012-10-01 Jer Noble <jer.noble@apple.com> - * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj: Added property svn:eol-style. - * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj: Added property svn:eol-style. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj: Added property svn:eol-style. + Enable ENCRYPTED_MEDIA support on Mac. + https://bugs.webkit.org/show_bug.cgi?id=98044 -2012-09-16 Mark Lam <mark.lam@apple.com> + Reviewed by Anders Carlsson. - Added MSVC project changes to enable building the llint. - https://bugs.webkit.org/show_bug.cgi?id=96175. + Enable the ENCRYPTED_MEDIA flag. - Reviewed by Geoff Garen. + * Configurations/FeatureDefines.xcconfig: - This only adds the ability to build the llint, but currently, only the - C++ backend is supported. By default, the Windows port will remain - running with the baseline JIT. The llint will not be enabled. +2012-10-12 Filip Pizlo <fpizlo@apple.com> - * JavaScriptCore.vcproj/JavaScriptCore.sln: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.vcproj/LLIntAssembly: Added. - * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.make: Added. - * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj: Added. - * JavaScriptCore.vcproj/LLIntAssembly/build-LLIntAssembly.sh: Added. - * JavaScriptCore.vcproj/LLIntDesiredOffsets: Added. - * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make: Added. - * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj: Added. - * JavaScriptCore.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh: Added. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor: Added. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj: Added. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops: Added. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops: Added. - * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops: Added. - -2012-09-16 Filip Pizlo <fpizlo@apple.com> - - JSObject.cpp and JSArray.cpp have inconsistent tests for the invalid array index case - https://bugs.webkit.org/show_bug.cgi?id=96878 + Unreviewed. It should be possible to build JSC on ARMv7. - Reviewed by Sam Weinig. + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::patchableBranchPtr): - Removed the uses of UNLIKELY() because I don't believe they are buying us anything, - since we're already on the slow path. Also found other places where we're testing for - the invalid array index case using unusual predicates rather than just using - MAX_ARRAY_INDEX. With this change, I believe that all of our tests for invalid - array indices (i.e. indices that should be treated as non-indexed properties) - uniformly use MAX_ARRAY_INDEX and PropertyName::NotAnIndex. +2012-10-11 Mark Hahnenberg <mhahnenberg@apple.com> - * runtime/JSArray.cpp: - (JSC::JSArray::push): - * runtime/JSObject.cpp: - (JSC::JSObject::putByIndex): - (JSC::JSObject::defineOwnIndexedProperty): + BlockAllocator should use regions as its VM allocation abstraction + https://bugs.webkit.org/show_bug.cgi?id=99107 -2012-09-15 Filip Pizlo <fpizlo@apple.com> + Reviewed by Geoffrey Garen. - Following the Butterfly refactoring, the comment for lastArraySize was not updated - https://bugs.webkit.org/show_bug.cgi?id=96877 + Currently the BlockAllocator allocates a single block at a time directly from the OS. Our block + allocations are on the large-ish side (64 KB) to amortize across many allocations the expense of + mapping new virtual memory from the OS. These large blocks are then shared between the MarkedSpace + and the CopiedSpace. This design makes it difficult to vary the size of the blocks in different + parts of the Heap while still allowing us to amortize the VM allocation costs. - Reviewed by Sam Weinig. + We should redesign the BlockAllocator so that it has a layer of indirection between blocks that are + used by the allocator/collector and our primary unit of VM allocation from the OS. In particular, + the BlockAllocator should allocate Regions of virtual memory from the OS, which are then subdivided + into one or more Blocks to be used in our custom allocators. This design has the following nice properties: - * runtime/JSObject.cpp: - (JSC): + 1) We can remove the knowledge of PageAllocationAligned from HeapBlocks. Each HeapBlock will now + only know what Region it belongs to. The Region maintains all the metadata for how to allocate + and deallocate virtual memory from the OS. -2012-09-15 Mark Lam <mark.lam@apple.com> + 2) We can easily allocate in larger chunks than we need to satisfy a particular request for a Block. + We can then continue to amortize our VM allocation costs while allowing for smaller block sizes, + which should increase locality in the mutator when allocating, lazy sweeping, etc. - Fixed JSLock to use the platform abstraction for Mutex instead of - depending on pthreads. - https://bugs.webkit.org/show_bug.cgi?id=96858. + 3) By encapsulating the logic of where our memory comes from inside of the Region class, we can more + easily transition over to allocating VM from a specific range of pre-reserved address space. This + will be a necessary step along the way to 32-bit pointers. - Reviewed by Filip Pizlo. + This particular patch will not change the size of MarkedBlocks or CopiedBlocks, nor will it change how + much VM we allocate per failed Block request. It only sets up the data structures that we need to make + these changes in future patches. - This fixes a synchronization problem on the Windows port and makes - it more reliable when running the layout tests. + Most of the changes in this patch relate to the addition of the Region class to be used by the + BlockAllocator and the threading of changes made to BlockAllocator's interface through to the call sites. - * runtime/InitializeThreading.cpp: - (JSC::initializeThreadingOnce): - * runtime/JSLock.cpp: + * heap/BlockAllocator.cpp: The BlockAllocator now has three lists that track the three disjoint sets of + Regions that it cares about: empty regions, partially full regions, and completely full regions. + Empty regions have no blocks currently in use and can be freed immediately if the freeing thread + determines they should be. Partial regions have some blocks used, but aren't completely in use yet. + These regions are preferred for recycling before empty regions to mitigate fragmentation within regions. + Completely full regions are no longer able to be used for allocations. Regions move between these + three lists as they are created and their constituent blocks are allocated and deallocated. + (JSC::BlockAllocator::BlockAllocator): + (JSC::BlockAllocator::~BlockAllocator): + (JSC::BlockAllocator::releaseFreeRegions): + (JSC::BlockAllocator::waitForRelativeTimeWhileHoldingLock): + (JSC::BlockAllocator::waitForRelativeTime): + (JSC::BlockAllocator::blockFreeingThreadMain): + * heap/BlockAllocator.h: (JSC): - (JSC::GlobalJSLock::GlobalJSLock): - (JSC::GlobalJSLock::~GlobalJSLock): - (JSC::GlobalJSLock::initialize): - * runtime/JSLock.h: - (GlobalJSLock): - (JSLock): + (DeadBlock): + (JSC::DeadBlock::DeadBlock): + (Region): + (JSC::Region::blockSize): + (JSC::Region::isFull): + (JSC::Region::isEmpty): + (JSC::Region::create): This function is responsible for doing the actual VM allocation. This should be the + only function in the entire JSC object runtime that calls out the OS for virtual memory allocation. + (JSC::Region::Region): + (JSC::Region::~Region): + (JSC::Region::allocate): + (JSC::Region::deallocate): + (BlockAllocator): + (JSC::BlockAllocator::tryAllocateFromRegion): Helper function that encapsulates checking a particular list + of regions for a free block. + (JSC::BlockAllocator::allocate): + (JSC::BlockAllocator::allocateCustomSize): This function is responsible for allocating one-off custom size + regions for use in oversize allocations in both the MarkedSpace and the CopiedSpace. These regions are not + tracked by the BlockAllocator. The only pointer to them is in the HeapBlock that is returned. These regions + contain exactly one block. + (JSC::BlockAllocator::deallocate): + (JSC::BlockAllocator::deallocateCustomSize): This function is responsible for deallocating one-off custom size + regions. The regions are deallocated back to the OS eagerly. + * heap/CopiedBlock.h: Re-worked CopiedBlocks to use Regions instead of PageAllocationAligned. + (CopiedBlock): + (JSC::CopiedBlock::createNoZeroFill): + (JSC::CopiedBlock::create): + (JSC::CopiedBlock::CopiedBlock): + (JSC::CopiedBlock::payloadEnd): + (JSC::CopiedBlock::capacity): + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::~CopiedSpace): + (JSC::CopiedSpace::tryAllocateOversize): + (JSC::CopiedSpace::tryReallocateOversize): + (JSC::CopiedSpace::doneCopying): + * heap/CopiedSpaceInlineMethods.h: + (JSC::CopiedSpace::allocateBlockForCopyingPhase): + (JSC::CopiedSpace::allocateBlock): + * heap/HeapBlock.h: + (JSC::HeapBlock::destroy): + (JSC::HeapBlock::HeapBlock): + (JSC::HeapBlock::region): + (HeapBlock): + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::allocateBlock): + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::create): + (JSC::MarkedBlock::MarkedBlock): + * heap/MarkedBlock.h: + (JSC::MarkedBlock::capacity): + * heap/MarkedSpace.cpp: + (JSC::MarkedSpace::freeBlock): -2012-09-15 Filip Pizlo <fpizlo@apple.com> +2012-10-11 Filip Pizlo <fpizlo@apple.com> - Structure check hoisting fails to consider the possibility of conflicting checks on the source of the first assignment to the hoisted variable - https://bugs.webkit.org/show_bug.cgi?id=96872 + UInt32ToNumber and OSR exit should be aware of copy propagation and correctly recover both versions of a variable that was subject to a UInt32ToNumber cast + https://bugs.webkit.org/show_bug.cgi?id=99100 + <rdar://problem/12480955> - Reviewed by Oliver Hunt. + Reviewed by Michael Saboff and Mark Hahnenberg. - This does a few related things: - - - It turns off the use of ForceOSRExit for sure-to-fail CheckStructures, because - I noticed that this would sometimes happen for a ForwardCheckStructure. The - problem is that ForceOSRExit exits backwards, not forwards. Since the code that - led to those ForceOSRExit's being inserted was written out of paranoia rather - than need, I removed it. Specifically, I removed the m_isValid = false code - for CheckStructure/StructureTransitionWatchpoint in AbstractState. - - - If a structure check causes a structure set to go empty, we don't want a - PutStructure to revive the set. It should instead be smart enough to realize - that an empty set implies that the code can't execute. This was the only "bug" - that the use of m_isValid = false was preventing. - - - Finally, the main change: structure check hoisting looks at the source of the - SetLocals on structure-check-hoistable variables and ensures that the source - is not checked with a conflicting structure. This is O(n^2) but it does not - show up at all in performance tests. - - The first two parts of this change were auxiliary bugs that were revealed by - the structure check hoister doing bad things. + Fixed by forcing UInt32ToNumber to use a different register. This "undoes" the copy propagation that we + would have been doing, since it has no performance effect in this case and has the benefit of making the + OSR exit compiler a lot simpler. - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::initialize): - (JSC::DFG::AbstractState::execute): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileUInt32ToNumber): -2012-09-14 Filip Pizlo <fpizlo@apple.com> +2012-10-11 Geoffrey Garen <ggaren@apple.com> - All of the things in SparseArrayValueMap should be out-of-line - https://bugs.webkit.org/show_bug.cgi?id=96854 + Removed some more static assumptions about inline object capacity + https://bugs.webkit.org/show_bug.cgi?id=98603 - Reviewed by Andy Estes. + Reviewed by Filip Pizlo. - Those inline methods were buying us nothing. + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): Use JSObject::allocationSize() + for a little more flexibility. We still pass it a constant inline capacity + because the JIT doesn't have a strategy for selecting a size class based + on non-constant capacity yet. "INLINE_STORAGE_CAPACITY" is a marker for + code that makes static assumptions about object size. - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * runtime/JSArray.cpp: - * runtime/JSGlobalData.cpp: - * runtime/JSObject.cpp: - * runtime/RegExpMatchesArray.cpp: - * runtime/SparseArrayValueMap.cpp: - (JSC::SparseArrayValueMap::SparseArrayValueMap): - (JSC): - (JSC::SparseArrayValueMap::~SparseArrayValueMap): - (JSC::SparseArrayValueMap::finishCreation): - (JSC::SparseArrayValueMap::create): - (JSC::SparseArrayValueMap::destroy): - (JSC::SparseArrayValueMap::createStructure): - (JSC::SparseArrayValueMap::add): - (JSC::SparseArrayValueMap::putEntry): - (JSC::SparseArrayValueMap::putDirect): - (JSC::SparseArrayEntry::get): - (JSC::SparseArrayEntry::getNonSparseMode): - (JSC::SparseArrayValueMap::visitChildren): - * runtime/SparseArrayValueMapInlineMethods.h: Removed. + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + * llint/LLIntData.cpp: + (JSC::LLInt::Data::performAssertions): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: Ditto for the rest of our many execution engines. -2012-09-14 Mike West <mkwst@chromium.org> + * runtime/JSObject.h: + (JSC::JSObject::allocationSize): + (JSC::JSFinalObject::finishCreation): + (JSC::JSFinalObject::create): New helper function for computing object + size dynamically, since we plan to have objects of different sizes. - JSC should throw a more descriptive exception when blocking 'eval' via CSP. - https://bugs.webkit.org/show_bug.cgi?id=94331 + (JSC::JSFinalObject::JSFinalObject): Note that our m_inlineStorage used + to auto-generate an implicit C++ constructor with default null initialization. + This memory is not observed in its uninitialized state, and our LLInt and + JIT allocators do not initialize it, so I did not add any explicit code + to do so, now that the implicit code is gone. - Reviewed by Geoffrey Garen. + (JSC::JSObject::offsetOfInlineStorage): Changed the math here to match + inlineStorageUnsafe(), since we can rely on an explicit data member anymore. - Unless explicitly whitelisted, the 'script-src' Content Security Policy - directive blocks 'eval' and 'eval'-like constructs such as - 'new Function()'. When 'eval' is encountered in code, an 'EvalError' is - thrown, but the associated message is poor: "Eval is disabled" doesn't - give developers enough information about why their code isn't behaving - as expected. - - This patch adds an 'errorMessage' parameter to the JavaScriptCore method - used to disable 'eval'; ContentSecurityPolicy has the opportunity to - pass in a more detailed and descriptive error that contains more context - for the developer. - - * runtime/Executable.cpp: - (JSC::EvalExecutable::compileInternal): - Drop the hard-coded "Eval is disabled" error message in favor of - reading the error message off the global object. - * runtime/FunctionConstructor.cpp: - (JSC::FunctionConstructor::getCallData): - Drop the hard-coded "Function constructor is disabled" error message - in favor of reading the error message off the global object. - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::evalEnabled): - Making this accessor method const. - (JSC::JSGlobalObject::evalDisabledErrorMessage): - Accessor for the error message set via 'setEvalDisabled'. - (JSC::JSGlobalObject::setEvalEnabled): - Adding an 'errorMessage' parameter which is stored on the global - object, and used when exceptions are thrown. +2012-10-11 Geoffrey Garen <ggaren@apple.com> -2012-09-14 Filip Pizlo <fpizlo@apple.com> + Enable RUNTIME_HEURISTICS all the time, for easier testing + https://bugs.webkit.org/show_bug.cgi?id=99090 - bbc homepage crashes immediately - https://bugs.webkit.org/show_bug.cgi?id=96812 - <rdar://problem/12081386> + Reviewed by Filip Pizlo. - Reviewed by Oliver Hunt. + I find myself using this a lot, and there doesn't seem to be an obvious + reason to compile it out, since it only runs once at startup. - If you use the old storage pointer to write to space you thought was newly allocated, - you're going to have a bad time. + * runtime/Options.cpp: + (JSC::overrideOptionWithHeuristic): + (JSC::Options::initialize): + * runtime/Options.h: Removed the #ifdef. - * runtime/JSArray.cpp: - (JSC::JSArray::unshiftCount): +2012-10-11 Geoffrey Garen <ggaren@apple.com> -2012-09-14 Adam Barth <abarth@webkit.org> + Removed ASSERT_CLASS_FITS_IN_CELL + https://bugs.webkit.org/show_bug.cgi?id=97634 - Remove webkitPostMessage - https://bugs.webkit.org/show_bug.cgi?id=96577 + Reviewed by Mark Hahnenberg. - Reviewed by Ojan Vafai. + Our collector now supports arbitrarily sized objects, so the ASSERT is not needed. - Add ENABLE_LEGACY_VENDOR_PREFIXES flag. + * API/JSCallbackFunction.cpp: + * API/JSCallbackObject.cpp: + * heap/MarkedSpace.h: + * jsc.cpp: + * runtime/Arguments.cpp: + * runtime/ArrayConstructor.cpp: + * runtime/ArrayPrototype.cpp: + * runtime/BooleanConstructor.cpp: + * runtime/BooleanObject.cpp: + * runtime/BooleanPrototype.cpp: + * runtime/DateConstructor.cpp: + * runtime/DatePrototype.cpp: + * runtime/Error.cpp: + * runtime/ErrorConstructor.cpp: + * runtime/ErrorPrototype.cpp: + * runtime/FunctionConstructor.cpp: + * runtime/FunctionPrototype.cpp: + * runtime/InternalFunction.cpp: + * runtime/JSActivation.cpp: + * runtime/JSArray.cpp: + * runtime/JSBoundFunction.cpp: + * runtime/JSFunction.cpp: + * runtime/JSGlobalObject.cpp: + * runtime/JSGlobalThis.cpp: + * runtime/JSNameScope.cpp: + * runtime/JSNotAnObject.cpp: + * runtime/JSONObject.cpp: + * runtime/JSObject.cpp: + * runtime/JSPropertyNameIterator.cpp: + * runtime/JSScope.cpp: + * runtime/JSWithScope.cpp: + * runtime/JSWrapperObject.cpp: + * runtime/MathObject.cpp: + * runtime/NameConstructor.cpp: + * runtime/NamePrototype.cpp: + * runtime/NativeErrorConstructor.cpp: + * runtime/NativeErrorPrototype.cpp: + * runtime/NumberConstructor.cpp: + * runtime/NumberObject.cpp: + * runtime/NumberPrototype.cpp: + * runtime/ObjectConstructor.cpp: + * runtime/ObjectPrototype.cpp: + * runtime/RegExpConstructor.cpp: + * runtime/RegExpMatchesArray.cpp: + * runtime/RegExpObject.cpp: + * runtime/RegExpPrototype.cpp: + * runtime/StringConstructor.cpp: + * runtime/StringObject.cpp: + * runtime/StringPrototype.cpp: + * testRegExp.cpp: Removed the ASSERT. - * Configurations/FeatureDefines.xcconfig: +2012-10-11 Filip Pizlo <fpizlo@apple.com> -2012-09-14 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + DFG should inline code blocks that use new_array_buffer + https://bugs.webkit.org/show_bug.cgi?id=98996 - [Qt] Make force_static_libs_as_shared work on Mac OS + Reviewed by Geoffrey Garen. - We had to move a few LIBS += around that were in the wrong place, - and not caught when everything was just linked into the final - QtWebKit library. + This adds plumbing to drop in constant buffers from the inlinees to the inliner. + It's smart about not duplicating buffers needlessly but doesn't try to completely + hash-cons them, either. - Reviewed by Simon Hausmann. + * bytecode/CodeBlock.h: + (JSC::CodeBlock::numberOfConstantBuffers): + (JSC::CodeBlock::addConstantBuffer): + (JSC::CodeBlock::constantBufferAsVector): + (JSC::CodeBlock::constantBuffer): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (ConstantBufferKey): + (JSC::DFG::ConstantBufferKey::ConstantBufferKey): + (JSC::DFG::ConstantBufferKey::operator==): + (JSC::DFG::ConstantBufferKey::hash): + (JSC::DFG::ConstantBufferKey::isHashTableDeletedValue): + (JSC::DFG::ConstantBufferKey::codeBlock): + (JSC::DFG::ConstantBufferKey::index): + (DFG): + (JSC::DFG::ConstantBufferKeyHash::hash): + (JSC::DFG::ConstantBufferKeyHash::equal): + (ConstantBufferKeyHash): + (WTF): + (ByteCodeParser): + (InlineStackEntry): + (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGCapabilities.h: + (JSC::DFG::canInlineOpcode): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): - * jsc.pro: No need for AppKit, we get it from WTF.pri +2012-10-10 Zoltan Horvath <zoltan@webkit.org> -2012-09-14 Kevin Funk <kevin.funk@kdab.com> + Pageload tests should measure memory usage + https://bugs.webkit.org/show_bug.cgi?id=93958 - Fix interpreter build - https://bugs.webkit.org/show_bug.cgi?id=96617 + Reviewed by Ryosuke Niwa. - Reviewed by Simon Hausmann. + Add JS Heap and Heap memory measurement to PageLoad tests. - Make compile. + * heap/HeapStatistics.cpp: + (JSC::HeapStatistics::usedJSHeap): Add new private function to expose the used JS Heap size. + (JSC): + * heap/HeapStatistics.h: + (HeapStatistics): Add new private function to expose the used JS Heap size. - * interpreter/Interpreter.cpp: +2012-10-10 Balazs Kilvady <kilvadyb@homejinni.com> -2012-09-14 Parth Patel <parpatel@rim.com> + RegisterFile to JSStack rename fix for a struct member. - [BlackBerry] Switching from Slogger to Slogger2 requires changes in CMakeList of - webkit in order to include libraries of slog2 - https://bugs.webkit.org/show_bug.cgi?id=96391 + Compilation problem in debug build on MIPS + https://bugs.webkit.org/show_bug.cgi?id=98808 - Reviewed by Yong Li. + Reviewed by Alexey Proskuryakov. - Changes in Cmake files of JavaScriptCore of webkit to include slog2 libs in build - files of webkit in response to switching from Slogger to Slogger2. + In ASSERT conditions structure field name "registerFile" was replaced + with type name "JSStack" and it should be "stack". - * shell/PlatformBlackBerry.cmake: + * jit/JITStubs.cpp: + (JSC::JITThunks::JITThunks): structure member name fix. -2012-09-14 Mark Hahnenberg <mhahnenberg@apple.com> +2012-10-10 Michael Saboff <msaboff@apple.com> - Remove the Zapped BlockState - https://bugs.webkit.org/show_bug.cgi?id=96708 + After r130344, OpaqueJSString::string() shouldn't directly return the wrapped String + https://bugs.webkit.org/show_bug.cgi?id=98801 Reviewed by Geoffrey Garen. - The Zapped block state is rather confusing. It indicates that a block is in one of two different states that we - can't tell the difference between: - - 1) I have run all destructors of things that are zapped, and I have not allocated any more objects. This block - is ready for reclaiming if you so choose. - 2) I have run all the destructors of things that are zapped, but I have allocated more stuff since then, so it - is not safe to reclaim this block. - - This state adds a lot of complexity to our state transition model for MarkedBlocks. We should get rid of it. - We can replace this state by making sure mark bits represent all of the liveness information we need when running - our conservative stack scan. Instead of zapping the free list when canonicalizing cell liveness data prior to - a conservative scan, we can instead mark all objects in the block except for those in the free list. This should - incur no performance penalty since we're doing it on a very small O(1) number of blocks at the beginning of the collection. - - For the time being we still need to use zapping to determine whether we have run an object's destructor or not. - - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::tryAllocateHelper): Renaming stuff. - * heap/MarkedAllocator.h: Renamed zapFreeList to canonicalizeCellLivenessData to match. - (MarkedAllocator): - (JSC::MarkedAllocator::canonicalizeCellLivenessData): Same as old zapFreeList, but just call canonicalize instead. - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::specializedSweep): Remove the check for Zapped block stuff. Also change the block state to Marked - instead of Zapped if we're not producing a FreeList since that's the only other state that really makes any sense. - (JSC::MarkedBlock::sweepHelper): Remove Zapped related code. - (SetAllMarksFunctor): Functor to set all the mark bits in the block since there's not a simple function to call on - the Bitmap itself. - (JSC::SetAllMarksFunctor::operator()): - (JSC): - (JSC::MarkedBlock::canonicalizeCellLivenessData): Remove all the stuff for Zapped. For FreeListed, set all the mark bits - and then clear the ones for the objects in the FreeList. This ensures that only the things that were in the FreeList - are considered to be dead by the conservative scan, just like if we were to have zapped the FreeList like before. - * heap/MarkedBlock.h: - (MarkedBlock): - (JSC::MarkedBlock::clearMarked): Add function to clear individual mark bits, since we need that functionality now. - (JSC): - (JSC::MarkedBlock::isLive): Remove code for Zapped stuff. Marked handles all interesting cases now. - (JSC::MarkedBlock::forEachCell): Add new iterator function that iterates over all cells in the block, regardless of - whether they're live or a dead. - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::canonicalizeCellLivenessData): Change to call the renamed canonicalize function. - -2012-09-13 Kevin Funk <kevin.funk@kdab.com> - - Make compile with both OS(WINCE) and PLATFORM(QT) support - https://bugs.webkit.org/show_bug.cgi?id=95536 + Return a copy of the wrapped String so that the wrapped string cannot be turned into + an Identifier. - Reviewed by Simon Hausmann. + * API/OpaqueJSString.cpp: + (OpaqueJSString::string): + * API/OpaqueJSString.h: + (OpaqueJSString): - Do not link against advapi32 on wince +2012-10-10 Peter Gal <galpeter@inf.u-szeged.hu> - * jsc.pro: + Add moveDoubleToInts and moveIntsToDouble to MacroAssemblerARM + https://bugs.webkit.org/show_bug.cgi?id=98855 -2012-09-13 Geoffrey Garen <ggaren@apple.com> + Reviewed by Filip Pizlo. - Refactored the DFG to make fewer assumptions about variable capture - https://bugs.webkit.org/show_bug.cgi?id=96680 + Implement the missing moveDoubleToInts and moveIntsToDouble + methods in the MacroAssemblerARM after r130839. - Reviewed by Gavin Barraclough. + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::moveDoubleToInts): + (MacroAssemblerARM): + (JSC::MacroAssemblerARM::moveIntsToDouble): - A variable capture optimization patch I'm working on broke DFG - correctness and the arguments simplification optimization phase, so I've - refactored both to make fewer assumptions about variable capture. +2012-10-09 Filip Pizlo <fpizlo@apple.com> - * bytecode/CodeBlock.h: - (JSC::CodeBlock::isCaptured): This is the new One True Way to find out - if a variable was captured. This gives us a single point of maintenance - as we chagne capture behavior. + Typed arrays should not be 20x slower in the baseline JIT than in the DFG JIT + https://bugs.webkit.org/show_bug.cgi?id=98605 - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::clobberCapturedVars): Don't assume that captured - variables have any particular location. Instead, ask the One True Function. + Reviewed by Oliver Hunt and Gavin Barraclough. - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): - (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): Mechanical - changes to separate being captured from being 'arguments'. What used - to be - if (captured) - if (arguments) - x - y - is now - if (arguments) - x - y - else if (captured) - y + This adds typed array get_by_val/put_by_val patching to the baseline JIT. It's + a big (~40%) win on benchmarks that have trouble staying in the DFG JIT. Even + if we fix those benchmarks, this functionality gives us the insurance that we + typically desire with all speculative optimizations: even if we bail to + baseline, we're still reasonably performant. - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::getLocal): - (JSC::DFG::ByteCodeParser::setLocal): - (JSC::DFG::ByteCodeParser::getArgument): - (JSC::DFG::ByteCodeParser::setArgument): - (JSC::DFG::ByteCodeParser::flushDirect): - (JSC::DFG::ByteCodeParser::parseBlock): - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * assembler/MacroAssembler.cpp: Added. + (JSC): + * assembler/MacroAssembler.h: + (MacroAssembler): + (JSC::MacroAssembler::patchableBranchPtr): + * assembler/MacroAssemblerARMv7.h: + (MacroAssemblerARMv7): + (JSC::MacroAssemblerARMv7::moveDoubleToInts): + (JSC::MacroAssemblerARMv7::moveIntsToDouble): + (JSC::MacroAssemblerARMv7::patchableBranchPtr): + * assembler/MacroAssemblerX86.h: + (MacroAssemblerX86): + (JSC::MacroAssemblerX86::moveDoubleToInts): + (JSC::MacroAssemblerX86::moveIntsToDouble): + * bytecode/ByValInfo.h: + (JSC::hasOptimizableIndexingForClassInfo): + (JSC): + (JSC::hasOptimizableIndexing): + (JSC::jitArrayModeForClassInfo): + (JSC::jitArrayModeForStructure): + (JSC::ByValInfo::ByValInfo): + (ByValInfo): + * dfg/DFGAssemblyHelpers.cpp: + (DFG): + * dfg/DFGAssemblyHelpers.h: + (AssemblyHelpers): + (JSC::DFG::AssemblyHelpers::boxDouble): + (JSC::DFG::AssemblyHelpers::unboxDouble): * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compile): Use the One True Function. + (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray): + (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * jit/JIT.h: + (JIT): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompileGetByVal): + (JSC::JIT::privateCompilePutByVal): + (JSC::JIT::emitIntTypedArrayGetByVal): + (JSC): + (JSC::JIT::emitFloatTypedArrayGetByVal): + (JSC::JIT::emitIntTypedArrayPutByVal): + (JSC::JIT::emitFloatTypedArrayPutByVal): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/JSCell.h: + * runtime/JSGlobalData.h: + (JSGlobalData): + (JSC::JSGlobalData::typedArrayDescriptor): + * runtime/TypedArrayDescriptor.h: Added. + (JSC): + (JSC::TypedArrayDescriptor::TypedArrayDescriptor): + (TypedArrayDescriptor): -2012-09-13 Benjamin Poulain <bpoulain@apple.com> +2012-10-09 Michael Saboff <msaboff@apple.com> - Improve the SourceProvider hierarchy - https://bugs.webkit.org/show_bug.cgi?id=95635 + Add tests to testapi for null OpaqueJSStrings + https://bugs.webkit.org/show_bug.cgi?id=98805 Reviewed by Geoffrey Garen. - SourceProvider was designed to have subclasses magically handling the data without - decoding all of it. The virtual methods length() and getRange() were based - on these assumptions. - - In practice, the magic was in our head, there is no implementation that takes - advantage of that. - - SourceProvider is modified to adopt WebCore's ScriptSourceProvider::source() and base - everything on it. - The code using SourceProvider is also simplified. - - * interpreter/Interpreter.cpp: - (JSC::appendSourceToError): Keep a reference to the string instead of querying it for - each time it is used. - * parser/Lexer.cpp: - (JSC::::setCode): - (JSC::::sourceCode): - * parser/Parser.h: - (JSC::parse): - * parser/SourceCode.h: - (JSC::SourceCode::SourceCode): - (JSC::SourceCode::subExpression): - * parser/SourceProvider.h: - (SourceProvider): - (JSC::SourceProvider::getRange): + Added tests that check that OpaqueJSString, which is wrapped via JSStringRef, properly returns + null strings and that a null string in a JSStringRef will return a NULL JSChar* and 0 length + via the JSStringGetCharactersPtr() and JSStringGetLength() APIs respectively. Added a check that + JSValueMakeFromJSONString() properly handles a null string as well. -2012-09-13 Filip Pizlo <fpizlo@apple.com> + * API/tests/testapi.c: + (main): - DFG: Dead GetButterfly's shouldn't be subject to CSE - https://bugs.webkit.org/show_bug.cgi?id=96707 - <rdar://problem/12296311> +2012-10-09 Jian Li <jianli@chromium.org> - Reviewed by Oliver Hunt. - - There were a number of cases of this that creeped into the CSE: it would - match something even though it was dead. + Update the CSS property used to support draggable regions. + https://bugs.webkit.org/show_bug.cgi?id=97156 - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): - (JSC::DFG::CSEPhase::checkArrayElimination): - (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): - (JSC::DFG::CSEPhase::getScopeChainLoadElimination): - (JSC::DFG::CSEPhase::getLocalLoadElimination): + Reviewed by Adam Barth. -2012-09-13 Oliver Hunt <oliver@apple.com> + The CSS property to support draggable regions, guarded under + WIDGET_REGION is now disabled from Mac WebKit, in order not to cause + confusion with DASHBOARD_SUPPORT feature. - Make global const initialisation explicit in the bytecode - https://bugs.webkit.org/show_bug.cgi?id=96711 + * Configurations/FeatureDefines.xcconfig: Disable WIDGET_REGION feature. - Reviewed by Gavin Barraclough. +2012-10-09 Filip Pizlo <fpizlo@apple.com> - Added op_init_global_const to make initialisation of global const - fields explicit. This will help us keep correct semantics in the - upcoming variable resolution refactoring. + Unreviewed, adding forgotten files. - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - * bytecode/Opcode.h: + * bytecode/ByValInfo.h: Added. (JSC): - (JSC::padOpcodeName): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitInitGlobalConst): + (JSC::isOptimizableIndexingType): + (JSC::jitArrayModeForIndexingType): + (JSC::ByValInfo::ByValInfo): + (ByValInfo): + (JSC::getByValInfoBytecodeIndex): + * runtime/IndexingType.cpp: Added. (JSC): - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - * bytecompiler/NodesCodegen.cpp: - (JSC::ConstDeclNode::emitCodeSingle): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCapabilities.h: - (JSC::DFG::canCompileOpcode): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JIT.cpp: - (JSC::JIT::privateCompileMainPass): - (JSC::JIT::privateCompileSlowCases): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-09-13 Mark Hahnenberg <mhahnenberg@apple.com> - - Rename forEachCell to forEachLiveCell - https://bugs.webkit.org/show_bug.cgi?id=96685 - - Reviewed by Oliver Hunt. - - forEachCell actually only iterates over live cells. We should rename it to - reflect what it actually does. This is also helpful because we want to add a new - forEachCell that actually does iterate each and every cell in a MarkedBlock - regardless of whether or not it is live. - - * debugger/Debugger.cpp: - (JSC::Debugger::recompileAllJSFunctions): - * heap/Heap.cpp: - (JSC::Heap::globalObjectCount): - (JSC::Heap::objectTypeCounts): - * heap/MarkedBlock.h: - (MarkedBlock): - (JSC::MarkedBlock::forEachLiveCell): - * heap/MarkedSpace.h: - (MarkedSpace): - (JSC::MarkedSpace::forEachLiveCell): - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::releaseExecutableMemory): - -2012-09-13 Filip Pizlo <fpizlo@apple.com> - - [Qt][Win] REGRESSION(r128400): It broke the build - https://bugs.webkit.org/show_bug.cgi?id=96617 - - Reviewed by Simon Hausmann. - - Changed "JSC::Array" to "JSC::ArrayClass" because it's not used often enough - for the brevity to be beneficial, and because "Array" causes too much namespace - pollution. - - * runtime/IndexingType.h: - (JSC): - * runtime/JSArray.cpp: - (JSC::JSArray::pop): - (JSC::JSArray::push): - (JSC::JSArray::sortNumeric): - (JSC::JSArray::sort): - (JSC::JSArray::fillArgList): - (JSC::JSArray::copyToArguments): - (JSC::JSArray::compactForSorting): - * runtime/JSObject.cpp: - (JSC::JSObject::getOwnPropertySlotByIndex): - (JSC::JSObject::putByIndex): - (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode): - (JSC::JSObject::deletePropertyByIndex): - (JSC::JSObject::getOwnPropertyNames): - (JSC::JSObject::putByIndexBeyondVectorLength): - (JSC::JSObject::putDirectIndexBeyondVectorLength): - (JSC::JSObject::getNewVectorLength): - (JSC::JSObject::getOwnPropertyDescriptor): - * runtime/JSObject.h: - (JSC::JSObject::getArrayLength): - (JSC::JSObject::getVectorLength): - (JSC::JSObject::canGetIndexQuickly): - (JSC::JSObject::canSetIndexQuickly): - (JSC::JSObject::inSparseIndexingMode): - (JSC::JSObject::ensureArrayStorage): - -2012-09-13 Filip Pizlo <fpizlo@apple.com> + (JSC::indexingTypeToString): - Testing whether indexing type is ArrayWithArrayStorage should not compare against ArrayWithArrayStorage - https://bugs.webkit.org/show_bug.cgi?id=96611 +2012-10-08 Filip Pizlo <fpizlo@apple.com> - Reviewed by Gavin Barraclough. + JSC should infer when indexed storage is contiguous, and optimize for it + https://bugs.webkit.org/show_bug.cgi?id=97288 - * dfg/DFGRepatch.cpp: - (JSC::DFG::tryCacheGetByID): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::checkArray): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::privateCompilePatchGetArrayLength): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::privateCompilePatchGetArrayLength): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-09-09 Filip Pizlo <fpizlo@apple.com> - - JSC should have property butterflies - https://bugs.webkit.org/show_bug.cgi?id=91933 - - Reviewed by Geoffrey Garen. + Reviewed by Mark Hahnenberg. - This changes the JSC object model. Previously, all objects had fast lookup for - named properties. Integer indexed properties were only fast if you used a - JSArray. With this change, all objects have fast indexed properties. This is - accomplished without any space overhead by using a bidirectional object layout, - aka butterflies. Each JSObject has a m_butterfly pointer where previously it - had a m_outOfLineStorage pointer. To the left of the location pointed to by - m_butterfly, we place all named out-of-line properties. To the right, we place - all indexed properties along with indexing meta-data. Though, some indexing - meta-data is placed in the 8-byte word immediately left of the pointed-to - location; this is in anticipation of the indexing meta-data being small enough - in the common case that m_butterfly always points to the first indexed - property. + This introduces a new kind of indexed property storage called Contiguous, + which has the following properties: - This is performance neutral, except on tests that use indexed properties on - plain objects, where the speed-up is in excess of an order of magnitude. + - No header bits beyond IndexedHeader. This results in a 16 byte reduction + in memory usage per array versus an ArrayStorage array. It also means + that the total memory usage for an empty array is now just 3 * 8 on both + 32-bit and 64-bit. Of that, only 8 bytes are array-specific; the rest is + our standard object header overhead. - One notable aspect of what this change brings is that it allows indexing - storage to morph over time. Currently this is only used to allow all non-array - objects to start out without any indexed storage. But it could be used for - some kinds of array type inference in the future. + - No need for hole checks on store. This results in a ~4% speed-up on + Kraken and a ~1% speed-up on V8v7. + + - publicLength <= vectorLength. This means that doing new Array(blah) + immediately allocates room for blah elements. + + - No sparse map or index bias. + + If you ever do things to an array that would require publicLength > + vectorLength, a sparse map, or index bias, then we switch to ArrayStorage + mode. This seems to never happen in any benchmark we track, and is unlikely + to happen very frequently on any website. - * API/JSCallbackObject.h: - (JSCallbackObject): - * API/JSCallbackObjectFunctions.h: - (JSC::::getOwnPropertySlotByIndex): - (JSC): - (JSC::::getOwnNonIndexPropertyNames): - * API/JSObjectRef.cpp: * CMakeLists.txt: * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: * Target.pri: - * bytecode/ArrayProfile.h: - (JSC): - (JSC::arrayModeFromStructure): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitDirectPutById): + * assembler/AbstractMacroAssembler.h: + (JSC::AbstractMacroAssembler::JumpList::append): + * assembler/MacroAssembler.h: + (MacroAssembler): + (JSC::MacroAssembler::patchableBranchTest32): + * bytecode/ByValInfo.h: Added. + (JSC): + (JSC::isOptimizableIndexingType): + (JSC::jitArrayModeForIndexingType): + (JSC::ByValInfo::ByValInfo): + (ByValInfo): + (JSC::getByValInfoBytecodeIndex): + * bytecode/CodeBlock.h: + (CodeBlock): + (JSC::CodeBlock::getByValInfo): + (JSC::CodeBlock::setNumberOfByValInfos): + (JSC::CodeBlock::numberOfByValInfos): + (JSC::CodeBlock::byValInfo): + * bytecode/SamplingTool.h: * dfg/DFGAbstractState.cpp: (JSC::DFG::AbstractState::execute): - * dfg/DFGAdjacencyList.h: - (JSC::DFG::AdjacencyList::AdjacencyList): - (AdjacencyList): * dfg/DFGArrayMode.cpp: (JSC::DFG::fromObserved): (JSC::DFG::modeAlreadyChecked): @@ -2591,3391 +1851,547 @@ (JSC::DFG::modeUsesButterfly): (JSC::DFG::modeIsJSArray): (JSC::DFG::isInBoundsAccess): + (JSC::DFG::mayStoreToTail): + (JSC::DFG::mayStoreToHole): + (JSC::DFG::modeIsPolymorphic): + (JSC::DFG::polymorphicIncludesContiguous): + (JSC::DFG::polymorphicIncludesArrayStorage): + (JSC::DFG::canCSEStorage): (JSC::DFG::modeSupportsLength): + (JSC::DFG::benefitsFromStructureCheck): + (JSC::DFG::isEffectful): * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleGetByOffset): - (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::handleIntrinsic): * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::getArrayLengthElimination): + (JSC::DFG::CSEPhase::getByValLoadElimination): (JSC::DFG::CSEPhase::performNodeCSE): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): - (JSC::DFG::FixupPhase::addNode): - (FixupPhase): (JSC::DFG::FixupPhase::checkArray): + (JSC::DFG::FixupPhase::blessArrayOperation): * dfg/DFGGraph.h: (JSC::DFG::Graph::byValIsPure): - * dfg/DFGNode.h: - (JSC::DFG::Node::Node): - (Node): - * dfg/DFGNodeType.h: - (DFG): * dfg/DFGOperations.cpp: - (JSC::DFG::putByVal): * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): * dfg/DFGRepatch.cpp: - (JSC::DFG::generateProtoChainAccessStub): (JSC::DFG::tryCacheGetByID): - (JSC::DFG::tryBuildGetByIDList): - (JSC::DFG::emitPutReplaceStub): - (JSC::DFG::emitPutTransitionStub): - (JSC::DFG::tryBuildPutByIdList): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::checkArray): - (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): + (JSC::DFG::SpeculativeJIT::arrayify): (JSC::DFG::SpeculativeJIT::compileGetArrayLength): - (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): - (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): + (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal): + (DFG): * dfg/DFGSpeculativeJIT.h: + (DFG): (JSC::DFG::SpeculativeJIT::callOperation): - (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::putByValWillNeedExtraRegister): + (JSC::DFG::SpeculativeJIT::temporaryRegisterForPutByVal): * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::cachedGetById): - (JSC::DFG::SpeculativeJIT::cachedPutById): + (JSC::DFG::SpeculativeJIT::compileContiguousGetByVal): + (DFG): + (JSC::DFG::SpeculativeJIT::compileArrayStorageGetByVal): + (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal): + (JSC::DFG::SpeculativeJIT::compileArrayStoragePutByVal): (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::cachedGetById): - (JSC::DFG::SpeculativeJIT::cachedPutById): + (JSC::DFG::SpeculativeJIT::compileContiguousGetByVal): + (DFG): + (JSC::DFG::SpeculativeJIT::compileArrayStorageGetByVal): + (JSC::DFG::SpeculativeJIT::compileContiguousPutByVal): + (JSC::DFG::SpeculativeJIT::compileArrayStoragePutByVal): (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - * heap/CopiedSpace.h: - (CopiedSpace): + * interpreter/Interpreter.cpp: + (SamplingScope): + (JSC::SamplingScope::SamplingScope): + (JSC::SamplingScope::~SamplingScope): + (JSC): + (JSC::Interpreter::execute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileSlowCases): + (JSC::JIT::privateCompile): * jit/JIT.h: + (JSC::ByValCompilationInfo::ByValCompilationInfo): + (ByValCompilationInfo): + (JSC): + (JIT): + (JSC::JIT::compileGetByVal): + (JSC::JIT::compilePutByVal): * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - (JSC::JIT::emitAllocateBasicStorage): (JSC::JIT::emitAllocateJSArray): + (JSC::JIT::emitArrayProfileStoreToHoleSpecialCase): + (JSC): + (JSC::arrayProfileSaw): + (JSC::JIT::chooseArrayMode): * jit/JITOpcodes.cpp: + (JSC::JIT::emitSlow_op_get_argument_by_val): (JSC::JIT::emit_op_new_array): (JSC::JIT::emitSlow_op_new_array): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emitSlow_op_get_argument_by_val): * jit/JITPropertyAccess.cpp: (JSC::JIT::emit_op_get_by_val): - (JSC::JIT::compileGetDirectOffset): + (JSC): + (JSC::JIT::emitContiguousGetByVal): + (JSC::JIT::emitArrayStorageGetByVal): + (JSC::JIT::emitSlow_op_get_by_val): (JSC::JIT::emit_op_put_by_val): - (JSC::JIT::compileGetByIdHotPath): - (JSC::JIT::emit_op_put_by_id): - (JSC::JIT::compilePutDirectOffset): + (JSC::JIT::emitContiguousPutByVal): + (JSC::JIT::emitArrayStoragePutByVal): + (JSC::JIT::emitSlow_op_put_by_val): (JSC::JIT::privateCompilePatchGetArrayLength): + (JSC::JIT::privateCompileGetByVal): + (JSC::JIT::privateCompilePutByVal): * jit/JITPropertyAccess32_64.cpp: (JSC::JIT::emit_op_get_by_val): + (JSC): + (JSC::JIT::emitContiguousGetByVal): + (JSC::JIT::emitArrayStorageGetByVal): + (JSC::JIT::emitSlow_op_get_by_val): (JSC::JIT::emit_op_put_by_val): - (JSC::JIT::compileGetByIdHotPath): - (JSC::JIT::emit_op_put_by_id): - (JSC::JIT::compilePutDirectOffset): - (JSC::JIT::compileGetDirectOffset): - (JSC::JIT::privateCompilePatchGetArrayLength): + (JSC::JIT::emitContiguousPutByVal): + (JSC::JIT::emitArrayStoragePutByVal): + (JSC::JIT::emitSlow_op_put_by_val): * jit/JITStubs.cpp: + (JSC::getByVal): + (JSC): (JSC::DEFINE_STUB_FUNCTION): - * jsc.cpp: - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): + (JSC::putByVal): + * jit/JITStubs.h: * llint/LowLevelInterpreter.asm: * llint/LowLevelInterpreter32_64.asm: * llint/LowLevelInterpreter64.asm: - * runtime/Arguments.cpp: - (JSC::Arguments::deletePropertyByIndex): - (JSC::Arguments::defineOwnProperty): - * runtime/ArrayConstructor.cpp: - * runtime/ArrayConventions.h: Added. - (JSC): + * runtime/ArrayConventions.h: (JSC::isDenseEnoughForVector): - (JSC::indexingHeaderForArray): - (JSC::baseIndexingHeaderForArray): * runtime/ArrayPrototype.cpp: - (JSC::ArrayPrototype::create): - (JSC): - (JSC::ArrayPrototype::ArrayPrototype): - (JSC::arrayProtoFuncToString): - (JSC::arrayProtoFuncJoin): - (JSC::arrayProtoFuncSort): - (JSC::arrayProtoFuncFilter): - (JSC::arrayProtoFuncMap): - (JSC::arrayProtoFuncEvery): - (JSC::arrayProtoFuncForEach): - (JSC::arrayProtoFuncSome): - (JSC::arrayProtoFuncReduce): - (JSC::arrayProtoFuncReduceRight): - * runtime/ArrayPrototype.h: - (ArrayPrototype): - (JSC::ArrayPrototype::createStructure): - * runtime/ArrayStorage.h: Added. - (JSC): - (ArrayStorage): - (JSC::ArrayStorage::ArrayStorage): - (JSC::ArrayStorage::from): - (JSC::ArrayStorage::butterfly): - (JSC::ArrayStorage::indexingHeader): - (JSC::ArrayStorage::length): - (JSC::ArrayStorage::setLength): - (JSC::ArrayStorage::vectorLength): - (JSC::ArrayStorage::setVectorLength): - (JSC::ArrayStorage::copyHeaderFromDuringGC): - (JSC::ArrayStorage::inSparseMode): - (JSC::ArrayStorage::lengthOffset): - (JSC::ArrayStorage::vectorLengthOffset): - (JSC::ArrayStorage::numValuesInVectorOffset): - (JSC::ArrayStorage::vectorOffset): - (JSC::ArrayStorage::indexBiasOffset): - (JSC::ArrayStorage::sparseMapOffset): - (JSC::ArrayStorage::sizeFor): - * runtime/Butterfly.h: Added. (JSC): + (JSC::shift): + (JSC::unshift): + (JSC::arrayProtoFuncPush): + (JSC::arrayProtoFuncShift): + (JSC::arrayProtoFuncSplice): + (JSC::arrayProtoFuncUnShift): + * runtime/Butterfly.h: (Butterfly): - (JSC::Butterfly::Butterfly): - (JSC::Butterfly::totalSize): - (JSC::Butterfly::fromBase): - (JSC::Butterfly::offsetOfIndexingHeader): - (JSC::Butterfly::offsetOfPublicLength): - (JSC::Butterfly::offsetOfVectorLength): - (JSC::Butterfly::indexingHeader): - (JSC::Butterfly::propertyStorage): - (JSC::Butterfly::indexingPayload): - (JSC::Butterfly::arrayStorage): - (JSC::Butterfly::offsetOfPropertyStorage): - (JSC::Butterfly::indexOfPropertyStorage): - (JSC::Butterfly::base): - * runtime/ButterflyInlineMethods.h: Added. - (JSC): - (JSC::Butterfly::createUninitialized): - (JSC::Butterfly::create): - (JSC::Butterfly::createUninitializedDuringCollection): - (JSC::Butterfly::base): - (JSC::Butterfly::growPropertyStorage): - (JSC::Butterfly::growArrayRight): - (JSC::Butterfly::resizeArray): + (JSC::Butterfly::fromPointer): + (JSC::Butterfly::pointer): + (JSC::Butterfly::publicLength): + (JSC::Butterfly::vectorLength): + (JSC::Butterfly::setPublicLength): + (JSC::Butterfly::setVectorLength): + (JSC::Butterfly::contiguous): + (JSC::Butterfly::fromContiguous): + * runtime/ButterflyInlineMethods.h: (JSC::Butterfly::unshift): (JSC::Butterfly::shift): - * runtime/ClassInfo.h: - (MethodTable): - (JSC): - * runtime/IndexingHeader.h: Added. - (JSC): - (IndexingHeader): - (JSC::IndexingHeader::offsetOfIndexingHeader): - (JSC::IndexingHeader::offsetOfPublicLength): - (JSC::IndexingHeader::offsetOfVectorLength): - (JSC::IndexingHeader::IndexingHeader): - (JSC::IndexingHeader::vectorLength): - (JSC::IndexingHeader::setVectorLength): - (JSC::IndexingHeader::publicLength): - (JSC::IndexingHeader::setPublicLength): - (JSC::IndexingHeader::from): - (JSC::IndexingHeader::fromEndOf): - (JSC::IndexingHeader::propertyStorage): - (JSC::IndexingHeader::arrayStorage): - (JSC::IndexingHeader::butterfly): - * runtime/IndexingHeaderInlineMethods.h: Added. - (JSC): - (JSC::IndexingHeader::preCapacity): + * runtime/IndexingHeaderInlineMethods.h: (JSC::IndexingHeader::indexingPayloadSizeInBytes): - * runtime/IndexingType.h: Added. + * runtime/IndexingType.cpp: Added. (JSC): - (JSC::hasIndexingHeader): - * runtime/JSActivation.cpp: - (JSC::JSActivation::JSActivation): - (JSC::JSActivation::visitChildren): - (JSC::JSActivation::getOwnNonIndexPropertyNames): - * runtime/JSActivation.h: - (JSActivation): - (JSC::JSActivation::tearOff): - * runtime/JSArray.cpp: + (JSC::indexingTypeToString): + * runtime/IndexingType.h: (JSC): - (JSC::createArrayButterflyInDictionaryIndexingMode): - (JSC::JSArray::setLengthWritable): - (JSC::JSArray::defineOwnProperty): - (JSC::JSArray::getOwnPropertySlot): - (JSC::JSArray::getOwnPropertyDescriptor): - (JSC::JSArray::put): - (JSC::JSArray::deleteProperty): - (JSC::JSArray::getOwnNonIndexPropertyNames): - (JSC::JSArray::unshiftCountSlowCase): + (JSC::hasContiguous): + * runtime/JSArray.cpp: + (JSC::JSArray::setLengthWithArrayStorage): (JSC::JSArray::setLength): + (JSC): (JSC::JSArray::pop): (JSC::JSArray::push): - (JSC::JSArray::shiftCount): - (JSC::JSArray::unshiftCount): + (JSC::JSArray::shiftCountWithArrayStorage): + (JSC::JSArray::shiftCountWithAnyIndexingType): + (JSC::JSArray::unshiftCountWithArrayStorage): + (JSC::JSArray::unshiftCountWithAnyIndexingType): + (JSC::JSArray::sortNumericVector): (JSC::JSArray::sortNumeric): + (JSC::JSArray::sortCompactedVector): (JSC::JSArray::sort): + (JSC::JSArray::sortVector): (JSC::JSArray::fillArgList): (JSC::JSArray::copyToArguments): (JSC::JSArray::compactForSorting): * runtime/JSArray.h: - (JSC): + (JSC::JSArray::shiftCountForShift): + (JSC::JSArray::shiftCountForSplice): (JSArray): - (JSC::JSArray::JSArray): - (JSC::JSArray::length): - (JSC::JSArray::createStructure): + (JSC::JSArray::shiftCount): + (JSC::JSArray::unshiftCountForShift): + (JSC::JSArray::unshiftCountForSplice): + (JSC::JSArray::unshiftCount): (JSC::JSArray::isLengthWritable): - (JSC::createArrayButterfly): + (JSC::createContiguousArrayButterfly): + (JSC): (JSC::JSArray::create): (JSC::JSArray::tryCreateUninitialized): - * runtime/JSBoundFunction.cpp: - (JSC::boundFunctionCall): - (JSC::boundFunctionConstruct): - (JSC::JSBoundFunction::finishCreation): - * runtime/JSCell.cpp: - (JSC::JSCell::getOwnNonIndexPropertyNames): - (JSC): - * runtime/JSCell.h: - (JSCell): - * runtime/JSFunction.cpp: - (JSC::JSFunction::getOwnPropertySlot): - (JSC::JSFunction::getOwnPropertyDescriptor): - (JSC::JSFunction::getOwnNonIndexPropertyNames): - (JSC::JSFunction::defineOwnProperty): - * runtime/JSFunction.h: - (JSFunction): - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: - (JSGlobalData): * runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::reset): - * runtime/JSONObject.cpp: - (JSC::Stringifier::Holder::appendNextProperty): - (JSC::Walker::walk): - * runtime/JSObject.cpp: (JSC): + (JSC::JSGlobalObject::haveABadTime): + (JSC::JSGlobalObject::visitChildren): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::arrayStructureWithArrayStorage): + (JSC::JSGlobalObject::addressOfArrayStructureWithArrayStorage): + (JSC::constructEmptyArray): + * runtime/JSObject.cpp: (JSC::JSObject::visitButterfly): - (JSC::JSObject::visitChildren): - (JSC::JSFinalObject::visitChildren): (JSC::JSObject::getOwnPropertySlotByIndex): - (JSC::JSObject::put): (JSC::JSObject::putByIndex): - (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists): (JSC::JSObject::enterDictionaryIndexingMode): + (JSC::JSObject::createInitialContiguous): + (JSC): (JSC::JSObject::createArrayStorage): - (JSC::JSObject::createInitialArrayStorage): + (JSC::JSObject::convertContiguousToArrayStorage): + (JSC::JSObject::ensureContiguousSlow): + (JSC::JSObject::ensureArrayStorageSlow): + (JSC::JSObject::ensureIndexedStorageSlow): (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode): - (JSC::JSObject::putDirectAccessor): - (JSC::JSObject::deleteProperty): + (JSC::JSObject::switchToSlowPutArrayStorage): + (JSC::JSObject::setPrototype): (JSC::JSObject::deletePropertyByIndex): (JSC::JSObject::getOwnPropertyNames): - (JSC::JSObject::getOwnNonIndexPropertyNames): - (JSC::JSObject::preventExtensions): - (JSC::JSObject::fillGetterPropertySlot): - (JSC::JSObject::putIndexedDescriptor): (JSC::JSObject::defineOwnIndexedProperty): - (JSC::JSObject::allocateSparseIndexMap): - (JSC::JSObject::deallocateSparseIndexMap): - (JSC::JSObject::putByIndexBeyondVectorLengthWithArrayStorage): + (JSC::JSObject::putByIndexBeyondVectorLengthContiguousWithoutAttributes): (JSC::JSObject::putByIndexBeyondVectorLength): (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage): (JSC::JSObject::putDirectIndexBeyondVectorLength): (JSC::JSObject::getNewVectorLength): + (JSC::JSObject::countElementsInContiguous): (JSC::JSObject::increaseVectorLength): - (JSC::JSObject::checkIndexingConsistency): - (JSC::JSObject::growOutOfLineStorage): + (JSC::JSObject::ensureContiguousLengthSlow): (JSC::JSObject::getOwnPropertyDescriptor): - (JSC::putDescriptor): - (JSC::JSObject::putDirectMayBeIndex): - (JSC::JSObject::defineOwnNonIndexProperty): - (JSC::JSObject::defineOwnProperty): - (JSC::JSObject::getOwnPropertySlotSlow): * runtime/JSObject.h: (JSC::JSObject::getArrayLength): - (JSObject): (JSC::JSObject::getVectorLength): - (JSC::JSObject::putDirectIndex): (JSC::JSObject::canGetIndexQuickly): (JSC::JSObject::getIndexQuickly): + (JSC::JSObject::tryGetIndexQuickly): (JSC::JSObject::canSetIndexQuickly): + (JSC::JSObject::canSetIndexQuicklyForPutDirect): (JSC::JSObject::setIndexQuickly): (JSC::JSObject::initializeIndex): - (JSC::JSObject::completeInitialization): + (JSC::JSObject::hasSparseMap): (JSC::JSObject::inSparseIndexingMode): - (JSC::JSObject::butterfly): - (JSC::JSObject::outOfLineStorage): - (JSC::JSObject::offsetForLocation): - (JSC::JSObject::indexingShouldBeSparse): - (JSC::JSObject::butterflyOffset): - (JSC::JSObject::butterflyAddress): - (JSC::JSObject::arrayStorage): - (JSC::JSObject::arrayStorageOrZero): - (JSC::JSObject::ensureArrayStorage): - (JSC::JSObject::checkIndexingConsistency): - (JSC::JSNonFinalObject::JSNonFinalObject): - (JSC): - (JSC::JSObject::setButterfly): - (JSC::JSObject::setButterflyWithoutChangingStructure): - (JSC::JSObject::JSObject): - (JSC::JSObject::inlineGetOwnPropertySlot): - (JSC::JSObject::putDirectInternal): - (JSC::JSObject::setStructureAndReallocateStorageIfNecessary): - (JSC::JSObject::putDirectWithoutTransition): - (JSC::offsetInButterfly): - (JSC::offsetRelativeToPatchedStorage): - (JSC::indexRelativeToBase): - (JSC::offsetRelativeToBase): - * runtime/JSPropertyNameIterator.cpp: - (JSC::JSPropertyNameIterator::create): - * runtime/JSSymbolTableObject.cpp: - (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames): - * runtime/JSSymbolTableObject.h: - (JSSymbolTableObject): - * runtime/JSTypeInfo.h: - (JSC): - (JSC::TypeInfo::interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero): - (JSC::TypeInfo::overridesGetPropertyNames): - * runtime/LiteralParser.cpp: - (JSC::::parse): - * runtime/ObjectConstructor.cpp: - * runtime/ObjectPrototype.cpp: - (JSC::ObjectPrototype::ObjectPrototype): - (JSC): - * runtime/ObjectPrototype.h: - (ObjectPrototype): - * runtime/PropertyOffset.h: - (JSC::offsetInOutOfLineStorage): - * runtime/PropertyStorage.h: Added. - (JSC): - * runtime/PutDirectIndexMode.h: Added. - (JSC): - * runtime/RegExpMatchesArray.cpp: - (JSC::RegExpMatchesArray::RegExpMatchesArray): - (JSC): - (JSC::RegExpMatchesArray::create): - (JSC::RegExpMatchesArray::finishCreation): - * runtime/RegExpMatchesArray.h: - (RegExpMatchesArray): - (JSC::RegExpMatchesArray::createStructure): - * runtime/RegExpObject.cpp: - (JSC::RegExpObject::getOwnNonIndexPropertyNames): - * runtime/RegExpObject.h: - (RegExpObject): - * runtime/Reject.h: Added. - (JSC): - (JSC::reject): - * runtime/SparseArrayValueMap.cpp: Added. - (JSC): - * runtime/SparseArrayValueMap.h: Added. - (JSC): - (SparseArrayEntry): - (JSC::SparseArrayEntry::SparseArrayEntry): - (SparseArrayValueMap): - (JSC::SparseArrayValueMap::sparseMode): - (JSC::SparseArrayValueMap::setSparseMode): - (JSC::SparseArrayValueMap::lengthIsReadOnly): - (JSC::SparseArrayValueMap::setLengthIsReadOnly): - (JSC::SparseArrayValueMap::find): - (JSC::SparseArrayValueMap::remove): - (JSC::SparseArrayValueMap::notFound): - (JSC::SparseArrayValueMap::isEmpty): - (JSC::SparseArrayValueMap::contains): - (JSC::SparseArrayValueMap::size): - (JSC::SparseArrayValueMap::begin): - (JSC::SparseArrayValueMap::end): - * runtime/SparseArrayValueMapInlineMethods.h: Added. - (JSC): - (JSC::SparseArrayValueMap::SparseArrayValueMap): - (JSC::SparseArrayValueMap::~SparseArrayValueMap): - (JSC::SparseArrayValueMap::finishCreation): - (JSC::SparseArrayValueMap::create): - (JSC::SparseArrayValueMap::destroy): - (JSC::SparseArrayValueMap::createStructure): - (JSC::SparseArrayValueMap::add): - (JSC::SparseArrayValueMap::putEntry): - (JSC::SparseArrayValueMap::putDirect): - (JSC::SparseArrayEntry::get): - (JSC::SparseArrayEntry::getNonSparseMode): - (JSC::SparseArrayValueMap::visitChildren): - * runtime/StorageBarrier.h: Removed. - * runtime/StringObject.cpp: - (JSC::StringObject::putByIndex): - (JSC): - (JSC::StringObject::deletePropertyByIndex): - * runtime/StringObject.h: - (StringObject): - * runtime/StringPrototype.cpp: + (JSObject): + (JSC::JSObject::ensureContiguous): + (JSC::JSObject::ensureIndexedStorage): + (JSC::JSObject::ensureContiguousLength): + (JSC::JSObject::indexingData): + (JSC::JSObject::relevantLength): + * runtime/JSValue.cpp: + (JSC::JSValue::description): + * runtime/Options.cpp: + (JSC::Options::initialize): * runtime/Structure.cpp: - (JSC::Structure::Structure): - (JSC::Structure::materializePropertyMap): - (JSC::Structure::nonPropertyTransition): + (JSC::Structure::needsSlowPutIndexing): (JSC): + (JSC::Structure::suggestedArrayStorageTransition): * runtime/Structure.h: (Structure): - (JSC::Structure::indexingType): - (JSC::Structure::indexingTypeIncludingHistory): - (JSC::Structure::indexingTypeOffset): - (JSC::Structure::create): * runtime/StructureTransitionTable.h: - (JSC): - (JSC::toAttributes): (JSC::newIndexingType): - (JSC::StructureTransitionTable::Hash::hash): - * tests/mozilla/js1_6/Array/regress-304828.js: - -2012-09-12 Mark Lam <mark.lam@apple.com> - Refactor Opcodes to distinguish between core and extension opcodes. - https://bugs.webkit.org/show_bug.cgi?id=96466. +2012-10-09 Michael Saboff <msaboff@apple.com> - Reviewed by Filip Pizlo. - - * bytecode/Opcode.h: - (JSC): Added FOR_EACH_CORE_OPCODE_ID() macro. - * llint/LowLevelInterpreter.h: - (JSC): Auto-generate llint opcode aliases using the - FOR_EACH_CORE_OPCODE_ID() macro. - -2012-09-11 Geoffrey Garen <ggaren@apple.com> - - Second step to fixing the Windows build: Add new symbols. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-09-11 Geoffrey Garen <ggaren@apple.com> - - First step to fixing the Windows build: Remove old symbols. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-09-11 Geoffrey Garen <ggaren@apple.com> - - Don't allocate a backing store just for a function's name - https://bugs.webkit.org/show_bug.cgi?id=96468 - - Reviewed by Oliver Hunt. + After r130344, OpaqueJSString::identifier() adds wrapped String to identifier table + https://bugs.webkit.org/show_bug.cgi?id=98693 + REGRESSION (r130344): Install failed in Install Environment + <rdar://problem/12450118> - Treat function.name like function.length etc., and use a custom getter. - This saves space in closures. - - * debugger/DebuggerCallFrame.cpp: - (JSC::DebuggerCallFrame::functionName): - * debugger/DebuggerCallFrame.h: - (DebuggerCallFrame): Updated for interface change. - - * runtime/Executable.h: - (JSC::JSFunction::JSFunction): Do a little inlining. - - * runtime/JSFunction.cpp: - (JSC::JSFunction::finishCreation): Gone now. That's the point of the patch. - - (JSC::JSFunction::name): - (JSC::JSFunction::displayName): - (JSC::JSFunction::nameGetter): - (JSC::JSFunction::getOwnPropertySlot): - (JSC::JSFunction::getOwnPropertyDescriptor): - (JSC::JSFunction::getOwnPropertyNames): - (JSC::JSFunction::put): - (JSC::JSFunction::deleteProperty): - (JSC::JSFunction::defineOwnProperty): Added custom accessors for .name - just like .length and others. - - * runtime/JSFunction.h: - (JSC::JSFunction::create): - (JSFunction): Updated for interface changes. - -2012-09-11 Mark Hahnenberg <mhahnenberg@apple.com> - - IncrementalSweeper should not sweep/free Zapped blocks - https://bugs.webkit.org/show_bug.cgi?id=96464 - - Reviewed by Filip Pizlo. + Reviewed by Mark Rowe. - This is not beneficial in terms of performance because there isn't any way a block can emerge - in the Zapped state from a call to Heap::collect() unless we run an eager sweep on it, in which - case we've already run all the destructors we possibly can. This also causes bugs since we don't - take zapped-ness into account when determining whether or not a block is empty to free it. The - incremental sweeper can then accidentally free blocks that it thinks are empty but are in fact - zapped with still-live objects in them. + Use Identifier(LChar*, length) or Identifier(UChar*, length) constructors so that we don't + add the String instance in the OpaqueJSString to any identifier tables. - * heap/MarkedBlock.h: - (JSC::MarkedBlock::needsSweeping): It is only valid to sweep a block if it is in the Marked state. + * API/OpaqueJSString.cpp: + (OpaqueJSString::identifier): -2012-09-11 Geoffrey Garen <ggaren@apple.com> +2012-10-08 Mark Lam <mark.lam@apple.com> - JSActivation should inline allocate its registers, and eliminate - 'arguments' registers in the common case - https://bugs.webkit.org/show_bug.cgi?id=96427 + Renamed RegisterFile to JSStack, and removed prototype of the + previously deleted Interpreter::privateExecute(). + https://bugs.webkit.org/show_bug.cgi?id=98717. Reviewed by Filip Pizlo. - This cuts the size class for simple closures down to 64 bytes. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::BytecodeGenerator): Set the usesNonStrictEval - flag, which is new. Use a more specific test for whether a function - uses 'arguments', so we can avoid allocating, initializing, and tearing - off those registers in the common case. Distinguish between capturing - arguments and not, so we can avoid allocating space for arguments in - the torn-off object. - - We can make this even more general in the future, with some bytecode - generator refactoring. - - (JSC::BytecodeGenerator::resolve): Updated for new interface. - - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - (JSC::BytecodeGenerator::symbolTable): Updated some types. - - * heap/Heap.cpp: - (JSC::Heap::isValidAllocation): Allow large allocations, now that they - are both supported and used. - - * heap/Heap.h: - (Heap): Added a new form of allocateCell that specifies the full size - of the allocation, to allow for extra space on the end. - - * interpreter/CallFrame.h: - (JSC::ExecState::argumentOffset): - (JSC::ExecState::argumentOffsetIncludingThis): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::unwindCallFrame): Refactored this code to be more - specific about tearing off 'arguments' vs activations. This is something - I forgot in my last patch, and it is required now that we can have - acitvations without 'arguments' registers. - - * runtime/Arguments.h: - (JSC::Arguments::setRegisters): No need for setRegisters anymore because - the activation object's storage doesn't change. - - * runtime/JSActivation.cpp: - (JSC::JSActivation::JSActivation): Initialize our storage manually because - it's not declared to the C++ compiler. - - (JSC::JSActivation::visitChildren): No copyAndAppend because our storage - is not out-of-line anymore. - - (JSC::JSActivation::symbolTableGet): - (JSC::JSActivation::symbolTablePut): - (JSC::JSActivation::getOwnPropertyNames): - (JSC::JSActivation::symbolTablePutWithAttributes): - (JSC::JSActivation::getOwnPropertySlot): - (JSC::JSActivation::getOwnPropertyDescriptor): - (JSC::JSActivation::argumentsGetter): Refactored isTornOff() testing to - avoid using a data member and to avoid hard-coding any offset assumptions. - - * runtime/JSActivation.h: - (JSC): - (JSActivation): - (JSC::JSActivation::create): - (JSC::JSActivation::isDynamicScope): - (JSC::JSActivation::captureStart): - (JSC::JSActivation::storageSize): - (JSC::JSActivation::storageSizeInBytes): - (JSC::JSActivation::registerOffset): - (JSC::JSActivation::tearOff): - (JSC::JSActivation::isTornOff): - (JSC::JSActivation::storage): - (JSC::JSActivation::allocationSize): - (JSC::JSActivation::isValid): New helper functions for doing the math - on our inline storage. Note that in the "AllOfTheThings" tear-off case, - the number of things is not known at compile time, so we store the - number in the argument count register. We can't just copy the raw contents - of the register beacuse we need a value that is safe for precise marking, - and the value in the register file has an invalid tag. - - * runtime/JSCell.h: - (JSC::allocateCell): New function for allocating with extra storage - on the end. - - * runtime/JSSymbolTableObject.h: - (JSC::JSSymbolTableObject::JSSymbolTableObject): - (JSC::JSSymbolTableObject::finishCreation): - * runtime/JSVariableObject.h: - (JSC::JSVariableObject::JSVariableObject): - (JSVariableObject): Make it easier for subclasses to use their symbol - tables during construction, by passing the table as a constructor argument. - - * runtime/SymbolTable.h: - (JSC::SharedSymbolTable::usesNonStrictEval): - (JSC::SharedSymbolTable::setUsesNonStrictEval): - (SharedSymbolTable): - (JSC::SharedSymbolTable::captureMode): - (JSC::SharedSymbolTable::setCaptureMode): - (JSC::SharedSymbolTable::captureStart): - (JSC::SharedSymbolTable::setCaptureStart): - (JSC::SharedSymbolTable::captureEnd): - (JSC::SharedSymbolTable::setCaptureEnd): - (JSC::SharedSymbolTable::parameterCountIncludingThis): - (JSC::SharedSymbolTable::setParameterCountIncludingThis): - (JSC::SharedSymbolTable::SharedSymbolTable): Added data members to more - precisely describe what kind of capture is in play, and to avoid having - data members in the activation. We expect N activations per symbol table, - so this can be a big savings in heavy closure usage. - -2012-09-11 Ryuan Choi <ryuan.choi@samsung.com> - - Fix build break with LLINT on 32bit machine after r128219 - https://bugs.webkit.org/show_bug.cgi?id=96461 - - Unreviewed build fix. - - * llint/LowLevelInterpreter32_64.asm: Fixed typo. - -2012-09-11 Michael Saboff <msaboff@apple.com> - - Build fixed for http://trac.webkit.org/changeset/128243 - - Rubber stamped by Stephanie Lewis. - - Added missing include file needed by 96422. - - * icu/unicode/unorm2.h: Added. - -2012-09-11 Michael Saboff <msaboff@apple.com> - - Build fixed for http://trac.webkit.org/changeset/128243 - - Rubber stamped by Stephanie Lewis. - - Added missing include file needed by 96422. - - * icu/unicode/ptypes.h: Added. - -2012-09-11 Michael Saboff <msaboff@apple.com> - - Update ICU header files to more recent version - https://bugs.webkit.org/show_bug.cgi?id=96422 - - Reviewed by Geoff Garen. - - Updated ICU header files to 4.6.1. Modifications made as part of the merge are: - platform.h - Changed ifndef / define / endif for U_HAVE_UINT8_T, U_HAVE_UINT16_T, U_HAVE_UINT32_T, - U_HAVE_UINT64_T, U_IS_BIG_ENDIAN and U_ENABLE_TRACING to match the existing platform.h - putil.h (line 132) - Changes defined(U_WINDOWS) to defined(WIN32) || defined(OS2) to match existing putil.h - ustring.h (line 945) - Wrapped macro argument cs with { (const UChar *)cs } to match existing ustring.h - utypes.h (line 545) - Changed defined(U_WINDOWS) to defined(WIN32) to match existing utypes.h - - * icu/unicode/localpointer.h: Added. - * 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/uscript.h: - * icu/unicode/uset.h: - * icu/unicode/ustring.h: - * icu/unicode/utf.h: - * icu/unicode/utf16.h: - * icu/unicode/utf8.h: - * icu/unicode/utypes.h: - * icu/unicode/uvernum.h: Added. - * icu/unicode/uversion.h: - -2012-09-11 Matt Lilek <mrl@apple.com> - - OS X port should compile with newer versions of clang - https://bugs.webkit.org/show_bug.cgi?id=96434 - - m_identIsVarDecl is unused - remove it. - - Reviewed by Anders Carlsson. - - * parser/NodeConstructors.h: - (JSC::ForInNode::ForInNode): - * parser/Nodes.h: - (ForInNode): - -2012-09-11 Filip Pizlo <fpizlo@apple.com> - - LLInt should optimize and profile array length accesses - https://bugs.webkit.org/show_bug.cgi?id=96417 - - Reviewed by Oliver Hunt. - - This fixes the following hole in our array profiling strategy, where the array - is large (more than 1000 elements): - - for (var i = 0; i < array.length; ++i) ... - - The peeled use of array.length (in the array prologue) will execute only once - before DFG optimization kicks in from the loop's OSR point. Since it executed - only once, it executed in the LLInt. And prior to this patch, the LLInt did - not profile array.length accesses - so the DFG will assume, based on the lack - of profiling, that the access is in fact not an access to the JSArray length - property. That could then impede our ability to hoist the array structure - check, and may make us pessimistic in other ways as well, since the generic - GetById used for the array length access will be viewed as a side-effecting - operation. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::printGetByIdCacheStatus): - (JSC::CodeBlock::finalizeUnconditionally): - * bytecode/GetByIdStatus.cpp: - (JSC::GetByIdStatus::computeFromLLInt): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCapabilities.h: - (JSC::DFG::canCompileOpcode): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - * jit/JIT.cpp: - (JSC::JIT::privateCompileMainPass): - (JSC::JIT::privateCompileSlowCases): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter.asm: - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-09-11 Raphael Kubo da Costa <rakuco@webkit.org> - - [EFL] Rewrite the EFL-related Find modules - https://bugs.webkit.org/show_bug.cgi?id=95237 - - Reviewed by Kenneth Rohde Christiansen. - - * CMakeLists.txt: Stop setting the LINK_FLAGS property. - * PlatformEfl.cmake: Ditto. - * shell/PlatformEfl.cmake: Ditto. - -2012-09-11 Raphael Kubo da Costa <rakuco@webkit.org> - - [EFL] Unreviewed build fix after r128065. - - * CMakeLists.txt: Link against WTF for FastMalloc symbols, which - are needed when building with SYSTEM_MALLOC off. - -2012-09-10 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove m_classInfo from JSCell - https://bugs.webkit.org/show_bug.cgi?id=96311 - - Reviewed by Oliver Hunt. - - Now that no one is using the ClassInfo in JSCell, we can remove it for the greater good. This is a 1.5% win on v8v7 and - a 1.7% win on kraken, and is an overall performance progression. - - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): Had to rearrange the order of when we take things off the free list - and when we store the Structure in the object because we would clobber the free list otherwise. This made it not okay for - the structure argument and the scratch register to alias one another. Also removed the store of the ClassInfo pointer in the - object. Yay! - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: Since it's no longer okay for for the scratch register and structure register to alias - one another as stated above, had to add an extra temporary for passing the Structure. - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: Ditto. - (JSC::DFG::SpeculativeJIT::compile): - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): Similar changes to DFG's inline allocation except that it removed the object from - the free list first, so no changes were necessary there. - * llint/LowLevelInterpreter.asm: Change the constants for amount of inline storage to match PropertyOffset.h and remove - the store of the ClassInfo pointer during inline allocation. - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/JSCell.h: Remove the m_classInfo field and associated methods. - (JSCell): - * runtime/JSObject.h: - (JSObject): - * runtime/PropertyOffset.h: Expand the number of inline storage properties to take up the extra space that we're freeing - with the removal of the ClassInfo pointer. - (JSC): - * runtime/Structure.h: - (JSC): - (JSC::JSCell::JSCell): - (JSC::JSCell::finishCreation): - -2012-09-10 Geoffrey Garen <ggaren@apple.com> - - Added large allocation support to MarkedSpace - https://bugs.webkit.org/show_bug.cgi?id=96214 - - Originally reviewed by Oliver Hunt, then I added a design revision by - suggested by Phil Pizlo. - - I expanded the imprecise size classes to cover up to 32KB, then added - an mmap-based allocator for everything bigger. There's a lot of tuning - we could do in these size classes, but currently they're almost - completely unused, so I haven't done any tuning. - - Subtle point: the large allocator is a degenerate case of our free list - logic. Its list only ever contains zero or one items. - - * heap/Heap.h: - (JSC::Heap::allocateStructure): Pipe in size information. - - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::tryAllocateHelper): Handle the case where we - find a free item in the sweep list but the item isn't big enough. This - can happen in the large allocator because it mixes sizes. - - (JSC::MarkedAllocator::tryAllocate): - (JSC::MarkedAllocator::allocateSlowCase): More piping. - - (JSC::MarkedAllocator::allocateBlock): Handle the oversize case. - - (JSC::MarkedAllocator::addBlock): I moved the call to didAddBlock here - because it made more sense. - - * heap/MarkedAllocator.h: - (MarkedAllocator): - (JSC::MarkedAllocator::allocate): - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::MarkedSpace): - (JSC::MarkedSpace::resetAllocators): - (JSC::MarkedSpace::canonicalizeCellLivenessData): - (JSC::MarkedSpace::isPagedOut): - (JSC::MarkedSpace::freeBlock): - * heap/MarkedSpace.h: - (MarkedSpace): - (JSC::MarkedSpace::allocatorFor): - (JSC::MarkedSpace::destructorAllocatorFor): - (JSC::MarkedSpace::allocateWithoutDestructor): - (JSC::MarkedSpace::allocateWithDestructor): - (JSC::MarkedSpace::allocateStructure): - (JSC::MarkedSpace::forEachBlock): - * runtime/Structure.h: - (JSC::Structure): More piping. - -2012-09-10 Geoffrey Garen <ggaren@apple.com> - - Try to fix the Windows (32-bit) build. - - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_tear_off_arguments): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_tear_off_arguments): Get operands 1 and 2, not 1 and 1. :( - - Also took this opportunity to rename to indicate that these values are - not destinations anymore. - -2012-09-10 Geoffrey Garen <ggaren@apple.com> - - DFG misses arguments tear-off for function.arguments if 'arguments' is used - https://bugs.webkit.org/show_bug.cgi?id=96227 - - Reviewed by Gavin Barraclough. - - We've decided not to allow function.arguments to alias the local - 'arguments' object, or a local var or function named 'arguments'. - Aliasing complicates the implementation (cf, this bug) and can produce - surprising behavior for web programmers. - - Eliminating the aliasing has the side-effect of fixing this bug. - - The compatibilty story: function.arguments is deprecated, was never - specified, and throws an exception in strict mode, so we expect it to - disappear over time. Firefox does not alias to 'arguments'; Chrome - does, but not if you use eval or with; IE does; Safari did. - - * dfg/DFGByteCodeParser.cpp: Noticed a little cleanup while verifying - this code. Use the CodeBlock method for better encapsulation. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::retrieveArgumentsFromVMCode): Behavior change: don't - alias. - - * tests/mozilla/js1_4/Functions/function-001.js: - (TestFunction_4): Updated test expectations for changed behavior. - -2012-09-10 Filip Pizlo <fpizlo@apple.com> - - offlineasm has some impossible to implement, and unused, instructions - https://bugs.webkit.org/show_bug.cgi?id=96310 - - Reviewed by Mark Hahnenberg. - - * offlineasm/armv7.rb: - * offlineasm/instructions.rb: - * offlineasm/x86.rb: - -2012-09-09 Geoffrey Garen <ggaren@apple.com> - - Refactored op_tear_off* to support activations that don't allocate space for 'arguments' - https://bugs.webkit.org/show_bug.cgi?id=96231 - - Reviewed by Gavin Barraclough. - - This is a step toward smaller activations. - - As a side-effect, this patch eliminates a load and branch from the hot path - of activation tear-off by moving it to the cold path of arguments tear-off. Our - optimizing assumptions are that activations are common and that reifying the - arguments object is less common. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - * bytecode/Opcode.h: - (JSC::padOpcodeName): Updated for new opcode lengths. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::BytecodeGenerator): - (JSC::BytecodeGenerator::addConstantValue): Added support for JSValue() - in the bytecode, which we use when we have 'arguments' but no activation. - - (JSC::BytecodeGenerator::emitReturn): Always emit tear_off_arguments - if we've allocated the arguments registers. This allows tear_off_activation - not to worry about the arguments object anymore. - - Also, pass the activation and arguments values directly to these opcodes - instead of requiring the opcodes to infer the values through special - registers. This gives us more flexibility to move or eliminate registers. - - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGNode.h: - (Node): Updated for new opcode lengths. - - * dfg/DFGOperations.cpp: Activation tear-off doesn't worry about the - arguments object anymore. If 'arguments' is in use and reified, it's - responsible for aliasing back to the activation object in tear_off_arguments. - - * dfg/DFGOperations.h: - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): Don't pass the arguments object to - activation tear-off; do pass the activation object to arguments tear-off. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): Ditto. - - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_tear_off_activation): - (JSC::JIT::emit_op_tear_off_arguments): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_tear_off_activation): - (JSC::JIT::emit_op_tear_off_arguments): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: Same change in a few more execution engines. - -2012-09-10 Patrick Gansterer <paroga@webkit.org> - - [JSC] Use StringBuilder::appendNumber() instead of String::number() - https://bugs.webkit.org/show_bug.cgi?id=96236 - - Reviewed by Benjamin Poulain. - - * API/JSContextRef.cpp: - (JSContextCreateBacktrace): - -2012-09-06 Mark Hahnenberg <mhahnenberg@apple.com> - - Combine MarkStack and SlotVisitor into single class - https://bugs.webkit.org/show_bug.cgi?id=96043 - - Reviewed by Geoff Garen. - - Move all of MarkStack into SlotVisitor. The remaining stuff in MarkStack.cpp actually has to do - with MarkStack management/allocation. Cleaned up a few of the header files while I was at it. - * CMakeLists.txt: * GNUmakefile.list.am: + * JavaScriptCore.order: * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: * Target.pri: + * bytecode/BytecodeConventions.h: * bytecode/CodeBlock.cpp: - * dfg/DFGCommon.h: - * heap/GCThreadSharedData.cpp: - * heap/GCThreadSharedData.h: - (GCThreadSharedData): - * heap/HeapRootVisitor.h: - * heap/MarkStack.cpp: - (JSC): - * heap/MarkStack.h: - (JSC): - (MarkStackSegment): - (JSC::MarkStackSegment::data): - (JSC::MarkStackSegment::capacityFromSize): - (JSC::MarkStackSegment::sizeFromCapacity): - (MarkStackSegmentAllocator): - (MarkStackArray): - * heap/MarkStackInlineMethods.h: - (JSC::MarkStackArray::postIncTop): - (JSC): - (JSC::MarkStackArray::preDecTop): - (JSC::MarkStackArray::setTopForFullSegment): - (JSC::MarkStackArray::setTopForEmptySegment): - (JSC::MarkStackArray::top): - (JSC::MarkStackArray::validatePrevious): - (JSC::MarkStackArray::append): - (JSC::MarkStackArray::canRemoveLast): - (JSC::MarkStackArray::removeLast): - (JSC::MarkStackArray::isEmpty): - (JSC::MarkStackArray::size): - * heap/SlotVisitor.cpp: Added. - (JSC): - (JSC::SlotVisitor::SlotVisitor): - (JSC::SlotVisitor::~SlotVisitor): - (JSC::SlotVisitor::setup): - (JSC::SlotVisitor::reset): - (JSC::SlotVisitor::append): - (JSC::visitChildren): - (JSC::SlotVisitor::donateKnownParallel): - (JSC::SlotVisitor::drain): - (JSC::SlotVisitor::drainFromShared): - (JSC::SlotVisitor::mergeOpaqueRoots): - (JSC::SlotVisitor::startCopying): - (JSC::SlotVisitor::allocateNewSpaceSlow): - (JSC::SlotVisitor::allocateNewSpaceOrPin): - (JSC::JSString::tryHashConstLock): - (JSC::JSString::releaseHashConstLock): - (JSC::JSString::shouldTryHashConst): - (JSC::SlotVisitor::internalAppend): - (JSC::SlotVisitor::copyAndAppend): - (JSC::SlotVisitor::doneCopying): - (JSC::SlotVisitor::harvestWeakReferences): - (JSC::SlotVisitor::finalizeUnconditionalFinalizers): - (JSC::SlotVisitor::validate): - * heap/SlotVisitor.h: - (JSC): - (SlotVisitor): - (JSC::SlotVisitor::sharedData): - (JSC::SlotVisitor::isEmpty): - (JSC::SlotVisitor::visitCount): - (JSC::SlotVisitor::resetChildCount): - (JSC::SlotVisitor::childCount): - (JSC::SlotVisitor::incrementChildCount): - (ParallelModeEnabler): - (JSC::ParallelModeEnabler::ParallelModeEnabler): - (JSC::ParallelModeEnabler::~ParallelModeEnabler): - * heap/SlotVisitorInlineMethods.h: - (JSC::SlotVisitor::append): - (JSC): - (JSC::SlotVisitor::appendUnbarrieredPointer): - (JSC::SlotVisitor::appendUnbarrieredValue): - (JSC::SlotVisitor::internalAppend): - (JSC::SlotVisitor::addWeakReferenceHarvester): - (JSC::SlotVisitor::addUnconditionalFinalizer): - (JSC::SlotVisitor::addOpaqueRoot): - (JSC::SlotVisitor::containsOpaqueRoot): - (JSC::SlotVisitor::opaqueRootCount): - (JSC::SlotVisitor::mergeOpaqueRootsIfNecessary): - (JSC::SlotVisitor::mergeOpaqueRootsIfProfitable): - (JSC::SlotVisitor::donate): - (JSC::SlotVisitor::donateAndDrain): - * jit/JITWriteBarrier.h: - (JSC::SlotVisitor::append): - * jit/JumpReplacementWatchpoint.cpp: - * runtime/JSCell.h: - * runtime/Structure.h: - (JSC::SlotVisitor::internalAppend): - * runtime/WriteBarrier.h: - (JSC): - (JSC::SlotVisitor::append): - (JSC::SlotVisitor::appendValues): - * yarr/YarrJIT.cpp: - -2012-09-10 Hojong Han <hojong.han@samsung.com> - - [EFL] JIT memory usage is not retrieved - https://bugs.webkit.org/show_bug.cgi?id=96095 - - Reviewed by Geoffrey Garen. - - Fill JITBytes for EFL port. - - * runtime/MemoryStatistics.cpp: - (JSC::globalMemoryStatistics): - -2012-09-10 Thiago Marcos P. Santos <thiago.santos@intel.com> - - [CMake][EFL] Enable the LLInt - https://bugs.webkit.org/show_bug.cgi?id=92682 - - Reviewed by Csaba Osztrogonác. - - Generate the headers needed by LLint when LLint is enabled. - - * CMakeLists.txt: - -2012-09-10 Carlos Garcia Campos <cgarcia@igalia.com> - - Unreviewed. Fix make distcheck. - - * GNUmakefile.list.am: Add missing files. - -2012-09-09 Mark Lam <mark.lam@apple.com> - - Fixed a few llint C++ interpreter bugs. - https://bugs.webkit.org/show_bug.cgi?id=96127. - - Reviewed by Geoffrey Garen. - - * llint/LLIntCLoop.h: - CLoop::execute()'s bootstrapOpcodeId does not need a default - value. There is no case when this function is called without - that parameter being specified. - * llint/LowLevelInterpreter.asm: - Moved the dispatchAfterCall() call to where it is needed. - For the C_LOOP back-end, it generates unreachable code. - * llint/LowLevelInterpreter.cpp: - #include <wtf/Assertions.h> because LLIntAssembly.h needs it. - (JSC): - Fixed bug in SIGN_BIT32() macro. - Placate a MSVC warning for t0, and t1 being uninitialized. - (JSC::CLoop::execute): - The bootstrapOpcodeId arg should always be specified. - MSVC doesn't like UNUSED_PARAM() for labels. Switch to using - the new UNUSED_LABEL() macro. - * offlineasm/cloop.rb: - * offlineasm/generate_offset_extractor.rb: - Resolved a compiler warning found via MSVC. - -2012-09-09 Patrick Gansterer <paroga@webkit.org> - - Add StringBuilder::appendNumber() and use it - https://bugs.webkit.org/show_bug.cgi?id=96030 - - Reviewed by Eric Seidel. - - Also fix a bunch of append() vs. appendLiteral() issues in the surrounding code. - - * API/JSContextRef.cpp: - (JSContextCreateBacktrace): - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * interpreter/Interpreter.h: - (JSC::StackFrame::toString): - -2012-09-09 Patrick Gansterer <paroga@webkit.org> - - Make the String initialization on the function side of String::number() - https://bugs.webkit.org/show_bug.cgi?id=95940 - - Reviewed by Benjamin Poulain. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-09-09 Geoffrey Garen <ggaren@apple.com> - - Rolled out <http://trac.webkit.org/changeset/127939> because it broke - fast/js/named-function-expression.html. - - Refactored bytecode generator initialization to support moving captured vars around - https://bugs.webkit.org/show_bug.cgi?id=96159 - - Reviewed by Gavin Barraclough. - -2012-09-08 Csaba Osztrogonác <ossy@webkit.org> - - LLInt buildfix for case sensitive filesystems - https://bugs.webkit.org/show_bug.cgi?id=96099 - - Reviewed by Michael Saboff. - - * llint/LowLevelInterpreter.cpp: Fix filenames. - -2012-09-07 Benjamin Poulain <bpoulain@apple.com> - - Rename the ustring() accessor to string() - https://bugs.webkit.org/show_bug.cgi?id=95919 - - Reviewed by Geoffrey Garen. - - Rename ustring() to string() to make the accessor name more logical after - r127191. - - * API/JSBase.cpp: - (JSEvaluateScript): - (JSCheckScriptSyntax): - * API/JSObjectRef.cpp: - (JSObjectMakeFunctionWithCallback): - (JSObjectMakeFunction): - (JSObjectCopyPropertyNames): - * API/JSProfilerPrivate.cpp: - (JSStartProfiling): - (JSEndProfiling): - * API/JSValueRef.cpp: - (JSValueMakeString): - (JSValueMakeFromJSONString): - * API/OpaqueJSString.cpp: - (OpaqueJSString::string): - * API/OpaqueJSString.h: - (OpaqueJSString): - * bytecode/CodeBlock.cpp: - (JSC::idName): - (JSC::CodeBlock::dump): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitLoad): - (JSC::BytecodeGenerator::addStringConstant): - * bytecompiler/NodesCodegen.cpp: - (JSC::RegExpNode::emitBytecode): - (JSC::processClauseList): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dump): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * jsc.cpp: - (GlobalObject::addFunction): - (GlobalObject::addConstructableFunction): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * parser/ASTBuilder.h: - (JSC::ASTBuilder::createRegExp): - * parser/Parser.cpp: - (JSC::::parsePrimaryExpression): - * parser/Parser.h: - (JSC::Scope::declareVariable): - (JSC::Scope::declareParameter): - (JSC::Scope::useVariable): - * parser/SyntaxChecker.h: - (JSC::SyntaxChecker::createRegExp): - * runtime/ExceptionHelpers.cpp: - (JSC::createUndefinedVariableError): - * runtime/Executable.cpp: - (JSC::FunctionExecutable::paramString): - * runtime/Executable.h: - (JSC::FunctionExecutable::finishCreation): - * runtime/FunctionPrototype.cpp: - (JSC::FunctionPrototype::addFunctionProperties): - * runtime/Identifier.h: - (JSC::Identifier::string): - * runtime/JSFunction.cpp: - (JSC::JSFunction::calculatedDisplayName): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::reset): - * runtime/JSONObject.cpp: - (JSC::PropertyNameForFunctionCall::value): - (JSC::Stringifier::Holder::appendNextProperty): - (JSC::Walker::walk): - * runtime/JSPropertyNameIterator.h: - (JSC::JSPropertyNameIterator::finishCreation): - * runtime/JSScope.cpp: - (JSC::JSScope::resolveBase): - * runtime/JSString.h: - (JSC::inlineJSValueNotStringtoString): - * runtime/LiteralParser.cpp: - (JSC::::parse): - * runtime/ObjectConstructor.cpp: - (JSC::ObjectConstructor::finishCreation): - (JSC::objectConstructorGetOwnPropertyNames): - (JSC::objectConstructorKeys): - * runtime/RegExpConstructor.cpp: - (JSC::RegExpConstructor::finishCreation): - -2012-09-07 Gavin Barraclough <barraclough@apple.com> - - CALLFRAME_OFFSET and EXCEPTION_OFFSET are same in ctiTrampoline on ARM Thumb2 - https://bugs.webkit.org/show_bug.cgi?id=82013 - - Reviewed by Geoff Garen. - - Neither of these values need to be stored. At all. - - * jit/JITStubs.cpp: - (JSC): - (JSC::ctiTrampoline): - (JSC::JITThunks::JITThunks): - - Nothing to see here. Move along. - -2012-09-07 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r127938. - http://trac.webkit.org/changeset/127938 - https://bugs.webkit.org/show_bug.cgi?id=96166 - - It broke the build (Requested by smfr on #webkit). - - * llint/LowLevelInterpreter.cpp: - (JSC): - (JSC::CLoop::execute): - * offlineasm/cloop.rb: - -2012-09-07 Geoffrey Garen <ggaren@apple.com> - - Refactored bytecode generator initialization to support moving captured vars around - https://bugs.webkit.org/show_bug.cgi?id=96159 - - Reviewed by Gavin Barraclough. - - This patch separates the stages of allocating registers, declaring identifiers - in the symbol table, and initializing registers, so you can change - allocation decisions without breaking the world. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::BytecodeGenerator): Call a set of helper functions - instead of inlining all the code, to help clarity. - - (JSC::BytecodeGenerator::allocateCapturedVars): - (JSC::BytecodeGenerator::allocateUncapturedVars): - (JSC::BytecodeGenerator::allocateActivationVar): - (JSC::BytecodeGenerator::allocateArgumentsVars): - (JSC::BytecodeGenerator::allocateCalleeVarUndeclared): - (JSC::BytecodeGenerator::declareParameters): - (JSC::BytecodeGenerator::declareCallee): - (JSC::BytecodeGenerator::initCalleeVar): - (JSC::BytecodeGenerator::initArgumentsVars): - (JSC::BytecodeGenerator::initActivationVar): - (JSC::BytecodeGenerator::initThisParameter): - (JSC::BytecodeGenerator::initFunctionDeclarations): - (JSC::BytecodeGenerator::declareParameter): - (JSC::BytecodeGenerator::createLazyRegisterIfNecessary): - (JSC::BytecodeGenerator::createActivationIfNecessary): Factored these - helper functions out from pre-existing code. - - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - * parser/ASTBuilder.h: - (JSC::ASTBuilder::createFuncDeclStatement): - (JSC::ASTBuilder::addVar): - * parser/Nodes.h: - (JSC::DeclarationStacks::VarDeclaration::VarDeclaration): - (VarDeclaration): - (JSC::DeclarationStacks::FunctionDeclaration::FunctionDeclaration): - (FunctionDeclaration): Declaration stacks get a little more data now, - to support allocating registers before putting things in the symbol - table. I'm convinced that we should eventually just expand the symbol - table to understand these things. - -2012-09-07 Mark Lam <mark.lam@apple.com> - - Fix a llint C++ interpreter bugs. - https://bugs.webkit.org/show_bug.cgi?id=96127. - - Reviewed by Filip Pizlo. - - * llint/LowLevelInterpreter.cpp: - (JSC): - (JSC::CLoop::execute): - * offlineasm/cloop.rb: - -2012-09-07 Gavin Barraclough <barraclough@apple.com> - - Object.prototype.__define{G,S}etter__ with non-callable second parameter should throw TypeError instead of SyntaxError - https://bugs.webkit.org/show_bug.cgi?id=93873 - - Reviewed by Sam Weinig. - - * runtime/ObjectPrototype.cpp: - (JSC::objectProtoFuncDefineGetter): - - throw TypeError instead of SyntaxError - (JSC::objectProtoFuncDefineSetter): - - throw TypeError instead of SyntaxError - -2012-09-06 Mark Hahnenberg <mhahnenberg@apple.com> - - JSC should have a zombie mode - https://bugs.webkit.org/show_bug.cgi?id=96047 - - Reviewed by Geoffrey Garen. - - To aid clients of JSC while they are debugging memory issues, we should add a zombie - mode that scribbles into objects in the MarkedSpace after they are found to be dead - to prevent a sort of "use after free" situation. As a first cut we should support a - mode that just scribbles on objects prior to their being reused (i.e. while they are - "zombies") and a mode in which, in addition to scribbling on zombies, once an object - has been marked its mark bit will never be cleared, thus giving us "immortal" zombies. - - These two modes will be enabled through the use of environment variables. For now these - will be "JSZombieEnabled" and "JSImmortalZombieEnabled". Setting them to any value will - result in the use of the appropriate mode. - - * heap/Heap.cpp: - (JSC::Heap::collect): Zombifies dead objects at the end of collection if zombie mode is enabled. - (ZombifyCellFunctor): - (JSC::ZombifyCellFunctor::ZombifyCellFunctor): Sets marked bits for dead objects if in immortal mode and writes 0xbbadbeef into them. - (JSC::ZombifyCellFunctor::operator()): - (JSC): - (ZombifyBlockFunctor): - (JSC::ZombifyBlockFunctor::operator()): - (JSC::Heap::zombifyDeadObjects): Eagerly sweeps so that we don't write garbage into an object before it - is finalized/destroyed. - * heap/Heap.h: - (Heap): - * heap/MarkedBlock.h: - (MarkedBlock): - (JSC::MarkedBlock::forEachDeadCell): Used to iterate over dead cells at the end of collection if zombie mode is enabled. - (JSC): - * runtime/Options.cpp: - (JSC::Options::initialize): - * runtime/Options.h: - (JSC): - -2012-09-05 Geoffrey Garen <ggaren@apple.com> - - Rolled back in <http://trac.webkit.org/changeset/127698> with a fix for - fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html, which - is to make sure that function declarations don't put their names in scope. - - Reviewed by Gavin Barraclough. - - Named functions should not allocate scope objects for their names - https://bugs.webkit.org/show_bug.cgi?id=95659 - - Reviewed by Oliver Hunt. - -2012-09-06 Michael Saboff <msaboff@apple.com> - - 16 bit JSRopeString up converts an 8 bit fibers to 16 bits during resolution - https://bugs.webkit.org/show_bug.cgi?id=95810 - - Reviewed by Benjamin Poulain. - - Added 8 bit path that copies the contents of an 8 bit fiber to the 16 bit buffer - when resolving a 16 bit rope. - - * runtime/JSString.cpp: - (JSC::JSRopeString::resolveRopeSlowCase): - -2012-09-06 Gavin Barraclough <barraclough@apple.com> - - JS test suite puts incorrect limitations on Function.toString() - https://bugs.webkit.org/show_bug.cgi?id=3975 - - Reviewed by Geoff Garen. - - The result of function toString is implementation defined; - these test cases were looking for specific whitespace formatting - that matches mozilla's, and for redundant braces to be inserted - around if/else blocks. Stop that. - - * tests/mozilla/expected.html: - * tests/mozilla/js1_2/function/tostring-1.js: - (simplify): - - reduce whitespace differences - * tests/mozilla/js1_2/function/tostring-2.js: - (simplify): - - reduce whitespace differences - (TestOr): - (TestAnd): - - added braces to match expected output - -2012-09-06 Yuqiang Xian <yuqiang.xian@intel.com> - - Performance regressions on 32-bit platforms with revisions 125637 and 126387 - https://bugs.webkit.org/show_bug.cgi?id=95953 - - Reviewed by Filip Pizlo. - - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::emit_op_get_by_val): Fix the typo. - -2012-09-05 Geoffrey Garen <ggaren@apple.com> - - Rolled out <http://trac.webkit.org/changeset/127698> because it broke - fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html - - Named functions should not allocate scope objects for their names - https://bugs.webkit.org/show_bug.cgi?id=95659 - - Reviewed by Oliver Hunt. - -2012-09-06 Mark Lam <mark.lam@apple.com> - - Renamed useYarrJIT() option to useRegExpJIT(). Also fixed regression in - which inadvertantly allows the ASM llint to use the baseline JIT when - useRegExpJIT() is true. - https://bugs.webkit.org/show_bug.cgi?id=95918. - - Reviewed by Geoffrey Garen. - - * runtime/JSGlobalData.cpp: - (JSC::enableAssembler): - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: - (JSC::JSGlobalData::canUseJIT): - (JSC::JSGlobalData::canUseRegExpJIT): - (JSGlobalData): - * runtime/Options.cpp: - (JSC::Options::initialize): - * runtime/Options.h: - (JSC): - -2012-09-06 Patrick Gansterer <paroga@webkit.org> - - Build fix for Interpreter after r127698. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - -2012-09-05 Geoffrey Garen <ggaren@apple.com> - - Named functions should not allocate scope objects for their names - https://bugs.webkit.org/show_bug.cgi?id=95659 - - Reviewed by Oliver Hunt. - - In most cases, we can merge a function expression's name into its symbol - table. This reduces memory footprint per closure from three objects - (function + activation + name scope) to two (function + activation), - speeds up closure allocation, and speeds up recursive calls. - - In the case of a named function expression that contains a non-strict - eval, the rules are so bat-poop crazy that I don't know how to model - them without an extra object. Since functions now default to not having - such an object, this case needs to allocate the object on function - entry. - - Therefore, this patch makes the slow case a bit slower so the fast case - can be faster and more memory-efficient. (Note that the slow case already - allocates an activation on entry, and until recently also allocated a - scope chain node on entry, so adding one allocation on entry shouldn't - break the bank.) - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::CodeBlock): Caught a missed initializer. No behavior change. - + (JSC::CodeBlock::nameForRegister): + * bytecode/CodeBlock.h: + (CodeBlock): + * bytecode/ValueRecovery.h: + (JSC::ValueRecovery::alreadyInJSStack): + (JSC::ValueRecovery::alreadyInJSStackAsUnboxedInt32): + (JSC::ValueRecovery::alreadyInJSStackAsUnboxedCell): + (JSC::ValueRecovery::alreadyInJSStackAsUnboxedBoolean): + (JSC::ValueRecovery::alreadyInJSStackAsUnboxedDouble): + (JSC::ValueRecovery::displacedInJSStack): + (JSC::ValueRecovery::isAlreadyInJSStack): + (JSC::ValueRecovery::virtualRegister): + (JSC::ValueRecovery::dump): * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::BytecodeGenerator): Put the callee in static scope - during compilation so it doesn't need to be in dynamic scope at runtime. - (JSC::BytecodeGenerator::resolveCallee): - (JSC::BytecodeGenerator::addCallee): Helper functions for either statically - resolving the callee or adding a dynamic scope that will resolve to it, - depending on whether you're in the fast path. - - We move the callee into a var location if it's captured because activations - prefer to have contiguous ranges of captured variables. - + (JSC::BytecodeGenerator::emitCall): + (JSC::BytecodeGenerator::emitConstruct): * bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::registerFor): - (BytecodeGenerator): - - * dfg/DFGOperations.cpp: - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): This is the point of the patch: remove - one allocation in the case of a named function expression. - - * parser/Parser.cpp: - (JSC::::Parser): - * parser/Parser.h: - (JSC::Scope::declareCallee): - (Scope): - (Parser): - (JSC::parse): - * runtime/Executable.cpp: - (JSC::EvalExecutable::compileInternal): - (JSC::ProgramExecutable::checkSyntax): - (JSC::ProgramExecutable::compileInternal): - (JSC::FunctionExecutable::produceCodeBlockFor): - (JSC::FunctionExecutable::fromGlobalCode): Pipe the callee's name through - the parser so we get accurate information on whether the callee was captured. - - (JSC::FunctionExecutable::FunctionExecutable): - (JSC::EvalExecutable::compileInternal): - (JSC::ProgramExecutable::checkSyntax): - (JSC::ProgramExecutable::compileInternal): - (JSC::FunctionExecutable::produceCodeBlockFor): - (JSC::FunctionExecutable::fromGlobalCode): - * runtime/Executable.h: - (JSC::FunctionExecutable::create): - (FunctionExecutable): - (JSC::FunctionExecutable::finishCreation): I had to refactor function - creation to support the following function constructor quirk: the function - gets a name, but its name is not in lexical scope. - - To simplify this, FunctionExecutable now automatically extracts all the - data it needs from the parsed node. The special "fromGlobalCode" path - used by the function constructor creates an anonymous function, and then - quirkily sets the value used by the .name property to be non-null, even - though the parsed name is null. - - * runtime/JSNameScope.h: - (JSC::JSNameScope::create): - (JSC::JSNameScope::JSNameScope): Added support for explicitly specifying - your container scope. The compiler uses this for named function expressions. - -2012-09-05 Gavin Barraclough <barraclough@apple.com> - - a = data[a]++; sets the wrong key in data - https://bugs.webkit.org/show_bug.cgi?id=91270 - - Reviewed by Oliver Hunt. - - Postfix inc/dec is unsafely using finalDestination, can trample base/subscript prior to the result being put. - - * bytecompiler/NodesCodegen.cpp: - (JSC::PostfixNode::emitResolve): - - Remove redundant parens. - (JSC::PostfixNode::emitBracket): - (JSC::PostfixNode::emitDot): - - Refactored to use tempDestination instead of finalDestination. - (JSC::PrefixNode::emitBracket): - (JSC::PrefixNode::emitDot): - - Should be using emitPreIncOrDec. - -2012-09-05 Gavin Barraclough <barraclough@apple.com> - - Bug, assignment within subscript of prefix/postfix increment of bracket access - https://bugs.webkit.org/show_bug.cgi?id=95913 - - Reviewed by Oliver Hunt. - - javascript:alert((function(){ var a = { x:1 }; var b = { x:1 }; a[a=b,"x"]++; return a.x; })()) - - * bytecompiler/NodesCodegen.cpp: - (JSC::PostfixNode::emitBracket): - (JSC::PrefixNode::emitBracket): - - Should check for assigments in the subscript when loading the base. - * parser/Nodes.h: - (JSC::BracketAccessorNode::subscriptHasAssignments): - (BracketAccessorNode): - - Used by emitBracket methods. - -2012-09-05 Gavin Barraclough <barraclough@apple.com> - - Merge prefix/postfix nodes - https://bugs.webkit.org/show_bug.cgi?id=95898 - - Reviewed by Geoff Garen. - - Simplify the AST. - This will also mean we have access to m_subscriptHasAssignments when generating a prefix/postfix op applied to a bracket access. - - * bytecompiler/NodesCodegen.cpp: - (JSC::PostfixNode::emitResolve): - - was PostfixResolveNode::emitBytecode - (JSC::PostfixNode::emitBracket): - - was PostfixBracketNode::emitBytecode - (JSC::PostfixNode::emitDot): - - was PostfixDotNode::emitBytecode - (JSC::PostfixNode::emitBytecode): - - was PostfixErrorNode::emitBytecode, call resolve/bracket/dot version as appropriate. - (JSC::PrefixNode::emitResolve): - - was PrefixResolveNode::emitBytecode - (JSC::PrefixNode::emitBracket): - - was PrefixBracketNode::emitBytecode - (JSC::PrefixNode::emitDot): - - was PrefixDotNode::emitBytecode - (JSC::PrefixNode::emitBytecode): - - was PrefixErrorNode::emitBytecode, call resolve/bracket/dot version as appropriate. - * parser/ASTBuilder.h: - (JSC::ASTBuilder::makePrefixNode): - - Just makes a PrefixNode! - (JSC::ASTBuilder::makePostfixNode): - - Just makes a PostfixNode! - * parser/NodeConstructors.h: - (JSC::PostfixNode::PostfixNode): - - Added, merge of PostfixResolveNode/PostfixBracketNode/PostfixDotNode/PostfixErrorNode. - (JSC::PrefixNode::PrefixNode): - - Added, merge of PrefixResolveNode/PrefixBracketNode/PrefixDotNode/PrefixErrorNode. - * parser/Nodes.h: - (PostfixNode): - - Added, merge of PostfixResolveNode/PostfixBracketNode/PostfixDotNode/PostfixErrorNode. - (PrefixNode): - - Added, merge of PrefixResolveNode/PrefixBracketNode/PrefixDotNode/PrefixErrorNode. - -2012-09-05 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove use of JSCell::classInfoOffset() from tryCacheGetByID - https://bugs.webkit.org/show_bug.cgi?id=95860 - - Reviewed by Oliver Hunt. - - We should just do the indirection through the Structure instead. - - * dfg/DFGRepatch.cpp: - (JSC::DFG::tryCacheGetByID): - -2012-09-05 Geoffrey Garen <ggaren@apple.com> - - Throw exceptions when assigning to const in strict mode - https://bugs.webkit.org/show_bug.cgi?id=95894 - - Reviewed by Oliver Hunt. - - Currently, this never happens; but it will start happening once the - callee is a local const register. In this patch, there's no change in - behavior. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitReadOnlyExceptionIfNeeded): Helper function - for doing the throwing. - * bytecompiler/BytecodeGenerator.h: - - * bytecompiler/NodesCodegen.cpp: - (JSC::PostfixResolveNode::emitBytecode): - (JSC::PrefixResolveNode::emitBytecode): - (JSC::ReadModifyResolveNode::emitBytecode): - (JSC::AssignResolveNode::emitBytecode): Call the helper function. - -2012-09-05 Geoffrey Garen <ggaren@apple.com> - - Refactored callee access in the DFG to support it in the general case - https://bugs.webkit.org/show_bug.cgi?id=95887 - - Reviewed by Phil Pizlo and Gavin Barraclough. - - To support named function expressions, the DFG needs to understand the - callee register being used in arbitrary expressions, and not just - create_this. - + * dfg/DFGAbstractState.h: + (AbstractState): + * dfg/DFGAssemblyHelpers.h: + (JSC::DFG::AssemblyHelpers::emitGetFromCallFrameHeaderPtr): + (JSC::DFG::AssemblyHelpers::emitPutToCallFrameHeader): + (JSC::DFG::AssemblyHelpers::emitPutImmediateToCallFrameHeader): * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::getDirect): - (JSC::DFG::ByteCodeParser::getCallee): Remap access to the callee register - into a GetCallee node. Otherwise, we get confused and think we have a - negatively indexed argument. - - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand): Inlining also - needs to remap, but to the callee in the inline frame, and not the caller's - callee. - - (JSC::DFG::ByteCodeParser::parseBlock): Since we support the callee in - the general case now, there's no need to handle it in a special way for - create_this. - -2012-09-05 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove use of JSCell::classInfoOffset() from virtualForThunkGenerator - https://bugs.webkit.org/show_bug.cgi?id=95821 - - Reviewed by Oliver Hunt. - - We can replace the load of the ClassInfo from the object with a load from the Structure. - - * dfg/DFGThunks.cpp: - (JSC::DFG::virtualForThunkGenerator): - -2012-09-05 Benjamin Poulain <bpoulain@apple.com> - - Fix the uses of String::operator+=() for Mac - https://bugs.webkit.org/show_bug.cgi?id=95818 - - Reviewed by Dan Bernstein. - - * jsc.cpp: - (functionJSCStack): Use StringBuilder to create the stack dump, it is faster - and avoid String::operator+=(). - - * parser/Parser.h: - (JSC::Parser::updateErrorMessageSpecialCase): - (JSC::Parser::updateErrorMessage): - (JSC::Parser::updateErrorWithNameAndMessage): - Use the String operators (and makeString) to concatenate the strings. - -2012-09-05 Gabor Rapcsanyi <rgabor@webkit.org> - - DFG JIT doesn't work properly on ARM hardfp - https://bugs.webkit.org/show_bug.cgi?id=95684 - - Reviewed by Filip Pizlo. - - Add hardfp support to DFG JIT. The patch is created with the - help of Zoltan Herczeg. - - * dfg/DFGCCallHelpers.h: - (CCallHelpers): - (JSC::DFG::CCallHelpers::setupArguments): - * dfg/DFGFPRInfo.h: - (FPRInfo): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheckSetResult): - (JSC::DFG::SpeculativeJIT::appendCallSetResult): - -2012-09-04 Mark Lam <mark.lam@apple.com> - - Allow the YarrJIT to use the assembler even when useJIT() is false. - Introduce the useYarrJIT() option. - https://bugs.webkit.org/show_bug.cgi?id=95809. - - Reviewed by Geoffrey Garen. - - * runtime/JSGlobalData.cpp: - (JSC::enableAssembler): - * runtime/Options.cpp: - (JSC::Options::initialize): - * runtime/Options.h: - (JSC): - -2012-09-04 Gavin Barraclough <barraclough@apple.com> - - inc/dec behave incorrectly operating on a resolved const - https://bugs.webkit.org/show_bug.cgi?id=95815 - - Reviewed by Geoff Garen. - - There are two bugs here. - - (1) When the value being incremented is const, and the result is ignored, we assume this cannot be observed, and emit no code. - However if the value being incremented is not a primitive & has a valueOf conversion, then this should be being called. - - (2) In the case of a pre-increment of a const value where the result is not ignored, we'll move +/-1 to the destination, then - add the resolved const value being incremented to this. This is problematic if the destination is a local, and the const - value being incremented has a valueOf conversion that throws - the destination will be modified erroneously. Instead, we - need to use a temporary location. - - * bytecompiler/NodesCodegen.cpp: - (JSC::PostfixResolveNode::emitBytecode): - (JSC::PrefixResolveNode::emitBytecode): - - always at least perform a toNumber conversion, use tempDestination when reducing inc/dec to an add +/-1. - -2012-09-04 Filip Pizlo <fpizlo@apple.com> - - DFG GetByVal for JSArrays shouldn't OSR exit every time that the index is out of bound - https://bugs.webkit.org/show_bug.cgi?id=95717 - - Reviewed by Oliver Hunt. - - Rolling back in after fixing the negative index case. - - Make GetByVal for JSArrayOutOfBounds do meaningful things. The profiling was already - there so we should just use it! - - * bytecode/DFGExitProfile.h: - (JSC::DFG::exitKindToString): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-09-04 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r127503. - http://trac.webkit.org/changeset/127503 - https://bugs.webkit.org/show_bug.cgi?id=95788 - - broke some tests (fast/js/dfg-negative-array-index, fast/js - /dfg-put-by-val-setter-then-get-by-val) (Requested by thorton - on #webkit). - - * bytecode/DFGExitProfile.h: - (JSC::DFG::exitKindToString): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::ByteCodeParser::getDirect): + (JSC::DFG::ByteCodeParser::findArgumentPositionForLocal): + (JSC::DFG::ByteCodeParser::addCall): + (JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand): + (JSC::DFG::ByteCodeParser::handleInlining): + (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGGenerationInfo.h: + (GenerationInfo): + (JSC::DFG::GenerationInfo::needsSpill): + * dfg/DFGGraph.h: + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::compileEntry): + (JSC::DFG::JITCompiler::compileFunction): + * dfg/DFGJITCompiler.h: + (JSC::DFG::JITCompiler::beginCall): + * dfg/DFGOSREntry.cpp: + (JSC::DFG::prepareOSREntry): + * dfg/DFGOSRExitCompiler32_64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGOSRExitCompiler64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGRepatch.cpp: + (JSC::DFG::tryBuildGetByIDList): + * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compile): - -2012-09-04 Benjamin Poulain <bpoulain@apple.com> - - Improve JSC use of Strings after the UString->String change - https://bugs.webkit.org/show_bug.cgi?id=95633 - - Reviewed by Geoffrey Garen. - - This patch improve the use of strings in the JSC runtime. - - The initialization of Identifier is left for future patches. - - The improvements are the following: - -5% faster to raise one of the modified exception. - -3 times faster to execute Boolean::toString() - - Most of the changes are just about using the new methods - for string literals. - - With the changes, the binary on x86_64 gets 176 bytes smaller. - - * API/JSCallbackObjectFunctions.h: - (JSC::::staticFunctionGetter): - (JSC::::callbackGetter): - * API/JSContextRef.cpp: - (JSContextCreateBacktrace): - * API/JSObjectRef.cpp: - (JSObjectMakeFunctionWithCallback): - * bytecode/CodeBlock.cpp: - (JSC::valueToSourceString): - (JSC::CodeBlock::nameForRegister): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::addStackTraceIfNecessary): - * runtime/ArrayConstructor.cpp: - (JSC::constructArrayWithSizeQuirk): - * runtime/ArrayPrototype.cpp: - (JSC::shift): - (JSC::unshift): - (JSC::arrayProtoFuncPop): - (JSC::arrayProtoFuncReverse): - * runtime/BooleanPrototype.cpp: - (JSC::booleanProtoFuncToString): Instead of instanciating new strings, reuse the - keywords available in SmallStrings. Avoiding the creation of the JSString and StringImpl - makes the method significantly faster. - - * runtime/DateConversion.cpp: - (JSC::formatDateTime): - * runtime/DatePrototype.cpp: - (JSC::formatLocaleDate): - (JSC::formateDateInstance): - (JSC::dateProtoFuncToISOString): - Change the way we use snprintf() for clarity and performance. - - Instead of allocating one extra byte to put a zero "just in case", we use the size returned - by snprintf(). - To prevent any overflow from a programming mistake, we explicitely test for overflow and - return an empty string. - - (JSC::dateProtoFuncToJSON): - * runtime/Error.cpp: - (JSC::createNotEnoughArgumentsError): - (JSC::throwTypeError): - (JSC::throwSyntaxError): - * runtime/Error.h: - (JSC::StrictModeTypeErrorFunction::create): - * runtime/ErrorPrototype.cpp: - (JSC::ErrorPrototype::finishCreation): - (JSC::errorProtoFuncToString): - Using a null String is correct because (8) uses jsString(), (9) tests for a length of 0. - - * runtime/ExceptionHelpers.cpp: - (JSC::InterruptedExecutionError::defaultValue): - (JSC::TerminatedExecutionError::defaultValue): - (JSC::createStackOverflowError): - (JSC::createOutOfMemoryError): - * runtime/Executable.cpp: - (JSC::EvalExecutable::compileInternal): - (JSC::FunctionExecutable::paramString): - * runtime/FunctionConstructor.cpp: - (JSC::constructFunction): - (JSC::constructFunctionSkippingEvalEnabledCheck): - * runtime/FunctionPrototype.h: - (JSC::FunctionPrototype::create): - Using a null String for the name is correct because InternalFunction uses jsString() - to create the name value. - - * runtime/InternalFunction.cpp: - (JSC::InternalFunction::finishCreation): - There is no need to create an empty string for a null string, jsString() handle both - cases as empty JSString. - - * runtime/JSArray.cpp: - (JSC::reject): - (JSC::SparseArrayValueMap::put): - (JSC::JSArray::put): - (JSC::JSArray::putByIndexBeyondVectorLength): - (JSC::JSArray::putDirectIndexBeyondVectorLength): - (JSC::JSArray::setLength): - (JSC::JSArray::pop): - (JSC::JSArray::push): - * runtime/JSFunction.cpp: - (JSC::JSFunction::finishCreation): Same issue as InternalFunction::finishCreation. - - (JSC::JSFunction::callerGetter): - (JSC::JSFunction::defineOwnProperty): - * runtime/JSGlobalData.cpp: - (JSC::enableAssembler): Use CFSTR() instead of CFStringCreateWithCString(). - CFStringCreateWithCString() copy the content and may choose to decode the data. - CFSTR() is much more efficient. - - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::reset): - JSFunction uses jsString() to create the name, we can use null strings instead - of creating empty strings. - - (JSC::JSGlobalObject::createThrowTypeError): ditto. - * runtime/JSGlobalObjectFunctions.cpp: - (JSC::encode): - (JSC::decode): - (JSC::globalFuncEval): - * runtime/JSONObject.cpp: - (JSC::Stringifier::appendStringifiedValue): - (JSC::Stringifier::Holder::appendNextProperty): - (JSC::JSONProtoFuncParse): - (JSC::JSONProtoFuncStringify): - * runtime/JSObject.cpp: - (JSC::JSObject::put): - (JSC::JSObject::defaultValue): - (JSC::JSObject::hasInstance): - (JSC::JSObject::defineOwnProperty): - * runtime/JSString.cpp: - Return an empty JSString to avoid the creation of a temporary empty String. - - (JSC::JSRopeString::getIndexSlowCase): - * runtime/JSString.h: - (JSC): Remove the versions of jsNontrivialString() taking a char*. All the callers - have been replaced by calls using ASCIILiteral. - - * runtime/JSValue.cpp: - (JSC::JSValue::putToPrimitive): - * runtime/LiteralParser.cpp: - (JSC::::Lexer::lex): - (JSC::::Lexer::lexString): - (JSC::::Lexer::lexNumber): - (JSC::::parse): - * runtime/LiteralParser.h: - (JSC::LiteralParser::getErrorMessage): - * runtime/NumberPrototype.cpp: - (JSC::numberProtoFuncToExponential): - (JSC::numberProtoFuncToFixed): - (JSC::numberProtoFuncToPrecision): - (JSC::numberProtoFuncToString): - * runtime/ObjectConstructor.cpp: - (JSC::objectConstructorGetPrototypeOf): - (JSC::objectConstructorGetOwnPropertyDescriptor): - (JSC::objectConstructorGetOwnPropertyNames): - (JSC::objectConstructorKeys): - (JSC::toPropertyDescriptor): - (JSC::objectConstructorDefineProperty): - (JSC::objectConstructorDefineProperties): - (JSC::objectConstructorCreate): - (JSC::objectConstructorSeal): - (JSC::objectConstructorFreeze): - (JSC::objectConstructorPreventExtensions): - (JSC::objectConstructorIsSealed): - (JSC::objectConstructorIsFrozen): - (JSC::objectConstructorIsExtensible): - * runtime/ObjectPrototype.cpp: - (JSC::objectProtoFuncDefineGetter): - (JSC::objectProtoFuncDefineSetter): - (JSC::objectProtoFuncToString): - * runtime/RegExpConstructor.cpp: - (JSC::constructRegExp): - * runtime/RegExpObject.cpp: - (JSC::reject): - (JSC::regExpObjectSource): - * runtime/RegExpPrototype.cpp: - (JSC::regExpProtoFuncCompile): - * runtime/StringObject.cpp: - (JSC::StringObject::defineOwnProperty): - * runtime/StringPrototype.cpp: - (JSC::jsSpliceSubstrings): - (JSC::jsSpliceSubstringsWithSeparators): - -2012-09-04 Filip Pizlo <fpizlo@apple.com> - - DFG GetByVal for JSArrays shouldn't OSR exit every time that the index is out of bound - https://bugs.webkit.org/show_bug.cgi?id=95717 - - Reviewed by Oliver Hunt. - - Make GetByVal for JSArrayOutOfBounds do meaningful things. The profiling was already - there so we should just use it! - - * bytecode/DFGExitProfile.h: - (JSC::DFG::exitKindToString): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: + (JSC::DFG::SpeculativeJIT::checkArgumentTypes): + (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::spill): * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::emitCall): (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::fillInteger): + (JSC::DFG::SpeculativeJIT::emitCall): (JSC::DFG::SpeculativeJIT::compile): - -2012-09-04 Zoltan Horvath <zoltan@webkit.org> - - Extend the coverage of the Custom Allocation Framework in WTF and in JavaScriptCore - https://bugs.webkit.org/show_bug.cgi?id=95737 - - Reviewed by Eric Seidel. - - Add WTF_MAKE_FAST_ALLOCATED macro to the following class declarations because these are instantiated by operator new. - - * wtf/CryptographicallyRandomNumber.cpp: CryptographicallyRandomNumber is instantiated at wtf/CryptographicallyRandomNumber.cpp:162. - - * heap/MachineStackMarker.cpp: - (MachineThreads::Thread): Thread is instantiated at heap/MachineStackMarker.cpp:196. - * jit/ExecutableAllocatorFixedVMPool.cpp: - (FixedVMPoolExecutableAllocator): FixedVMPoolExecutableAllocator is instantiated at jit/ExecutableAllocatorFixedVMPool.cpp:111 - * parser/SourceProviderCache.h: - (SourceProviderCache): SourceProviderCache is instantiated at parser/SourceProvider.h:49. - * parser/SourceProviderCacheItem.h: - (SourceProviderCacheItem): SourceProviderCacheItem is instantiated at parser/Parser.cpp:843. - * runtime/GCActivityCallback.h: - (GCActivityCallback): GCActivityCallback is instantiated at runtime/GCActivityCallback.h:96. - * tools/CodeProfile.h: - (CodeProfile): CodeProfile is instantiated at JavaScriptCore/tools/CodeProfiling.cpp:140. - -2012-09-04 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove uses of ClassInfo from SpeculativeJIT::compileObjectOrOtherLogicalNot - https://bugs.webkit.org/show_bug.cgi?id=95510 - - Reviewed by Oliver Hunt. - - More refactoring to get rid of ClassInfo checks in the DFG. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compileNonStringCellOrOtherLogicalNot): - (JSC::DFG::SpeculativeJIT::compileLogicalNot): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compileNonStringCellOrOtherLogicalNot): - (JSC::DFG::SpeculativeJIT::compileLogicalNot): - -2012-09-03 Patrick Gansterer <paroga@webkit.org> - - Unreviewed. Build fix for ENABLE(CLASSIC_INTERPRETER) after r127393. - - * interpreter/Interpreter.h: - -2012-09-02 Geoffrey Garen <ggaren@apple.com> - - Fixed failures seen on Linux bots. - - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_push_with_scope): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_push_with_scope): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * jit/JITStubs.h: push_*_scope doesn't have a destination operand anymore. - Accordingly, update these places in the baseline JIT, which I missed in my last patch. - -2012-09-02 Geoffrey Garen <ggaren@apple.com> - - Refactored scope chain opcodes to support optimization for named function expressions - https://bugs.webkit.org/show_bug.cgi?id=95658 - - Reviewed by Sam Weinig. - - Renamed - push_scope => push_with_scope - push_new_scope => push_name_scope - to clarify the difference between them. - - Changed push_with_scope and push_name_scope not to save the new scope in - a temporary register, since doing so made optimization harder. - - (The old behavior was a hold-over from when the scope chain wasn't - a GC object, and wouldn't be marked otherwise. Now, the scope chain is - marked because it is a GC object pointed to by the call frame.) - - Changed push_name_scope to accept an operand specifying the attributes - for the named property, instead of assuming DontDelete, because a named - function expression needs ReadOnly|DontDelete. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::highestUsedRegister): Removed this function, - which used to be related to preserving saved scope object temporaries, - because it had no callers. - -2012-09-01 Geoffrey Garen <ggaren@apple.com> - - Rolled back out a piece of <http://trac.webkit.org/changeset/127293> - because it broke inspector tests on Windows. - - Shrink activation objects by half - https://bugs.webkit.org/show_bug.cgi?id=95591 - - Reviewed by Sam Weinig. - -2012-09-01 Mark Lam <mark.lam@apple.com> - - LLInt C loop backend. - https://bugs.webkit.org/show_bug.cgi?id=91052. - - Reviewed by Filip Pizlo. - - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - (JSC::CodeBlock::bytecodeOffset): + * dfg/DFGThunks.cpp: + (JSC::DFG::throwExceptionFromCallSlowPathGenerator): + (JSC::DFG::slowPathFor): + (JSC::DFG::virtualForThunkGenerator): + * dfg/DFGValueSource.cpp: + (JSC::DFG::ValueSource::dump): + * dfg/DFGValueSource.h: + (JSC::DFG::dataFormatToValueSourceKind): + (JSC::DFG::valueSourceKindToDataFormat): + (JSC::DFG::isInJSStack): + (JSC::DFG::ValueSource::forSpeculation): + (JSC::DFG::ValueSource::isInJSStack): + (JSC::DFG::ValueSource::valueRecovery): + * dfg/DFGVariableEventStream.cpp: + (JSC::DFG::VariableEventStream::reconstruct): + * heap/Heap.cpp: + (JSC::Heap::stack): + (JSC::Heap::getConservativeRegisterRoots): + (JSC::Heap::markRoots): + * heap/Heap.h: + (JSC): + (Heap): + * interpreter/CallFrame.cpp: + (JSC::CallFrame::stack): + * interpreter/CallFrame.h: + (JSC::ExecState::calleeAsValue): + (JSC::ExecState::callee): + (JSC::ExecState::codeBlock): + (JSC::ExecState::scope): + (JSC::ExecState::callerFrame): + (JSC::ExecState::returnPC): + (JSC::ExecState::hasReturnPC): + (JSC::ExecState::clearReturnPC): + (JSC::ExecState::bytecodeOffsetForNonDFGCode): + (JSC::ExecState::setBytecodeOffsetForNonDFGCode): + (JSC::ExecState::inlineCallFrame): + (JSC::ExecState::codeOriginIndexForDFG): + (JSC::ExecState::currentVPC): + (JSC::ExecState::setCurrentVPC): + (JSC::ExecState::setCallerFrame): + (JSC::ExecState::setScope): + (JSC::ExecState::init): + (JSC::ExecState::argumentCountIncludingThis): + (JSC::ExecState::offsetFor): + (JSC::ExecState::setArgumentCountIncludingThis): + (JSC::ExecState::setCallee): + (JSC::ExecState::setCodeBlock): + (JSC::ExecState::setReturnPC): + (JSC::ExecState::setInlineCallFrame): + (ExecState): * interpreter/Interpreter.cpp: + (JSC::Interpreter::slideRegisterWindowForCall): + (JSC::eval): + (JSC::loadVarargs): + (JSC::Interpreter::dumpRegisters): + (JSC::Interpreter::throwException): (JSC::Interpreter::execute): (JSC::Interpreter::executeCall): (JSC::Interpreter::executeConstruct): - (JSC): + (JSC::Interpreter::prepareForRepeatCall): + (JSC::Interpreter::endRepeatCall): * interpreter/Interpreter.h: - * jit/JITStubs.h: - (JITStackFrame): - (JSC): - * llint/LLIntCLoop.cpp: Added. - (JSC): - (LLInt): - (JSC::LLInt::CLoop::initialize): - (JSC::LLInt::CLoop::catchRoutineFor): - (JSC::LLInt::CLoop::hostCodeEntryFor): - (JSC::LLInt::CLoop::jsCodeEntryWithArityCheckFor): - (JSC::LLInt::CLoop::jsCodeEntryFor): - * llint/LLIntCLoop.h: Added. - (JSC): - (LLInt): - (CLoop): - * llint/LLIntData.cpp: - (JSC::LLInt::initialize): - * llint/LLIntData.h: - (JSC): - * llint/LLIntOfflineAsmConfig.h: - * llint/LLIntOpcode.h: - * llint/LLIntThunks.cpp: - (LLInt): - * llint/LowLevelInterpreter.asm: - * llint/LowLevelInterpreter.cpp: - (LLInt): - (JSC::LLInt::Ints2Double): - (JSC): - (JSC::CLoop::execute): - * llint/LowLevelInterpreter.h: - (JSC): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * offlineasm/asm.rb: - * offlineasm/backends.rb: - * offlineasm/cloop.rb: Added. - * offlineasm/instructions.rb: - * runtime/Executable.h: - (ExecutableBase): - (JSC::ExecutableBase::hostCodeEntryFor): - (JSC::ExecutableBase::jsCodeEntryFor): - (JSC::ExecutableBase::jsCodeWithArityCheckEntryFor): - (JSC::ExecutableBase::catchRoutineFor): - (NativeExecutable): - * runtime/JSValue.h: - (JSC): - (LLInt): - (JSValue): - * runtime/JSValueInlineMethods.h: + (JSC::Interpreter::stack): + (Interpreter): + (JSC::Interpreter::execute): (JSC): - (JSC::JSValue::JSValue): - * runtime/Options.cpp: - (JSC::Options::initialize): - -2012-09-01 Geoffrey Garen <ggaren@apple.com> - - Rolled back in a piece of <http://trac.webkit.org/changeset/127293>. - - Shrink activation objects by half - https://bugs.webkit.org/show_bug.cgi?id=95591 - - Reviewed by Sam Weinig. - - * runtime/JSActivation.h: - (JSActivation): - -2012-09-01 Geoffrey Garen <ggaren@apple.com> - - Rolled back in a piece of <http://trac.webkit.org/changeset/127293>. - - Shrink activation objects by half - https://bugs.webkit.org/show_bug.cgi?id=95591 - - Reviewed by Sam Weinig. - - * runtime/JSActivation.cpp: - (JSC::JSActivation::JSActivation): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - (JSC::JSGlobalObject::setGlobalThis): + * interpreter/JSStack.cpp: Copied from Source/JavaScriptCore/interpreter/RegisterFile.cpp. + (JSC::stackStatisticsMutex): + (JSC::JSStack::~JSStack): + (JSC::JSStack::growSlowCase): + (JSC::JSStack::gatherConservativeRoots): + (JSC::JSStack::releaseExcessCapacity): + (JSC::JSStack::initializeThreading): + (JSC::JSStack::committedByteCount): + (JSC::JSStack::addToCommittedByteCount): + * interpreter/JSStack.h: Copied from Source/JavaScriptCore/interpreter/RegisterFile.h. + (JSStack): + (JSC::JSStack::JSStack): + (JSC::JSStack::shrink): + (JSC::JSStack::grow): + * interpreter/RegisterFile.cpp: Removed. + * interpreter/RegisterFile.h: Removed. + * interpreter/VMInspector.cpp: + (JSC::VMInspector::dumpFrame): + * jit/JIT.cpp: + (JSC::JIT::JIT): + (JSC::JIT::privateCompile): + * jit/JIT.h: (JSC): - (JSC::JSGlobalObject::visitChildren): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSScope::globalThis): + (JIT): + * jit/JITCall.cpp: + (JSC::JIT::compileLoadVarargs): + (JSC::JIT::compileCallEval): + (JSC::JIT::compileCallEvalSlowCase): + (JSC::JIT::compileOpCall): + * jit/JITCall32_64.cpp: + (JSC::JIT::emit_op_ret): + (JSC::JIT::emit_op_ret_object_or_this): + (JSC::JIT::compileLoadVarargs): + (JSC::JIT::compileCallEval): + (JSC::JIT::compileCallEvalSlowCase): + (JSC::JIT::compileOpCall): + * jit/JITCode.h: (JSC): - (JSC::JSGlobalObject::globalThis): - * runtime/JSNameScope.h: - (JSC::JSNameScope::JSNameScope): - * runtime/JSScope.cpp: - (JSC::JSScope::visitChildren): - * runtime/JSScope.h: - (JSScope): - (JSC::JSScope::JSScope): - (JSC::JSScope::globalObject): - (JSC::JSScope::globalData): - * runtime/JSSegmentedVariableObject.h: - (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject): - * runtime/JSSymbolTableObject.h: - (JSC::JSSymbolTableObject::JSSymbolTableObject): - * runtime/JSVariableObject.h: - (JSC::JSVariableObject::JSVariableObject): - * runtime/JSWithScope.h: - (JSC::JSWithScope::JSWithScope): - * runtime/StrictEvalActivation.cpp: - (JSC::StrictEvalActivation::StrictEvalActivation): - -2012-09-01 Geoffrey Garen <ggaren@apple.com> - - Rolled back out a piece of <http://trac.webkit.org/changeset/127293> - because it broke Window inspector tests. - - Shrink activation objects by half - https://bugs.webkit.org/show_bug.cgi?id=95591 - - Reviewed by Sam Weinig. - - * runtime/JSActivation.h: - (JSActivation): - -2012-08-31 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, attempt to fix Windows, take two. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-08-31 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, attempt to fix Windows. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-08-31 Filip Pizlo <fpizlo@apple.com> - - JSArray::putDirectIndex should by default behave like JSObject::putDirect - https://bugs.webkit.org/show_bug.cgi?id=95630 - - Reviewed by Gavin Barraclough. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * jsc.cpp: - (GlobalObject::finishCreation): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * runtime/JSArray.cpp: - (JSC::SparseArrayValueMap::putDirect): - (JSC::JSArray::defineOwnNumericProperty): - (JSC::JSArray::putDirectIndexBeyondVectorLength): - * runtime/JSArray.h: - (SparseArrayValueMap): - (JSArray): - (JSC::JSArray::putDirectIndex): - * runtime/JSONObject.cpp: - (JSC::Walker::walk): - * runtime/RegExpMatchesArray.cpp: - (JSC::RegExpMatchesArray::reifyAllProperties): - (JSC::RegExpMatchesArray::reifyMatchProperty): - * runtime/StringPrototype.cpp: - (JSC::splitStringByOneCharacterImpl): - (JSC::stringProtoFuncSplit): - -2012-08-31 Geoffrey Garen <ggaren@apple.com> - - Rolled back in a piece of <http://trac.webkit.org/changeset/127293>. - - Shrink activation objects by half - https://bugs.webkit.org/show_bug.cgi?id=95591 - - Reviewed by Sam Weinig. - - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: - (JSGlobalData): - * runtime/JSNameScope.h: - (JSC::JSNameScope::JSNameScope): - * runtime/JSWithScope.h: - (JSC::JSWithScope::JSWithScope): - * runtime/StrictEvalActivation.cpp: - (JSC::StrictEvalActivation::StrictEvalActivation): - -2012-08-31 Geoffrey Garen <ggaren@apple.com> - - Rolled back in a piece of <http://trac.webkit.org/changeset/127293>. - - Shrink activation objects by half - https://bugs.webkit.org/show_bug.cgi?id=95591 - - Reviewed by Sam Weinig. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): + (JSC::JITCode::execute): + * jit/JITInlineMethods.h: + (JSC::JIT::emitPutToCallFrameHeader): + (JSC::JIT::emitPutCellToCallFrameHeader): + (JSC::JIT::emitPutIntToCallFrameHeader): + (JSC::JIT::emitPutImmediateToCallFrameHeader): + (JSC::JIT::emitGetFromCallFrameHeaderPtr): + (JSC::JIT::emitGetFromCallFrameHeader32): + (JSC::JIT::updateTopCallFrame): + (JSC::JIT::unmap): * jit/JITOpcodes.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + (JSC::JIT::privateCompileCTINativeCall): + (JSC::JIT::emit_op_end): + (JSC::JIT::emit_op_ret): + (JSC::JIT::emit_op_ret_object_or_this): + (JSC::JIT::emit_op_create_this): + (JSC::JIT::emit_op_get_arguments_length): + (JSC::JIT::emit_op_get_argument_by_val): (JSC::JIT::emit_op_resolve_global_dynamic): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/JSActivation.cpp: - (JSC::JSActivation::JSActivation): - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: - (JSGlobalData): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::reset): - (JSC::JSGlobalObject::visitChildren): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::withScopeStructure): - (JSC::JSGlobalObject::strictEvalActivationStructure): - (JSC::JSGlobalObject::activationStructure): - (JSC::JSGlobalObject::nameScopeStructure): - -2012-08-31 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove use of ClassInfo in SpeculativeJIT::emitBranch - https://bugs.webkit.org/show_bug.cgi?id=95623 - - Reviewed by Filip Pizlo. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::emitNonStringCellOrOtherBranch): - (JSC::DFG::SpeculativeJIT::emitBranch): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::emitNonStringCellOrOtherBranch): - (JSC::DFG::SpeculativeJIT::emitBranch): - -2012-08-31 Geoffrey Garen <ggaren@apple.com> - - Rolled back in a piece of <http://trac.webkit.org/changeset/127293>. - - Shrink activation objects by half - https://bugs.webkit.org/show_bug.cgi?id=95591 - - Reviewed by Sam Weinig. - - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::MarkedBlock): - * heap/MarkedBlock.h: - (MarkedBlock): - (JSC::MarkedBlock::globalData): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + (JSC::JIT::privateCompileCTINativeCall): + (JSC::JIT::emit_op_end): + (JSC::JIT::emit_op_create_this): + (JSC::JIT::emit_op_get_arguments_length): + (JSC::JIT::emit_op_get_argument_by_val): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_scoped_var): + (JSC::JIT::emit_op_put_scoped_var): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_scoped_var): + (JSC::JIT::emit_op_put_scoped_var): + * jit/JITStubs.cpp: + (JSC::ctiTrampoline): + (JSC::JITThunks::JITThunks): (JSC): - * heap/WeakSet.cpp: - (JSC::WeakSet::addAllocator): - * heap/WeakSet.h: - (WeakSet): - (JSC::WeakSet::WeakSet): - (JSC::WeakSet::globalData): - * runtime/JSGlobalData.h: - (JSC::WeakSet::heap): + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: (JSC): - -2012-08-31 Mark Lam <mark.lam@apple.com> - - Refactor LLInt and supporting code in preparation for the C Loop backend. - https://bugs.webkit.org/show_bug.cgi?id=95531. - - Reviewed by Filip Pizlo. - - * bytecode/GetByIdStatus.cpp: - (JSC::GetByIdStatus::computeFromLLInt): - * bytecode/PutByIdStatus.cpp: - (JSC::PutByIdStatus::computeFromLLInt): - * jit/JITExceptions.cpp: - (JSC::genericThrow): Use ExecutableBase::catchRoutineFor() to fetch - fetch the catch routine for a thrown exception. This will allow - us to redefine that for the C loop later, and still keep this - code readable. - * llint/LLIntOfflineAsmConfig.h: Moved ASM macros to - LowLevelInterpreter.cpp which is the only place they are used. This - will make it more convenient to redefine them for the C loop later. + (JITStackFrame): + * jit/JSInterfaceJIT.h: + * jit/SpecializedThunkJIT.h: + (JSC::SpecializedThunkJIT::SpecializedThunkJIT): + (JSC::SpecializedThunkJIT::returnJSValue): + (JSC::SpecializedThunkJIT::returnDouble): + (JSC::SpecializedThunkJIT::returnInt32): + (JSC::SpecializedThunkJIT::returnJSCell): + * llint/LLIntData.cpp: + (JSC::LLInt::Data::performAssertions): + * llint/LLIntOffsetsExtractor.cpp: * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::setUpCall): Use ExecutableBase's hostCodeEntry() - jsCodeEntryFor(), and jsCodeWithArityCheckEntryFor() for computing - the entry points to functions being called. + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + (JSC::LLInt::genericCall): * llint/LLIntSlowPaths.h: - (SlowPathReturnType): - (JSC::LLInt::encodeResult): (LLInt): - (JSC::LLInt::decodeResult): Added. Needed by LLInt C Loop later. * llint/LowLevelInterpreter.asm: - * llint/LowLevelInterpreter.cpp: - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * offlineasm/asm.rb: Disambiguate between opcodes and other labels. - * offlineasm/config.rb: - * runtime/Executable.h: - (JSC::ExecutableBase::hostCodeEntryFor): Added. - (ExecutableBase): - (JSC::ExecutableBase::jsCodeEntryFor): Added. - (JSC::ExecutableBase::jsCodeWithArityCheckEntryFor): Added. - (JSC::ExecutableBase::catchRoutineFor): Added. - * runtime/JSValueInlineMethods.h: - (JSC): - -2012-08-31 Tony Chang <tony@chromium.org> - - Remove ENABLE_CSS3_FLEXBOX compile time flag - https://bugs.webkit.org/show_bug.cgi?id=95382 - - Reviewed by Ojan Vafai. - - Everyone is already enabling this by default and the spec has stablized. - - * Configurations/FeatureDefines.xcconfig: - -2012-08-31 Geoffrey Garen <ggaren@apple.com> - - Not reviewed. - - Rolled out http://trac.webkit.org/changeset/127293 because it broke - inspector tests on Windows. - - Shrink activation objects by half - https://bugs.webkit.org/show_bug.cgi?id=95591 - - Reviewed by Sam Weinig. - -2012-08-31 Geoffrey Garen <ggaren@apple.com> - - Shrink activation objects by half - https://bugs.webkit.org/show_bug.cgi?id=95591 - - Reviewed by Sam Weinig. - - Removed the global object, global data, and global this pointers from - JSScope, and changed an int to a bitfield. This gets the JSActivation - class down to 64 bytes, which in practice cuts it in half by getting it - out of the 128 byte size class. - - Now, it's one extra indirection to get these pointers. These pointers - aren't accessed by JIT code, so I thought there would be no cost to the - extra indirection. However, some C++-heavy SunSpider tests regressed a - bit in an early version of the patch, which added even more indirection. - This suggests that calls to exec->globalData() and/or exec->lexicalGlobalObject() - are common and probably duplicated in lots of places, and could stand - further optimization in C++. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): Test against the specific activation - for our global object, since there's no VM-shared activation structure - anymore. This is guaranteed to have the same success rate as the old test - because activation scope is fixed at compile time. - - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::MarkedBlock): - * heap/MarkedBlock.h: - (JSC::MarkedBlock::globalData): - * heap/WeakSet.cpp: - (JSC::WeakSet::addAllocator): - * heap/WeakSet.h: - (WeakSet): - (JSC::WeakSet::WeakSet): - (JSC::WeakSet::globalData): Store a JSGlobalData* instead of a Heap* - because JSGlobalData->Heap is just a constant fold in the addressing - mode, while Heap->JSGlobalData is an extra pointer dereference. (These - objects should eventually just merge.) - - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_resolve_global_dynamic): See DFGAbstractState.cpp. - - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: Load the activation structure from - the code block instead of the global data because the structure is not - VM-shared anymore. (See DFGAbstractState.cpp.) - + * runtime/Arguments.cpp: + (JSC::Arguments::tearOffForInlineCallFrame): + * runtime/CommonSlowPaths.h: + (JSC::CommonSlowPaths::arityCheckFor): + * runtime/InitializeThreading.cpp: + (JSC::initializeThreadingOnce): * runtime/JSActivation.cpp: - (JSC::JSActivation::JSActivation): - * runtime/JSActivation.h: - (JSActivation): This is the point of the patch: Remove the data. - - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: - (JSGlobalData): No longer VM-shared. (See DFGAbstractState.cpp.) - - (JSC::WeakSet::heap): (See WeakSet.h.) - + (JSC::JSActivation::visitChildren): * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - (JSC::JSGlobalObject::setGlobalThis): - (JSC::JSGlobalObject::reset): - (JSC::JSGlobalObject::visitChildren): + (JSC::JSGlobalObject::globalExec): * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::withScopeStructure): - (JSC::JSGlobalObject::strictEvalActivationStructure): - (JSC::JSGlobalObject::activationStructure): - (JSC::JSGlobalObject::nameScopeStructure): - (JSC::JSScope::globalThis): - (JSC::JSGlobalObject::globalThis): Data that used to be in the JSScope - class goes here now, so it's not duplicated across all activations. - - * runtime/JSNameScope.h: - (JSC::JSNameScope::JSNameScope): - * runtime/JSScope.cpp: - (JSC::JSScope::visitChildren): This is the point of the patch: Remove the data. - - * runtime/JSScope.h: - (JSScope): - (JSC::JSScope::JSScope): - (JSC::JSScope::globalObject): - (JSC::JSScope::globalData): - * runtime/JSSegmentedVariableObject.h: - (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject): - * runtime/JSSymbolTableObject.h: - (JSC::JSSymbolTableObject::JSSymbolTableObject): - * runtime/JSVariableObject.h: - (JSC::JSVariableObject::JSVariableObject): - * runtime/JSWithScope.h: - (JSC::JSWithScope::JSWithScope): - * runtime/StrictEvalActivation.cpp: - (JSC::StrictEvalActivation::StrictEvalActivation): Simplified now that - we don't need to pass so much data to JSScope. - -2012-08-31 Patrick Gansterer <paroga@webkit.org> - - Build fix for WinCE after r127191. - - * bytecode/JumpTable.h: - -2012-08-30 Filip Pizlo <fpizlo@apple.com> - - ASSERTION FAILURE in JSC::JSGlobalData::float32ArrayDescriptor when running fast/js/dfg-float64array.html - https://bugs.webkit.org/show_bug.cgi?id=95398 - - Reviewed by Mark Hahnenberg. - - Trying to get the build failure to be a bit more informative. - - * runtime/JSGlobalData.h: - (JSGlobalData): - -2012-08-30 Geoffrey Garen <ggaren@apple.com> - - Try to fix the Qt build: add some #includes that, for some reason, only the Qt linker requires. - - * runtime/BooleanObject.cpp: - * runtime/ErrorInstance.cpp: - * runtime/NameInstance.cpp: - -2012-08-30 Geoffrey Garen <ggaren@apple.com> - - Fix the Qt build: Removed a now-dead variable. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::execute): - -2012-08-30 Benjamin Poulain <bpoulain@apple.com> - - Ambiguous operator[] after r127191 on some compiler - https://bugs.webkit.org/show_bug.cgi?id=95509 - - Reviewed by Simon Fraser. - - On some compilers, the operator[] conflicts with the Obj-C++ operators. This attempts to solve - the issue. - - * runtime/JSString.h: - (JSC::jsSingleCharacterSubstring): - (JSC::jsString): - (JSC::jsSubstring8): - (JSC::jsSubstring): - (JSC::jsOwnedString): - -2012-08-30 Geoffrey Garen <ggaren@apple.com> - - Try to fix the Qt build: Remove the inline keyword at the declaration - site. - - The Qt compiler seems to be confused, complaining about these functions - not being defined in a translation unit, even though no generated code - in the unit calls these functions. Maybe removing the keyword at the - declaration site will change its mind. - - This shouldn't change the inlining decision at all: the definition is - still inline. - - * interpreter/CallFrame.h: - (ExecState): - -2012-08-30 Geoffrey Garen <ggaren@apple.com> - - Undo Qt build fix guess, since it breaks other builds. - - * runtime/JSArray.h: - -2012-08-30 Geoffrey Garen <ggaren@apple.com> - - Try to fix the Qt build: add an #include to JSArray.h, since - it's included by some of the files Qt complains about, and - some of is functions call the functions Qt complains about. - - * runtime/JSArray.h: - -2012-08-30 Geoffrey Garen <ggaren@apple.com> - - Second step toward fixing the Windows build: Add new symbols. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-08-30 Geoffrey Garen <ggaren@apple.com> - - Try to fix the Qt build: add an #include. - - * bytecode/GetByIdStatus.cpp: - -2012-08-30 Geoffrey Garen <ggaren@apple.com> - - First step toward fixing the Windows build: Remove old symbols. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-08-30 Geoffrey Garen <ggaren@apple.com> - - Use one object instead of two for closures, eliminating ScopeChainNode - https://bugs.webkit.org/show_bug.cgi?id=95501 - - Reviewed by Filip Pizlo. - - This patch removes ScopeChainNode, and moves all the data and related - functions that used to be in ScopeChainNode into JSScope. - - Most of this patch is mechanical changes to use a JSScope* where we used - to use a ScopeChainNode*. I've only specifically commented about items - that were non-mechanical. - - * runtime/Completion.cpp: - (JSC::evaluate): - * runtime/Completion.h: Don't require an explicit scope chain argument - when evaluating code. Clients never wanted anything other than the - global scope, and other arbitrary scopes probably wouldn't work - correctly, anyway. - - * runtime/JSScope.cpp: - * runtime/JSScope.h: - (JSC::JSScope::JSScope): JSScope now requires the data we used to pass to - ScopeChainNode, so it can link itself into the scope chain correctly. - - * runtime/JSWithScope.h: - (JSC::JSWithScope::create): - (JSC::JSWithScope::JSWithScope): JSWithScope gets an extra constructor - for specifically supplying your own scope chain. The DOM needs this - interface for setting up the scope chain for certain event handlers. - Other clients always just push the JSWithScope to the head of the current - scope chain. - -2012-08-30 Mark Lam <mark.lam@apple.com> - - Render unto #ifdef's that which belong to them. - https://bugs.webkit.org/show_bug.cgi?id=95482. - - Reviewed by Filip Pizlo. - - Refining / disambiguating between #ifdefs and adding some. For - example, ENABLE(JIT) is conflated with ENABLE(LLINT) in some places. - Also, we need to add ENABLE(COMPUTED_GOTO_OPCODES) to indicate that we - want interpreted opcodes to use COMPUTED GOTOs apart from ENABLE(LLINT) - and ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER). Also cleaned up #ifdefs - in certain places which were previously incorrect. - - * bytecode/CodeBlock.cpp: (JSC): - (JSC::CodeBlock::bytecodeOffset): - * bytecode/CodeBlock.h: - (CodeBlock): - * bytecode/Opcode.h: - (JSC::padOpcodeName): - * config.h: - * dfg/DFGOperations.cpp: - * interpreter/AbstractPC.cpp: - (JSC::AbstractPC::AbstractPC): - * interpreter/CallFrame.h: - (ExecState): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::~Interpreter): - (JSC::Interpreter::initialize): - (JSC::Interpreter::isOpcode): - (JSC::Interpreter::unwindCallFrame): - (JSC::getLineNumberForCallFrame): - (JSC::getCallerInfo): - (JSC::Interpreter::execute): - (JSC::Interpreter::executeCall): - (JSC::Interpreter::executeConstruct): - (JSC::Interpreter::privateExecute): - * interpreter/Interpreter.h: - (JSC::Interpreter::getOpcode): - (JSC::Interpreter::getOpcodeID): - (Interpreter): - * jit/HostCallReturnValue.h: - * jit/JITCode.h: - (JITCode): - * jit/JITExceptions.cpp: - * jit/JITExceptions.h: - * jit/JSInterfaceJIT.h: - * llint/LLIntData.h: - (JSC::LLInt::getOpcode): - * llint/LLIntEntrypoints.cpp: - (JSC::LLInt::getFunctionEntrypoint): - (JSC::LLInt::getEvalEntrypoint): - (JSC::LLInt::getProgramEntrypoint): - * llint/LLIntOffsetsExtractor.cpp: - (JSC::LLIntOffsetsExtractor::dummy): - * llint/LLIntSlowPaths.cpp: - (LLInt): - * runtime/JSGlobalData.cpp: + (JSGlobalObject): + * runtime/JSLock.cpp: (JSC): + * runtime/JSVariableObject.h: + (JSVariableObject): + * runtime/MemoryStatistics.cpp: + (JSC::globalMemoryStatistics): -2012-08-30 JungJik Lee <jungjik.lee@samsung.com> - - [EFL][WK2] Add WebMemorySampler feature. - https://bugs.webkit.org/show_bug.cgi?id=91214 - - Reviewed by Kenneth Rohde Christiansen. +2012-10-08 Kiran Muppala <cmuppala@apple.com> - WebMemorySampler collects Javascript stack and JIT memory usage in globalMemoryStatistics. + Throttle DOM timers on hidden pages. + https://bugs.webkit.org/show_bug.cgi?id=98474 - * PlatformEfl.cmake: + Reviewed by Maciej Stachowiak. -2012-08-30 Benjamin Poulain <bpoulain@apple.com> + Add HIDDEN_PAGE_DOM_TIMER_THROTTLING feature define. - Replace JSC::UString by WTF::String - https://bugs.webkit.org/show_bug.cgi?id=95271 + * Configurations/FeatureDefines.xcconfig: - Reviewed by Geoffrey Garen. +2012-10-08 Michael Saboff <msaboff@apple.com> - Having JSC::UString and WTF::String increase the complexity of working on WebKit, and - add useless conversions in the bindings. It also cause some code bloat. + After r130344, OpaqueJSString() creates an empty string which should be a null string + https://bugs.webkit.org/show_bug.cgi?id=98417 - The performance advantages of UString have been ported over in previous patches. This patch - is the last step: getting rid of UString. + Reviewed by Sam Weinig. - In addition to the simplified code, this also reduce the binary size by 15kb on x86_64. + Changed create() of a null string to return 0. This is the same behavior as before r130344. * API/OpaqueJSString.cpp: - (OpaqueJSString::ustring): - * runtime/Identifier.h: - (JSC::Identifier::ustring): - To avoid changing everything at once, the function named ustring() were kept as is. They - will be renamed in a follow up patch. - - * runtime/JSString.h: - (JSC::JSString::string): - (JSC::JSValue::toWTFString): - (JSC::inlineJSValueNotStringtoString): - (JSC::JSValue::toWTFStringInline): - Since JSValue::toString() already exist (and return the JSString), the direct accessor is renamed - to ::toWTFString(). We may change ::string() to ::jsString() and ::toWTFString() to ::toString() - in the future. - - * runtime/StringPrototype.cpp: - (JSC::substituteBackreferencesSlow): Replace the use of UString::getCharacters<>() by String::getCharactersWithUpconvert<>(). - -2012-08-24 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove uses of ClassInfo in StrictEq and CompareEq in the DFG - https://bugs.webkit.org/show_bug.cgi?id=93401 - - Reviewed by Filip Pizlo. - - Another incremental step in removing the dependence on ClassInfo pointers in object headers. - - * bytecode/SpeculatedType.h: - (JSC::isCellOrOtherSpeculation): - (JSC): - * dfg/DFGAbstractState.cpp: Updated the CFA to reflect the changes to the backend. - (JSC::DFG::AbstractState::execute): - * dfg/DFGNode.h: - (Node): - (JSC::DFG::Node::shouldSpeculateString): Added this new function since it was conspicuously absent. - (JSC::DFG::Node::shouldSpeculateNonStringCellOrOther): Also add this function for use in the CFA. - * dfg/DFGSpeculativeJIT.cpp: Refactored how we handle CompareEq and CompareStrictEq in the DFG. We now just - check for Strings by comparing the object's Structure to the global Structure for strings. We only - check for MasqueradesAsUndefined if the watchpoint has fired. These changes allow us to remove our - uses of the ClassInfo pointer for compiling these nodes. - (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality): - (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch): - (JSC::DFG::SpeculativeJIT::compare): - (JSC::DFG::SpeculativeJIT::compileStrictEq): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: Same changes for 32 bit as for 64 bit. - (JSC::DFG::SpeculativeJIT::compileObjectEquality): - (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): - (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compileObjectEquality): - (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): - (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): - -2012-08-30 Yong Li <yoli@rim.com> - - [BlackBerry] Implement IncrementalSweeper for PLATFORM(BLACKBERRY) - https://bugs.webkit.org/show_bug.cgi?id=95469 - - Reviewed by Rob Buis. - - RIM PR# 200595. - Share most code with USE(CF) and implement timer-related methods - for PLATFORM(BLACKBERRY). - - * heap/IncrementalSweeper.cpp: - (JSC): - (JSC::IncrementalSweeper::IncrementalSweeper): - (JSC::IncrementalSweeper::create): - (JSC::IncrementalSweeper::scheduleTimer): - (JSC::IncrementalSweeper::cancelTimer): - (JSC::IncrementalSweeper::doSweep): - * heap/IncrementalSweeper.h: - (IncrementalSweeper): - -2012-08-30 Mark Lam <mark.lam@apple.com> - - Fix broken classic intrpreter build. - https://bugs.webkit.org/show_bug.cgi?id=95484. - - Reviewed by Filip Pizlo. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - -2012-08-30 Byungwoo Lee <bw80.lee@samsung.com> - - Build warning : -Wsign-compare on DFGByteCodeParser.cpp. - https://bugs.webkit.org/show_bug.cgi?id=95418 - - Reviewed by Filip Pizlo. - - There is a build warning '-Wsign-compare' on - findArgumentPositionForLocal() in DFGByteCodeParser.cpp. - - For removing this warning, casting statement is added explicitly. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::findArgumentPositionForLocal): - (JSC::DFG::ByteCodeParser::findArgumentPosition): - -2012-08-30 Yong Li <yoli@rim.com> - - [BlackBerry] Set timer client on platform timer used in HeapTimer - https://bugs.webkit.org/show_bug.cgi?id=95464 - - Reviewed by Rob Buis. - - Otherwise the timer won't work. - - * heap/HeapTimer.cpp: - (JSC::HeapTimer::HeapTimer): - -2012-08-30 Julien BRIANCEAU <jbrianceau@nds.com> - - [sh4] Add missing implementation for JavaScriptCore JIT - https://bugs.webkit.org/show_bug.cgi?id=95452 - - Reviewed by Oliver Hunt. - - * assembler/MacroAssemblerSH4.h: - (JSC::MacroAssemblerSH4::isCompactPtrAlignedAddressOffset): - (MacroAssemblerSH4): - (JSC::MacroAssemblerSH4::add32): - (JSC::MacroAssemblerSH4::convertibleLoadPtr): - * assembler/SH4Assembler.h: - (JSC::SH4Assembler::labelIgnoringWatchpoints): - (SH4Assembler): - (JSC::SH4Assembler::replaceWithLoad): - (JSC::SH4Assembler::replaceWithAddressComputation): - -2012-08-30 Charles Wei <charles.wei@torchmobile.com.cn> - - [BlackBerry] Eliminate build warnings - https://bugs.webkit.org/show_bug.cgi?id=95338 - - Reviewed by Filip Pizlo. - - static_cast to the same type to eliminate the build time warnings. - - * assembler/AssemblerBufferWithConstantPool.h: - (JSC::AssemblerBufferWithConstantPool::flushWithoutBarrier): - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::branch32): - -2012-08-29 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove use of ClassInfo from compileGetByValOnArguments and compileGetArgumentsLength - https://bugs.webkit.org/show_bug.cgi?id=95131 - - Reviewed by Filip Pizlo. - - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): We don't need this speculation check. We can replace it - with an assert to guarantee this. - -2012-08-29 Mark Lam <mark.lam@apple.com> - - Refactoring LLInt::Data. - https://bugs.webkit.org/show_bug.cgi?id=95316. - - Reviewed by Geoff Garen. - - This change allows its opcodeMap to be easily queried from any function - without needing to go through a GlobalData object. It also introduces - the LLInt::getCodePtr() methods that will be used by the LLInt C loop - later to redefine how llint symbols (opcodes and trampoline glue - labels) get resolved. - - * assembler/MacroAssemblerCodeRef.h: - (MacroAssemblerCodePtr): - (JSC::MacroAssemblerCodePtr::createLLIntCodePtr): - (MacroAssemblerCodeRef): - (JSC::MacroAssemblerCodeRef::createLLIntCodeRef): - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::adjustPCIfAtCallSite): - (JSC::CodeBlock::bytecodeOffset): - * bytecode/Opcode.h: - Remove the 'const' to simplify things and avoid having to do - additional casts and #ifdefs in many places. - * bytecode/ResolveGlobalStatus.cpp: - (JSC::computeForLLInt): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::generate): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::initialize): - * interpreter/Interpreter.h: - (Interpreter): - * jit/JITExceptions.cpp: - (JSC::genericThrow): - * llint/LLIntData.cpp: - (LLInt): - (JSC::LLInt::initialize): - * llint/LLIntData.h: - (JSC): - (LLInt): - (Data): - (JSC::LLInt::exceptionInstructions): - (JSC::LLInt::opcodeMap): - (JSC::LLInt::getOpcode): - (JSC::LLInt::getCodePtr): - (JSC::LLInt::Data::performAssertions): - * llint/LLIntExceptions.cpp: - (JSC::LLInt::returnToThrowForThrownException): - (JSC::LLInt::returnToThrow): - (JSC::LLInt::callToThrow): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - (JSC::LLInt::handleHostCall): - * runtime/InitializeThreading.cpp: - (JSC::initializeThreadingOnce): Initialize the singleton LLInt data. - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: - (JSGlobalData): Removed the now unneeded LLInt::Data instance in - JSGlobalData. - * runtime/JSValue.h: - (JSValue): - -2012-08-29 Gavin Barraclough <barraclough@apple.com> - - PutById uses DataLabel32, not DataLabelCompact - https://bugs.webkit.org/show_bug.cgi?id=95245 - - Reviewed by Geoff Garen. - - JIT::resetPatchPutById calls the the wrong thing on x86-64 – this is moot right now, - since they currently both do the same thing, but if we were to ever make compact mean - 8-bit this could be a real problem. Also, relying on the object still being in eax - on entry to the transition stub isn't very robust - added nonArgGPR1 to at least make - this explicit. - - * jit/JITPropertyAccess.cpp: - (JSC::JIT::emitSlow_op_put_by_id): - - copy regT0 to nonArgGPR1 - (JSC::JIT::privateCompilePutByIdTransition): - - DataLabelCompact -> DataLabel32 - (JSC::JIT::resetPatchPutById): - - reload regT0 from nonArgGPR1 - * jit/JSInterfaceJIT.h: - (JSInterfaceJIT): - - added nonArgGPR1 - -2012-08-28 Yong Li <yoli@rim.com> - - ExecutableAllocator should be destructed after Heap - https://bugs.webkit.org/show_bug.cgi?id=95244 - - Reviewed by Rob Buis. - - RIM PR# 199364. - Make ExecutableAllocator the first member in JSGlobalData. - Existing Web Worker tests can show the issue. - - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: - (JSGlobalData): - -2012-08-29 Geoffrey Garen <ggaren@apple.com> - - Try to fix the Windows build. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Export! - -2012-08-28 Geoffrey Garen <ggaren@apple.com> - - Introduced JSWithScope, making all scope objects subclasses of JSScope - https://bugs.webkit.org/show_bug.cgi?id=95295 - - Reviewed by Filip Pizlo. - - This is a step toward removing ScopeChainNode. With a uniform representation - for objects in the scope chain, we can move data from ScopeChainNode - into JSScope. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: Build! - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): Use an explicit JSWithScope object - for 'with' statements. Since 'with' can put any object in the scope - chain, we'll need an adapter object to hold the data ScopeChainNode - currently holds. - - (JSGlobalData): Support for JSWithScope. - - * runtime/JSScope.cpp: - (JSC::JSScope::objectAtScope): - * runtime/JSScope.h: Check for and unwrap JSWithScope. - - * runtime/JSType.h: Support for JSWithScope. - - * runtime/StrictEvalActivation.cpp: - (JSC::StrictEvalActivation::StrictEvalActivation): - * runtime/StrictEvalActivation.h: - (StrictEvalActivation): Inherit from JSScope, to make the scope chain uniform. - - * runtime/JSWithScope.cpp: Added. - (JSC::JSWithScope::visitChildren): - * runtime/JSWithScope.h: Added. - (JSWithScope): - (JSC::JSWithScope::create): - (JSC::JSWithScope::object): - (JSC::JSWithScope::createStructure): - (JSC::JSWithScope::JSWithScope): New adapter object. Since this object - is never exposed to scripts, it doesn't need any meaningful implementation - of property access or other callbacks. - -2012-08-29 Patrick Gansterer <paroga@webkit.org> - - Unreviewed. Build fix for !ENABLE(JIT) after r126962. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): + (OpaqueJSString::create): -2012-08-28 Geoffrey Garen <ggaren@apple.com> - - Added JSScope::objectInScope(), and refactored callers to use it - https://bugs.webkit.org/show_bug.cgi?id=95281 - - Reviewed by Gavin Barraclough. - - This is a step toward removing ScopeChainNode. We need a layer of - indirection so that 'with' scopes can proxy for an object. - JSScope::objectInScope() will be that layer. - - * bytecode/EvalCodeCache.h: - (JSC::EvalCodeCache::tryGet): - (JSC::EvalCodeCache::getSlow): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::resolve): - (JSC::BytecodeGenerator::resolveConstDecl): . vs -> - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::unwindCallFrame): - (JSC::Interpreter::execute): - * runtime/JSScope.cpp: - (JSC::JSScope::resolve): - (JSC::JSScope::resolveSkip): - (JSC::JSScope::resolveGlobalDynamic): - (JSC::JSScope::resolveBase): - (JSC::JSScope::resolveWithBase): - (JSC::JSScope::resolveWithThis): Added JSScope::objectAtScope() calls. - - * runtime/JSScope.h: - (JSScope): - (JSC::JSScope::objectAtScope): - (JSC): - (ScopeChainIterator): - (JSC::ScopeChainIterator::ScopeChainIterator): - (JSC::ScopeChainIterator::get): - (JSC::ScopeChainIterator::operator->): - (JSC::ScopeChainIterator::operator++): - (JSC::ScopeChainIterator::operator==): - (JSC::ScopeChainIterator::operator!=): - (JSC::ScopeChainNode::begin): - (JSC::ScopeChainNode::end): I moved ScopeChainIterator to this file - to resolve a circular #include problem. Eventually, I'll probably rename - it to JSScope::iterator, so I think it belongs here. - - * runtime/ScopeChain.cpp: - (JSC::ScopeChainNode::print): - (JSC::ScopeChainNode::localDepth): . vs -> - - * runtime/ScopeChain.h: - (ScopeChainNode): I made the 'object' data member private because it's - no longer safe to access -- you need to call JSScope::objectAtScope() - instead. - - The JITs need to be friends because of the private declaration. - - Subtly, JIT/LLInt code is correct without any changes because JIT/LLInt - code never compiles direct access to a with scope. - -2012-08-28 Mark Lam <mark.lam@apple.com> - - Adding support for adding LLInt opcode extensions. This will be needed - by the LLInt C loop interpreter later. - https://bugs.webkit.org/show_bug.cgi?id=95277. - - Reviewed by Geoffrey Garen. - - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/Opcode.h: - * llint/LLIntOpcode.h: Added. - * llint/LowLevelInterpreter.h: - -2012-08-28 Gavin Barraclough <barraclough@apple.com> - - Rolled out r126928, this broke stuff :'-( - - * jit/JITPropertyAccess.cpp: - (JSC::JIT::privateCompilePutByIdTransition): - (JSC::JIT::resetPatchPutById): - -2012-08-28 Gavin Barraclough <barraclough@apple.com> - - PutById uses DataLabel32, not DataLabelCompact - https://bugs.webkit.org/show_bug.cgi?id=95245 - - Reviewed by Geoff Garen. - - JIT::resetPatchPutById calls the the wrong thing on x86-64 – this is moot right now, - since they currently both do the same thing, but if we were to ever make compact mean - 8-bit this could be a real problem. Also, don't rely on the object still being in eax - on entry to the transition stub – this isn't very robust. - - * jit/JITPropertyAccess.cpp: - (JSC::JIT::privateCompilePutByIdTransition): - - DataLabelCompact -> DataLabel32 - (JSC::JIT::resetPatchPutById): - - reload regT0 from the stack - -2012-08-28 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r126914. - http://trac.webkit.org/changeset/126914 - https://bugs.webkit.org/show_bug.cgi?id=95239 - - it breaks everything and fixes nothing (Requested by pizlo on - #webkit). - - * API/JSCallbackObject.h: - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty): - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): - * API/JSCallbackObjectFunctions.h: - (JSC::::getOwnPropertyNames): - * API/JSClassRef.cpp: - (OpaqueJSClass::~OpaqueJSClass): - (OpaqueJSClassContextData::OpaqueJSClassContextData): - (OpaqueJSClass::contextData): - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - (JSC::EvalCodeCache::visitAggregate): - (JSC::CodeBlock::nameForRegister): - * bytecode/JumpTable.h: - (JSC::StringJumpTable::offsetForValue): - (JSC::StringJumpTable::ctiForValue): - * bytecode/LazyOperandValueProfile.cpp: - (JSC::LazyOperandValueProfileParser::getIfPresent): - * bytecode/SamplingTool.cpp: - (JSC::SamplingTool::dump): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::addVar): - (JSC::BytecodeGenerator::addGlobalVar): - (JSC::BytecodeGenerator::addConstant): - (JSC::BytecodeGenerator::addConstantValue): - (JSC::BytecodeGenerator::emitLoad): - (JSC::BytecodeGenerator::addStringConstant): - (JSC::BytecodeGenerator::emitLazyNewFunction): - * bytecompiler/NodesCodegen.cpp: - (JSC::PropertyListNode::emitBytecode): - * debugger/Debugger.cpp: - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): - (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): - (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): - (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild): - * dfg/DFGAssemblyHelpers.cpp: - (JSC::DFG::AssemblyHelpers::decodedCodeMapFor): - * dfg/DFGByteCodeCache.h: - (JSC::DFG::ByteCodeCache::~ByteCodeCache): - (JSC::DFG::ByteCodeCache::get): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::cellConstant): - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): - (JSC::DFG::StructureCheckHoistingPhase::noticeClobber): - * heap/Heap.cpp: - (JSC::Heap::markProtectedObjects): - * heap/Heap.h: - (JSC::Heap::forEachProtectedCell): - * heap/JITStubRoutineSet.cpp: - (JSC::JITStubRoutineSet::markSlow): - (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): - * heap/MarkStack.cpp: - (JSC::MarkStack::internalAppend): - * heap/Weak.h: - (JSC::weakRemove): - * jit/JIT.cpp: - (JSC::JIT::privateCompile): - * jit/JITStubs.cpp: - (JSC::JITThunks::ctiStub): - * parser/Parser.cpp: - (JSC::::parseStrictObjectLiteral): - * profiler/Profile.cpp: - (JSC::functionNameCountPairComparator): - (JSC::Profile::debugPrintDataSampleStyle): - * runtime/Identifier.cpp: - (JSC::Identifier::add): - * runtime/JSActivation.cpp: - (JSC::JSActivation::getOwnPropertyNames): - (JSC::JSActivation::symbolTablePutWithAttributes): - * runtime/JSArray.cpp: - (JSC::SparseArrayValueMap::put): - (JSC::SparseArrayValueMap::putDirect): - (JSC::SparseArrayValueMap::visitChildren): - (JSC::JSArray::enterDictionaryMode): - (JSC::JSArray::defineOwnNumericProperty): - (JSC::JSArray::getOwnPropertySlotByIndex): - (JSC::JSArray::getOwnPropertyDescriptor): - (JSC::JSArray::putByIndexBeyondVectorLength): - (JSC::JSArray::putDirectIndexBeyondVectorLength): - (JSC::JSArray::deletePropertyByIndex): - (JSC::JSArray::getOwnPropertyNames): - (JSC::JSArray::setLength): - (JSC::JSArray::sort): - (JSC::JSArray::compactForSorting): - (JSC::JSArray::checkConsistency): - * runtime/JSSymbolTableObject.cpp: - (JSC::JSSymbolTableObject::getOwnPropertyNames): - * runtime/JSSymbolTableObject.h: - (JSC::symbolTableGet): - (JSC::symbolTablePut): - (JSC::symbolTablePutWithAttributes): - * runtime/RegExpCache.cpp: - (JSC::RegExpCache::invalidateCode): - * runtime/WeakGCMap.h: - (JSC::WeakGCMap::clear): - (JSC::WeakGCMap::set): - * tools/ProfileTreeNode.h: - (JSC::ProfileTreeNode::sampleChild): - (JSC::ProfileTreeNode::childCount): - (JSC::ProfileTreeNode::dumpInternal): - (JSC::ProfileTreeNode::compareEntries): - -2012-08-28 Filip Pizlo <fpizlo@apple.com> - - LLInt should not rely on ordering of global labels - https://bugs.webkit.org/show_bug.cgi?id=95221 - - Reviewed by Oliver Hunt. - - * llint/LowLevelInterpreter.asm: - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-08-28 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> +2012-10-07 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> Rename first/second to key/value in HashMap iterators https://bugs.webkit.org/show_bug.cgi?id=82784 @@ -5987,266 +2403,7 @@ (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): * API/JSCallbackObjectFunctions.h: - (JSC::::getOwnPropertyNames): - * API/JSClassRef.cpp: - (OpaqueJSClass::~OpaqueJSClass): - (OpaqueJSClassContextData::OpaqueJSClassContextData): - (OpaqueJSClass::contextData): - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - (JSC::EvalCodeCache::visitAggregate): - (JSC::CodeBlock::nameForRegister): - * bytecode/JumpTable.h: - (JSC::StringJumpTable::offsetForValue): - (JSC::StringJumpTable::ctiForValue): - * bytecode/LazyOperandValueProfile.cpp: - (JSC::LazyOperandValueProfileParser::getIfPresent): - * bytecode/SamplingTool.cpp: - (JSC::SamplingTool::dump): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::addVar): - (JSC::BytecodeGenerator::addGlobalVar): - (JSC::BytecodeGenerator::addConstant): - (JSC::BytecodeGenerator::addConstantValue): - (JSC::BytecodeGenerator::emitLoad): - (JSC::BytecodeGenerator::addStringConstant): - (JSC::BytecodeGenerator::emitLazyNewFunction): - * bytecompiler/NodesCodegen.cpp: - (JSC::PropertyListNode::emitBytecode): - * debugger/Debugger.cpp: - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): - (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): - (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): - (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild): - * dfg/DFGAssemblyHelpers.cpp: - (JSC::DFG::AssemblyHelpers::decodedCodeMapFor): - * dfg/DFGByteCodeCache.h: - (JSC::DFG::ByteCodeCache::~ByteCodeCache): - (JSC::DFG::ByteCodeCache::get): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::cellConstant): - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): - (JSC::DFG::StructureCheckHoistingPhase::noticeClobber): - * heap/Heap.cpp: - (JSC::Heap::markProtectedObjects): - * heap/Heap.h: - (JSC::Heap::forEachProtectedCell): - * heap/JITStubRoutineSet.cpp: - (JSC::JITStubRoutineSet::markSlow): - (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): - * heap/MarkStack.cpp: - (JSC::MarkStack::internalAppend): - * heap/Weak.h: - (JSC::weakRemove): - * jit/JIT.cpp: - (JSC::JIT::privateCompile): - * jit/JITStubs.cpp: - (JSC::JITThunks::ctiStub): - * parser/Parser.cpp: - (JSC::::parseStrictObjectLiteral): - * profiler/Profile.cpp: - (JSC::functionNameCountPairComparator): - (JSC::Profile::debugPrintDataSampleStyle): - * runtime/Identifier.cpp: - (JSC::Identifier::add): - * runtime/JSActivation.cpp: - (JSC::JSActivation::getOwnPropertyNames): - (JSC::JSActivation::symbolTablePutWithAttributes): - * runtime/JSArray.cpp: - (JSC::SparseArrayValueMap::put): - (JSC::SparseArrayValueMap::putDirect): - (JSC::SparseArrayValueMap::visitChildren): - (JSC::JSArray::enterDictionaryMode): - (JSC::JSArray::defineOwnNumericProperty): - (JSC::JSArray::getOwnPropertySlotByIndex): - (JSC::JSArray::getOwnPropertyDescriptor): - (JSC::JSArray::putByIndexBeyondVectorLength): - (JSC::JSArray::putDirectIndexBeyondVectorLength): - (JSC::JSArray::deletePropertyByIndex): - (JSC::JSArray::getOwnPropertyNames): - (JSC::JSArray::setLength): - (JSC::JSArray::sort): - (JSC::JSArray::compactForSorting): - (JSC::JSArray::checkConsistency): - * runtime/JSSymbolTableObject.cpp: - (JSC::JSSymbolTableObject::getOwnPropertyNames): - * runtime/JSSymbolTableObject.h: - (JSC::symbolTableGet): - (JSC::symbolTablePut): - (JSC::symbolTablePutWithAttributes): - * runtime/RegExpCache.cpp: - (JSC::RegExpCache::invalidateCode): - * runtime/WeakGCMap.h: - (JSC::WeakGCMap::clear): - (JSC::WeakGCMap::set): - * tools/ProfileTreeNode.h: - (JSC::ProfileTreeNode::sampleChild): - (JSC::ProfileTreeNode::childCount): - (JSC::ProfileTreeNode::dumpInternal): - (JSC::ProfileTreeNode::compareEntries): - -2012-08-28 Geoffrey Garen <ggaren@apple.com> - - GCC warning in JSActivation is causing Mac EWS errors - https://bugs.webkit.org/show_bug.cgi?id=95103 - - Reviewed by Sam Weinig. - - Try to fix a strict aliasing violation by using bitwise_cast. The - union in the cast should signal to the compiler that aliasing between - types is happening. - - * runtime/JSActivation.cpp: - (JSC::JSActivation::visitChildren): - -2012-08-28 Geoffrey Garen <ggaren@apple.com> - - Build fix: svn add two files I forgot in my last patch. - -2012-08-27 Geoffrey Garen <ggaren@apple.com> - - Refactored and consolidated variable resolution functions - https://bugs.webkit.org/show_bug.cgi?id=95166 - - Reviewed by Filip Pizlo. - - This patch does a few things: - - (1) Introduces a new class, JSScope, which is the base class for all - objects that represent a scope in the scope chain. - - (2) Refactors and consolidates duplicate implementations of variable - resolution into the JSScope class. - - (3) Renames JSStaticScopeObject to JSNameScope because, as distinct from - something like a 'let' scope, JSStaticScopeObject only has storage for a - single name. - - These changes makes logical sense to me as-is. I will also use them in an - upcoming optimization. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: Build! - - * bytecode/CodeBlock.cpp: - (JSC): Build fix for LLInt-only builds. - - * bytecode/GlobalResolveInfo.h: - (GlobalResolveInfo): Use PropertyOffset to be consistent with other parts - of the engine. - - * bytecompiler/NodesCodegen.cpp: - * dfg/DFGOperations.cpp: Use the shared code in JSScope instead of rolling - our own. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::execute): - (JSC::Interpreter::createExceptionScope): - (JSC::Interpreter::privateExecute): - * interpreter/Interpreter.h: Use the shared code in JSScope instead of rolling - our own. - - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): Use the shared code in JSScope instead of rolling - our own. - - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - (LLInt): Use the shared code in JSScope instead of rolling our own. Note - that one of these slow paths calls the wrong helper function. I left it - that way to avoid a behavior change in a refactoring patch. - - * parser/Nodes.cpp: Updated for rename. - - * runtime/CommonSlowPaths.h: - (CommonSlowPaths): Removed resolve slow paths because were duplicative. - - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: - (JSGlobalData): Updated for renames. - - * runtime/JSNameScope.cpp: Copied from Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp. - (JSC): - (JSC::JSNameScope::visitChildren): - (JSC::JSNameScope::toThisObject): - (JSC::JSNameScope::put): - (JSC::JSNameScope::getOwnPropertySlot): - * runtime/JSNameScope.h: Copied from Source/JavaScriptCore/runtime/JSStaticScopeObject.h. - (JSC): - (JSC::JSNameScope::create): - (JSC::JSNameScope::createStructure): - (JSNameScope): - (JSC::JSNameScope::JSNameScope): - (JSC::JSNameScope::isDynamicScope): Used do-webcore-rename script here. - It is fabulous! - - * runtime/JSObject.h: - (JSObject): - (JSC::JSObject::isNameScopeObject): More rename. - - * runtime/JSScope.cpp: Added. - (JSC): - (JSC::JSScope::isDynamicScope): - (JSC::JSScope::resolve): - (JSC::JSScope::resolveSkip): - (JSC::JSScope::resolveGlobal): - (JSC::JSScope::resolveGlobalDynamic): - (JSC::JSScope::resolveBase): - (JSC::JSScope::resolveWithBase): - (JSC::JSScope::resolveWithThis): - * runtime/JSScope.h: Added. - (JSC): - (JSScope): - (JSC::JSScope::JSScope): All the code here is a port from the - Interpreter.cpp implementations of this functionality. - - * runtime/JSStaticScopeObject.cpp: Removed. - * runtime/JSStaticScopeObject.h: Removed. - - * runtime/JSSymbolTableObject.cpp: - (JSC): - * runtime/JSSymbolTableObject.h: - (JSSymbolTableObject): - * runtime/JSType.h: Updated for rename. - - * runtime/Operations.h: - (JSC::resolveBase): Removed because it was duplicative. - -2012-08-28 Alban Browaeys <prahal@yahoo.com> - - [GTK] LLint build fails with -g -02 - https://bugs.webkit.org/show_bug.cgi?id=90098 - - Reviewed by Filip Pizlo. - - Avoid duplicate offsets for llint, discarding them. - - * offlineasm/offsets.rb: - -2012-08-27 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r126836. - http://trac.webkit.org/changeset/126836 - https://bugs.webkit.org/show_bug.cgi?id=95163 - - Broke all Apple ports, EFL, and Qt. (Requested by tkent on - #webkit). - - * API/JSCallbackObject.h: - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty): - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): - * API/JSCallbackObjectFunctions.h: - (JSC::::getOwnPropertyNames): + (JSC::::getOwnNonIndexPropertyNames): * API/JSClassRef.cpp: (OpaqueJSClass::~OpaqueJSClass): (OpaqueJSClassContextData::OpaqueJSClassContextData): @@ -6298,8 +2455,8 @@ * heap/JITStubRoutineSet.cpp: (JSC::JITStubRoutineSet::markSlow): (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): - * heap/MarkStack.cpp: - (JSC::MarkStack::internalAppend): + * heap/SlotVisitor.cpp: + (JSC::SlotVisitor::internalAppend): * heap/Weak.h: (JSC::weakRemove): * jit/JIT.cpp: @@ -6314,147 +2471,32 @@ * runtime/Identifier.cpp: (JSC::Identifier::add): * runtime/JSActivation.cpp: - (JSC::JSActivation::getOwnPropertyNames): + (JSC::JSActivation::getOwnNonIndexPropertyNames): (JSC::JSActivation::symbolTablePutWithAttributes): * runtime/JSArray.cpp: - (JSC::SparseArrayValueMap::put): - (JSC::SparseArrayValueMap::putDirect): - (JSC::SparseArrayValueMap::visitChildren): - (JSC::JSArray::enterDictionaryMode): - (JSC::JSArray::defineOwnNumericProperty): - (JSC::JSArray::getOwnPropertySlotByIndex): - (JSC::JSArray::getOwnPropertyDescriptor): - (JSC::JSArray::putByIndexBeyondVectorLength): - (JSC::JSArray::putDirectIndexBeyondVectorLength): - (JSC::JSArray::deletePropertyByIndex): - (JSC::JSArray::getOwnPropertyNames): (JSC::JSArray::setLength): - (JSC::JSArray::sort): - (JSC::JSArray::compactForSorting): - (JSC::JSArray::checkConsistency): + * runtime/JSObject.cpp: + (JSC::JSObject::getOwnPropertySlotByIndex): + (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists): + (JSC::JSObject::deletePropertyByIndex): + (JSC::JSObject::getOwnPropertyNames): + (JSC::JSObject::defineOwnIndexedProperty): + (JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype): + (JSC::JSObject::putByIndexBeyondVectorLengthWithArrayStorage): + (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage): + (JSC::JSObject::getOwnPropertyDescriptor): * runtime/JSSymbolTableObject.cpp: - (JSC::JSSymbolTableObject::getOwnPropertyNames): + (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames): * runtime/JSSymbolTableObject.h: (JSC::symbolTableGet): (JSC::symbolTablePut): (JSC::symbolTablePutWithAttributes): * runtime/RegExpCache.cpp: (JSC::RegExpCache::invalidateCode): - * runtime/WeakGCMap.h: - (JSC::WeakGCMap::clear): - (JSC::WeakGCMap::set): - * tools/ProfileTreeNode.h: - (JSC::ProfileTreeNode::sampleChild): - (JSC::ProfileTreeNode::childCount): - (JSC::ProfileTreeNode::dumpInternal): - (JSC::ProfileTreeNode::compareEntries): - -2012-08-27 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> - - Rename first/second to key/value in HashMap iterators - https://bugs.webkit.org/show_bug.cgi?id=82784 - - Reviewed by Eric Seidel. - - * API/JSCallbackObject.h: - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty): - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): - * API/JSCallbackObjectFunctions.h: - (JSC::::getOwnPropertyNames): - * API/JSClassRef.cpp: - (OpaqueJSClass::~OpaqueJSClass): - (OpaqueJSClassContextData::OpaqueJSClassContextData): - (OpaqueJSClass::contextData): - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - (JSC::EvalCodeCache::visitAggregate): - (JSC::CodeBlock::nameForRegister): - * bytecode/JumpTable.h: - (JSC::StringJumpTable::offsetForValue): - (JSC::StringJumpTable::ctiForValue): - * bytecode/LazyOperandValueProfile.cpp: - (JSC::LazyOperandValueProfileParser::getIfPresent): - * bytecode/SamplingTool.cpp: - (JSC::SamplingTool::dump): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::addVar): - (JSC::BytecodeGenerator::addGlobalVar): - (JSC::BytecodeGenerator::addConstant): - (JSC::BytecodeGenerator::addConstantValue): - (JSC::BytecodeGenerator::emitLoad): - (JSC::BytecodeGenerator::addStringConstant): - (JSC::BytecodeGenerator::emitLazyNewFunction): - * bytecompiler/NodesCodegen.cpp: - (JSC::PropertyListNode::emitBytecode): - * debugger/Debugger.cpp: - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): - (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): - (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): - (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild): - * dfg/DFGAssemblyHelpers.cpp: - (JSC::DFG::AssemblyHelpers::decodedCodeMapFor): - * dfg/DFGByteCodeCache.h: - (JSC::DFG::ByteCodeCache::~ByteCodeCache): - (JSC::DFG::ByteCodeCache::get): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::cellConstant): - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): - (JSC::DFG::StructureCheckHoistingPhase::noticeClobber): - * heap/Heap.cpp: - (JSC::Heap::markProtectedObjects): - * heap/Heap.h: - (JSC::Heap::forEachProtectedCell): - * heap/JITStubRoutineSet.cpp: - (JSC::JITStubRoutineSet::markSlow): - (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): - * heap/MarkStack.cpp: - (JSC::MarkStack::internalAppend): - * heap/Weak.h: - (JSC::weakRemove): - * jit/JIT.cpp: - (JSC::JIT::privateCompile): - * jit/JITStubs.cpp: - (JSC::JITThunks::ctiStub): - * parser/Parser.cpp: - (JSC::::parseStrictObjectLiteral): - * profiler/Profile.cpp: - (JSC::functionNameCountPairComparator): - (JSC::Profile::debugPrintDataSampleStyle): - * runtime/Identifier.cpp: - (JSC::Identifier::add): - * runtime/JSActivation.cpp: - (JSC::JSActivation::getOwnPropertyNames): - (JSC::JSActivation::symbolTablePutWithAttributes): - * runtime/JSArray.cpp: - (JSC::SparseArrayValueMap::put): + * runtime/SparseArrayValueMap.cpp: + (JSC::SparseArrayValueMap::putEntry): (JSC::SparseArrayValueMap::putDirect): (JSC::SparseArrayValueMap::visitChildren): - (JSC::JSArray::enterDictionaryMode): - (JSC::JSArray::defineOwnNumericProperty): - (JSC::JSArray::getOwnPropertySlotByIndex): - (JSC::JSArray::getOwnPropertyDescriptor): - (JSC::JSArray::putByIndexBeyondVectorLength): - (JSC::JSArray::putDirectIndexBeyondVectorLength): - (JSC::JSArray::deletePropertyByIndex): - (JSC::JSArray::getOwnPropertyNames): - (JSC::JSArray::setLength): - (JSC::JSArray::sort): - (JSC::JSArray::compactForSorting): - (JSC::JSArray::checkConsistency): - * runtime/JSSymbolTableObject.cpp: - (JSC::JSSymbolTableObject::getOwnPropertyNames): - * runtime/JSSymbolTableObject.h: - (JSC::symbolTableGet): - (JSC::symbolTablePut): - (JSC::symbolTablePutWithAttributes): - * runtime/RegExpCache.cpp: - (JSC::RegExpCache::invalidateCode): * runtime/WeakGCMap.h: (JSC::WeakGCMap::clear): (JSC::WeakGCMap::set): @@ -6464,13995 +2506,445 @@ (JSC::ProfileTreeNode::dumpInternal): (JSC::ProfileTreeNode::compareEntries): -2012-08-27 Filip Pizlo <fpizlo@apple.com> - - Structure check hoisting should abstain if the OSR entry's must-handle value for the respective variable has a different structure - https://bugs.webkit.org/show_bug.cgi?id=95141 - <rdar://problem/12170401> - - Reviewed by Mark Hahnenberg. - - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - -2012-08-27 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove use of ClassInfo from SpeculativeJIT::compileGetByValOnArguments - https://bugs.webkit.org/show_bug.cgi?id=95131 - - Reviewed by Filip Pizlo. - - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): We don't need this speculation check. We can replace it - with an assert to guarantee this. - -2012-08-27 Oliver Hunt <oliver@apple.com> - - Remove opcode definition autogen for now - https://bugs.webkit.org/show_bug.cgi?id=95148 - - Reviewed by Mark Hahnenberg. - - This isn't worth doing at the moment. - - * DerivedSources.make: - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecode/OpcodeDefinitions.h: Removed. - * bytecode/opcodes: Removed. - * opcode_definition_generator.py: Removed. - * opcode_generator.py: Removed. - * opcode_parser.py: Removed. - -2012-08-27 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove uses of TypedArray ClassInfo from SpeculativeJIT::checkArgumentTypes - https://bugs.webkit.org/show_bug.cgi?id=95112 - - Reviewed by Filip Pizlo. - - Removing these checks since we no longer need them. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::initialize): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::checkArgumentTypes): - -2012-08-27 Benjamin Poulain <benjamin@webkit.org> - - Add ECMAScript Number to String conversion to WTF::String - https://bugs.webkit.org/show_bug.cgi?id=95016 - - Reviewed by Geoffrey Garen. - - Rename UString::number(double) to UString::numberToStringECMAScript(double) to - differenciate it from the fixed-width conversion performed by String::number(). - - * parser/ParserArena.h: - (JSC::IdentifierArena::makeNumericIdentifier): - * runtime/JSONObject.cpp: - (JSC::Stringifier::appendStringifiedValue): - * runtime/NumberPrototype.cpp: - (JSC::numberProtoFuncToExponential): - (JSC::numberProtoFuncToFixed): - (JSC::numberProtoFuncToPrecision): - (JSC::numberProtoFuncToString): - * runtime/NumericStrings.h: - (JSC::NumericStrings::add): - * runtime/UString.cpp: - (JSC::UString::numberToStringECMAScript): - * runtime/UString.h: - (UString): - -2012-08-27 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com> - - Rename RegisterProtocolHandler API to NavigatorContentUtils - https://bugs.webkit.org/show_bug.cgi?id=94920 - - Reviewed by Adam Barth. - - ENABLE_REGISTER_PROTOCOL_HANDLER is renamed to ENABLE_NAVIGATOR_CONTENT_UTILS. - - * Configurations/FeatureDefines.xcconfig: - -2012-08-26 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, fix for builds without VALUE_PROFILING. I had forgotten that shouldEmitProfiling() - is designed to return true if DFG_JIT is disabled. I should be using canBeOptimized() instead. - - * jit/JITCall.cpp: - (JSC::JIT::compileOpCall): - * jit/JITCall32_64.cpp: - (JSC::JIT::compileOpCall): - -2012-08-26 Geoffrey Garen <ggaren@apple.com> - - Don't allocate space for arguments and call frame if arguments aren't captured - https://bugs.webkit.org/show_bug.cgi?id=95024 - - Reviewed by Phil Pizlo. - - 27% on v8-real-earley. - - * runtime/JSActivation.h: - (JSC::JSActivation::registerOffset): The offset is zero if we're skipping - the arguments and call frame because "offset" means space reserved for - those things. - - (JSC::JSActivation::tearOff): Don't copy the scope chain and callee. We - don't need them for anything, and we're no longer guaranteed to have - space for them. - -2012-08-26 Geoffrey Garen <ggaren@apple.com> - - Removed the NULL checks from visitChildren functions - https://bugs.webkit.org/show_bug.cgi?id=95021 - - Reviewed by Oliver Hunt. - - As of http://trac.webkit.org/changeset/126624, all values are NULL-checked - during GC, so explicit NULL checks aren't needed anymore. - -2011-08-26 Geoffrey Garen <ggaren@apple.com> - - Removed a JSC-specific hack from the web inspector - https://bugs.webkit.org/show_bug.cgi?id=95033 - - Reviewed by Filip Pizlo. - - Added support for what the web inspector really wanted instead. - - * runtime/JSActivation.cpp: - (JSC::JSActivation::symbolTableGet): - (JSC::JSActivation::symbolTablePut): Added some explanation for these - checks, which were non-obvious to me. - - (JSC::JSActivation::getOwnPropertySlot): It's impossible to access the - arguments property of an activation after it's been torn off, since the - only way to tear off an activation is to instantiate a new function, - which has its own arguments property in scope. However, the inspector - get special access to activations, and may try to perform this access, - so we need a special guard to maintain coherence and avoid crashing in - case the activation optimized out the arguments property. - - * runtime/JSActivation.cpp: - (JSC::JSActivation::symbolTableGet): - (JSC::JSActivation::symbolTablePut): - (JSC::JSActivation::getOwnPropertyNames): - (JSC::JSActivation::getOwnPropertyDescriptor): Provide getOwnPropertyNames - and getOwnPropertyDescriptor implementations, to meet the web inspector's - needs. (User code can never call these.) - -2012-08-24 Filip Pizlo <fpizlo@apple.com> - - Finally inlining should correctly track the catch context - https://bugs.webkit.org/show_bug.cgi?id=94986 - <rdar://problem/11753784> - - Reviewed by Sam Weinig. - - This fixes two behaviors: - - 1) Throwing from a finally block. Previously, we would seem to reenter the finally - block - though only once. - - 2) Executing a finally block from some nested context, for example due to a - 'continue', 'break', or 'return' in the try. This would execute the finally - block in the context of of the try block, which could lead to either scope depth - mismatches or reexecutions of the finally block on throw, similarly to (1) but - for different reasons. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC): - (JSC::BytecodeGenerator::pushFinallyContext): - (JSC::BytecodeGenerator::emitComplexJumpScopes): - (JSC::BytecodeGenerator::pushTry): - (JSC::BytecodeGenerator::popTryAndEmitCatch): - * bytecompiler/BytecodeGenerator.h: - (FinallyContext): - (TryData): - (JSC): - (TryContext): - (TryRange): - (BytecodeGenerator): - * bytecompiler/NodesCodegen.cpp: - (JSC::TryNode::emitBytecode): - -2012-08-26 Filip Pizlo <fpizlo@apple.com> - - Array type checks and storage accesses should be uniformly represented and available to CSE - https://bugs.webkit.org/show_bug.cgi?id=95013 - - Reviewed by Oliver Hunt. - - This uniformly breaks up all array accesses into up to three parts: - - 1) The type check, using a newly introduced CheckArray node, in addition to possibly - a CheckStructure node. We were already inserting the CheckStructure prior to this - patch. The CheckArray node will be automatically eliminated if the thing it was - checking for had already been checked for, either intentionally (a CheckStructure - inserted based on the array profile of this access) or accidentally (some checks, - typically a CheckStructure, inserted for some unrelated operations). The - CheckArray node may not be inserted if the array type is non-specific (Generic or - ForceExit). - - 2) The storage load using GetIndexedPropertyStorage. Previously, this only worked for - GetByVal. Now it works for all array accesses. The storage load may not be - inserted if the mode of array access does not permit CSE of storage loads (like - non-specific modes or Arguments). - - 3) The access itself: one of GetByVal, PutByVal, PutByValAlias, ArrayPush, ArrayPop, - GetArrayLength, StringCharAt, or StringCharCodeAt. - - This means that the type check can be subjected to CSE even if the CFA isn't smart - enough to reason about it (yet!). It also means that the storage load can always be - subjected to CSE; previously CSE on storage load only worked for array loads and not - other forms of access. Finally, it removes the bizarre behavior that - GetIndexedPropertyStorage previously had: previously, it was responsible for the type - check in some cases, but not others; this made reasoning about the CFA really - confusing. - - This change also disables late refinement of array mode, since I decided that - supporting that feature is both confusing and likely unprofitable. The array modes are - now locked in in the first fixup run after prediction propagation. Of course, - refinements from Generic to something else would not have been a problem; we could - reenable those if we thought we really needed to. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - * dfg/DFGArrayMode.cpp: - (JSC::DFG::fromStructure): - (DFG): - (JSC::DFG::refineArrayMode): - * dfg/DFGArrayMode.h: - (DFG): - (JSC::DFG::modeIsJSArray): - (JSC::DFG::lengthNeedsStorage): - (JSC::DFG::modeIsSpecific): - (JSC::DFG::modeSupportsLength): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::ByteCodeParser): - (JSC::DFG::ByteCodeParser::getArrayMode): - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks): - (JSC::DFG::ByteCodeParser::handleIntrinsic): - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::mergeBlocks): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::CSEPhase): - (JSC::DFG::CSEPhase::checkStructureElimination): - (CSEPhase): - (JSC::DFG::CSEPhase::checkArrayElimination): - (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - (JSC::DFG::performCSE): - * dfg/DFGCSEPhase.h: - (DFG): - * dfg/DFGCommon.h: - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::foldConstants): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - (JSC::DFG::FixupPhase::checkArray): - (FixupPhase): - (JSC::DFG::FixupPhase::blessArrayOperation): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::Graph): - (DFG): - (JSC::DFG::Graph::dump): - (JSC::DFG::Graph::collectGarbage): - * dfg/DFGGraph.h: - (Graph): - (JSC::DFG::Graph::vote): - (JSC::DFG::Graph::substitute): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasArrayMode): - (JSC::DFG::Node::setArrayMode): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOperations.cpp: - * dfg/DFGPhase.h: - (DFG): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - (JSC::DFG::PredictionPropagationPhase::mergeDefaultFlags): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::checkArray): - (JSC::DFG::SpeculativeJIT::useChildren): - (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): - (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray): - (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): - (JSC::DFG::SpeculativeJIT::compileGetArrayLength): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - -2012-08-26 Filip Pizlo <fpizlo@apple.com> - - DFGGraph.h has a bogus comment about the nature of StorageAccessData - https://bugs.webkit.org/show_bug.cgi?id=95035 - - Reviewed by Oliver Hunt. - - The comment is both wrong (storage access instructions don't reference CheckStructure) - and highly redundant: of course it's the case that two structures may have the same - identifier. Our interference analyses currently don't care about this and make the - conservative assumptions when necessary (same identifier, same object -> must be same - property; same identifier, may be same object -> may be the same property). Better to - remove the bogus comment since the code that operates over this data structure is - fairly self-explanatory already. - - * dfg/DFGGraph.h: - (StorageAccessData): - -2012-08-25 Geoffrey Garen <ggaren@apple.com> - - Try a little harder to fix the Linux build. - - * runtime/JSActivation.cpp: - * runtime/JSActivation.h: - -2012-08-25 Geoffrey Garen <ggaren@apple.com> - - Try to fix the Linux build. - - * runtime/JSActivation.cpp: - -2012-08-25 Geoffrey Garen <ggaren@apple.com> - - Don't use malloc / destructors for activation objects - https://bugs.webkit.org/show_bug.cgi?id=94897 - - Reviewed by Oliver Hunt. - - 65% faster on v8-real-earley. - - Lots of boilerplate here, but the jist is this: - - (1) Use CopiedSpace instead of malloc to allocate the activation's - backing store. - - (2) Use MarkedSpace instead of ref-counting to allocate the symbol table. - - (3) ==> No more destructor. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::CodeBlock): - (JSC::CodeBlock::stronglyVisitStrongReferences): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::symbolTable): - (CodeBlock): - (JSC::GlobalCodeBlock::GlobalCodeBlock): - (JSC::FunctionCodeBlock::FunctionCodeBlock): - (FunctionCodeBlock): SymbolTable is a GC object now, so it gets a write - barrier and visit calls instead of ref-counting. I changed all CodeBlocks - to use shared symbol tables because the distinction between shared and - unshared hurt my head. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::resolve): - (JSC::BytecodeGenerator::resolveConstDecl): - (JSC::BytecodeGenerator::emitPutStaticVar): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): Sometimes, a period just wants - to be an arrow. And then C++ is there to accommodate. - - * jit/JITDriver.h: - (JSC::jitCompileFunctionIfAppropriate): - * runtime/Arguments.h: - (ArgumentsData): - (JSC::Arguments::setRegisters): - (Arguments): - (JSC::Arguments::argument): - (JSC::Arguments::finishCreation): - * runtime/Executable.cpp: - (JSC::FunctionExecutable::FunctionExecutable): - (JSC::ProgramExecutable::compileInternal): - (JSC::FunctionExecutable::compileForCallInternal): - (JSC::FunctionExecutable::compileForConstructInternal): - (JSC::FunctionExecutable::visitChildren): - * runtime/Executable.h: - (JSC::FunctionExecutable::symbolTable): - (FunctionExecutable): - * runtime/ExecutionHarness.h: - (JSC::prepareFunctionForExecution): I changed from WriteBarrier to - WriteBarrierBase so activations could reuse StorageBarrier and PropertyStorage. - - * runtime/JSActivation.cpp: - (JSC::JSActivation::JSActivation): - (JSC::JSActivation::finishCreation): Allocate the symbol table here, - after we're fully constructed, to avoid GC during initialization. - - (JSC::JSActivation::visitChildren): - (JSC::JSActivation::symbolTableGet): - (JSC::JSActivation::symbolTablePut): - (JSC::JSActivation::getOwnPropertyNames): - (JSC::JSActivation::symbolTablePutWithAttributes): - * runtime/JSActivation.h: - (JSC::JSActivation::create): - (JSActivation): - (JSC::JSActivation::registerOffset): - (JSC): - (JSC::JSActivation::registerArraySize): - (JSC::JSActivation::registerArraySizeInBytes): - (JSC::JSActivation::tearOff): Tear-off zero-initializes all uncopied - registers. This makes it safe to copyAndAppend the full buffer in - visitChildren, without any extra checks. - - * runtime/JSCell.h: - (JSCell): Moved a shared default set of flags into this base class, so - I could use it in a few places. - - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: - (JSGlobalData): New structure for symbol tables. - - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - (JSC::JSGlobalObject::addStaticGlobals): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::symbolTableHasProperty): We don't need an inline - symbol table -- JSSymbolTableObject will GC allocate one for us. - - * runtime/JSObject.h: - (JSObject): - * runtime/JSSegmentedVariableObject.h: - (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject): - * runtime/JSStaticScopeObject.cpp: - (JSC): - (JSC::JSStaticScopeObject::visitChildren): NULL check our register store - because finishCreation allocates an object now, so we may get marked - before we've assigned to our register store. - - * runtime/JSStaticScopeObject.h: - (JSC::JSStaticScopeObject::finishCreation): - (JSC::JSStaticScopeObject::JSStaticScopeObject): - (JSStaticScopeObject): No more destructor for this object, either, since - it no longer embeds a hash table. - - * runtime/JSSymbolTableObject.cpp: - (JSC::JSSymbolTableObject::visitChildren): - (JSC::JSSymbolTableObject::deleteProperty): - (JSC::JSSymbolTableObject::getOwnPropertyNames): - * runtime/JSSymbolTableObject.h: - (JSC::JSSymbolTableObject::symbolTable): - (JSSymbolTableObject): - (JSC::JSSymbolTableObject::JSSymbolTableObject): - (JSC::JSSymbolTableObject::finishCreation): - (JSC::symbolTableGet): - (JSC::symbolTablePut): - (JSC::symbolTablePutWithAttributes): SymbolTableObject allocates a symbol - table automatically if one isn't provided. (Activations provide their - own, which they get from compiled code.) - - * runtime/JSVariableObject.cpp: - (JSC): - * runtime/JSVariableObject.h: - (JSC::JSVariableObject::registerAt): - (JSC::JSVariableObject::addressOfRegisters): - (JSVariableObject): - (JSC::JSVariableObject::JSVariableObject): - (JSC::JSVariableObject::finishCreation): Removed a bunch of obsolete code. - Activations manage their registers directly now. - - * runtime/StorageBarrier.h: - (StorageBarrier): - (JSC::StorageBarrier::operator!): - - * runtime/SymbolTable.cpp: - (JSC): - (JSC::SharedSymbolTable::destroy): - * runtime/SymbolTable.h: - (JSC::SharedSymbolTable::create): - (SharedSymbolTable): - (JSC::SharedSymbolTable::createStructure): - (JSC::SharedSymbolTable::SharedSymbolTable): Boilerplat code to - make shared symbol table GC-allocated. - -2012-08-25 Filip Pizlo <fpizlo@apple.com> - - op_call should have ArrayProfiling for the benefit of array intrinsics - https://bugs.webkit.org/show_bug.cgi?id=95014 - - Reviewed by Sam Weinig. - - This is a performance-neutral change that just adds the profiling but does not - use it, yet. If in the future we wanted to make this kind of profiling cheaper - we could move it into specialized thunks for the relevant array intrinsics, but - I figure that if this much simpler change gives us what we need without any - discernable performance penalty then that's for the best. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitCall): - * jit/JITCall.cpp: - (JSC::JIT::compileOpCall): - * jit/JITCall32_64.cpp: - (JSC::JIT::compileOpCall): - * llint/LowLevelInterpreter.asm: - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-08-25 Filip Pizlo <fpizlo@apple.com> - - The redundant phi elimination phase is not used and should be removed - https://bugs.webkit.org/show_bug.cgi?id=95006 - - Reviewed by Dan Bernstein. - - Just removing dead code. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * dfg/DFGDriver.cpp: - * dfg/DFGRedundantPhiEliminationPhase.cpp: Removed. - * dfg/DFGRedundantPhiEliminationPhase.h: Removed. - -2012-08-24 Benjamin Poulain <bpoulain@apple.com> +2012-10-05 Mark Hahnenberg <mhahnenberg@apple.com> - Unify Number to StringImpl conversion - https://bugs.webkit.org/show_bug.cgi?id=94879 + JSC should have a way to gather and log Heap memory use and pause times + https://bugs.webkit.org/show_bug.cgi?id=98431 Reviewed by Geoffrey Garen. - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * runtime/UString.cpp: - * runtime/UString.h: - (JSC::UString::number): - Update UString to directly use the common NumberToString implementation. - -2012-08-24 Oliver Hunt <oliver@apple.com> - - Always null check cells before marking - https://bugs.webkit.org/show_bug.cgi?id=94968 - - Reviewed by Geoffrey Garen. - - Originally we tried to minimise null checks by only null checking values - that we knew could be null, however given that we can't ever guarantee - when a GC will happen, we're better off just always assuming that a null - check will be necessary. This results in a much less fragile code base - as we can add GC allocations to object initialisers without having to - subsequently worry about whether the object we are initialising will need - to add a bunch of null checks in its visitChildren implementation. - - * heap/MarkStack.cpp: - (JSC::MarkStack::internalAppend): - * heap/MarkStackInlineMethods.h: - (JSC::MarkStack::append): - (JSC::MarkStack::appendUnbarrieredPointer): - * runtime/Structure.h: - (JSC::MarkStack::internalAppend): - -2012-08-23 Oliver Hunt <oliver@apple.com> - - Autogenerate Opcode definitions - https://bugs.webkit.org/show_bug.cgi?id=94840 - - Reviewed by Gavin Barraclough. - - Start the process of autogenerating the code emission for the bytecode. - We'll just start with automatic generation of the list of Opcodes as that - requires the actual definition of the opcodes, and the logic for parsing - them. - - Due to some rather annoying dependency cycles, this initial version has - the OpcodeDefinitions.h file checked into the tree, although with some - work I hope to be able to fix that. - - * DerivedSources.make: - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/Opcode.h: - Include OpcodeDefinitions.h as our definitive source of info - about the opcodes. - * bytecode/OpcodeDefinitions.h: Added. - Autogenerated file - * bytecode/opcodes: Added. - The new opcode definition file - * opcode_definition_generator.py: Added. - (generateOpcodeDefinition): - (generate): - Module that generates the content for OpcodeDefinitions.h - * opcode_generator.py: Added. - (printUsage): - (main): - Driver script - * opcode_parser.py: Added. - Simple parser for the opcode definitions. - -2011-08-23 Geoffrey Garen <ggaren@apple.com> - - Unreviewed, rolling out r126505. - http://trac.webkit.org/changeset/126505 - https://bugs.webkit.org/show_bug.cgi?id=94840 - - Caused testapi to crash on launch - - * DerivedSources.make: - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecode/OpcodeDefinitions.h: Removed. - * bytecode/opcodes: Removed. - * opcode_definition_generator.py: Removed. - * opcode_generator.py: Removed. - * opcode_parser.py: Removed. - -2012-08-23 Oliver Hunt <oliver@apple.com> - - Autogenerate Opcode definitions - https://bugs.webkit.org/show_bug.cgi?id=94840 - - Reviewed by Gavin Barraclough. - - Start the process of autogenerating the code emission for the bytecode. - We'll just start with automatic generation of the list of Opcodes as that - requires the actual definition of the opcodes, and the logic for parsing - them. - - Due to some rather annoying dependency cycles, this initial version has - the OpcodeDefinitions.h file checked into the tree, although with some - work I hope to be able to fix that. - - * DerivedSources.make: - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/Opcode.h: - Include OpcodeDefinitions.h as our definitive source of info - about the opcodes. - * bytecode/OpcodeDefinitions.h: Added. - Autogenerated file - * bytecode/opcodes: Added. - The new opcode definition file - * opcode_definition_generator.py: Added. - (generateOpcodeDefinition): - (generate): - Module that generates the content for OpcodeDefinitions.h - * opcode_generator.py: Added. - (printUsage): - (main): - Driver script - * opcode_parser.py: Added. - Simple parser for the opcode definitions. - -2012-08-23 Mark Hahnenberg <mhahnenberg@apple.com> - - Change behavior of MasqueradesAsUndefined to better accommodate DFG changes - https://bugs.webkit.org/show_bug.cgi?id=93884 - - Reviewed by Filip Pizlo. - - With some upcoming changes to the DFG to remove uses of ClassInfo, we will be changing the behavior of - MasqueradesAsUndefined. In order to make this change consistent across all of our execution engines, - we will make this change to MasqueradesAsUndefined as a separate patch. After this patch, MasqueradesAsUndefined - objects will only masquerade as undefined in their original context (i.e. their original JSGlobalObject). - For example, if an object that masquerades as undefined in frame A is passed to frame B, it will not - masquerade as undefined within frame B, but it will continue to masquerade in frame A. - - There are two primary changes that are taking place here. One is to thread the ExecState* through - JSValue::toBoolean and JSCell::toBoolean so that JSCell::toBoolean can check the object's - JSGlobalObject to compare it to the lexical JSGlobalObject of the currently running code. If the two - are distinct, then the object cannot MasqueradeAsUndefined. - - The other change is to perform this comparison of JSGlobalObjects everywhere where the MasqueradesAsUndefined - flag in the Structure is checked. For C++ code, this check has been factored into its own function in - Structure::masqueradesAsUndefined. We only perform this check in the DFG if the current JSGlobalObject has - had a MasqueradesAsUndefined object allocated within its context. This conditional compilation is managed - through the use of a WatchpointSet in each JSGlobalObject and alternate create() functions for JS DOM wrappers - that are MasqueradesAsUndefined. - - * API/JSValueRef.cpp: - (JSValueToBoolean): - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * bytecode/Watchpoint.h: - (WatchpointSet): - * debugger/DebuggerCallFrame.h: - (JSC::DebuggerCallFrame::callFrame): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::run): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): - (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): - (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): - (JSC::DFG::SpeculativeJIT::compile): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_is_undefined): - (JSC::JIT::emit_op_jeq_null): - (JSC::JIT::emit_op_jneq_null): - (JSC::JIT::emit_op_eq_null): - (JSC::JIT::emit_op_neq_null): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_is_undefined): - (JSC::JIT::emit_op_jeq_null): - (JSC::JIT::emit_op_jneq_null): - (JSC::JIT::emit_op_eq_null): - (JSC::JIT::emit_op_neq_null): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/ArrayPrototype.cpp: - (JSC::arrayProtoFuncFilter): - (JSC::arrayProtoFuncEvery): - (JSC::arrayProtoFuncSome): - * runtime/BooleanConstructor.cpp: - (JSC::constructBoolean): - (JSC::callBooleanConstructor): - * runtime/JSCell.h: - (JSCell): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::masqueradesAsUndefinedWatchpoint): - * runtime/JSString.h: - (JSC::JSCell::toBoolean): - (JSC::JSValue::toBoolean): - * runtime/JSValue.h: - * runtime/ObjectConstructor.cpp: - (JSC::toPropertyDescriptor): - * runtime/Operations.cpp: - (JSC::jsTypeStringForValue): - (JSC::jsIsObjectType): - * runtime/Operations.h: - (JSC): - (JSC::JSValue::equalSlowCaseInline): - * runtime/RegExpConstructor.cpp: - (JSC::setRegExpConstructorMultiline): - * runtime/RegExpPrototype.cpp: - (JSC::regExpProtoFuncToString): - * runtime/Structure.h: - (Structure): - (JSC::Structure::globalObjectOffset): - (JSC::Structure::masqueradesAsUndefined): - (JSC): - -2012-08-23 Mark Rowe <mrowe@apple.com> - - Make JavaScriptCore build with the latest version of clang. - - Reviewed by Dan Bernstein. - - * heap/MachineStackMarker.cpp: - (JSC::MachineThreads::MachineThreads): The m_heap member is only used within - assertions, so guard its initialization with !ASSERT_DISABLED. - * heap/MachineStackMarker.h: - (MachineThreads): Ditto for its declaration. - * jit/JITStubCall.h: - (JSC::JITStubCall::JITStubCall): The m_returnType member is only used within - assertions or if we're using JSVALUE32_64, so guard its uses with the appropriate - #if. - (JITStubCall): Ditto. - -2012-08-23 Christophe Dumez <christophe.dumez@intel.com> - - Serialization of JavaScript values does not appear to respect new HTML5 Structured Clone semantics - https://bugs.webkit.org/show_bug.cgi?id=65292 - - Reviewed by Oliver Hunt. - - Add function to construct a StringObject from a JSValue. - Similar functions already exist for NumberObject and - BooleanObject for example. - - Export several symbols so address linking errors in - WebCore. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * runtime/BooleanObject.h: - (BooleanObject): - * runtime/NumberObject.h: - (NumberObject): - (JSC): - * runtime/StringObject.cpp: - (JSC::constructString): - (JSC): - * runtime/StringObject.h: - (JSC): - -2012-08-22 Filip Pizlo <fpizlo@apple.com> - - Array accesses should remember what kind of array they are predicted to access - https://bugs.webkit.org/show_bug.cgi?id=94448 - - Reviewed by Gavin Barraclough. - - Introduced the notion of DFG::Array::Mode, stored in node.arrayMode(), which allows nodes - to remember how they decided to access arrays. This permits the bytecode parser to "lock in" - the mode of access if it has profiling at its disposal, and it also allows the prediction - propagator to do a fixup of the array mode later in the optimization fixpoint. - - This patch adds a healthy amount of new capability (specifically the ability of the parser - to lock in an array mode regardless of type predictions) and it also blows away a lot of - messy code. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - * dfg/DFGArrayMode.cpp: Added. - (DFG): - (JSC::DFG::fromObserved): - (JSC::DFG::refineArrayMode): - (JSC::DFG::modeAlreadyChecked): - (JSC::DFG::modeToString): - * dfg/DFGArrayMode.h: Added. - (DFG): - (JSC::DFG::canCSEStorage): - (JSC::DFG::modeForPut): - (JSC::DFG::modesCompatibleForStorageLoad): - (JSC::DFG::modeSupportsLength): - * dfg/DFGByteCodeParser.cpp: - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::getArrayModeWithoutOSRExit): - (JSC::DFG::ByteCodeParser::getArrayMode): - (JSC::DFG::ByteCodeParser::handleIntrinsic): - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::getByValLoadElimination): - (JSC::DFG::CSEPhase::checkStructureLoadElimination): - (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): - (JSC::DFG::CSEPhase::getByOffsetLoadElimination): - (JSC::DFG::CSEPhase::putByOffsetStoreElimination): - (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dump): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::byValIsPure): - (JSC::DFG::Graph::clobbersWorld): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasArrayMode): - (Node): - (JSC::DFG::Node::arrayMode): - (JSC::DFG::Node::setArrayMode): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::typedArrayDescriptor): - (DFG): - (JSC::DFG::SpeculativeJIT::speculateArray): - (JSC::DFG::SpeculativeJIT::compileGetByValOnString): - (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray): - (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): - (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray): - (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray): - (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): - (JSC::DFG::SpeculativeJIT::compileGetArrayLength): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - -2012-08-22 Geoffrey Garen <ggaren@apple.com> - - ThreadRestrictionVerifier should be opt-in, not opt-out - https://bugs.webkit.org/show_bug.cgi?id=94761 - - Reviewed by Mark Hahnenberg. - - Removed explicit calls to disable the verifier, since it's off by default now. + In order to improve our infrastructure for benchmark-driven development, we should + have a centralized method of gathering and logging various statistics about the state + of the JS heap. This would allow us to create and to use other tools to analyze the + output of the VM after running various workloads. - * parser/SourceProvider.h: - (JSC::SourceProvider::SourceProvider): - (SourceProvider): - * runtime/SymbolTable.h: - (JSC::SharedSymbolTable::SharedSymbolTable): + The first two statistics that might be interesting is memory use by JSC and GC pause + times. We can control whether this recording happens through the use of the Options + class, allowing us to either use environment variables or command line flags. -2012-08-22 Mark Hahnenberg <mhahnenberg@apple.com> - - Separate MarkStackThreadSharedData from MarkStack - https://bugs.webkit.org/show_bug.cgi?id=94294 - - Reviewed by Filip Pizlo. - - MarkStackThreadSharedData is soon going to have data to allow for a parallel copying - mode too, so to separate our concerns we should split it out into its own set of files - and rename it to GCThreadSharedData. For now this is purely a cosmetic refactoring. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * heap/GCThreadSharedData.cpp: Added. - (JSC): - (JSC::GCThreadSharedData::resetChildren): - (JSC::GCThreadSharedData::childVisitCount): - (JSC::GCThreadSharedData::markingThreadMain): - (JSC::GCThreadSharedData::markingThreadStartFunc): - (JSC::GCThreadSharedData::GCThreadSharedData): - (JSC::GCThreadSharedData::~GCThreadSharedData): - (JSC::GCThreadSharedData::reset): - * heap/GCThreadSharedData.h: Added. - (JSC): - (GCThreadSharedData): + * heap/Heap.cpp: + (JSC::Heap::collect): If we finish a collection and are still over our set GC heap size, + we end the program immediately and report an error. Also added recording of pause times. * heap/Heap.h: (Heap): - * heap/ListableHandler.h: - (ListableHandler): - * heap/MarkStack.cpp: - (JSC::MarkStack::MarkStack): - (JSC::MarkStack::~MarkStack): - * heap/MarkStack.h: - (JSC): - (MarkStack): - (JSC::MarkStack::sharedData): - * heap/MarkStackInlineMethods.h: Added. - (JSC): - (JSC::MarkStack::append): - (JSC::MarkStack::appendUnbarrieredPointer): - (JSC::MarkStack::appendUnbarrieredValue): - (JSC::MarkStack::internalAppend): - (JSC::MarkStack::addWeakReferenceHarvester): - (JSC::MarkStack::addUnconditionalFinalizer): - (JSC::MarkStack::addOpaqueRoot): - (JSC::MarkStack::containsOpaqueRoot): - (JSC::MarkStack::opaqueRootCount): - * heap/SlotVisitor.h: - (JSC): - (SlotVisitor): - (JSC::SlotVisitor::SlotVisitor): - -2012-08-22 Gabor Ballabas <gaborb@inf.u-szeged.hu> - - Fix JSC build when DFG-JIT is disabled - https://bugs.webkit.org/show_bug.cgi?id=94694 - - Reviewed by Csaba Osztrogonác. - - Adding an appropriate guard for fixing the build. - - * bytecode/ResolveGlobalStatus.cpp: - (JSC): - -2012-08-21 Mark Lam <mark.lam@apple.com> - - Introducing the VMInspector for VM debugging use. - https://bugs.webkit.org/show_bug.cgi?id=94613. - - Reviewed by Filip Pizlo. - - Adding some utility functions for debugging the VM. This code is - presently #ifdef'd out by default. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * interpreter/CallFrame.h: - (ExecState): - * interpreter/VMInspector.cpp: Added. - (JSC): - (JSC::VMInspector::getTypeName): - (JSC::VMInspector::dumpFrame0): - (JSC::VMInspector::dumpFrame): - (JSC::VMInspector::countFrames): - * interpreter/VMInspector.h: Added. + (JSC::Heap::shouldCollect): When we set a specific GC heap size through Options, we + ignore all other heuristics on when we should collect and instead only ask if we're + greater than the amount specified in the Option value. This allows us to view time/memory + tradeoffs more clearly. + * heap/HeapStatistics.cpp: Added. + (JSC): + (JSC::HeapStatistics::initialize): + (JSC::HeapStatistics::recordGCPauseTime): + (JSC::HeapStatistics::logStatistics): + (JSC::HeapStatistics::exitWithFailure): + (JSC::HeapStatistics::reportSuccess): + (JSC::HeapStatistics::parseMemoryAmount): + (StorageStatistics): + (JSC::StorageStatistics::StorageStatistics): + (JSC::StorageStatistics::operator()): + (JSC::StorageStatistics::objectWithOutOfLineStorageCount): + (JSC::StorageStatistics::objectCount): + (JSC::StorageStatistics::storageSize): + (JSC::StorageStatistics::storageCapacity): + (JSC::HeapStatistics::showObjectStatistics): Moved the old showHeapStatistics (renamed to showObjectStatistics) + to try to start collecting our various memory statistics gathering/reporting mechanisms scattered throughout the + codebase into one place. + * heap/HeapStatistics.h: Added. + (JSC): + (HeapStatistics): + * jsc.cpp: + (main): + * runtime/InitializeThreading.cpp: + (JSC::initializeThreadingOnce): We need to initialize our data structures for recording + statistics if necessary. + * runtime/Options.cpp: Add new Options for the various types of statistics we'll be gathering. + (JSC::parse): (JSC): - (VMInspector): - -2012-08-21 Filip Pizlo <fpizlo@apple.com> - - A patchable GetById right after a watchpoint should have the appropriate nop padding - https://bugs.webkit.org/show_bug.cgi?id=94635 - - Reviewed by Mark Hahnenberg. - - * assembler/AbstractMacroAssembler.h: - (JSC::AbstractMacroAssembler::padBeforePatch): - (AbstractMacroAssembler): - * assembler/MacroAssemblerARMv7.h: - (JSC::MacroAssemblerARMv7::load32WithCompactAddressOffsetPatch): - (JSC::MacroAssemblerARMv7::moveWithPatch): - (JSC::MacroAssemblerARMv7::patchableJump): - * assembler/MacroAssemblerX86.h: - (JSC::MacroAssemblerX86::moveWithPatch): - (JSC::MacroAssemblerX86::branchPtrWithPatch): - (JSC::MacroAssemblerX86::storePtrWithPatch): - * assembler/MacroAssemblerX86Common.h: - (JSC::MacroAssemblerX86Common::load32WithAddressOffsetPatch): - (JSC::MacroAssemblerX86Common::load32WithCompactAddressOffsetPatch): - (JSC::MacroAssemblerX86Common::loadCompactWithAddressOffsetPatch): - (JSC::MacroAssemblerX86Common::store32WithAddressOffsetPatch): - * assembler/MacroAssemblerX86_64.h: - (JSC::MacroAssemblerX86_64::loadPtrWithAddressOffsetPatch): - (JSC::MacroAssemblerX86_64::loadPtrWithCompactAddressOffsetPatch): - (JSC::MacroAssemblerX86_64::storePtrWithAddressOffsetPatch): - (JSC::MacroAssemblerX86_64::moveWithPatch): - * jit/JumpReplacementWatchpoint.cpp: - (JSC::JumpReplacementWatchpoint::fireInternal): - -2012-08-20 Mark Lam <mark.lam@apple.com> - - Fix broken non-JIT build. - https://bugs.webkit.org/show_bug.cgi?id=94564. - - Reviewed by Filip Pizlo. - - Added some UNUSED_PARAM() macros to make the compiler happy. - - * runtime/Executable.cpp: - (JSC::EvalExecutable::compileInternal): - (JSC::ProgramExecutable::compileInternal): - (JSC::FunctionExecutable::compileForCallInternal): - (JSC::FunctionExecutable::compileForConstructInternal): - -2012-08-20 Mark Lam <mark.lam@apple.com> - - Fixed erroneous line number for LLint frame when throwing exceptions. - https://bugs.webkit.org/show_bug.cgi?id=94051. - - Reviewed by Filip Pizlo. - - For LLInt frames, before throwing an exception, adjust the PC from the - return PC back to the call PC if we are indeed at a call site. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::adjustPCIfAtCallSite): + (JSC::Options::initialize): Initialize the various new options using environment variables. + (JSC::Options::dumpOption): + * runtime/Options.h: (JSC): - (JSC::CodeBlock::bytecodeOffset): - * bytecode/CodeBlock.h: - (CodeBlock): - * llint/LLIntExceptions.cpp: - (JSC::LLInt::fixupPCforExceptionIfNeeded): - (LLInt): - (JSC::LLInt::interpreterThrowInCaller): - (JSC::LLInt::returnToThrow): - (JSC::LLInt::callToThrow): - -2012-08-20 Filip Pizlo <fpizlo@apple.com> - - fast/js/dfg-peephole-compare-final-object-to-final-object-or-other-when-both-proven-final-object.html on 32-bit - https://bugs.webkit.org/show_bug.cgi?id=94538 - - Reviewed by Mark Hahnenberg. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): - -2012-08-20 Filip Pizlo <fpizlo@apple.com> - - fast/js/dfg-compare-final-object-to-final-object-or-other-when-both-proven-final-object.html crashes on 32-bit - https://bugs.webkit.org/show_bug.cgi?id=94026 - - Reviewed by Mark Hahnenberg. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): - -2012-08-19 Filip Pizlo <fpizlo@apple.com> - - The relationship between abstract values and structure transition watchpoints should be rationalized - https://bugs.webkit.org/show_bug.cgi?id=94205 - - Reviewed by Geoffrey Garen. - - This patch does a number of things related to the handling of the abstract values - arrising from values with structures known to be watchpointable: - - - This rationalizes the relationship between the structure that we know an object - to have *right now* based on having executed a check against that structure, and - the structure that we know the object could have *in the future* based on a type - check executed in the past over a structure that was watchpointable. - - - We use the above to assert that structure transition watchpoints are being used - soundly. - - - We use the above to strength reduce CheckStructure into StructureTransitionWatchpoint - whenever possible. - - - This rationalizes the handling of CFA over constants that appeared in the bytecode. - If at compile-time the constant has a watchpointable structure, then we can prove - what structures it may have in the future. The analysis uses this to both assert - that structure transition watchpoints are being used correctly, and to find - opportunities for using them more aggressively. - - The net effect of all of these changes is that OSR entry should work more smoothly. - It may also be a slight win due to strength reductions, though most of those strength - reductions would have already been done by the parser and the structure check hoister. - - * GNUmakefile.list.am: - * JavaScriptCore.xcodeproj/project.pbxproj: - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::beginBasicBlock): - (JSC::DFG::AbstractState::execute): - * dfg/DFGAbstractValue.h: - (DFG): - (JSC::DFG::AbstractValue::clear): - (JSC::DFG::AbstractValue::isClear): - (JSC::DFG::AbstractValue::makeTop): - (JSC::DFG::AbstractValue::clobberStructures): - (JSC::DFG::AbstractValue::isTop): - (JSC::DFG::AbstractValue::setFuturePossibleStructure): - (AbstractValue): - (JSC::DFG::AbstractValue::filterFuturePossibleStructure): - (JSC::DFG::AbstractValue::setMostSpecific): - (JSC::DFG::AbstractValue::set): - (JSC::DFG::AbstractValue::operator==): - (JSC::DFG::AbstractValue::merge): - (JSC::DFG::AbstractValue::filter): - (JSC::DFG::AbstractValue::filterValueByType): - (JSC::DFG::AbstractValue::validateType): - (JSC::DFG::AbstractValue::validate): - (JSC::DFG::AbstractValue::checkConsistency): - (JSC::DFG::AbstractValue::dump): - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::checkStructureLoadElimination): - (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::foldConstants): - * dfg/DFGNode.h: - (JSC::DFG::Node::convertToStructureTransitionWatchpoint): - (Node): - (JSC::DFG::Node::hasStructure): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOSREntry.cpp: - (JSC::DFG::prepareOSREntry): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward): - (JSC::DFG::SpeculativeJIT::forwardSpeculationWatchpoint): - (DFG): - (JSC::DFG::SpeculativeJIT::speculationWatchpointWithConditionalDirection): - (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): - (JSC::DFG::SpeculativeJIT::speculateArray): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGStructureAbstractValue.h: Added. - (DFG): - (StructureAbstractValue): - (JSC::DFG::StructureAbstractValue::StructureAbstractValue): - (JSC::DFG::StructureAbstractValue::clear): - (JSC::DFG::StructureAbstractValue::makeTop): - (JSC::DFG::StructureAbstractValue::top): - (JSC::DFG::StructureAbstractValue::add): - (JSC::DFG::StructureAbstractValue::addAll): - (JSC::DFG::StructureAbstractValue::contains): - (JSC::DFG::StructureAbstractValue::isSubsetOf): - (JSC::DFG::StructureAbstractValue::doesNotContainAnyOtherThan): - (JSC::DFG::StructureAbstractValue::isSupersetOf): - (JSC::DFG::StructureAbstractValue::filter): - (JSC::DFG::StructureAbstractValue::isClear): - (JSC::DFG::StructureAbstractValue::isTop): - (JSC::DFG::StructureAbstractValue::isClearOrTop): - (JSC::DFG::StructureAbstractValue::isNeitherClearNorTop): - (JSC::DFG::StructureAbstractValue::size): - (JSC::DFG::StructureAbstractValue::at): - (JSC::DFG::StructureAbstractValue::operator[]): - (JSC::DFG::StructureAbstractValue::last): - (JSC::DFG::StructureAbstractValue::speculationFromStructures): - (JSC::DFG::StructureAbstractValue::hasSingleton): - (JSC::DFG::StructureAbstractValue::singleton): - (JSC::DFG::StructureAbstractValue::operator==): - (JSC::DFG::StructureAbstractValue::dump): - (JSC::DFG::StructureAbstractValue::topValue): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - -2012-08-17 Filip Pizlo <fpizlo@apple.com> - - The current state of the call frame should be taken into account in the DFG for both predictions and proofs - https://bugs.webkit.org/show_bug.cgi?id=94412 - Reviewed by Geoffrey Garen. +2012-10-04 Rik Cabanier <cabanier@adobe.com> - This ensures that no matter how smart the DFG gets, it'll always know through - which entrypoint OSR will try to enter, and with which values it will attempt - to do so. For prologue OSR, this has no effect other than adding the current - arguments to the argument predictions. For loop OSR, this makes our treatment - of the loop slightly more conservative - just conservative enough to ensure - that OSR succeeds. + Turn Compositing on by default in WebKit build + https://bugs.webkit.org/show_bug.cgi?id=98315 - * bytecode/CodeBlock.cpp: - (JSC::ProgramCodeBlock::compileOptimized): - (JSC::EvalCodeBlock::compileOptimized): - (JSC::FunctionCodeBlock::compileOptimized): - * bytecode/CodeBlock.h: - (CodeBlock): - (ProgramCodeBlock): - (EvalCodeBlock): - (FunctionCodeBlock): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::initialize): - * dfg/DFGAbstractValue.h: - (JSC::DFG::AbstractValue::setMostSpecific): - (AbstractValue): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::fixVariableAccessPredictions): - (JSC::DFG::ByteCodeParser::parse): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - (JSC::DFG::tryCompile): - (JSC::DFG::tryCompileFunction): - * dfg/DFGDriver.h: - (DFG): - (JSC::DFG::tryCompile): - (JSC::DFG::tryCompileFunction): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::Graph): - (Graph): - * jit/JITDriver.h: - (JSC::jitCompileIfAppropriate): - (JSC::jitCompileFunctionIfAppropriate): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * runtime/Executable.cpp: - (JSC::EvalExecutable::compileOptimized): - (JSC::EvalExecutable::compileInternal): - (JSC::ProgramExecutable::compileOptimized): - (JSC::ProgramExecutable::compileInternal): - (JSC::FunctionExecutable::compileOptimizedForCall): - (JSC::FunctionExecutable::compileOptimizedForConstruct): - (JSC::FunctionExecutable::compileForCallInternal): - (JSC::FunctionExecutable::compileForConstructInternal): - * runtime/Executable.h: - (EvalExecutable): - (ProgramExecutable): - (FunctionExecutable): - (JSC::FunctionExecutable::compileOptimizedFor): - * runtime/ExecutionHarness.h: - (JSC::prepareForExecution): - (JSC::prepareFunctionForExecution): - -2012-08-17 Filip Pizlo <fpizlo@apple.com> - - DFG CSE should be more honest about when it changed the IR - https://bugs.webkit.org/show_bug.cgi?id=94408 - - Reviewed by Geoffrey Garen. - - The CSE phase now always returns true if it changed the IR. - - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::setReplacement): - (JSC::DFG::CSEPhase::eliminate): - (JSC::DFG::CSEPhase::performNodeCSE): - -2012-08-17 Filip Pizlo <fpizlo@apple.com> - - DFG is still too pessimistic about what constitutes a side-effect on array accesses - https://bugs.webkit.org/show_bug.cgi?id=94309 - - Reviewed by Geoffrey Garen. - - This change means that even if structure transition watchpoints are not used for - hoisting of clobbered structure checks, we still retain good performance on the - benchmarks we care about. That's important, since butterflies will likely make - most array structures not watchpointable. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - -2012-08-17 Milian Wolff <milian.wolff@kdab.com> - - [Qt] QNX build fails due to ctype usage in system headers - https://bugs.webkit.org/show_bug.cgi?id=93849 - - Reviewed by Simon Hausmann. - - Move the check for whether DisallowCType should be active or not - to the DisallowCType.h header. This way, we can update the list - of platforms or OSes which do not work with this header in a - central place. All users can now safely include the header - and do not need to place custom guards around it. - - * config.h: - -2012-08-16 Simon Hausmann <simon.hausmann@nokia.com> - - [Qt] Replace use of internal Weak smart pointer with JSWeakObjectMap - https://bugs.webkit.org/show_bug.cgi?id=93872 - - Reviewed by Kenneth Rohde Christiansen. - - * Target.pri: Add missing JSWeakObjectMap file to build. - -2012-08-16 Filip Pizlo <fpizlo@apple.com> - - Structure check hoisting should be less expensive - https://bugs.webkit.org/show_bug.cgi?id=94201 - - Reviewed by Mark Hahnenberg. - - This appears like a broad win on short-running programs. - - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::compareAndSwap): - (Graph): - (JSC::DFG::Graph::substitute): - (JSC::DFG::Graph::substituteGetLocal): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - -2012-08-16 Filip Pizlo <fpizlo@apple.com> - - All op_resolve_global instructions should end up in the list of global resolve instructions - https://bugs.webkit.org/show_bug.cgi?id=94247 - <rdar://problem/12103500> - - Reviewed by Mark Hahnenberg. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitResolveWithBase): - -2012-08-15 Bruno de Oliveira Abinader <bruno.abinader@basyskom.com> - - [css3-text] Add CSS3 Text decoration compile flag - https://bugs.webkit.org/show_bug.cgi?id=93863 - - Reviewed by Julien Chaffraix. + Reviewed by Simon Fraser. - This patch handles the compile flag implementation, which will come disabled by - default, thus not exposing the CSS3 text decoration features to the web, unless - when explicitly enabling it with "--css3-text-decoration" build parameter. + enable -webkit-blend-mode on trunk. * Configurations/FeatureDefines.xcconfig: -2012-08-15 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r125687. - http://trac.webkit.org/changeset/125687 - https://bugs.webkit.org/show_bug.cgi?id=94147 - - It broke the whole world (Requested by Ossy_night on #webkit). - - * API/JSValueRef.cpp: - (JSValueToBoolean): - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * bytecode/Watchpoint.h: - (WatchpointSet): - * debugger/DebuggerCallFrame.h: - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::run): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): - (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): - (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): - (JSC::DFG::SpeculativeJIT::compile): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_is_undefined): - (JSC::JIT::emit_op_jeq_null): - (JSC::JIT::emit_op_jneq_null): - (JSC::JIT::emit_op_eq_null): - (JSC::JIT::emit_op_neq_null): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_is_undefined): - (JSC::JIT::emit_op_jeq_null): - (JSC::JIT::emit_op_jneq_null): - (JSC::JIT::emit_op_eq_null): - (JSC::JIT::emit_op_neq_null): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/ArrayPrototype.cpp: - (JSC::arrayProtoFuncFilter): - (JSC::arrayProtoFuncEvery): - (JSC::arrayProtoFuncSome): - * runtime/BooleanConstructor.cpp: - (JSC::constructBoolean): - (JSC::callBooleanConstructor): - * runtime/JSCell.h: - (JSCell): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - * runtime/JSString.h: - (JSC::JSCell::toBoolean): - (JSC::JSValue::toBoolean): - * runtime/JSValue.h: - * runtime/ObjectConstructor.cpp: - (JSC::toPropertyDescriptor): - * runtime/Operations.cpp: - (JSC::jsTypeStringForValue): - (JSC::jsIsObjectType): - * runtime/Operations.h: - (JSC): - (JSC::JSValue::equalSlowCaseInline): - * runtime/RegExpConstructor.cpp: - (JSC::setRegExpConstructorMultiline): - * runtime/RegExpPrototype.cpp: - (JSC::regExpProtoFuncToString): - * runtime/Structure.h: - -2012-08-15 Gabor Ballabas <gaborb@inf.u-szeged.hu> +2012-10-04 Michael Saboff <msaboff@apple.com> - Buildfix after r125541 - https://bugs.webkit.org/show_bug.cgi?id=94097 + Crash in Safari at com.apple.JavaScriptCore: WTF::StringImpl::is8Bit const + 12 + https://bugs.webkit.org/show_bug.cgi?id=98433 - Reviewed by Filip Pizlo. - - r125541 has broken the traditional ARM port build of JSC. - - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::neg32): - (JSC::MacroAssemblerARM::xor32): - -2012-08-14 Mark Hahnenberg <mhahnenberg@apple.com> - - Change behavior of MasqueradesAsUndefined to better accommodate DFG changes - https://bugs.webkit.org/show_bug.cgi?id=93884 - - Reviewed by Geoffrey Garen. + Reviewed by Jessie Berlin. - With some upcoming changes to the DFG to remove uses of ClassInfo, we will be changing the behavior of - MasqueradesAsUndefined. In order to make this change consistent across all of our execution engines, - we will make this change to MasqueradesAsUndefined as a separate patch. After this patch, MasqueradesAsUndefined - objects will only masquerade as undefined in their original context (i.e. their original JSGlobalObject). - For example, if an object that masquerades as undefined in frame A is passed to frame B, it will not - masquerade as undefined within frame B, but it will continue to masquerade in frame A. - - There are two primary changes that are taking place here. One is to thread the ExecState* through - JSValue::toBoolean and JSCell::toBoolean so that JSCell::toBoolean can check the object's - JSGlobalObject to compare it to the lexical JSGlobalObject of the currently running code. If the two - are distinct, then the object cannot MasqueradeAsUndefined. - - The other change is to perform this comparison of JSGlobalObjects everywhere where the MasqueradesAsUndefined - flag in the Structure is checked. For C++ code, this check has been factored into its own function in - Structure::masqueradesAsUndefined. We only perform this check in the DFG if the current JSGlobalObject has - had a MasqueradesAsUndefined object allocated within its context. This conditional compilation is managed - through the use of a WatchpointSet in each JSGlobalObject and alternate create() functions for JS DOM wrappers - that are MasqueradesAsUndefined. + The problem is due to a String with a null StringImpl (i.e. a null string). + Added a length check before the is8Bit() check since length() checks for a null StringImpl. Changed the + characters16() call to characters() since it can handle a null StringImpl as well. * API/JSValueRef.cpp: - (JSValueToBoolean): - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * bytecode/Watchpoint.h: - (WatchpointSet): - * debugger/DebuggerCallFrame.h: - (JSC::DebuggerCallFrame::callFrame): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::run): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): - (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): - (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): - (JSC::DFG::SpeculativeJIT::compile): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_is_undefined): - (JSC::JIT::emit_op_jeq_null): - (JSC::JIT::emit_op_jneq_null): - (JSC::JIT::emit_op_eq_null): - (JSC::JIT::emit_op_neq_null): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_is_undefined): - (JSC::JIT::emit_op_jeq_null): - (JSC::JIT::emit_op_jneq_null): - (JSC::JIT::emit_op_eq_null): - (JSC::JIT::emit_op_neq_null): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/ArrayPrototype.cpp: - (JSC::arrayProtoFuncFilter): - (JSC::arrayProtoFuncEvery): - (JSC::arrayProtoFuncSome): - * runtime/BooleanConstructor.cpp: - (JSC::constructBoolean): - (JSC::callBooleanConstructor): - * runtime/JSCell.h: - (JSCell): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::masqueradesAsUndefinedWatchpoint): - * runtime/JSString.h: - (JSC::JSCell::toBoolean): - (JSC::JSValue::toBoolean): - * runtime/JSValue.h: - * runtime/ObjectConstructor.cpp: - (JSC::toPropertyDescriptor): - * runtime/Operations.cpp: - (JSC::jsTypeStringForValue): - (JSC::jsIsObjectType): - * runtime/Operations.h: - (JSC): - (JSC::JSValue::equalSlowCaseInline): - * runtime/RegExpConstructor.cpp: - (JSC::setRegExpConstructorMultiline): - * runtime/RegExpPrototype.cpp: - (JSC::regExpProtoFuncToString): - * runtime/Structure.h: - (Structure): - (JSC::Structure::globalObjectOffset): - (JSC::Structure::masqueradesAsUndefined): - (JSC): - -2012-08-14 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, build fix for !ENABLE(DFG_JIT) - - * jit/JITPropertyAccess.cpp: - (JSC::JIT::emit_op_get_by_val): - (JSC::JIT::emit_op_put_by_val): - (JSC::JIT::privateCompilePatchGetArrayLength): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::emit_op_get_by_val): - (JSC::JIT::emit_op_put_by_val): - (JSC::JIT::privateCompilePatchGetArrayLength): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-08-13 Filip Pizlo <fpizlo@apple.com> - - Array checks should use the structure, not the class info - https://bugs.webkit.org/show_bug.cgi?id=93150 - - Reviewed by Mark Hahnenberg. - - This changes all array checks used in array accesses (get, put, get length, - push, pop) to use the structure, not the class info. Additionally, these - checks in the LLInt and baseline JIT record the structure in an ArrayProfile, - so that the DFG can know exactly what structure to check for. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * bytecode/ArrayProfile.cpp: Added. - (JSC): - (JSC::ArrayProfile::computeUpdatedPrediction): - * bytecode/ArrayProfile.h: Added. - (JSC): - (JSC::arrayModeFromStructure): - (ArrayProfile): - (JSC::ArrayProfile::ArrayProfile): - (JSC::ArrayProfile::bytecodeOffset): - (JSC::ArrayProfile::addressOfLastSeenStructure): - (JSC::ArrayProfile::observeStructure): - (JSC::ArrayProfile::expectedStructure): - (JSC::ArrayProfile::structureIsPolymorphic): - (JSC::ArrayProfile::hasDefiniteStructure): - (JSC::ArrayProfile::observedArrayModes): - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - (JSC::CodeBlock::getArrayProfile): - (JSC): - (JSC::CodeBlock::getOrAddArrayProfile): - (JSC::CodeBlock::updateAllPredictionsAndCountLiveness): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::executionEntryCount): - (JSC::CodeBlock::numberOfArrayProfiles): - (JSC::CodeBlock::arrayProfiles): - (JSC::CodeBlock::addArrayProfile): - (CodeBlock): - * bytecode/Instruction.h: - (JSC): - (JSC::Instruction::Instruction): - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitGetArgumentByVal): - (JSC::BytecodeGenerator::emitGetByVal): - (JSC::BytecodeGenerator::emitPutByVal): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::initialize): - (JSC::DFG::AbstractState::execute): - * dfg/DFGAbstractValue.h: - (JSC::DFG::StructureAbstractValue::hasSingleton): - (StructureAbstractValue): - (JSC::DFG::StructureAbstractValue::singleton): - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::speculateArray): - (DFG): - (JSC::DFG::SpeculativeJIT::compile): - (JSC::DFG::SpeculativeJIT::checkArgumentTypes): - (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::emit_op_get_by_val): - (JSC::JIT::emit_op_put_by_val): - (JSC::JIT::privateCompilePatchGetArrayLength): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::emit_op_get_by_val): - (JSC::JIT::emit_op_put_by_val): - (JSC::JIT::privateCompilePatchGetArrayLength): - * llint/LLIntOffsetsExtractor.cpp: - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/Structure.h: - (Structure): - (JSC::Structure::classInfoOffset): - -2012-08-14 Gabor Ballabas <gaborb@inf.u-szeged.hu> - - Rename functions in the ARM port of DFG-JIT for better code readability. - https://bugs.webkit.org/show_bug.cgi?id=93609 - - Reviewed by Zoltan Herczeg. - - Rename functions in the ARM port of DFG-JIT for better code - readability, and for following the WebKit coding style - wherever it is possible. - - * assembler/ARMAssembler.cpp: - (JSC::ARMAssembler::genInt): - (JSC::ARMAssembler::getImm): - (JSC::ARMAssembler::moveImm): - (JSC::ARMAssembler::encodeComplexImm): - (JSC::ARMAssembler::dataTransfer32): - (JSC::ARMAssembler::baseIndexTransfer32): - (JSC::ARMAssembler::dataTransfer16): - (JSC::ARMAssembler::baseIndexTransfer16): - (JSC::ARMAssembler::dataTransferFloat): - (JSC::ARMAssembler::baseIndexTransferFloat): - * assembler/ARMAssembler.h: - (JSC::ARMAssembler::bitAnd): - (JSC::ARMAssembler::bitAnds): - (JSC::ARMAssembler::eor): - (JSC::ARMAssembler::eors): - (JSC::ARMAssembler::sub): - (JSC::ARMAssembler::subs): - (JSC::ARMAssembler::rsb): - (JSC::ARMAssembler::rsbs): - (JSC::ARMAssembler::add): - (JSC::ARMAssembler::adds): - (JSC::ARMAssembler::adc): - (JSC::ARMAssembler::adcs): - (JSC::ARMAssembler::sbc): - (JSC::ARMAssembler::sbcs): - (JSC::ARMAssembler::rsc): - (JSC::ARMAssembler::rscs): - (JSC::ARMAssembler::tst): - (JSC::ARMAssembler::teq): - (JSC::ARMAssembler::cmp): - (JSC::ARMAssembler::cmn): - (JSC::ARMAssembler::orr): - (JSC::ARMAssembler::orrs): - (JSC::ARMAssembler::mov): - (JSC::ARMAssembler::movw): - (JSC::ARMAssembler::movt): - (JSC::ARMAssembler::movs): - (JSC::ARMAssembler::bic): - (JSC::ARMAssembler::bics): - (JSC::ARMAssembler::mvn): - (JSC::ARMAssembler::mvns): - (JSC::ARMAssembler::mul): - (JSC::ARMAssembler::muls): - (JSC::ARMAssembler::mull): - (JSC::ARMAssembler::vmov_f64): - (JSC::ARMAssembler::vadd_f64): - (JSC::ARMAssembler::vdiv_f64): - (JSC::ARMAssembler::vsub_f64): - (JSC::ARMAssembler::vmul_f64): - (JSC::ARMAssembler::vcmp_f64): - (JSC::ARMAssembler::vsqrt_f64): - (JSC::ARMAssembler::vabs_f64): - (JSC::ARMAssembler::vneg_f64): - (JSC::ARMAssembler::ldrImmediate): - (JSC::ARMAssembler::ldrUniqueImmediate): - (JSC::ARMAssembler::dtrUp): - (JSC::ARMAssembler::dtrUpRegister): - (JSC::ARMAssembler::dtrDown): - (JSC::ARMAssembler::dtrDownRegister): - (JSC::ARMAssembler::halfDtrUp): - (JSC::ARMAssembler::halfDtrUpRegister): - (JSC::ARMAssembler::halfDtrDown): - (JSC::ARMAssembler::halfDtrDownRegister): - (JSC::ARMAssembler::doubleDtrUp): - (JSC::ARMAssembler::doubleDtrDown): - (JSC::ARMAssembler::push): - (JSC::ARMAssembler::pop): - (JSC::ARMAssembler::poke): - (JSC::ARMAssembler::peek): - (JSC::ARMAssembler::vmov_vfp64): - (JSC::ARMAssembler::vmov_arm64): - (JSC::ARMAssembler::vmov_vfp32): - (JSC::ARMAssembler::vmov_arm32): - (JSC::ARMAssembler::vcvt_f64_s32): - (JSC::ARMAssembler::vcvt_s32_f64): - (JSC::ARMAssembler::vcvt_u32_f64): - (JSC::ARMAssembler::vcvt_f64_f32): - (JSC::ARMAssembler::vcvt_f32_f64): - (JSC::ARMAssembler::clz): - (JSC::ARMAssembler::lslRegister): - (JSC::ARMAssembler::lsrRegister): - (JSC::ARMAssembler::asrRegister): - (JSC::ARMAssembler::align): - (JSC::ARMAssembler::loadBranchTarget): - (JSC::ARMAssembler::vmov): - * assembler/MacroAssemblerARM.cpp: - (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::add32): - (JSC::MacroAssemblerARM::and32): - (JSC::MacroAssemblerARM::lshift32): - (JSC::MacroAssemblerARM::mul32): - (JSC::MacroAssemblerARM::or32): - (JSC::MacroAssemblerARM::rshift32): - (JSC::MacroAssemblerARM::urshift32): - (JSC::MacroAssemblerARM::sub32): - (JSC::MacroAssemblerARM::xor32): - (JSC::MacroAssemblerARM::countLeadingZeros32): - (JSC::MacroAssemblerARM::convertibleLoadPtr): - (JSC::MacroAssemblerARM::load32WithAddressOffsetPatch): - (JSC::MacroAssemblerARM::load32WithCompactAddressOffsetPatch): - (JSC::MacroAssemblerARM::store32WithAddressOffsetPatch): - (JSC::MacroAssemblerARM::store32): - (JSC::MacroAssemblerARM::pop): - (JSC::MacroAssemblerARM::push): - (JSC::MacroAssemblerARM::move): - (JSC::MacroAssemblerARM::swap): - (JSC::MacroAssemblerARM::branch32): - (JSC::MacroAssemblerARM::branchTest32): - (JSC::MacroAssemblerARM::mull32): - (JSC::MacroAssemblerARM::branchSub32): - (JSC::MacroAssemblerARM::compare32): - (JSC::MacroAssemblerARM::test32): - (JSC::MacroAssemblerARM::load32): - (JSC::MacroAssemblerARM::relativeTableJump): - (JSC::MacroAssemblerARM::moveWithPatch): - (JSC::MacroAssemblerARM::loadDouble): - (JSC::MacroAssemblerARM::moveDouble): - (JSC::MacroAssemblerARM::addDouble): - (JSC::MacroAssemblerARM::divDouble): - (JSC::MacroAssemblerARM::subDouble): - (JSC::MacroAssemblerARM::mulDouble): - (JSC::MacroAssemblerARM::sqrtDouble): - (JSC::MacroAssemblerARM::absDouble): - (JSC::MacroAssemblerARM::negateDouble): - (JSC::MacroAssemblerARM::convertInt32ToDouble): - (JSC::MacroAssemblerARM::convertFloatToDouble): - (JSC::MacroAssemblerARM::convertDoubleToFloat): - (JSC::MacroAssemblerARM::branchDouble): - (JSC::MacroAssemblerARM::branchTruncateDoubleToInt32): - (JSC::MacroAssemblerARM::branchTruncateDoubleToUint32): - (JSC::MacroAssemblerARM::truncateDoubleToInt32): - (JSC::MacroAssemblerARM::truncateDoubleToUint32): - (JSC::MacroAssemblerARM::branchConvertDoubleToInt32): - (JSC::MacroAssemblerARM::branchDoubleNonZero): - (JSC::MacroAssemblerARM::branchDoubleZeroOrNaN): - -2012-08-13 Simon Hausmann <simon.hausmann@nokia.com> - - Unreviewed, rolling out r125444. - http://trac.webkit.org/changeset/125444 - https://bugs.webkit.org/show_bug.cgi?id=93872 - - Broke some tests - - * Target.pri: - -2012-08-13 Simon Hausmann <simon.hausmann@nokia.com> - - [Qt] Replace use of internal Weak smart pointer with JSWeakObjectMap - https://bugs.webkit.org/show_bug.cgi?id=93872 - - Reviewed by Kenneth Rohde Christiansen. - - * Target.pri: Add missing JSWeakObjectMap file to build. - -2012-08-13 Raphael Kubo da Costa <rakuco@webkit.org> - - [CMake] Remove glib-related Find modules and write single new one instead. - https://bugs.webkit.org/show_bug.cgi?id=93786 - - Reviewed by Rob Buis. - - * shell/PlatformEfl.cmake: Use GLIB_* instead of Glib_*. - -2012-08-12 Allan Sandfeld Jensen <allan.jensen@nokia.com> - - Doesn't build with ENABLE_JIT=0 - https://bugs.webkit.org/show_bug.cgi?id=85042 - - Reviewed by Eric Seidel. - - Include headers without which CallFrame.h does not build, and - fix gcc warning about comparing unsigned int with 0. - - * dfg/DFGDriver.cpp: - * interpreter/Interpreter.cpp: - (JSC::Interpreter::isOpcode): - -2012-08-10 Yong Li <yoli@rim.com> - - [BlackBerry] GCActivityCallback should always schedule GC even allocated bytes is a small number - https://bugs.webkit.org/show_bug.cgi?id=93650 - - Reviewed by Rob Buis. - - Even a small number of allocated JS objects could hold expensive resources. - - * runtime/GCActivityCallbackBlackBerry.cpp: - (JSC::DefaultGCActivityCallback::didAllocate): - -2012-08-09 Yong Li <yoli@rim.com> - - [QNX] Implement getCPUTime() for OS(QNX) - https://bugs.webkit.org/show_bug.cgi?id=93516 - - Reviewed by George Staikos. - - Implement getCPUTime() with CLOCK_THREAD_CPUTIME_ID so it will tell - exactly how long the current thread has spent without being impacted - by other things. - - * runtime/TimeoutChecker.cpp: - (JSC::getCPUTime): - -2012-08-08 Shane Stephens <shanestephens@google.com> - - Compile flag for CSS Hierarchies - https://bugs.webkit.org/show_bug.cgi?id=92433 - - Reviewed by Tony Chang. - - * Configurations/FeatureDefines.xcconfig: + (JSValueMakeFromJSONString): -2012-08-08 Benjamin Poulain <bpoulain@apple.com> +2012-10-04 Benjamin Poulain <bpoulain@apple.com> - Use char* instead of LChar* for the public interface of String construction from literals - https://bugs.webkit.org/show_bug.cgi?id=93402 + Use copyLCharsFromUCharSource() for IdentifierLCharFromUCharTranslator translation + https://bugs.webkit.org/show_bug.cgi?id=98335 Reviewed by Michael Saboff. - Update JSC' Identifier to use StringImpl::createFromLiteral with a char*. - - * runtime/Identifier.cpp: - (JSC::IdentifierASCIIStringTranslator::translate): - -2012-08-08 Patrick Gansterer <paroga@webkit.org> - - Remove ce_time.(cpp|h) from list of source files - https://bugs.webkit.org/show_bug.cgi?id=93446 - - Reviewed by Simon Hausmann. - - r125004 removed the last dependency on functions defined in ce_time.cpp. - - * Target.pri: - -2012-08-08 Patrick Gansterer <paroga@webkit.org> - - [WIN] Use GetTimeZoneInformation() for getting the timezone name - https://bugs.webkit.org/show_bug.cgi?id=91936 - - Reviewed by Ryosuke Niwa. - - The MS CRT implementation of strftime calls the same functions in the background. - Using them directly avoids the overhead of parsing the format string and removes - the dependency on strftime() for WinCE where this function does not exist. - - * runtime/DateConversion.cpp: - (JSC::formatTime): - -2012-08-07 Gabor Ballabas <gaborb@inf.u-szeged.hu> - - Refactor magic numbers in the ARM port of DFG-JIT - https://bugs.webkit.org/show_bug.cgi?id=93348 - - Reviewed by Eric Seidel. - - Introduce new names for hard-coded magic numbers. - Refactor constant with confusing names to more descriptive ones. - - * assembler/ARMAssembler.cpp: - (JSC::ARMAssembler::patchConstantPoolLoad): - (JSC::ARMAssembler::getOp2): - (JSC::ARMAssembler::genInt): - (JSC::ARMAssembler::getImm): - (JSC::ARMAssembler::moveImm): - (JSC::ARMAssembler::encodeComplexImm): - (JSC::ARMAssembler::dataTransfer32): - (JSC::ARMAssembler::dataTransfer16): - (JSC::ARMAssembler::dataTransferFloat): - (JSC::ARMAssembler::executableCopy): - * assembler/ARMAssembler.h: - (JSC::ARMAssembler::emitInstruction): - (JSC::ARMAssembler::ands_r): - (JSC::ARMAssembler::eors_r): - (JSC::ARMAssembler::subs_r): - (JSC::ARMAssembler::rsbs_r): - (JSC::ARMAssembler::adds_r): - (JSC::ARMAssembler::adcs_r): - (JSC::ARMAssembler::sbcs_r): - (JSC::ARMAssembler::rscs_r): - (JSC::ARMAssembler::tst_r): - (JSC::ARMAssembler::teq_r): - (JSC::ARMAssembler::cmp_r): - (JSC::ARMAssembler::cmn_r): - (JSC::ARMAssembler::orrs_r): - (JSC::ARMAssembler::movs_r): - (JSC::ARMAssembler::bics_r): - (JSC::ARMAssembler::mvns_r): - (JSC::ARMAssembler::muls_r): - (JSC::ARMAssembler::ldr_imm): - (JSC::ARMAssembler::ldr_un_imm): - (JSC::ARMAssembler::dtr_u): - (JSC::ARMAssembler::dtr_ur): - (JSC::ARMAssembler::dtr_dr): - (JSC::ARMAssembler::dtrh_u): - (JSC::ARMAssembler::dtrh_ur): - (JSC::ARMAssembler::fdtr_u): - (JSC::ARMAssembler::push_r): - (JSC::ARMAssembler::pop_r): - (JSC::ARMAssembler::getLdrImmAddress): - (JSC::ARMAssembler::getLdrImmAddressOnPool): - (JSC::ARMAssembler::patchConstantPoolLoad): - (JSC::ARMAssembler::repatchCompact): - (JSC::ARMAssembler::replaceWithJump): - (JSC::ARMAssembler::replaceWithLoad): - (JSC::ARMAssembler::replaceWithAddressComputation): - (JSC::ARMAssembler::getOp2Byte): - (JSC::ARMAssembler::getOp2Half): - (JSC::ARMAssembler::getImm16Op2): - (JSC::ARMAssembler::placeConstantPoolBarrier): - (JSC::ARMAssembler::getConditionalField): - * assembler/MacroAssemblerARM.cpp: - (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::and32): - (JSC::MacroAssemblerARM::branch32): - (JSC::MacroAssemblerARM::branchTest32): - (JSC::MacroAssemblerARM::branchTruncateDoubleToInt32): - -2012-08-07 Benjamin Poulain <benjamin@webkit.org> - - Use the initialization from literal for JSC's Identifiers - https://bugs.webkit.org/show_bug.cgi?id=93193 - - Reviewed by Geoffrey Garen. - - This patches modify Identifier ot take advantage of the new initialization from literal. - - In addition to the memory savings (~600bytes per instance), this gives us a 2% speed - improvement on CommonIdentifiers on average. - - * runtime/CommonIdentifiers.cpp: - (JSC::CommonIdentifiers::CommonIdentifiers): - Null and empty strings are forbidden for literal initialization. Use the most efficient constructors - instead of a literal. - - * runtime/Identifier.cpp: - (IdentifierASCIIStringTranslator): - Rename IdentifierCStringTranslator to IdentifierASCIIStringTranslator to make the text encoding - explicit. - (JSC::IdentifierASCIIStringTranslator::hash): - (JSC::IdentifierASCIIStringTranslator::equal): - (JSC::IdentifierASCIIStringTranslator::translate): Use the fast initialization from literal. - (JSC::Identifier::add): - * runtime/Identifier.h: - (JSC::Identifier::Identifier): - -2012-08-07 Simon Hausmann <simon.hausmann@nokia.com> - - [Qt][Win] Remove pthreads linkage - - Reviewed by Csaba Osztrogonác. - - After r124823 linkage to pthreads is not needed anymore for the Windows - build. - - * JavaScriptCore.pri: - -2012-08-07 Gabor Ballabas <gaborb@inf.u-szeged.hu> - - Refactor emit*Inst functions and introduce toARMWord functions in DFG-JIT's traditional ARM port - https://bugs.webkit.org/show_bug.cgi?id=93266 - - Reviewed by Csaba Osztrogonác. - - First part of a bigger refactoring issue trying to make traditional - ARM DFG-JIT port easier to read and understand. - - - * assembler/ARMAssembler.h: - (JSC::ARMAssembler::emitInstruction): - (JSC::ARMAssembler::emitDoublePrecisionInstruction): - (JSC::ARMAssembler::emitSinglePrecisionInstruction): - (JSC::ARMAssembler::and_r): - (JSC::ARMAssembler::ands_r): - (JSC::ARMAssembler::eor_r): - (JSC::ARMAssembler::eors_r): - (JSC::ARMAssembler::sub_r): - (JSC::ARMAssembler::subs_r): - (JSC::ARMAssembler::rsb_r): - (JSC::ARMAssembler::rsbs_r): - (JSC::ARMAssembler::add_r): - (JSC::ARMAssembler::adds_r): - (JSC::ARMAssembler::adc_r): - (JSC::ARMAssembler::adcs_r): - (JSC::ARMAssembler::sbc_r): - (JSC::ARMAssembler::sbcs_r): - (JSC::ARMAssembler::rsc_r): - (JSC::ARMAssembler::rscs_r): - (JSC::ARMAssembler::tst_r): - (JSC::ARMAssembler::teq_r): - (JSC::ARMAssembler::cmp_r): - (JSC::ARMAssembler::cmn_r): - (JSC::ARMAssembler::orr_r): - (JSC::ARMAssembler::orrs_r): - (JSC::ARMAssembler::mov_r): - (JSC::ARMAssembler::movw_r): - (JSC::ARMAssembler::movt_r): - (JSC::ARMAssembler::movs_r): - (JSC::ARMAssembler::bic_r): - (JSC::ARMAssembler::bics_r): - (JSC::ARMAssembler::mvn_r): - (JSC::ARMAssembler::mvns_r): - (JSC::ARMAssembler::mul_r): - (JSC::ARMAssembler::muls_r): - (JSC::ARMAssembler::mull_r): - (JSC::ARMAssembler::vmov_f64_r): - (JSC::ARMAssembler::vadd_f64_r): - (JSC::ARMAssembler::vdiv_f64_r): - (JSC::ARMAssembler::vsub_f64_r): - (JSC::ARMAssembler::vmul_f64_r): - (JSC::ARMAssembler::vcmp_f64_r): - (JSC::ARMAssembler::vsqrt_f64_r): - (JSC::ARMAssembler::vabs_f64_r): - (JSC::ARMAssembler::vneg_f64_r): - (JSC::ARMAssembler::ldr_imm): - (JSC::ARMAssembler::ldr_un_imm): - (JSC::ARMAssembler::dtr_u): - (JSC::ARMAssembler::dtr_ur): - (JSC::ARMAssembler::dtr_d): - (JSC::ARMAssembler::dtr_dr): - (JSC::ARMAssembler::dtrh_u): - (JSC::ARMAssembler::dtrh_ur): - (JSC::ARMAssembler::dtrh_d): - (JSC::ARMAssembler::dtrh_dr): - (JSC::ARMAssembler::fdtr_u): - (JSC::ARMAssembler::fdtr_d): - (JSC::ARMAssembler::push_r): - (JSC::ARMAssembler::pop_r): - (JSC::ARMAssembler::vmov_vfp64_r): - (JSC::ARMAssembler::vmov_arm64_r): - (JSC::ARMAssembler::vmov_vfp32_r): - (JSC::ARMAssembler::vmov_arm32_r): - (JSC::ARMAssembler::vcvt_f64_s32_r): - (JSC::ARMAssembler::vcvt_s32_f64_r): - (JSC::ARMAssembler::vcvt_u32_f64_r): - (JSC::ARMAssembler::vcvt_f64_f32_r): - (JSC::ARMAssembler::vcvt_f32_f64_r): - (JSC::ARMAssembler::vmrs_apsr): - (JSC::ARMAssembler::clz_r): - (JSC::ARMAssembler::bx): - (JSC::ARMAssembler::blx): - (JSC::ARMAssembler::linkJump): - (JSC::ARMAssembler::toARMWord): - (ARMAssembler): - -2012-08-06 Patrick Gansterer <paroga@webkit.org> - - [WIN] Remove dependency on pthread from MachineStackMarker - https://bugs.webkit.org/show_bug.cgi?id=68429 - - Reviewed by Geoffrey Garen. - - Windows has no support for calling a destructor for thread specific data. - Since we need more control over creating and deleting thread specific keys - we can not simply extend WTF::ThreadSpecific with this functionality. - - All thread specific keys created via the new API get stored in a list. - After a thread function finished we iterate over this list and call - the registered destructor for every item if needed. - - * heap/MachineStackMarker.cpp: Use the new functions instead of pthread directly. - (JSC::MachineThreads::~MachineThreads): - (JSC::MachineThreads::makeUsableFromMultipleThreads): - (JSC::MachineThreads::addCurrentThread): - * heap/MachineStackMarker.h: - (MachineThreads): - -2012-08-06 Patrick Gansterer <paroga@webkit.org> - - Unify JSC date and time formating functions - https://bugs.webkit.org/show_bug.cgi?id=92282 - - Reviewed by Geoffrey Garen. - - Replace the existing functions for formating GregorianDateTime - with one single function. This removes some code duplications - in DatePrototype and is a preperation to fix encoding issues, - since we can add UChar* values to the resulting string now. - - * runtime/DateConstructor.cpp: - (JSC::callDate): - * runtime/DateConversion.cpp: - (JSC::formatDateTime): - * runtime/DateConversion.h: - (JSC): - * runtime/DatePrototype.cpp: - (JSC::formateDateInstance): - (JSC::dateProtoFuncToString): - (JSC::dateProtoFuncToUTCString): - (JSC::dateProtoFuncToDateString): - (JSC::dateProtoFuncToTimeString): - (JSC::dateProtoFuncToGMTString): - -2012-08-06 Carlos Garcia Campos <cgarcia@igalia.com> - - Unreviewed. Fix make distcheck. - - * GNUmakefile.list.am: Add missing header file. - -2012-08-05 Peter Wang <peter.wang@torchmobile.com.cn> - - Web Inspector: [JSC] implement setting breakpoints by line:column - https://bugs.webkit.org/show_bug.cgi?id=53003 - - Reviewed by Geoffrey Garen. - - Add a counter to Lexer to record the column info of each Token. Add a column parameter to - op_debug, cti_op_debug, and _llint_op_debug byte-code command. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::resolve): - (JSC::BytecodeGenerator::emitDebugHook): - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - * bytecompiler/NodesCodegen.cpp: - (JSC::ArrayNode::toArgumentList): - (JSC::ApplyFunctionCallDotNode::emitBytecode): - (JSC::ConstStatementNode::emitBytecode): - (JSC::EmptyStatementNode::emitBytecode): - (JSC::DebuggerStatementNode::emitBytecode): - (JSC::ExprStatementNode::emitBytecode): - (JSC::VarStatementNode::emitBytecode): - (JSC::IfNode::emitBytecode): - (JSC::IfElseNode::emitBytecode): - (JSC::DoWhileNode::emitBytecode): - (JSC::WhileNode::emitBytecode): - (JSC::ForNode::emitBytecode): - (JSC::ForInNode::emitBytecode): - (JSC::ContinueNode::emitBytecode): - (JSC::BreakNode::emitBytecode): - (JSC::ReturnNode::emitBytecode): - (JSC::WithNode::emitBytecode): - (JSC::SwitchNode::emitBytecode): - (JSC::LabelNode::emitBytecode): - (JSC::ThrowNode::emitBytecode): - (JSC::TryNode::emitBytecode): - (JSC::ProgramNode::emitBytecode): - (JSC::EvalNode::emitBytecode): - (JSC::FunctionBodyNode::emitBytecode): - * debugger/Debugger.h: - * interpreter/Interpreter.cpp: - (JSC::Interpreter::unwindCallFrame): - (JSC::Interpreter::throwException): - (JSC::Interpreter::debug): - (JSC::Interpreter::privateExecute): - * interpreter/Interpreter.h: - (Interpreter): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_debug): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_debug): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter.asm: - * parser/ASTBuilder.h: - (ASTBuilder): - (JSC::ASTBuilder::createCommaExpr): - (JSC::ASTBuilder::createLogicalNot): - (JSC::ASTBuilder::createUnaryPlus): - (JSC::ASTBuilder::createVoid): - (JSC::ASTBuilder::thisExpr): - (JSC::ASTBuilder::createResolve): - (JSC::ASTBuilder::createObjectLiteral): - (JSC::ASTBuilder::createArray): - (JSC::ASTBuilder::createNumberExpr): - (JSC::ASTBuilder::createString): - (JSC::ASTBuilder::createBoolean): - (JSC::ASTBuilder::createNull): - (JSC::ASTBuilder::createBracketAccess): - (JSC::ASTBuilder::createDotAccess): - (JSC::ASTBuilder::createRegExp): - (JSC::ASTBuilder::createNewExpr): - (JSC::ASTBuilder::createConditionalExpr): - (JSC::ASTBuilder::createAssignResolve): - (JSC::ASTBuilder::createFunctionExpr): - (JSC::ASTBuilder::createFunctionBody): - (JSC::ASTBuilder::createGetterOrSetterProperty): - (JSC::ASTBuilder::createArgumentsList): - (JSC::ASTBuilder::createPropertyList): - (JSC::ASTBuilder::createFuncDeclStatement): - (JSC::ASTBuilder::createBlockStatement): - (JSC::ASTBuilder::createExprStatement): - (JSC::ASTBuilder::createIfStatement): - (JSC::ASTBuilder::createForLoop): - (JSC::ASTBuilder::createForInLoop): - (JSC::ASTBuilder::createEmptyStatement): - (JSC::ASTBuilder::createVarStatement): - (JSC::ASTBuilder::createReturnStatement): - (JSC::ASTBuilder::createBreakStatement): - (JSC::ASTBuilder::createContinueStatement): - (JSC::ASTBuilder::createTryStatement): - (JSC::ASTBuilder::createSwitchStatement): - (JSC::ASTBuilder::createWhileStatement): - (JSC::ASTBuilder::createDoWhileStatement): - (JSC::ASTBuilder::createLabelStatement): - (JSC::ASTBuilder::createWithStatement): - (JSC::ASTBuilder::createThrowStatement): - (JSC::ASTBuilder::createDebugger): - (JSC::ASTBuilder::createConstStatement): - (JSC::ASTBuilder::appendConstDecl): - (JSC::ASTBuilder::combineCommaNodes): - (JSC::ASTBuilder::appendBinaryOperation): - (JSC::ASTBuilder::createAssignment): - (JSC::ASTBuilder::createNumber): - (JSC::ASTBuilder::makeTypeOfNode): - (JSC::ASTBuilder::makeDeleteNode): - (JSC::ASTBuilder::makeNegateNode): - (JSC::ASTBuilder::makeBitwiseNotNode): - (JSC::ASTBuilder::makeMultNode): - (JSC::ASTBuilder::makeDivNode): - (JSC::ASTBuilder::makeModNode): - (JSC::ASTBuilder::makeAddNode): - (JSC::ASTBuilder::makeSubNode): - (JSC::ASTBuilder::makeLeftShiftNode): - (JSC::ASTBuilder::makeRightShiftNode): - (JSC::ASTBuilder::makeURightShiftNode): - (JSC::ASTBuilder::makeBitOrNode): - (JSC::ASTBuilder::makeBitAndNode): - (JSC::ASTBuilder::makeBitXOrNode): - (JSC::ASTBuilder::makeFunctionCallNode): - (JSC::ASTBuilder::makeBinaryNode): - (JSC::ASTBuilder::makeAssignNode): - (JSC::ASTBuilder::makePrefixNode): - (JSC::ASTBuilder::makePostfixNode): - * parser/Lexer.cpp: - (JSC::::setCode): - (JSC::::internalShift): - (JSC::::shift): - (JSC::::lex): - * parser/Lexer.h: - (Lexer): - (JSC::Lexer::currentColumnNumber): - (JSC::::lexExpectIdentifier): - * parser/NodeConstructors.h: - (JSC::Node::Node): - (JSC::ExpressionNode::ExpressionNode): - (JSC::StatementNode::StatementNode): - (JSC::NullNode::NullNode): - (JSC::BooleanNode::BooleanNode): - (JSC::NumberNode::NumberNode): - (JSC::StringNode::StringNode): - (JSC::RegExpNode::RegExpNode): - (JSC::ThisNode::ThisNode): - (JSC::ResolveNode::ResolveNode): - (JSC::ArrayNode::ArrayNode): - (JSC::PropertyListNode::PropertyListNode): - (JSC::ObjectLiteralNode::ObjectLiteralNode): - (JSC::BracketAccessorNode::BracketAccessorNode): - (JSC::DotAccessorNode::DotAccessorNode): - (JSC::ArgumentListNode::ArgumentListNode): - (JSC::NewExprNode::NewExprNode): - (JSC::EvalFunctionCallNode::EvalFunctionCallNode): - (JSC::FunctionCallValueNode::FunctionCallValueNode): - (JSC::FunctionCallResolveNode::FunctionCallResolveNode): - (JSC::FunctionCallBracketNode::FunctionCallBracketNode): - (JSC::FunctionCallDotNode::FunctionCallDotNode): - (JSC::CallFunctionCallDotNode::CallFunctionCallDotNode): - (JSC::ApplyFunctionCallDotNode::ApplyFunctionCallDotNode): - (JSC::PrePostResolveNode::PrePostResolveNode): - (JSC::PostfixResolveNode::PostfixResolveNode): - (JSC::PostfixBracketNode::PostfixBracketNode): - (JSC::PostfixDotNode::PostfixDotNode): - (JSC::PostfixErrorNode::PostfixErrorNode): - (JSC::DeleteResolveNode::DeleteResolveNode): - (JSC::DeleteBracketNode::DeleteBracketNode): - (JSC::DeleteDotNode::DeleteDotNode): - (JSC::DeleteValueNode::DeleteValueNode): - (JSC::VoidNode::VoidNode): - (JSC::TypeOfResolveNode::TypeOfResolveNode): - (JSC::TypeOfValueNode::TypeOfValueNode): - (JSC::PrefixResolveNode::PrefixResolveNode): - (JSC::PrefixBracketNode::PrefixBracketNode): - (JSC::PrefixDotNode::PrefixDotNode): - (JSC::PrefixErrorNode::PrefixErrorNode): - (JSC::UnaryOpNode::UnaryOpNode): - (JSC::UnaryPlusNode::UnaryPlusNode): - (JSC::NegateNode::NegateNode): - (JSC::BitwiseNotNode::BitwiseNotNode): - (JSC::LogicalNotNode::LogicalNotNode): - (JSC::BinaryOpNode::BinaryOpNode): - (JSC::MultNode::MultNode): - (JSC::DivNode::DivNode): - (JSC::ModNode::ModNode): - (JSC::AddNode::AddNode): - (JSC::SubNode::SubNode): - (JSC::LeftShiftNode::LeftShiftNode): - (JSC::RightShiftNode::RightShiftNode): - (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode): - (JSC::LessNode::LessNode): - (JSC::GreaterNode::GreaterNode): - (JSC::LessEqNode::LessEqNode): - (JSC::GreaterEqNode::GreaterEqNode): - (JSC::ThrowableBinaryOpNode::ThrowableBinaryOpNode): - (JSC::InstanceOfNode::InstanceOfNode): - (JSC::InNode::InNode): - (JSC::EqualNode::EqualNode): - (JSC::NotEqualNode::NotEqualNode): - (JSC::StrictEqualNode::StrictEqualNode): - (JSC::NotStrictEqualNode::NotStrictEqualNode): - (JSC::BitAndNode::BitAndNode): - (JSC::BitOrNode::BitOrNode): - (JSC::BitXOrNode::BitXOrNode): - (JSC::LogicalOpNode::LogicalOpNode): - (JSC::ConditionalNode::ConditionalNode): - (JSC::ReadModifyResolveNode::ReadModifyResolveNode): - (JSC::AssignResolveNode::AssignResolveNode): - (JSC::ReadModifyBracketNode::ReadModifyBracketNode): - (JSC::AssignBracketNode::AssignBracketNode): - (JSC::AssignDotNode::AssignDotNode): - (JSC::ReadModifyDotNode::ReadModifyDotNode): - (JSC::AssignErrorNode::AssignErrorNode): - (JSC::CommaNode::CommaNode): - (JSC::ConstStatementNode::ConstStatementNode): - (JSC::EmptyStatementNode::EmptyStatementNode): - (JSC::DebuggerStatementNode::DebuggerStatementNode): - (JSC::ExprStatementNode::ExprStatementNode): - (JSC::VarStatementNode::VarStatementNode): - (JSC::IfNode::IfNode): - (JSC::IfElseNode::IfElseNode): - (JSC::DoWhileNode::DoWhileNode): - (JSC::WhileNode::WhileNode): - (JSC::ForNode::ForNode): - (JSC::ContinueNode::ContinueNode): - (JSC::BreakNode::BreakNode): - (JSC::ReturnNode::ReturnNode): - (JSC::WithNode::WithNode): - (JSC::LabelNode::LabelNode): - (JSC::ThrowNode::ThrowNode): - (JSC::TryNode::TryNode): - (JSC::FuncExprNode::FuncExprNode): - (JSC::FuncDeclNode::FuncDeclNode): - (JSC::SwitchNode::SwitchNode): - (JSC::ConstDeclNode::ConstDeclNode): - (JSC::BlockNode::BlockNode): - (JSC::ForInNode::ForInNode): - * parser/Nodes.cpp: - (JSC::StatementNode::setLoc): - (JSC): - (JSC::ScopeNode::ScopeNode): - (JSC::ProgramNode::ProgramNode): - (JSC::ProgramNode::create): - (JSC::EvalNode::EvalNode): - (JSC::EvalNode::create): - (JSC::FunctionBodyNode::FunctionBodyNode): - (JSC::FunctionBodyNode::create): - * parser/Nodes.h: - (Node): - (JSC::Node::columnNo): - (ExpressionNode): - (StatementNode): - (JSC::StatementNode::column): - (NullNode): - (BooleanNode): - (NumberNode): - (StringNode): - (RegExpNode): - (ThisNode): - (ResolveNode): - (ArrayNode): - (PropertyListNode): - (ObjectLiteralNode): - (BracketAccessorNode): - (DotAccessorNode): - (ArgumentListNode): - (NewExprNode): - (EvalFunctionCallNode): - (FunctionCallValueNode): - (FunctionCallResolveNode): - (FunctionCallBracketNode): - (FunctionCallDotNode): - (CallFunctionCallDotNode): - (ApplyFunctionCallDotNode): - (PrePostResolveNode): - (PostfixResolveNode): - (PostfixBracketNode): - (PostfixDotNode): - (PostfixErrorNode): - (DeleteResolveNode): - (DeleteBracketNode): - (DeleteDotNode): - (DeleteValueNode): - (VoidNode): - (TypeOfResolveNode): - (TypeOfValueNode): - (PrefixResolveNode): - (PrefixBracketNode): - (PrefixDotNode): - (PrefixErrorNode): - (UnaryOpNode): - (UnaryPlusNode): - (NegateNode): - (BitwiseNotNode): - (LogicalNotNode): - (BinaryOpNode): - (MultNode): - (DivNode): - (ModNode): - (AddNode): - (SubNode): - (LeftShiftNode): - (RightShiftNode): - (UnsignedRightShiftNode): - (LessNode): - (GreaterNode): - (LessEqNode): - (GreaterEqNode): - (ThrowableBinaryOpNode): - (InstanceOfNode): - (InNode): - (EqualNode): - (NotEqualNode): - (StrictEqualNode): - (NotStrictEqualNode): - (BitAndNode): - (BitOrNode): - (BitXOrNode): - (LogicalOpNode): - (ConditionalNode): - (ReadModifyResolveNode): - (AssignResolveNode): - (ReadModifyBracketNode): - (AssignBracketNode): - (AssignDotNode): - (ReadModifyDotNode): - (AssignErrorNode): - (CommaNode): - (ConstDeclNode): - (ConstStatementNode): - (BlockNode): - (EmptyStatementNode): - (DebuggerStatementNode): - (ExprStatementNode): - (VarStatementNode): - (IfNode): - (IfElseNode): - (DoWhileNode): - (WhileNode): - (ForNode): - (ForInNode): - (ContinueNode): - (BreakNode): - (ReturnNode): - (WithNode): - (LabelNode): - (ThrowNode): - (TryNode): - (ScopeNode): - (ProgramNode): - (EvalNode): - (FunctionBodyNode): - (FuncExprNode): - (FuncDeclNode): - (SwitchNode): - * parser/Parser.cpp: - (JSC::::parseSourceElements): - (JSC::::parseVarDeclaration): - (JSC::::parseConstDeclaration): - (JSC::::parseDoWhileStatement): - (JSC::::parseWhileStatement): - (JSC::::parseVarDeclarationList): - (JSC::::parseConstDeclarationList): - (JSC::::parseForStatement): - (JSC::::parseBreakStatement): - (JSC::::parseContinueStatement): - (JSC::::parseReturnStatement): - (JSC::::parseThrowStatement): - (JSC::::parseWithStatement): - (JSC::::parseSwitchStatement): - (JSC::::parseTryStatement): - (JSC::::parseDebuggerStatement): - (JSC::::parseBlockStatement): - (JSC::::parseStatement): - (JSC::::parseFunctionBody): - (JSC::::parseFunctionInfo): - (JSC::::parseFunctionDeclaration): - (JSC::::parseExpressionOrLabelStatement): - (JSC::::parseExpressionStatement): - (JSC::::parseIfStatement): - (JSC::::parseExpression): - (JSC::::parseAssignmentExpression): - (JSC::::parseConditionalExpression): - (JSC::::parseBinaryExpression): - (JSC::::parseProperty): - (JSC::::parseObjectLiteral): - (JSC::::parseStrictObjectLiteral): - (JSC::::parseArrayLiteral): - (JSC::::parsePrimaryExpression): - (JSC::::parseArguments): - (JSC::::parseMemberExpression): - (JSC::::parseUnaryExpression): - * parser/Parser.h: - (JSC::Parser::next): - (JSC::Parser::nextExpectIdentifier): - (JSC::Parser::tokenStart): - (JSC::Parser::tokenLine): - (JSC::Parser::tokenEnd): - (JSC::Parser::tokenLocation): - (Parser): - (JSC::Parser::getTokenName): - (JSC::::parse): - * parser/ParserTokens.h: - (JSC::JSTokenLocation::JSTokenLocation): - (JSTokenLocation): - (JSToken): - * parser/SourceProviderCacheItem.h: - (JSC::SourceProviderCacheItem::closeBraceToken): - * parser/SyntaxChecker.h: - (JSC::SyntaxChecker::makeFunctionCallNode): - (JSC::SyntaxChecker::createCommaExpr): - (JSC::SyntaxChecker::makeAssignNode): - (JSC::SyntaxChecker::makePrefixNode): - (JSC::SyntaxChecker::makePostfixNode): - (JSC::SyntaxChecker::makeTypeOfNode): - (JSC::SyntaxChecker::makeDeleteNode): - (JSC::SyntaxChecker::makeNegateNode): - (JSC::SyntaxChecker::makeBitwiseNotNode): - (JSC::SyntaxChecker::createLogicalNot): - (JSC::SyntaxChecker::createUnaryPlus): - (JSC::SyntaxChecker::createVoid): - (JSC::SyntaxChecker::thisExpr): - (JSC::SyntaxChecker::createResolve): - (JSC::SyntaxChecker::createObjectLiteral): - (JSC::SyntaxChecker::createArray): - (JSC::SyntaxChecker::createNumberExpr): - (JSC::SyntaxChecker::createString): - (JSC::SyntaxChecker::createBoolean): - (JSC::SyntaxChecker::createNull): - (JSC::SyntaxChecker::createBracketAccess): - (JSC::SyntaxChecker::createDotAccess): - (JSC::SyntaxChecker::createRegExp): - (JSC::SyntaxChecker::createNewExpr): - (JSC::SyntaxChecker::createConditionalExpr): - (JSC::SyntaxChecker::createAssignResolve): - (JSC::SyntaxChecker::createFunctionExpr): - (JSC::SyntaxChecker::createFunctionBody): - (JSC::SyntaxChecker::createArgumentsList): - (JSC::SyntaxChecker::createPropertyList): - (JSC::SyntaxChecker::createFuncDeclStatement): - (JSC::SyntaxChecker::createBlockStatement): - (JSC::SyntaxChecker::createExprStatement): - (JSC::SyntaxChecker::createIfStatement): - (JSC::SyntaxChecker::createForLoop): - (JSC::SyntaxChecker::createForInLoop): - (JSC::SyntaxChecker::createEmptyStatement): - (JSC::SyntaxChecker::createVarStatement): - (JSC::SyntaxChecker::createReturnStatement): - (JSC::SyntaxChecker::createBreakStatement): - (JSC::SyntaxChecker::createContinueStatement): - (JSC::SyntaxChecker::createTryStatement): - (JSC::SyntaxChecker::createSwitchStatement): - (JSC::SyntaxChecker::createWhileStatement): - (JSC::SyntaxChecker::createWithStatement): - (JSC::SyntaxChecker::createDoWhileStatement): - (JSC::SyntaxChecker::createLabelStatement): - (JSC::SyntaxChecker::createThrowStatement): - (JSC::SyntaxChecker::createDebugger): - (JSC::SyntaxChecker::createConstStatement): - (JSC::SyntaxChecker::appendConstDecl): - (JSC::SyntaxChecker::createGetterOrSetterProperty): - (JSC::SyntaxChecker::combineCommaNodes): - (JSC::SyntaxChecker::operatorStackPop): - -2012-08-03 Filip Pizlo <fpizlo@apple.com> - - Crashes in dfgBuildPutByIdList when clicking on just about anything on Google Maps - https://bugs.webkit.org/show_bug.cgi?id=92691 - - Reviewed by Mark Hahnenberg. - - The state of the stubs was changing after we determined the type (by virtue of the slow path - function that was called), since the get or put (in this case put) could cause arbitrary - side effects. Perhaps a full-blown fix would be to eliminate our reliance of the slow path - function to determine what to do, but an easier fix for now is to have the slow path give up - if its assumptions were invalidated by a side effect. - - * dfg/DFGOperations.cpp: - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - -2012-08-03 Filip Pizlo <fpizlo@apple.com> - - DFG handling of get_by_id should always inject a ForceOSRExit node if there is no prediction - https://bugs.webkit.org/show_bug.cgi?id=93162 - - Reviewed by Mark Hahnenberg. - - This simplifies the DFG IR by ensuring that all nodes that use value profiles will be preceded - by a ForceOSRExit if the value profile had no data. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - -2012-08-03 Filip Pizlo <fpizlo@apple.com> - - DFG::StructureCheckHoistingPhase keeps a Node& around for too long - https://bugs.webkit.org/show_bug.cgi?id=93157 - - Reviewed by Mark Hahnenberg. - - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - -2012-08-02 Patrick Gansterer <paroga@webkit.org> - - Move getLocalTime() as static inline function to DateMath - https://bugs.webkit.org/show_bug.cgi?id=92955 - - Reviewed by Ryosuke Niwa. - - getCurrentLocalTime() and getLocalTime() has been superseded with the - GregorianDateTime class. So we can move it into DateMath.cpp as an static inline - function. This allows us to remove the dependecy on time() and localtime() - for Windows CE, where this functions require the ce_time library to work. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-08-02 Filip Pizlo <fpizlo@apple.com> - - ASSERTION FAILED: at(m_compileIndex).canExit() || m_isCheckingArgumentTypes - https://bugs.webkit.org/show_bug.cgi?id=91074 - - Reviewed by Mark Hahnenberg. - - Fixes a bug where the speculative JIT was performing an unnecessary speculation that the - CFA had proven shouldn't be performed, leading to asserts that a node should not have - exit sites. This is a debug-only assert with no release symptom - we were just emitting - a check that was not reachable. - - Also found, and fixed, a bug where structure check hoisting was slightly confusing the - CFA by inserting GetLocal's into the graph. CSE would clean the GetLocal's up, which - would make the backend happy - but the CFA would produce subtly wrong results. - - * bytecode/SpeculatedType.h: - (JSC::isOtherOrEmptySpeculation): - (JSC): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dump): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): - (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): - -2012-08-02 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, build fix for DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE). - - * dfg/DFGStructureCheckHoistingPhase.cpp: - (JSC::DFG::StructureCheckHoistingPhase::run): - -2012-08-01 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove all uses of ClassInfo for JSStrings in JIT code - https://bugs.webkit.org/show_bug.cgi?id=92935 - - Reviewed by Geoffrey Garen. - - This is the first step in removing our dependence on in-object ClassInfo pointers - in JIT code. Most of the changes are to check the Structure, which is unique for - JSString primitives. - - * bytecode/SpeculatedType.cpp: - (JSC::speculationFromClassInfo): - (JSC::speculationFromStructure): Changed to check the TypeInfo in the Structure - since there wasn't a JSGlobalData immediately available to grab the JSString - Structure out of. - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JITInlineMethods.h: - (JSC::JIT::emitLoadCharacterString): - * jit/JITOpcodes.cpp: - (JSC::JIT::privateCompileCTIMachineTrampolines): - (JSC::JIT::emit_op_to_primitive): - (JSC::JIT::emit_op_convert_this): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::privateCompileCTIMachineTrampolines): - (JSC::JIT::emit_op_to_primitive): - (JSC::JIT::emitSlow_op_eq): - (JSC::JIT::emitSlow_op_neq): - (JSC::JIT::compileOpStrictEq): - (JSC::JIT::emit_op_convert_this): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::stringGetByValStubGenerator): - (JSC::JIT::emitSlow_op_get_by_val): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::stringGetByValStubGenerator): - (JSC::JIT::emitSlow_op_get_by_val): - * jit/SpecializedThunkJIT.h: - (JSC::SpecializedThunkJIT::loadJSStringArgument): - * jit/ThunkGenerators.cpp: - (JSC::stringCharLoad): - (JSC::charCodeAtThunkGenerator): - (JSC::charAtThunkGenerator): - -2012-08-02 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, missed a style goof in the previous patch: "NodeIndex nodeIndex" - in a method signature is painfully redundant. - - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - -2012-08-02 Filip Pizlo <fpizlo@apple.com> - - DFGSpeculativeJIT.h has too many inline method bodies - https://bugs.webkit.org/show_bug.cgi?id=92957 - - Reviewed by Antti Koivisto. - - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::speculationCheck): - (DFG): - (JSC::DFG::SpeculativeJIT::speculationWatchpoint): - (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): - (JSC::DFG::SpeculativeJIT::speculationCheckWithConditionalDirection): - (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution): - (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - -2012-08-01 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r124406. - http://trac.webkit.org/changeset/124406 - https://bugs.webkit.org/show_bug.cgi?id=92951 - - it set the Mac bots on fire (Requested by pizlo on #webkit). - - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitDebugHook): - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - * bytecompiler/NodesCodegen.cpp: - (JSC::ArrayNode::toArgumentList): - (JSC::ApplyFunctionCallDotNode::emitBytecode): - (JSC::ConditionalNode::emitBytecode): - (JSC::ConstStatementNode::emitBytecode): - (JSC::EmptyStatementNode::emitBytecode): - (JSC::DebuggerStatementNode::emitBytecode): - (JSC::ExprStatementNode::emitBytecode): - (JSC::VarStatementNode::emitBytecode): - (JSC::IfNode::emitBytecode): - (JSC::IfElseNode::emitBytecode): - (JSC::DoWhileNode::emitBytecode): - (JSC::WhileNode::emitBytecode): - (JSC::ForNode::emitBytecode): - (JSC::ForInNode::emitBytecode): - (JSC::ContinueNode::emitBytecode): - (JSC::BreakNode::emitBytecode): - (JSC::ReturnNode::emitBytecode): - (JSC::WithNode::emitBytecode): - (JSC::SwitchNode::emitBytecode): - (JSC::LabelNode::emitBytecode): - (JSC::ThrowNode::emitBytecode): - (JSC::TryNode::emitBytecode): - (JSC::ProgramNode::emitBytecode): - (JSC::EvalNode::emitBytecode): - (JSC::FunctionBodyNode::emitBytecode): - * debugger/Debugger.h: - * interpreter/Interpreter.cpp: - (JSC::Interpreter::unwindCallFrame): - (JSC::Interpreter::throwException): - (JSC::Interpreter::debug): - * interpreter/Interpreter.h: - (Interpreter): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_debug): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_debug): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * parser/ASTBuilder.h: - (ASTBuilder): - (JSC::ASTBuilder::createCommaExpr): - (JSC::ASTBuilder::createLogicalNot): - (JSC::ASTBuilder::createUnaryPlus): - (JSC::ASTBuilder::createVoid): - (JSC::ASTBuilder::thisExpr): - (JSC::ASTBuilder::createResolve): - (JSC::ASTBuilder::createObjectLiteral): - (JSC::ASTBuilder::createArray): - (JSC::ASTBuilder::createNumberExpr): - (JSC::ASTBuilder::createString): - (JSC::ASTBuilder::createBoolean): - (JSC::ASTBuilder::createNull): - (JSC::ASTBuilder::createBracketAccess): - (JSC::ASTBuilder::createDotAccess): - (JSC::ASTBuilder::createRegExp): - (JSC::ASTBuilder::createNewExpr): - (JSC::ASTBuilder::createConditionalExpr): - (JSC::ASTBuilder::createAssignResolve): - (JSC::ASTBuilder::createFunctionExpr): - (JSC::ASTBuilder::createFunctionBody): - (JSC::ASTBuilder::createGetterOrSetterProperty): - (JSC::ASTBuilder::createArgumentsList): - (JSC::ASTBuilder::createPropertyList): - (JSC::ASTBuilder::createFuncDeclStatement): - (JSC::ASTBuilder::createBlockStatement): - (JSC::ASTBuilder::createExprStatement): - (JSC::ASTBuilder::createIfStatement): - (JSC::ASTBuilder::createForLoop): - (JSC::ASTBuilder::createForInLoop): - (JSC::ASTBuilder::createEmptyStatement): - (JSC::ASTBuilder::createVarStatement): - (JSC::ASTBuilder::createReturnStatement): - (JSC::ASTBuilder::createBreakStatement): - (JSC::ASTBuilder::createContinueStatement): - (JSC::ASTBuilder::createTryStatement): - (JSC::ASTBuilder::createSwitchStatement): - (JSC::ASTBuilder::createWhileStatement): - (JSC::ASTBuilder::createDoWhileStatement): - (JSC::ASTBuilder::createLabelStatement): - (JSC::ASTBuilder::createWithStatement): - (JSC::ASTBuilder::createThrowStatement): - (JSC::ASTBuilder::createDebugger): - (JSC::ASTBuilder::createConstStatement): - (JSC::ASTBuilder::appendConstDecl): - (JSC::ASTBuilder::combineCommaNodes): - (JSC::ASTBuilder::appendBinaryOperation): - (JSC::ASTBuilder::createAssignment): - (JSC::ASTBuilder::createNumber): - (JSC::ASTBuilder::makeTypeOfNode): - (JSC::ASTBuilder::makeDeleteNode): - (JSC::ASTBuilder::makeNegateNode): - (JSC::ASTBuilder::makeBitwiseNotNode): - (JSC::ASTBuilder::makeMultNode): - (JSC::ASTBuilder::makeDivNode): - (JSC::ASTBuilder::makeModNode): - (JSC::ASTBuilder::makeAddNode): - (JSC::ASTBuilder::makeSubNode): - (JSC::ASTBuilder::makeLeftShiftNode): - (JSC::ASTBuilder::makeRightShiftNode): - (JSC::ASTBuilder::makeURightShiftNode): - (JSC::ASTBuilder::makeBitOrNode): - (JSC::ASTBuilder::makeBitAndNode): - (JSC::ASTBuilder::makeBitXOrNode): - (JSC::ASTBuilder::makeFunctionCallNode): - (JSC::ASTBuilder::makeBinaryNode): - (JSC::ASTBuilder::makeAssignNode): - (JSC::ASTBuilder::makePrefixNode): - (JSC::ASTBuilder::makePostfixNode): - * parser/Lexer.cpp: - (JSC::::setCode): - (JSC::::internalShift): - (JSC::::shift): - (JSC::::lex): - * parser/Lexer.h: - (Lexer): - (JSC::::lexExpectIdentifier): - * parser/NodeConstructors.h: - (JSC::Node::Node): - (JSC::ExpressionNode::ExpressionNode): - (JSC::StatementNode::StatementNode): - (JSC::NullNode::NullNode): - (JSC::BooleanNode::BooleanNode): - (JSC::NumberNode::NumberNode): - (JSC::StringNode::StringNode): - (JSC::RegExpNode::RegExpNode): - (JSC::ThisNode::ThisNode): - (JSC::ResolveNode::ResolveNode): - (JSC::ArrayNode::ArrayNode): - (JSC::PropertyListNode::PropertyListNode): - (JSC::ObjectLiteralNode::ObjectLiteralNode): - (JSC::BracketAccessorNode::BracketAccessorNode): - (JSC::DotAccessorNode::DotAccessorNode): - (JSC::ArgumentListNode::ArgumentListNode): - (JSC::NewExprNode::NewExprNode): - (JSC::EvalFunctionCallNode::EvalFunctionCallNode): - (JSC::FunctionCallValueNode::FunctionCallValueNode): - (JSC::FunctionCallResolveNode::FunctionCallResolveNode): - (JSC::FunctionCallBracketNode::FunctionCallBracketNode): - (JSC::FunctionCallDotNode::FunctionCallDotNode): - (JSC::CallFunctionCallDotNode::CallFunctionCallDotNode): - (JSC::ApplyFunctionCallDotNode::ApplyFunctionCallDotNode): - (JSC::PrePostResolveNode::PrePostResolveNode): - (JSC::PostfixResolveNode::PostfixResolveNode): - (JSC::PostfixBracketNode::PostfixBracketNode): - (JSC::PostfixDotNode::PostfixDotNode): - (JSC::PostfixErrorNode::PostfixErrorNode): - (JSC::DeleteResolveNode::DeleteResolveNode): - (JSC::DeleteBracketNode::DeleteBracketNode): - (JSC::DeleteDotNode::DeleteDotNode): - (JSC::DeleteValueNode::DeleteValueNode): - (JSC::VoidNode::VoidNode): - (JSC::TypeOfResolveNode::TypeOfResolveNode): - (JSC::TypeOfValueNode::TypeOfValueNode): - (JSC::PrefixResolveNode::PrefixResolveNode): - (JSC::PrefixBracketNode::PrefixBracketNode): - (JSC::PrefixDotNode::PrefixDotNode): - (JSC::PrefixErrorNode::PrefixErrorNode): - (JSC::UnaryOpNode::UnaryOpNode): - (JSC::UnaryPlusNode::UnaryPlusNode): - (JSC::NegateNode::NegateNode): - (JSC::BitwiseNotNode::BitwiseNotNode): - (JSC::LogicalNotNode::LogicalNotNode): - (JSC::BinaryOpNode::BinaryOpNode): - (JSC::MultNode::MultNode): - (JSC::DivNode::DivNode): - (JSC::ModNode::ModNode): - (JSC::AddNode::AddNode): - (JSC::SubNode::SubNode): - (JSC::LeftShiftNode::LeftShiftNode): - (JSC::RightShiftNode::RightShiftNode): - (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode): - (JSC::LessNode::LessNode): - (JSC::GreaterNode::GreaterNode): - (JSC::LessEqNode::LessEqNode): - (JSC::GreaterEqNode::GreaterEqNode): - (JSC::ThrowableBinaryOpNode::ThrowableBinaryOpNode): - (JSC::InstanceOfNode::InstanceOfNode): - (JSC::InNode::InNode): - (JSC::EqualNode::EqualNode): - (JSC::NotEqualNode::NotEqualNode): - (JSC::StrictEqualNode::StrictEqualNode): - (JSC::NotStrictEqualNode::NotStrictEqualNode): - (JSC::BitAndNode::BitAndNode): - (JSC::BitOrNode::BitOrNode): - (JSC::BitXOrNode::BitXOrNode): - (JSC::LogicalOpNode::LogicalOpNode): - (JSC::ConditionalNode::ConditionalNode): - (JSC::ReadModifyResolveNode::ReadModifyResolveNode): - (JSC::AssignResolveNode::AssignResolveNode): - (JSC::ReadModifyBracketNode::ReadModifyBracketNode): - (JSC::AssignBracketNode::AssignBracketNode): - (JSC::AssignDotNode::AssignDotNode): - (JSC::ReadModifyDotNode::ReadModifyDotNode): - (JSC::AssignErrorNode::AssignErrorNode): - (JSC::CommaNode::CommaNode): - (JSC::ConstStatementNode::ConstStatementNode): - (JSC::EmptyStatementNode::EmptyStatementNode): - (JSC::DebuggerStatementNode::DebuggerStatementNode): - (JSC::ExprStatementNode::ExprStatementNode): - (JSC::VarStatementNode::VarStatementNode): - (JSC::IfNode::IfNode): - (JSC::IfElseNode::IfElseNode): - (JSC::DoWhileNode::DoWhileNode): - (JSC::WhileNode::WhileNode): - (JSC::ForNode::ForNode): - (JSC::ContinueNode::ContinueNode): - (JSC::BreakNode::BreakNode): - (JSC::ReturnNode::ReturnNode): - (JSC::WithNode::WithNode): - (JSC::LabelNode::LabelNode): - (JSC::ThrowNode::ThrowNode): - (JSC::TryNode::TryNode): - (JSC::FuncExprNode::FuncExprNode): - (JSC::FuncDeclNode::FuncDeclNode): - (JSC::SwitchNode::SwitchNode): - (JSC::ConstDeclNode::ConstDeclNode): - (JSC::BlockNode::BlockNode): - (JSC::ForInNode::ForInNode): - * parser/Nodes.cpp: - (JSC): - (JSC::StatementNode::setLoc): - (JSC::ScopeNode::ScopeNode): - (JSC::ProgramNode::ProgramNode): - (JSC::ProgramNode::create): - (JSC::EvalNode::EvalNode): - (JSC::EvalNode::create): - (JSC::FunctionBodyNode::FunctionBodyNode): - (JSC::FunctionBodyNode::create): - * parser/Nodes.h: - (Node): - (ExpressionNode): - (StatementNode): - (NullNode): - (BooleanNode): - (NumberNode): - (StringNode): - (RegExpNode): - (ThisNode): - (ResolveNode): - (ArrayNode): - (PropertyListNode): - (ObjectLiteralNode): - (BracketAccessorNode): - (DotAccessorNode): - (ArgumentListNode): - (NewExprNode): - (EvalFunctionCallNode): - (FunctionCallValueNode): - (FunctionCallResolveNode): - (FunctionCallBracketNode): - (FunctionCallDotNode): - (CallFunctionCallDotNode): - (ApplyFunctionCallDotNode): - (PrePostResolveNode): - (PostfixResolveNode): - (PostfixBracketNode): - (PostfixDotNode): - (PostfixErrorNode): - (DeleteResolveNode): - (DeleteBracketNode): - (DeleteDotNode): - (DeleteValueNode): - (VoidNode): - (TypeOfResolveNode): - (TypeOfValueNode): - (PrefixResolveNode): - (PrefixBracketNode): - (PrefixDotNode): - (PrefixErrorNode): - (UnaryOpNode): - (UnaryPlusNode): - (NegateNode): - (BitwiseNotNode): - (LogicalNotNode): - (BinaryOpNode): - (MultNode): - (DivNode): - (ModNode): - (AddNode): - (SubNode): - (LeftShiftNode): - (RightShiftNode): - (UnsignedRightShiftNode): - (LessNode): - (GreaterNode): - (LessEqNode): - (GreaterEqNode): - (ThrowableBinaryOpNode): - (InstanceOfNode): - (InNode): - (EqualNode): - (NotEqualNode): - (StrictEqualNode): - (NotStrictEqualNode): - (BitAndNode): - (BitOrNode): - (BitXOrNode): - (LogicalOpNode): - (ConditionalNode): - (ReadModifyResolveNode): - (AssignResolveNode): - (ReadModifyBracketNode): - (AssignBracketNode): - (AssignDotNode): - (ReadModifyDotNode): - (AssignErrorNode): - (CommaNode): - (ConstDeclNode): - (ConstStatementNode): - (BlockNode): - (EmptyStatementNode): - (DebuggerStatementNode): - (ExprStatementNode): - (VarStatementNode): - (IfNode): - (IfElseNode): - (DoWhileNode): - (WhileNode): - (ForNode): - (ForInNode): - (ContinueNode): - (BreakNode): - (ReturnNode): - (WithNode): - (LabelNode): - (ThrowNode): - (TryNode): - (ScopeNode): - (ProgramNode): - (EvalNode): - (FunctionBodyNode): - (FuncExprNode): - (FuncDeclNode): - (SwitchNode): - * parser/Parser.cpp: - (JSC::::parseSourceElements): - (JSC::::parseVarDeclaration): - (JSC::::parseConstDeclaration): - (JSC::::parseDoWhileStatement): - (JSC::::parseWhileStatement): - (JSC::::parseVarDeclarationList): - (JSC::::parseConstDeclarationList): - (JSC::::parseForStatement): - (JSC::::parseBreakStatement): - (JSC::::parseContinueStatement): - (JSC::::parseReturnStatement): - (JSC::::parseThrowStatement): - (JSC::::parseWithStatement): - (JSC::::parseSwitchStatement): - (JSC::::parseTryStatement): - (JSC::::parseDebuggerStatement): - (JSC::::parseBlockStatement): - (JSC::::parseStatement): - (JSC::::parseFunctionBody): - (JSC::::parseFunctionInfo): - (JSC::::parseFunctionDeclaration): - (JSC::::parseExpressionOrLabelStatement): - (JSC::::parseExpressionStatement): - (JSC::::parseIfStatement): - (JSC::::parseExpression): - (JSC::::parseAssignmentExpression): - (JSC::::parseConditionalExpression): - (JSC::::parseBinaryExpression): - (JSC::::parseProperty): - (JSC::::parseObjectLiteral): - (JSC::::parseStrictObjectLiteral): - (JSC::::parseArrayLiteral): - (JSC::::parsePrimaryExpression): - (JSC::::parseArguments): - (JSC::::parseMemberExpression): - (JSC::::parseUnaryExpression): - * parser/Parser.h: - (JSC::Parser::next): - (JSC::Parser::nextExpectIdentifier): - (JSC::Parser::tokenStart): - (JSC::Parser::tokenLine): - (JSC::Parser::tokenEnd): - (JSC::Parser::getTokenName): - (JSC::::parse): - * parser/ParserTokens.h: - (JSC::JSTokenInfo::JSTokenInfo): - (JSTokenInfo): - (JSToken): - * parser/SourceProviderCacheItem.h: - (JSC::SourceProviderCacheItem::closeBraceToken): - * parser/SyntaxChecker.h: - (JSC::SyntaxChecker::makeFunctionCallNode): - (JSC::SyntaxChecker::createCommaExpr): - (JSC::SyntaxChecker::makeAssignNode): - (JSC::SyntaxChecker::makePrefixNode): - (JSC::SyntaxChecker::makePostfixNode): - (JSC::SyntaxChecker::makeTypeOfNode): - (JSC::SyntaxChecker::makeDeleteNode): - (JSC::SyntaxChecker::makeNegateNode): - (JSC::SyntaxChecker::makeBitwiseNotNode): - (JSC::SyntaxChecker::createLogicalNot): - (JSC::SyntaxChecker::createUnaryPlus): - (JSC::SyntaxChecker::createVoid): - (JSC::SyntaxChecker::thisExpr): - (JSC::SyntaxChecker::createResolve): - (JSC::SyntaxChecker::createObjectLiteral): - (JSC::SyntaxChecker::createArray): - (JSC::SyntaxChecker::createNumberExpr): - (JSC::SyntaxChecker::createString): - (JSC::SyntaxChecker::createBoolean): - (JSC::SyntaxChecker::createNull): - (JSC::SyntaxChecker::createBracketAccess): - (JSC::SyntaxChecker::createDotAccess): - (JSC::SyntaxChecker::createRegExp): - (JSC::SyntaxChecker::createNewExpr): - (JSC::SyntaxChecker::createConditionalExpr): - (JSC::SyntaxChecker::createAssignResolve): - (JSC::SyntaxChecker::createFunctionExpr): - (JSC::SyntaxChecker::createFunctionBody): - (JSC::SyntaxChecker::createArgumentsList): - (JSC::SyntaxChecker::createPropertyList): - (JSC::SyntaxChecker::createFuncDeclStatement): - (JSC::SyntaxChecker::createBlockStatement): - (JSC::SyntaxChecker::createExprStatement): - (JSC::SyntaxChecker::createIfStatement): - (JSC::SyntaxChecker::createForLoop): - (JSC::SyntaxChecker::createForInLoop): - (JSC::SyntaxChecker::createEmptyStatement): - (JSC::SyntaxChecker::createVarStatement): - (JSC::SyntaxChecker::createReturnStatement): - (JSC::SyntaxChecker::createBreakStatement): - (JSC::SyntaxChecker::createContinueStatement): - (JSC::SyntaxChecker::createTryStatement): - (JSC::SyntaxChecker::createSwitchStatement): - (JSC::SyntaxChecker::createWhileStatement): - (JSC::SyntaxChecker::createWithStatement): - (JSC::SyntaxChecker::createDoWhileStatement): - (JSC::SyntaxChecker::createLabelStatement): - (JSC::SyntaxChecker::createThrowStatement): - (JSC::SyntaxChecker::createDebugger): - (JSC::SyntaxChecker::createConstStatement): - (JSC::SyntaxChecker::appendConstDecl): - (JSC::SyntaxChecker::createGetterOrSetterProperty): - (JSC::SyntaxChecker::combineCommaNodes): - (JSC::SyntaxChecker::operatorStackPop): - -2012-08-01 Peter Wang <peter.wang@torchmobile.com.cn> - - Web Inspector: [JSC] implement setting breakpoints by line:column - https://bugs.webkit.org/show_bug.cgi?id=53003 - - Reviewed by Geoffrey Garen. - - Add a counter in lexer to record the column of each token. Debugger will use column info - in "Pretty Print" debug mode of Inspector. - - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitDebugHook): - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - * bytecompiler/NodesCodegen.cpp: - (JSC::ArrayNode::toArgumentList): - (JSC::ApplyFunctionCallDotNode::emitBytecode): - (JSC::ConditionalNode::emitBytecode): - (JSC::ConstStatementNode::emitBytecode): - (JSC::EmptyStatementNode::emitBytecode): - (JSC::DebuggerStatementNode::emitBytecode): - (JSC::ExprStatementNode::emitBytecode): - (JSC::VarStatementNode::emitBytecode): - (JSC::IfNode::emitBytecode): - (JSC::IfElseNode::emitBytecode): - (JSC::DoWhileNode::emitBytecode): - (JSC::WhileNode::emitBytecode): - (JSC::ForNode::emitBytecode): - (JSC::ForInNode::emitBytecode): - (JSC::ContinueNode::emitBytecode): - (JSC::BreakNode::emitBytecode): - (JSC::ReturnNode::emitBytecode): - (JSC::WithNode::emitBytecode): - (JSC::SwitchNode::emitBytecode): - (JSC::LabelNode::emitBytecode): - (JSC::ThrowNode::emitBytecode): - (JSC::TryNode::emitBytecode): - (JSC::ProgramNode::emitBytecode): - (JSC::EvalNode::emitBytecode): - (JSC::FunctionBodyNode::emitBytecode): - * debugger/Debugger.h: - * interpreter/Interpreter.cpp: - (JSC::Interpreter::unwindCallFrame): - (JSC::Interpreter::throwException): - (JSC::Interpreter::debug): - * interpreter/Interpreter.h: - (Interpreter): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_debug): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_debug): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * parser/ASTBuilder.h: - (ASTBuilder): - (JSC::ASTBuilder::createCommaExpr): - (JSC::ASTBuilder::createLogicalNot): - (JSC::ASTBuilder::createUnaryPlus): - (JSC::ASTBuilder::createVoid): - (JSC::ASTBuilder::thisExpr): - (JSC::ASTBuilder::createResolve): - (JSC::ASTBuilder::createObjectLiteral): - (JSC::ASTBuilder::createArray): - (JSC::ASTBuilder::createNumberExpr): - (JSC::ASTBuilder::createString): - (JSC::ASTBuilder::createBoolean): - (JSC::ASTBuilder::createNull): - (JSC::ASTBuilder::createBracketAccess): - (JSC::ASTBuilder::createDotAccess): - (JSC::ASTBuilder::createRegExp): - (JSC::ASTBuilder::createNewExpr): - (JSC::ASTBuilder::createConditionalExpr): - (JSC::ASTBuilder::createAssignResolve): - (JSC::ASTBuilder::createFunctionExpr): - (JSC::ASTBuilder::createFunctionBody): - (JSC::ASTBuilder::createGetterOrSetterProperty): - (JSC::ASTBuilder::createArgumentsList): - (JSC::ASTBuilder::createPropertyList): - (JSC::ASTBuilder::createFuncDeclStatement): - (JSC::ASTBuilder::createBlockStatement): - (JSC::ASTBuilder::createExprStatement): - (JSC::ASTBuilder::createIfStatement): - (JSC::ASTBuilder::createForLoop): - (JSC::ASTBuilder::createForInLoop): - (JSC::ASTBuilder::createEmptyStatement): - (JSC::ASTBuilder::createVarStatement): - (JSC::ASTBuilder::createReturnStatement): - (JSC::ASTBuilder::createBreakStatement): - (JSC::ASTBuilder::createContinueStatement): - (JSC::ASTBuilder::createTryStatement): - (JSC::ASTBuilder::createSwitchStatement): - (JSC::ASTBuilder::createWhileStatement): - (JSC::ASTBuilder::createDoWhileStatement): - (JSC::ASTBuilder::createLabelStatement): - (JSC::ASTBuilder::createWithStatement): - (JSC::ASTBuilder::createThrowStatement): - (JSC::ASTBuilder::createDebugger): - (JSC::ASTBuilder::createConstStatement): - (JSC::ASTBuilder::appendConstDecl): - (JSC::ASTBuilder::combineCommaNodes): - (JSC::ASTBuilder::appendBinaryOperation): - (JSC::ASTBuilder::createAssignment): - (JSC::ASTBuilder::createNumber): - (JSC::ASTBuilder::makeTypeOfNode): - (JSC::ASTBuilder::makeDeleteNode): - (JSC::ASTBuilder::makeNegateNode): - (JSC::ASTBuilder::makeBitwiseNotNode): - (JSC::ASTBuilder::makeMultNode): - (JSC::ASTBuilder::makeDivNode): - (JSC::ASTBuilder::makeModNode): - (JSC::ASTBuilder::makeAddNode): - (JSC::ASTBuilder::makeSubNode): - (JSC::ASTBuilder::makeLeftShiftNode): - (JSC::ASTBuilder::makeRightShiftNode): - (JSC::ASTBuilder::makeURightShiftNode): - (JSC::ASTBuilder::makeBitOrNode): - (JSC::ASTBuilder::makeBitAndNode): - (JSC::ASTBuilder::makeBitXOrNode): - (JSC::ASTBuilder::makeFunctionCallNode): - (JSC::ASTBuilder::makeBinaryNode): - (JSC::ASTBuilder::makeAssignNode): - (JSC::ASTBuilder::makePrefixNode): - (JSC::ASTBuilder::makePostfixNode): - * parser/Lexer.cpp: - (JSC::::setCode): - (JSC::::internalShift): - (JSC::::shift): - (JSC::::lex): - * parser/Lexer.h: - (Lexer): - (JSC::Lexer::currentColumnNumber): - (JSC::::lexExpectIdentifier): - * parser/NodeConstructors.h: - (JSC::Node::Node): - (JSC::ExpressionNode::ExpressionNode): - (JSC::StatementNode::StatementNode): - (JSC::NullNode::NullNode): - (JSC::BooleanNode::BooleanNode): - (JSC::NumberNode::NumberNode): - (JSC::StringNode::StringNode): - (JSC::RegExpNode::RegExpNode): - (JSC::ThisNode::ThisNode): - (JSC::ResolveNode::ResolveNode): - (JSC::ArrayNode::ArrayNode): - (JSC::PropertyListNode::PropertyListNode): - (JSC::ObjectLiteralNode::ObjectLiteralNode): - (JSC::BracketAccessorNode::BracketAccessorNode): - (JSC::DotAccessorNode::DotAccessorNode): - (JSC::ArgumentListNode::ArgumentListNode): - (JSC::NewExprNode::NewExprNode): - (JSC::EvalFunctionCallNode::EvalFunctionCallNode): - (JSC::FunctionCallValueNode::FunctionCallValueNode): - (JSC::FunctionCallResolveNode::FunctionCallResolveNode): - (JSC::FunctionCallBracketNode::FunctionCallBracketNode): - (JSC::FunctionCallDotNode::FunctionCallDotNode): - (JSC::CallFunctionCallDotNode::CallFunctionCallDotNode): - (JSC::ApplyFunctionCallDotNode::ApplyFunctionCallDotNode): - (JSC::PrePostResolveNode::PrePostResolveNode): - (JSC::PostfixResolveNode::PostfixResolveNode): - (JSC::PostfixBracketNode::PostfixBracketNode): - (JSC::PostfixDotNode::PostfixDotNode): - (JSC::PostfixErrorNode::PostfixErrorNode): - (JSC::DeleteResolveNode::DeleteResolveNode): - (JSC::DeleteBracketNode::DeleteBracketNode): - (JSC::DeleteDotNode::DeleteDotNode): - (JSC::DeleteValueNode::DeleteValueNode): - (JSC::VoidNode::VoidNode): - (JSC::TypeOfResolveNode::TypeOfResolveNode): - (JSC::TypeOfValueNode::TypeOfValueNode): - (JSC::PrefixResolveNode::PrefixResolveNode): - (JSC::PrefixBracketNode::PrefixBracketNode): - (JSC::PrefixDotNode::PrefixDotNode): - (JSC::PrefixErrorNode::PrefixErrorNode): - (JSC::UnaryOpNode::UnaryOpNode): - (JSC::UnaryPlusNode::UnaryPlusNode): - (JSC::NegateNode::NegateNode): - (JSC::BitwiseNotNode::BitwiseNotNode): - (JSC::LogicalNotNode::LogicalNotNode): - (JSC::BinaryOpNode::BinaryOpNode): - (JSC::MultNode::MultNode): - (JSC::DivNode::DivNode): - (JSC::ModNode::ModNode): - (JSC::AddNode::AddNode): - (JSC::SubNode::SubNode): - (JSC::LeftShiftNode::LeftShiftNode): - (JSC::RightShiftNode::RightShiftNode): - (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode): - (JSC::LessNode::LessNode): - (JSC::GreaterNode::GreaterNode): - (JSC::LessEqNode::LessEqNode): - (JSC::GreaterEqNode::GreaterEqNode): - (JSC::ThrowableBinaryOpNode::ThrowableBinaryOpNode): - (JSC::InstanceOfNode::InstanceOfNode): - (JSC::InNode::InNode): - (JSC::EqualNode::EqualNode): - (JSC::NotEqualNode::NotEqualNode): - (JSC::StrictEqualNode::StrictEqualNode): - (JSC::NotStrictEqualNode::NotStrictEqualNode): - (JSC::BitAndNode::BitAndNode): - (JSC::BitOrNode::BitOrNode): - (JSC::BitXOrNode::BitXOrNode): - (JSC::LogicalOpNode::LogicalOpNode): - (JSC::ConditionalNode::ConditionalNode): - (JSC::ReadModifyResolveNode::ReadModifyResolveNode): - (JSC::AssignResolveNode::AssignResolveNode): - (JSC::ReadModifyBracketNode::ReadModifyBracketNode): - (JSC::AssignBracketNode::AssignBracketNode): - (JSC::AssignDotNode::AssignDotNode): - (JSC::ReadModifyDotNode::ReadModifyDotNode): - (JSC::AssignErrorNode::AssignErrorNode): - (JSC::CommaNode::CommaNode): - (JSC::ConstStatementNode::ConstStatementNode): - (JSC::EmptyStatementNode::EmptyStatementNode): - (JSC::DebuggerStatementNode::DebuggerStatementNode): - (JSC::ExprStatementNode::ExprStatementNode): - (JSC::VarStatementNode::VarStatementNode): - (JSC::IfNode::IfNode): - (JSC::IfElseNode::IfElseNode): - (JSC::DoWhileNode::DoWhileNode): - (JSC::WhileNode::WhileNode): - (JSC::ForNode::ForNode): - (JSC::ContinueNode::ContinueNode): - (JSC::BreakNode::BreakNode): - (JSC::ReturnNode::ReturnNode): - (JSC::WithNode::WithNode): - (JSC::LabelNode::LabelNode): - (JSC::ThrowNode::ThrowNode): - (JSC::TryNode::TryNode): - (JSC::FuncExprNode::FuncExprNode): - (JSC::FuncDeclNode::FuncDeclNode): - (JSC::SwitchNode::SwitchNode): - (JSC::ConstDeclNode::ConstDeclNode): - (JSC::BlockNode::BlockNode): - (JSC::ForInNode::ForInNode): - * parser/Nodes.cpp: - (JSC::StatementNode::setLoc): - (JSC): - (JSC::ScopeNode::ScopeNode): - (JSC::ProgramNode::ProgramNode): - (JSC::ProgramNode::create): - (JSC::EvalNode::EvalNode): - (JSC::EvalNode::create): - (JSC::FunctionBodyNode::FunctionBodyNode): - (JSC::FunctionBodyNode::create): - * parser/Nodes.h: - (Node): - (JSC::Node::columnNo): - (ExpressionNode): - (StatementNode): - (JSC::StatementNode::column): - (NullNode): - (BooleanNode): - (NumberNode): - (StringNode): - (RegExpNode): - (ThisNode): - (ResolveNode): - (ArrayNode): - (PropertyListNode): - (ObjectLiteralNode): - (BracketAccessorNode): - (DotAccessorNode): - (ArgumentListNode): - (NewExprNode): - (EvalFunctionCallNode): - (FunctionCallValueNode): - (FunctionCallResolveNode): - (FunctionCallBracketNode): - (FunctionCallDotNode): - (CallFunctionCallDotNode): - (ApplyFunctionCallDotNode): - (PrePostResolveNode): - (PostfixResolveNode): - (PostfixBracketNode): - (PostfixDotNode): - (PostfixErrorNode): - (DeleteResolveNode): - (DeleteBracketNode): - (DeleteDotNode): - (DeleteValueNode): - (VoidNode): - (TypeOfResolveNode): - (TypeOfValueNode): - (PrefixResolveNode): - (PrefixBracketNode): - (PrefixDotNode): - (PrefixErrorNode): - (UnaryOpNode): - (UnaryPlusNode): - (NegateNode): - (BitwiseNotNode): - (LogicalNotNode): - (BinaryOpNode): - (MultNode): - (DivNode): - (ModNode): - (AddNode): - (SubNode): - (LeftShiftNode): - (RightShiftNode): - (UnsignedRightShiftNode): - (LessNode): - (GreaterNode): - (LessEqNode): - (GreaterEqNode): - (ThrowableBinaryOpNode): - (InstanceOfNode): - (InNode): - (EqualNode): - (NotEqualNode): - (StrictEqualNode): - (NotStrictEqualNode): - (BitAndNode): - (BitOrNode): - (BitXOrNode): - (LogicalOpNode): - (ConditionalNode): - (ReadModifyResolveNode): - (AssignResolveNode): - (ReadModifyBracketNode): - (AssignBracketNode): - (AssignDotNode): - (ReadModifyDotNode): - (AssignErrorNode): - (CommaNode): - (ConstDeclNode): - (ConstStatementNode): - (BlockNode): - (EmptyStatementNode): - (DebuggerStatementNode): - (ExprStatementNode): - (VarStatementNode): - (IfNode): - (IfElseNode): - (DoWhileNode): - (WhileNode): - (ForNode): - (ForInNode): - (ContinueNode): - (BreakNode): - (ReturnNode): - (WithNode): - (LabelNode): - (ThrowNode): - (TryNode): - (ScopeNode): - (ProgramNode): - (EvalNode): - (FunctionBodyNode): - (FuncExprNode): - (FuncDeclNode): - (SwitchNode): - * parser/Parser.cpp: - (JSC::::parseSourceElements): - (JSC::::parseVarDeclaration): - (JSC::::parseConstDeclaration): - (JSC::::parseDoWhileStatement): - (JSC::::parseWhileStatement): - (JSC::::parseVarDeclarationList): - (JSC::::parseConstDeclarationList): - (JSC::::parseForStatement): - (JSC::::parseBreakStatement): - (JSC::::parseContinueStatement): - (JSC::::parseReturnStatement): - (JSC::::parseThrowStatement): - (JSC::::parseWithStatement): - (JSC::::parseSwitchStatement): - (JSC::::parseTryStatement): - (JSC::::parseDebuggerStatement): - (JSC::::parseBlockStatement): - (JSC::::parseStatement): - (JSC::::parseFunctionBody): - (JSC::::parseFunctionInfo): - (JSC::::parseFunctionDeclaration): - (JSC::::parseExpressionOrLabelStatement): - (JSC::::parseExpressionStatement): - (JSC::::parseIfStatement): - (JSC::::parseExpression): - (JSC::::parseAssignmentExpression): - (JSC::::parseConditionalExpression): - (JSC::::parseBinaryExpression): - (JSC::::parseProperty): - (JSC::::parseObjectLiteral): - (JSC::::parseStrictObjectLiteral): - (JSC::::parseArrayLiteral): - (JSC::::parsePrimaryExpression): - (JSC::::parseArguments): - (JSC::::parseMemberExpression): - (JSC::::parseUnaryExpression): - * parser/Parser.h: - (JSC::Parser::next): - (JSC::Parser::nextExpectIdentifier): - (JSC::Parser::tokenStart): - (JSC::Parser::tokenLine): - (JSC::Parser::tokenEnd): - (JSC::Parser::tokenLocation): - (Parser): - (JSC::Parser::getTokenName): - (JSC::::parse): - * parser/ParserTokens.h: - (JSC::JSTokenLocation::JSTokenLocation): - (JSTokenLocation): - (JSToken): - * parser/SourceProviderCacheItem.h: - (JSC::SourceProviderCacheItem::closeBraceToken): - * parser/SyntaxChecker.h: - (JSC::SyntaxChecker::makeFunctionCallNode): - (JSC::SyntaxChecker::createCommaExpr): - (JSC::SyntaxChecker::makeAssignNode): - (JSC::SyntaxChecker::makePrefixNode): - (JSC::SyntaxChecker::makePostfixNode): - (JSC::SyntaxChecker::makeTypeOfNode): - (JSC::SyntaxChecker::makeDeleteNode): - (JSC::SyntaxChecker::makeNegateNode): - (JSC::SyntaxChecker::makeBitwiseNotNode): - (JSC::SyntaxChecker::createLogicalNot): - (JSC::SyntaxChecker::createUnaryPlus): - (JSC::SyntaxChecker::createVoid): - (JSC::SyntaxChecker::thisExpr): - (JSC::SyntaxChecker::createResolve): - (JSC::SyntaxChecker::createObjectLiteral): - (JSC::SyntaxChecker::createArray): - (JSC::SyntaxChecker::createNumberExpr): - (JSC::SyntaxChecker::createString): - (JSC::SyntaxChecker::createBoolean): - (JSC::SyntaxChecker::createNull): - (JSC::SyntaxChecker::createBracketAccess): - (JSC::SyntaxChecker::createDotAccess): - (JSC::SyntaxChecker::createRegExp): - (JSC::SyntaxChecker::createNewExpr): - (JSC::SyntaxChecker::createConditionalExpr): - (JSC::SyntaxChecker::createAssignResolve): - (JSC::SyntaxChecker::createFunctionExpr): - (JSC::SyntaxChecker::createFunctionBody): - (JSC::SyntaxChecker::createArgumentsList): - (JSC::SyntaxChecker::createPropertyList): - (JSC::SyntaxChecker::createFuncDeclStatement): - (JSC::SyntaxChecker::createBlockStatement): - (JSC::SyntaxChecker::createExprStatement): - (JSC::SyntaxChecker::createIfStatement): - (JSC::SyntaxChecker::createForLoop): - (JSC::SyntaxChecker::createForInLoop): - (JSC::SyntaxChecker::createEmptyStatement): - (JSC::SyntaxChecker::createVarStatement): - (JSC::SyntaxChecker::createReturnStatement): - (JSC::SyntaxChecker::createBreakStatement): - (JSC::SyntaxChecker::createContinueStatement): - (JSC::SyntaxChecker::createTryStatement): - (JSC::SyntaxChecker::createSwitchStatement): - (JSC::SyntaxChecker::createWhileStatement): - (JSC::SyntaxChecker::createWithStatement): - (JSC::SyntaxChecker::createDoWhileStatement): - (JSC::SyntaxChecker::createLabelStatement): - (JSC::SyntaxChecker::createThrowStatement): - (JSC::SyntaxChecker::createDebugger): - (JSC::SyntaxChecker::createConstStatement): - (JSC::SyntaxChecker::appendConstDecl): - (JSC::SyntaxChecker::createGetterOrSetterProperty): - (JSC::SyntaxChecker::combineCommaNodes): - (JSC::SyntaxChecker::operatorStackPop): - -2012-08-01 Filip Pizlo <fpizlo@apple.com> - - DFG should hoist structure checks - https://bugs.webkit.org/show_bug.cgi?id=92696 - - Reviewed by Gavin Barraclough. - - This hoists structure checks in the same way that we would hoist array checks, but with added - complexity to cope with the fact that the structure of an object may change. This is handled - by performing a side effects analysis over the region in which the respective variable is - live. If a structure clobbering side effect may happen then we either hoist the structure - checks and fall back on structure transition watchpoints (if the watchpoint set is still - valid), or we avoid hoisting altogether. - - Doing this required teaching the CFA that we may have an expectation that an object has a - particular structure even after structure clobbering happens, in the sense that structure - proofs that were cobbered can be revived using watchpoints. CFA must know about this so that - OSR entry may know about it, since we cannot allow entry to happen if the variable has a - clobbered structure proof, will have a watchpoint to revive the proof, and the variable in - the baseline JIT has a completely unrelated structure. - - This is mostly performance neutral. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * bytecode/ValueRecovery.h: - (JSC::ValueRecovery::isSet): - (JSC::ValueRecovery::operator!): - (ValueRecovery): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - (JSC::DFG::AbstractState::clobberWorld): - (DFG): - (JSC::DFG::AbstractState::clobberCapturedVars): - * dfg/DFGAbstractState.h: - (AbstractState): - * dfg/DFGAbstractValue.h: - (JSC::DFG::AbstractValue::clear): - (JSC::DFG::AbstractValue::isClear): - (JSC::DFG::AbstractValue::makeTop): - (JSC::DFG::AbstractValue::isTop): - (JSC::DFG::AbstractValue::set): - (JSC::DFG::AbstractValue::operator==): - (JSC::DFG::AbstractValue::merge): - (JSC::DFG::AbstractValue::filter): - (JSC::DFG::AbstractValue::validate): - (JSC::DFG::AbstractValue::validateForEntry): - (AbstractValue): - (JSC::DFG::AbstractValue::checkConsistency): - (JSC::DFG::AbstractValue::dump): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::setLocal): - (JSC::DFG::ByteCodeParser::getArgument): - (JSC::DFG::ByteCodeParser::setArgument): - (JSC::DFG::ByteCodeParser::parseBlock): - (JSC::DFG::ByteCodeParser::fixVariableAccessSpeculations): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::checkStructureLoadElimination): - (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): - (JSC::DFG::CSEPhase::putStructureStoreElimination): - (JSC::DFG::CSEPhase::getLocalLoadElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dump): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::vote): - (Graph): - * dfg/DFGNode.h: - (JSC::DFG::Node::convertToStructureTransitionWatchpoint): - (Node): - (JSC::DFG::Node::hasStructureSet): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOSREntry.cpp: - (JSC::DFG::prepareOSREntry): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - (PredictionPropagationPhase): - (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): - (JSC::DFG::SpeculativeJIT::speculationCheckWithConditionalDirection): - (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection): - (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand): - (JSC::DFG::SpeculateCellOperand::gpr): - (SpeculateCellOperand): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::fillSpeculateCell): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::fillSpeculateCell): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGStructureCheckHoistingPhase.cpp: Added. - (DFG): - (StructureCheckHoistingPhase): - (JSC::DFG::StructureCheckHoistingPhase::StructureCheckHoistingPhase): - (JSC::DFG::StructureCheckHoistingPhase::run): - (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): - (JSC::DFG::StructureCheckHoistingPhase::noticeClobber): - (JSC::DFG::StructureCheckHoistingPhase::clobber): - (CheckData): - (JSC::DFG::StructureCheckHoistingPhase::CheckData::CheckData): - (JSC::DFG::performStructureCheckHoisting): - * dfg/DFGStructureCheckHoistingPhase.h: Added. - (DFG): - * dfg/DFGVariableAccessData.h: - (VariableAccessData): - (JSC::DFG::VariableAccessData::VariableAccessData): - (JSC::DFG::VariableAccessData::mergeStructureCheckHoistingFailed): - (JSC::DFG::VariableAccessData::structureCheckHoistingFailed): - (JSC::DFG::VariableAccessData::clearVotes): - (JSC::DFG::VariableAccessData::vote): - (JSC::DFG::VariableAccessData::voteRatio): - (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote): - * runtime/Options.h: - (JSC): - -2012-08-01 Filip Pizlo <fpizlo@apple.com> - - DFG should distinguish between PutByVal's that clobber the world and ones that don't - https://bugs.webkit.org/show_bug.cgi?id=92923 - - Reviewed by Mark Hahnenberg. - - This is performance-neutral. I also confirmed that it's neutral if we make the - clobbering variant (PutByValSafe) clobber all knowledge of what is an array, - which should feed nicely into work on removing uses of ClassInfo. - - * bytecode/DFGExitProfile.h: - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::getByValLoadElimination): - (JSC::DFG::CSEPhase::checkStructureLoadElimination): - (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): - (JSC::DFG::CSEPhase::getByOffsetLoadElimination): - (JSC::DFG::CSEPhase::putByOffsetStoreElimination): - (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): - (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::byValIsPure): - (JSC::DFG::Graph::clobbersWorld): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-08-01 Jian Li <jianli@chromium.org> - - Add new CSS property "-webkit-widget-region" to expose dashboard region support for other port - https://bugs.webkit.org/show_bug.cgi?id=90298 - - Reviewed by Adam Barth. - - * Configurations/FeatureDefines.xcconfig: Add ENABLE_WIDGET_REGION define. - -2012-08-01 Patrick Gansterer <paroga@webkit.org> - - Replace WTF::getCurrentLocalTime() with GregorianDateTime::setToCurrentLocalTime() - https://bugs.webkit.org/show_bug.cgi?id=92286 - - Reviewed by Geoffrey Garen. - - Add a method to GregorianDateTime to set its values to the current locale time. - Replacing all occurrences of getCurrentLocalTime with the new function allows - us to remove getCurrentLocalTime in a next step. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-08-01 Mark Hahnenberg <mhahnenberg@apple.com> - - C++ code should get ClassInfo from the Structure - https://bugs.webkit.org/show_bug.cgi?id=92892 - - Reviewed by Geoffrey Garen. - - In our march to remove ClassInfo from our JSCell object headers, we can switch - C++ code over to grabbing the ClassInfo from the Structure since it is finally - safe to do so now that Structure access is safe during finalization/destruction. - The remaining JIT code changes can be done in a separate patch. - - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::callDestructor): We don't want to clear the Structure any more - since the Structure should still be valid at this point. - * heap/WeakSetInlines.h: - (JSC::WeakBlock::finalize): Ditto. - * runtime/JSCell.h: - (JSC): - * runtime/Structure.h: - (JSC::JSCell::classInfo): Move JSCell's classInfo() to Structure.h so it can be - inline. Use a different method of getting the JSCell's Structure based on - whether we're in GC_VALIDATION mode or not, since always using get() will cause - infinite recursion in GC_VALIDATION mode. - (JSC): - -2012-07-31 Mark Hahnenberg <mhahnenberg@apple.com> - - MarkedBlock::sweep() should sweep another block if it can't sweep a Structure block - https://bugs.webkit.org/show_bug.cgi?id=92819 - - Reviewed by Geoffrey Garen. - - If we are forced to allocate a new block for Structures because we are unable to safely - sweep our pre-existing Structure blocks, we should sweep another random block so that we - can start sweeping Structure blocks sooner. - - * heap/IncrementalSweeper.cpp: - (JSC::IncrementalSweeper::doSweep): Change to use sweepNextBlock. - (JSC): - (JSC::IncrementalSweeper::sweepNextBlock): - * heap/IncrementalSweeper.h: - (IncrementalSweeper): - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::tryAllocateHelper): When we can't safely sweep - our Structure blocks, call sweepNextBlock instead. - -2012-07-31 Sam Weinig <sam@webkit.org> - - Fix the Windows build. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - -2012-07-31 Geoffrey Garen <ggaren@apple.com> - - Maybe fix the GCC build. - - * heap/HeapBlock.h: - (HeapBlock): Accommodate incorrect parsing in GCC. - -2012-07-31 Sam Weinig <sam@webkit.org> - - Stop masking 8 bits off of the visited link hash. We need all the bits! - https://bugs.webkit.org/show_bug.cgi?id=92799 - - Reviewed by Anders Carlsson. + Michael Saboff added an optimized version of UChar->LChar conversion in r125846. + Use this function in JSC::Identifier. * runtime/Identifier.cpp: - (JSC::IdentifierCStringTranslator::hash): - (JSC::IdentifierLCharFromUCharTranslator::hash): - * runtime/Identifier.h: - (JSC::IdentifierCharBufferTranslator::hash): - Update for new function names. - -2012-07-31 Geoffrey Garen <ggaren@apple.com> - - Maybe break the Windows build. - - Reviewed by Anders Carlsson. - - Formally objected to by Sam Weinig. - - * heap/HeapBlock.h: - (HeapBlock): Try to slightly improve this because we don't want Windows to control our lives. - -2012-07-30 Mark Hahnenberg <mhahnenberg@apple.com> + (JSC::IdentifierLCharFromUCharTranslator::translate): - Structures should be swept after all other objects - https://bugs.webkit.org/show_bug.cgi?id=92679 - - Reviewed by Filip Pizlo. - - In order to get rid of ClassInfo from our objects, we need to be able to safely get the - ClassInfo during the destruction of objects. We'd like to get the ClassInfo out of the - Structure, but currently it is not safe to do so because the order of destruction of objects - is not guaranteed to sweep objects before their corresponding Structure. We can fix this by - sweeping Structures after everything else. - - * heap/Heap.cpp: - (JSC::Heap::isSafeToSweepStructures): Add a function that checks if it is safe to sweep Structures. - If the Heap's IncrementalSweeper member is null, that means we're shutting down this VM and it is - safe to sweep structures since we'll always do Structures last anyways due to the ordering of - MarkedSpace::forEachBlock. - (JSC): - (JSC::Heap::didStartVMShutdown): Add this intermediate function to the Heap that ~JSGlobalData now - calls rather than calling the two HeapTimer objects individually. This allows the Heap to null out - these pointers after it has invalidated them to prevent accidental use-after-free in the sweep() - calls during lastChanceToFinalize(). - * heap/Heap.h: - (Heap): - * heap/HeapTimer.h: - (HeapTimer): - * heap/IncrementalSweeper.cpp: - (JSC::IncrementalSweeper::structuresCanBeSwept): Determines if it is currently safe to sweep Structures. - This decision is based on whether we have gotten to the end of the vector of blocks that need sweeping - the first time. - (JSC): - (JSC::IncrementalSweeper::doSweep): We add a second pass over the vector to sweep Structures after we - make our first pass. We now null out the slots as we sweep them so that we can quickly find the - Structures during the second pass. - (JSC::IncrementalSweeper::startSweeping): Initialize our new Structure sweeping index. - (JSC::IncrementalSweeper::willFinishSweeping): Callback that is called by MarkedSpace::sweep to notify - the IncrementalSweeper that we are going to sweep all of the remaining blocks in the Heap so it can - assume that everything is taken care of in the correct order. Since MarkedSpace::forEachBlock - iterates over the Structure blocks after all other blocks, the ordering property for sweeping Structures holds. - (JSC::IncrementalSweeper::IncrementalSweeper): Initialize Structure sweeping index. - * heap/IncrementalSweeper.h: Add declarations for new stuff. - (IncrementalSweeper): - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::tryAllocateHelper): We now check if the current block only contains structures and - if so and it isn't safe to sweep Structures according to the Heap, we just return early instead of doing - the normal lazy sweep. If this proves to be too much of a waste in the future we can add an extra clause that - will sweep some number of other blocks in place of the current block to mitigate the cost of the floating - Structure garbage. - (JSC::MarkedAllocator::addBlock): - * heap/MarkedAllocator.h: - (JSC::MarkedAllocator::zapFreeList): When we zap the free list in the MarkedAllocator, the current block is no - longer valid to allocate from, so we set the current block to null. - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::sweepHelper): Added a couple assertions to make sure that we weren't trying to sweep Structures - at an unsafe time. - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::sweep): Notify the IncrementalSweeper that the MarkedSpace will finish all currently remaining sweeping. - (JSC): - * heap/MarkedSpace.h: - (JSC): - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::~JSGlobalData): Call the new Heap::didStartVMShutdown. - -2012-07-31 Geoffrey Garen <ggaren@apple.com> - - Fix all the other builds I just broke. Maybe fix the Windows build. - - * heap/HeapBlock.h: - (HeapBlock): WTF? - -2012-07-31 Geoffrey Garen <ggaren@apple.com> - - Maybe fix the Windows build. - - * heap/HeapBlock.h: - (HeapBlock): WTF? - -2012-07-31 Geoffrey Garen <ggaren@apple.com> - - Maybe fix the Windows build. - - * heap/HeapBlock.h: - (HeapBlock): WTF? - -2012-07-31 Geoffrey Garen <ggaren@apple.com> - - Removed some public data and casting from the Heap - https://bugs.webkit.org/show_bug.cgi?id=92777 - - Reviewed by Oliver Hunt. - - * heap/BlockAllocator.cpp: - (JSC::BlockAllocator::releaseFreeBlocks): - (JSC::BlockAllocator::blockFreeingThreadMain): Use the DeadBlock class - since HeapBlock is a template, and not a class, now. Call destroy() - instead of monkeying around with DeadBlock's internal data because - encapsulation is good. - - * heap/BlockAllocator.h: - (DeadBlock): Added a class to represent a dead block, since HeapBlock is - a template now, and can't be instantiated directly. - - (JSC::DeadBlock::DeadBlock): - (JSC::DeadBlock::create): - (BlockAllocator): - (JSC::BlockAllocator::allocate): - (JSC::BlockAllocator::deallocate): Use the DeadBlock class because - encapsulation is good. - - * heap/CopiedBlock.h: - (CopiedBlock::destroy): No need for a destroy() function, since we - inherit one now. - - (JSC::CopiedBlock::CopiedBlock): - (JSC::CopiedBlock::payloadEnd): - (JSC::CopiedBlock::capacity): Updated for some encapsulation inside - HeapBlock. - - * heap/CopiedSpace.cpp: - (JSC::CopiedSpace::~CopiedSpace): - (JSC::CopiedSpace::doneCopying): - (JSC::CopiedSpace::size): - (JSC::CopiedSpace::capacity): - (JSC::isBlockListPagedOut): Removed a bunch of casting. This is no longer - necessary, now that our list and its nodes have the right type. - - * heap/CopiedSpace.h: Use the right type in our data structures because - it improves clarity. - - * heap/CopiedSpaceInlineMethods.h: - (JSC::CopiedSpace::startedCopying): Use swap to avoid duplicating it. - - * heap/HeapBlock.h: - (HeapBlock): Made this a class template so we can return the right type - in linked list operations. Made our data private because encapsulation - is good. - - (JSC::HeapBlock::destroy): Since we know our type, we can also eliminate - duplicate destroy() functions in our subclasses. - - (JSC::HeapBlock::allocation): Added an accessor so we can hide our data. - By using const, this accessor prevents clients from accidentally deleting - our allocation. - - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::isPagedOut): - (JSC::MarkedAllocator::tryAllocateHelper): - (JSC::MarkedAllocator::removeBlock): Removed a bunch of casting. This is - no longer necessary, now that our list and its nodes have the right type. - - * heap/MarkedAllocator.h: - (MarkedAllocator): - (JSC::MarkedAllocator::reset): - (JSC::MarkedAllocator::forEachBlock): Use the right type, do less casting. - - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::destroy): Removed this function because our parent - class provides it for us now. - - (JSC::MarkedBlock::MarkedBlock): - * heap/MarkedBlock.h: - (MarkedBlock): - (JSC::MarkedBlock::capacity): Updated for encapsulation. +2012-10-04 Michael Saboff <msaboff@apple.com> -2012-07-31 Filip Pizlo <fpizlo@apple.com> + After r130344, OpaqueJSString() creates a empty string which should be a null string + https://bugs.webkit.org/show_bug.cgi?id=98417 - DFG OSR exit profiling has unusual oversights - https://bugs.webkit.org/show_bug.cgi?id=92728 - - Reviewed by Geoffrey Garen. - - * dfg/DFGOSRExit.cpp: - (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::speculationWatchpoint): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-07-31 Chao-ying Fu <fu@mips.com> - - Add MIPS add32 function - https://bugs.webkit.org/show_bug.cgi?id=91522 - - Reviewed by Oliver Hunt. - - Add isCompactPtrAlignedAddressOffset. - Add a new version of add32 that accepts AbsoluteAddress as inputs. - - * assembler/MacroAssemblerMIPS.h: - (JSC::MacroAssemblerMIPS::isCompactPtrAlignedAddressOffset): New. - (MacroAssemblerMIPS): - (JSC::MacroAssemblerMIPS::add32): Support AbsoluteAddress as inputs. - -2012-07-30 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r124123. - http://trac.webkit.org/changeset/124123 - https://bugs.webkit.org/show_bug.cgi?id=92700 - - ASSERT crashes terminate webkit Layout tests (Requested by - msaboff on #webkit). - - * heap/Heap.cpp: - * heap/Heap.h: - (Heap): - * heap/IncrementalSweeper.cpp: - (JSC::IncrementalSweeper::doSweep): - (JSC::IncrementalSweeper::startSweeping): - (JSC::IncrementalSweeper::IncrementalSweeper): - (JSC): - * heap/IncrementalSweeper.h: - (IncrementalSweeper): - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::tryAllocateHelper): - (JSC::MarkedAllocator::addBlock): - * heap/MarkedAllocator.h: - (JSC::MarkedAllocator::zapFreeList): - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::sweepHelper): - * heap/MarkedSpace.cpp: - * heap/MarkedSpace.h: - (JSC::MarkedSpace::sweep): - (JSC): - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::~JSGlobalData): - -2012-07-30 Mark Hahnenberg <mhahnenberg@apple.com> - - Structures should be swept after all other objects - https://bugs.webkit.org/show_bug.cgi?id=92679 - - Reviewed by Filip Pizlo. - - In order to get rid of ClassInfo from our objects, we need to be able to safely get the - ClassInfo during the destruction of objects. We'd like to get the ClassInfo out of the - Structure, but currently it is not safe to do so because the order of destruction of objects - is not guaranteed to sweep objects before their corresponding Structure. We can fix this by - sweeping Structures after everything else. - - * heap/Heap.cpp: - (JSC::Heap::isSafeToSweepStructures): Add a function that checks if it is safe to sweep Structures. - If the Heap's IncrementalSweeper member is null, that means we're shutting down this VM and it is - safe to sweep structures since we'll always do Structures last anyways due to the ordering of - MarkedSpace::forEachBlock. - (JSC): - (JSC::Heap::didStartVMShutdown): Add this intermediate function to the Heap that ~JSGlobalData now - calls rather than calling the two HeapTimer objects individually. This allows the Heap to null out - these pointers after it has invalidated them to prevent accidental use-after-free in the sweep() - calls during lastChanceToFinalize(). - * heap/Heap.h: - (Heap): - * heap/HeapTimer.h: - (HeapTimer): - * heap/IncrementalSweeper.cpp: - (JSC::IncrementalSweeper::structuresCanBeSwept): Determines if it is currently safe to sweep Structures. - This decision is based on whether we have gotten to the end of the vector of blocks that need sweeping - the first time. - (JSC): - (JSC::IncrementalSweeper::doSweep): We add a second pass over the vector to sweep Structures after we - make our first pass. We now null out the slots as we sweep them so that we can quickly find the - Structures during the second pass. - (JSC::IncrementalSweeper::startSweeping): Initialize our new Structure sweeping index. - (JSC::IncrementalSweeper::willFinishSweeping): Callback that is called by MarkedSpace::sweep to notify - the IncrementalSweeper that we are going to sweep all of the remaining blocks in the Heap so it can - assume that everything is taken care of in the correct order. Since MarkedSpace::forEachBlock - iterates over the Structure blocks after all other blocks, the ordering property for sweeping Structures holds. - (JSC::IncrementalSweeper::IncrementalSweeper): Initialize Structure sweeping index. - * heap/IncrementalSweeper.h: Add declarations for new stuff. - (IncrementalSweeper): - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::tryAllocateHelper): We now check if the current block only contains structures and - if so and it isn't safe to sweep Structures according to the Heap, we just return early instead of doing - the normal lazy sweep. If this proves to be too much of a waste in the future we can add an extra clause that - will sweep some number of other blocks in place of the current block to mitigate the cost of the floating - Structure garbage. - (JSC::MarkedAllocator::addBlock): - * heap/MarkedAllocator.h: - (JSC::MarkedAllocator::zapFreeList): When we zap the free list in the MarkedAllocator, the current block is no - longer valid to allocate from, so we set the current block to null. - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::sweepHelper): Added a couple assertions to make sure that we weren't trying to sweep Structures - at an unsafe time. - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::sweep): Notify the IncrementalSweeper that the MarkedSpace will finish all currently remaining sweeping. - (JSC): - * heap/MarkedSpace.h: - (JSC): - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::~JSGlobalData): Call the new Heap::didStartVMShutdown. - -2012-07-29 Filip Pizlo <fpizlo@apple.com> - - PropertyNameArray::m_shouldCache is only assigned and never used - https://bugs.webkit.org/show_bug.cgi?id=92598 - - Reviewed by Dan Bernstein. - - * runtime/PropertyNameArray.h: - (JSC::PropertyNameArray::PropertyNameArray): - (PropertyNameArray): - -2012-07-29 Rik Cabanier <cabanier@adobe.com> - - Add ENABLE_CSS_COMPOSITING flag - https://bugs.webkit.org/show_bug.cgi?id=92553 - - Reviewed by Dirk Schulze. - - Adds compiler flag CSS_COMPOSITING to build systems to enable CSS blending and compositing. See spec https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html - - * Configurations/FeatureDefines.xcconfig: - -2012-07-27 Mark Hahnenberg <mhahnenberg@apple.com> - - Split functionality of MarkedAllocator::m_currentBlock - https://bugs.webkit.org/show_bug.cgi?id=92550 - - Reviewed by Filip Pizlo. + Reviewed by Alexey Proskuryakov. - MarkedAllocator::m_currentBlock serves two purposes right now; it indicates the block that is currently - being used for allocation and the beginning of the list of blocks that need to be swept. We should split - these two functionalities into two separate fields. + Removed the setting of enclosed string to an empty string from default constructor. + Before changeset r130344, the semantic was the default constructor produced a null + string. - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::tryAllocateHelper): Use m_blocksToSweep instead of m_currentBlock as the - initializer/reference of the loop. Only change m_currentBlock when we know what the result will be. - (JSC::MarkedAllocator::addBlock): When we add a new block we know that both m_blocksToSweep and - m_currentBlock are null. In order to preserve the invariant that m_currentBlock <= m_blocksToSweep, - we assign both of them to point to the new block. - (JSC::MarkedAllocator::removeBlock): We need a separate check to see if the block we're removing is - m_blocksToSweep and if so, advance it to the next block in the list. - * heap/MarkedAllocator.h: - (MarkedAllocator): Initialize m_blocksToSweep. - (JSC::MarkedAllocator::MarkedAllocator): - (JSC::MarkedAllocator::reset): We set m_blocksToSweep to be the head of our list. This function is called - at the end of a collection, so all of the blocks in our allocator need to be swept. We need to sweep a - block before we can start allocating, so m_currentBlock is set to null. We also set the freeList to - the empty FreeList to emphasize the fact that we can't start allocating until we do some sweeping. + * API/OpaqueJSString.h: + (OpaqueJSString::OpaqueJSString): -2012-07-27 Mark Hahnenberg <mhahnenberg@apple.com> +2012-10-04 Csaba Osztrogonác <ossy@webkit.org> - Increase inline storage for JSFinalObjects by one - https://bugs.webkit.org/show_bug.cgi?id=92526 + [Qt] Add missing LLInt dependencies to the build system + https://bugs.webkit.org/show_bug.cgi?id=98394 Reviewed by Geoffrey Garen. - Now that we've removed the inheritorID from objects, we can increase our inline storage for JSFinalObjects on - 64-bit platforms by 1. - - * llint/LowLevelInterpreter.asm: Change the constant. - * runtime/PropertyOffset.h: Change the constant. - (JSC): + * DerivedSources.pri: + * LLIntOffsetsExtractor.pro: -2012-07-27 Jer Noble <jer.noble@apple.com> +2012-10-03 Geoffrey Garen <ggaren@apple.com> - Support a rational time class for use by media elements. - https://bugs.webkit.org/show_bug.cgi?id=88787 + Next step toward fixing Windows: add new symbol. - Re-export WTF::MediaTime from JavaScriptCore. - - Reviewed by Eric Carlson. - - * JavaScriptCore.order: * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: -2012-07-26 Filip Pizlo <fpizlo@apple.com> - - JSObject::reallocateStorageIfNecessary is neither used nor defined - https://bugs.webkit.org/show_bug.cgi?id=92417 - - Reviewed by Mark Rowe. - - * runtime/JSObject.h: - (JSObject): - -2012-07-26 Mark Hahnenberg <mhahnenberg@apple.com> - - Allocate Structures in a separate part of the Heap - https://bugs.webkit.org/show_bug.cgi?id=92420 - - Reviewed by Filip Pizlo. - - To fix our issue with destruction/finalization of Structures before their objects, we can move Structures to a separate - part of the Heap that will be swept after all other objects. This first patch will just be separating Structures - out into their own separate MarkedAllocator. Everything else will behave identically. - - * heap/Heap.h: New function to allocate Structures in the Heap. - (Heap): - (JSC): - (JSC::Heap::allocateStructure): - * heap/MarkedAllocator.cpp: Pass whether or not we're allocated Structures to the MarkedBlock. - (JSC::MarkedAllocator::allocateBlock): - * heap/MarkedAllocator.h: Add tracking for whether or not we're allocating only Structures. - (JSC::MarkedAllocator::onlyContainsStructures): - (MarkedAllocator): - (JSC::MarkedAllocator::MarkedAllocator): - (JSC::MarkedAllocator::init): - * heap/MarkedBlock.cpp: Add tracking for whether or not we're allocating only Structures. We need this to be able to - distinguish the various MarkedBlock types in MarkedSpace::allocatorFor(MarkedBlock*). - (JSC::MarkedBlock::create): - (JSC::MarkedBlock::MarkedBlock): - * heap/MarkedBlock.h: - (MarkedBlock): - (JSC::MarkedBlock::onlyContainsStructures): - (JSC): - * heap/MarkedSpace.cpp: Include the new Structure allocator in all the places that all the other allocators are used/modified. - (JSC::MarkedSpace::MarkedSpace): - (JSC::MarkedSpace::resetAllocators): - (JSC::MarkedSpace::canonicalizeCellLivenessData): - (JSC::MarkedSpace::isPagedOut): - * heap/MarkedSpace.h: Add new MarkedAllocator just for Structures. - (MarkedSpace): - (JSC::MarkedSpace::allocatorFor): - (JSC::MarkedSpace::allocateStructure): - (JSC): - (JSC::MarkedSpace::forEachBlock): - * runtime/Structure.h: Move all of the functions that call allocateCell<Structure> down below the explicit template specialization - for allocateCell<Structure>. The new inline specialization for allocateCell directly calls the allocateStructure() function in the - Heap. - (Structure): - (JSC::Structure): - (JSC): - (JSC::Structure::create): - (JSC::Structure::createStructure): - -2012-07-26 Filip Pizlo <fpizlo@apple.com> - - JSArray has methods that are neither used nor defined - https://bugs.webkit.org/show_bug.cgi?id=92416 - - Reviewed by Simon Fraser. - - * runtime/JSArray.h: - (JSArray): - -2012-07-26 Zoltan Herczeg <zherczeg@webkit.org> - - [Qt][ARM]ARMAssembler needs buildfix afert r123417 - https://bugs.webkit.org/show_bug.cgi?id=92086 - - Reviewed by Csaba Osztrogonác. - - The ARM implementation of this should be optimized code path - is covered by a non-optimized code path. This patch fixes this, - and adds a new function which returns with the offset range. - - * assembler/ARMAssembler.h: - (JSC::ARMAssembler::readPointer): - (ARMAssembler): - (JSC::ARMAssembler::repatchInt32): - (JSC::ARMAssembler::repatchCompact): - * assembler/MacroAssemblerARM.h: - (MacroAssemblerARM): - (JSC::MacroAssemblerARM::isCompactPtrAlignedAddressOffset): - (JSC::MacroAssemblerARM::load32WithCompactAddressOffsetPatch): - -2012-07-25 Mark Hahnenberg <mhahnenberg@apple.com> - - Build fix for 32-bit after r123682 - - * runtime/JSObject.h: Need to pad out JSObjects on 32-bit so that they're the correct size since - we only removed one 4-byte word and we need to be 8-byte aligned. - (JSObject): - -2012-07-25 Filip Pizlo <fpizlo@apple.com> - - JSC GC object copying APIs should allow for greater flexibility - https://bugs.webkit.org/show_bug.cgi?id=92316 - - Reviewed by Mark Hahnenberg. - - It's now the case that visitChildren() methods can directly pin and allocate in new space during copying. - They can also do the copying and marking themselves. This new API is only used for JSObjects for now. +2012-10-03 Geoffrey Garen <ggaren@apple.com> - * JavaScriptCore.xcodeproj/project.pbxproj: - * heap/MarkStack.cpp: - (JSC::SlotVisitor::allocateNewSpaceSlow): - (JSC::SlotVisitor::allocateNewSpaceOrPin): - (JSC): - (JSC::SlotVisitor::copyAndAppend): - * heap/MarkStack.h: - (MarkStack): - (JSC::MarkStack::appendUnbarrieredValue): - (JSC): - * heap/SlotVisitor.h: - * heap/SlotVisitorInlineMethods.h: Added. - (JSC): - (JSC::SlotVisitor::checkIfShouldCopyAndPinOtherwise): - (JSC::SlotVisitor::allocateNewSpace): - * runtime/JSObject.cpp: - (JSC::JSObject::visitOutOfLineStorage): - (JSC): - (JSC::JSObject::visitChildren): - (JSC::JSFinalObject::visitChildren): - * runtime/JSObject.h: - (JSObject): - -2012-07-25 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove JSObject::m_inheritorID - https://bugs.webkit.org/show_bug.cgi?id=88378 - - Reviewed by Filip Pizlo. - - This is rarely used, and not performance critical (the commonly accessed copy is cached on JSFunction), - and most objects don't need an inheritorID (this value is only used if the object is used as a prototype). - Instead use a private named value in the object's property storage. - - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): No need m_inheritorID to initialize! - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): No need m_inheritorID to initialize! - * llint/LowLevelInterpreter.asm: No need m_inheritorID to initialize! - * runtime/JSGlobalData.h: - (JSGlobalData): Added private name 'm_inheritorIDKey'. - * runtime/JSGlobalThis.cpp: - (JSC::JSGlobalThis::setUnwrappedObject): resetInheritorID is now passed a JSGlobalData&. - * runtime/JSObject.cpp: - (JSC::JSObject::visitChildren): No m_inheritorID to be marked. - (JSC::JSFinalObject::visitChildren): No m_inheritorID to be marked. - (JSC::JSObject::createInheritorID): Store the newly created inheritorID in the property map. Make sure - it's got the DontEnum attribute!! - * runtime/JSObject.h: - (JSObject): - (JSC::JSObject::resetInheritorID): Remove the inheritorID from property storage. - (JSC): - (JSC::JSObject::inheritorID): Read the inheritorID from property storage. - -2012-07-25 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> - - Create a specialized pair for use in HashMap iterators - https://bugs.webkit.org/show_bug.cgi?id=92137 - - Reviewed by Ryosuke Niwa. - - Update a couple of sites that relied on the fact that "contents" of iterators were - std::pairs. - - * profiler/Profile.cpp: - (JSC): This code kept a vector of the pairs that were the "contents" of the iterators. This - is changed to use a KeyValuePair. We make use HashCount's ValueType (which represents only - the key) to get the proper key parameter for KeyValuePair. - * tools/ProfileTreeNode.h: - (ProfileTreeNode): Use HashMap::ValueType to declare the type of the contents of the hash - instead of declaring it manually. This will make use of the new KeyValuePair. - -2012-07-25 Patrick Gansterer <paroga@webkit.org> - - REGRESSION(r123505): Date.getYear() returns the same as Date.getFullYear() - https://bugs.webkit.org/show_bug.cgi?id=92218 - - Reviewed by Csaba Osztrogonác. - - * runtime/DatePrototype.cpp: - (JSC::dateProtoFuncGetYear): Added the missing offset of 1900 to the return value. - -2012-07-24 Filip Pizlo <fpizlo@apple.com> - - REGRESSION(r123417): It made tests assert/crash on 32 bit - https://bugs.webkit.org/show_bug.cgi?id=92088 - - Reviewed by Mark Hahnenberg. - - The pointer arithmetic was wrong, because negative numbers are hard to think about. - - * dfg/DFGRepatch.cpp: - (JSC::DFG::emitPutTransitionStub): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): - -2012-07-24 Patrick Gansterer <paroga@webkit.org> - - Store the full year in GregorianDateTime - https://bugs.webkit.org/show_bug.cgi?id=92067 - - Reviewed by Geoffrey Garen. - - Use the full year instead of the offset from year 1900 - for the year member variable of GregorianDateTime. - - * runtime/DateConstructor.cpp: - (JSC::constructDate): - (JSC::dateUTC): - * runtime/DateConversion.cpp: - (JSC::formatDate): - (JSC::formatDateUTCVariant): - * runtime/DatePrototype.cpp: - (JSC::formatLocaleDate): - (JSC::fillStructuresUsingDateArgs): - (JSC::dateProtoFuncToISOString): - (JSC::dateProtoFuncGetFullYear): - (JSC::dateProtoFuncGetUTCFullYear): - (JSC::dateProtoFuncSetYear): - * runtime/JSDateMath.cpp: - (JSC::gregorianDateTimeToMS): - (JSC::msToGregorianDateTime): - -2012-07-24 Patrick Gansterer <paroga@webkit.org> - - [WIN] Build fix after r123417. + First step toward fixing Windows: remove old symbol. * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: -2012-07-23 Patrick Gansterer <paroga@webkit.org> - - Move GregorianDateTime from JSC to WTF namespace - https://bugs.webkit.org/show_bug.cgi?id=91948 - - Reviewed by Geoffrey Garen. - - Moving GregorianDateTime into the WTF namespace allows us to us to - use it in WebCore too. The new class has the same behaviour as the - old struct. Only the unused timeZone member has been removed. - - * runtime/DateConstructor.cpp: - * runtime/DateConversion.cpp: - * runtime/DateConversion.h: - * runtime/DateInstance.h: - * runtime/DatePrototype.cpp: - * runtime/JSDateMath.cpp: - * runtime/JSDateMath.h: - -2012-07-23 Filip Pizlo <fpizlo@apple.com> +2012-10-03 Geoffrey Garen <ggaren@apple.com> - Property storage should grow in reverse address direction, to support butterflies - https://bugs.webkit.org/show_bug.cgi?id=91788 - - Reviewed by Geoffrey Garen. - - Changes property storage to grow to the left, and changes the property storage pointer to point - one 8-byte word (i.e. JSValue) to the right of the first value in the storage. - - Also improved debug support somewhat, by adding a describe() function to the jsc command-line, - and a slow mode of object access in LLInt. - - * assembler/ARMv7Assembler.h: - (JSC::ARMv7Assembler::repatchCompact): - * assembler/MacroAssemblerARMv7.h: - (MacroAssemblerARMv7): - (JSC::MacroAssemblerARMv7::isCompactPtrAlignedAddressOffset): - (JSC::MacroAssemblerARMv7::load32WithCompactAddressOffsetPatch): - * assembler/MacroAssemblerX86Common.h: - (JSC::MacroAssemblerX86Common::isCompactPtrAlignedAddressOffset): - (JSC::MacroAssemblerX86Common::repatchCompact): - * assembler/X86Assembler.h: - (JSC::X86Assembler::repatchCompact): - * bytecode/CodeBlock.cpp: - (JSC::dumpStructure): - * bytecode/GetByIdStatus.h: - (JSC::GetByIdStatus::GetByIdStatus): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGRepatch.cpp: - (JSC::DFG::tryCacheGetByID): - (JSC::DFG::emitPutTransitionStub): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): - (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * heap/ConservativeRoots.cpp: - (JSC::ConservativeRoots::genericAddPointer): - * heap/CopiedSpace.h: - (CopiedSpace): - * heap/CopiedSpaceInlineMethods.h: - (JSC::CopiedSpace::pinIfNecessary): - (JSC): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::compileGetDirectOffset): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::compileGetDirectOffset): - * jit/JITStubs.cpp: - (JSC::JITThunks::tryCacheGetByID): - * jsc.cpp: - (GlobalObject::finishCreation): - (functionDescribe): - * llint/LLIntCommon.h: - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/JSObject.cpp: - (JSC::JSObject::visitChildren): - (JSC::JSFinalObject::visitChildren): - (JSC::JSObject::growOutOfLineStorage): - * runtime/JSObject.h: - (JSC::JSObject::getDirectLocation): - (JSC::JSObject::offsetForLocation): - * runtime/JSValue.h: - (JSValue): - * runtime/PropertyOffset.h: - (JSC::offsetInOutOfLineStorage): - -2012-07-23 Filip Pizlo <fpizlo@apple.com> - - DFG is too aggressive in performing the specific value optimization on loads - https://bugs.webkit.org/show_bug.cgi?id=92034 - - Reviewed by Mark Hahnenberg. - - This ensures that we don't do optimizations based on a structure having a specific - value, if there is no way to detect that the value is despecified. This is the - case for dictionaries, since despecifying a value in a dictionary does not lead to - a transition and so cannot be caught by either structure checks or structure - transition watchpoints. - - * bytecode/GetByIdStatus.cpp: - (JSC::GetByIdStatus::computeFromLLInt): - (JSC::GetByIdStatus::computeForChain): - (JSC::GetByIdStatus::computeFor): - * bytecode/ResolveGlobalStatus.cpp: - (JSC::computeForStructure): - -2012-07-23 Filip Pizlo <fpizlo@apple.com> - - REGRESSION(r123169): It made fast/js/dfg-inline-arguments-use-from-uninlined-code.html fail on 32 bit platforms - https://bugs.webkit.org/show_bug.cgi?id=92002 - - Reviewed by Mark Hahnenberg. - - In the process of changing the nature of local variable typing, I forgot to modify one of the places where - we glue the DFG's notion of variable prediction to the runtime's notion of variable tagging. - - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-07-23 Simon Fraser <simon.fraser@apple.com> - - Part 2 of: Implement sticky positioning - https://bugs.webkit.org/show_bug.cgi?id=90046 - - Reviewed by Ojan Vafai. - - Turn on ENABLE_CSS_STICKY_POSITION. - - * Configurations/FeatureDefines.xcconfig: - -2012-07-23 Patrick Gansterer <paroga@webkit.org> - - Move JSC::parseDate() from DateConversion to JSDateMath - https://bugs.webkit.org/show_bug.cgi?id=91982 - - Reviewed by Geoffrey Garen. - - Moveing this function into the other files removes the dependency - on JSC spcific classes in DateConversion.{cpp|h}. - - * runtime/DateConversion.cpp: - * runtime/DateConversion.h: - (JSC): - * runtime/JSDateMath.cpp: - (JSC::parseDate): - (JSC): - * runtime/JSDateMath.h: - (JSC): - -2012-07-23 Simon Fraser <simon.fraser@apple.com> - - Part 1 of: Implement sticky positioning - https://bugs.webkit.org/show_bug.cgi?id=90046 - - Reviewed by Ojan Vafai. - - Add ENABLE_CSS_STICKY_POSITION, defaulting to off initially. - - Sort the ENABLE_CSS lines in the file. Make sure all the flags - are in FEATURE_DEFINES. - - * Configurations/FeatureDefines.xcconfig: - -2012-07-23 Yong Li <yoli@rim.com> - - [BlackBerry] Implement GCActivityCallback with platform timer - https://bugs.webkit.org/show_bug.cgi?id=90175 - - Reviewed by Rob Buis. - - Use JSLock when performing GC to avoid assertions. - - * runtime/GCActivityCallbackBlackBerry.cpp: - (JSC::DefaultGCActivityCallback::doWork): - -2012-07-23 Kent Tamura <tkent@chromium.org> - - Rename ENABLE_METER_TAG and ENABLE_PROGRESS_TAG to ENABLE_METER_ELEMENT and ENABLE_PROGRESS_ELEMENT respectively - https://bugs.webkit.org/show_bug.cgi?id=91941 - - Reviewed by Kentaro Hara. - - A flag name for an elmement should be ENABLE_*_ELEMENT. - - * Configurations/FeatureDefines.xcconfig: - -2012-07-22 Kent Tamura <tkent@chromium.org> - - Rename ENABLE_DETAILS to ENABLE_DETAILS_ELEMENT - https://bugs.webkit.org/show_bug.cgi?id=91928 - - Reviewed by Kentaro Hara. - - A flag name for an elmement should be ENABLE_*_ELEMENT. - - * Configurations/FeatureDefines.xcconfig: - -2012-07-21 Patrick Gansterer <paroga@webkit.org> - - [WIN] Use GetDateFormat and GetTimeFormat instead of strftime - https://bugs.webkit.org/show_bug.cgi?id=83436 - - Reviewed by Brent Fulgham. - - The MS CRT implementation of strftime calls the same two functions. - Using them directly avoids the overhead of parsing the format string and removes - the dependency on strftime() for WinCE where this function does not exist. - - * runtime/DatePrototype.cpp: - (JSC::formatLocaleDate): - -2012-07-20 Kent Tamura <tkent@chromium.org> - - Rename ENABLE_DATALIST to ENABLE_DATALIST_ELEMENT - https://bugs.webkit.org/show_bug.cgi?id=91846 - - Reviewed by Kentaro Hara. - - A flag name for an elmement should be ENABLE_*_ELEMENT. - - * Configurations/FeatureDefines.xcconfig: - -2012-07-20 Han Shen <shenhan@google.com> - - [Chromium] Compilation fails under gcc 4.7 - https://bugs.webkit.org/show_bug.cgi?id=90227 - - Reviewed by Tony Chang. - - Disable warnings about c++0x compatibility in gcc newer than 4.6. - - * JavaScriptCore.gyp/JavaScriptCore.gyp: - -2012-07-18 Filip Pizlo <fpizlo@apple.com> - - DFG cell checks should be hoisted - https://bugs.webkit.org/show_bug.cgi?id=91717 - - Reviewed by Geoffrey Garen. - - The DFG has always had the policy of hoisting array and integer checks to - the point of variable assignment. Eventually, we added doubles and booleans - to the mix. But cells should really be part of this as well, particularly - for 32-bit where accessing a known-type variable is dramatically cheaper - than accessing a variable whose types is only predicted but otherwise - unproven. - - This appears to be a definite speed-up for V8 on 32-bit, a possible speed-up - for Kraken, and a possible slow-down for V8 on 64-bit (around 0.2% if at - all). Any slow-downs can, and should, be addressed by making the hoisting - logic cognizant of variables that are never used in a manner that requires - type checks, and by sinking argument checks to the point(s) of first use. - - To make this work I had to change some OSR machinery, and special-case the - type predictions of the 'this' argument for constructors. OSR exit normally - assumes that arguments are boxed, which happens to be true because the - type prediction used for check hoisting is LUB'd with the type of the - argument that was passed in - so either the arguments are always stored to - with the full tag+payload, or if only the payload is stored then the tag - matches whatever the caller would have set. But not so with the 'this' - argument for constructors, which is not initialized by the caller. We - could make this more precise by having argument types for OSR be inferred - using similar machinery to other locals, but I figured that for this patch - I should use the surgical fix. - - * assembler/MacroAssemblerX86_64.h: - (JSC::MacroAssemblerX86_64::branchTestPtr): - (MacroAssemblerX86_64): - * assembler/X86Assembler.h: - (JSC::X86Assembler::testq_rm): - (X86Assembler): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::initialize): - (JSC::DFG::AbstractState::execute): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::isCreatedThisArgument): - (Graph): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::checkArgumentTypes): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGValueSource.h: - (JSC::DFG::ValueSource::forSpeculation): - -2012-07-19 Filip Pizlo <fpizlo@apple.com> - - Fast path of storage resize should be removed from property storage reallocation, since it is only useful for arrays - https://bugs.webkit.org/show_bug.cgi?id=91796 - - Reviewed by Geoffrey Garen. - - * dfg/DFGRepatch.cpp: - (JSC::DFG::emitPutTransitionStub): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): - * runtime/JSObject.cpp: - (JSC::JSObject::growOutOfLineStorage): - -2012-07-19 Mark Lam <mark.lam@apple.com> - - Bug fixes and enhancements for OfflineASM annotation system. - https://bugs.webkit.org/show_bug.cgi?id=91690 - - Reviewed by Filip Pizlo. - - * offlineasm/armv7.rb: added default handling of Instruction lower(). - * offlineasm/asm.rb: added more support for annotations and more pretty printing. - * offlineasm/ast.rb: added more support for annotations. - * offlineasm/config.rb: added $preferredCommentStartColumn, simplified $enableInstrAnnotations. - * offlineasm/parser.rb: added more support for annotations. - * offlineasm/transform.rb: added more support for annotations. - * offlineasm/x86.rb: added default handling of Instruction lower(). - -2012-07-19 Patrick Gansterer <paroga@webkit.org> - - [WIN] Fix compilation of JSGlobalData.h with ENABLE(DFG_JIT) - https://bugs.webkit.org/show_bug.cgi?id=91243 - - Reviewed by Geoffrey Garen. - - Disable MSVC warning 4200 "zero-sized array in struct/union" for JSC::ScratchBuffer. - - * runtime/JSGlobalData.h: - (JSC): - -2012-07-19 Mark Lam <mark.lam@apple.com> - - Fixed broken ENABLE_JIT=0 build. - https://bugs.webkit.org/show_bug.cgi?id=91725 - - Reviewed by Oliver Hunt. - - * bytecode/Watchpoint.cpp: - * heap/JITStubRoutineSet.h: - (JSC): - (JITStubRoutineSet): - (JSC::JITStubRoutineSet::JITStubRoutineSet): - (JSC::JITStubRoutineSet::~JITStubRoutineSet): - (JSC::JITStubRoutineSet::add): - (JSC::JITStubRoutineSet::clearMarks): - (JSC::JITStubRoutineSet::mark): - (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): - (JSC::JITStubRoutineSet::traceMarkedStubRoutines): - -2012-07-19 Kristóf Kosztyó <kkristof@inf.u-szeged.hu> - - [Qt] Unreviewed buildfix after r123042. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::dumpRegisters): - -2012-07-18 Filip Pizlo <fpizlo@apple.com> - - DFG should emit inline code for property storage (re)allocation - https://bugs.webkit.org/show_bug.cgi?id=91597 - - Reviewed by Oliver Hunt. - - This adds two new ops to the DFG IR: AllocatePropertyStorage and - ReallocatePropertyStorage. It enables these to interact properly with - CSE so that a GetPropertyStorage on something for which we have - obviously done a (Re)AllocatePropertyStorage will result in the - GetPropertyStorage being eliminated. Other than that, the code - emitted for these ops is identical to the code we were emitting in - the corresponding PutById stub. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::putStructureStoreElimination): - (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasStructureTransitionData): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): - (DFG): - (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * runtime/Structure.cpp: - (JSC::nextOutOfLineStorageCapacity): - * runtime/Structure.h: - (JSC): - -2012-07-16 Oliver Hunt <oliver@apple.com> - - dumpCallFrame is broken in ToT - https://bugs.webkit.org/show_bug.cgi?id=91444 - - Reviewed by Gavin Barraclough. - - Various changes have been made to the SF calling convention, but - dumpCallFrame has not been updated to reflect these changes. - That resulted in both bogus information, as well as numerous - assertions of sadness. - - This patch makes dumpCallFrame actually work again and adds the - wonderful feature of telling you the name of the variable that a - register reflects, or what value it contains. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::nameForRegister): - A really innefficient mechanism for finding the name of a local register. - This should only ever be used by debug code so this should be okay. - * bytecode/CodeBlock.h: - (CodeBlock): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::generate): - Debug builds no longer throw away a functions symbol table, this allows - us to actually perform a register# to name mapping - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::link): - We weren't propogating the bytecode offset here leading to assertions - in debug builds when dumping bytecode of DFG compiled code. - * interpreter/Interpreter.cpp: - (JSC): - (JSC::Interpreter::dumpRegisters): - Rework to actually be correct. - (JSC::getCallerInfo): - Return the byteocde offset as well now, given we have to determine it - anyway. - (JSC::Interpreter::getStackTrace): - (JSC::Interpreter::retrieveCallerFromVMCode): - * interpreter/Interpreter.h: - (Interpreter): - * jsc.cpp: - (GlobalObject::finishCreation): - (functionDumpCallFrame): - Give debug builds of JSC a method for calling dumpCallFrame so we can - inspect a callframe without requiring us to break in a debugger. - -2012-07-18 Filip Pizlo <fpizlo@apple.com> - - DFG 32-bit PutById transition stub storage reallocation case copies the first pointer of each JSValue instead of the whole JSValue - https://bugs.webkit.org/show_bug.cgi?id=91599 - - Reviewed by Geoffrey Garen. - - * dfg/DFGRepatch.cpp: - (JSC::DFG::emitPutTransitionStub): - -2012-07-17 Filip Pizlo <fpizlo@apple.com> - - DFG 32-bit PutById transition stub passes the payload/tag arguments to a DFG operation in the wrong order - https://bugs.webkit.org/show_bug.cgi?id=91576 - - Reviewed by Gavin Barraclough. - - * dfg/DFGRepatch.cpp: - (JSC::DFG::emitPutTransitionStub): - -2012-07-17 Filip Pizlo <fpizlo@apple.com> - - [Qt] REGRESSION(r122768, r122771): They broke jquery/data.html and inspector/elements/edit-dom-actions.html - https://bugs.webkit.org/show_bug.cgi?id=91476 - - Reviewed by Mark Hahnenberg. - - The 32-bit repatching code was not correctly adapted to the new world where there may not always - be an available scratch register. Fixed it by ensuring that the scratch register we select does - not overlap with the value tag. - - * dfg/DFGRepatch.cpp: - (JSC::DFG::generateProtoChainAccessStub): - (JSC::DFG::tryCacheGetByID): - (JSC::DFG::tryBuildGetByIDList): - (JSC::DFG::emitPutReplaceStub): - -2012-07-17 Gabor Rapcsanyi <rgabor@webkit.org> - - Unreviewed buildfix from Zoltan Herczeg after 122768. - - * dfg/DFGCCallHelpers.h: - (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): - (CCallHelpers): - -2012-07-17 David Barr <davidbarr@chromium.org> - - Introduce ENABLE_CSS_IMAGE_ORIENTATION compile flag - https://bugs.webkit.org/show_bug.cgi?id=89055 - - Reviewed by Kent Tamura. - - The css3-images module is at candidate recommendation. - http://www.w3.org/TR/2012/CR-css3-images-20120417/#the-image-orientation - - Add a configuration option for CSS image-orientation support, disabling it by default. - - * Configurations/FeatureDefines.xcconfig: - -2012-07-16 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, roll out 122790 because it broke the Windows build. I'm not - sure what to do with exported symbols that are predicated on NDEBUG. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * bytecode/CodeBlock.cpp: - (JSC): - * bytecode/CodeBlock.h: - (CodeBlock): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::generate): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::link): - * interpreter/Interpreter.cpp: - (JSC): - (JSC::Interpreter::dumpRegisters): - (JSC::getCallerInfo): - (JSC::Interpreter::getStackTrace): - (JSC::Interpreter::retrieveCallerFromVMCode): - * interpreter/Interpreter.h: - (Interpreter): - * jsc.cpp: - (GlobalObject::finishCreation): - -2012-07-16 Oliver Hunt <oliver@apple.com> - - dumpCallFrame is broken in ToT - https://bugs.webkit.org/show_bug.cgi?id=91444 - - Reviewed by Gavin Barraclough. - - Various changes have been made to the SF calling convention, but - dumpCallFrame has not been updated to reflect these changes. - That resulted in both bogus information, as well as numerous - assertions of sadness. - - This patch makes dumpCallFrame actually work again and adds the - wonderful feature of telling you the name of the variable that a - register reflects, or what value it contains. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::nameForRegister): - A really innefficient mechanism for finding the name of a local register. - This should only ever be used by debug code so this should be okay. - * bytecode/CodeBlock.h: - (CodeBlock): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::generate): - Debug builds no longer throw away a functions symbol table, this allows - us to actually perform a register# to name mapping - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::link): - We weren't propogating the bytecode offset here leading to assertions - in debug builds when dumping bytecode of DFG compiled code. - * interpreter/Interpreter.cpp: - (JSC): - (JSC::Interpreter::dumpRegisters): - Rework to actually be correct. - (JSC::getCallerInfo): - Return the byteocde offset as well now, given we have to determine it - anyway. - (JSC::Interpreter::getStackTrace): - (JSC::Interpreter::retrieveCallerFromVMCode): - * interpreter/Interpreter.h: - (Interpreter): - * jsc.cpp: - (GlobalObject::finishCreation): - (functionDumpCallFrame): - Give debug builds of JSC a method for calling dumpCallFrame so we can - inspect a callframe without requiring us to break in a debugger. - -2012-07-16 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, adding forgotten files. - - * dfg/DFGRegisterSet.h: Added. - (DFG): - (RegisterSet): - (JSC::DFG::RegisterSet::RegisterSet): - (JSC::DFG::RegisterSet::asPOD): - (JSC::DFG::RegisterSet::copyInfo): - (JSC::DFG::RegisterSet::set): - (JSC::DFG::RegisterSet::setGPRByIndex): - (JSC::DFG::RegisterSet::clear): - (JSC::DFG::RegisterSet::get): - (JSC::DFG::RegisterSet::getGPRByIndex): - (JSC::DFG::RegisterSet::getFreeGPR): - (JSC::DFG::RegisterSet::setFPRByIndex): - (JSC::DFG::RegisterSet::getFPRByIndex): - (JSC::DFG::RegisterSet::setByIndex): - (JSC::DFG::RegisterSet::getByIndex): - (JSC::DFG::RegisterSet::numberOfSetGPRs): - (JSC::DFG::RegisterSet::numberOfSetFPRs): - (JSC::DFG::RegisterSet::numberOfSetRegisters): - (JSC::DFG::RegisterSet::setBit): - (JSC::DFG::RegisterSet::clearBit): - (JSC::DFG::RegisterSet::getBit): - * dfg/DFGScratchRegisterAllocator.h: Added. - (DFG): - (ScratchRegisterAllocator): - (JSC::DFG::ScratchRegisterAllocator::ScratchRegisterAllocator): - (JSC::DFG::ScratchRegisterAllocator::lock): - (JSC::DFG::ScratchRegisterAllocator::allocateScratch): - (JSC::DFG::ScratchRegisterAllocator::allocateScratchGPR): - (JSC::DFG::ScratchRegisterAllocator::allocateScratchFPR): - (JSC::DFG::ScratchRegisterAllocator::didReuseRegisters): - (JSC::DFG::ScratchRegisterAllocator::preserveReusedRegistersByPushing): - (JSC::DFG::ScratchRegisterAllocator::restoreReusedRegistersByPopping): - (JSC::DFG::ScratchRegisterAllocator::desiredScratchBufferSize): - (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer): - (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer): - -2012-07-15 Filip Pizlo <fpizlo@apple.com> - - DFG PutById transition should handle storage allocation, and inline it - https://bugs.webkit.org/show_bug.cgi?id=91337 - - Reviewed by Oliver Hunt. - - This enables the patching of DFG PutById to handle the out-of-line storage - allocation case. Furthermore, it inlines out-of-line storage allocation (and - reallocation) into the generated stubs. - - To do this, this patch adds the ability to store the relevant register - allocation state (i.e. the set of in-use registers) in the structure stub - info so that the stub generation code can more flexibly select scratch - registers: sometimes it needs none, sometimes one - or sometimes up to - three. Moreover, to make the stub generation register allocation simple and - maintainable, this patch introduces a reusable scratch register allocator - class. This register allocator understands that some registers are in use by - the main path code and so must be spilled as necessary, other registers are - locked for use in the stub itself and so cannot even be spilled, while still - others may be allocated for scratch purposes. A scratch register that is - used must be spilled. If a register is locked, it cannot be used as a - scratch register. If a register is used, it can be used as a scratch - register so long as it is spilled. - - This is a sub-1% speed-up on V8 and neutral elsewhere. - - * GNUmakefile.list.am: - * JavaScriptCore.xcodeproj/project.pbxproj: - * assembler/MacroAssemblerCodeRef.h: - (FunctionPtr): - (JSC::FunctionPtr::FunctionPtr): - * bytecode/StructureStubInfo.h: - * dfg/DFGCCallHelpers.h: - (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): - (CCallHelpers): - * dfg/DFGGPRInfo.h: - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::link): - * dfg/DFGJITCompiler.h: - (JSC::DFG::PropertyAccessRecord::PropertyAccessRecord): - (PropertyAccessRecord): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGRegisterBank.h: - (JSC::DFG::RegisterBank::isInUse): - (RegisterBank): - * dfg/DFGRegisterSet.h: Added. - (DFG): - (RegisterSet): - (JSC::DFG::RegisterSet::RegisterSet): - (JSC::DFG::RegisterSet::asPOD): - (JSC::DFG::RegisterSet::copyInfo): - (JSC::DFG::RegisterSet::set): - (JSC::DFG::RegisterSet::setGPRByIndex): - (JSC::DFG::RegisterSet::clear): - (JSC::DFG::RegisterSet::get): - (JSC::DFG::RegisterSet::getGPRByIndex): - (JSC::DFG::RegisterSet::getFreeGPR): - (JSC::DFG::RegisterSet::setFPRByIndex): - (JSC::DFG::RegisterSet::getFPRByIndex): - (JSC::DFG::RegisterSet::setByIndex): - (JSC::DFG::RegisterSet::getByIndex): - (JSC::DFG::RegisterSet::numberOfSetGPRs): - (JSC::DFG::RegisterSet::numberOfSetFPRs): - (JSC::DFG::RegisterSet::numberOfSetRegisters): - (JSC::DFG::RegisterSet::setBit): - (JSC::DFG::RegisterSet::clearBit): - (JSC::DFG::RegisterSet::getBit): - * dfg/DFGRepatch.cpp: - (JSC::DFG::generateProtoChainAccessStub): - (JSC::DFG::tryCacheGetByID): - (JSC::DFG::tryBuildGetByIDList): - (JSC::DFG::emitPutReplaceStub): - (JSC::DFG::emitPutTransitionStub): - (JSC::DFG::tryCachePutByID): - (JSC::DFG::tryBuildPutByIdList): - * dfg/DFGScratchRegisterAllocator.h: Added. - (DFG): - (ScratchRegisterAllocator): - (JSC::DFG::ScratchRegisterAllocator::ScratchRegisterAllocator): - (JSC::DFG::ScratchRegisterAllocator::lock): - (JSC::DFG::ScratchRegisterAllocator::allocateScratch): - (JSC::DFG::ScratchRegisterAllocator::allocateScratchGPR): - (JSC::DFG::ScratchRegisterAllocator::allocateScratchFPR): - (JSC::DFG::ScratchRegisterAllocator::didReuseRegisters): - (JSC::DFG::ScratchRegisterAllocator::preserveReusedRegistersByPushing): - (JSC::DFG::ScratchRegisterAllocator::restoreReusedRegistersByPopping): - (JSC::DFG::ScratchRegisterAllocator::desiredScratchBufferSize): - (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer): - (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - (JSC::DFG::SpeculativeJIT::usedRegisters): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::cachedGetById): - (JSC::DFG::SpeculativeJIT::cachedPutById): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::cachedGetById): - (JSC::DFG::SpeculativeJIT::cachedPutById): - (JSC::DFG::SpeculativeJIT::compile): - * heap/CopiedAllocator.h: - (CopiedAllocator): - (JSC::CopiedAllocator::fastPathShouldSucceed): - (JSC): - -2012-07-16 Patrick Gansterer <paroga@webkit.org> - - Add dfg switch to create_jit_stubs script - https://bugs.webkit.org/show_bug.cgi?id=91256 - - Reviewed by Geoffrey Garen. - - * create_jit_stubs: Add a switch to enable or disable the generation of - stub functions in #if ENABLE(DFG_JIT) conditions. - -2012-07-16 Gabor Rapcsanyi <rgabor@webkit.org> - - Unreviewed buildfix after r122729. Typo fix. - - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::add32): - -2012-07-16 Gabor Rapcsanyi <rgabor@webkit.org> - - Unreviewed buildfix from Zoltan Herczeg after r122677. - Implement missing add32 function to MacroAssemblerARM. - - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::add32): - (MacroAssemblerARM): - -2012-07-14 Filip Pizlo <fpizlo@apple.com> - - DFG PutByVal opcodes should accept more than 3 operands - https://bugs.webkit.org/show_bug.cgi?id=91332 - - Reviewed by Oliver Hunt. - - Turned PutByVal/PutByValAlias into var-arg nodes, so that we can give them - 4 or more operands in the future. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::getByValLoadElimination): - (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - (JSC::DFG::FixupPhase::fixDoubleEdge): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::byValIsPure): - (JSC::DFG::Graph::varArgNumChildren): - (Graph): - (JSC::DFG::Graph::numChildren): - (JSC::DFG::Graph::varArgChild): - (JSC::DFG::Graph::child): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): - (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-07-14 Filip Pizlo <fpizlo@apple.com> - - Rationalize and optimize storage allocation - https://bugs.webkit.org/show_bug.cgi?id=91303 - - Reviewed by Oliver Hunt. - - This implements a backwards bump allocator for copied space storage - allocation, shown in pseudo-code below: - - pointer bump(size) { - pointer tmp = allocator->remaining; - tmp -= size; - if (tmp < 0) - fail; - allocator->remaining = tmp; - return allocator->payloadEnd - tmp - size; - } - - The advantage of this allocator is that it: - - - Only requires one comparison in the common case where size is known to - not be huge, and this comparison can be done by checking the sign bit - of the subtraction. - - - Can be implemented even when only one register is available. This - register is reused for both temporary storage during allocation and - for the result. - - - Preserves the behavior that memory in a block is filled in from lowest - address to highest address, which allows for a cheap reallocation fast - path. - - - Is resilient against the block used for allocation being the last one - in virtual memory, thereby otherwise leading to the risk of overflow - in the bump pointer, despite only doing one branch. - - In order to implement this allocator using the smallest possible chunk - of code, I refactored the copied space code so that all of the allocation - logic is in CopiedAllocator, and all of the state is in either - CopiedBlock or CopiedAllocator. This should make changing the allocation - fast path easier in the future. - - In order to do this, I needed to add some new assembler support, - particularly for various forms of add(address, register) and negPtr(). - - This is performance neutral. The purpose of this change is to facilitate - further inlining of storage allocation without having to reserve - additional registers or emit too much code. - - * assembler/MacroAssembler.h: - (JSC::MacroAssembler::addPtr): - (MacroAssembler): - (JSC::MacroAssembler::negPtr): - * assembler/MacroAssemblerARMv7.h: - (MacroAssemblerARMv7): - (JSC::MacroAssemblerARMv7::add32): - * assembler/MacroAssemblerX86.h: - (JSC::MacroAssemblerX86::add32): - (MacroAssemblerX86): - * assembler/MacroAssemblerX86_64.h: - (MacroAssemblerX86_64): - (JSC::MacroAssemblerX86_64::addPtr): - (JSC::MacroAssemblerX86_64::negPtr): - * assembler/X86Assembler.h: - (X86Assembler): - (JSC::X86Assembler::addl_mr): - (JSC::X86Assembler::addq_mr): - (JSC::X86Assembler::negq_r): - * heap/CopiedAllocator.h: - (CopiedAllocator): - (JSC::CopiedAllocator::isValid): - (JSC::CopiedAllocator::CopiedAllocator): - (JSC::CopiedAllocator::tryAllocate): - (JSC): - (JSC::CopiedAllocator::tryReallocate): - (JSC::CopiedAllocator::forceAllocate): - (JSC::CopiedAllocator::resetCurrentBlock): - (JSC::CopiedAllocator::setCurrentBlock): - (JSC::CopiedAllocator::currentCapacity): - * heap/CopiedBlock.h: - (CopiedBlock): - (JSC::CopiedBlock::create): - (JSC::CopiedBlock::zeroFillWilderness): - (JSC::CopiedBlock::CopiedBlock): - (JSC::CopiedBlock::payloadEnd): - (JSC): - (JSC::CopiedBlock::payloadCapacity): - (JSC::CopiedBlock::data): - (JSC::CopiedBlock::dataEnd): - (JSC::CopiedBlock::dataSize): - (JSC::CopiedBlock::wilderness): - (JSC::CopiedBlock::wildernessEnd): - (JSC::CopiedBlock::wildernessSize): - (JSC::CopiedBlock::size): - * heap/CopiedSpace.cpp: - (JSC::CopiedSpace::tryAllocateSlowCase): - (JSC::CopiedSpace::tryAllocateOversize): - (JSC::CopiedSpace::tryReallocate): - (JSC::CopiedSpace::doneFillingBlock): - (JSC::CopiedSpace::doneCopying): - * heap/CopiedSpace.h: - (CopiedSpace): - * heap/CopiedSpaceInlineMethods.h: - (JSC::CopiedSpace::startedCopying): - (JSC::CopiedSpace::allocateBlockForCopyingPhase): - (JSC::CopiedSpace::allocateBlock): - (JSC::CopiedSpace::tryAllocate): - (JSC): - * heap/MarkStack.cpp: - (JSC::SlotVisitor::startCopying): - (JSC::SlotVisitor::allocateNewSpace): - (JSC::SlotVisitor::doneCopying): - * heap/SlotVisitor.h: - (JSC::SlotVisitor::SlotVisitor): - * jit/JIT.h: - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicStorage): - (JSC::JIT::emitAllocateJSArray): - -2012-07-13 Mark Lam <mark.lam@apple.com> - - OfflineASM Pretty printing and commenting enhancements. - https://bugs.webkit.org/show_bug.cgi?id=91281 + Removed the assumption that "final" objects have a fixed number of inline slots + https://bugs.webkit.org/show_bug.cgi?id=98332 Reviewed by Filip Pizlo. - Added some minor pretty printing in the OfflineASM. - Also added infrastruture for adding multiple types of comments and - annotations with the ability to enable/disable them in the generated - output as desired. - - * GNUmakefile.list.am: add new file config.rb. - * llint/LLIntOfflineAsmConfig.h: - Added OFFLINE_ASM_BEGIN, OFFLINE_ASM_END, and OFFLINE_ASM_LOCAL_LABEL macros. - This will allow us to redefine these for other backends later. - * llint/LowLevelInterpreter32_64.asm: - Add a small example of instruction annotations for now. - * llint/LowLevelInterpreter64.asm: - Add a small example of instruction annotations for now. - * offlineasm/armv7.rb: Added handling of annotations. - * offlineasm/asm.rb: - Added machinery to dump the new comments and annotations. - Also added some indentations to make the output a little prettier. - * offlineasm/ast.rb: Added annotation field in class Instruction. - * offlineasm/backends.rb: - * offlineasm/config.rb: Added. - Currently only contains commenting options. This file is meant to be - a centralized place for build config values much like config.h for - JavaScriptCore. - * offlineasm/generate_offset_extractor.rb: - * offlineasm/instructions.rb: - * offlineasm/offsets.rb: - * offlineasm/opt.rb: - * offlineasm/parser.rb: Parse and record annotations. - * offlineasm/registers.rb: - * offlineasm/self_hash.rb: - * offlineasm/settings.rb: - * offlineasm/transform.rb: - * offlineasm/x86.rb: Added handling of annotations. - -2012-07-13 Filip Pizlo <fpizlo@apple.com> - - ASSERTION FAILED: use.useKind() != DoubleUse - https://bugs.webkit.org/show_bug.cgi?id=91082 - - Reviewed by Geoffrey Garen. + This is a step toward object size inference. - The implementation of Branch() was unwisely relying on register allocation state - to decide what speculations to perform. That's never correct. + I replaced the inline storage capacity constant with a data member per + structure, set the the maximum supported value for the constant to 100, + then fixed what broke. (Note that even though this patch increases the + theoretical maximum inline capacity, it doesn't change any actual inline + capacity.) * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): - -2012-07-13 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r122640. - http://trac.webkit.org/changeset/122640 - https://bugs.webkit.org/show_bug.cgi?id=91298 - - LLInt apparently does not expect to mark these (Requested by - olliej on #webkit). - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::visitStructures): - (JSC::CodeBlock::stronglyVisitStrongReferences): - -2012-07-13 Oliver Hunt <oliver@apple.com> - - LLInt fails to mark structures stored in the bytecode - https://bugs.webkit.org/show_bug.cgi?id=91296 - - Reviewed by Geoffrey Garen. - - LLInt stores structures in the bytecode, so we need to visit the appropriate - instructions as we would if we were running in the classic interpreter. - This requires adding additional checks for the LLInt specific opcodes, and - the lint specific variants of operand ordering. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::visitStructures): - (JSC::CodeBlock::stronglyVisitStrongReferences): - -2012-07-13 Yong Li <yoli@rim.com> - - [BlackBerry] Implement GCActivityCallback with platform timer - https://bugs.webkit.org/show_bug.cgi?id=90175 - - Reviewed by Rob Buis. - - Implement GCActivityCallback and HeapTimer for BlackBerry port. - - * heap/HeapTimer.cpp: - (JSC): - (JSC::HeapTimer::HeapTimer): - (JSC::HeapTimer::~HeapTimer): - (JSC::HeapTimer::timerDidFire): - (JSC::HeapTimer::synchronize): - (JSC::HeapTimer::invalidate): - (JSC::HeapTimer::didStartVMShutdown): - * heap/HeapTimer.h: - (HeapTimer): - * runtime/GCActivityCallbackBlackBerry.cpp: - (JSC): - (JSC::DefaultGCActivityCallback::doWork): - (JSC::DefaultGCActivityCallback::didAllocate): - (JSC::DefaultGCActivityCallback::willCollect): - (JSC::DefaultGCActivityCallback::cancel): - -2012-07-13 Patrick Gansterer <paroga@webkit.org> - - [WIN] Fix compilation of DFGRepatch.cpp - https://bugs.webkit.org/show_bug.cgi?id=91241 - - Reviewed by Geoffrey Garen. - - Use intptr_t instead of uintptr_t when calling CodeLocationCommon::dataLabelPtrAtOffset(int) - to fix MSVC "unary minus operator applied to unsigned type, result still unsigned" warning. - - * dfg/DFGRepatch.cpp: - (JSC::DFG::dfgResetGetByID): - (JSC::DFG::dfgResetPutByID): - -2012-07-13 Patrick Gansterer <paroga@webkit.org> - - Fix ARM_TRADITIONAL JIT for COMPILER(MSVC) and COMPILER(RVCT) after r121885 - https://bugs.webkit.org/show_bug.cgi?id=91238 - - Reviewed by Zoltan Herczeg. - - r121885 changed the assembler instruction only for COMPILER(GCC). - Use the same instructions for the other compilers too. - - * jit/JITStubs.cpp: - (JSC::ctiTrampoline): - (JSC::ctiTrampolineEnd): - (JSC::ctiVMThrowTrampoline): - -2012-07-12 Filip Pizlo <fpizlo@apple.com> - - DFG property access stubs should use structure transition watchpoints - https://bugs.webkit.org/show_bug.cgi?id=91135 - - Reviewed by Geoffrey Garen. - - This adds a Watchpoint subclass that will clear a structure stub (i.e. - a property access stub) when fired. The DFG stub generation code now - uses this optimization. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * bytecode/CodeBlock.cpp: - (JSC): - (JSC::CodeBlock::finalizeUnconditionally): - (JSC::CodeBlock::resetStub): - (JSC::CodeBlock::resetStubInternal): - * bytecode/CodeBlock.h: - (JSC): - (CodeBlock): - * bytecode/StructureStubClearingWatchpoint.cpp: Added. - (JSC): - (JSC::StructureStubClearingWatchpoint::~StructureStubClearingWatchpoint): - (JSC::StructureStubClearingWatchpoint::push): - (JSC::StructureStubClearingWatchpoint::fireInternal): - (JSC::WatchpointsOnStructureStubInfo::~WatchpointsOnStructureStubInfo): - (JSC::WatchpointsOnStructureStubInfo::addWatchpoint): - (JSC::WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint): - * bytecode/StructureStubClearingWatchpoint.h: Added. - (JSC): - (StructureStubClearingWatchpoint): - (JSC::StructureStubClearingWatchpoint::StructureStubClearingWatchpoint): - (WatchpointsOnStructureStubInfo): - (JSC::WatchpointsOnStructureStubInfo::WatchpointsOnStructureStubInfo): - (JSC::WatchpointsOnStructureStubInfo::codeBlock): - (JSC::WatchpointsOnStructureStubInfo::stubInfo): - * bytecode/StructureStubInfo.h: - (JSC::StructureStubInfo::reset): - (JSC::StructureStubInfo::addWatchpoint): - (StructureStubInfo): - * dfg/DFGRepatch.cpp: - (JSC::DFG::addStructureTransitionCheck): - (DFG): - (JSC::DFG::generateProtoChainAccessStub): - (JSC::DFG::emitPutTransitionStub): - * jit/JumpReplacementWatchpoint.h: - -2012-07-12 Filip Pizlo <fpizlo@apple.com> - - DFG CFA may get overzealous in loops that have code that must exit - https://bugs.webkit.org/show_bug.cgi?id=91188 - - Reviewed by Gavin Barraclough. - - Ensure that if the CFA assumes that an operation must exit, then it will always exit - no matter what happens after. That's necessary to preserve soundness. - - Remove a broken fixup done by the DFG simplifier, where it was trying to say that the - variable-at-head was the first access in the second block in the merge, if the first - block did not read the variable. That's totally wrong, if the first block was in fact - doing a phantom read. I removed that fixup and instead hardened the rest of the - compiler. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::endBasicBlock): - * dfg/DFGBasicBlock.h: - (JSC::DFG::BasicBlock::BasicBlock): - (BasicBlock): - * dfg/DFGCFAPhase.cpp: - (JSC::DFG::CFAPhase::performBlockCFA): - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::mergeBlocks): - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::ConstantFoldingPhase): - (JSC::DFG::ConstantFoldingPhase::run): - (ConstantFoldingPhase): - (JSC::DFG::ConstantFoldingPhase::foldConstants): - (JSC::DFG::ConstantFoldingPhase::paintUnreachableCode): - * dfg/DFGVariableEventStream.cpp: - (JSC::DFG::VariableEventStream::reconstruct): - -2012-07-12 Allan Sandfeld Jensen <allan.jensen@nokia.com> - - [Qt] Implement MemoryUsageSupport - https://bugs.webkit.org/show_bug.cgi?id=91094 - - Reviewed by Adam Barth. - - Compile in MemoryStatistics so we can make use of the interface. - - * Target.pri: - -2012-07-12 Csaba Osztrogonác <ossy@webkit.org> - - Remove dead code after r122392. - https://bugs.webkit.org/show_bug.cgi?id=91049 - - Reviewed by Filip Pizlo. - - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::emitCall): - -2012-07-11 Adenilson Cavalcanti <cavalcantii@gmail.com> - - Build fix + remove dead code - https://bugs.webkit.org/show_bug.cgi?id=91039 - - Reviewed by Filip Pizlo. - - An unused variable was breaking compilation (thanks to warnings being treated as errors). - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::emitCall): - -2012-07-11 Mark Rowe <mrowe@apple.com> - - <http://webkit.org/b/91024> Build against the latest SDK when targeting older OS X versions. - - Reviewed by Dan Bernstein. - - The deployment target is already set to the version that we're targeting, and it's that setting - which determines which functionality from the SDK is available to us. - - * Configurations/Base.xcconfig: - -2012-07-11 Filip Pizlo <fpizlo@apple.com> - - DFG should have fast virtual calls - https://bugs.webkit.org/show_bug.cgi?id=90924 - - Reviewed by Gavin Barraclough. - - Implements virtual call support in the style of the old JIT, with the - caveat that we still use the same slow path for both InternalFunction - calls and JSFunction calls. Also rationalized the way that our - CodeOrigin indices tie into exception checks (previously it was a - strange one-to-one mapping with fairly limited assertions; now it's a - one-to-many mapping for CodeOrigins to exception checks, respectively). - I also took the opportunity to clean up - CallLinkInfo::callReturnLocation, which previously was either a Call or - a NearCall. Now it's just a NearCall. As well, exceptions during slow - path call resolution are now handled by returning an exception throwing - thunk rather than returning null. And finally, I made a few things - public that were previously private-with-lots-of-friends, because I - truly despise the thought of listing each thunk generating function as - a friend of JSValue and friends. - - * bytecode/CallLinkInfo.cpp: - (JSC::CallLinkInfo::unlink): - * bytecode/CallLinkInfo.h: - (CallLinkInfo): - * bytecode/CodeOrigin.h: - (JSC::CodeOrigin::CodeOrigin): - (JSC::CodeOrigin::isSet): - * dfg/DFGAssemblyHelpers.h: - (JSC::DFG::AssemblyHelpers::AssemblyHelpers): - * dfg/DFGCCallHelpers.h: - (JSC::DFG::CCallHelpers::CCallHelpers): - * dfg/DFGGPRInfo.h: - (GPRInfo): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::link): - (JSC::DFG::JITCompiler::compileFunction): - * dfg/DFGJITCompiler.h: - (JSC::DFG::CallBeginToken::CallBeginToken): - (JSC::DFG::CallBeginToken::~CallBeginToken): - (CallBeginToken): - (JSC::DFG::CallBeginToken::set): - (JSC::DFG::CallBeginToken::registerWithExceptionCheck): - (JSC::DFG::CallBeginToken::codeOrigin): - (JSC::DFG::CallExceptionRecord::CallExceptionRecord): - (CallExceptionRecord): - (JSC::DFG::JITCompiler::currentCodeOriginIndex): - (JITCompiler): - (JSC::DFG::JITCompiler::beginCall): - (JSC::DFG::JITCompiler::notifyCall): - (JSC::DFG::JITCompiler::prepareForExceptionCheck): - (JSC::DFG::JITCompiler::addExceptionCheck): - (JSC::DFG::JITCompiler::addFastExceptionCheck): - * dfg/DFGOperations.cpp: - * dfg/DFGRepatch.cpp: - (JSC::DFG::dfgLinkFor): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheck): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::emitCall): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::emitCall): - * dfg/DFGThunks.cpp: - (JSC::DFG::emitPointerValidation): - (DFG): - (JSC::DFG::throwExceptionFromCallSlowPathGenerator): - (JSC::DFG::slowPathFor): - (JSC::DFG::linkForThunkGenerator): - (JSC::DFG::linkCallThunkGenerator): - (JSC::DFG::linkConstructThunkGenerator): - (JSC::DFG::virtualForThunkGenerator): - (JSC::DFG::virtualCallThunkGenerator): - (JSC::DFG::virtualConstructThunkGenerator): - * dfg/DFGThunks.h: - (DFG): - * jit/JIT.cpp: - (JSC::JIT::privateCompile): - (JSC::JIT::linkFor): - * runtime/Executable.h: - (ExecutableBase): - (JSC::ExecutableBase::offsetOfJITCodeFor): - (JSC::ExecutableBase::offsetOfNumParametersFor): - * runtime/JSValue.h: - (JSValue): - -2012-07-11 Filip Pizlo <fpizlo@apple.com> - - Accidentally used the wrong license (3-clause instead of 2-clause) in some - files I just committed. - - Rubber stamped by Oliver Hunt. - - * bytecode/Watchpoint.cpp: - * bytecode/Watchpoint.h: - * jit/JumpReplacementWatchpoint.cpp: - * jit/JumpReplacementWatchpoint.h: - -2012-07-11 Filip Pizlo <fpizlo@apple.com> - - Watchpoints and jump replacement should be decoupled - https://bugs.webkit.org/show_bug.cgi?id=91016 - - Reviewed by Oliver Hunt. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * assembler/AbstractMacroAssembler.h: - (JSC): - (Label): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::appendWatchpoint): - (JSC::CodeBlock::watchpoint): - (DFGData): - * bytecode/Watchpoint.cpp: - (JSC): - * bytecode/Watchpoint.h: - (JSC::Watchpoint::Watchpoint): - (Watchpoint): - (JSC::Watchpoint::fire): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::speculationWatchpoint): - * jit/JumpReplacementWatchpoint.cpp: Added. - (JSC): - (JSC::JumpReplacementWatchpoint::correctLabels): - (JSC::JumpReplacementWatchpoint::fireInternal): - * jit/JumpReplacementWatchpoint.h: Added. - (JSC): - (JumpReplacementWatchpoint): - (JSC::JumpReplacementWatchpoint::JumpReplacementWatchpoint): - (JSC::JumpReplacementWatchpoint::setDestination): - -2012-07-11 Kevin Ollivier <kevino@theolliviers.com> - - [wx] Unreviewed build fix. Don't try to build udis86_itab.c since it's included by - another file. - - * wscript: - -2012-07-11 Chao-ying Fu <fu@mips.com> - - Add MIPS convertibleLoadPtr and other functions - https://bugs.webkit.org/show_bug.cgi?id=90714 - - Reviewed by Oliver Hunt. - - * assembler/MIPSAssembler.h: - (JSC::MIPSAssembler::labelIgnoringWatchpoints): - (MIPSAssembler): - (JSC::MIPSAssembler::replaceWithLoad): - (JSC::MIPSAssembler::replaceWithAddressComputation): - * assembler/MacroAssemblerMIPS.h: - (JSC::MacroAssemblerMIPS::convertibleLoadPtr): - (MacroAssemblerMIPS): - -2012-07-11 Anders Carlsson <andersca@apple.com> - - Add -Wtautological-compare and -Wsign-compare warning flags - https://bugs.webkit.org/show_bug.cgi?id=90994 - - Reviewed by Mark Rowe. - - * Configurations/Base.xcconfig: - -2012-07-11 Benjamin Poulain <bpoulain@apple.com> - - Simplify the copying of JSC ARMv7's LinkRecord - https://bugs.webkit.org/show_bug.cgi?id=90930 - - Reviewed by Filip Pizlo. - - The class LinkRecord is used by value everywhere in ARMv7Assembler. The compiler uses - memmove() to move the objects. - - The problem is memmove() is overkill for this object, moving the value can be done with - 3 load-store. This patch adds an operator= to the class doing more efficient copying. - This reduces the link time by 19%. - - * assembler/ARMv7Assembler.h: - (JSC::ARMv7Assembler::LinkRecord::LinkRecord): - (JSC::ARMv7Assembler::LinkRecord::operator=): - (JSC::ARMv7Assembler::LinkRecord::from): - (JSC::ARMv7Assembler::LinkRecord::setFrom): - (JSC::ARMv7Assembler::LinkRecord::to): - (JSC::ARMv7Assembler::LinkRecord::type): - (JSC::ARMv7Assembler::LinkRecord::linkType): - (JSC::ARMv7Assembler::LinkRecord::setLinkType): - (JSC::ARMv7Assembler::LinkRecord::condition): - -2012-07-11 Andy Wingo <wingo@igalia.com> - - jsc: Parse options before creating global data - https://bugs.webkit.org/show_bug.cgi?id=90975 - - Reviewed by Filip Pizlo. - - This patch moves the options parsing in "jsc" before the creation - of the JSGlobalData, so that --useJIT=no has a chance to take - effect. - - * jsc.cpp: - (CommandLine::parseArguments): Refactor to be a class, and take - argc and argv as constructor arguments. - (jscmain): Move arg parsing before JSGlobalData creation. - -2012-07-10 Filip Pizlo <fpizlo@apple.com> - - REGRESSION(r122166): It made 170 tests crash on 32 bit platforms - https://bugs.webkit.org/show_bug.cgi?id=90852 - - Reviewed by Zoltan Herczeg. - - If we can't use the range filter, we should still make sure that the - address is remotely sane, otherwise the hashtables will assert. - - * jit/JITStubRoutine.h: - (JSC::JITStubRoutine::passesFilter): - -2012-07-10 Filip Pizlo <fpizlo@apple.com> - - DFG recompilation heuristics should be based on count, not rate - https://bugs.webkit.org/show_bug.cgi?id=90146 - - Reviewed by Oliver Hunt. - - Rolling r121511 back in after fixing the DFG's interpretation of op_div - profiling, with Gavin's rubber stamp. - - This removes a bunch of code that was previously trying to prevent spurious - reoptimizations if a large enough majority of executions of a code block did - not result in OSR exit. It turns out that this code was purely harmful. This - patch removes all of that logic and replaces it with a dead-simple - heuristic: if you exit more than N times (where N is an exponential function - of the number of times the code block has already been recompiled) then we - will recompile. - - This appears to be a broad ~1% win on many benchmarks large and small. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::CodeBlock): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::couldTakeSpecialFastCase): - (CodeBlock): - (JSC::CodeBlock::osrExitCounter): - (JSC::CodeBlock::countOSRExit): - (JSC::CodeBlock::addressOfOSRExitCounter): - (JSC::CodeBlock::offsetOfOSRExitCounter): - (JSC::CodeBlock::adjustedExitCountThreshold): - (JSC::CodeBlock::exitCountThresholdForReoptimization): - (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop): - (JSC::CodeBlock::shouldReoptimizeNow): - (JSC::CodeBlock::shouldReoptimizeFromLoopNow): - * bytecode/ExecutionCounter.cpp: - (JSC::ExecutionCounter::setThreshold): - * bytecode/ExecutionCounter.h: - (ExecutionCounter): - (JSC::ExecutionCounter::clippedThreshold): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::makeDivSafe): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::compileBody): - * dfg/DFGOSRExit.cpp: - (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): - * dfg/DFGOSRExitCompiler.cpp: - (JSC::DFG::OSRExitCompiler::handleExitCounts): - * dfg/DFGOperations.cpp: - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * runtime/Options.h: - (JSC): - -2012-07-09 Matt Falkenhagen <falken@chromium.org> - - Add ENABLE_DIALOG_ELEMENT and skeleton files - https://bugs.webkit.org/show_bug.cgi?id=90521 - - Reviewed by Kent Tamura. - - * Configurations/FeatureDefines.xcconfig: - -2012-07-09 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, roll out http://trac.webkit.org/changeset/121511 - It made in-browser V8v7 10% slower. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::CodeBlock): - * bytecode/CodeBlock.h: - (CodeBlock): - (JSC::CodeBlock::countSpeculationSuccess): - (JSC::CodeBlock::countSpeculationFailure): - (JSC::CodeBlock::speculativeSuccessCounter): - (JSC::CodeBlock::speculativeFailCounter): - (JSC::CodeBlock::forcedOSRExitCounter): - (JSC::CodeBlock::addressOfSpeculativeSuccessCounter): - (JSC::CodeBlock::addressOfSpeculativeFailCounter): - (JSC::CodeBlock::addressOfForcedOSRExitCounter): - (JSC::CodeBlock::offsetOfSpeculativeSuccessCounter): - (JSC::CodeBlock::offsetOfSpeculativeFailCounter): - (JSC::CodeBlock::offsetOfForcedOSRExitCounter): - (JSC::CodeBlock::largeFailCountThreshold): - (JSC::CodeBlock::largeFailCountThresholdForLoop): - (JSC::CodeBlock::shouldReoptimizeNow): - (JSC::CodeBlock::shouldReoptimizeFromLoopNow): - * bytecode/ExecutionCounter.cpp: - (JSC::ExecutionCounter::setThreshold): - * bytecode/ExecutionCounter.h: - (ExecutionCounter): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::compileBody): - * dfg/DFGOSRExit.cpp: - (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): - * dfg/DFGOSRExitCompiler.cpp: - (JSC::DFG::OSRExitCompiler::handleExitCounts): - * dfg/DFGOperations.cpp: - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * runtime/Options.h: - (JSC): - -2012-07-09 Filip Pizlo <fpizlo@apple.com> - - DFG may get stuck in an infinite fix point if it constant folds a mispredicted node - https://bugs.webkit.org/show_bug.cgi?id=90829 - <rdar://problem/11823843> - - Reviewed by Oliver Hunt. - - If a node is shown to have been mispredicted during CFA, then don't allow constant - folding to make the graph even more degenerate. Instead, pull back on constant folding - and allow the normal OSR machinery to fix our profiling so that a future recompilation - doesn't see the same mistake. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGAbstractState.h: - (JSC::DFG::AbstractState::trySetConstant): - (AbstractState): - * dfg/DFGPhase.h: - (JSC::DFG::Phase::name): - (Phase): - (JSC::DFG::runAndLog): - (DFG): - (JSC::DFG::runPhase): - -2012-07-09 Filip Pizlo <fpizlo@apple.com> - - It should be possible to jettison JIT stub routines even if they are currently running - https://bugs.webkit.org/show_bug.cgi?id=90731 - - Reviewed by Gavin Barraclough. - - This gives the GC awareness of all JIT-generated stubs for inline caches. That - means that if you want to delete a JIT-generated stub, you don't have to worry - about whether or not it is currently running: if there is a chance that it might - be, the GC will kindly defer deletion until non-running-ness is proved. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * bytecode/Instruction.h: - (JSC): - (PolymorphicStubInfo): - (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set): - (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList): - * bytecode/PolymorphicPutByIdList.cpp: - (JSC::PutByIdAccess::fromStructureStubInfo): - * bytecode/PolymorphicPutByIdList.h: - (JSC::PutByIdAccess::transition): - (JSC::PutByIdAccess::replace): - (JSC::PutByIdAccess::stubRoutine): - (PutByIdAccess): - (JSC::PolymorphicPutByIdList::currentSlowPathTarget): - * bytecode/StructureStubInfo.h: - (JSC::StructureStubInfo::reset): - * dfg/DFGRepatch.cpp: - (JSC::DFG::generateProtoChainAccessStub): - (JSC::DFG::tryCacheGetByID): - (JSC::DFG::tryBuildGetByIDList): - (JSC::DFG::tryBuildGetByIDProtoList): - (JSC::DFG::emitPutReplaceStub): - (JSC::DFG::emitPutTransitionStub): - (JSC::DFG::tryCachePutByID): - (JSC::DFG::tryBuildPutByIdList): - * heap/ConservativeRoots.cpp: - (JSC): - (DummyMarkHook): - (JSC::DummyMarkHook::mark): - (JSC::ConservativeRoots::add): - (CompositeMarkHook): - (JSC::CompositeMarkHook::CompositeMarkHook): - (JSC::CompositeMarkHook::mark): - * heap/ConservativeRoots.h: - (JSC): - (ConservativeRoots): - * heap/Heap.cpp: - (JSC::Heap::markRoots): - (JSC::Heap::deleteUnmarkedCompiledCode): - * heap/Heap.h: - (JSC): - (Heap): - * heap/JITStubRoutineSet.cpp: Added. - (JSC): - (JSC::JITStubRoutineSet::JITStubRoutineSet): - (JSC::JITStubRoutineSet::~JITStubRoutineSet): - (JSC::JITStubRoutineSet::add): - (JSC::JITStubRoutineSet::clearMarks): - (JSC::JITStubRoutineSet::markSlow): - (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): - (JSC::JITStubRoutineSet::traceMarkedStubRoutines): - * heap/JITStubRoutineSet.h: Added. - (JSC): - (JITStubRoutineSet): - (JSC::JITStubRoutineSet::mark): - * heap/MachineStackMarker.h: - (JSC): - * interpreter/RegisterFile.cpp: - (JSC::RegisterFile::gatherConservativeRoots): - * interpreter/RegisterFile.h: - (JSC): - * jit/ExecutableAllocator.cpp: - (JSC::DemandExecutableAllocator::DemandExecutableAllocator): - * jit/ExecutableAllocator.h: - (JSC): - * jit/ExecutableAllocatorFixedVMPool.cpp: - (JSC): - (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator): - * jit/GCAwareJITStubRoutine.cpp: Added. - (JSC): - (JSC::GCAwareJITStubRoutine::GCAwareJITStubRoutine): - (JSC::GCAwareJITStubRoutine::~GCAwareJITStubRoutine): - (JSC::GCAwareJITStubRoutine::observeZeroRefCount): - (JSC::GCAwareJITStubRoutine::deleteFromGC): - (JSC::GCAwareJITStubRoutine::markRequiredObjectsInternal): - (JSC::MarkingGCAwareJITStubRoutineWithOneObject::MarkingGCAwareJITStubRoutineWithOneObject): - (JSC::MarkingGCAwareJITStubRoutineWithOneObject::~MarkingGCAwareJITStubRoutineWithOneObject): - (JSC::MarkingGCAwareJITStubRoutineWithOneObject::markRequiredObjectsInternal): - (JSC::createJITStubRoutine): - * jit/GCAwareJITStubRoutine.h: Added. - (JSC): - (GCAwareJITStubRoutine): - (JSC::GCAwareJITStubRoutine::markRequiredObjects): - (MarkingGCAwareJITStubRoutineWithOneObject): * jit/JITPropertyAccess.cpp: - (JSC::JIT::privateCompilePutByIdTransition): - (JSC::JIT::privateCompilePatchGetArrayLength): - (JSC::JIT::privateCompileGetByIdProto): - (JSC::JIT::privateCompileGetByIdSelfList): - (JSC::JIT::privateCompileGetByIdProtoList): - (JSC::JIT::privateCompileGetByIdChainList): - (JSC::JIT::privateCompileGetByIdChain): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::privateCompilePutByIdTransition): - (JSC::JIT::privateCompilePatchGetArrayLength): - (JSC::JIT::privateCompileGetByIdProto): - (JSC::JIT::privateCompileGetByIdSelfList): - (JSC::JIT::privateCompileGetByIdProtoList): - (JSC::JIT::privateCompileGetByIdChainList): - (JSC::JIT::privateCompileGetByIdChain): - * jit/JITStubRoutine.cpp: Added. - (JSC): - (JSC::JITStubRoutine::~JITStubRoutine): - (JSC::JITStubRoutine::observeZeroRefCount): - * jit/JITStubRoutine.h: Added. - (JSC): - (JITStubRoutine): - (JSC::JITStubRoutine::JITStubRoutine): - (JSC::JITStubRoutine::createSelfManagedRoutine): - (JSC::JITStubRoutine::code): - (JSC::JITStubRoutine::asCodePtr): - (JSC::JITStubRoutine::ref): - (JSC::JITStubRoutine::deref): - (JSC::JITStubRoutine::startAddress): - (JSC::JITStubRoutine::endAddress): - (JSC::JITStubRoutine::addressStep): - (JSC::JITStubRoutine::canPerformRangeFilter): - (JSC::JITStubRoutine::filteringStartAddress): - (JSC::JITStubRoutine::filteringExtentSize): - (JSC::JITStubRoutine::passesFilter): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - (JSC::getPolymorphicAccessStructureListSlot): - -2012-07-09 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r122107. - http://trac.webkit.org/changeset/122107 - https://bugs.webkit.org/show_bug.cgi?id=90794 - - Build failure on Mac debug bots (Requested by falken_ on - #webkit). - - * Configurations/FeatureDefines.xcconfig: - -2012-07-09 Matt Falkenhagen <falken@chromium.org> - - Add ENABLE_DIALOG_ELEMENT and skeleton files - https://bugs.webkit.org/show_bug.cgi?id=90521 - - Reviewed by Kent Tamura. - - * Configurations/FeatureDefines.xcconfig: - -2012-07-08 Ryosuke Niwa <rniwa@webkit.org> - - gcc build fix after r121925. - - * runtime/JSObject.h: - (JSC::JSFinalObject::finishCreation): - -2012-07-08 Zoltan Herczeg <zherczeg@webkit.org> + (JSC::JIT::compileGetDirectOffset): These functions just get a rename: + the constant they need is the first out of line offset along the offset + number line, which is not necessarily the same thing (and is, in this + patch, never the same thing) as the inline capacity of any given object. - [Qt][ARM] Implementing missing macro assembler instructions after r121925 - https://bugs.webkit.org/show_bug.cgi?id=90657 - - Reviewed by Csaba Osztrogonác. - - Implementing convertibleLoadPtr, replaceWithLoad and - replaceWithAddressComputation. - - * assembler/ARMAssembler.h: - (JSC::ARMAssembler::replaceWithLoad): - (ARMAssembler): - (JSC::ARMAssembler::replaceWithAddressComputation): - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::convertibleLoadPtr): - (MacroAssemblerARM): - -2012-07-06 Filip Pizlo <fpizlo@apple.com> - - WebKit Version 5.1.7 (6534.57.2, r121935): Double-click no longer works on OpenStreetMap - https://bugs.webkit.org/show_bug.cgi?id=90703 - - Reviewed by Michael Saboff. - - It turns out that in my object model refactoring, I managed to fix get_by_pname in all - execution engines except 64-bit baseline JIT. - - * jit/JITPropertyAccess.cpp: (JSC::JIT::emit_op_get_by_pname): + * jit/JITPropertyAccess32_64.cpp: This function changes functionality, + since it needs to convert from the abstract offset number line to an + actual offset in memory, and it can't assume that inline and out-of-line + offsets are contiguous on the number line. -2012-07-06 Pravin D <pravind.2k4@gmail.com> - - Build Error on Qt Linux build - https://bugs.webkit.org/show_bug.cgi?id=90699 + (JSC::JIT::compileGetDirectOffset): Updated for rename. - Reviewed by Laszlo Gombos. + (JSC::JIT::emit_op_get_by_pname): Same as emit_op_get_by_pname above. - * parser/Parser.cpp: - (JSC::::parseForStatement): - Removed unused boolean variable as this was causing build error on Qt Linux. - -2012-07-06 Nuno Lopes <nlopes@apple.com> + * llint/LowLevelInterpreter.asm: Updated to mirror changes in PropertyOffset.h, + since we duplicate values from there. - Fix build with recent clang. - https://bugs.webkit.org/show_bug.cgi?id=90634 - - Reviewed by Oliver Hunt. - - * jit/SpecializedThunkJIT.h: - (JSC::SpecializedThunkJIT::SpecializedThunkJIT): - (SpecializedThunkJIT): - * jit/ThunkGenerators.cpp: - (JSC::charCodeAtThunkGenerator): - (JSC::charAtThunkGenerator): - (JSC::fromCharCodeThunkGenerator): - (JSC::sqrtThunkGenerator): - (JSC::floorThunkGenerator): - (JSC::ceilThunkGenerator): - (JSC::roundThunkGenerator): - (JSC::expThunkGenerator): - (JSC::logThunkGenerator): - (JSC::absThunkGenerator): - (JSC::powThunkGenerator): - * parser/ASTBuilder.h: - (JSC::ASTBuilder::createAssignResolve): - (JSC::ASTBuilder::createForLoop): - (JSC::ASTBuilder::createForInLoop): - (JSC::ASTBuilder::makeAssignNode): - (JSC::ASTBuilder::makePrefixNode): - (JSC::ASTBuilder::makePostfixNode): - * parser/NodeConstructors.h: - (JSC::PostfixErrorNode::PostfixErrorNode): - (JSC::PrefixErrorNode::PrefixErrorNode): - (JSC::AssignResolveNode::AssignResolveNode): - (JSC::AssignErrorNode::AssignErrorNode): - (JSC::ForNode::ForNode): - (JSC::ForInNode::ForInNode): - * parser/Nodes.h: - (FunctionCallResolveNode): - (PostfixErrorNode): - (PrefixErrorNode): - (ReadModifyResolveNode): - (AssignResolveNode): - (AssignErrorNode): - (ForNode): - (ForInNode): - * parser/Parser.cpp: - (JSC::::parseVarDeclarationList): - (JSC::::parseForStatement): - * parser/SyntaxChecker.h: - (JSC::SyntaxChecker::createAssignResolve): - (JSC::SyntaxChecker::createForLoop): - -2012-07-06 Zoltan Herczeg <zherczeg@webkit.org> - - [Qt][ARM] REGRESSION(r121885): It broke 30 jsc tests, 500+ layout tests - https://bugs.webkit.org/show_bug.cgi?id=90656 - - Reviewed by Csaba Osztrogonác. - - Typo fixes. - - * assembler/MacroAssemblerARM.cpp: - (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): - Rename getOp2Byte() -> getOp2Half() - * assembler/MacroAssemblerARMv7.h: - (JSC::MacroAssemblerARMv7::convertibleLoadPtr): - Add a necessary space. - * jit/JITStubs.cpp: - (JSC): - Revert INLINE_ARM_FUNCTION macro. - -2012-07-05 Filip Pizlo <fpizlo@apple.com> - - REGRESSION(r121925): It broke 5 sputnik tests on x86 platforms - https://bugs.webkit.org/show_bug.cgi?id=90658 - - Reviewed by Zoltan Herczeg. - - Under the new object model, out-of-line property accesses such as those - in ResolveGlobal must account for the fact that the offset to the Kth - property is represented by K + inlineStorageCapacity. Hence, the property - loads in ResolveGlobal must have an additional -inlineStorageCapacity * - sizeof(JSValue) offset. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-07-05 Csaba Osztrogonác <ossy@webkit.org> - - [Qt] Unreviewed 64 bit buildfix after r121925. - - * bytecode/PutByIdStatus.cpp: - (JSC::PutByIdStatus::computeFromLLInt): - -2012-07-05 Michael Saboff <msaboff@apple.com> - - JSString::tryHashConstLock() fails to get exclusive lock - https://bugs.webkit.org/show_bug.cgi?id=90639 - - Reviewed by Oliver Hunt. - - Added check that the string is already locked even before compare and swap. - - * heap/MarkStack.cpp: - (JSC::JSString::tryHashConstLock): - -2012-07-04 Filip Pizlo <fpizlo@apple.com> - - Inline property storage should not be wasted when it is exhausted - https://bugs.webkit.org/show_bug.cgi?id=90347 + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: Just like the JIT, most things are just + renames, and get_by_pname changes to do more math. I also standardized + offset calculations to use a hard-coded "-2", to match the JIT. This + isn't really better, but it makes global search and replace easier, + should we choose to refactor this code not to hard-code constants. - Reviewed by Gavin Barraclough. - - Previously, if we switched an object from using inline storage to out-of-line - storage, we would abandon the inline storage. This would have two main implications: - (i) all accesses to the object, even for properties that were previously in inline - storage, must now take an extra indirection; and (ii) we waste a non-trivial amount - of space since we must allocate additional out-of-line storage to hold properties - that would have fit in the inline storage. There's also the copying cost when - switching to out-of-line storage - we must copy all inline properties into ouf-of-line - storage. - - This patch changes the way that object property storage works so that we can use both - inline and out-of-line storage concurrently. This is accomplished by introducing a - new notion of property offset. This PropertyOffset is a 32-bit signed integer and it - behaves as follows: - - offset == -1: invalid offset, indicating a property that does not exist. - - 0 <= offset <= inlineStorageCapacity: offset into inline storage. - - inlineStorageCapacity < offset: offset into out-of-line storage. - - Because non-final objects don't have inline storage, the only valid PropertyOffsets - for those objects' properties are -1 or > inlineStorageCapacity. - - This now means that the decision to use inline or out-of-line storage for an access is - made based on the offset, rather than the structure. It also means that any access - where the offset is a variable must have an extra branch, unless the type of the - object is also known (if it's known to be a non-final object then we can just assert - that the offset is >= inlineStorageCapacity). - - This looks like a big Kraken speed-up and a slight V8 speed-up. + I also renamed loadPropertyAtVariableOffsetKnownNotFinal to + loadPropertyAtVariableOffsetKnownNotInline in order to sever the assumption + that inline capacity is tied to object type, and I changed the 64bit LLInt + to use this -- not using this previously seems to have been an oversight. - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * assembler/ARMv7Assembler.h: - (ARMv7Assembler): - (JSC::ARMv7Assembler::ldrWide8BitImmediate): - (JSC::ARMv7Assembler::replaceWithLoad): - (JSC::ARMv7Assembler::replaceWithAddressComputation): - * assembler/AbstractMacroAssembler.h: - (AbstractMacroAssembler): - (ConvertibleLoadLabel): - (JSC::AbstractMacroAssembler::ConvertibleLoadLabel::ConvertibleLoadLabel): - (JSC::AbstractMacroAssembler::ConvertibleLoadLabel::isSet): - (JSC::AbstractMacroAssembler::labelIgnoringWatchpoints): - (JSC::AbstractMacroAssembler::replaceWithLoad): - (JSC::AbstractMacroAssembler::replaceWithAddressComputation): - * assembler/CodeLocation.h: - (JSC): - (CodeLocationCommon): - (CodeLocationConvertibleLoad): - (JSC::CodeLocationConvertibleLoad::CodeLocationConvertibleLoad): - (JSC::CodeLocationCommon::convertibleLoadAtOffset): - * assembler/LinkBuffer.cpp: - (JSC::LinkBuffer::finalizeCodeWithDisassembly): - * assembler/LinkBuffer.h: - (LinkBuffer): - (JSC::LinkBuffer::locationOf): - * assembler/MacroAssemblerARMv7.h: - (MacroAssemblerARMv7): - (JSC::MacroAssemblerARMv7::convertibleLoadPtr): - * assembler/MacroAssemblerX86.h: - (JSC::MacroAssemblerX86::convertibleLoadPtr): - (MacroAssemblerX86): - * assembler/MacroAssemblerX86_64.h: - (JSC::MacroAssemblerX86_64::convertibleLoadPtr): - (MacroAssemblerX86_64): - * assembler/RepatchBuffer.h: - (RepatchBuffer): - (JSC::RepatchBuffer::replaceWithLoad): - (JSC::RepatchBuffer::replaceWithAddressComputation): - (JSC::RepatchBuffer::setLoadInstructionIsActive): - * assembler/X86Assembler.h: - (JSC::X86Assembler::replaceWithLoad): - (X86Assembler): - (JSC::X86Assembler::replaceWithAddressComputation): - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::printGetByIdOp): - (JSC::CodeBlock::dump): - (JSC::CodeBlock::finalizeUnconditionally): - * bytecode/GetByIdStatus.cpp: - (JSC::GetByIdStatus::computeFromLLInt): - (JSC::GetByIdStatus::computeForChain): - (JSC::GetByIdStatus::computeFor): - * bytecode/GetByIdStatus.h: - (JSC::GetByIdStatus::GetByIdStatus): - (JSC::GetByIdStatus::offset): - (GetByIdStatus): - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecode/PutByIdStatus.cpp: - (JSC::PutByIdStatus::computeFromLLInt): - (JSC::PutByIdStatus::computeFor): - * bytecode/PutByIdStatus.h: - (JSC::PutByIdStatus::PutByIdStatus): - (JSC::PutByIdStatus::offset): - (PutByIdStatus): - * bytecode/ResolveGlobalStatus.cpp: - (JSC): - (JSC::computeForStructure): - * bytecode/ResolveGlobalStatus.h: - (JSC::ResolveGlobalStatus::ResolveGlobalStatus): - (JSC::ResolveGlobalStatus::offset): - (ResolveGlobalStatus): - * bytecode/StructureSet.h: - (StructureSet): - * bytecode/StructureStubInfo.h: - * dfg/DFGByteCodeParser.cpp: - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::handleGetByOffset): - (JSC::DFG::ByteCodeParser::handleGetById): - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCapabilities.h: - (JSC::DFG::canCompileOpcode): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::link): - * dfg/DFGJITCompiler.h: - (JSC::DFG::PropertyAccessRecord::PropertyAccessRecord): - (PropertyAccessRecord): - * dfg/DFGRepatch.cpp: - (JSC::DFG::dfgRepatchByIdSelfAccess): - (JSC::DFG::generateProtoChainAccessStub): - (JSC::DFG::tryCacheGetByID): - (JSC::DFG::tryBuildGetByIDList): - (JSC::DFG::tryBuildGetByIDProtoList): - (JSC::DFG::emitPutReplaceStub): - (JSC::DFG::emitPutTransitionStub): - (JSC::DFG::tryCachePutByID): - (JSC::DFG::tryBuildPutByIdList): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::cachedGetById): - (JSC::DFG::SpeculativeJIT::cachedPutById): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::cachedGetById): - (JSC::DFG::SpeculativeJIT::cachedPutById): - (JSC::DFG::SpeculativeJIT::compile): - * heap/MarkStack.cpp: - (JSC::visitChildren): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::tryCacheGetByID): - (JSC::Interpreter::privateExecute): - * jit/JIT.cpp: - (JSC::JIT::privateCompileMainPass): - (JSC::JIT::privateCompileSlowCases): - (JSC::PropertyStubCompilationInfo::copyToStubInfo): - * jit/JIT.h: - (JSC::PropertyStubCompilationInfo::PropertyStubCompilationInfo): - (JSC::JIT::compileGetByIdProto): - (JSC::JIT::compileGetByIdSelfList): - (JSC::JIT::compileGetByIdProtoList): - (JSC::JIT::compileGetByIdChainList): - (JSC::JIT::compileGetByIdChain): - (JSC::JIT::compilePutByIdTransition): - (JIT): - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_resolve_global): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_resolve_global): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::compileGetDirectOffset): - (JSC::JIT::emit_op_method_check): - (JSC::JIT::compileGetByIdHotPath): - (JSC::JIT::emit_op_put_by_id): - (JSC::JIT::compilePutDirectOffset): - (JSC::JIT::privateCompilePutByIdTransition): - (JSC::JIT::patchGetByIdSelf): - (JSC::JIT::patchPutByIdReplace): - (JSC::JIT::privateCompileGetByIdProto): - (JSC::JIT::privateCompileGetByIdSelfList): - (JSC::JIT::privateCompileGetByIdProtoList): - (JSC::JIT::privateCompileGetByIdChainList): - (JSC::JIT::privateCompileGetByIdChain): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::emit_op_method_check): - (JSC::JIT::compileGetByIdHotPath): - (JSC::JIT::emit_op_put_by_id): - (JSC::JIT::compilePutDirectOffset): - (JSC::JIT::compileGetDirectOffset): - (JSC::JIT::privateCompilePutByIdTransition): - (JSC::JIT::patchGetByIdSelf): - (JSC::JIT::patchPutByIdReplace): - (JSC::JIT::privateCompileGetByIdProto): - (JSC::JIT::privateCompileGetByIdSelfList): - (JSC::JIT::privateCompileGetByIdProtoList): - (JSC::JIT::privateCompileGetByIdChainList): - (JSC::JIT::privateCompileGetByIdChain): - (JSC::JIT::emit_op_get_by_pname): - * jit/JITStubs.cpp: - (JSC::JITThunks::tryCacheGetByID): - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter.asm: - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * offlineasm/x86.rb: - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::functionNameOffset): * runtime/JSObject.cpp: (JSC::JSObject::visitChildren): - (JSC): (JSC::JSFinalObject::visitChildren): - (JSC::JSObject::put): - (JSC::JSObject::deleteProperty): - (JSC::JSObject::getPropertySpecificValue): - (JSC::JSObject::removeDirect): - (JSC::JSObject::growOutOfLineStorage): - (JSC::JSObject::getOwnPropertyDescriptor): * runtime/JSObject.h: - (JSObject): - (JSC::JSObject::getDirect): - (JSC::JSObject::getDirectLocation): - (JSC::JSObject::hasInlineStorage): - (JSC::JSObject::inlineStorageUnsafe): - (JSC::JSObject::inlineStorage): - (JSC::JSObject::outOfLineStorage): - (JSC::JSObject::locationForOffset): (JSC::JSObject::offsetForLocation): - (JSC::JSObject::getDirectOffset): - (JSC::JSObject::putDirectOffset): - (JSC::JSObject::putUndefinedAtDirectOffset): - (JSC::JSObject::addressOfOutOfLineStorage): - (JSC::JSObject::finishCreation): - (JSC::JSNonFinalObject::JSNonFinalObject): - (JSC::JSNonFinalObject::finishCreation): + (JSNonFinalObject): + (JSC::JSFinalObject::createStructure): (JSFinalObject): - (JSC::JSFinalObject::finishCreation): - (JSC::JSFinalObject::JSFinalObject): - (JSC::JSObject::offsetOfOutOfLineStorage): - (JSC::JSObject::setOutOfLineStorage): - (JSC::JSObject::JSObject): - (JSC): - (JSC::JSCell::fastGetOwnProperty): - (JSC::JSObject::putDirectInternal): - (JSC::JSObject::setStructureAndReallocateStorageIfNecessary): - (JSC::JSObject::putDirectWithoutTransition): - (JSC::offsetRelativeToPatchedStorage): - (JSC::indexRelativeToBase): - (JSC::offsetRelativeToBase): - * runtime/JSPropertyNameIterator.cpp: - (JSC::JSPropertyNameIterator::create): + (JSC::JSFinalObject::finishCreation): Updated for above changes. + * runtime/JSPropertyNameIterator.h: (JSPropertyNameIterator): - (JSC::JSPropertyNameIterator::getOffset): - (JSC::JSPropertyNameIterator::finishCreation): - * runtime/JSValue.cpp: - (JSC::JSValue::putToPrimitive): - * runtime/Operations.h: - (JSC::normalizePrototypeChain): - * runtime/Options.cpp: - (JSC): - (JSC::Options::initialize): + (JSC::JSPropertyNameIterator::finishCreation): Store the inline capacity + of our object, since it's not a constant. + + (JSC::JSPropertyNameIterator::getOffset): Removed. This function was + wrong. Luckily, it was also unused, since the C++ interpreter is gone. + * runtime/PropertyMapHashTable.h: - (PropertyMapEntry): - (JSC::PropertyMapEntry::PropertyMapEntry): - (PropertyTable): - (JSC::PropertyTable::PropertyTable): - (JSC::PropertyTable::getDeletedOffset): - (JSC::PropertyTable::addDeletedOffset): + (PropertyTable): Use a helper function instead of hard-coding assumptions + about object types. + (JSC::PropertyTable::nextOffset): - (JSC): - (JSC::PropertyTable::sizeInMemory): - * runtime/PropertyOffset.h: Added. + * runtime/PropertyOffset.h: (JSC): (JSC::checkOffset): (JSC::validateOffset): - (JSC::isValidOffset): (JSC::isInlineOffset): - (JSC::isOutOfLineOffset): - (JSC::offsetInInlineStorage): - (JSC::offsetInOutOfLineStorage): - (JSC::offsetInRespectiveStorage): - (JSC::numberOfOutOfLineSlotsForLastOffset): (JSC::numberOfSlotsForLastOffset): - (JSC::nextPropertyOffsetFor): - (JSC::firstPropertyOffsetFor): - * runtime/PropertySlot.h: - (JSC::PropertySlot::cachedOffset): - (JSC::PropertySlot::setValue): - (JSC::PropertySlot::setCacheableGetterSlot): - (JSC::PropertySlot::clearOffset): - * runtime/PutPropertySlot.h: - (JSC::PutPropertySlot::setExistingProperty): - (JSC::PutPropertySlot::setNewProperty): - (JSC::PutPropertySlot::cachedOffset): - (PutPropertySlot): + (JSC::propertyOffsetFor): Refactored these functions to take inline capacity + as an argument, since it's not fixed at compile time anymore. + * runtime/Structure.cpp: (JSC::Structure::Structure): - (JSC::Structure::materializePropertyMap): - (JSC::nextOutOfLineStorageCapacity): - (JSC::Structure::growOutOfLineCapacity): - (JSC::Structure::suggestedNewOutOfLineStorageCapacity): - (JSC::Structure::addPropertyTransitionToExistingStructure): - (JSC::Structure::addPropertyTransition): - (JSC::Structure::removePropertyTransition): (JSC::Structure::flattenDictionaryStructure): - (JSC::Structure::addPropertyWithoutTransition): - (JSC::Structure::removePropertyWithoutTransition): - (JSC::Structure::copyPropertyTableForPinning): - (JSC::Structure::get): (JSC::Structure::putSpecificValue): - (JSC::Structure::remove): * runtime/Structure.h: (Structure): - (JSC::Structure::putWillGrowOutOfLineStorage): - (JSC::Structure::previousID): (JSC::Structure::outOfLineCapacity): - (JSC::Structure::outOfLineSizeForKnownFinalObject): - (JSC::Structure::outOfLineSizeForKnownNonFinalObject): - (JSC::Structure::outOfLineSize): (JSC::Structure::hasInlineStorage): (JSC::Structure::inlineCapacity): - (JSC::Structure::inlineSizeForKnownFinalObject): (JSC::Structure::inlineSize): - (JSC::Structure::totalStorageSize): - (JSC::Structure::totalStorageCapacity): (JSC::Structure::firstValidOffset): (JSC::Structure::lastValidOffset): - (JSC::Structure::isValidOffset): - (JSC::Structure::isEmpty): - (JSC::Structure::transitionCount): - (JSC::Structure::get): + (JSC::Structure::create): Removed some hard-coded assumptions about inline + capacity and object type, and replaced with more liberal use of helper functions. -2012-07-05 Oliver Hunt <oliver@apple.com> +2012-10-03 Michael Saboff <msaboff@apple.com> - JSObjectCallAsFunction should thisConvert the provided thisObject - https://bugs.webkit.org/show_bug.cgi?id=90628 - - Reviewed by Gavin Barraclough. - - Perform this conversion on the provided this object. - - * API/JSObjectRef.cpp: - (JSObjectCallAsFunction): - -2012-07-05 Zoltan Herczeg <zherczeg@webkit.org> - - [Qt] Unreviewed buildfix after r121886. Typo fix. - - * assembler/MacroAssemblerARM.cpp: - (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): - -2012-07-05 Zoltan Herczeg <zherczeg@webkit.org> - - Port DFG JIT to traditional ARM - https://bugs.webkit.org/show_bug.cgi?id=90198 - - Reviewed by Filip Pizlo. - - This patch contains the macro assembler part of the - DFG JIT support on ARM systems with fixed 32 bit instruction - width. A large amount of old code was refactored, and the ARMv4 - or lower support is removed from the macro assembler. - - Sunspider is improved by 8%, and V8 is 92%. - - * assembler/ARMAssembler.cpp: - (JSC::ARMAssembler::dataTransfer32): - (JSC::ARMAssembler::baseIndexTransfer32): - (JSC): - (JSC::ARMAssembler::dataTransfer16): - (JSC::ARMAssembler::baseIndexTransfer16): - (JSC::ARMAssembler::dataTransferFloat): - (JSC::ARMAssembler::baseIndexTransferFloat): - (JSC::ARMAssembler::executableCopy): - * assembler/ARMAssembler.h: - (JSC::ARMAssembler::ARMAssembler): - (JSC::ARMAssembler::emitInst): - (JSC::ARMAssembler::vmov_f64_r): - (ARMAssembler): - (JSC::ARMAssembler::vabs_f64_r): - (JSC::ARMAssembler::vneg_f64_r): - (JSC::ARMAssembler::ldr_imm): - (JSC::ARMAssembler::ldr_un_imm): - (JSC::ARMAssembler::dtr_u): - (JSC::ARMAssembler::dtr_ur): - (JSC::ARMAssembler::dtr_d): - (JSC::ARMAssembler::dtr_dr): - (JSC::ARMAssembler::dtrh_u): - (JSC::ARMAssembler::dtrh_ur): - (JSC::ARMAssembler::dtrh_d): - (JSC::ARMAssembler::dtrh_dr): - (JSC::ARMAssembler::fdtr_u): - (JSC::ARMAssembler::fdtr_d): - (JSC::ARMAssembler::push_r): - (JSC::ARMAssembler::pop_r): - (JSC::ARMAssembler::poke_r): - (JSC::ARMAssembler::peek_r): - (JSC::ARMAssembler::vmov_vfp64_r): - (JSC::ARMAssembler::vmov_arm64_r): - (JSC::ARMAssembler::vmov_vfp32_r): - (JSC::ARMAssembler::vmov_arm32_r): - (JSC::ARMAssembler::vcvt_u32_f64_r): - (JSC::ARMAssembler::vcvt_f64_f32_r): - (JSC::ARMAssembler::vcvt_f32_f64_r): - (JSC::ARMAssembler::clz_r): - (JSC::ARMAssembler::bkpt): - (JSC::ARMAssembler::bx): - (JSC::ARMAssembler::blx): - (JSC::ARMAssembler::labelIgnoringWatchpoints): - (JSC::ARMAssembler::labelForWatchpoint): - (JSC::ARMAssembler::label): - (JSC::ARMAssembler::getLdrImmAddress): - (JSC::ARMAssembler::replaceWithJump): - (JSC::ARMAssembler::maxJumpReplacementSize): - (JSC::ARMAssembler::getOp2Byte): - (JSC::ARMAssembler::getOp2Half): - (JSC::ARMAssembler::RM): - (JSC::ARMAssembler::RS): - (JSC::ARMAssembler::RD): - (JSC::ARMAssembler::RN): - * assembler/AssemblerBufferWithConstantPool.h: - (JSC::AssemblerBufferWithConstantPool::ensureSpaceForAnyInstruction): - * assembler/MacroAssemblerARM.cpp: - (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::add32): - (MacroAssemblerARM): - (JSC::MacroAssemblerARM::and32): - (JSC::MacroAssemblerARM::lshift32): - (JSC::MacroAssemblerARM::mul32): - (JSC::MacroAssemblerARM::neg32): - (JSC::MacroAssemblerARM::rshift32): - (JSC::MacroAssemblerARM::urshift32): - (JSC::MacroAssemblerARM::xor32): - (JSC::MacroAssemblerARM::load8): - (JSC::MacroAssemblerARM::load8Signed): - (JSC::MacroAssemblerARM::load16): - (JSC::MacroAssemblerARM::load16Signed): - (JSC::MacroAssemblerARM::load32): - (JSC::MacroAssemblerARM::load32WithAddressOffsetPatch): - (JSC::MacroAssemblerARM::store32WithAddressOffsetPatch): - (JSC::MacroAssemblerARM::store8): - (JSC::MacroAssemblerARM::store16): - (JSC::MacroAssemblerARM::store32): - (JSC::MacroAssemblerARM::move): - (JSC::MacroAssemblerARM::jump): - (JSC::MacroAssemblerARM::branchAdd32): - (JSC::MacroAssemblerARM::mull32): - (JSC::MacroAssemblerARM::branchMul32): - (JSC::MacroAssemblerARM::nearCall): - (JSC::MacroAssemblerARM::compare32): - (JSC::MacroAssemblerARM::test32): - (JSC::MacroAssemblerARM::sub32): - (JSC::MacroAssemblerARM::call): - (JSC::MacroAssemblerARM::loadFloat): - (JSC::MacroAssemblerARM::loadDouble): - (JSC::MacroAssemblerARM::storeFloat): - (JSC::MacroAssemblerARM::storeDouble): - (JSC::MacroAssemblerARM::moveDouble): - (JSC::MacroAssemblerARM::addDouble): - (JSC::MacroAssemblerARM::divDouble): - (JSC::MacroAssemblerARM::subDouble): - (JSC::MacroAssemblerARM::mulDouble): - (JSC::MacroAssemblerARM::absDouble): - (JSC::MacroAssemblerARM::negateDouble): - (JSC::MacroAssemblerARM::convertInt32ToDouble): - (JSC::MacroAssemblerARM::convertFloatToDouble): - (JSC::MacroAssemblerARM::convertDoubleToFloat): - (JSC::MacroAssemblerARM::branchTruncateDoubleToInt32): - (JSC::MacroAssemblerARM::branchTruncateDoubleToUint32): - (JSC::MacroAssemblerARM::truncateDoubleToInt32): - (JSC::MacroAssemblerARM::truncateDoubleToUint32): - (JSC::MacroAssemblerARM::branchConvertDoubleToInt32): - (JSC::MacroAssemblerARM::branchDoubleNonZero): - (JSC::MacroAssemblerARM::branchDoubleZeroOrNaN): - (JSC::MacroAssemblerARM::invert): - (JSC::MacroAssemblerARM::replaceWithJump): - (JSC::MacroAssemblerARM::maxJumpReplacementSize): - (JSC::MacroAssemblerARM::call32): - * assembler/SH4Assembler.h: - (JSC::SH4Assembler::label): - * dfg/DFGAssemblyHelpers.h: - (JSC::DFG::AssemblyHelpers::debugCall): - (JSC::DFG::AssemblyHelpers::boxDouble): - (JSC::DFG::AssemblyHelpers::unboxDouble): - * dfg/DFGCCallHelpers.h: - (CCallHelpers): - (JSC::DFG::CCallHelpers::setupArguments): - * dfg/DFGFPRInfo.h: - (DFG): - * dfg/DFGGPRInfo.h: - (DFG): - (GPRInfo): - * dfg/DFGOperations.cpp: - (JSC): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheckSetResult): - (JSC::DFG::SpeculativeJIT::appendCallSetResult): - * jit/JITStubs.cpp: - (JSC): - * jit/JITStubs.h: - (JITStackFrame): - * jit/JSInterfaceJIT.h: - (JSInterfaceJIT): - -2012-07-04 Anthony Scian <ascian@rim.com> - - Web Inspector [JSC]: Implement ScriptCallStack::stackTrace - https://bugs.webkit.org/show_bug.cgi?id=40118 - - Reviewed by Yong Li. - - Added member functions to expose function name, urlString, and line #. - Refactored toString to make use of these member functions to reduce - duplicated code for future maintenance. - - Manually tested refactoring of toString by tracing thrown exceptions. - - * interpreter/Interpreter.h: - (JSC::StackFrame::toString): - (JSC::StackFrame::friendlySourceURL): - (JSC::StackFrame::friendlyFunctionName): - (JSC::StackFrame::friendlyLineNumber): - -2012-07-04 Andy Wingo <wingo@igalia.com> - - [GTK] Enable parallel GC - https://bugs.webkit.org/show_bug.cgi?id=90568 - - Reviewed by Martin Robinson. - - * runtime/Options.cpp: Include <algorithm.h> for std::min. - -2012-07-04 John Mellor <johnme@chromium.org> - - Text Autosizing: Add compile flag and runtime setting - https://bugs.webkit.org/show_bug.cgi?id=87394 - - This patch renames Font Boosting to Text Autosizing. - - Reviewed by Adam Barth. - - * Configurations/FeatureDefines.xcconfig: - -2012-07-03 Michael Saboff <msaboff@apple.com> - - Enh: Hash Const JSString in Backing Stores to Save Memory - https://bugs.webkit.org/show_bug.cgi?id=86024 - - Reviewed by Oliver Hunt. - - During garbage collection, each marking thread keeps a HashMap of - strings. While visiting via MarkStack::copyAndAppend(), we check to - see if the string we are visiting is already in the HashMap. If not - we add it. If so, we change the reference to the current string we're - visiting to the prior string. - - To reduce the performance impact of this change, two throttles have - ben added. 1) We only try hash consting if a significant number of new - strings have been created since the last hash const. Currently this is - set at 100 strings. 2) If a string is unique at the end of a marking - it will not be checked during further GC phases. In some cases this - won't catch all duplicates, but we are trying to catch the growth of - duplicate strings. - - * heap/Heap.cpp: - (JSC::Heap::markRoots): - * heap/MarkStack.cpp: - (JSC::MarkStackThreadSharedData::resetChildren): - (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData): - (JSC::MarkStackThreadSharedData::reset): - (JSC::MarkStack::setup): Check to see if enough strings have been created - to hash const. - (JSC::MarkStack::reset): Added call to clear m_uniqueStrings. - (JSC::JSString::tryHashConstLock): New method to lock JSString for - hash consting. - (JSC::JSString::releaseHashConstLock): New unlock method. - (JSC::JSString::shouldTryHashConst): Set of checks to see if we should - try to hash const the string. - (JSC::MarkStack::internalAppend): New method that performs the hash consting. - (JSC::SlotVisitor::copyAndAppend): Changed to call the new hash - consting internalAppend(). - * heap/MarkStack.h: - (MarkStackThreadSharedData): - (MarkStack): - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: - (JSGlobalData): - (JSC::JSGlobalData::haveEnoughNewStringsToHashConst): - (JSC::JSGlobalData::resetNewStringsSinceLastHashConst): - * runtime/JSString.h: - (JSString): Changed from using bool flags to using an unsigned - m_flags field. This works better with the weakCompareAndSwap in - JSString::tryHashConstLock(). Changed the 8bitness setting and - checking to use new accessors. - (JSC::JSString::JSString): - (JSC::JSString::finishCreation): - (JSC::JSString::is8Bit): Updated for new m_flags. - (JSC::JSString::setIs8Bit): New setter. - New hash const flags accessors: - (JSC::JSString::isHashConstSingleton): - (JSC::JSString::clearHashConstSingleton): - (JSC::JSString::setHashConstSingleton): - (JSC::JSRopeString::finishCreation): - (JSC::JSRopeString::append): - -2012-07-03 Tony Chang <tony@chromium.org> - - [chromium] Unreviewed, update .gitignore to handle VS2010 files. - - * JavaScriptCore.gyp/.gitignore: - -2012-07-03 Mark Lam <mark.lam@apple.com> - - Add ability to symbolically set and dump JSC VM options. - See comments in runtime/Options.h for details on how the options work. - https://bugs.webkit.org/show_bug.cgi?id=90420 - - Reviewed by Filip Pizlo. - - * assembler/LinkBuffer.cpp: - (JSC::LinkBuffer::finalizeCodeWithDisassembly): - * assembler/LinkBuffer.h: - (JSC): - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::shouldOptimizeNow): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::likelyToTakeSlowCase): - (JSC::CodeBlock::couldTakeSlowCase): - (JSC::CodeBlock::likelyToTakeSpecialFastCase): - (JSC::CodeBlock::likelyToTakeDeepestSlowCase): - (JSC::CodeBlock::likelyToTakeAnySlowCase): - (JSC::CodeBlock::jitAfterWarmUp): - (JSC::CodeBlock::jitSoon): - (JSC::CodeBlock::reoptimizationRetryCounter): - (JSC::CodeBlock::countReoptimization): - (JSC::CodeBlock::counterValueForOptimizeAfterWarmUp): - (JSC::CodeBlock::counterValueForOptimizeAfterLongWarmUp): - (JSC::CodeBlock::optimizeSoon): - (JSC::CodeBlock::exitCountThresholdForReoptimization): - (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop): - * bytecode/ExecutionCounter.h: - (JSC::ExecutionCounter::clippedThreshold): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleInlining): - * dfg/DFGCapabilities.h: - (JSC::DFG::mightCompileEval): - (JSC::DFG::mightCompileProgram): - (JSC::DFG::mightCompileFunctionForCall): - (JSC::DFG::mightCompileFunctionForConstruct): - (JSC::DFG::mightInlineFunctionForCall): - (JSC::DFG::mightInlineFunctionForConstruct): - * dfg/DFGCommon.h: - (JSC::DFG::shouldShowDisassembly): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGOSRExit.cpp: - (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): - * dfg/DFGVariableAccessData.h: - (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote): - * heap/MarkStack.cpp: - (JSC::MarkStackSegmentAllocator::allocate): - (JSC::MarkStackSegmentAllocator::shrinkReserve): - (JSC::MarkStackArray::MarkStackArray): - (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData): - (JSC::SlotVisitor::donateKnownParallel): - (JSC::SlotVisitor::drain): - (JSC::SlotVisitor::drainFromShared): - * heap/MarkStack.h: - (JSC::MarkStack::mergeOpaqueRootsIfProfitable): - (JSC::MarkStack::addOpaqueRoot): - * heap/SlotVisitor.h: - (JSC::SlotVisitor::donate): - * jit/JIT.cpp: - (JSC::JIT::emitOptimizationCheck): - * jsc.cpp: - (printUsageStatement): - (parseArguments): - * runtime/InitializeThreading.cpp: - (JSC::initializeThreadingOnce): - * runtime/JSGlobalData.cpp: - (JSC::enableAssembler): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - * runtime/Options.cpp: - (JSC): - (JSC::overrideOptionWithHeuristic): - (JSC::Options::initialize): - (JSC::Options::setOption): - (JSC::Options::dumpAllOptions): - (JSC::Options::dumpOption): - * runtime/Options.h: - (JSC): - (Options): - (EntryInfo): - -2012-07-03 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> Joel Dillon <joel.dillon@codethink.co.uk> - - [Qt][Win] Fix broken QtWebKit5.lib linking - https://bugs.webkit.org/show_bug.cgi?id=88321 - - Reviewed by Kenneth Rohde Christiansen. - - The goal is to have different ports build systems define STATICALLY_LINKED_WITH_WTF - when building JavaScriptCore, if both are packaged in the same DLL, instead - of relying on the code to handle this. - The effects of BUILDING_* and STATICALLY_LINKED_WITH_* are currently the same - except for a check in Source/JavaScriptCore/config.h. - - Keeping the old way for the WX port as requested by the port's contributors. - For non-Windows ports there is no difference between IMPORT and EXPORT, no - change is needed. - - * API/JSBase.h: - JS symbols shouldn't be included by WTF objects anymore. Remove the export when BUILDING_WTF. - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops: - Make sure that JavaScriptCore uses import symbols of WTF for the Win port. - * runtime/JSExportMacros.h: - -2012-07-02 Filip Pizlo <fpizlo@apple.com> - - DFG OSR exit value recoveries should be computed lazily - https://bugs.webkit.org/show_bug.cgi?id=82155 - - Reviewed by Gavin Barraclough. - - This change aims to reduce one aspect of DFG compile times: the fact - that we currently compute the value recoveries for each local and - argument on every speculation check. We compile many speculation checks, - so this can add up quick. The strategy that this change takes is to - have the DFG save just enough information about how the compiler is - choosing to represent state, that the DFG::OSRExitCompiler can reify - the value recoveries lazily. - - This appears to be an 0.3% SunSpider speed-up and is neutral elsewhere. - - I also took the opportunity to fix the sampling regions profiler (it - was missing an export macro) and to put in more sampling regions in - the DFG (which are disabled so long as ENABLE(SAMPLING_REGIONS) is - false). - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * bytecode/CodeBlock.cpp: - (JSC): - (JSC::CodeBlock::shrinkDFGDataToFit): - * bytecode/CodeBlock.h: - (CodeBlock): - (JSC::CodeBlock::minifiedDFG): - (JSC::CodeBlock::variableEventStream): - (DFGData): - * bytecode/Operands.h: - (JSC::Operands::hasOperand): - (Operands): - (JSC::Operands::size): - (JSC::Operands::at): - (JSC::Operands::operator[]): - (JSC::Operands::isArgument): - (JSC::Operands::isVariable): - (JSC::Operands::argumentForIndex): - (JSC::Operands::variableForIndex): - (JSC::Operands::operandForIndex): - (JSC): - (JSC::dumpOperands): - * bytecode/SamplingTool.h: - (SamplingRegion): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::parse): - * dfg/DFGCFAPhase.cpp: - (JSC::DFG::performCFA): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::performCSE): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::performFixup): - * dfg/DFGGenerationInfo.h: - (JSC::DFG::GenerationInfo::GenerationInfo): - (JSC::DFG::GenerationInfo::initConstant): - (JSC::DFG::GenerationInfo::initInteger): - (JSC::DFG::GenerationInfo::initJSValue): - (JSC::DFG::GenerationInfo::initCell): - (JSC::DFG::GenerationInfo::initBoolean): - (JSC::DFG::GenerationInfo::initDouble): - (JSC::DFG::GenerationInfo::initStorage): - (GenerationInfo): - (JSC::DFG::GenerationInfo::noticeOSRBirth): - (JSC::DFG::GenerationInfo::use): - (JSC::DFG::GenerationInfo::spill): - (JSC::DFG::GenerationInfo::setSpilled): - (JSC::DFG::GenerationInfo::fillJSValue): - (JSC::DFG::GenerationInfo::fillCell): - (JSC::DFG::GenerationInfo::fillInteger): - (JSC::DFG::GenerationInfo::fillBoolean): - (JSC::DFG::GenerationInfo::fillDouble): - (JSC::DFG::GenerationInfo::fillStorage): - (JSC::DFG::GenerationInfo::appendFill): - (JSC::DFG::GenerationInfo::appendSpill): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::link): - (JSC::DFG::JITCompiler::compile): - (JSC::DFG::JITCompiler::compileFunction): - * dfg/DFGMinifiedGraph.h: Added. - (DFG): - (MinifiedGraph): - (JSC::DFG::MinifiedGraph::MinifiedGraph): - (JSC::DFG::MinifiedGraph::at): - (JSC::DFG::MinifiedGraph::append): - (JSC::DFG::MinifiedGraph::prepareAndShrink): - (JSC::DFG::MinifiedGraph::setOriginalGraphSize): - (JSC::DFG::MinifiedGraph::originalGraphSize): - * dfg/DFGMinifiedNode.cpp: Added. - (DFG): - (JSC::DFG::MinifiedNode::fromNode): - * dfg/DFGMinifiedNode.h: Added. - (DFG): - (JSC::DFG::belongsInMinifiedGraph): - (MinifiedNode): - (JSC::DFG::MinifiedNode::MinifiedNode): - (JSC::DFG::MinifiedNode::index): - (JSC::DFG::MinifiedNode::op): - (JSC::DFG::MinifiedNode::hasChild1): - (JSC::DFG::MinifiedNode::child1): - (JSC::DFG::MinifiedNode::hasConstant): - (JSC::DFG::MinifiedNode::hasConstantNumber): - (JSC::DFG::MinifiedNode::constantNumber): - (JSC::DFG::MinifiedNode::hasWeakConstant): - (JSC::DFG::MinifiedNode::weakConstant): - (JSC::DFG::MinifiedNode::getIndex): - (JSC::DFG::MinifiedNode::compareByNodeIndex): - (JSC::DFG::MinifiedNode::hasChild): - * dfg/DFGNode.h: - (Node): - * dfg/DFGOSRExit.cpp: - (JSC::DFG::OSRExit::OSRExit): - * dfg/DFGOSRExit.h: - (OSRExit): - * dfg/DFGOSRExitCompiler.cpp: - * dfg/DFGOSRExitCompiler.h: - (OSRExitCompiler): - * dfg/DFGOSRExitCompiler32_64.cpp: - (JSC::DFG::OSRExitCompiler::compileExit): - * dfg/DFGOSRExitCompiler64.cpp: - (JSC::DFG::OSRExitCompiler::compileExit): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::performPredictionPropagation): - * dfg/DFGRedundantPhiEliminationPhase.cpp: - (JSC::DFG::performRedundantPhiElimination): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::SpeculativeJIT): - (DFG): - (JSC::DFG::SpeculativeJIT::fillStorage): - (JSC::DFG::SpeculativeJIT::noticeOSRBirth): - (JSC::DFG::SpeculativeJIT::compileMovHint): - (JSC::DFG::SpeculativeJIT::compile): - (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): - * dfg/DFGSpeculativeJIT.h: - (DFG): - (JSC::DFG::SpeculativeJIT::use): - (SpeculativeJIT): - (JSC::DFG::SpeculativeJIT::spill): - (JSC::DFG::SpeculativeJIT::speculationCheck): - (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): - (JSC::DFG::SpeculativeJIT::recordSetLocal): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::fillInteger): - (JSC::DFG::SpeculativeJIT::fillDouble): - (JSC::DFG::SpeculativeJIT::fillJSValue): - (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): - (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): - (JSC::DFG::SpeculativeJIT::fillSpeculateCell): - (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::fillInteger): - (JSC::DFG::SpeculativeJIT::fillDouble): - (JSC::DFG::SpeculativeJIT::fillJSValue): - (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): - (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): - (JSC::DFG::SpeculativeJIT::fillSpeculateCell): - (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGValueRecoveryOverride.h: Added. - (DFG): - (ValueRecoveryOverride): - (JSC::DFG::ValueRecoveryOverride::ValueRecoveryOverride): - * dfg/DFGValueSource.cpp: Added. - (DFG): - (JSC::DFG::ValueSource::dump): - * dfg/DFGValueSource.h: Added. - (DFG): - (JSC::DFG::dataFormatToValueSourceKind): - (JSC::DFG::valueSourceKindToDataFormat): - (JSC::DFG::isInRegisterFile): - (ValueSource): - (JSC::DFG::ValueSource::ValueSource): - (JSC::DFG::ValueSource::forPrediction): - (JSC::DFG::ValueSource::forDataFormat): - (JSC::DFG::ValueSource::isSet): - (JSC::DFG::ValueSource::kind): - (JSC::DFG::ValueSource::isInRegisterFile): - (JSC::DFG::ValueSource::dataFormat): - (JSC::DFG::ValueSource::valueRecovery): - (JSC::DFG::ValueSource::nodeIndex): - (JSC::DFG::ValueSource::nodeIndexFromKind): - (JSC::DFG::ValueSource::kindFromNodeIndex): - * dfg/DFGVariableEvent.cpp: Added. - (DFG): - (JSC::DFG::VariableEvent::dump): - (JSC::DFG::VariableEvent::dumpFillInfo): - (JSC::DFG::VariableEvent::dumpSpillInfo): - * dfg/DFGVariableEvent.h: Added. - (DFG): - (VariableEvent): - (JSC::DFG::VariableEvent::VariableEvent): - (JSC::DFG::VariableEvent::reset): - (JSC::DFG::VariableEvent::fillGPR): - (JSC::DFG::VariableEvent::fillPair): - (JSC::DFG::VariableEvent::fillFPR): - (JSC::DFG::VariableEvent::spill): - (JSC::DFG::VariableEvent::death): - (JSC::DFG::VariableEvent::setLocal): - (JSC::DFG::VariableEvent::movHint): - (JSC::DFG::VariableEvent::kind): - (JSC::DFG::VariableEvent::nodeIndex): - (JSC::DFG::VariableEvent::dataFormat): - (JSC::DFG::VariableEvent::gpr): - (JSC::DFG::VariableEvent::tagGPR): - (JSC::DFG::VariableEvent::payloadGPR): - (JSC::DFG::VariableEvent::fpr): - (JSC::DFG::VariableEvent::virtualRegister): - (JSC::DFG::VariableEvent::operand): - (JSC::DFG::VariableEvent::variableRepresentation): - * dfg/DFGVariableEventStream.cpp: Added. - (DFG): - (JSC::DFG::VariableEventStream::logEvent): - (MinifiedGenerationInfo): - (JSC::DFG::MinifiedGenerationInfo::MinifiedGenerationInfo): - (JSC::DFG::MinifiedGenerationInfo::update): - (JSC::DFG::VariableEventStream::reconstruct): - * dfg/DFGVariableEventStream.h: Added. - (DFG): - (VariableEventStream): - (JSC::DFG::VariableEventStream::appendAndLog): - * dfg/DFGVirtualRegisterAllocationPhase.cpp: - (JSC::DFG::performVirtualRegisterAllocation): - -2012-07-02 Filip Pizlo <fpizlo@apple.com> - - DFG::ArgumentsSimplificationPhase should assert that the PhantomArguments nodes it creates are not shouldGenerate() - https://bugs.webkit.org/show_bug.cgi?id=90407 - - Reviewed by Mark Hahnenberg. - - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - -2012-07-02 Gavin Barraclough <barraclough@apple.com> - - Array.prototype.pop should throw if property is not configurable - https://bugs.webkit.org/show_bug.cgi?id=75788 - - Rubber Stamped by Oliver Hunt. - - No real bug here any more, but the error we throw sometimes has a misleading message. - - * runtime/JSArray.cpp: - (JSC::JSArray::pop): - -2012-06-29 Filip Pizlo <fpizlo@apple.com> - - JSObject wastes too much memory on unused property slots - https://bugs.webkit.org/show_bug.cgi?id=90255 - - Reviewed by Mark Hahnenberg. - - Rolling back in after applying a simple fix: it appears that - JSObject::setStructureAndReallocateStorageIfNecessary() was allocating more - property storage than necessary. Fixing this appears to resolve the crash. - - This does a few things: - - - JSNonFinalObject no longer has inline property storage. - - - Initial out-of-line property storage size is 4 slots for JSNonFinalObject, - or 2x the inline storage for JSFinalObject. - - - Property storage is only reallocated if it needs to be. Previously, we - would reallocate the property storage on any transition where the original - structure said shouldGrowProperyStorage(), but this led to spurious - reallocations when doing transitionless property adds and there are - deleted property slots available. That in turn led to crashes, because we - would switch to out-of-line storage even if the capacity matched the - criteria for inline storage. - - - Inline JSFunction allocation is killed off because we don't have a good - way of inlining property storage allocation. This didn't hurt performance. - Killing off code is better than fixing it if that code wasn't doing any - good. - - This looks like a 1% progression on V8. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JIT.cpp: - (JSC::JIT::privateCompileSlowCases): - * jit/JIT.h: - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - (JSC): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_new_func): - (JSC): - (JSC::JIT::emit_op_new_func_exp): - * runtime/JSFunction.cpp: - (JSC::JSFunction::finishCreation): - * runtime/JSObject.h: - (JSC::JSObject::isUsingInlineStorage): - (JSObject): - (JSC::JSObject::finishCreation): - (JSC): - (JSC::JSNonFinalObject::hasInlineStorage): - (JSNonFinalObject): - (JSC::JSNonFinalObject::JSNonFinalObject): - (JSC::JSNonFinalObject::finishCreation): - (JSC::JSFinalObject::hasInlineStorage): - (JSC::JSFinalObject::finishCreation): - (JSC::JSObject::offsetOfInlineStorage): - (JSC::JSObject::setPropertyStorage): - (JSC::Structure::inlineStorageCapacity): - (JSC::Structure::isUsingInlineStorage): - (JSC::JSObject::putDirectInternal): - (JSC::JSObject::setStructureAndReallocateStorageIfNecessary): - (JSC::JSObject::putDirectWithoutTransition): - * runtime/Structure.cpp: - (JSC::Structure::Structure): - (JSC::nextPropertyStorageCapacity): - (JSC): - (JSC::Structure::growPropertyStorageCapacity): - (JSC::Structure::suggestedNewPropertyStorageSize): - * runtime/Structure.h: - (JSC::Structure::putWillGrowPropertyStorage): - (Structure): - -2012-06-29 Filip Pizlo <fpizlo@apple.com> - - Webkit crashes in DFG on Google Docs when creating a new document - https://bugs.webkit.org/show_bug.cgi?id=90209 - - Reviewed by Gavin Barraclough. - - Don't attempt to short-circuit Phantom(GetLocal) if the GetLocal is for a - captured variable. - - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::mergeBlocks): - -2012-06-30 Zan Dobersek <zandobersek@gmail.com> - - Unreviewed, rolling out r121605. - http://trac.webkit.org/changeset/121605 - https://bugs.webkit.org/show_bug.cgi?id=90336 - - Changes caused flaky crashes in sputnik/Unicode tests on Apple - WK1 and GTK Linux builders - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JIT.cpp: - (JSC::JIT::privateCompileSlowCases): - * jit/JIT.h: - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - (JSC::JIT::emitAllocateJSFinalObject): - (JSC): - (JSC::JIT::emitAllocateJSFunction): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_new_func): - (JSC::JIT::emitSlow_op_new_func): - (JSC): - (JSC::JIT::emit_op_new_func_exp): - (JSC::JIT::emitSlow_op_new_func_exp): - * runtime/JSFunction.cpp: - (JSC::JSFunction::finishCreation): - * runtime/JSObject.h: - (JSC::JSObject::isUsingInlineStorage): - (JSObject): - (JSC::JSObject::finishCreation): - (JSC): - (JSNonFinalObject): - (JSC::JSNonFinalObject::JSNonFinalObject): - (JSC::JSNonFinalObject::finishCreation): - (JSFinalObject): - (JSC::JSFinalObject::finishCreation): - (JSC::JSObject::offsetOfInlineStorage): - (JSC::JSObject::setPropertyStorage): - (JSC::Structure::isUsingInlineStorage): - (JSC::JSObject::putDirectInternal): - (JSC::JSObject::putDirectWithoutTransition): - (JSC::JSObject::transitionTo): - * runtime/Structure.cpp: - (JSC::Structure::Structure): - (JSC): - (JSC::Structure::growPropertyStorageCapacity): - (JSC::Structure::suggestedNewPropertyStorageSize): - * runtime/Structure.h: - (JSC::Structure::shouldGrowPropertyStorage): - (JSC::Structure::propertyStorageSize): - -2012-06-29 Mark Hahnenberg <mhahnenberg@apple.com> - - Remove warning about protected values when the Heap is being destroyed - https://bugs.webkit.org/show_bug.cgi?id=90302 + OpaqueJSString doesn't optimally handle 8 bit strings + https://bugs.webkit.org/show_bug.cgi?id=98300 Reviewed by Geoffrey Garen. - Having to do book-keeping about whether values allocated from a certain - VM are or are not protected makes the JSC API much more difficult to use - correctly. Clients should be able to throw an entire VM away and not have - to worry about unprotecting all of the values that they protected earlier. - - * heap/Heap.cpp: - (JSC::Heap::lastChanceToFinalize): - -2012-06-29 Filip Pizlo <fpizlo@apple.com> - - JSObject wastes too much memory on unused property slots - https://bugs.webkit.org/show_bug.cgi?id=90255 - - Reviewed by Mark Hahnenberg. - - This does a few things: - - - JSNonFinalObject no longer has inline property storage. - - - Initial out-of-line property storage size is 4 slots for JSNonFinalObject, - or 2x the inline storage for JSFinalObject. - - - Property storage is only reallocated if it needs to be. Previously, we - would reallocate the property storage on any transition where the original - structure said shouldGrowProperyStorage(), but this led to spurious - reallocations when doing transitionless property adds and there are - deleted property slots available. That in turn led to crashes, because we - would switch to out-of-line storage even if the capacity matched the - criteria for inline storage. - - - Inline JSFunction allocation is killed off because we don't have a good - way of inlining property storage allocation. This didn't hurt performance. - Killing off code is better than fixing it if that code wasn't doing any - good. - - This looks like a 1% progression on V8. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JIT.cpp: - (JSC::JIT::privateCompileSlowCases): - * jit/JIT.h: - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - (JSC): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_new_func): - (JSC): - (JSC::JIT::emit_op_new_func_exp): - * runtime/JSFunction.cpp: - (JSC::JSFunction::finishCreation): - * runtime/JSObject.h: - (JSC::JSObject::isUsingInlineStorage): - (JSObject): - (JSC::JSObject::finishCreation): - (JSC): - (JSC::JSNonFinalObject::hasInlineStorage): - (JSNonFinalObject): - (JSC::JSNonFinalObject::JSNonFinalObject): - (JSC::JSNonFinalObject::finishCreation): - (JSC::JSFinalObject::hasInlineStorage): - (JSC::JSFinalObject::finishCreation): - (JSC::JSObject::offsetOfInlineStorage): - (JSC::JSObject::setPropertyStorage): - (JSC::Structure::inlineStorageCapacity): - (JSC::Structure::isUsingInlineStorage): - (JSC::JSObject::putDirectInternal): - (JSC::JSObject::setStructureAndReallocateStorageIfNecessary): - (JSC::JSObject::putDirectWithoutTransition): - * runtime/Structure.cpp: - (JSC::Structure::Structure): - (JSC::nextPropertyStorageCapacity): - (JSC): - (JSC::Structure::growPropertyStorageCapacity): - (JSC::Structure::suggestedNewPropertyStorageSize): - * runtime/Structure.h: - (JSC::Structure::putWillGrowPropertyStorage): - (Structure): - -2012-06-28 Filip Pizlo <fpizlo@apple.com> - - DFG recompilation heuristics should be based on count, not rate - https://bugs.webkit.org/show_bug.cgi?id=90146 - - Reviewed by Oliver Hunt. - - This removes a bunch of code that was previously trying to prevent spurious - reoptimizations if a large enough majority of executions of a code block did - not result in OSR exit. It turns out that this code was purely harmful. This - patch removes all of that logic and replaces it with a dead-simple - heuristic: if you exit more than N times (where N is an exponential function - of the number of times the code block has already been recompiled) then we - will recompile. - - This appears to be a broad ~1% win on many benchmarks large and small. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::CodeBlock): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::osrExitCounter): - (JSC::CodeBlock::countOSRExit): - (CodeBlock): - (JSC::CodeBlock::addressOfOSRExitCounter): - (JSC::CodeBlock::offsetOfOSRExitCounter): - (JSC::CodeBlock::adjustedExitCountThreshold): - (JSC::CodeBlock::exitCountThresholdForReoptimization): - (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop): - (JSC::CodeBlock::shouldReoptimizeNow): - (JSC::CodeBlock::shouldReoptimizeFromLoopNow): - * bytecode/ExecutionCounter.cpp: - (JSC::ExecutionCounter::setThreshold): - * bytecode/ExecutionCounter.h: - (ExecutionCounter): - (JSC::ExecutionCounter::clippedThreshold): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::compileBody): - * dfg/DFGOSRExit.cpp: - (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): - * dfg/DFGOSRExitCompiler.cpp: - (JSC::DFG::OSRExitCompiler::handleExitCounts): - * dfg/DFGOperations.cpp: - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * runtime/Options.cpp: - (Options): - (JSC::Options::initializeOptions): - * runtime/Options.h: - (Options): - -2012-06-28 Mark Lam <mark.lam@apple.com> - - Adding a commenting utility to record BytecodeGenerator comments - with opcodes that are emitted. Presently, the comments can only - be constant strings. Adding comments for opcodes is optional. - If a comment is added, the comment will be printed following the - opcode when CodeBlock::dump() is called. - - This utility is disabled by default, and is only meant for VM - development purposes. It should not be enabled for product builds. + Change OpaqueJSString to store and manage a String instead of a UChar buffer. + The member string is a copy of any string used during creation. - To enable this utility, set ENABLE_BYTECODE_COMMENTS in CodeBlock.h - to 1. - - https://bugs.webkit.org/show_bug.cgi?id=90095 - - Reviewed by Geoffrey Garen. - - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dumpBytecodeCommentAndNewLine): Dumps the comment. - (JSC): - (JSC::CodeBlock::printUnaryOp): Add comment dumps. - (JSC::CodeBlock::printBinaryOp): Add comment dumps. - (JSC::CodeBlock::printConditionalJump): Add comment dumps. - (JSC::CodeBlock::printCallOp): Add comment dumps. - (JSC::CodeBlock::printPutByIdOp): Add comment dumps. - (JSC::CodeBlock::dump): Add comment dumps. - (JSC::CodeBlock::CodeBlock): - (JSC::CodeBlock::commentForBytecodeOffset): - Finds the comment for an opcode if available. - (JSC::CodeBlock::dumpBytecodeComments): - For debugging whether comments are collected. - It is not being called anywhere. - * bytecode/CodeBlock.h: - (CodeBlock): - (JSC::CodeBlock::bytecodeComments): - * bytecode/Comment.h: Added. - (JSC): - (Comment): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::BytecodeGenerator): - (JSC::BytecodeGenerator::emitOpcode): Calls emitComment(). - (JSC): - (JSC::BytecodeGenerator::emitComment): Adds comment to CodeBlock. - (JSC::BytecodeGenerator::prependComment): - Registers a comment for emitComemnt() to use later. - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - (JSC::BytecodeGenerator::emitComment): - (JSC::BytecodeGenerator::prependComment): - These are inlined versions of these functions that nullify them - when ENABLE_BYTECODE_COMMENTS is 0. - (JSC::BytecodeGenerator::comments): - -2012-06-28 Oliver Hunt <oliver@apple.com> - - 32bit DFG incorrectly claims an fpr is fillable even if it has not been proven double - https://bugs.webkit.org/show_bug.cgi?id=90127 - - Reviewed by Filip Pizlo. - - The 32-bit version of fillSpeculateDouble doesn't handle Number->fpr loads - correctly. This patch fixes this by killing the fill info in the GenerationInfo - when the spillFormat doesn't guarantee the value is a double. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): - -2012-06-28 Kent Tamura <tkent@chromium.org> - - Classify form control states by their owner forms - https://bugs.webkit.org/show_bug.cgi?id=89950 - - Reviewed by Hajime Morita. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - Expose WTF::StringBuilder::canShrink() - -2012-06-27 Michael Saboff <msaboff@apple.com> - - [Win] jscore-tests flakey - https://bugs.webkit.org/show_bug.cgi?id=88118 - - Reviewed by Jessie Berlin. - - jsDriver.pl on windows intermittently doesn't get the returned value from jsc, - instead it gets 126. Added a new option to jsc (-x) which prints the exit - code before exiting. jsDriver.pl uses this option on Windows and parses the - exit code output for the exit code, removing it before comparing the actual - and expected outputs. Filed a follow on "FIXME" defect: - [WIN] Intermittent failure for jsc return value to propagate through jsDriver.pl - https://bugs.webkit.org/show_bug.cgi?id=90119 - - * jsc.cpp: - (CommandLine::CommandLine): - (CommandLine): - (printUsageStatement): - (parseArguments): - (jscmain): - * tests/mozilla/jsDriver.pl: - (execute_tests): - -2012-06-27 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r121359. - http://trac.webkit.org/changeset/121359 - https://bugs.webkit.org/show_bug.cgi?id=90115 - - Broke many inspector tests (Requested by jpfau on #webkit). - - * interpreter/Interpreter.h: - (JSC::StackFrame::toString): - -2012-06-27 Filip Pizlo <fpizlo@apple.com> - - Javascript SHA-512 gives wrong hash on second and subsequent runs unless Web Inspector Javascript Debugging is on - https://bugs.webkit.org/show_bug.cgi?id=90053 - <rdar://problem/11764613> - - Reviewed by Mark Hahnenberg. - - The problem is that the code was assuming that the recovery should be Undefined if the source of - the SetLocal was !shouldGenerate(). But that's wrong, since the DFG optimizer may skip around a - UInt32ToNumber node (hence making it !shouldGenerate()) and keep the source of that node alive. - In that case we should base the recovery on the source of the UInt32ToNumber. The logic for this - was already in place but the fast check for !shouldGenerate() broke it. - - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): - -2012-06-27 Filip Pizlo <fpizlo@apple.com> - - DFG disassembly should be easier to read - https://bugs.webkit.org/show_bug.cgi?id=90106 - - Reviewed by Mark Hahnenberg. - - Did a few things: - - - Options::showDFGDisassembly now shows OSR exit disassembly as well. - - - Phi node dumping doesn't attempt to do line wrapping since it just made the dump harder - to read. - - - DFG graph disassembly view shows a few additional node types that turn out to be - essential for understanding OSR exits. - - Put together, these changes reinforce the philosophy that anything needed for computing - OSR exit is just as important as the machine code itself. Of course, we still don't take - that philosophy to its full extreme - for example Phantom nodes are not dumped. We may - revisit that in the future. - - * assembler/LinkBuffer.cpp: - (JSC::LinkBuffer::finalizeCodeWithDisassembly): - * assembler/LinkBuffer.h: - (JSC): - * dfg/DFGDisassembler.cpp: - (JSC::DFG::Disassembler::dump): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dumpBlockHeader): - * dfg/DFGNode.h: - (JSC::DFG::Node::willHaveCodeGenOrOSR): - * dfg/DFGOSRExitCompiler.cpp: - * jit/JIT.cpp: - (JSC::JIT::privateCompile): - -2012-06-25 Mark Hahnenberg <mhahnenberg@apple.com> - - JSLock should be per-JSGlobalData - https://bugs.webkit.org/show_bug.cgi?id=89123 - - Reviewed by Geoffrey Garen. - - * API/APIShims.h: - (APIEntryShimWithoutLock): - (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): Added an extra parameter to the constructor to - determine whether we should ref the JSGlobalData or not. We want to ref all the time except for in the - HeapTimer class because timerDidFire could run after somebody has started to tear down that particular - JSGlobalData, so we wouldn't want to resurrect the ref count of that JSGlobalData from 0 back to 1 after - its destruction has begun. - (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock): - (JSC::APIEntryShim::APIEntryShim): - (APIEntryShim): - (JSC::APIEntryShim::~APIEntryShim): - (JSC::APIEntryShim::init): Factored out common initialization code for the various APIEntryShim constructors. - Also moved the timeoutChecker stop and start here because we need to start after we've grabbed the API lock - and before we've released it, which can only done in APIEntryShim. - (JSC::APICallbackShim::~APICallbackShim): We no longer need to synchronize here. - * API/JSContextRef.cpp: - (JSGlobalContextCreate): - (JSGlobalContextCreateInGroup): - (JSGlobalContextRelease): - (JSContextCreateBacktrace): - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * heap/CopiedSpace.cpp: - (JSC::CopiedSpace::tryAllocateSlowCase): - * heap/Heap.cpp: - (JSC::Heap::protect): - (JSC::Heap::unprotect): - (JSC::Heap::collect): - (JSC::Heap::setActivityCallback): - (JSC::Heap::activityCallback): - (JSC::Heap::sweeper): - * heap/Heap.h: Changed m_activityCallback and m_sweeper to be raw pointers rather than OwnPtrs because they - are now responsible for their own lifetime. Also changed the order of declaration of the GCActivityCallback - and the IncrementalSweeper to make sure they're the last things that get initialized during construction to - prevent any issues with uninitialized memory in the JSGlobalData/Heap they might care about. - (Heap): - * heap/HeapTimer.cpp: Refactored to allow for thread-safe operation and shutdown. - (JSC::HeapTimer::~HeapTimer): - (JSC::HeapTimer::invalidate): - (JSC): - (JSC::HeapTimer::didStartVMShutdown): Called at the beginning of ~JSGlobalData. If we're on the same thread - that the HeapTimer is running on, we kill the HeapTimer ourselves. If not, then we set some state in the - HeapTimer and schedule it to fire immediately so that it can notice and kill itself. - (JSC::HeapTimer::timerDidFire): We grab our mutex and check our JSGlobalData pointer. If it has been zero-ed - out, then we know the VM has started to shutdown and we should kill ourselves. Otherwise, grab the APIEntryShim, - but without ref-ing the JSGlobalData (we don't want to bring the JSGlobalData's ref-count from 0 to 1) in case - we were interrupted between releasing our mutex and trying to grab the APILock. - * heap/HeapTimer.h: - (HeapTimer): - * heap/IncrementalSweeper.cpp: - (JSC::IncrementalSweeper::doWork): We no longer need the API shim here since HeapTimer::timerDidFire handles - all of that for us. - (JSC::IncrementalSweeper::create): - * heap/IncrementalSweeper.h: - (IncrementalSweeper): - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::allocateSlowCase): - * heap/WeakBlock.cpp: - (JSC::WeakBlock::reap): - * jsc.cpp: - (functionGC): - (functionReleaseExecutableMemory): - (jscmain): - * runtime/Completion.cpp: - (JSC::checkSyntax): - (JSC::evaluate): - * runtime/GCActivityCallback.h: - (DefaultGCActivityCallback): - (JSC::DefaultGCActivityCallback::create): - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - (JSC::JSGlobalData::~JSGlobalData): Signals to the two HeapTimers (GCActivityCallback and IncrementalSweeper) - that the VM has started shutting down. It then waits until the HeapTimer is done with whatever activity - it needs to do before continuing with any further destruction. Also asserts that we do not currently hold the - APILock because this could potentially cause deadlock when we try to signal to the HeapTimers using their mutexes. - (JSC::JSGlobalData::sharedInstance): Protect the initialization for the shared instance with the GlobalJSLock. - (JSC::JSGlobalData::sharedInstanceInternal): - * runtime/JSGlobalData.h: Change to be ThreadSafeRefCounted so that we don't have to worry about refing and - de-refing JSGlobalDatas on separate threads since we don't do it that often anyways. - (JSGlobalData): - (JSC::JSGlobalData::apiLock): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::~JSGlobalObject): - (JSC::JSGlobalObject::init): - * runtime/JSLock.cpp: - (JSC): - (JSC::GlobalJSLock::GlobalJSLock): For accessing the shared instance. - (JSC::GlobalJSLock::~GlobalJSLock): - (JSC::JSLockHolder::JSLockHolder): MutexLocker for JSLock. Also refs the JSGlobalData to keep it alive so that - it can successfully unlock it later without it disappearing from underneath it. - (JSC::JSLockHolder::~JSLockHolder): - (JSC::JSLock::JSLock): - (JSC::JSLock::~JSLock): - (JSC::JSLock::lock): Uses the spin lock for guarding the lock count and owner thread fields. Uses the mutex for - actually waiting for long periods. - (JSC::JSLock::unlock): - (JSC::JSLock::currentThreadIsHoldingLock): - (JSC::JSLock::dropAllLocks): - (JSC::JSLock::dropAllLocksUnconditionally): - (JSC::JSLock::grabAllLocks): - (JSC::JSLock::DropAllLocks::DropAllLocks): - (JSC::JSLock::DropAllLocks::~DropAllLocks): - * runtime/JSLock.h: - (JSC): - (GlobalJSLock): - (JSLockHolder): - (JSLock): - (DropAllLocks): - * runtime/WeakGCMap.h: - (JSC::WeakGCMap::set): - * testRegExp.cpp: - (realMain): - -2012-06-27 Filip Pizlo <fpizlo@apple.com> - - x86 disassembler confuses immediates with addresses - https://bugs.webkit.org/show_bug.cgi?id=90099 - - Reviewed by Mark Hahnenberg. - - Prepend "$" to immediates to disambiguate between immediates and addresses. This is in - accordance with the gas and AT&T syntax. - - * disassembler/udis86/udis86_syn-att.c: - (gen_operand): - -2012-06-27 Filip Pizlo <fpizlo@apple.com> - - Add a comment clarifying Options::showDisassembly versus Options::showDFGDisassembly. - - Rubber stamped by Mark Hahnenberg. - - * runtime/Options.cpp: - (JSC::Options::initializeOptions): - -2012-06-27 Anthony Scian <ascian@rim.com> - - Web Inspector [JSC]: Implement ScriptCallStack::stackTrace - https://bugs.webkit.org/show_bug.cgi?id=40118 - - Reviewed by Yong Li. - - Added member functions to expose function name, urlString, and line #. - Refactored toString to make use of these member functions to reduce - duplicated code for future maintenance. - - Manually tested refactoring of toString by tracing thrown exceptions. - - * interpreter/Interpreter.h: - (StackFrame): - (JSC::StackFrame::toString): - (JSC::StackFrame::friendlySourceURL): - (JSC::StackFrame::friendlyFunctionName): - (JSC::StackFrame::friendlyLineNumber): - -2012-06-27 Oswald Buddenhagen <oswald.buddenhagen@nokia.com> - - [Qt] Remove redundant c++11 warning suppression code - - This is already handled in default_post. - - Reviewed by Tor Arne Vestbø. - - * Target.pri: - -2012-06-26 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> - - [Qt] Add missing heades to HEADERS - - For JavaScriptCore there aren't any Qt specific files, so we include all - headers for easy editing in Qt Creator. - - Reviewed by Simon Hausmann. - - * Target.pri: - -2012-06-26 Dominic Cooney <dominicc@chromium.org> - - [Chromium] Remove unused build scripts and empty folders for JavaScriptCore w/ gyp - https://bugs.webkit.org/show_bug.cgi?id=90029 - - Reviewed by Adam Barth. - - * gyp: Removed. - * gyp/generate-derived-sources.sh: Removed. - * gyp/generate-dtrace-header.sh: Removed. - * gyp/run-if-exists.sh: Removed. - * gyp/update-info-plist.sh: Removed. - -2012-06-26 Geoffrey Garen <ggaren@apple.com> - - Reduced (but did not eliminate) use of "berzerker GC" - https://bugs.webkit.org/show_bug.cgi?id=89237 - - Reviewed by Gavin Barraclough. - - (PART 2) - - This part turns off "berzerker GC" and turns on incremental shrinking. - - * heap/IncrementalSweeper.cpp: - (JSC::IncrementalSweeper::doSweep): Free or shrink after sweeping to - maintain the behavior we used to get from the occasional berzerker GC, - which would run all finalizers and then free or shrink all blocks - synchronously. - - * heap/MarkedBlock.h: - (JSC::MarkedBlock::needsSweeping): Sweep zapped blocks, too. It's always - safe to sweep a zapped block (that's the point of zapping), and it's - sometimes profitable. For example, consider this case: Block A does some - allocation (transitioning Block A from Marked to FreeListed), then GC - happens (transitioning Block A to Zapped), then all objects in Block A - are free, then the incremental sweeper visits Block A. If we skipped - Zapped blocks, we'd skip Block A, even though it would be profitable to - run its destructors and free its memory. - - * runtime/GCActivityCallback.cpp: - (JSC::DefaultGCActivityCallback::doWork): Don't sweep eagerly; we'll do - this incrementally. - -2012-06-26 Filip Pizlo <fpizlo@apple.com> - - DFG PutByValAlias is too aggressive - https://bugs.webkit.org/show_bug.cgi?id=90026 - <rdar://problem/11751830> - - Reviewed by Gavin Barraclough. - - For CSE on normal arrays, we now treat PutByVal as impure. This does not appear to affect - performance by much. - - For CSE on typed arrays, we fix PutByValAlias by making GetByVal speculate that the access - is within bounds. This also has the effect of making our out-of-bounds handling consistent - with WebCore. - - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::byValIsPure): - (JSC::DFG::Graph::clobbersWorld): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray): - (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray): - -2012-06-26 Yong Li <yoli@rim.com> - - [BlackBerry] Add JSC statistics into about:memory - https://bugs.webkit.org/show_bug.cgi?id=89779 - - Reviewed by Rob Buis. - - Fix non-JIT build on BlackBerry broken by r121196. + * API/OpaqueJSString.cpp: + (OpaqueJSString::create): + (OpaqueJSString::identifier): + * API/OpaqueJSString.h: + (OpaqueJSString::characters): + (OpaqueJSString::length): + (OpaqueJSString::string): + (OpaqueJSString::OpaqueJSString): + (OpaqueJSString): - * runtime/MemoryStatistics.cpp: - (JSC::globalMemoryStatistics): +2012-10-03 Filip Pizlo <fpizlo@apple.com> -2012-06-25 Filip Pizlo <fpizlo@apple.com> + Array.splice should be fast when it is used to remove elements other than the very first + https://bugs.webkit.org/show_bug.cgi?id=98236 - DFG::operationNewArray is unnecessarily slow, and may use the wrong array - prototype when inlined - https://bugs.webkit.org/show_bug.cgi?id=89821 + Reviewed by Michael Saboff. - Reviewed by Geoffrey Garen. - - Fixes all array allocations to use the right structure, and hence the right prototype. Adds - inlining of new Array(...) with a non-zero number of arguments. Optimizes allocations of - empty arrays. + Applied the same technique that was used to optimize the unshift case of splice in + http://trac.webkit.org/changeset/129676. This is a >20x speed-up on programs that + use splice for element removal. - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleConstantInternalFunction): - * dfg/DFGCCallHelpers.h: - (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): - (CCallHelpers): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): + * runtime/ArrayPrototype.cpp: + (JSC::shift): + * runtime/JSArray.cpp: + (JSC::JSArray::shiftCount): * runtime/JSArray.h: - (JSC): - (JSC::constructArray): - * runtime/JSGlobalObject.h: - (JSC): - (JSC::constructArray): - -2012-06-26 Filip Pizlo <fpizlo@apple.com> - - New fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit.html fails on 32 bit - https://bugs.webkit.org/show_bug.cgi?id=89953 - - Reviewed by Zoltan Herczeg. - - DFG 32-bit JIT was confused about the difference between a predicted type and a - proven type. This is easy to get confused about, since a local that is predicted int32 - almost always means that the local must be an int32 since speculations are hoisted to - stores to locals. But that is less likely to be the case for arguments, where there is - an additional least-upper-bounding step: any store to an argument with a weird type - may force the argument to be any type. - - This patch basically duplicates the functionality in DFGSpeculativeJIT64.cpp for - GetLocal: the decision of whether to load a local as an int32 (or as an array, or as - a boolean) is made based on the AbstractValue::m_type, which is a type proof, rather - than the VariableAccessData::prediction(), which is a predicted type. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-06-25 Filip Pizlo <fpizlo@apple.com> - - JSC should try to make profiling deterministic because otherwise reproducing failures is - nearly impossible - https://bugs.webkit.org/show_bug.cgi?id=89940 - - Rubber stamped by Gavin Barraclough. - - This rolls out the part of http://trac.webkit.org/changeset/121215 that introduced randomness - into the system. Now, instead of randomizing the tier-up threshold, we always set it to an - artificially low (and statically predetermined!) value. This gives most of the benefit of - threshold randomization without actually making the system behave completely differently on - each invocation. - - * bytecode/ExecutionCounter.cpp: - (JSC::ExecutionCounter::setThreshold): - * runtime/Options.cpp: - (Options): - (JSC::Options::initializeOptions): - * runtime/Options.h: - (Options): - -2012-06-22 Filip Pizlo <fpizlo@apple.com> - - Value profiling should use tier-up threshold randomization to get more coverage - https://bugs.webkit.org/show_bug.cgi?id=89802 - - Reviewed by Gavin Barraclough. - - This patch causes both LLInt and Baseline JIT code to take the OSR slow path several - times before actually doing OSR. If we take the OSR slow path before the execution - count threshold is reached, then we just call CodeBlock::updateAllPredictions() to - compute the current latest least-upper-bound SpecType of all values seen in each - ValueProfile. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::stronglyVisitStrongReferences): - (JSC::CodeBlock::updateAllPredictionsAndCountLiveness): - (JSC): - (JSC::CodeBlock::updateAllPredictions): - (JSC::CodeBlock::shouldOptimizeNow): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::llintExecuteCounter): - (JSC::CodeBlock::jitExecuteCounter): - (CodeBlock): - (JSC::CodeBlock::updateAllPredictions): - * bytecode/ExecutionCounter.cpp: - (JSC::ExecutionCounter::setThreshold): - (JSC::ExecutionCounter::status): - (JSC): - * bytecode/ExecutionCounter.h: - (JSC::ExecutionCounter::count): - (ExecutionCounter): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGOperations.cpp: - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::jitCompileAndSetHeuristics): - (JSC::LLInt::entryOSR): - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - (JSC): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::weakRandomInteger): - * runtime/Options.cpp: - (Options): - (JSC::Options::initializeOptions): - * runtime/Options.h: - (Options): - * runtime/WeakRandom.h: - (WeakRandom): - (JSC::WeakRandom::seedUnsafe): - -2012-06-25 Yong Li <yoli@rim.com> - - [BlackBerry] Add JSC statistics into about:memory - https://bugs.webkit.org/show_bug.cgi?id=89779 - - Reviewed by Rob Buis. - - Add MemoryStatistics.cpp into build, and fill JITBytes for BlackBerry port. - - * PlatformBlackBerry.cmake: - * runtime/MemoryStatistics.cpp: - (JSC::globalMemoryStatistics): - -2012-06-23 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r121058. - http://trac.webkit.org/changeset/121058 - https://bugs.webkit.org/show_bug.cgi?id=89809 - - Patch causes plugins tests to crash in GTK debug builds - (Requested by zdobersek on #webkit). - - * API/APIShims.h: - (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): - (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock): - (APIEntryShimWithoutLock): - (JSC::APIEntryShim::APIEntryShim): - (APIEntryShim): - (JSC::APICallbackShim::~APICallbackShim): - * API/JSContextRef.cpp: - (JSGlobalContextCreate): - (JSGlobalContextCreateInGroup): - (JSGlobalContextRelease): - (JSContextCreateBacktrace): - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * heap/CopiedSpace.cpp: - (JSC::CopiedSpace::tryAllocateSlowCase): - * heap/Heap.cpp: - (JSC::Heap::protect): - (JSC::Heap::unprotect): - (JSC::Heap::collect): - (JSC::Heap::setActivityCallback): - (JSC::Heap::activityCallback): - (JSC::Heap::sweeper): - * heap/Heap.h: - (Heap): - * heap/HeapTimer.cpp: - (JSC::HeapTimer::~HeapTimer): - (JSC::HeapTimer::invalidate): - (JSC::HeapTimer::timerDidFire): - (JSC): - * heap/HeapTimer.h: - (HeapTimer): - * heap/IncrementalSweeper.cpp: - (JSC::IncrementalSweeper::doWork): - (JSC::IncrementalSweeper::create): - * heap/IncrementalSweeper.h: - (IncrementalSweeper): - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::allocateSlowCase): - * heap/WeakBlock.cpp: - (JSC::WeakBlock::reap): - * jsc.cpp: - (functionGC): - (functionReleaseExecutableMemory): - (jscmain): - * runtime/Completion.cpp: - (JSC::checkSyntax): - (JSC::evaluate): - * runtime/GCActivityCallback.h: - (DefaultGCActivityCallback): - (JSC::DefaultGCActivityCallback::create): - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - (JSC::JSGlobalData::~JSGlobalData): - (JSC::JSGlobalData::sharedInstance): - (JSC::JSGlobalData::sharedInstanceInternal): - * runtime/JSGlobalData.h: - (JSGlobalData): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::~JSGlobalObject): - (JSC::JSGlobalObject::init): - * runtime/JSLock.cpp: - (JSC): - (JSC::createJSLockCount): - (JSC::JSLock::lockCount): - (JSC::setLockCount): - (JSC::JSLock::JSLock): - (JSC::JSLock::lock): - (JSC::JSLock::unlock): - (JSC::JSLock::currentThreadIsHoldingLock): - (JSC::JSLock::DropAllLocks::DropAllLocks): - (JSC::JSLock::DropAllLocks::~DropAllLocks): - * runtime/JSLock.h: - (JSC): - (JSLock): - (JSC::JSLock::JSLock): - (JSC::JSLock::~JSLock): - (DropAllLocks): - * runtime/WeakGCMap.h: - (JSC::WeakGCMap::set): - * testRegExp.cpp: - (realMain): - -2012-06-22 Alexandru Chiculita <achicu@adobe.com> - - [CSS Shaders] Re-enable the CSS Shaders compile time flag on Safari Mac - https://bugs.webkit.org/show_bug.cgi?id=89781 - - Reviewed by Dean Jackson. - - Added ENABLE_CSS_SHADERS flag as enabled by default on Safari for Mac. - - * Configurations/FeatureDefines.xcconfig: - -2012-06-22 Filip Pizlo <fpizlo@apple.com> - - DFG tier-up should happen in prologues, not epilogues - https://bugs.webkit.org/show_bug.cgi?id=89752 - - Reviewed by Geoffrey Garen. - - This change has two outcomes: - - 1) Slightly reduces the likelihood that a function will be optimized both - standalone and via inlining. Previously, if you had a call sequence like foo() - calls bar() exactly once, and nobody else calls bar(), then bar() would get - optimized first (because it returns first) and then foo() gets optimized. If foo() - can inline bar() then that means that bar() gets optimized twice. But now, if we - optimize in prologues, then foo() will be optimized first. If it inlines bar(), - that means that there will no longer be any calls to bar(). - - 2) It lets us kill some code in JITStubs. Epilogue tier-up was very different from - loop tier-up, since epilogue tier-up should not attempt OSR. But prologue tier-up - requires OSR (albeit really easy OSR since it's the top of the compilation unit), - so it becomes just like loop tier-up. As a result, we now have one optimization - hook (cti_optimize) instead of two (cti_optimize_from_loop and - cti_optimize_from_ret). - - As a consequence of not having an optimization check in epilogues, the OSR exit - code must now trigger reoptimization itself instead of just signaling the epilogue - check to fire. - - This also adds the ability to count the number of DFG compilations, which was - useful for debugging this patch and might be useful for other things in the future. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::reoptimize): - (JSC): - * bytecode/CodeBlock.h: - (CodeBlock): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseCodeBlock): - * dfg/DFGDriver.cpp: - (DFG): - (JSC::DFG::getNumCompilations): - (JSC::DFG::compile): - * dfg/DFGDriver.h: - (DFG): - * dfg/DFGOSRExitCompiler.cpp: - (JSC::DFG::OSRExitCompiler::handleExitCounts): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * jit/JIT.cpp: - (JSC::JIT::emitOptimizationCheck): - * jit/JIT.h: - * jit/JITCall32_64.cpp: - (JSC::JIT::emit_op_ret): - (JSC::JIT::emit_op_ret_object_or_this): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_ret): - (JSC::JIT::emit_op_ret_object_or_this): - (JSC::JIT::emit_op_enter): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_enter): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - * jit/JITStubs.h: - -2012-06-20 Mark Hahnenberg <mhahnenberg@apple.com> - - JSLock should be per-JSGlobalData - https://bugs.webkit.org/show_bug.cgi?id=89123 - - Reviewed by Gavin Barraclough. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * API/APIShims.h: - (APIEntryShimWithoutLock): - (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): Added an extra parameter to the constructor to - determine whether we should ref the JSGlobalData or not. We want to ref all the time except for in the - HeapTimer class because timerDidFire could run after somebody has started to tear down that particular - JSGlobalData, so we wouldn't want to resurrect the ref count of that JSGlobalData from 0 back to 1 after - its destruction has begun. - (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock): Now derefs if it also refed. - (JSC::APIEntryShim::APIEntryShim): - (APIEntryShim): - (JSC::APIEntryShim::~APIEntryShim): - (JSC::APIEntryShim::init): Factored out common initialization code for the various APIEntryShim constructors. - Also moved the timeoutChecker stop and start here because we need to start after we've grabbed the API lock - and before we've released it, which can only done in APIEntryShim. - (JSC::APICallbackShim::~APICallbackShim): We no longer need to synchronize here. - * API/JSContextRef.cpp: - (JSGlobalContextCreate): - (JSGlobalContextCreateInGroup): - (JSGlobalContextRelease): - (JSContextCreateBacktrace): - * heap/CopiedSpace.cpp: - (JSC::CopiedSpace::tryAllocateSlowCase): - * heap/Heap.cpp: - (JSC::Heap::protect): - (JSC::Heap::unprotect): - (JSC::Heap::collect): - (JSC::Heap::setActivityCallback): - (JSC::Heap::activityCallback): - (JSC::Heap::sweeper): - * heap/Heap.h: Changed m_activityCallback and m_sweeper to be raw pointers rather than OwnPtrs because they - are now responsible for their own lifetime. Also changed the order of declaration of the GCActivityCallback - and the IncrementalSweeper to make sure they're the last things that get initialized during construction to - prevent any issues with uninitialized memory in the JSGlobalData/Heap they might care about. - (Heap): - * heap/HeapTimer.cpp: Refactored to allow for thread-safe operation and shutdown. - (JSC::HeapTimer::~HeapTimer): - (JSC::HeapTimer::invalidate): - (JSC): - (JSC::HeapTimer::didStartVMShutdown): Called at the beginning of ~JSGlobalData. If we're on the same thread - that the HeapTimer is running on, we kill the HeapTimer ourselves. If not, then we set some state in the - HeapTimer and schedule it to fire immediately so that it can notice and kill itself. - (JSC::HeapTimer::timerDidFire): We grab our mutex and check our JSGlobalData pointer. If it has been zero-ed - out, then we know the VM has started to shutdown and we should kill ourselves. Otherwise, grab the APIEntryShim, - but without ref-ing the JSGlobalData (we don't want to bring the JSGlobalData's ref-count from 0 to 1) in case - we were interrupted between releasing our mutex and trying to grab the APILock. - * heap/HeapTimer.h: - (HeapTimer): - * heap/IncrementalSweeper.cpp: - (JSC::IncrementalSweeper::doWork): We no longer need the API shim here since HeapTimer::timerDidFire handles - all of that for us. - (JSC::IncrementalSweeper::create): - * heap/IncrementalSweeper.h: - (IncrementalSweeper): - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::allocateSlowCase): - * heap/WeakBlock.cpp: - (JSC::WeakBlock::reap): - * jsc.cpp: - (functionGC): - (functionReleaseExecutableMemory): - (jscmain): - * runtime/Completion.cpp: - (JSC::checkSyntax): - (JSC::evaluate): - * runtime/GCActivityCallback.h: - (DefaultGCActivityCallback): - (JSC::DefaultGCActivityCallback::create): - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - (JSC::JSGlobalData::~JSGlobalData): Signals to the two HeapTimers (GCActivityCallback and IncrementalSweeper) - that the VM has started shutting down. It then waits until the HeapTimer is done with whatever activity - it needs to do before continuing with any further destruction. Also asserts that we do not currently hold the - APILock because this could potentially cause deadlock when we try to signal to the HeapTimers using their mutexes. - (JSC::JSGlobalData::sharedInstance): Protect the initialization for the shared instance with the GlobalJSLock. - (JSC::JSGlobalData::sharedInstanceInternal): - * runtime/JSGlobalData.h: Change to be ThreadSafeRefCounted so that we don't have to worry about refing and - de-refing JSGlobalDatas on separate threads since we don't do it that often anyways. - (JSGlobalData): - (JSC::JSGlobalData::apiLock): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::~JSGlobalObject): - (JSC::JSGlobalObject::init): - * runtime/JSLock.cpp: - (JSC): - (JSC::GlobalJSLock::GlobalJSLock): For accessing the shared instance. - (JSC::GlobalJSLock::~GlobalJSLock): - (JSC::JSLockHolder::JSLockHolder): MutexLocker for JSLock. Also refs the JSGlobalData to keep it alive so that - it can successfully unlock it later without it disappearing from underneath it. - (JSC::JSLockHolder::~JSLockHolder): - (JSC::JSLock::JSLock): - (JSC::JSLock::~JSLock): - (JSC::JSLock::lock): Uses the spin lock for guarding the lock count and owner thread fields. Uses the mutex for - actually waiting for long periods. - (JSC::JSLock::unlock): - (JSC::JSLock::currentThreadIsHoldingLock): - (JSC::JSLock::dropAllLocks): - (JSC::JSLock::dropAllLocksUnconditionally): - (JSC::JSLock::grabAllLocks): - (JSC::JSLock::DropAllLocks::DropAllLocks): - (JSC::JSLock::DropAllLocks::~DropAllLocks): - * runtime/JSLock.h: - (JSC): - (GlobalJSLock): - (JSLockHolder): - (JSLock): - (DropAllLocks): - * runtime/WeakGCMap.h: - (JSC::WeakGCMap::set): - * testRegExp.cpp: - (realMain): - -2012-06-22 Peter Beverloo <peter@chromium.org> - - [Chromium] Disable c++0x compatibility warnings in JavaScriptCore.gyp when building for Android - https://bugs.webkit.org/show_bug.cgi?id=88853 - - Reviewed by Steve Block. - - The Android exclusions were necessary to fix a gyp generation error, as - the gcc_version variable wasn't being defined for Android. Remove these - exceptions when Chromium is able to define the gcc_version variable. - - * JavaScriptCore.gyp/JavaScriptCore.gyp: - -2012-06-21 Filip Pizlo <fpizlo@apple.com> - - op_resolve_global should not prevent DFG inlining - https://bugs.webkit.org/show_bug.cgi?id=89726 - - Reviewed by Gavin Barraclough. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::CodeBlock): - (JSC::CodeBlock::shrinkToFit): - * bytecode/GlobalResolveInfo.h: - (JSC::GlobalResolveInfo::GlobalResolveInfo): - (GlobalResolveInfo): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - * dfg/DFGCapabilities.h: - (JSC::DFG::canInlineOpcode): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-06-20 Filip Pizlo <fpizlo@apple.com> - - DFG should inline 'new Array()' - https://bugs.webkit.org/show_bug.cgi?id=89632 - - Reviewed by Geoffrey Garen. - - This adds support for treating InternalFunction like intrinsics. The code - to do so is actually quite clean, so I don't feel bad about perpetuating - the InternalFunction vs. JSFunction-with-NativeExecutable dichotomy. - - Currently this newfound power is only used to inline 'new Array()'. - - * dfg/DFGByteCodeParser.cpp: - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::handleCall): - (JSC::DFG::ByteCodeParser::handleConstantInternalFunction): - (DFG): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::isInternalFunctionConstant): - (JSC::DFG::Graph::valueOfInternalFunctionConstant): - -2012-06-21 Mark Hahnenberg <mhahnenberg@apple.com> - - Adding copyrights to new files. - - * heap/HeapTimer.cpp: - * heap/HeapTimer.h: - * heap/IncrementalSweeper.cpp: - * heap/IncrementalSweeper.h: - -2012-06-21 Arnaud Renevier <arno@renevier.net> - - make sure headers are included only once per file - https://bugs.webkit.org/show_bug.cgi?id=88922 - - Reviewed by Alexey Proskuryakov. - - * bytecode/CodeBlock.h: - * heap/MachineStackMarker.cpp: - * runtime/JSVariableObject.h: - -2012-06-21 Ryuan Choi <ryuan.choi@gmail.com> - - [EFL][WK2] Make WebKit2/Efl headers and resources installable. - https://bugs.webkit.org/show_bug.cgi?id=88207 - - Reviewed by Chang Shu. - - * shell/CMakeLists.txt: Use ${EXEC_INSTALL_DIR} instead of hardcoding "bin" - -2012-06-20 Geoffrey Garen <ggaren@apple.com> - - Reduced (but did not eliminate) use of "berzerker GC" - https://bugs.webkit.org/show_bug.cgi?id=89237 - - Reviewed by Gavin Barraclough. - - (PART 1) - - This patch turned out to be crashy, so I'm landing the non-crashy bits - first. - - This part is pre-requisite refactoring. I didn't actually turn off - "berzerker GC" or turn on incremental shrinking. - - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::removeBlock): Make sure to clear the free list when - we throw away the block we're currently allocating out of. Otherwise, we'll - allocate out of a stale free list. - - * heap/MarkedSpace.cpp: - (JSC::Free::Free): - (JSC::Free::operator()): - (JSC::Free::returnValue): Refactored this functor to use a shared helper - function, so we can share our implementation with the incremental sweeper. - - Also changed to freeing individual blocks immediately instead of linking - them into a list for later freeing. This makes the programming interface - simpler, and it's slightly more efficient to boot. - - (JSC::MarkedSpace::~MarkedSpace): Updated for rename. - - (JSC::MarkedSpace::freeBlock): - (JSC::MarkedSpace::freeOrShrinkBlock): New helper functions to share behavior - with the incremental sweeper. - - (JSC::MarkedSpace::shrink): Updated for new functor behavior. - - * heap/MarkedSpace.h: Statically typed languages are awesome. - -2012-06-20 Filip Pizlo <fpizlo@apple.com> - - DFG should optimize ResolveGlobal - https://bugs.webkit.org/show_bug.cgi?id=89617 - - Reviewed by Oliver Hunt. - - This adds inlining of ResolveGlobal accesses that are known monomorphic. It also - adds the specific function optimization to ResolveGlobal, when it is inlined. And, - it makes internal functions act like specific functions, since that will be the - most common use-case of this optimization. - - This is only a slighy speed-up (sub 1%), since we don't yet do the obvious thing - with this optimization, which is to completely inline common "globally resolved" - function and constructor calls, like "new Array()". - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::globalResolveInfoForBytecodeOffset): - * bytecode/CodeBlock.h: - (CodeBlock): - (JSC::CodeBlock::numberOfGlobalResolveInfos): - * bytecode/GlobalResolveInfo.h: - (JSC::getGlobalResolveInfoBytecodeOffset): - (JSC): - * bytecode/ResolveGlobalStatus.cpp: Added. - (JSC): - (JSC::computeForStructure): - (JSC::computeForLLInt): - (JSC::ResolveGlobalStatus::computeFor): - * bytecode/ResolveGlobalStatus.h: Added. - (JSC): - (ResolveGlobalStatus): - (JSC::ResolveGlobalStatus::ResolveGlobalStatus): - (JSC::ResolveGlobalStatus::state): - (JSC::ResolveGlobalStatus::isSet): - (JSC::ResolveGlobalStatus::operator!): - (JSC::ResolveGlobalStatus::isSimple): - (JSC::ResolveGlobalStatus::takesSlowPath): - (JSC::ResolveGlobalStatus::structure): - (JSC::ResolveGlobalStatus::offset): - (JSC::ResolveGlobalStatus::specificValue): - * dfg/DFGByteCodeParser.cpp: - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::handleGetByOffset): - (DFG): - (JSC::DFG::ByteCodeParser::handleGetById): - (JSC::DFG::ByteCodeParser::parseBlock): - * runtime/JSObject.cpp: - (JSC::getCallableObjectSlow): - (JSC): - (JSC::JSObject::put): - (JSC::JSObject::putDirectVirtual): - (JSC::JSObject::putDirectAccessor): - * runtime/JSObject.h: - (JSC): - (JSC::getCallableObject): - (JSC::JSObject::putOwnDataProperty): - (JSC::JSObject::putDirect): - (JSC::JSObject::putDirectWithoutTransition): - -2012-06-20 Filip Pizlo <fpizlo@apple.com> - - Functions on global objects should be specializable - https://bugs.webkit.org/show_bug.cgi?id=89615 - - Reviewed by Oliver Hunt. - - I tested to see if this brought back the bug in https://bugs.webkit.org/show_bug.cgi?id=33343, - and it didn't. Bug 33343 was the reason why we disabled global object function specialization - to begin with. So I'm guessing this is safe. - - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::init): - -2012-06-20 Filip Pizlo <fpizlo@apple.com> - - build-webkit failure due to illegal 32-bit integer constants in code - generated by offlineasm - https://bugs.webkit.org/show_bug.cgi?id=89347 - - Reviewed by Geoffrey Garen. - - The offending constants are the magic numbers used by offlineasm to find - offsets in the generated machine code. Added code to turn them into what - the C++ compiler will believe to be valid 32-bit values. - - * offlineasm/offsets.rb: - -2012-06-19 Geoffrey Garen <ggaren@apple.com> - - Made the incremental sweeper more aggressive - https://bugs.webkit.org/show_bug.cgi?id=89527 - - Reviewed by Oliver Hunt. - - This is a pre-requisite to getting rid of "berzerker GC" because we need - the sweeper to reclaim memory in a timely fashion, or we'll see a memory - footprint regression. - - * heap/IncrementalSweeper.h: - * heap/IncrementalSweeper.cpp: - (JSC::IncrementalSweeper::scheduleTimer): Since the time slice is predictable, - no need to use a data member to record it. - - (JSC::IncrementalSweeper::doSweep): Sweep as many blocks as we can in a - small time slice. This is better than sweeping only one block per timer - fire because that strategy has a heavy timer overhead, and artificially - delays memory reclamation. - -2012-06-20 Filip Pizlo <fpizlo@apple.com> - - DFG should be able to print disassembly interleaved with the IR - https://bugs.webkit.org/show_bug.cgi?id=89551 - - Reviewed by Geoffrey Garen. - - This change also removes running Dominators unconditionally on every DFG - compile. Dominators are designed to be computed on-demand, and currently - the only demand is graph dumps. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * assembler/ARMv7Assembler.h: - (JSC::ARMv7Assembler::labelIgnoringWatchpoints): - (ARMv7Assembler): - * assembler/AbstractMacroAssembler.h: - (AbstractMacroAssembler): - (JSC::AbstractMacroAssembler::labelIgnoringWatchpoints): - * assembler/X86Assembler.h: - (X86Assembler): - (JSC::X86Assembler::labelIgnoringWatchpoints): - * dfg/DFGCommon.h: - (JSC::DFG::shouldShowDisassembly): - (DFG): - * dfg/DFGDisassembler.cpp: Added. - (DFG): - (JSC::DFG::Disassembler::Disassembler): - (JSC::DFG::Disassembler::dump): - (JSC::DFG::Disassembler::dumpDisassembly): - * dfg/DFGDisassembler.h: Added. - (DFG): - (Disassembler): - (JSC::DFG::Disassembler::setStartOfCode): - (JSC::DFG::Disassembler::setForBlock): - (JSC::DFG::Disassembler::setForNode): - (JSC::DFG::Disassembler::setEndOfMainPath): - (JSC::DFG::Disassembler::setEndOfCode): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dumpCodeOrigin): - (JSC::DFG::Graph::amountOfNodeWhiteSpace): - (DFG): - (JSC::DFG::Graph::printNodeWhiteSpace): - (JSC::DFG::Graph::dump): - (JSC::DFG::Graph::dumpBlockHeader): - * dfg/DFGGraph.h: - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::JITCompiler): - (DFG): - (JSC::DFG::JITCompiler::compile): - (JSC::DFG::JITCompiler::compileFunction): - * dfg/DFGJITCompiler.h: - (JITCompiler): - (JSC::DFG::JITCompiler::setStartOfCode): - (JSC::DFG::JITCompiler::setForBlock): - (JSC::DFG::JITCompiler::setForNode): - (JSC::DFG::JITCompiler::setEndOfMainPath): - (JSC::DFG::JITCompiler::setEndOfCode): - * dfg/DFGNode.h: - (Node): - (JSC::DFG::Node::willHaveCodeGen): - * dfg/DFGNodeFlags.cpp: - (JSC::DFG::nodeFlagsAsString): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - * runtime/Options.cpp: - (Options): - (JSC::Options::initializeOptions): - * runtime/Options.h: - (Options): - -2012-06-19 Filip Pizlo <fpizlo@apple.com> - - JSC should be able to show disassembly for all generated JIT code - https://bugs.webkit.org/show_bug.cgi?id=89536 - - Reviewed by Gavin Barraclough. - - Now instead of doing linkBuffer.finalizeCode(), you do - FINALIZE_CODE(linkBuffer, (... explanation ...)). FINALIZE_CODE() then - prints your explanation and the disassembled code, if - Options::showDisassembly is set to true. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * assembler/LinkBuffer.cpp: Added. - (JSC): - (JSC::LinkBuffer::finalizeCodeWithoutDisassembly): - (JSC::LinkBuffer::finalizeCodeWithDisassembly): - (JSC::LinkBuffer::linkCode): - (JSC::LinkBuffer::performFinalization): - (JSC::LinkBuffer::dumpLinkStatistics): - (JSC::LinkBuffer::dumpCode): - * assembler/LinkBuffer.h: - (LinkBuffer): - (JSC): - * assembler/MacroAssemblerCodeRef.h: - (JSC::MacroAssemblerCodeRef::tryToDisassemble): - (MacroAssemblerCodeRef): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::compile): - (JSC::DFG::JITCompiler::compileFunction): - * dfg/DFGOSRExitCompiler.cpp: - * dfg/DFGRepatch.cpp: - (JSC::DFG::generateProtoChainAccessStub): - (JSC::DFG::tryCacheGetByID): - (JSC::DFG::tryBuildGetByIDList): - (JSC::DFG::emitPutReplaceStub): - (JSC::DFG::emitPutTransitionStub): - * dfg/DFGThunks.cpp: - (JSC::DFG::osrExitGenerationThunkGenerator): - * disassembler/Disassembler.h: - (JSC): - (JSC::tryToDisassemble): - * disassembler/UDis86Disassembler.cpp: - (JSC::tryToDisassemble): - * jit/JIT.cpp: - (JSC::JIT::privateCompile): - * jit/JITCode.h: - (JSC::JITCode::tryToDisassemble): - * jit/JITOpcodes.cpp: - (JSC::JIT::privateCompileCTIMachineTrampolines): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::privateCompileCTIMachineTrampolines): - (JSC::JIT::privateCompileCTINativeCall): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::stringGetByValStubGenerator): - (JSC::JIT::privateCompilePutByIdTransition): - (JSC::JIT::privateCompilePatchGetArrayLength): - (JSC::JIT::privateCompileGetByIdProto): - (JSC::JIT::privateCompileGetByIdSelfList): - (JSC::JIT::privateCompileGetByIdProtoList): - (JSC::JIT::privateCompileGetByIdChainList): - (JSC::JIT::privateCompileGetByIdChain): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::stringGetByValStubGenerator): - (JSC::JIT::privateCompilePutByIdTransition): - (JSC::JIT::privateCompilePatchGetArrayLength): - (JSC::JIT::privateCompileGetByIdProto): - (JSC::JIT::privateCompileGetByIdSelfList): - (JSC::JIT::privateCompileGetByIdProtoList): - (JSC::JIT::privateCompileGetByIdChainList): - (JSC::JIT::privateCompileGetByIdChain): - * jit/SpecializedThunkJIT.h: - (JSC::SpecializedThunkJIT::finalize): - * jit/ThunkGenerators.cpp: - (JSC::charCodeAtThunkGenerator): - (JSC::charAtThunkGenerator): - (JSC::fromCharCodeThunkGenerator): - (JSC::sqrtThunkGenerator): - (JSC::floorThunkGenerator): - (JSC::ceilThunkGenerator): - (JSC::roundThunkGenerator): - (JSC::expThunkGenerator): - (JSC::logThunkGenerator): - (JSC::absThunkGenerator): - (JSC::powThunkGenerator): - * llint/LLIntThunks.cpp: - (JSC::LLInt::generateThunkWithJumpTo): - (JSC::LLInt::functionForCallEntryThunkGenerator): - (JSC::LLInt::functionForConstructEntryThunkGenerator): - (JSC::LLInt::functionForCallArityCheckThunkGenerator): - (JSC::LLInt::functionForConstructArityCheckThunkGenerator): - (JSC::LLInt::evalEntryThunkGenerator): - (JSC::LLInt::programEntryThunkGenerator): - * runtime/Options.cpp: - (Options): - (JSC::Options::initializeOptions): - * runtime/Options.h: - (Options): - * yarr/YarrJIT.cpp: - (JSC::Yarr::YarrGenerator::compile): - -2012-06-19 Mark Hahnenberg <mhahnenberg@apple.com> - - [Qt][Mac] REGRESSION(r120742): It broke the build - https://bugs.webkit.org/show_bug.cgi?id=89516 - - Reviewed by Geoffrey Garen. - - Removing GCActivityCallbackCF.cpp because it doesn't mesh well with cross-platform - code on Darwin (e.g. Qt). We now use plain ol' vanilla ifdefs to handle platforms - without CF support. These if-defs will probably disappear in the future when we - use cross-platform timers in HeapTimer. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * runtime/GCActivityCallback.cpp: - (JSC): - (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback): - (JSC::DefaultGCActivityCallback::doWork): - (JSC::DefaultGCActivityCallback::scheduleTimer): - (JSC::DefaultGCActivityCallback::cancelTimer): - (JSC::DefaultGCActivityCallback::didAllocate): - (JSC::DefaultGCActivityCallback::willCollect): - (JSC::DefaultGCActivityCallback::cancel): - * runtime/GCActivityCallbackCF.cpp: Removed. - -2012-06-19 Filip Pizlo <fpizlo@apple.com> - - DFG CFA forgets to notify subsequent phases of found constants if it proves LogicalNot to be a constant - https://bugs.webkit.org/show_bug.cgi?id=89511 - <rdar://problem/11700089> - - Reviewed by Geoffrey Garen. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - -2012-06-19 Mark Lam <mark.lam@apple.com> - - CodeBlock::needsCallReturnIndices() is no longer needed. - https://bugs.webkit.org/show_bug.cgi?id=89490 - - Reviewed by Geoffrey Garen. - - * bytecode/CodeBlock.h: - (JSC::CodeBlock::needsCallReturnIndices): removed. - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::link): - * jit/JIT.cpp: - (JSC::JIT::privateCompile): - -2012-06-19 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, try to fix Windows build. - - * JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd: - -2012-06-17 Filip Pizlo <fpizlo@apple.com> - - It should be possible to look at disassembly - https://bugs.webkit.org/show_bug.cgi?id=89319 - - Reviewed by Sam Weinig. - - This imports the udis86 disassembler library. The library is placed - behind an abstraction in disassembler/Disassembler.h, so that we can - in the future use other disassemblers (for other platforms) whenever - appropriate. As a first step, the disassembler is being invoked for - DFG verbose dumps. - - If we ever want to merge a new version of udis86 in the future, I've - made notes about changes I made to the library in - disassembler/udis86/differences.txt. - - * CMakeLists.txt: - * DerivedSources.make: - * GNUmakefile.list.am: - * JavaScriptCore.pri: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops: - * JavaScriptCore.xcodeproj/project.pbxproj: - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::compile): - (JSC::DFG::JITCompiler::compileFunction): - * disassembler: Added. - * disassembler/Disassembler.h: Added. - (JSC): - (JSC::tryToDisassemble): - * disassembler/UDis86Disassembler.cpp: Added. - (JSC): - (JSC::tryToDisassemble): - * disassembler/udis86: Added. - * disassembler/udis86/differences.txt: Added. - * disassembler/udis86/itab.py: Added. - (UdItabGenerator): - (UdItabGenerator.__init__): - (UdItabGenerator.toGroupId): - (UdItabGenerator.genLookupTable): - (UdItabGenerator.genLookupTableList): - (UdItabGenerator.genInsnTable): - (genItabH): - (genItabH.UD_ITAB_H): - (genItabC): - (genItab): - (main): - * disassembler/udis86/optable.xml: Added. - * disassembler/udis86/ud_opcode.py: Added. - (UdOpcodeTables): - (UdOpcodeTables.sizeOfTable): - (UdOpcodeTables.nameOfTable): - (UdOpcodeTables.updateTable): - (UdOpcodeTables.Insn): - (UdOpcodeTables.Insn.__init__): - (UdOpcodeTables.Insn.__init__.opcode): - (UdOpcodeTables.parse): - (UdOpcodeTables.addInsnDef): - (UdOpcodeTables.print_table): - (UdOpcodeTables.print_tree): - * disassembler/udis86/ud_optable.py: Added. - (UdOptableXmlParser): - (UdOptableXmlParser.parseDef): - (UdOptableXmlParser.parse): - (printFn): - (parse): - (main): - * disassembler/udis86/udis86.c: Added. - (ud_init): - (ud_disassemble): - (ud_set_mode): - (ud_set_vendor): - (ud_set_pc): - (ud): - (ud_insn_asm): - (ud_insn_off): - (ud_insn_hex): - (ud_insn_ptr): - (ud_insn_len): - * disassembler/udis86/udis86.h: Added. - * disassembler/udis86/udis86_decode.c: Added. - (eff_adr_mode): - (ud_lookup_mnemonic): - (decode_prefixes): - (modrm): - (resolve_operand_size): - (resolve_mnemonic): - (decode_a): - (decode_gpr): - (resolve_gpr64): - (resolve_gpr32): - (resolve_reg): - (decode_imm): - (decode_modrm_reg): - (decode_modrm_rm): - (decode_o): - (decode_operand): - (decode_operands): - (clear_insn): - (resolve_mode): - (gen_hex): - (decode_insn): - (decode_3dnow): - (decode_ssepfx): - (decode_ext): - (decode_opcode): - (ud_decode): - * disassembler/udis86/udis86_decode.h: Added. - (ud_itab_entry_operand): - (ud_itab_entry): - (ud_lookup_table_list_entry): - (sse_pfx_idx): - (mode_idx): - (modrm_mod_idx): - (vendor_idx): - (is_group_ptr): - (group_idx): - * disassembler/udis86/udis86_extern.h: Added. - * disassembler/udis86/udis86_input.c: Added. - (inp_buff_hook): - (inp_file_hook): - (ud): - (ud_set_user_opaque_data): - (ud_get_user_opaque_data): - (ud_set_input_buffer): - (ud_set_input_file): - (ud_input_skip): - (ud_input_end): - (ud_inp_next): - (ud_inp_back): - (ud_inp_peek): - (ud_inp_move): - (ud_inp_uint8): - (ud_inp_uint16): - (ud_inp_uint32): - (ud_inp_uint64): - * disassembler/udis86/udis86_input.h: Added. - * disassembler/udis86/udis86_itab_holder.c: Added. - * disassembler/udis86/udis86_syn-att.c: Added. - (opr_cast): - (gen_operand): - (ud_translate_att): - * disassembler/udis86/udis86_syn-intel.c: Added. - (opr_cast): - (gen_operand): - (ud_translate_intel): - * disassembler/udis86/udis86_syn.c: Added. - * disassembler/udis86/udis86_syn.h: Added. - (mkasm): - * disassembler/udis86/udis86_types.h: Added. - (ud_operand): - (ud): - * jit/JITCode.h: - (JITCode): - (JSC::JITCode::tryToDisassemble): - -2012-06-19 Mark Hahnenberg <mhahnenberg@apple.com> - - GCActivityCallback and IncrementalSweeper should share code - https://bugs.webkit.org/show_bug.cgi?id=89400 - - Reviewed by Geoffrey Garen. - - A lot of functionality is duplicated between GCActivityCallback and IncrementalSweeper. - We should extract the common functionality out into a separate class that both of them - can inherit from. This refactoring will be an even greater boon when we add the ability - to shut these two agents down in a thread-safe fashion - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * heap/Heap.cpp: - (JSC::Heap::Heap): Move initialization down so that the JSGlobalData has a valid Heap when - we're initializing the GCActivityCallback and the IncrementalSweeper. - * heap/Heap.h: - (Heap): - * heap/HeapTimer.cpp: Added. - (JSC): - (JSC::HeapTimer::HeapTimer): Initialize the various base class data that - DefaultGCActivityCallback::commonConstructor() used to do. - (JSC::HeapTimer::~HeapTimer): Call to invalidate(). - (JSC::HeapTimer::synchronize): Same functionality as the old DefaultGCActivityCallback::synchronize(). - Virtual so that non-CF subclasses can override. - (JSC::HeapTimer::invalidate): Tears down the runloop timer to prevent any future firing. - (JSC::HeapTimer::timerDidFire): Callback to pass to the timer function. Casts and calls the virtual doWork(). - * heap/HeapTimer.h: Added. This is the class that serves as the common base class for - both GCActivityCallback and IncrementalSweeper. It handles setting up and tearing down run loops and synchronizing - across threads for its subclasses. - (JSC): - (HeapTimer): - * heap/IncrementalSweeper.cpp: Changes to accomodate the extraction of common functionality - between IncrementalSweeper and GCActivityCallback into a common ancestor. - (JSC): - (JSC::IncrementalSweeper::doWork): - (JSC::IncrementalSweeper::IncrementalSweeper): - (JSC::IncrementalSweeper::cancelTimer): - (JSC::IncrementalSweeper::create): - * heap/IncrementalSweeper.h: - (IncrementalSweeper): - * runtime/GCActivityCallback.cpp: - (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback): - (JSC::DefaultGCActivityCallback::doWork): - * runtime/GCActivityCallback.h: - (GCActivityCallback): - (JSC::GCActivityCallback::willCollect): - (JSC::GCActivityCallback::GCActivityCallback): - (JSC): - (DefaultGCActivityCallback): Remove the platform data struct. The platform data should be kept in - the class itself so as to be accessible by doWork(). Most of the platform data for CF is kept in - HeapTimer anyways, so we only need the m_delay field now. - * runtime/GCActivityCallbackBlackBerry.cpp: - (JSC): - (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback): - (JSC::DefaultGCActivityCallback::doWork): - (JSC::DefaultGCActivityCallback::didAllocate): - * runtime/GCActivityCallbackCF.cpp: - (JSC): - (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback): - (JSC::DefaultGCActivityCallback::doWork): - (JSC::DefaultGCActivityCallback::scheduleTimer): - (JSC::DefaultGCActivityCallback::cancelTimer): - (JSC::DefaultGCActivityCallback::didAllocate): - (JSC::DefaultGCActivityCallback::willCollect): - (JSC::DefaultGCActivityCallback::cancel): - - -2012-06-19 Mike West <mkwst@chromium.org> - - Introduce ENABLE_CSP_NEXT configuration flag. - https://bugs.webkit.org/show_bug.cgi?id=89300 - - Reviewed by Adam Barth. - - The 1.0 draft of the Content Security Policy spec is just about to - move to Last Call. We'll hide work on the upcoming 1.1 spec behind - this ENABLE flag, disabled by default. - - Spec: https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html - - * Configurations/FeatureDefines.xcconfig: + (JSArray): -2012-06-18 Mark Lam <mark.lam@apple.com> +2012-09-16 Mark Hahnenberg <mhahnenberg@apple.com> - Changed JSC to always record line number information so that error.stack - and window.onerror() can report proper line numbers. - https://bugs.webkit.org/show_bug.cgi?id=89410 + Delayed structure sweep can leak structures without bound + https://bugs.webkit.org/show_bug.cgi?id=96546 Reviewed by Geoffrey Garen. - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::CodeBlock): - (JSC::CodeBlock::lineNumberForBytecodeOffset): - (JSC::CodeBlock::shrinkToFit): m_lineInfo is now available unconditionally. - - * bytecode/CodeBlock.h: - (JSC::CodeBlock::addLineInfo): - (JSC::CodeBlock::hasLineInfo): Unused. Now removed. - (JSC::CodeBlock::needsCallReturnIndices): - (CodeBlock): - (RareData): Hoisted m_lineInfo out of m_rareData. m_lineInfo is now - filled in unconditionally. - - * bytecompiler/BytecodeGenerator.h: - (JSC::BytecodeGenerator::addLineInfo): - -2012-06-18 Andy Estes <aestes@apple.com> - - Fix r120663, which didn't land the change that was reviewed. - -2012-06-18 Andy Estes <aestes@apple.com> - - [JSC] In JSGlobalData.cpp, enableAssembler() sometimes leaks two CF objects - https://bugs.webkit.org/show_bug.cgi?id=89415 - - Reviewed by Sam Weinig. - - In the case where canUseJIT was a non-NULL CFBooleanRef, - enableAssembler() would leak both canUseJITKey and canUseJIT by - returning before calling CFRelease. Fix this by using RetainPtr. - - * runtime/JSGlobalData.cpp: - (JSC::enableAssembler): - -2012-06-17 Geoffrey Garen <ggaren@apple.com> - - GC copy phase spends needless cycles zero-filling blocks - https://bugs.webkit.org/show_bug.cgi?id=89128 - - Reviewed by Gavin Barraclough. - - We only need to zero-fill when we're allocating memory that might not - get fully initialized before GC. - - * heap/CopiedBlock.h: - (JSC::CopiedBlock::createNoZeroFill): - (JSC::CopiedBlock::create): Added a way to create without zero-filling. - This is our optimization. - - (JSC::CopiedBlock::zeroFillToEnd): - (JSC::CopiedBlock::CopiedBlock): Split zero-filling out from creation, - so we can sometimes create without zero-filling. - - * heap/CopiedSpace.cpp: - (JSC::CopiedSpace::init): - (JSC::CopiedSpace::tryAllocateSlowCase): - (JSC::CopiedSpace::doneCopying): Renamed addNewBlock to allocateBlock() - to clarify that the new block is always newly-allocated. - - (JSC::CopiedSpace::doneFillingBlock): Make sure to zero-fill to the end - of a block that might be used in the future for allocation. (Most of the - time, this is a no-op, since we've already filled the block completely.) - - (JSC::CopiedSpace::getFreshBlock): Removed this function because the - abstraction of "allocation must succeed" is no longer useful. - - * heap/CopiedSpace.h: Updated declarations to match. - - * heap/CopiedSpaceInlineMethods.h: - (JSC::CopiedSpace::allocateBlockForCopyingPhase): New function, which - knows that it can skip zero-filling. - - Added tighter scoping to our lock, to improve parallelism. - - (JSC::CopiedSpace::allocateBlock): Folded getFreshBlock functionality - into this function, for simplicity. - - * heap/MarkStack.cpp: - (JSC::SlotVisitor::startCopying): - (JSC::SlotVisitor::allocateNewSpace): Use our new zero-fill-free helper - function for great good. - -2012-06-17 Filip Pizlo <fpizlo@apple.com> - - DFG should attempt to use structure watchpoints for all inlined get_by_id's and put_by_id's - https://bugs.webkit.org/show_bug.cgi?id=89316 - - Reviewed by Oliver Hunt. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::addStructureTransitionCheck): - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::handleGetById): - (JSC::DFG::ByteCodeParser::parseBlock): - -2012-06-15 Yong Li <yoli@rim.com> - - [BlackBerry] Put platform-specific GC policy in GCActivityCallback - https://bugs.webkit.org/show_bug.cgi?id=89236 - - Reviewed by Rob Buis. - - Add GCActivityCallbackBlackBerry.cpp and implement platform-specific - low memory GC policy there. - - * PlatformBlackBerry.cmake: - * heap/Heap.h: - (JSC::Heap::isSafeToCollect): Added. - * runtime/GCActivityCallbackBlackBerry.cpp: Added. - (JSC): - (JSC::DefaultGCActivityCallbackPlatformData::DefaultGCActivityCallbackPlatformData): - (DefaultGCActivityCallbackPlatformData): - (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback): - (JSC::DefaultGCActivityCallback::~DefaultGCActivityCallback): - (JSC::DefaultGCActivityCallback::didAllocate): - (JSC::DefaultGCActivityCallback::willCollect): - (JSC::DefaultGCActivityCallback::synchronize): - (JSC::DefaultGCActivityCallback::cancel): - -2012-06-15 Filip Pizlo <fpizlo@apple.com> - - DFG should be able to set watchpoints on structure transitions in the - method check prototype chain - https://bugs.webkit.org/show_bug.cgi?id=89058 - - Adding the same assertion to 32-bit that I added to 64-bit. This change - does not affect correctness but it's a good thing for assertion coverage. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-06-13 Filip Pizlo <fpizlo@apple.com> - - DFG should be able to set watchpoints on structure transitions in the - method check prototype chain - https://bugs.webkit.org/show_bug.cgi?id=89058 - - Reviewed by Gavin Barraclough. - - This adds the ability to set watchpoints on Structures, and then does - the most modest thing we can do with this ability: the DFG now sets - watchpoints on structure transitions in the prototype chain of method - checks. - - This appears to be a >1% speed-up on V8. - - * bytecode/PutByIdStatus.cpp: - (JSC::PutByIdStatus::computeFromLLInt): - (JSC::PutByIdStatus::computeFor): - * bytecode/StructureSet.h: - (JSC::StructureSet::containsOnly): - (StructureSet): - * bytecode/Watchpoint.cpp: - (JSC::WatchpointSet::WatchpointSet): - (JSC::InlineWatchpointSet::add): - (JSC): - (JSC::InlineWatchpointSet::inflateSlow): - (JSC::InlineWatchpointSet::freeFat): - * bytecode/Watchpoint.h: - (WatchpointSet): - (JSC): - (InlineWatchpointSet): - (JSC::InlineWatchpointSet::InlineWatchpointSet): - (JSC::InlineWatchpointSet::~InlineWatchpointSet): - (JSC::InlineWatchpointSet::hasBeenInvalidated): - (JSC::InlineWatchpointSet::isStillValid): - (JSC::InlineWatchpointSet::startWatching): - (JSC::InlineWatchpointSet::notifyWrite): - (JSC::InlineWatchpointSet::isFat): - (JSC::InlineWatchpointSet::fat): - (JSC::InlineWatchpointSet::inflate): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::addStructureTransitionCheck): - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): - (CSEPhase): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGCommon.h: - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dump): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::isCellConstant): - * dfg/DFGJITCompiler.h: - (JSC::DFG::JITCompiler::addWeakReferences): - (JITCompiler): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasStructure): - (Node): - (JSC::DFG::Node::structure): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGRepatch.cpp: - (JSC::DFG::emitPutTransitionStub): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JITStubs.cpp: - (JSC::JITThunks::tryCachePutByID): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * runtime/Structure.cpp: - (JSC::Structure::Structure): - * runtime/Structure.h: - (JSC::Structure::transitionWatchpointSetHasBeenInvalidated): - (Structure): - (JSC::Structure::transitionWatchpointSetIsStillValid): - (JSC::Structure::addTransitionWatchpoint): - (JSC::Structure::notifyTransitionFromThisStructure): - (JSC::JSCell::setStructure): - * runtime/SymbolTable.cpp: - (JSC::SymbolTableEntry::attemptToWatch): - -2012-06-13 Filip Pizlo <fpizlo@apple.com> - - DFG should be able to set watchpoints on global variables - https://bugs.webkit.org/show_bug.cgi?id=88692 - - Reviewed by Geoffrey Garen. - - Rolling back in after fixing Windows build issues, and implementing - branchTest8 for the Qt port's strange assemblers. - - This implements global variable constant folding by allowing the optimizing - compiler to set a "watchpoint" on globals that it wishes to constant fold. - If the watchpoint fires, then an OSR exit is forced by overwriting the - machine code that the optimizing compiler generated with a jump. - - As such, this patch is adding quite a bit of stuff: - - - Jump replacement on those hardware targets supported by the optimizing - JIT. It is now possible to patch in a jump instruction over any recorded - watchpoint label. The jump must be "local" in the sense that it must be - within the range of the largest jump distance supported by a one - instruction jump. - - - WatchpointSets and Watchpoints. A Watchpoint is a doubly-linked list node - that records the location where a jump must be inserted and the - destination to which it should jump. Watchpoints can be added to a - WatchpointSet. The WatchpointSet can be fired all at once, which plants - all jumps. WatchpointSet also remembers if it had ever been invalidated, - which allows for monotonicity: we typically don't want to optimize using - watchpoints on something for which watchpoints had previously fired. The - act of notifying a WatchpointSet has a trivial fast path in case no - Watchpoints are registered (one-byte load+branch). - - - SpeculativeJIT::speculationWatchpoint(). It's like speculationCheck(), - except that you don't have to emit branches. But, you need to know what - WatchpointSet to add the resulting Watchpoint to. Not everything that - you could write a speculationCheck() for will have a WatchpointSet that - would get notified if the condition you were speculating against became - invalid. - - - SymbolTableEntry now has the ability to refer to a WatchpointSet. It can - do so without incurring any space overhead for those entries that don't - have WatchpointSets. - - - The bytecode generator infers all global function variables to be - watchable, and makes all stores perform the WatchpointSet's write check, - and marks all loads as being potentially watchable (i.e. you can compile - them to a watchpoint and a constant). - - Put together, this allows for fully sleazy inlining of calls to globally - declared functions. The inline prologue will no longer contain the load of - the function, or any checks of the function you're calling. I.e. it's - pretty much like the kind of inlining you would see in Java or C++. - Furthermore, the watchpointing functionality is built to be fairly general, - and should allow setting watchpoints on all sorts of interesting things - in the future. - - The sleazy inlining means that we will now sometimes inline in code paths - that have never executed. Previously, to inline we would have either had - to have executed the call (to read the call's inline cache) or have - executed the method check (to read the method check's inline cache). Now, - we might inline when the callee is a watched global variable. This - revealed some humorous bugs. First, constant folding disagreed with CFA - over what kinds of operations can clobber (example: code path A is dead - but stores a String into variable X, all other code paths store 0 into - X, and then you do CompareEq(X, 0) - CFA will say that this is a non- - clobbering constant, but constant folding thought it was clobbering - because it saw the String prediction). Second, inlining would crash if - the inline callee had not been compiled. This patch fixes both bugs, - since otherwise run-javascriptcore-tests would report regressions. + This patch gets rid of the separate Structure allocator in the MarkedSpace and adds two new destructor-only + allocators. We now have separate allocators for our three types of objects: those objects with no destructors, + those objects with destructors and with immortal structures, and those objects with destructors that don't have + immortal structures. All of the objects of the third type (destructors without immortal structures) now + inherit from a new class named JSDestructibleObject (which in turn is a subclass of JSNonFinalObject), which stores + the ClassInfo for these classes at a fixed offset for safe retrieval during sweeping/destruction. - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * assembler/ARMv7Assembler.h: - (ARMv7Assembler): - (JSC::ARMv7Assembler::ARMv7Assembler): - (JSC::ARMv7Assembler::labelForWatchpoint): - (JSC::ARMv7Assembler::label): - (JSC::ARMv7Assembler::replaceWithJump): - (JSC::ARMv7Assembler::maxJumpReplacementSize): - * assembler/AbstractMacroAssembler.h: - (JSC): - (AbstractMacroAssembler): - (Label): - (JSC::AbstractMacroAssembler::watchpointLabel): - (JSC::AbstractMacroAssembler::readPointer): - * assembler/AssemblerBuffer.h: - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::branchTest8): - (MacroAssemblerARM): - (JSC::MacroAssemblerARM::replaceWithJump): - (JSC::MacroAssemblerARM::maxJumpReplacementSize): - * assembler/MacroAssemblerARMv7.h: - (JSC::MacroAssemblerARMv7::load8Signed): - (JSC::MacroAssemblerARMv7::load16Signed): - (MacroAssemblerARMv7): - (JSC::MacroAssemblerARMv7::replaceWithJump): - (JSC::MacroAssemblerARMv7::maxJumpReplacementSize): - (JSC::MacroAssemblerARMv7::branchTest8): - (JSC::MacroAssemblerARMv7::jump): - (JSC::MacroAssemblerARMv7::makeBranch): - * assembler/MacroAssemblerMIPS.h: - (JSC::MacroAssemblerMIPS::branchTest8): - (MacroAssemblerMIPS): - (JSC::MacroAssemblerMIPS::replaceWithJump): - (JSC::MacroAssemblerMIPS::maxJumpReplacementSize): - * assembler/MacroAssemblerSH4.h: - (JSC::MacroAssemblerSH4::branchTest8): - (MacroAssemblerSH4): - (JSC::MacroAssemblerSH4::replaceWithJump): - (JSC::MacroAssemblerSH4::maxJumpReplacementSize): - * assembler/MacroAssemblerX86.h: - (MacroAssemblerX86): - (JSC::MacroAssemblerX86::branchTest8): - * assembler/MacroAssemblerX86Common.h: - (JSC::MacroAssemblerX86Common::replaceWithJump): - (MacroAssemblerX86Common): - (JSC::MacroAssemblerX86Common::maxJumpReplacementSize): - * assembler/MacroAssemblerX86_64.h: - (MacroAssemblerX86_64): - (JSC::MacroAssemblerX86_64::branchTest8): - * assembler/X86Assembler.h: - (JSC::X86Assembler::X86Assembler): - (X86Assembler): - (JSC::X86Assembler::cmpb_im): - (JSC::X86Assembler::testb_im): - (JSC::X86Assembler::labelForWatchpoint): - (JSC::X86Assembler::label): - (JSC::X86Assembler::replaceWithJump): - (JSC::X86Assembler::maxJumpReplacementSize): - (JSC::X86Assembler::X86InstructionFormatter::memoryModRM): - * bytecode/CodeBlock.cpp: - (JSC): - (JSC::CodeBlock::printGetByIdCacheStatus): - (JSC::CodeBlock::dump): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::appendOSRExit): - (JSC::CodeBlock::appendSpeculationRecovery): - (CodeBlock): - (JSC::CodeBlock::appendWatchpoint): - (JSC::CodeBlock::numberOfWatchpoints): - (JSC::CodeBlock::watchpoint): - (DFGData): - * bytecode/DFGExitProfile.h: - (JSC::DFG::exitKindToString): - (JSC::DFG::exitKindIsCountable): - * bytecode/GetByIdStatus.cpp: - (JSC::GetByIdStatus::computeForChain): - * bytecode/Instruction.h: - (Instruction): - (JSC::Instruction::Instruction): - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecode/Watchpoint.cpp: Added. - (JSC): - (JSC::Watchpoint::~Watchpoint): - (JSC::Watchpoint::correctLabels): - (JSC::Watchpoint::fire): - (JSC::WatchpointSet::WatchpointSet): - (JSC::WatchpointSet::~WatchpointSet): - (JSC::WatchpointSet::add): - (JSC::WatchpointSet::notifyWriteSlow): - (JSC::WatchpointSet::fireAllWatchpoints): - * bytecode/Watchpoint.h: Added. - (JSC): - (Watchpoint): - (JSC::Watchpoint::Watchpoint): - (JSC::Watchpoint::setDestination): - (WatchpointSet): - (JSC::WatchpointSet::isStillValid): - (JSC::WatchpointSet::hasBeenInvalidated): - (JSC::WatchpointSet::startWatching): - (JSC::WatchpointSet::notifyWrite): - (JSC::WatchpointSet::addressOfIsWatched): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::ResolveResult::checkValidity): - (JSC::BytecodeGenerator::addGlobalVar): - (JSC::BytecodeGenerator::BytecodeGenerator): - (JSC::BytecodeGenerator::resolve): - (JSC::BytecodeGenerator::emitResolve): - (JSC::BytecodeGenerator::emitResolveWithBase): - (JSC::BytecodeGenerator::emitResolveWithThis): - (JSC::BytecodeGenerator::emitGetStaticVar): - (JSC::BytecodeGenerator::emitPutStaticVar): - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - * bytecompiler/NodesCodegen.cpp: - (JSC::FunctionCallResolveNode::emitBytecode): - (JSC::PostfixResolveNode::emitBytecode): - (JSC::PrefixResolveNode::emitBytecode): - (JSC::ReadModifyResolveNode::emitBytecode): - (JSC::AssignResolveNode::emitBytecode): - (JSC::ConstDeclNode::emitCodeSingle): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - (JSC::DFG::AbstractState::clobberStructures): - * dfg/DFGAbstractState.h: - (AbstractState): - (JSC::DFG::AbstractState::didClobber): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleInlining): - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCCallHelpers.h: - (CCallHelpers): - (JSC::DFG::CCallHelpers::setupArguments): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::globalVarWatchpointElimination): - (CSEPhase): - (JSC::DFG::CSEPhase::globalVarStoreElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGCapabilities.h: - (JSC::DFG::canCompileOpcode): - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::run): - * dfg/DFGCorrectableJumpPoint.h: - (JSC::DFG::CorrectableJumpPoint::isSet): - (CorrectableJumpPoint): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::linkOSRExits): - (JSC::DFG::JITCompiler::link): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasIdentifierNumberForCheck): - (Node): - (JSC::DFG::Node::identifierNumberForCheck): - (JSC::DFG::Node::hasRegisterPointer): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOSRExit.cpp: - (JSC::DFG::OSRExit::OSRExit): - * dfg/DFGOSRExit.h: - (OSRExit): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - (JSC::DFG::SpeculativeJIT::appendCall): - (SpeculativeJIT): - (JSC::DFG::SpeculativeJIT::speculationWatchpoint): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - * jit/JIT.cpp: - (JSC::JIT::privateCompileMainPass): - (JSC::JIT::privateCompileSlowCases): - * jit/JIT.h: - * jit/JITPropertyAccess.cpp: - (JSC::JIT::emit_op_put_global_var_check): - (JSC): - (JSC::JIT::emitSlow_op_put_global_var_check): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::emit_op_put_global_var_check): - (JSC): - (JSC::JIT::emitSlow_op_put_global_var_check): - * jit/JITStubs.cpp: - (JSC::DEFINE_STUB_FUNCTION): - (JSC): - * jit/JITStubs.h: - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - (LLInt): - * llint/LLIntSlowPaths.h: - (LLInt): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/JSObject.cpp: - (JSC::JSObject::removeDirect): - * runtime/JSObject.h: - (JSObject): - * runtime/JSSymbolTableObject.h: - (JSC::symbolTableGet): - (JSC::symbolTablePut): - (JSC::symbolTablePutWithAttributes): - * runtime/SymbolTable.cpp: Added. - (JSC): - (JSC::SymbolTableEntry::copySlow): - (JSC::SymbolTableEntry::freeFatEntrySlow): - (JSC::SymbolTableEntry::couldBeWatched): - (JSC::SymbolTableEntry::attemptToWatch): - (JSC::SymbolTableEntry::addressOfIsWatched): - (JSC::SymbolTableEntry::addWatchpoint): - (JSC::SymbolTableEntry::notifyWriteSlow): - (JSC::SymbolTableEntry::inflateSlow): - * runtime/SymbolTable.h: + * API/JSCallbackConstructor.cpp: Use JSDestructibleObject for JSCallbackConstructor. (JSC): - (SymbolTableEntry): - (Fast): - (JSC::SymbolTableEntry::Fast::Fast): - (JSC::SymbolTableEntry::Fast::isNull): - (JSC::SymbolTableEntry::Fast::getIndex): - (JSC::SymbolTableEntry::Fast::isReadOnly): - (JSC::SymbolTableEntry::Fast::getAttributes): - (JSC::SymbolTableEntry::Fast::isFat): - (JSC::SymbolTableEntry::SymbolTableEntry): - (JSC::SymbolTableEntry::~SymbolTableEntry): - (JSC::SymbolTableEntry::operator=): - (JSC::SymbolTableEntry::isNull): - (JSC::SymbolTableEntry::getIndex): - (JSC::SymbolTableEntry::getFast): - (JSC::SymbolTableEntry::getAttributes): - (JSC::SymbolTableEntry::isReadOnly): - (JSC::SymbolTableEntry::watchpointSet): - (JSC::SymbolTableEntry::notifyWrite): - (FatEntry): - (JSC::SymbolTableEntry::FatEntry::FatEntry): - (JSC::SymbolTableEntry::isFat): - (JSC::SymbolTableEntry::fatEntry): - (JSC::SymbolTableEntry::inflate): - (JSC::SymbolTableEntry::bits): - (JSC::SymbolTableEntry::freeFatEntry): - (JSC::SymbolTableEntry::pack): - (JSC::SymbolTableEntry::isValidIndex): - -2012-06-13 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r120172. - http://trac.webkit.org/changeset/120172 - https://bugs.webkit.org/show_bug.cgi?id=88976 - - The patch causes compilation failures on Gtk, Qt and Apple Win - bots (Requested by zdobersek on #webkit). - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * assembler/ARMv7Assembler.h: - (JSC::ARMv7Assembler::nop): - (JSC::ARMv7Assembler::label): - (JSC::ARMv7Assembler::readPointer): - (ARMv7Assembler): - * assembler/AbstractMacroAssembler.h: + (JSC::JSCallbackConstructor::JSCallbackConstructor): + * API/JSCallbackConstructor.h: + (JSCallbackConstructor): + * API/JSCallbackObject.cpp: Inherit from JSDestructibleObject for normal JSCallbackObjects and use a finalizer for + JSCallbackObject<JSGlobalObject>, since JSGlobalObject also uses a finalizer. (JSC): - (AbstractMacroAssembler): - (Label): - * assembler/AssemblerBuffer.h: - * assembler/MacroAssemblerARM.h: - * assembler/MacroAssemblerARMv7.h: - (JSC::MacroAssemblerARMv7::nop): - (JSC::MacroAssemblerARMv7::jump): - (JSC::MacroAssemblerARMv7::makeBranch): - * assembler/MacroAssemblerMIPS.h: - * assembler/MacroAssemblerSH4.h: - * assembler/MacroAssemblerX86.h: - (MacroAssemblerX86): - (JSC::MacroAssemblerX86::moveWithPatch): - * assembler/MacroAssemblerX86Common.h: - * assembler/MacroAssemblerX86_64.h: - (JSC::MacroAssemblerX86_64::branchTest8): - * assembler/X86Assembler.h: - (JSC::X86Assembler::cmpb_im): - (JSC::X86Assembler::codeSize): - (JSC::X86Assembler::label): - (JSC::X86Assembler::X86InstructionFormatter::memoryModRM): - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::appendOSRExit): - (JSC::CodeBlock::appendSpeculationRecovery): - (DFGData): - * bytecode/DFGExitProfile.h: - (JSC::DFG::exitKindToString): - (JSC::DFG::exitKindIsCountable): - * bytecode/Instruction.h: - * bytecode/Opcode.h: + (JSC::::create): We need to move the create function for JSCallbackObject<JSGlobalObject> out of line so we can add + the finalizer for it. We don't want to add the finalizer is something like finishCreation in case somebody decides + to subclass this. We use this same technique for many other subclasses of JSGlobalObject. + (JSC::::createStructure): + * API/JSCallbackObject.h: + (JSCallbackObject): (JSC): - (JSC::padOpcodeName): - * bytecode/Watchpoint.cpp: Removed. - * bytecode/Watchpoint.h: Removed. - * bytecompiler/BytecodeGenerator.cpp: - (JSC::ResolveResult::checkValidity): - (JSC::BytecodeGenerator::addGlobalVar): - (JSC::BytecodeGenerator::BytecodeGenerator): - (JSC::BytecodeGenerator::resolve): - (JSC::BytecodeGenerator::emitResolve): - (JSC::BytecodeGenerator::emitResolveWithBase): - (JSC::BytecodeGenerator::emitResolveWithThis): - (JSC::BytecodeGenerator::emitGetStaticVar): - (JSC::BytecodeGenerator::emitPutStaticVar): - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - * bytecompiler/NodesCodegen.cpp: - (JSC::FunctionCallResolveNode::emitBytecode): - (JSC::PostfixResolveNode::emitBytecode): - (JSC::PrefixResolveNode::emitBytecode): - (JSC::ReadModifyResolveNode::emitBytecode): - (JSC::AssignResolveNode::emitBytecode): - (JSC::ConstDeclNode::emitCodeSingle): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - (JSC::DFG::AbstractState::clobberStructures): - * dfg/DFGAbstractState.h: - (AbstractState): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleInlining): - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCCallHelpers.h: - (JSC::DFG::CCallHelpers::setupArguments): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::globalVarStoreElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGCapabilities.h: - (JSC::DFG::canCompileOpcode): - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::run): - * dfg/DFGCorrectableJumpPoint.h: - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::linkOSRExits): - (JSC::DFG::JITCompiler::link): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasRegisterPointer): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOSRExit.cpp: - (JSC::DFG::OSRExit::OSRExit): - * dfg/DFGOSRExit.h: - (OSRExit): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - (JSC::DFG::SpeculativeJIT::appendCallSetResult): - (JSC::DFG::SpeculativeJIT::speculationCheck): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JIT.cpp: - (JSC::JIT::privateCompileMainPass): - (JSC::JIT::privateCompileSlowCases): - * jit/JIT.h: - * jit/JITPropertyAccess.cpp: - * jit/JITPropertyAccess32_64.cpp: - * jit/JITStubs.cpp: - * jit/JITStubs.h: - * llint/LLIntSlowPaths.cpp: - * llint/LLIntSlowPaths.h: - (LLInt): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/JSObject.cpp: - (JSC::JSObject::removeDirect): - * runtime/JSObject.h: - (JSObject): - * runtime/JSSymbolTableObject.h: - (JSC::symbolTableGet): - (JSC::symbolTablePut): - (JSC::symbolTablePutWithAttributes): - * runtime/SymbolTable.cpp: Removed. - * runtime/SymbolTable.h: + * API/JSClassRef.cpp: Change all the JSCallbackObject<JSNonFinalObject> to use JSDestructibleObject instead. + (OpaqueJSClass::prototype): + * API/JSObjectRef.cpp: Ditto. + (JSObjectMake): + (JSObjectGetPrivate): + (JSObjectSetPrivate): + (JSObjectGetPrivateProperty): + (JSObjectSetPrivateProperty): + (JSObjectDeletePrivateProperty): + * API/JSValueRef.cpp: Ditto. + (JSValueIsObjectOfClass): + * API/JSWeakObjectMapRefPrivate.cpp: Ditto. + * JSCTypedArrayStubs.h: (JSC): - (JSC::SymbolTableEntry::isNull): - (JSC::SymbolTableEntry::getIndex): - (SymbolTableEntry): - (JSC::SymbolTableEntry::getAttributes): - (JSC::SymbolTableEntry::isReadOnly): - (JSC::SymbolTableEntry::pack): - (JSC::SymbolTableEntry::isValidIndex): - -2012-06-12 Filip Pizlo <fpizlo@apple.com> - - DFG should be able to set watchpoints on global variables - https://bugs.webkit.org/show_bug.cgi?id=88692 - - Reviewed by Geoffrey Garen. - - This implements global variable constant folding by allowing the optimizing - compiler to set a "watchpoint" on globals that it wishes to constant fold. - If the watchpoint fires, then an OSR exit is forced by overwriting the - machine code that the optimizing compiler generated with a jump. - - As such, this patch is adding quite a bit of stuff: - - - Jump replacement on those hardware targets supported by the optimizing - JIT. It is now possible to patch in a jump instruction over any recorded - watchpoint label. The jump must be "local" in the sense that it must be - within the range of the largest jump distance supported by a one - instruction jump. - - - WatchpointSets and Watchpoints. A Watchpoint is a doubly-linked list node - that records the location where a jump must be inserted and the - destination to which it should jump. Watchpoints can be added to a - WatchpointSet. The WatchpointSet can be fired all at once, which plants - all jumps. WatchpointSet also remembers if it had ever been invalidated, - which allows for monotonicity: we typically don't want to optimize using - watchpoints on something for which watchpoints had previously fired. The - act of notifying a WatchpointSet has a trivial fast path in case no - Watchpoints are registered (one-byte load+branch). - - - SpeculativeJIT::speculationWatchpoint(). It's like speculationCheck(), - except that you don't have to emit branches. But, you need to know what - WatchpointSet to add the resulting Watchpoint to. Not everything that - you could write a speculationCheck() for will have a WatchpointSet that - would get notified if the condition you were speculating against became - invalid. - - - SymbolTableEntry now has the ability to refer to a WatchpointSet. It can - do so without incurring any space overhead for those entries that don't - have WatchpointSets. - - - The bytecode generator infers all global function variables to be - watchable, and makes all stores perform the WatchpointSet's write check, - and marks all loads as being potentially watchable (i.e. you can compile - them to a watchpoint and a constant). - - Put together, this allows for fully sleazy inlining of calls to globally - declared functions. The inline prologue will no longer contain the load of - the function, or any checks of the function you're calling. I.e. it's - pretty much like the kind of inlining you would see in Java or C++. - Furthermore, the watchpointing functionality is built to be fairly general, - and should allow setting watchpoints on all sorts of interesting things - in the future. - - The sleazy inlining means that we will now sometimes inline in code paths - that have never executed. Previously, to inline we would have either had - to have executed the call (to read the call's inline cache) or have - executed the method check (to read the method check's inline cache). Now, - we might inline when the callee is a watched global variable. This - revealed some humorous bugs. First, constant folding disagreed with CFA - over what kinds of operations can clobber (example: code path A is dead - but stores a String into variable X, all other code paths store 0 into - X, and then you do CompareEq(X, 0) - CFA will say that this is a non- - clobbering constant, but constant folding thought it was clobbering - because it saw the String prediction). Second, inlining would crash if - the inline callee had not been compiled. This patch fixes both bugs, - since otherwise run-javascriptcore-tests would report regressions. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * assembler/ARMv7Assembler.h: - (ARMv7Assembler): - (JSC::ARMv7Assembler::ARMv7Assembler): - (JSC::ARMv7Assembler::labelForWatchpoint): - (JSC::ARMv7Assembler::label): - (JSC::ARMv7Assembler::replaceWithJump): - (JSC::ARMv7Assembler::maxJumpReplacementSize): - * assembler/AbstractMacroAssembler.h: - (JSC): - (AbstractMacroAssembler): - (Label): - (JSC::AbstractMacroAssembler::watchpointLabel): - * assembler/AssemblerBuffer.h: - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::replaceWithJump): - (MacroAssemblerARM): - (JSC::MacroAssemblerARM::maxJumpReplacementSize): - * assembler/MacroAssemblerARMv7.h: - (MacroAssemblerARMv7): - (JSC::MacroAssemblerARMv7::replaceWithJump): - (JSC::MacroAssemblerARMv7::maxJumpReplacementSize): - (JSC::MacroAssemblerARMv7::branchTest8): - (JSC::MacroAssemblerARMv7::jump): - (JSC::MacroAssemblerARMv7::makeBranch): - * assembler/MacroAssemblerMIPS.h: - (JSC::MacroAssemblerMIPS::replaceWithJump): - (MacroAssemblerMIPS): - (JSC::MacroAssemblerMIPS::maxJumpReplacementSize): - * assembler/MacroAssemblerSH4.h: - (JSC::MacroAssemblerSH4::replaceWithJump): - (MacroAssemblerSH4): - (JSC::MacroAssemblerSH4::maxJumpReplacementSize): - * assembler/MacroAssemblerX86.h: - (MacroAssemblerX86): - (JSC::MacroAssemblerX86::branchTest8): - * assembler/MacroAssemblerX86Common.h: - (JSC::MacroAssemblerX86Common::replaceWithJump): - (MacroAssemblerX86Common): - (JSC::MacroAssemblerX86Common::maxJumpReplacementSize): - * assembler/MacroAssemblerX86_64.h: - (MacroAssemblerX86_64): - (JSC::MacroAssemblerX86_64::branchTest8): - * assembler/X86Assembler.h: - (JSC::X86Assembler::X86Assembler): - (X86Assembler): - (JSC::X86Assembler::cmpb_im): - (JSC::X86Assembler::testb_im): - (JSC::X86Assembler::labelForWatchpoint): - (JSC::X86Assembler::label): - (JSC::X86Assembler::replaceWithJump): - (JSC::X86Assembler::maxJumpReplacementSize): - (JSC::X86Assembler::X86InstructionFormatter::memoryModRM): - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::appendOSRExit): - (JSC::CodeBlock::appendSpeculationRecovery): - (CodeBlock): - (JSC::CodeBlock::appendWatchpoint): - (JSC::CodeBlock::numberOfWatchpoints): - (JSC::CodeBlock::watchpoint): - (DFGData): - * bytecode/DFGExitProfile.h: - (JSC::DFG::exitKindToString): - (JSC::DFG::exitKindIsCountable): - * bytecode/Instruction.h: - (Instruction): - (JSC::Instruction::Instruction): - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecode/Watchpoint.cpp: Added. - (JSC): - (JSC::Watchpoint::~Watchpoint): - (JSC::Watchpoint::correctLabels): - (JSC::Watchpoint::fire): - (JSC::WatchpointSet::WatchpointSet): - (JSC::WatchpointSet::~WatchpointSet): - (JSC::WatchpointSet::add): - (JSC::WatchpointSet::notifyWriteSlow): - (JSC::WatchpointSet::fireAllWatchpoints): - * bytecode/Watchpoint.h: Added. - (JSC): - (Watchpoint): - (JSC::Watchpoint::Watchpoint): - (JSC::Watchpoint::setDestination): - (WatchpointSet): - (JSC::WatchpointSet::isStillValid): - (JSC::WatchpointSet::hasBeenInvalidated): - (JSC::WatchpointSet::startWatching): - (JSC::WatchpointSet::notifyWrite): - (JSC::WatchpointSet::addressOfIsWatched): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::ResolveResult::checkValidity): - (JSC::BytecodeGenerator::addGlobalVar): - (JSC::BytecodeGenerator::BytecodeGenerator): - (JSC::BytecodeGenerator::resolve): - (JSC::BytecodeGenerator::emitResolve): - (JSC::BytecodeGenerator::emitResolveWithBase): - (JSC::BytecodeGenerator::emitResolveWithThis): - (JSC::BytecodeGenerator::emitGetStaticVar): - (JSC::BytecodeGenerator::emitPutStaticVar): - * bytecompiler/BytecodeGenerator.h: - (BytecodeGenerator): - * bytecompiler/NodesCodegen.cpp: - (JSC::FunctionCallResolveNode::emitBytecode): - (JSC::PostfixResolveNode::emitBytecode): - (JSC::PrefixResolveNode::emitBytecode): - (JSC::ReadModifyResolveNode::emitBytecode): - (JSC::AssignResolveNode::emitBytecode): - (JSC::ConstDeclNode::emitCodeSingle): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - (JSC::DFG::AbstractState::clobberStructures): - * dfg/DFGAbstractState.h: - (AbstractState): - (JSC::DFG::AbstractState::didClobber): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleInlining): - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCCallHelpers.h: - (CCallHelpers): - (JSC::DFG::CCallHelpers::setupArguments): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::globalVarWatchpointElimination): - (CSEPhase): - (JSC::DFG::CSEPhase::globalVarStoreElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGCapabilities.h: - (JSC::DFG::canCompileOpcode): - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::run): - * dfg/DFGCorrectableJumpPoint.h: - (JSC::DFG::CorrectableJumpPoint::isSet): - (CorrectableJumpPoint): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::linkOSRExits): - (JSC::DFG::JITCompiler::link): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasIdentifierNumberForCheck): - (Node): - (JSC::DFG::Node::identifierNumberForCheck): - (JSC::DFG::Node::hasRegisterPointer): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOSRExit.cpp: - (JSC::DFG::OSRExit::OSRExit): - * dfg/DFGOSRExit.h: - (OSRExit): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - (JSC::DFG::SpeculativeJIT::appendCall): - (SpeculativeJIT): - (JSC::DFG::SpeculativeJIT::speculationWatchpoint): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JIT.cpp: - (JSC::JIT::privateCompileMainPass): - (JSC::JIT::privateCompileSlowCases): - * jit/JIT.h: - * jit/JITPropertyAccess.cpp: - (JSC::JIT::emit_op_put_global_var_check): - (JSC): - (JSC::JIT::emitSlow_op_put_global_var_check): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::emit_op_put_global_var_check): - (JSC): - (JSC::JIT::emitSlow_op_put_global_var_check): - * jit/JITStubs.cpp: - (JSC::JITThunks::JITThunks): - (JSC::DEFINE_STUB_FUNCTION): - (JSC): - * jit/JITStubs.h: - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - (LLInt): - * llint/LLIntSlowPaths.h: - (LLInt): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/JSObject.cpp: - (JSC::JSObject::removeDirect): - * runtime/JSObject.h: - (JSObject): - * runtime/JSSymbolTableObject.h: - (JSC::symbolTableGet): - (JSC::symbolTablePut): - (JSC::symbolTablePutWithAttributes): - * runtime/SymbolTable.cpp: Added. - (JSC): - (JSC::SymbolTableEntry::copySlow): - (JSC::SymbolTableEntry::freeFatEntrySlow): - (JSC::SymbolTableEntry::couldBeWatched): - (JSC::SymbolTableEntry::attemptToWatch): - (JSC::SymbolTableEntry::addressOfIsWatched): - (JSC::SymbolTableEntry::addWatchpoint): - (JSC::SymbolTableEntry::notifyWriteSlow): - (JSC::SymbolTableEntry::inflateSlow): - * runtime/SymbolTable.h: - (JSC): - (SymbolTableEntry): - (Fast): - (JSC::SymbolTableEntry::Fast::Fast): - (JSC::SymbolTableEntry::Fast::isNull): - (JSC::SymbolTableEntry::Fast::getIndex): - (JSC::SymbolTableEntry::Fast::isReadOnly): - (JSC::SymbolTableEntry::Fast::getAttributes): - (JSC::SymbolTableEntry::Fast::isFat): - (JSC::SymbolTableEntry::SymbolTableEntry): - (JSC::SymbolTableEntry::~SymbolTableEntry): - (JSC::SymbolTableEntry::operator=): - (JSC::SymbolTableEntry::isNull): - (JSC::SymbolTableEntry::getIndex): - (JSC::SymbolTableEntry::getFast): - (JSC::SymbolTableEntry::getAttributes): - (JSC::SymbolTableEntry::isReadOnly): - (JSC::SymbolTableEntry::watchpointSet): - (JSC::SymbolTableEntry::notifyWrite): - (FatEntry): - (JSC::SymbolTableEntry::FatEntry::FatEntry): - (JSC::SymbolTableEntry::isFat): - (JSC::SymbolTableEntry::fatEntry): - (JSC::SymbolTableEntry::inflate): - (JSC::SymbolTableEntry::bits): - (JSC::SymbolTableEntry::freeFatEntry): - (JSC::SymbolTableEntry::pack): - (JSC::SymbolTableEntry::isValidIndex): - -2012-06-12 Filip Pizlo <fpizlo@apple.com> - - Unreviewed build fix for ARMv7 debug builds. - - * jit/JITStubs.cpp: - (JSC::JITThunks::JITThunks): - -2012-06-12 Geoffrey Garen <ggaren@apple.com> - - Build fix for case-sensitive file systems: use the right case. - - * heap/ListableHandler.h: - -2012-06-11 Geoffrey Garen <ggaren@apple.com> - - GC should be 1.7X faster - https://bugs.webkit.org/show_bug.cgi?id=88840 - - Reviewed by Oliver Hunt. - - I profiled, and removed anything that showed up as a concurrency - bottleneck. Then, I added 3 threads to our max thread count, since we - can scale up to more threads now. - - * heap/BlockAllocator.cpp: - (JSC::BlockAllocator::BlockAllocator): - (JSC::BlockAllocator::~BlockAllocator): - (JSC::BlockAllocator::releaseFreeBlocks): - (JSC::BlockAllocator::waitForRelativeTimeWhileHoldingLock): - (JSC::BlockAllocator::waitForRelativeTime): - (JSC::BlockAllocator::blockFreeingThreadMain): - * heap/BlockAllocator.h: - (BlockAllocator): - (JSC::BlockAllocator::allocate): - (JSC::BlockAllocator::deallocate): Use a spin lock for the common case - where we're just popping a linked list. (A pthread mutex would sleep our - thread even if the lock were only contended for a microsecond.) - - Scope the lock to avoid holding it while allocating VM, since that's a - slow activity and it doesn't modify any of our data structures. - - We still use a pthread mutex to handle our condition variable since we - have to, and it's not a hot path. - - * heap/CopiedSpace.cpp: - (JSC::CopiedSpace::CopiedSpace): - (JSC::CopiedSpace::doneFillingBlock): - * heap/CopiedSpace.h: - (JSC::CopiedSpace::CopiedSpace): Use a spin lock for the to space lock, - since it just guards linked list and hash table manipulation. - - * heap/MarkStack.cpp: - (JSC::MarkStackSegmentAllocator::MarkStackSegmentAllocator): - (JSC::MarkStackSegmentAllocator::allocate): - (JSC::MarkStackSegmentAllocator::release): - (JSC::MarkStackSegmentAllocator::shrinkReserve): Use a spin lock, since - we're just managing a linked list. - - (JSC::MarkStackArray::donateSomeCellsTo): Changed donation to be proportional - to our current stack size. This fixes cases where we used to donate too - much. Interestingly, donating too much was starving the donor (when it - ran out of work later) *and* the recipient (since it had to wait on a - long donation operation to complete before it could acquire the lock). - - In the worst case, we're still guaranteed to donate N cells in roughly log N time. - - This change also fixes cases where we used to donate too little, since - we would always keep a fixed minimum number of cells. In the worst case, - with N marking threads, would could have N large object graph roots in - our stack for the duration of GC, and scale to only 1 thread. - - It's an interesting observation that a single object in the mark stack - might represent an arbitrarily large object graph -- and only the act - of marking can find out. - - (JSC::MarkStackArray::stealSomeCellsFrom): Steal in proportion to idle - threads. Once again, this fixes cases where constants could cause us - to steal too much or too little. - - (JSC::SlotVisitor::donateKnownParallel): Always wake up other threads - if they're idle. We can afford to do this because we're conservative - about when we donate. - - (JSC::SlotVisitor::drainFromShared): - * heap/MarkStack.h: - (MarkStackSegmentAllocator): - (MarkStackArray): - (JSC): - * heap/SlotVisitor.h: Merged the "should I donate?" decision into a - single function, for simplicity. - - * runtime/Options.cpp: - (minimumNumberOfScansBetweenRebalance): Reduced the delay before donation - a lot. We can afford to do this because, in the common case, donation is - a single branch that decides not to donate. - - (cpusToUse): Use more CPUs now, since we scale better now. - - * runtime/Options.h: - (Options): Removed now-unused variables. - -2012-06-12 Filip Pizlo <fpizlo@apple.com> - - REGRESSION(120121): inspector tests crash in DFG - https://bugs.webkit.org/show_bug.cgi?id=88941 - - Reviewed by Geoffrey Garen. - - The CFG simplifier has two different ways of fixing up GetLocal, Phantom, and Flush. If we've - already fixed up the node one way, we shouldn't try the other way. The reason why we shouldn't - is that the second way depends on the node referring to other nodes in the to-be-jettisoned - block. After fixup they potentially will refer to nodes in the block being merged to. - - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal): - (JSC::DFG::CFGSimplificationPhase::mergeBlocks): - -2012-06-12 Leo Yang <leo.yang@torchmobile.com.cn> - - Dynamic hash table in DOMObjectHashTableMap is wrong in multiple threads - https://bugs.webkit.org/show_bug.cgi?id=87334 - - Reviewed by Geoffrey Garen. - - Add a copy member function to JSC::HasTable. This function will copy all data - members except for *table* which contains thread specific data that prevents - up copying it. When you want to copy a JSC::HashTable that was constructed - on another thread you should call JSC::HashTable::copy(). - - * runtime/Lookup.h: - (JSC::HashTable::copy): - (HashTable): - -2012-06-12 Filip Pizlo <fpizlo@apple.com> - - DFG should not ASSERT if you have a double use of a variable that is not revealed to be a double - until after CFG simplification - https://bugs.webkit.org/show_bug.cgi?id=88927 - <rdar://problem/11513971> - - Reviewed by Geoffrey Garen. - - Speculation fixup needs to run if simplification did things, because simplification can change - predictions - particularly if you had a control flow path that stored weird things into a - variable, but that path got axed by the simplifier. - - Running fixup in the fixpoint requires making it idempotent, which it previously wasn't. Only - one place needed to be changed, namely the un-MustGenerate-ion of ValueToInt32. - - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - -2012-06-12 Filip Pizlo <fpizlo@apple.com> - - REGRESSION (r119779): Javascript TypeError: 'undefined' is not an object - https://bugs.webkit.org/show_bug.cgi?id=88783 - <rdar://problem/11640299> - - Reviewed by Geoffrey Garen. - - If you don't keep alive the base of an object access over the various checks - you do for the prototype chain, you're going to have a bad time. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleGetById): - -2012-06-12 Hojong Han <hojong.han@samsung.com> - - Property names of the built-in object cannot be retrieved - after trying to delete one of its properties - https://bugs.webkit.org/show_bug.cgi?id=86461 - - Reviewed by Gavin Barraclough. - - * runtime/JSObject.cpp: - (JSC::getClassPropertyNames): - (JSC::JSObject::getOwnPropertyNames): - -2012-06-11 Gyuyoung Kim <gyuyoung.kim@samsung.com> - - [CMAKE][EFL] Remove duplicated executable output path - https://bugs.webkit.org/show_bug.cgi?id=88765 - - Reviewed by Daniel Bates. - - CMake files for EFL port have redefined executable output path. However, EFL port doesn't - need to define again because it is already defined in top-level CMake file. - - * shell/CMakeLists.txt: - -2012-06-11 Carlos Garcia Campos <cgarcia@igalia.com> - - Unreviewed. Fix make distcheck issues. - - * GNUmakefile.list.am: Remove non existent header file. - -2012-06-10 Patrick Gansterer <paroga@webkit.org> - - Unreviewed. Build fix for !ENABLE(JIT) after r119844 and r119925. - - * runtime/Executable.h: - (ExecutableBase): - (JSC::ExecutableBase::clearCodeVirtual): - -2012-06-10 Patrick Gansterer <paroga@webkit.org> - - Unreviewed. Build fix for !ENABLE(JIT) after r119844. - - * runtime/Executable.h: - (ExecutableBase): - (JSC): - -2012-06-09 Dominic Cooney <dominicc@chromium.org> - - [Chromium] Remove JavaScriptCore dependencies from gyp - https://bugs.webkit.org/show_bug.cgi?id=88510 - - Reviewed by Adam Barth. - - Chromium doesn't support JSC any more and there doesn't seem to be - a strong interest in using GYP as the common build system in other - ports. - - * JavaScriptCore.gyp/JavaScriptCore.gyp: WebCore still depends on YARR interpreter. - * JavaScriptCore.gypi: Only include YARR source. - * gyp/JavaScriptCore.gyp: Removed. - * gyp/gtk.gyp: Removed. - -2012-06-09 Geoffrey Garen <ggaren@apple.com> - - Unreviewed, rolling back in part2 of r118646. - - This patch removes eager finalization. - - Weak pointer finalization should be lazy - https://bugs.webkit.org/show_bug.cgi?id=87599 - - Reviewed by Sam Weinig. - - * heap/Heap.cpp: - (JSC::Heap::collect): Don't finalize eagerly -- we'll do it lazily. - - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::sweep): Do sweep weak sets when sweeping a block, - since we won't get another chance. - - * heap/MarkedBlock.h: - (JSC::MarkedBlock::sweepWeakSet): - * heap/MarkedSpace.cpp: - (MarkedSpace::WeakSetSweep): - * heap/MarkedSpace.h: - (JSC::MarkedSpace::sweepWeakSets): Removed now-unused code. - -2012-06-09 Sukolsak Sakshuwong <sukolsak@google.com> - - Add UNDO_MANAGER flag - https://bugs.webkit.org/show_bug.cgi?id=87908 - - Reviewed by Tony Chang. - - * Configurations/FeatureDefines.xcconfig: - -2012-06-08 Geoffrey Garen <ggaren@apple.com> - - Unreviewed, rolling back in part1 of r118646. - - This patch includes everything necessary for lazy finalization, but - keeps eager finalization enabled for the time being. - - Weak pointer finalization should be lazy - https://bugs.webkit.org/show_bug.cgi?id=87599 - - Reviewed by Sam Weinig. - - * heap/MarkedBlock.cpp: - * heap/MarkedBlock.h: - (JSC::MarkedBlock::resetAllocator): - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::resetAllocators): - * heap/MarkedSpace.h: - (JSC::MarkedSpace::resetAllocators): Don't force allocator reset anymore. - It will happen automatically when a weak set is swept. It's simpler to - have only one canonical way for this to happen, and it wasn't buying - us anything to do it eagerly. - * heap/WeakBlock.cpp: - (JSC::WeakBlock::sweep): Don't short-circuit a sweep unless we know - the sweep would be a no-op. If even one finalizer is pending, we need to - run it, since we won't get another chance. - * heap/WeakSet.cpp: - (JSC::WeakSet::sweep): This loop can be simpler now that - WeakBlock::sweep() does what we mean. - Reset our allocator after a sweep because this is the optimal time to - start trying to recycle old weak pointers. - (JSC::WeakSet::tryFindAllocator): Don't sweep when searching for an - allocator because we've swept already, and forcing a new sweep would be - wasteful. - * heap/WeakSet.h: - (JSC::WeakSet::shrink): Be sure to reset our allocator after a shrink - because the shrink may have removed the block the allocator was going to - allocate out of. - -2012-06-08 Gavin Barraclough <barraclough@apple.com> - - Unreviewed roll out r119795. - - This broke jquery/core.html - - * dfg/DFGSpeculativeJIT.h: + * dfg/DFGSpeculativeJIT.h: Use the proper allocator type when doing inline allocation in the DFG. (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - * llint/LowLevelInterpreter.asm: - * runtime/JSGlobalData.h: - (JSGlobalData): - * runtime/JSGlobalThis.cpp: - (JSC::JSGlobalThis::setUnwrappedObject): - * runtime/JSObject.cpp: - (JSC::JSObject::visitChildren): - (JSC::JSObject::createInheritorID): - * runtime/JSObject.h: - (JSObject): - (JSC::JSObject::resetInheritorID): - (JSC): - (JSC::JSObject::offsetOfInheritorID): - (JSC::JSObject::inheritorID): - -2012-06-08 Filip Pizlo <fpizlo@apple.com> - - PredictedType should be called SpeculatedType - https://bugs.webkit.org/show_bug.cgi?id=88477 - - Unreviewed, fix a renaming goof from http://trac.webkit.org/changeset/119660. - I accidentally renamed ByteCodeParser::getPrediction to - ByteCodeParser::getSpeculation. That was not the intent. This changes it - back. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::addCall): - (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit): - (JSC::DFG::ByteCodeParser::getPrediction): - (JSC::DFG::ByteCodeParser::handleCall): - (JSC::DFG::ByteCodeParser::parseBlock): - -2012-06-08 Andy Wingo <wingo@igalia.com> - - Explictly mark stubs called by JIT as being internal - https://bugs.webkit.org/show_bug.cgi?id=88552 - - Reviewed by Filip Pizlo. - - * dfg/DFGOSRExitCompiler.h: - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * jit/HostCallReturnValue.h: - * jit/JITStubs.cpp: - * jit/JITStubs.h: - * jit/ThunkGenerators.cpp: - * llint/LLIntSlowPaths.h: Mark a bunch of stubs as being - WTF_INTERNAL. Change most calls to SYMBOL_STRING_RELOCATION to - LOCAL_REFERENCE, or GLOBAL_REFERENCE in the case of the wrappers - to truly global symbols. - * offlineasm/asm.rb: Generate LOCAL_REFERENCE instead of - SYMBOL_STRING_RELOCATION. - -2012-06-08 Geoffrey Garen <ggaren@apple.com> - - Don't rely on weak pointers for eager CodeBlock finalization - https://bugs.webkit.org/show_bug.cgi?id=88465 - - Reviewed by Gavin Barraclough. - - This is incompatible with lazy weak pointer finalization. - - I considered just making CodeBlock finalization lazy-friendly, but it - turns out that the heap is already way up in CodeBlock's business when - it comes to finalization, so I decided to finish the job and move full - responsibility for CodeBlock finalization into the heap. - - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Maybe this - will build. - - * debugger/Debugger.cpp: Updated for rename. - + (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject): * heap/Heap.cpp: - (JSC::Heap::deleteAllCompiledCode): Renamed for consistency. Fixed a bug - where we would not delete code for a code block that had been previously - jettisoned. I don't know if this happens in practice -- I mostly did - this to improve consistency with deleteUnmarkedCompiledCode. - - (JSC::Heap::deleteUnmarkedCompiledCode): New function, responsible for - eager finalization of unmarked code blocks. - - (JSC::Heap::collect): Updated for rename. Updated to call - deleteUnmarkedCompiledCode(), which takes care of jettisoned DFG code - blocks too. - - (JSC::Heap::addCompiledCode): Renamed, since this points to all code - now, not just functions. - - * heap/Heap.h: - (Heap): Keep track of all user code, not just functions. This is a - negligible additional overhead, since most code is function code. - - * runtime/Executable.cpp: - (JSC::*::finalize): Removed these functions, since we don't rely on - weak pointer finalization anymore. - - (JSC::FunctionExecutable::FunctionExecutable): Moved linked-list stuff - into base class so all executables can be in the list. - - (JSC::EvalExecutable::clearCode): - (JSC::ProgramExecutable::clearCode): - (JSC::FunctionExecutable::clearCode): All we need to do is delete our - CodeBlock -- that will delete all of its internal data structures. - - (JSC::FunctionExecutable::clearCodeIfNotCompiling): Factored out a helper - function to improve clarity. - - * runtime/Executable.h: - (JSC::ExecutableBase): Moved linked-list stuff - into base class so all executables can be in the list. - - (JSC::NativeExecutable::create): - (NativeExecutable): - (ScriptExecutable): - (JSC::ScriptExecutable::finishCreation): - (JSC::EvalExecutable::create): - (EvalExecutable): - (JSC::ProgramExecutable::create): - (ProgramExecutable): - (FunctionExecutable): - (JSC::FunctionExecutable::create): Don't use a finalizer -- the heap - will call us back to destroy our code block. - - (JSC::FunctionExecutable::discardCode): Renamed to clearCodeIfNotCompiling() - for clarity. - - (JSC::FunctionExecutable::isCompiling): New helper function, for clarity. - - (JSC::ScriptExecutable::clearCodeVirtual): New helper function, since - the heap needs to make polymorphic calls to clear code. - - * runtime/JSGlobalData.cpp: - (JSC::StackPreservingRecompiler::operator()): - * runtime/JSGlobalObject.cpp: - (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): Updated for - renames. - -2012-06-07 Filip Pizlo <fpizlo@apple.com> - - DFG should inline prototype chain accesses, and do the right things if the - specific function optimization is available - https://bugs.webkit.org/show_bug.cgi?id=88594 - - Reviewed by Gavin Barraclough. - - Looks like a 3% win on V8. - - * bytecode/CodeBlock.h: - (JSC::Structure::prototypeForLookup): (JSC): - * bytecode/GetByIdStatus.cpp: - (JSC::GetByIdStatus::computeFromLLInt): - (JSC): - (JSC::GetByIdStatus::computeForChain): - (JSC::GetByIdStatus::computeFor): - * bytecode/GetByIdStatus.h: - (JSC::GetByIdStatus::GetByIdStatus): - (JSC::GetByIdStatus::isSimple): - (JSC::GetByIdStatus::chain): - (JSC::GetByIdStatus::specificValue): - (GetByIdStatus): - * bytecode/StructureSet.h: - (StructureSet): - (JSC::StructureSet::singletonStructure): - * bytecode/StructureStubInfo.h: - (JSC::StructureStubInfo::initGetByIdProto): - (JSC::StructureStubInfo::initGetByIdChain): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleGetById): - * dfg/DFGRepatch.cpp: - (JSC::DFG::tryCacheGetByID): - * jit/JITStubs.cpp: - (JSC::JITThunks::tryCacheGetByID): - * runtime/JSGlobalObject.h: - (JSC::Structure::prototypeForLookup): - (JSC): - * runtime/Structure.h: - (Structure): - -2012-06-07 Gavin Barraclough <barraclough@apple.com> - - Remove JSObject::m_inheritorID - https://bugs.webkit.org/show_bug.cgi?id=88378 - - Reviewed by Geoff Garen. - - This is rarely used, and not performance critical (the commonly accessed copy is cached on JSFunction), - and most objects don't need an inheritorID (this value is only used if the object is used as a prototype). - Instead use a private named value in the object's property storage. - - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): - - No need m_inheritorID to initialize! - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - - No need m_inheritorID to initialize! - * llint/LowLevelInterpreter.asm: - - No need m_inheritorID to initialize! - * runtime/JSGlobalData.h: - (JSGlobalData): - - Added private name 'm_inheritorIDKey'. - * runtime/JSGlobalThis.cpp: - (JSC::JSGlobalThis::setUnwrappedObject): - - resetInheritorID is now passed a JSGlobalData&. - * runtime/JSObject.cpp: - (JSC::JSObject::visitChildren): - - No m_inheritorID to be marked. - (JSC::JSObject::createInheritorID): - - Store the newly created inheritorID in the property map. - * runtime/JSObject.h: - (JSC::JSObject::resetInheritorID): - - Remove the inheritorID from property storage. - (JSC::JSObject::inheritorID): - - Read the inheritorID from property storage. - -2012-06-07 Gavin Barraclough <barraclough@apple.com> - - Math.pow on iOS does not support denormal numbers. - https://bugs.webkit.org/show_bug.cgi?id=88592 - - Reviewed by Filip Pizlo. - - Import an implementation from fdlibm, detect cases where it is safe to use the system - implementation & where we should fall back to fdlibm. - - * runtime/MathObject.cpp: - (JSC::isDenormal): - (JSC::isEdgeCase): - (JSC::mathPow): - - On iOS, detect cases where denormal support may be required & use fdlibm in these cases. - (JSC::mathProtoFuncPow): - - Changed to use mathPow. - (JSC::fdlibmScalbn): - (JSC::fdlibmPow): - - These functions imported from fdlibm; original style retained to ease future merging. - -2012-06-07 Patrick Gansterer <paroga@webkit.org> - - Unreviewed. Build fix for !ENABLE(JIT) after r119441. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::privateExecute): - -2012-06-07 Andy Wingo <wingo@igalia.com> - - Unreviewed build fix after r119593. - - * llint/LLIntOfflineAsmConfig.h (OFFLINE_ASM_GLOBAL_LABEL): Fix - uses of "name" to be "label", the macro's parameter. Otherwise we - serialize mentions of the literal symbol "name" into the objcode. - Causes a build error using GNU ld (not gold). - -2012-06-06 Ryosuke Niwa <rniwa@webkit.org> - - Chromium build fix attempt. Why do we need to list these files in gyp!? - - * JavaScriptCore.gypi: - -2012-06-06 Filip Pizlo <fpizlo@apple.com> - - PredictedType should be called SpeculatedType - https://bugs.webkit.org/show_bug.cgi?id=88477 - - Rubber stamped by Gavin Barraclough. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::shouldOptimizeNow): - (JSC::CodeBlock::dumpValueProfiles): - * bytecode/CodeBlock.h: - (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset): - * bytecode/LazyOperandValueProfile.cpp: - (JSC::LazyOperandValueProfileParser::prediction): - * bytecode/LazyOperandValueProfile.h: - (LazyOperandValueProfileParser): - * bytecode/PredictedType.cpp: Removed. - * bytecode/PredictedType.h: Removed. - * bytecode/SpeculatedType.cpp: Copied from Source/JavaScriptCore/bytecode/PredictedType.cpp. - (JSC::speculationToString): - (JSC::speculationToAbbreviatedString): - (JSC::speculationFromClassInfo): - (JSC::speculationFromStructure): - (JSC::speculationFromCell): - (JSC::speculationFromValue): - * bytecode/SpeculatedType.h: Copied from Source/JavaScriptCore/bytecode/PredictedType.h. - (JSC): - (JSC::isAnySpeculation): - (JSC::isCellSpeculation): - (JSC::isObjectSpeculation): - (JSC::isFinalObjectSpeculation): - (JSC::isFinalObjectOrOtherSpeculation): - (JSC::isFixedIndexedStorageObjectSpeculation): - (JSC::isStringSpeculation): - (JSC::isArraySpeculation): - (JSC::isFunctionSpeculation): - (JSC::isInt8ArraySpeculation): - (JSC::isInt16ArraySpeculation): - (JSC::isInt32ArraySpeculation): - (JSC::isUint8ArraySpeculation): - (JSC::isUint8ClampedArraySpeculation): - (JSC::isUint16ArraySpeculation): - (JSC::isUint32ArraySpeculation): - (JSC::isFloat32ArraySpeculation): - (JSC::isFloat64ArraySpeculation): - (JSC::isArgumentsSpeculation): - (JSC::isActionableIntMutableArraySpeculation): - (JSC::isActionableFloatMutableArraySpeculation): - (JSC::isActionableTypedMutableArraySpeculation): - (JSC::isActionableMutableArraySpeculation): - (JSC::isActionableArraySpeculation): - (JSC::isArrayOrOtherSpeculation): - (JSC::isMyArgumentsSpeculation): - (JSC::isInt32Speculation): - (JSC::isDoubleRealSpeculation): - (JSC::isDoubleSpeculation): - (JSC::isNumberSpeculation): - (JSC::isBooleanSpeculation): - (JSC::isOtherSpeculation): - (JSC::isEmptySpeculation): - (JSC::mergeSpeculations): - (JSC::mergeSpeculation): - * bytecode/StructureSet.h: - (JSC::StructureSet::speculationFromStructures): - * bytecode/ValueProfile.h: - (JSC::ValueProfileBase::ValueProfileBase): - (JSC::ValueProfileBase::dump): - (JSC::ValueProfileBase::computeUpdatedPrediction): - (ValueProfileBase): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::initialize): - (JSC::DFG::AbstractState::execute): - (JSC::DFG::AbstractState::mergeStateAtTail): - * dfg/DFGAbstractState.h: - (JSC::DFG::AbstractState::speculateInt32Unary): - (JSC::DFG::AbstractState::speculateNumberUnary): - (JSC::DFG::AbstractState::speculateBooleanUnary): - (JSC::DFG::AbstractState::speculateInt32Binary): - (JSC::DFG::AbstractState::speculateNumberBinary): - * dfg/DFGAbstractValue.h: - (JSC::DFG::StructureAbstractValue::filter): - (JSC::DFG::StructureAbstractValue::speculationFromStructures): - (JSC::DFG::AbstractValue::AbstractValue): - (JSC::DFG::AbstractValue::clear): - (JSC::DFG::AbstractValue::isClear): - (JSC::DFG::AbstractValue::makeTop): - (JSC::DFG::AbstractValue::clobberStructures): - (JSC::DFG::AbstractValue::isTop): - (JSC::DFG::AbstractValue::set): - (JSC::DFG::AbstractValue::merge): - (JSC::DFG::AbstractValue::filter): - (JSC::DFG::AbstractValue::validateIgnoringValue): - (JSC::DFG::AbstractValue::validate): - (JSC::DFG::AbstractValue::checkConsistency): - (JSC::DFG::AbstractValue::dump): - (AbstractValue): - * dfg/DFGArgumentPosition.h: - (JSC::DFG::ArgumentPosition::ArgumentPosition): - (JSC::DFG::ArgumentPosition::mergeArgumentAwareness): - (JSC::DFG::ArgumentPosition::prediction): - (ArgumentPosition): - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - * dfg/DFGByteCodeParser.cpp: - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation): - (JSC::DFG::ByteCodeParser::getLocal): - (JSC::DFG::ByteCodeParser::getArgument): - (JSC::DFG::ByteCodeParser::addCall): - (JSC::DFG::ByteCodeParser::getSpeculationWithoutOSRExit): - (JSC::DFG::ByteCodeParser::getSpeculation): - (InlineStackEntry): - (JSC::DFG::ByteCodeParser::handleCall): - (JSC::DFG::ByteCodeParser::handleIntrinsic): - (JSC::DFG::ByteCodeParser::handleGetById): - (JSC::DFG::ByteCodeParser::parseBlock): - (JSC::DFG::ByteCodeParser::fixVariableAccessSpeculations): - (JSC::DFG::ByteCodeParser::parse): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::run): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - (JSC::DFG::FixupPhase::fixDoubleEdge): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::nameOfVariableAccessData): - (JSC::DFG::Graph::dump): - (JSC::DFG::Graph::predictArgumentTypes): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::getJSConstantSpeculation): - (JSC::DFG::Graph::isPredictedNumerical): - (JSC::DFG::Graph::byValIsPure): - * dfg/DFGJITCompiler.h: - (JSC::DFG::JITCompiler::getSpeculation): - * dfg/DFGNode.h: - (JSC::DFG::Node::Node): - (JSC::DFG::Node::getHeapPrediction): - (JSC::DFG::Node::predictHeap): - (JSC::DFG::Node::prediction): - (JSC::DFG::Node::predict): - (JSC::DFG::Node::shouldSpeculateInteger): - (JSC::DFG::Node::shouldSpeculateDouble): - (JSC::DFG::Node::shouldSpeculateNumber): - (JSC::DFG::Node::shouldSpeculateBoolean): - (JSC::DFG::Node::shouldSpeculateFinalObject): - (JSC::DFG::Node::shouldSpeculateFinalObjectOrOther): - (JSC::DFG::Node::shouldSpeculateArray): - (JSC::DFG::Node::shouldSpeculateArguments): - (JSC::DFG::Node::shouldSpeculateInt8Array): - (JSC::DFG::Node::shouldSpeculateInt16Array): - (JSC::DFG::Node::shouldSpeculateInt32Array): - (JSC::DFG::Node::shouldSpeculateUint8Array): - (JSC::DFG::Node::shouldSpeculateUint8ClampedArray): - (JSC::DFG::Node::shouldSpeculateUint16Array): - (JSC::DFG::Node::shouldSpeculateUint32Array): - (JSC::DFG::Node::shouldSpeculateFloat32Array): - (JSC::DFG::Node::shouldSpeculateFloat64Array): - (JSC::DFG::Node::shouldSpeculateArrayOrOther): - (JSC::DFG::Node::shouldSpeculateObject): - (JSC::DFG::Node::shouldSpeculateCell): - (Node): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::setPrediction): - (JSC::DFG::PredictionPropagationPhase::mergePrediction): - (JSC::DFG::PredictionPropagationPhase::propagate): - (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::fillStorage): - (JSC::DFG::SpeculativeJIT::writeBarrier): - (JSC::DFG::GPRTemporary::GPRTemporary): - (JSC::DFG::FPRTemporary::FPRTemporary): - (JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch): - (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality): - (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch): - (JSC::DFG::SpeculativeJIT::compile): - (JSC::DFG::SpeculativeJIT::checkArgumentTypes): - (JSC::DFG::SpeculativeJIT::compileGetCharCodeAt): - (JSC::DFG::SpeculativeJIT::compileGetByValOnString): - (JSC::DFG::SpeculativeJIT::compileValueToInt32): - (JSC::DFG::SpeculativeJIT::compileDoubleAsInt32): - (JSC::DFG::SpeculativeJIT::compileInt32ToDouble): - (JSC::DFG::SpeculativeJIT::compileGetTypedArrayLength): - (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray): - (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): - (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray): - (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray): - (JSC::DFG::SpeculativeJIT::compileInstanceOf): - (JSC::DFG::SpeculativeJIT::compileAdd): - (JSC::DFG::SpeculativeJIT::compileArithSub): - (JSC::DFG::SpeculativeJIT::compileArithNegate): - (JSC::DFG::SpeculativeJIT::compileArithMul): - (JSC::DFG::SpeculativeJIT::compileArithMod): - (JSC::DFG::SpeculativeJIT::compare): - (JSC::DFG::SpeculativeJIT::compileStrictEq): - (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): - (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): - (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength): - (JSC::DFG::SpeculativeJIT::compileRegExpExec): - * dfg/DFGSpeculativeJIT.h: - (DFG): - (JSC::DFG::ValueSource::forSpeculation): - (SpeculativeJIT): - (GPRTemporary): - (FPRTemporary): - (JSC::DFG::SpecDoubleOperand::SpecDoubleOperand): - (JSC::DFG::SpecDoubleOperand::~SpecDoubleOperand): - (JSC::DFG::SpecDoubleOperand::fpr): - (JSC::DFG::SpecCellOperand::SpecCellOperand): - (JSC::DFG::SpecCellOperand::~SpecCellOperand): - (JSC::DFG::SpecCellOperand::gpr): - (JSC::DFG::SpecBooleanOperand::SpecBooleanOperand): - (JSC::DFG::SpecBooleanOperand::~SpecBooleanOperand): - (JSC::DFG::SpecBooleanOperand::gpr): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): - (JSC::DFG::SpeculativeJIT::fillSpecDouble): - (JSC::DFG::SpeculativeJIT::fillSpecCell): - (JSC::DFG::SpeculativeJIT::fillSpecBoolean): - (JSC::DFG::SpeculativeJIT::compileObjectEquality): - (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): - (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): - (JSC::DFG::SpeculativeJIT::compileDoubleCompare): - (JSC::DFG::SpeculativeJIT::compileLogicalNot): - (JSC::DFG::SpeculativeJIT::emitBranch): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): - (JSC::DFG::SpeculativeJIT::fillSpecDouble): - (JSC::DFG::SpeculativeJIT::fillSpecCell): - (JSC::DFG::SpeculativeJIT::fillSpecBoolean): - (JSC::DFG::SpeculativeJIT::compileObjectEquality): - (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): - (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): - (JSC::DFG::SpeculativeJIT::compileDoubleCompare): - (JSC::DFG::SpeculativeJIT::compileLogicalNot): - (JSC::DFG::SpeculativeJIT::emitBranch): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGVariableAccessData.h: - (JSC::DFG::VariableAccessData::VariableAccessData): - (JSC::DFG::VariableAccessData::predict): - (JSC::DFG::VariableAccessData::nonUnifiedPrediction): - (JSC::DFG::VariableAccessData::prediction): - (JSC::DFG::VariableAccessData::argumentAwarePrediction): - (JSC::DFG::VariableAccessData::mergeArgumentAwarePrediction): - (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote): - (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat): - (VariableAccessData): - -2012-06-06 Filip Pizlo <fpizlo@apple.com> - - Global object variable accesses should not require an extra load - https://bugs.webkit.org/show_bug.cgi?id=88385 - - Reviewed by Gavin Barraclough and Geoffrey Garen. - - Previously, if you wanted to access a global variable, you'd first have - to load the register array from the appropriate global object and then - either load or store at an offset to the register array. This is because - JSGlobalObject inherited from JSVariableObject, and JSVariableObject is - designed with the pessimistic assumption that its register array may - point into the call stack. This is never the case for global objects. - Hence, even though the global object may add more registers at any time, - it does not need to store them in a contiguous array. It can use a - SegmentedVector or similar. - - This patch refactors global objects and variable objects as follows: - - - The functionality to track variables in an indexable array using a - SymbolTable to map names to indices is moved into JSSymbolTableObject, - which is now a supertype of JSVariableObject. JSVariableObject is now - just a holder for a registers array and implements the registerAt() - method that is left abstract in JSSymbolTableObject. Because all users - of JSVariableObject know whether they are a JSStaticScopeObject, - JSActivation, or JSGlobalObject, this "abstract" method is not virtual; - instead the utility methods that would call registerAt() are now - template functions that require you to know statically what subtype of - JSSymbolTableObject you're using (JSVariableObject or something else), - so that registerAt() can be statically bound. - - - A new class is added called JSSegmentedVariableObject, which only - differs from JSVariableObject in how it allocates registers. It uses a - SegmentedVector instead of manually managing a pointer to a contiguous - slab of registers. This changes the interface somewhat; for example - with JSVariableObject if you wanted to add a register you had to do - it yourself since the JSVariableObject didn't know how the registers - array ought to be allocated. With JSSegmentedVariableObject you can - just call addRegisters(). JSSegmentedVariableObject preserves the - invariant that once you get a pointer into a register, that pointer - will continue to be valid so long as the JSSegmentedVariableObject is - alive. This allows the JITs and interpreters to skip the extra load. - - - JSGlobalObject now inherits from JSSegmentedVariableObject. For now - (and possibly forever) it is the only subtype of this new class. - - - The bytecode format is changed so that get_global_var and - put_global_var have a pointer to the register directly rather than - having an index. A convenience method is provided in - JSSegmentedVariableObject to get the index given a a pointer, which is - used for assertions and debug dumps. - - This appears to be a 1% across the board win. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - * bytecode/Instruction.h: - (Instruction): - (JSC::Instruction::Instruction): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::ResolveResult::registerPointer): - (JSC): - (JSC::BytecodeGenerator::BytecodeGenerator): - (JSC::BytecodeGenerator::retrieveLastUnaryOp): - (JSC::BytecodeGenerator::resolve): - (JSC::BytecodeGenerator::resolveConstDecl): - (JSC::BytecodeGenerator::emitGetStaticVar): - (JSC::BytecodeGenerator::emitPutStaticVar): - * bytecompiler/BytecodeGenerator.h: - (ResolveResult): - (BytecodeGenerator): - * dfg/DFGAssemblyHelpers.h: - (AssemblyHelpers): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::globalVarLoadElimination): - (JSC::DFG::CSEPhase::globalVarStoreElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dump): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::globalObjectFor): - (Graph): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasVarNumber): - (Node): - (JSC::DFG::Node::hasRegisterPointer): - (JSC::DFG::Node::registerPointer): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * heap/Heap.h: + * heap/Heap.h: Add accessors for the various types of allocators now. Also remove the isSafeToSweepStructures function + since it's always safe to sweep Structures now. + (JSC::Heap::allocatorForObjectWithNormalDestructor): + (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor): (Heap): - (JSC::Heap::isWriteBarrierEnabled): - (JSC): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::execute): - (JSC::Interpreter::privateExecute): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::emit_op_get_global_var): - (JSC::JIT::emit_op_put_global_var): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::emit_op_get_global_var): - (JSC::JIT::emit_op_put_global_var): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/JSGlobalObject.cpp: - (JSC): - (JSC::JSGlobalObject::put): - (JSC::JSGlobalObject::putDirectVirtual): - (JSC::JSGlobalObject::defineOwnProperty): - (JSC::JSGlobalObject::visitChildren): - (JSC::JSGlobalObject::addStaticGlobals): - (JSC::JSGlobalObject::getOwnPropertySlot): - (JSC::JSGlobalObject::getOwnPropertyDescriptor): - * runtime/JSGlobalObject.h: - (JSGlobalObject): - (JSC::JSGlobalObject::JSGlobalObject): - (JSC): - (JSC::JSGlobalObject::hasOwnPropertyForWrite): - * runtime/JSSegmentedVariableObject.cpp: Added. - (JSC): - (JSC::JSSegmentedVariableObject::findRegisterIndex): - (JSC::JSSegmentedVariableObject::addRegisters): - (JSC::JSSegmentedVariableObject::visitChildren): - * runtime/JSSegmentedVariableObject.h: Added. - (JSC): - (JSSegmentedVariableObject): - (JSC::JSSegmentedVariableObject::registerAt): - (JSC::JSSegmentedVariableObject::assertRegisterIsInThisObject): - (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject): - (JSC::JSSegmentedVariableObject::finishCreation): - * runtime/JSStaticScopeObject.cpp: - (JSC::JSStaticScopeObject::put): - (JSC::JSStaticScopeObject::putDirectVirtual): - (JSC::JSStaticScopeObject::getOwnPropertySlot): - * runtime/JSSymbolTableObject.cpp: Added. - (JSC): - (JSC::JSSymbolTableObject::destroy): - (JSC::JSSymbolTableObject::deleteProperty): - (JSC::JSSymbolTableObject::getOwnPropertyNames): - (JSC::JSSymbolTableObject::putDirectVirtual): - (JSC::JSSymbolTableObject::isDynamicScope): - * runtime/JSSymbolTableObject.h: Added. - (JSC): - (JSSymbolTableObject): - (JSC::JSSymbolTableObject::symbolTable): - (JSC::JSSymbolTableObject::JSSymbolTableObject): - (JSC::JSSymbolTableObject::finishCreation): - (JSC::symbolTableGet): - (JSC::symbolTablePut): - (JSC::symbolTablePutWithAttributes): - * runtime/JSVariableObject.cpp: - (JSC): - * runtime/JSVariableObject.h: - (JSVariableObject): - (JSC::JSVariableObject::JSVariableObject): - (JSC::JSVariableObject::finishCreation): + (JSC::Heap::allocateWithNormalDestructor): (JSC): - * runtime/WriteBarrier.h: - -2012-06-06 Filip Pizlo <fpizlo@apple.com> - - DFG arguments access slow path should not crash if the arguments haven't been created - https://bugs.webkit.org/show_bug.cgi?id=88471 - - Reviewed by Gavin Barraclough. - - * dfg/DFGCCallHelpers.h: - (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): - (CCallHelpers): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-06-06 Michael Saboff <msaboff@apple.com> - - ENH: Add Logging to GC Marking Phase - https://bugs.webkit.org/show_bug.cgi?id=88364 - - Reviewed by Filip Pizlo. - - Log GC marking to stderr or a file. The logging in controlled - with the define ENABLE_OBJECT_MARK_LOGGING in wtf/Platform.h. - If DATA_LOG_TO_FILE in wtf/DataLog.cpp is set to 1, output is - logged to a file otherwise it is logged to stderr. - - When logging is enabled, the GC is built single threaded since the - log output from the various threads isn't buffered and output in a - thread safe manner. - - * heap/Heap.cpp: - (JSC::Heap::markRoots): - * heap/MarkStack.cpp: - (JSC::MarkStackThreadSharedData::resetChildren): - (JSC::MarkStackThreadSharedData::childVisitCount): - (JSC::MarkStackThreadSharedData::markingThreadMain): - (JSC::MarkStackThreadSharedData::markingThreadStartFunc): - (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData): - (JSC::MarkStackThreadSharedData::reset): - * heap/MarkStack.h: - (MarkStackThreadSharedData): - (MarkStack): - (JSC::MarkStack::sharedData): - (JSC::MarkStack::resetChildCount): - (JSC::MarkStack::childCount): - (JSC::MarkStack::incrementChildCount): - * runtime/JSArray.cpp: - (JSC::JSArray::visitChildren): - * runtime/JSCell.cpp: - (JSC::JSCell::className): - * runtime/JSCell.h: - (JSCell): - (JSC::JSCell::visitChildren): - * runtime/JSString.cpp: - (JSC::JSString::visitChildren): - * runtime/JSString.h: - (JSString): - * runtime/Structure.h: - (JSC::MarkStack::internalAppend): - -2012-06-06 Gavin Barraclough <barraclough@apple.com> - - Assigning to a static property should not change iteration order - https://bugs.webkit.org/show_bug.cgi?id=88401 - - Reviewed by Geoff Garen. - - A specific iteration order is not defined by the spec, but test-262 somewhat tenuously - requires that it is at least stable, e.g. ch10/10.4/10.4.2/S10.4.2_A1.1_T1.js - - Whilst it is not clear that this behavior really arises from the specification, it - would seem like common sense to conform to this. - - The problem here is that we allow properties in the structure to shadow those in the - static table, and we iterate the properties in the structure first - which means that - as values of existing properties are modified, their iteration order changes too. - - The easy fix is to iterate the properties from the static table first. This has a - further benefit, since it will mean that user added properties will come after those - present in the static table (respected the expected insertion-order). - - * runtime/JSObject.cpp: - (JSC::JSObject::getOwnPropertyNames): - - Iterate static properties first. - -2012-06-06 Andy Wingo <wingo@igalia.com> - - Ensure consistent order of evaluation in LLInt slow paths - https://bugs.webkit.org/show_bug.cgi?id=88409 - - Reviewed by Geoffrey Garen. - - * llint/LLIntSlowPaths.cpp: - (slow_path_mul) - (slow_path_sub) - (slow_path_div) - (slow_path_mod) - (slow_path_lshift) - (slow_path_rshift) - (slow_path_urshift) - (slow_path_bitand) - (slow_path_bitor) - (slow_path_bitxor): Avoid calling toNumber, toInt32, or toUInt32 - multiple times without intervening sequence points. Fixes - fast/js/exception-sequencing-binops.html with GCC 4.7 on x86-64 - Linux, which reordered evaluation of the arguments to fmod. - -2012-06-06 Andy Wingo <wingo@igalia.com> - - [GTK] Enable the LLInt - https://bugs.webkit.org/show_bug.cgi?id=88315 - - Reviewed by Filip Pizlo. - - * GNUmakefile.am: Add rules to generate LLIntDesiredOffsets.h and - LLIntAssembly.h. - * GNUmakefile.list.am: Add offlineasm and llint files to the - dist. Add LLInt source files to the build. - * llint/LowLevelInterpreter.asm (crash): Generate a store of - 0xbbadbeef to a register, not to a constant. Otherwise, gas was - failing to assemble result. - * offlineasm/asm.rb (labelReference): Generate a - SYMBOL_STRING_RELOCATION instead of a SYMBOL_STRING, so that we go - through the PLT on ELF systems. - -2012-06-06 Andy Wingo <wingo@igalia.com> - - REGRESSION (r106478): None of the Paper.js JavaScript examples work - https://bugs.webkit.org/show_bug.cgi?id=87158 - - Reviewed by Michael Saboff. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::resolve): If we have to bail out to - dynamicResolve(), only skip static scopes from the head of the - scope chain. Before, we were also skipping activations with - direct eval as well, which was incorrect. - -2012-06-06 Dan Bernstein <mitz@apple.com> - - Reverted r119567, the fix for <http://webkit.org/b/88378>, because it broke the 32-bit build. - - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - * llint/LowLevelInterpreter.asm: - * runtime/JSGlobalData.h: - (JSGlobalData): - * runtime/JSGlobalThis.cpp: - (JSC::JSGlobalThis::setUnwrappedObject): - * runtime/JSObject.cpp: - (JSC::JSObject::visitChildren): - (JSC::JSObject::createInheritorID): - * runtime/JSObject.h: - (JSObject): - (JSC::JSObject::resetInheritorID): + (JSC::Heap::allocateWithImmortalStructureDestructor): + * heap/IncrementalSweeper.cpp: Remove all the logic to detect when it's safe to sweep Structures from the + IncrementalSweeper since it's always safe to sweep Structures now. + (JSC::IncrementalSweeper::IncrementalSweeper): + (JSC::IncrementalSweeper::sweepNextBlock): + (JSC::IncrementalSweeper::startSweeping): + (JSC::IncrementalSweeper::willFinishSweeping): (JSC): - (JSC::JSObject::offsetOfInheritorID): - (JSC::JSObject::inheritorID): - -2012-06-05 Yuqiang Xian <yuqiang.xian@intel.com> - - Improve Math.round and Math.floor intrinsic - https://bugs.webkit.org/show_bug.cgi?id=88314 - - Reviewed by Filip Pizlo. - - Currently we call a native function from the JIT code to complete the - "round" and "floor" operations. We could inline some fast paths - especially for those positive values on the platforms where floating - point truncation is supported. - This brings 3% gain on Kraken, especially 32% on audio-oscillator, - and slight win on SunSpider, measured on IA32. - - * jit/ThunkGenerators.cpp: - (JSC::floorThunkGenerator): + * heap/IncrementalSweeper.h: + (IncrementalSweeper): + * heap/MarkedAllocator.cpp: Remove the logic that was preventing us from sweeping Structures if it wasn't safe. Add + tracking of the specific destructor type of allocator. + (JSC::MarkedAllocator::tryAllocateHelper): + (JSC::MarkedAllocator::allocateBlock): + * heap/MarkedAllocator.h: + (JSC::MarkedAllocator::destructorType): + (MarkedAllocator): + (JSC::MarkedAllocator::MarkedAllocator): + (JSC::MarkedAllocator::init): + * heap/MarkedBlock.cpp: Add all the destructor type stuff to MarkedBlocks so that we do the right thing when sweeping. + We also use the stored destructor type to determine the right thing to do in all JSCell::classInfo() calls. + (JSC::MarkedBlock::create): + (JSC::MarkedBlock::MarkedBlock): (JSC): - (JSC::roundThunkGenerator): - -2012-06-05 Gavin Barraclough <barraclough@apple.com> - - Remove JSObject::m_inheritorID - https://bugs.webkit.org/show_bug.cgi?id=88378 - - Reviewed by Geoff Garen. - - This is rarely used, and not performance critical (the commonly accessed copy is cached on JSFunction), - and most objects don't need an inheritorID (this value is only used if the object is used as a prototype). - Instead use a private named value in the object's property storage. - - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): - - No need m_inheritorID to initialize! - * jit/JITInlineMethods.h: - (JSC::JIT::emitAllocateBasicJSObject): - - No need m_inheritorID to initialize! - * llint/LowLevelInterpreter.asm: - - No need m_inheritorID to initialize! - * runtime/JSGlobalData.h: - (JSGlobalData): - - Added private name 'm_inheritorIDKey'. - * runtime/JSGlobalThis.cpp: - (JSC::JSGlobalThis::setUnwrappedObject): - - resetInheritorID is now passed a JSGlobalData&. - * runtime/JSObject.cpp: - (JSC::JSObject::visitChildren): - - No m_inheritorID to be marked. - (JSC::JSObject::createInheritorID): - - Store the newly created inheritorID in the property map. - * runtime/JSObject.h: - (JSC::JSObject::resetInheritorID): - - Remove the inheritorID from property storage. - (JSC::JSObject::inheritorID): - - Read the inheritorID from property storage. - -2012-06-05 Filip Pizlo <fpizlo@apple.com> - - DFG CFG simplification should not attempt to deref nodes inside of an unreachable subgraph - https://bugs.webkit.org/show_bug.cgi?id=88362 - - Reviewed by Gavin Barraclough. - - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::fixPhis): - (JSC::DFG::CFGSimplificationPhase::removePotentiallyDeadPhiReference): - -2012-06-05 Mark Hahnenberg <mhahnenberg@apple.com> - - Entry into JSC should CRASH() if the Heap is busy - https://bugs.webkit.org/show_bug.cgi?id=88355 - - Reviewed by Geoffrey Garen. - - Interpreter::execute() returns jsNull() right now if we try to enter it while - the Heap is busy (e.g. with a collection), which is okay, but some code paths - that call Interpreter::execute() allocate objects before checking if the Heap - is busy. Attempting to execute JS code while the Heap is busy should not be - allowed and should be enforced by a release-mode CRASH() to prevent vague, - unhelpful backtraces later on if somebody makes a mistake. Normally, recursively - executing JS code is okay, e.g. for evals, but it should not occur during a - Heap allocation or collection because the Heap is not guaranteed to be in a - consistent state (especially during collections). We are protected from - executing JS on the same Heap concurrently on two separate threads because - they must each take a JSLock first. However, we are not protected from reentrant - execution of JS on the same thread because JSLock allows reentrancy. Therefore, - we should fail early if we detect an entrance into JS code while the Heap is busy. - - * heap/Heap.cpp: Changed Heap::collect so that it sets the m_operationInProgress field - at the beginning of collection and then unsets it at the end so that it is set at all - times throughout the duration of a collection rather than sporadically during various - phases. There is no reason to unset during a collection because our collector does - not currently support running additional JS between the phases of a collection. - (JSC::Heap::getConservativeRegisterRoots): - (JSC::Heap::markRoots): - (JSC::Heap::collect): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::execute): Crash if the Heap is busy. - * runtime/Completion.cpp: Crash if the Heap is busy. We do it here before we call - Interpreter::execute() because we do some allocation prior to calling execute() which - could cause Heap corruption if, for example, that allocation caused a collection. - (JSC::evaluate): - -2012-06-05 Dongwoo Im <dw.im@samsung.com> - - Add 'isProtocolHandlerRegistered' and 'unregisterProtocolHandler'. - https://bugs.webkit.org/show_bug.cgi?id=73176 - - Reviewed by Adam Barth. - - Two more APIs are added in Custom Scheme Handler specification. - http://dev.w3.org/html5/spec/Overview.html#custom-handlers - One is 'isProtocolHandlerRegistered' to query whether the specific URL - is registered or not. - The other is 'unregisterProtocolHandler' to remove the registered URL. - - * Configurations/FeatureDefines.xcconfig: Add a macro 'ENABLE_CUSTOM_SCHEME_HANDLER'. - -2012-06-04 Filip Pizlo <fpizlo@apple.com> - - DFG CFG simplification should correct the variables at the head of the predecessor block - https://bugs.webkit.org/show_bug.cgi?id=88284 - - Reviewed by Geoffrey Garen. - - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::mergeBlocks): - -2012-06-04 Geoffrey Garen <ggaren@apple.com> - - Unreviewed. - - Rolled out r119364 because it's still causing crashes (when running - v8-earley in release builds of DRT) - - This time for sure! - - * heap/Heap.cpp: - (JSC::Heap::collect): - * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::specializedSweep): (JSC::MarkedBlock::sweep): + (JSC::MarkedBlock::sweepHelper): * heap/MarkedBlock.h: - (JSC::MarkedBlock::resetAllocator): - (JSC): - * heap/MarkedSpace.cpp: - (JSC::ResetAllocator::operator()): (JSC): + (JSC::MarkedBlock::allocator): + (JSC::MarkedBlock::destructorType): + * heap/MarkedSpace.cpp: Add the new destructor allocators to MarkedSpace. + (JSC::MarkedSpace::MarkedSpace): (JSC::MarkedSpace::resetAllocators): - (JSC::MarkedSpace::sweepWeakSets): + (JSC::MarkedSpace::canonicalizeCellLivenessData): + (JSC::MarkedSpace::isPagedOut): + (JSC::MarkedSpace::freeBlock): * heap/MarkedSpace.h: (MarkedSpace): - * heap/WeakBlock.cpp: - (JSC::WeakBlock::sweep): - * heap/WeakSet.cpp: - (JSC::WeakSet::sweep): - (JSC::WeakSet::tryFindAllocator): - * heap/WeakSet.h: - (JSC::WeakSet::shrink): - -2012-06-04 Filip Pizlo <fpizlo@apple.com> - - DFG arguments simplification should have rationalized handling of TearOffArguments - https://bugs.webkit.org/show_bug.cgi?id=88206 - - Reviewed by Geoffrey Garen. - - - Accesses to the unmodified arguments register ought to have the same effect on - alias/escape analysis of arguments as accesses to the mutable arguments register. - - - The existence of TearOffArguments should not get in the way of arguments aliasing. - - - TearOffArguments should be eliminated if CreateArguments is eliminated. - - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): - -2012-06-04 Gavin Barraclough <barraclough@apple.com> - - Remove enabledProfilerReference - https://bugs.webkit.org/show_bug.cgi?id=88258 - - Reviewed by Michael Saboff. - - Make the enabled profiler a member of JSGlobalData, and switch code that accesses it to do so directly - via the JSGlobalData, rather than holding a Profiler** reference to it. Do not pass the Profiler** - reference to JIT code. This patch does not change the stack layout on entry into JIT code (passing an - unused void* instead), since this is an intrusive change better handled in a separate patch. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::throwException): - (JSC::Interpreter::execute): - (JSC::Interpreter::executeCall): - (JSC::Interpreter::executeConstruct): - (JSC::Interpreter::privateExecute): - * jit/JITCode.h: - (JSC::JITCode::execute): - - Don't pass Profiler** to JIT code. - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_profile_will_call): - (JSC::JIT::emit_op_profile_did_call): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_profile_will_call): - (JSC::JIT::emit_op_profile_did_call): - * jit/JITStubs.cpp: + (JSC::MarkedSpace::immortalStructureDestructorAllocatorFor): + (JSC::MarkedSpace::normalDestructorAllocatorFor): + (JSC::MarkedSpace::allocateWithImmortalStructureDestructor): + (JSC::MarkedSpace::allocateWithNormalDestructor): + (JSC::MarkedSpace::forEachBlock): + * heap/SlotVisitor.cpp: Add include because the symbol was needed in an inlined function. + * jit/JIT.h: Make sure we use the correct allocator when doing inline allocations in the baseline JIT. + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + (JSC::JIT::emitAllocateJSFinalObject): + (JSC::JIT::emitAllocateJSArray): + * jsc.cpp: + (GlobalObject::create): Add finalizer here since JSGlobalObject needs to use a finalizer instead of inheriting from + JSDestructibleObject. + * runtime/Arguments.cpp: Inherit from JSDestructibleObject. (JSC): - (JSC::ctiTrampoline): - (JSC::ctiVMThrowTrampoline): - (JSC::ctiOpThrowNotCaught): - (JSC::JITThunks::JITThunks): - (JSC::DEFINE_STUB_FUNCTION): - - For ARM_THUMB2, rename ENABLE_PROFILER_REFERENCE_OFFSET to FIRST_STACK_ARGUMENT (which is how it is being used). - - For MIPS, remove ENABLE_PROFILER_REFERENCE_OFFSET. - * jit/JITStubs.h: - (JITStackFrame): + * runtime/Arguments.h: + (Arguments): + (JSC::Arguments::Arguments): + * runtime/ErrorPrototype.cpp: Added an assert to make sure we have a trivial destructor. (JSC): - - Renamed enabledProfilerReference to unusedX. - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter.asm: - * profiler/Profiler.cpp: + * runtime/Executable.h: Indicate that all of the Executable* classes have immortal Structures. (JSC): - (JSC::Profiler::startProfiling): - (JSC::Profiler::stopProfiling): - * profiler/Profiler.h: - (Profiler): - - Removed s_sharedEnabledProfilerReference, enabledProfilerReference(). - * runtime/JSGlobalData.cpp: - (JSC::JSGlobalData::JSGlobalData): - * runtime/JSGlobalData.h: + * runtime/InternalFunction.cpp: Inherit from JSDestructibleObject. (JSC): - (JSC::JSGlobalData::enabledProfiler): - (JSGlobalData): - - Added m_enabledProfiler, enabledProfiler(). - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::~JSGlobalObject): - -2012-06-04 Filip Pizlo <fpizlo@apple.com> - - get_argument_by_val should be profiled everywhere - https://bugs.webkit.org/show_bug.cgi?id=88205 - - Reviewed by Geoffrey Garen. - - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emitSlow_op_get_argument_by_val): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - -2012-06-04 Filip Pizlo <fpizlo@apple.com> - - DFG arguments simplification takes unkindly to direct accesses to the arguments register - https://bugs.webkit.org/show_bug.cgi?id=88261 - - Reviewed by Geoffrey Garen. - - Fixed arguments simplification for direct accesses to the arguments register, which may - arise if CSE had not run. Fixed CSE so that it does run prior to arguments simplification, - by making it a full-fledged member of the fixpoint. Fixed other issues in arguments - simplification, like realizing that it needs to bail if there is a direct assignment to - the arguments register, and failing to turn CreateArguments into PhantomArguments. Also - fixed CSE's handling of store elimination of captured locals in the presence of a - GetMyArgumentByVal (or one of its friends), and fixed CSE to correctly fixup variables at - tail if the Flush it removes is the last operation on a local in a basic block. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::run): - (JSC::DFG::CSEPhase::setLocalStoreElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - (CSEPhase): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - -2012-06-04 Anders Carlsson <andersca@apple.com> - - Fix a struct/class mismatch. - - * heap/Handle.h: - (Handle): - -2012-06-04 David Kilzer <ddkilzer@apple.com> - - BUILD FIX: FeatureDefines.xcconfig should match across projects - - * Configurations/FeatureDefines.xcconfig: - - Add missing ENABLE_LEGACY_CSS_VENDOR_PREFIXES. - -2012-06-02 Geoffrey Garen <ggaren@apple.com> - - Weak pointer finalization should be lazy - https://bugs.webkit.org/show_bug.cgi?id=87599 - - Reviewed by Sam Weinig. - - This time for sure! - - * heap/Heap.cpp: - (JSC::Heap::collect): Don't sweep eagerly -- we'll sweep lazily instead. - - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::sweep): Sweep our weak set before we sweep our other - destructors -- this is our last chance to run weak set finalizers before - we recycle our memory. - - * heap/MarkedBlock.h: - (JSC::MarkedBlock::resetAllocator): - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::resetAllocators): - * heap/MarkedSpace.h: - (JSC::MarkedSpace::resetAllocators): Don't force allocator reset anymore. - It will happen automatically when a weak set is swept. It's simpler to - have only one canonical way for this to happen, and it wasn't buying - us anything to do it eagerly. - - * heap/WeakBlock.cpp: - (JSC::WeakBlock::sweep): Don't short-circuit a sweep unless we know - the sweep would be a no-op. If even one finalizer is pending, we need to - run it, since we won't get another chance. - - * heap/WeakSet.cpp: - (JSC::WeakSet::sweep): This loop can be simpler now that - WeakBlock::sweep() does what we mean. - - Reset our allocator after a sweep because this is the optimal time to - start trying to recycle old weak pointers. - - (JSC::WeakSet::tryFindAllocator): Don't sweep when searching for an - allocator because we've swept already, and forcing a new sweep would be - wasteful. - - * heap/WeakSet.h: - (JSC::WeakSet::shrink): Be sure to reset our allocator after a shrink - because the shrink may have removed the block the allocator was going to - allocate out of. - -2012-06-02 Filip Pizlo <fpizlo@apple.com> - - If the DFG bytecode parser detects that op_method_check has gone polymorphic, it - shouldn't revert all the way to GetById/GetByIdFlush - https://bugs.webkit.org/show_bug.cgi?id=88176 - - Reviewed by Geoffrey Garen. - - Refactored the code so that the op_method_check case of the parser gracefully falls - through to all of the goodness of the normal op_get_by_id case. - - * dfg/DFGByteCodeParser.cpp: - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::handleGetById): - (DFG): - (JSC::DFG::ByteCodeParser::parseBlock): - -2012-06-02 Filip Pizlo <fpizlo@apple.com> - - DFG CSE should be able to eliminate unnecessary flushes of arguments and captured variables - https://bugs.webkit.org/show_bug.cgi?id=87929 - - Reviewed by Geoffrey Garen. - - Slight speed-up on V8. Big win (up to 50%) on programs that inline very small functions. - - This required a bunch of changes: - - - The obvious change is making CSE essentially ignore whether or not the set of - operations between the Flush and the SetLocal can exit, and instead focus on whether or - not that set of operations can clobber the world or access local variables. This code - is now refactored to return a set of flags indicating any of these events, and the CSE - decides what to do based on those flags. If the set of operations is non-clobbering - and non-accessing, then the Flush is turned into a Phantom on the child of the - SetLocal. This expands the liveness of the relevant variable but virtually guarantees - that it will be register allocated and not flushed to the stack. So, yeah, this patch - is a lot of work to save a few stores to the stack. - - - Previously, CheckArgumentsNotCreated was optimized "lazily" in that you only knew if - it was a no-op if you were holding onto a CFA abstract state. But this would make the - CSE act pessimistically, since it doesn't use the CFA. Hence, this patch changes the - constant folding phase into something more broad; it now fixes up - CheckArgumentsNotCreated nodes by turning them into phantoms if it knows that they are - no-ops. - - - Arguments simplification was previously relying on this very strange PhantomArguments - node, which had two different meanings: for normal execution it meant the empty value - but for OSR exit it meant that the arguments should be reified. This produces problems - when set SetLocals to the captured arguments registers are CSE'd away, since we'd be - triggering reification of arguments without having initialized the arguments registers - to empty. The cleanest solution was to fix PhantomArguments to have one meaning: - namely, arguments reification on OSR exit. Hence, this patch changes arguments - simplification to change SetLocal of CreateArguments on the arguments registers to be - a SetLocal of Empty. - - - Argument value recoveries were previously derived from the value source of the - arguments at the InlineStart. But that relies on all SetLocals to arguments having - been flushed. It's possible that we could have elided the SetLocal to the arguments - at the callsite because there were subsequent SetLocals to the arguments inside of the - callee, in which case the InlineStart would get the wrong information. Hence, this - patch changes argument value recovery computation to operate over the ArgumentPositions - directly. - - - But that doesn't actually work, because previously, there was no way to link an - InlineStart back to the corresponding ArgumentPositions, at least not without some - ugliness. So this patch instates the rule that the m_argumentPositions vector consists - of disjoint subsequences such that each subsequence corresponds to an inline callsite - and can be identified by its first index, and within each subsequence are the - ArgumentPositions of all of the arguments ordered by argument index. This required - flipping the order in which ArgumentPositions are added to the vector, and giving - InlineStart an operand that indicates the start of that inline callsite's - ArgumentPosition subsequence. - - - This patch also revealed a nasty bug in the reification of arguments in inline call - frames on OSR exit. Since the reification was happening after the values of virtual - registers were recovered, the value recoveries of the inline arguments were wrong. - Hence using operationCreateInlinedArguments is wrong. For example a value recovery - might say that you have to box a double, but if we had already boxed it then boxing - it a second time will result in garbage. The specific case of this bug was this patch - uncovered was that now it is possible for an inline call frame to not have any valid - value recoveries for any inline arguments, if the optimization elides all argument - flushes, while at the same time optimizing away arguments creation. Then OSR exit - would try to recover the arguments using the inline call frame, which had bogus - information, and humorous crashes would ensue. This patch fixes this issue by moving - arguments reification to after call frame reification, so that arguments reification - can always use operationCreateArguments instead of operationCreateInlinedArguments. - - - This patch may turn a Flush into a Phantom. That's kind of the whole point. But that - broke forward speculation checks, which knew to look for a Flush prior to a SetLocal - but didn't know that there could alternatively be a Phantom in place of the Flush. - This patch fixes that by augmenting the forward speculation check logic. - - - Finally, in the process of having fun with all of the above, I realized that my DFG - validation was not actually running on every phase like I had originally designed it - to. In fact it was only running just after bytecode parsing. I initially tried to - make it run in every phase but found that this causes some tests to timeout - (specifically the evil fuzzing ones), so I decided on a compromise where: (i) in - release mode validation never runs, (ii) in debug mode validation will run just - after parsing and just before the backend, and (iii) it's possible with a simple - switch to enable validation to run on every phase. - - Luckily all of the above issues were already covered by the 77 or so DFG-specific - layout tests. Hence, this patch does not introduce any new tests despite being so - meaty. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGArgumentPosition.h: - (JSC::DFG::ArgumentPosition::prediction): - (JSC::DFG::ArgumentPosition::doubleFormatState): - (JSC::DFG::ArgumentPosition::shouldUseDoubleFormat): - (ArgumentPosition): - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleInlining): - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::SetLocalStoreEliminationResult::SetLocalStoreEliminationResult): - (SetLocalStoreEliminationResult): - (JSC::DFG::CSEPhase::setLocalStoreElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGCommon.h: - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::run): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGNode.h: - (Node): - (JSC::DFG::Node::hasArgumentPositionStart): - (JSC::DFG::Node::argumentPositionStart): - * dfg/DFGOSRExitCompiler32_64.cpp: - (JSC::DFG::OSRExitCompiler::compileExit): - * dfg/DFGOSRExitCompiler64.cpp: - (JSC::DFG::OSRExitCompiler::compileExit): - * dfg/DFGPhase.cpp: - (DFG): - * dfg/DFGPhase.h: - (Phase): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-06-02 Geoffrey Garen <ggaren@apple.com> - - DOM string cache should hash pointers, not characters - https://bugs.webkit.org/show_bug.cgi?id=88175 - - Reviewed by Phil Pizlo and Sam Weinig. - - * heap/Weak.h: - (JSC::weakAdd): - (JSC::weakRemove): Made these function templates slightly more generic - to accommodate new client types. - -2012-06-01 Filip Pizlo <fpizlo@apple.com> - - DFG CFA should know that PutByVal can clobber the world - https://bugs.webkit.org/show_bug.cgi?id=88155 - - Reviewed by Gavin Barraclough. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - -2012-06-01 Filip Pizlo <fpizlo@apple.com> - - DFG CFA should mark basic blocks as having constants if local accesses yield constants - https://bugs.webkit.org/show_bug.cgi?id=88153 - - Reviewed by Gavin Barraclough. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - -2012-06-01 Filip Pizlo <fpizlo@apple.com> - - DFG arguments simplification phase uses a node.codeOrigin after appending a node - https://bugs.webkit.org/show_bug.cgi?id=88151 - - Reviewed by Geoffrey Garen. - - The right thing to do is to save the CodeOrigin before appending to the graph. - - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - -2012-06-01 Filip Pizlo <fpizlo@apple.com> - - DFG should not emit unnecessary speculation checks when performing an int32 to double conversion on - a value that is proved to be a number, predicted to be an int32, but not proved to be an int32 - https://bugs.webkit.org/show_bug.cgi?id=88146 - - Reviewed by Gavin Barraclough. - - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileInt32ToDouble): - -2012-06-01 Filip Pizlo <fpizlo@apple.com> - - DFG constant folding search for the last local access skips the immediately previous local access - https://bugs.webkit.org/show_bug.cgi?id=88141 - - Reviewed by Michael Saboff. - - If you use a loop in the style of: - - for (i = start; i--;) - - then you need to remember that the first value of 'i' that the loop body will see is 'start - 1'. - Hence the following is probably wrong: - - for (i = start - 1; i--;) - - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::run): - -2012-06-01 Filip Pizlo <fpizlo@apple.com> - - DFG constant folding should be OK with GetLocal of captured variables having a constant - https://bugs.webkit.org/show_bug.cgi?id=88137 - - Reviewed by Gavin Barraclough. - - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::run): - -2012-05-31 Mark Hahnenberg <mhahnenberg@apple.com> - - JSGlobalObject does not mark m_privateNameStructure - https://bugs.webkit.org/show_bug.cgi?id=88023 - - Rubber stamped by Gavin Barraclough. - - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::visitChildren): We need to mark this so it doesn't get - inadvertently garbage collected. - -2012-05-31 Erik Arvidsson <arv@chromium.org> - - Make DOM Exceptions Errors - https://bugs.webkit.org/show_bug.cgi?id=85078 - - Reviewed by Oliver Hunt. - - WebIDL mandates that exceptions should have Error.prototype on its prototype chain. - - For JSC we have access to the Error.prototype from the binding code. - - For V8 we set a field in the WrapperTypeInfo and when the constructor function is created we - set the prototype as needed. - - Updated test: fast/dom/DOMException/prototype-object.html - - * JavaScriptCore.xcodeproj/project.pbxproj: - * runtime/JSGlobalObject.cpp: + (JSC::InternalFunction::InternalFunction): + * runtime/InternalFunction.h: + (InternalFunction): + * runtime/JSCell.h: Added two static bools, needsDestruction and hasImmortalStructure, that classes can override + to indicate at compile time which part of the heap they should be allocated in. + (JSC::allocateCell): Use the appropriate allocator depending on the destructor type. + * runtime/JSDestructibleObject.h: Added. New class that stores the ClassInfo of any subclass so that it can be + accessed safely when the object is being destroyed. + (JSC): + (JSDestructibleObject): + (JSC::JSDestructibleObject::classInfo): + (JSC::JSDestructibleObject::JSDestructibleObject): + (JSC::JSCell::classInfo): Checks the current MarkedBlock to see where it should get the ClassInfo from so that it's always safe. + * runtime/JSGlobalObject.cpp: JSGlobalObject now uses a finalizer instead of a destructor so that it can avoid forcing all + of its relatives in the inheritance hierarchy (e.g. JSScope) to use destructors as well. (JSC::JSGlobalObject::reset): * runtime/JSGlobalObject.h: - (JSC): (JSGlobalObject): - (JSC::JSGlobalObject::errorPrototype): - -2012-05-31 Andy Wingo <wingo@igalia.com> - - Fix reference to unset variable in debug mode - https://bugs.webkit.org/show_bug.cgi?id=87981 - - Reviewed by Geoffrey Garen. - - * runtime/JSONObject.cpp (Stringifier::Holder::Holder): - Initialize m_size in debug mode, as we check it later in an assert. - -2012-05-30 Mark Hahnenberg <mhahnenberg@apple.com> - - Heap should sweep incrementally - https://bugs.webkit.org/show_bug.cgi?id=85429 - - We shouldn't have to wait for the opportunistic GC timer to fire in order - to call object destructors. Instead, we should incrementally sweep some - subset of the blocks requiring sweeping periodically. We tie this sweeping - to a timer rather than to collections because we want to reclaim this memory - even if we stop allocating. This way, our memory usage scales smoothly with - actual use, regardless of whether we've recently done an opportunistic GC or not. - - Reviewed by Geoffrey Garen. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.gypi: - * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * heap/Heap.cpp: - (JSC::Heap::Heap): - (JSC::Heap::collect): We no longer sweep during a full sweep. We only shrink now, - which we will switch over to being done during incremental sweeping too as soon as - all finalizers can be run lazily (and, by extension, incrementally). - (JSC::Heap::sweeper): - (JSC): - * heap/Heap.h: - (JSC): - (Heap): - * heap/IncrementalSweeper.cpp: Added. - (JSC): - (JSC::IncrementalSweeper::timerDidFire): The IncrementalSweeper works very similarly to - GCActivityCallback. It is tied to a run-loop based timer that fires periodically based - on how long the previous sweep increment took to run. The IncrementalSweeper doesn't do - anything if the platform doesn't support CoreFoundation. - (JSC::IncrementalSweeper::IncrementalSweeper): - (JSC::IncrementalSweeper::~IncrementalSweeper): - (JSC::IncrementalSweeper::create): - (JSC::IncrementalSweeper::scheduleTimer): - (JSC::IncrementalSweeper::cancelTimer): - (JSC::IncrementalSweeper::doSweep): Iterates over the snapshot of the MarkedSpace taken - during the last collection, checking to see which blocks need sweeping. If it successfully - gets to the end of the blocks that need sweeping then it cancels the timer. - (JSC::IncrementalSweeper::startSweeping): We take a snapshot of the Heap and store it in - a Vector that the incremental sweep will iterate over. We also reset our index into this Vector. - * heap/IncrementalSweeper.h: Added. - (JSC): - (IncrementalSweeper): - * heap/MarkedBlock.h: - (JSC::MarkedBlock::needsSweeping): If a block is in the Marked state it needs sweeping - to be usable and to run any destructors that need to be run. - -2012-05-30 Patrick Gansterer <paroga@webkit.org> - - [WINCE] Fix JSString after r115516. - https://bugs.webkit.org/show_bug.cgi?id=87892 - - Reviewed by Geoffrey Garen. - - r115516 splitted JSString into two classes, with addition nested classes. - Add a workaround for the WinCE compiler since it can't resolve the friend class - declerations corretly and denies the access to protected members of JSString. - - * runtime/JSString.h: - (JSC::JSRopeString::RopeBuilder::append): - (JSC::JSRopeString::append): - (JSRopeString): - -2012-05-30 Oliver Hunt <oliver@apple.com> - - Really provide error information with the inspector disabled - https://bugs.webkit.org/show_bug.cgi?id=87910 - - Reviewed by Filip Pizlo. - - Don't bother checking for anything other than pre-existing error info. - In the absence of complete line number information you'll only get the - line a function starts on, but at least it's something. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::throwException): - -2012-05-30 Filip Pizlo <fpizlo@apple.com> - - LLInt broken on x86-32 with JIT turned off - https://bugs.webkit.org/show_bug.cgi?id=87906 - - Reviewed by Geoffrey Garen. - - Fixed the code to not clobber registers that contain important things, like the call frame. - - * llint/LowLevelInterpreter32_64.asm: - -2012-05-30 Filip Pizlo <fpizlo@apple.com> - - ScriptDebugServer wants sourceIDs that are non-zero because that's what HashMaps want, so JSC should placate it - https://bugs.webkit.org/show_bug.cgi?id=87887 - - Reviewed by Darin Adler. - - Better fix - we now never call SourceProvider::asID() if SourceProvider* is 0. - - * parser/Nodes.h: - (JSC::ScopeNode::sourceID): - * parser/SourceCode.h: - (JSC::SourceCode::providerID): - (SourceCode): - * parser/SourceProvider.h: - (SourceProvider): - (JSC::SourceProvider::asID): - * runtime/Executable.h: - (JSC::ScriptExecutable::sourceID): - -2012-05-30 Filip Pizlo <fpizlo@apple.com> - - ScriptDebugServer wants sourceIDs that are non-zero because that's what HashMaps want, so JSC should placate it - https://bugs.webkit.org/show_bug.cgi?id=87887 - - Reviewed by Geoffrey Garen. - - * parser/SourceProvider.h: - (JSC::SourceProvider::asID): - -2012-05-30 Oliver Hunt <oliver@apple.com> - - DFG does not correctly handle exceptions caught in the LLInt - https://bugs.webkit.org/show_bug.cgi?id=87885 - - Reviewed by Filip Pizlo. - - Make the DFG use genericThrow, rather than reimplementing a small portion of it. - Also make the LLInt slow paths validate that their PC is correct. - - * dfg/DFGOperations.cpp: - * llint/LLIntSlowPaths.cpp: - (LLInt): - -2012-05-29 Filip Pizlo <fpizlo@apple.com> - - DFG CFA should infer types and values of captured variables - https://bugs.webkit.org/show_bug.cgi?id=87813 - - Reviewed by Gavin Barraclough. - - Slight speed-up in V8/earley-boyer (~1%). - - * bytecode/CodeBlock.h: - (JSC::CodeBlock::argumentsAreCaptured): - (JSC::CodeBlock::argumentIsCaptured): - (CodeBlock): - * dfg/DFGAbstractState.cpp: - (DFG): - (JSC::DFG::AbstractState::beginBasicBlock): - (JSC::DFG::AbstractState::initialize): - (JSC::DFG::AbstractState::endBasicBlock): - (JSC::DFG::AbstractState::execute): - (JSC::DFG::AbstractState::clobberWorld): - (JSC::DFG::AbstractState::clobberStructures): - (JSC::DFG::AbstractState::mergeStateAtTail): - (JSC::DFG::AbstractState::merge): - (JSC::DFG::AbstractState::mergeToSuccessors): - * dfg/DFGAbstractState.h: - (JSC::DFG::AbstractState::variables): - (AbstractState): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-05-30 Patrick Gansterer <paroga@webkit.org> - - Unreviewed. Build fix for !ENABLE(JIT) after r117823. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - -2012-05-30 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r118868. - http://trac.webkit.org/changeset/118868 - https://bugs.webkit.org/show_bug.cgi?id=87828 - - introduced ~20 crashes on Mac and Qt bots (Requested by pizlo_ - on #webkit). - - * heap/Heap.cpp: - (JSC::Heap::collect): - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::sweep): - * heap/MarkedBlock.h: - (JSC::MarkedBlock::sweepWeakSet): - (JSC): - * heap/MarkedSpace.cpp: - (JSC::SweepWeakSet::operator()): - (JSC): - (JSC::MarkedSpace::sweepWeakSets): - * heap/MarkedSpace.h: - (MarkedSpace): - -2012-05-29 Geoffrey Garen <ggaren@apple.com> - - Rolled back in r118646, now that - https://bugs.webkit.org/show_bug.cgi?id=87784 is fixed. - - http://trac.webkit.org/changeset/118646 - https://bugs.webkit.org/show_bug.cgi?id=87599 - - * heap/Heap.cpp: - (JSC::Heap::collect): - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::sweep): - * heap/MarkedBlock.h: - (JSC): - * heap/MarkedSpace.cpp: - (JSC): - * heap/MarkedSpace.h: - (MarkedSpace): - -2012-05-29 Filip Pizlo <fpizlo@apple.com> - - DFG should keep captured variables alive until the (inline) return. - https://bugs.webkit.org/show_bug.cgi?id=87205 - - Reviewed by Gavin Barraclough. - - Changes the way we do flushing for captured variables and arguments. Instead of flushing - each SetLocal immediately, we flush at kill points. So a SetLocal will cause a Flush of - whatever was live in the variable previously, and a return will cause a Flush of all - captured variables and all arguments. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::setDirect): - (JSC::DFG::ByteCodeParser::set): - (JSC::DFG::ByteCodeParser::setLocal): - (JSC::DFG::ByteCodeParser::getArgument): - (JSC::DFG::ByteCodeParser::setArgument): - (JSC::DFG::ByteCodeParser::findArgumentPositionForArgument): - (ByteCodeParser): - (JSC::DFG::ByteCodeParser::findArgumentPositionForLocal): - (JSC::DFG::ByteCodeParser::findArgumentPosition): - (JSC::DFG::ByteCodeParser::flush): - (JSC::DFG::ByteCodeParser::flushDirect): - (JSC::DFG::ByteCodeParser::flushArgumentsAndCapturedVariables): - (JSC::DFG::ByteCodeParser::handleInlining): - (JSC::DFG::ByteCodeParser::parseBlock): - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::setLocalStoreElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): - -2012-05-29 Geoffrey Garen <ggaren@apple.com> - - WeakGCMap should be lazy-finalization-safe - https://bugs.webkit.org/show_bug.cgi?id=87784 - - Reviewed by Darin Adler. - - * runtime/WeakGCMap.h: - (JSC::WeakGCMap::get): Since this is a map of raw WeakImpl pointers, and - not Weak<T>, we need to verify manually that the WeakImpl is live before - we return its payload. - -2012-05-29 Mark Hahnenberg <mhahnenberg@apple.com> - - CopiedSpace::doneCopying could start another collection - https://bugs.webkit.org/show_bug.cgi?id=86538 - - Reviewed by Geoffrey Garen. - - It's possible that if we don't have anything at the head of to-space - after a collection and the BlockAllocator doesn't have any fresh blocks - to give us right now we could start another collection while still in - the middle of the first collection when we call CopiedSpace::addNewBlock(). - - One way to resolve this would be to have Heap::shouldCollect() check that - m_operationInProgress is NoOperation. This would prevent the path in - getFreshBlock() that starts the collection if we're already in the middle of one. - - I could not come up with a test case to reproduce this crash on ToT. - - * heap/Heap.h: - (JSC::Heap::shouldCollect): We shouldn't collect if we're already in the middle - of a collection, i.e. the current operation should be NoOperation. - -2012-05-29 David Barr <davidbarr@chromium.org> - - Introduce ENABLE_CSS_IMAGE_RESOLUTION compile flag - https://bugs.webkit.org/show_bug.cgi?id=87685 - - Reviewed by Eric Seidel. - - Add a configuration option for CSS image-resolution support, disabling it by default. - - * Configurations/FeatureDefines.xcconfig: - -2012-05-28 Sheriff Bot <webkit.review.bot@gmail.com> - - Unreviewed, rolling out r118646. - http://trac.webkit.org/changeset/118646 - https://bugs.webkit.org/show_bug.cgi?id=87691 - - broke V8 raytrace benchmark (Requested by pizlo_ on #webkit). - - * heap/Heap.cpp: - (JSC::Heap::collect): - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::sweep): - * heap/MarkedBlock.h: - (JSC::MarkedBlock::sweepWeakSet): - (JSC): - * heap/MarkedSpace.cpp: - (JSC::SweepWeakSet::operator()): - (JSC): - (JSC::MarkedSpace::sweepWeakSets): - * heap/MarkedSpace.h: - (MarkedSpace): - -2012-05-28 Filip Pizlo <fpizlo@apple.com> - - DFG should not generate code for code that the CFA proves to be unreachable - https://bugs.webkit.org/show_bug.cgi?id=87682 - - Reviewed by Sam Weinig. - - This also fixes a small performance bug where CFA was not marking blocks - as having constants (and hence not triggering constant folding) if the only - constants were on GetLocals. - - And fixing that bug revealed another bug: constant folding was assuming that - a GetLocal must be the first access to a local in a basic block. This isn't - true. The first access may be a Flush. This patch fixes that issue using the - safest approach possible, since we don't need to be clever for something that - only happens in one of our benchmarks. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::run): - * dfg/DFGJITCompiler.h: - (JSC::DFG::JITCompiler::noticeOSREntry): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-05-28 Carlos Garcia Campos <cgarcia@igalia.com> - - Unreviewed. Fix make distcheck. - - * GNUmakefile.list.am: Add missing header file. - -2012-05-27 Geoffrey Garen <ggaren@apple.com> - - Weak pointer finalization should be lazy - https://bugs.webkit.org/show_bug.cgi?id=87599 - - Reviewed by Darin Adler. - - * heap/Heap.cpp: - (JSC::Heap::collect): Don't force immediate finalization -- it will - happen lazily. - - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::sweep): Sweep a block's weak set when sweeping the - block. The weak set may not have been swept yet, and this is our last - chance to run weak finalizers before we recycle the memory they reference. - - * heap/MarkedBlock.h: - * heap/MarkedSpace.cpp: - (JSC::MarkedBlock::sweepWeakSets): - * heap/MarkedSpace.h: - (JSC::MarkedSpace::sweepWeakSets): Nixed sweepWeakSets because it's unused - now. - -2012-05-26 Geoffrey Garen <ggaren@apple.com> - - WebKit should be lazy-finalization-safe (esp. the DOM) v2 - https://bugs.webkit.org/show_bug.cgi?id=87581 - - Reviewed by Oliver Hunt. - - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::callDestructor): - * heap/WeakBlock.h: - * heap/WeakSetInlines.h: - (JSC::WeakBlock::finalize): Since we don't guarantee destruction order, - it's not valid to access GC pointers like the Structure pointer during - finalization. We NULL out the structure pointer in debug builds to try - to make this programming mistake more obvious. - - * API/JSCallbackConstructor.cpp: - (JSC::JSCallbackConstructor::destroy): - * API/JSCallbackObject.cpp: - (JSC::::destroy): - (JSC::JSCallbackObjectData::finalize): - * runtime/Arguments.cpp: - (JSC::Arguments::destroy): - * runtime/DateInstance.cpp: - (JSC::DateInstance::destroy): - * runtime/Error.cpp: - (JSC::StrictModeTypeErrorFunction::destroy): - * runtime/Executable.cpp: - (JSC::ExecutableBase::destroy): - (JSC::NativeExecutable::destroy): - (JSC::ScriptExecutable::destroy): - (JSC::EvalExecutable::destroy): - (JSC::ProgramExecutable::destroy): - (JSC::FunctionExecutable::destroy): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::destroy): - * runtime/JSPropertyNameIterator.cpp: - (JSC::JSPropertyNameIterator::destroy): - * runtime/JSStaticScopeObject.cpp: - (JSC::JSStaticScopeObject::destroy): - * runtime/JSString.cpp: - (JSC::JSString::destroy): - * runtime/JSVariableObject.cpp: - (JSC::JSVariableObject::destroy): - * runtime/NameInstance.cpp: - (JSC::NameInstance::destroy): - * runtime/RegExp.cpp: - (JSC::RegExp::destroy): - * runtime/RegExpConstructor.cpp: - (JSC::RegExpConstructor::destroy): - * runtime/Structure.cpp: - (JSC::Structure::destroy): - * runtime/StructureChain.cpp: - (JSC::StructureChain::destroy): Use static_cast instead of jsCast because - jsCast does Structure-based validation, and our Structure is not guaranteed - to be alive when we get finalized. - -2012-05-22 Filip Pizlo <fpizlo@apple.com> - - DFG CSE should eliminate redundant WeakJSConstants - https://bugs.webkit.org/show_bug.cgi?id=87179 - - Reviewed by Gavin Barraclough. - - Merged r118141 from dfgopt. - - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::weakConstantCSE): - (CSEPhase): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGNode.h: - (JSC::DFG::Node::weakConstant): - -2012-05-22 Filip Pizlo <fpizlo@apple.com> - - DFG CSE should do redundant store elimination - https://bugs.webkit.org/show_bug.cgi?id=87161 - - Reviewed by Oliver Hunt. - - Merge r118138 from dfgopt. - - This patch adds redundant store elimination. For example, consider this - code: - - o.x = 42; - o.x = 84; - - If o.x is speculated to be a well-behaved field, the first assignment is - unnecessary, since the second just overwrites it. We would like to - eliminate the first assignment in these cases. The need for this - optimization arises mostly from stores that our runtime requires. For - example: - - o = {f:1, g:2, h:3}; - - This will have four assignments to the structure for the newly created - object - one assignment for the empty structure, one for {f}, one for - {f, g}, and one for {f, g, h}. We would like to only have the last of - those assigments in this case. - - Intriguingly, doing so for captured variables breaks the way arguments - simplification used to work. Consider that prior to either arguments - simplification or store elimination we will have IR that looks like: - - a: SetLocal(r0, Empty) - b: SetLocal(r1, Empty) - c: GetLocal(r0) - d: CreateArguments(@c) - e: SetLocal(r0, @d) - f: SetLocal(r1, @d) - - Then redundant store elimination will eliminate the stores that - initialize the arguments registers to Empty, but then arguments - simplification eliminates the stores that initialize the arguments to - the newly created arguments - and at this point we no longer have any - stores to the arguments register, leading to hilarious crashes. This - patch therefore changes arguments simplification to replace - CreateArguments with JSConstant(Empty) rather than eliminating the - SetLocals. But this revealed bugs where arguments simplification was - being overzealous, so I fixed those bugs. - - This is a minor speed-up on V8/early and a handful of other tests. - - * bytecode/CodeBlock.h: - (JSC::CodeBlock::uncheckedActivationRegister): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): - (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUses): - (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::globalVarStoreElimination): - (CSEPhase): - (JSC::DFG::CSEPhase::putStructureStoreElimination): - (JSC::DFG::CSEPhase::putByOffsetStoreElimination): - (JSC::DFG::CSEPhase::setLocalStoreElimination): - (JSC::DFG::CSEPhase::setReplacement): - (JSC::DFG::CSEPhase::eliminate): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::uncheckedActivationRegisterFor): - (Graph): - * dfg/DFGNode.h: - (JSC::DFG::Node::isPhantomArguments): - (Node): - (JSC::DFG::Node::hasConstant): - (JSC::DFG::Node::valueOfJSConstant): - (JSC::DFG::Node::hasStructureTransitionData): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-05-21 Filip Pizlo <fpizlo@apple.com> - - DFG ConvertThis should just be a CheckStructure if the structure is known - https://bugs.webkit.org/show_bug.cgi?id=87057 - - Reviewed by Gavin Barraclough. - - Merged r118021 from dfgopt. - - This gives ValueProfile the ability to track singleton values - i.e. profiling - sites that always see the same value. - - That is then used to profile the structure in op_convert_this. - - This is then used to optimize op_convert_this into a CheckStructure if the - structure is always the same. - - That then results in better CSE in inlined code that uses 'this', since - previously we couldn't CSE accesses on 'this' from different inline call frames. - - Also fixed a bug where we were unnecessarily flushing 'this'. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::dump): - (JSC::CodeBlock::stronglyVisitStrongReferences): - * bytecode/LazyOperandValueProfile.cpp: - (JSC::CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions): - * bytecode/LazyOperandValueProfile.h: - (CompressedLazyOperandValueProfileHolder): - * bytecode/Opcode.h: - (JSC): - (JSC::padOpcodeName): - * bytecode/ValueProfile.h: - (JSC::ValueProfileBase::ValueProfileBase): - (JSC::ValueProfileBase::dump): - (JSC::ValueProfileBase::computeUpdatedPrediction): - (ValueProfileBase): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::BytecodeGenerator): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::setArgument): - (JSC::DFG::ByteCodeParser::parseBlock): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_convert_this): - (JSC::JIT::emitSlow_op_convert_this): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_convert_this): - (JSC::JIT::emitSlow_op_convert_this): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - * runtime/JSValue.h: - (JSValue): - * runtime/Structure.h: - (JSC::JSValue::structureOrUndefined): - (JSC): - -2012-05-24 Tim Horton <timothy_horton@apple.com> - - Add feature defines for web-facing parts of CSS Regions and Exclusions - https://bugs.webkit.org/show_bug.cgi?id=87442 - <rdar://problem/10887709> - - Reviewed by Dan Bernstein. - - * Configurations/FeatureDefines.xcconfig: - -2012-05-24 Geoffrey Garen <ggaren@apple.com> - - WebKit should be lazy-finalization-safe (esp. the DOM) - https://bugs.webkit.org/show_bug.cgi?id=87456 - - Reviewed by Filip Pizlo. - - Lazy finalization adds one twist to weak pointer use: - - A HashMap of weak pointers may contain logically null entries. - (Weak pointers behave as-if null once their payloads die.) - Insertion must not assume that a pre-existing entry is - necessarily valid, and iteration must not assume that all - entries can be dereferenced. - - (Previously, I thought that it also added a second twist: - - A demand-allocated weak pointer may replace a dead payload - before the payload's finalizer runs. In that case, when the - payload's finalizer runs, the payload has already been - overwritten, and the finalizer should not clear the payload, - which now points to something new. - - But that's not the case here, since we cancel the old payload's - finalizer when we over-write it. I've added ASSERTs to verify this - assumption, in case it ever changes.) - - * API/JSClassRef.cpp: - (OpaqueJSClass::prototype): No need to specify null; that's the default. - - * API/JSWeakObjectMapRefPrivate.cpp: Use remove, since take() is gone. - - * heap/PassWeak.h: - (WeakImplAccessor::was): This is no longer a debug-only function, since - it's required to reason about lazily finalized pointers. - - * heap/Weak.h: - (JSC::weakAdd): - (JSC::weakRemove): - (JSC::weakClear): Added these helper functions for the common idioms of - what clients want to do in their weak pointer finalizers. - - * jit/JITStubs.cpp: - (JSC::JITThunks::hostFunctionStub): Use the new idioms. Otherwise, we - would return NULL for a "zombie" executable weak pointer that was waiting - for finalization (item (2)), and finalizing a dead executable weak pointer - would potentially destroy a new, live one (item (1)). - - * runtime/RegExpCache.cpp: - (JSC::RegExpCache::lookupOrCreate): - (JSC::RegExpCache::finalize): Ditto. - - (JSC::RegExpCache::invalidateCode): Check for null while iterating. (See - item (2).) - - * runtime/Structure.cpp: - (JSC::StructureTransitionTable::contains): - (JSC::StructureTransitionTable::add): Use get and set instead of add and - contains, since add and contains are not compatible with lazy finalization. - - * runtime/WeakGCMap.h: - (WeakGCMap): - (JSC::WeakGCMap::clear): - (JSC::WeakGCMap::remove): Removed a bunch of code that was incompatible with - lazy finalization because I didn't feel like making it compatible, and I had - no way to test it. - -2012-05-24 Filip Pizlo <fpizlo@apple.com> - - REGRESSION (r118013-r118031): Loops/Reloads under www.yahoo.com, quits after three tries with error - https://bugs.webkit.org/show_bug.cgi?id=87327 - - Reviewed by Geoffrey Garen. - - If you use AbstractValue::filter(StructureSet) to test subset relationships between TOP and a - set containing >=2 elements, you're going to have a bad time. - - That's because AbstractValue considers a set with >=2 elements to be equivalent to TOP, in order - to save space and speed up convergence. So filtering has no effect in this case, which made - the code think that the abstract value was proving that the structure check was unnecessary. - The correct thing to do is to use isSubsetOf() on the StructureAbstractValue, which does the - right thingies for TOP and >=2 elements. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-05-24 Filip Pizlo <fpizlo@apple.com> - - new test fast/js/dfg-arguments-mixed-alias.html fails on JSVALUE32_64 - https://bugs.webkit.org/show_bug.cgi?id=87378 - - Reviewed by Gavin Barraclough. - - - Captured variable tracking forgot did not consistently handle arguments, leading to OSR - badness. - - - Nodes capable of exiting were tracked in a non-monotonic way, leading to compiler errors. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::CSEPhase): - (CSEPhase): - (JSC::DFG::performCSE): - * dfg/DFGCSEPhase.h: - (DFG): - * dfg/DFGCommon.h: - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::resetExitStates): - (DFG): - * dfg/DFGGraph.h: - (Graph): - * dfg/DFGPhase.h: - (DFG): - (JSC::DFG::runPhase): - -2012-05-24 Geoffrey Garen <ggaren@apple.com> - - Made WeakSet per-block instead of per-heap - https://bugs.webkit.org/show_bug.cgi?id=87401 - - Reviewed by Oliver Hunt. - - This allows us fast access to the set of all weak pointers for a block, - which is a step toward lazy finalization. - - No performance change. - - * heap/Heap.cpp: - (JSC::Heap::Heap): - (JSC::Heap::lastChanceToFinalize): Removed the per-heap weak set, since - it's per-block now. - - (JSC::Heap::markRoots): Delegate weak set visiting to the marked space, - since it knows how to iterate all blocks. - - (JSC::Heap::collect): Moved the reaping outside of markRoots, since it - doesn't mark anything. - - Make sure to reset allocators after shrinking, since shrinking may - deallocate the current allocator. - - * heap/Heap.h: - (Heap): No more per-heap weak set, since it's per-block now. - - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::MarkedBlock): - * heap/MarkedBlock.h: - (MarkedBlock): - (JSC::MarkedBlock::lastChanceToFinalize): Migrated finalization logic - here from the heap, so the heap doesn't need to know about our internal - data structures like our weak set. - - (JSC::MarkedBlock::heap): - (JSC::MarkedBlock::weakSet): - (JSC::MarkedBlock::shrink): - (JSC::MarkedBlock::resetAllocator): - (JSC::MarkedBlock::visitWeakSet): - (JSC::MarkedBlock::reapWeakSet): - (JSC::MarkedBlock::sweepWeakSet): - * heap/MarkedSpace.cpp: - (JSC::VisitWeakSet::VisitWeakSet): - (JSC::VisitWeakSet::operator()): - (VisitWeakSet): + (JSC::JSGlobalObject::createRareDataIfNeeded): Since we always create a finalizer now, we don't have to worry about adding one + for the m_rareData field when it's created. + (JSC::JSGlobalObject::create): (JSC): - (JSC::ReapWeakSet::operator()): - (JSC::SweepWeakSet::operator()): - (JSC::LastChanceToFinalize::operator()): - (JSC::MarkedSpace::lastChanceToFinalize): - (JSC::ResetAllocator::operator()): - (JSC::MarkedSpace::resetAllocators): - (JSC::MarkedSpace::visitWeakSets): - (JSC::MarkedSpace::reapWeakSets): - (JSC::MarkedSpace::sweepWeakSets): - (JSC::Shrink::operator()): - (JSC::MarkedSpace::shrink): - * heap/MarkedSpace.h: - (MarkedSpace): Make sure to account for our weak sets when sweeping, - shrinking, etc. - - * heap/WeakSet.cpp: + * runtime/JSGlobalThis.h: Inherit from JSDestructibleObject. + (JSGlobalThis): + (JSC::JSGlobalThis::JSGlobalThis): + * runtime/JSPropertyNameIterator.h: Has an immortal Structure. (JSC): - * heap/WeakSet.h: - (WeakSet): - (JSC::WeakSet::heap): + * runtime/JSScope.cpp: (JSC): - (JSC::WeakSet::lastChanceToFinalize): - (JSC::WeakSet::visit): - (JSC::WeakSet::reap): - (JSC::WeakSet::shrink): - (JSC::WeakSet::resetAllocator): Inlined some things since they're called - once per block now instead of once per heap. - - * heap/WeakSetInlines.h: - (JSC::WeakSet::allocate): Use the per-block weak set since there is no - per-heap weak set anymore. - -2012-05-24 Gavin Barraclough <barraclough@apple.com> - - Fix arm build - - Rubber stamped by Geoff Garen - - * dfg/DFGGPRInfo.h: - (GPRInfo): - -2012-05-24 Gavin Barraclough <barraclough@apple.com> - - Move cacheFlush from ExecutableAllocator to Assembler classes - https://bugs.webkit.org/show_bug.cgi?id=87420 - - Reviewed by Oliver Hunt. - - Makes more sense there, & remove a pile of #ifdefs. - - * assembler/ARMAssembler.cpp: + * runtime/JSString.h: Has an immortal Structure. (JSC): - (JSC::ARMAssembler::cacheFlush): - * assembler/ARMAssembler.h: - (ARMAssembler): - (JSC::ARMAssembler::cacheFlush): - * assembler/ARMv7Assembler.h: - (JSC::ARMv7Assembler::relinkJump): - (JSC::ARMv7Assembler::cacheFlush): - (ARMv7Assembler): - (JSC::ARMv7Assembler::setInt32): - (JSC::ARMv7Assembler::setUInt7ForLoad): - * assembler/AbstractMacroAssembler.h: - (JSC::AbstractMacroAssembler::cacheFlush): - * assembler/LinkBuffer.h: - (JSC::LinkBuffer::performFinalization): - * assembler/MIPSAssembler.h: - (JSC::MIPSAssembler::relinkJump): - (JSC::MIPSAssembler::relinkCall): - (JSC::MIPSAssembler::repatchInt32): - (JSC::MIPSAssembler::cacheFlush): - (MIPSAssembler): - * assembler/SH4Assembler.h: - (JSC::SH4Assembler::repatchCompact): - (JSC::SH4Assembler::cacheFlush): - (SH4Assembler): - * assembler/X86Assembler.h: - (X86Assembler): - (JSC::X86Assembler::cacheFlush): - * jit/ExecutableAllocator.cpp: + * runtime/JSWrapperObject.h: Inherit from JSDestructibleObject. + (JSWrapperObject): + (JSC::JSWrapperObject::JSWrapperObject): + * runtime/MathObject.cpp: Cleaning up some of the inheritance stuff. (JSC): - * jit/ExecutableAllocator.h: - (ExecutableAllocator): - -2012-05-24 John Mellor <johnme@chromium.org> - - Font Boosting: Add compile flag and runtime setting - https://bugs.webkit.org/show_bug.cgi?id=87394 - - Reviewed by Adam Barth. - - Add ENABLE_FONT_BOOSTING. - - * Configurations/FeatureDefines.xcconfig: - -2012-05-24 Allan Sandfeld Jensen <allan.jensen@nokia.com> - - cti_vm_throw gets kicked out by gcc 4.6 -flto - https://bugs.webkit.org/show_bug.cgi?id=56088 - - Reviewed by Darin Adler. - - Add REFERENCED_FROM_ASM to functions only referenced from assembler. - - * dfg/DFGOperations.cpp: - * jit/HostCallReturnValue.h: - * jit/JITStubs.h: - * jit/ThunkGenerators.cpp: - -2012-05-24 Filip Pizlo <fpizlo@apple.com> - - Incorrect merge of r117542 from dfg opt branch in r118323 is leading to fast/js/dfg-arguments-osr-exit.html failing - https://bugs.webkit.org/show_bug.cgi?id=87350 - - Reviewed by Maciej Stachowiak. - - The dfgopt branch introduced the notion of a local variable being killed because it was aliased - to the Arguments object as in cases like: - - var a = arguments; - return a.length; - - This required changes to OSR exit handling - if the variable is dead but aliased to arguments, then - OSR exit should reify the arguments. But meanwhile, in tip of tree we introduced special handling for - dead variables on OSR exit. When the two were merged in r118323, the structure of the if/else branches - ended up being such that we would treat dead arguments variables as totally dead as opposed to treating - them as variables that need arguments reification. - - This fixes the structure of the relevant if/else block so that variables that are dead-but-arguments - end up being treated as reified arguments objects, while variables that are dead but not aliased to - arguments are treated as tip of tree would have treated them (initialize to Undefined). - - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-05-24 Csaba Osztrogonác <ossy@webkit.org> - - Unreviewed 32 bit buildfix after r118325. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): Use ASSERT_UNUSED instead ASSERT. - -2012-05-23 Filip Pizlo <fpizlo@apple.com> - - DFG operationTearOffActivation should return after handling the null activation case - https://bugs.webkit.org/show_bug.cgi?id=87348 - <rdar://problem/11522295> - - Reviewed by Oliver Hunt. - - * dfg/DFGOperations.cpp: - -2012-05-23 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, merge the arguments fix in r118138 to get bots green. - - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): - -2012-05-20 Filip Pizlo <fpizlo@apple.com> - - DFG CFA should record if a node can OSR exit - https://bugs.webkit.org/show_bug.cgi?id=86905 - - Reviewed by Oliver Hunt. - - Merged r117931 from dfgopt. - - Adds a NodeFlag that denotes nodes that are known to not have OSR exits. - This ought to aid any backwards analyses that need to know when a - backward flow merge might happen due to a side exit. - - Also added assertions into speculationCheck() that ensure that we did not - mark a node as non-exiting and then promptly compile in an exit. This - helped catch some minor bugs where we were doing unnecessary speculation - checks. - - This is a perf-neutral change. The speculation checks that this removes - were not on hot paths of major benchmarks. - - * bytecode/PredictedType.h: + * runtime/NameInstance.h: Inherit from JSDestructibleObject. + (NameInstance): + * runtime/RegExp.h: Has immortal Structure. (JSC): - (JSC::isAnyPrediction): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGAbstractState.h: - (JSC::DFG::AbstractState::speculateInt32Unary): - (AbstractState): - (JSC::DFG::AbstractState::speculateNumberUnary): - (JSC::DFG::AbstractState::speculateBooleanUnary): - (JSC::DFG::AbstractState::speculateInt32Binary): - (JSC::DFG::AbstractState::speculateNumberBinary): - * dfg/DFGNode.h: - (JSC::DFG::Node::mergeFlags): - (JSC::DFG::Node::filterFlags): - (Node): - (JSC::DFG::Node::setCanExit): - (JSC::DFG::Node::canExit): - * dfg/DFGNodeFlags.cpp: - (JSC::DFG::nodeFlagsAsString): - * dfg/DFGNodeFlags.h: - (DFG): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::SpeculativeJIT): - (JSC::DFG::SpeculativeJIT::checkArgumentTypes): - (JSC::DFG::SpeculativeJIT::compileValueToInt32): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::speculationCheck): - (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): - (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution): - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): - (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): - (JSC::DFG::SpeculativeJIT::fillSpeculateCell): - (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): - (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): - (JSC::DFG::SpeculativeJIT::fillSpeculateCell): - (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): - (JSC::DFG::SpeculativeJIT::compile): - -2012-05-20 Filip Pizlo <fpizlo@apple.com> - - DFG should not do unnecessary indirections when storing to objects - https://bugs.webkit.org/show_bug.cgi?id=86959 - - Reviewed by Oliver Hunt. - - Merged r117819 from dfgopt. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::getByOffsetLoadElimination): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-05-17 Filip Pizlo <fpizlo@apple.com> - - DFG should optimize aliased uses of the Arguments object of the current call frame - https://bugs.webkit.org/show_bug.cgi?id=86552 - - Reviewed by Geoff Garen. - - Merged r117542 and r117543 from dfgopt. - - Performs must-alias and escape analysis on uses of CreateArguments, and if - a variable is must-aliased to CreateArguments and does not escape, then we - turn all uses of that variable into direct arguments accesses. - - 36% speed-up on V8/earley leading to a 2.3% speed-up overall in V8. - - * bytecode/CodeBlock.h: - (JSC::CodeBlock::uncheckedArgumentsRegister): - * bytecode/ValueRecovery.h: - (JSC::ValueRecovery::argumentsThatWereNotCreated): - (ValueRecovery): - (JSC::ValueRecovery::dump): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGAdjacencyList.h: - (AdjacencyList): - (JSC::DFG::AdjacencyList::removeEdgeFromBag): - * dfg/DFGArgumentsSimplificationPhase.cpp: - (JSC::DFG::ArgumentsSimplificationPhase::run): - (ArgumentsSimplificationPhase): - (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): - (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUses): - (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): - (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): - (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild): - * dfg/DFGAssemblyHelpers.h: - (JSC::DFG::AssemblyHelpers::argumentsRegisterFor): - (AssemblyHelpers): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::removePotentiallyDeadPhiReference): - * dfg/DFGGPRInfo.h: - (GPRInfo): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::collectGarbage): - (DFG): - * dfg/DFGGraph.h: - (Graph): - (JSC::DFG::Graph::executableFor): - (JSC::DFG::Graph::argumentsRegisterFor): - (JSC::DFG::Graph::uncheckedArgumentsRegisterFor): - (JSC::DFG::Graph::clobbersWorld): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasHeapPrediction): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOSRExitCompiler.cpp: - * dfg/DFGOSRExitCompiler.h: - (JSC::DFG::OSRExitCompiler::OSRExitCompiler): - (OSRExitCompiler): - * dfg/DFGOSRExitCompiler32_64.cpp: - (JSC::DFG::OSRExitCompiler::compileExit): - * dfg/DFGOSRExitCompiler64.cpp: - (JSC::DFG::OSRExitCompiler::compileExit): - * dfg/DFGOperations.cpp: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::ValueSource::dump): - (JSC::DFG::SpeculativeJIT::compile): - (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): - * dfg/DFGSpeculativeJIT.h: - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGVariableAccessData.h: - (JSC::DFG::VariableAccessData::VariableAccessData): - (JSC::DFG::VariableAccessData::mergeIsArgumentsAlias): - (VariableAccessData): - (JSC::DFG::VariableAccessData::isArgumentsAlias): - * jit/JITOpcodes.cpp: - (JSC::JIT::emitSlow_op_get_argument_by_val): - -2012-05-23 Filip Pizlo <fpizlo@apple.com> - - DFGCapabilities should not try to get an arguments register from code blocks that don't have one - https://bugs.webkit.org/show_bug.cgi?id=87332 - - Reviewed by Andy Estes. - - * dfg/DFGCapabilities.h: - (JSC::DFG::canInlineOpcode): - -2012-05-23 Filip Pizlo <fpizlo@apple.com> - - DFG should have sparse conditional constant propagation - https://bugs.webkit.org/show_bug.cgi?id=86580 - - Reviewed by Oliver Hunt. - - Merged r117370 from dfgopt. - - This enhances CFA so that if it suspects at any point during the fixpoint that a - branch will only go one way, then it only propagates in that one way. - - This vastly increases the opportunities for CFG simplification. For example, it - enables us to evaporate this loop: - - for (var i = 0; i < 1; ++i) doThings(i); - - As a result, it uncovered loads of bugs in the CFG simplifier. In particular: - - - Phi fixup was assuming that all Phis worth fixing up are shouldGenerate(). - That's not true; we also fixup Phis that are dead. - - - GetLocal fixup was assuming that it's only necessary to rewire links to a - GetLocal, and that the GetLocal's own links don't need to be rewired. Untrue, - because the GetLocal may not be rewirable (first block has no GetLocal for r42 - but second block does have a GetLocal), in which case it will refer to a Phi - in the second block. We need it to refer to a Phi from the first block to - ensure that subsequent transformations work. - - - Tail operand fixup was ignoring the fact that Phis in successors may contain - references to the children of our tail variables. Hence, successor Phi child - substitution needs to use the original second block variable table as its - prior, rather than trying to reconstruct the prior later (since by that point - the children of the second block's tail variables will have been fixed up, so - we will not know what the prior would have been). - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::beginBasicBlock): - (JSC::DFG::AbstractState::endBasicBlock): - (JSC::DFG::AbstractState::reset): - (JSC::DFG::AbstractState::execute): - (JSC::DFG::AbstractState::mergeToSuccessors): - * dfg/DFGAbstractState.h: - (JSC::DFG::AbstractState::branchDirectionToString): - (AbstractState): - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::run): - (JSC::DFG::CFGSimplificationPhase::removePotentiallyDeadPhiReference): - (JSC::DFG::CFGSimplificationPhase::OperandSubstitution::OperandSubstitution): - (OperandSubstitution): - (JSC::DFG::CFGSimplificationPhase::skipGetLocal): - (JSC::DFG::CFGSimplificationPhase::recordPossibleIncomingReference): - (CFGSimplificationPhase): - (JSC::DFG::CFGSimplificationPhase::fixTailOperand): - (JSC::DFG::CFGSimplificationPhase::mergeBlocks): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::changeEdge): - -2012-05-23 Ojan Vafai <ojan@chromium.org> - - add back the ability to disable flexbox - https://bugs.webkit.org/show_bug.cgi?id=87147 - - Reviewed by Tony Chang. - - * Configurations/FeatureDefines.xcconfig: - -2012-05-23 Filip Pizlo <fpizlo@apple.com> - - Unreviewed, fix Windows build. - - * bytecode/CodeBlock.h: - * dfg/DFGCapabilities.h: - (JSC::DFG::canCompileOpcode): - (JSC::DFG::canCompileOpcodes): - * dfg/DFGCommon.h: - (DFG): - -2012-05-23 Filip Pizlo <fpizlo@apple.com> - - DFG should optimize inlined uses of arguments.length and arguments[i] - https://bugs.webkit.org/show_bug.cgi?id=86327 - - Reviewed by Gavin Barraclough. - - Merged r117017 from dfgopt. - - Turns inlined uses of arguments.length into a constant. - - Turns inlined uses of arguments[constant] into a direct reference to the - argument. - - Big win on micro-benchmarks. Not yet a win on V8 because the hot uses of - arguments.length and arguments[i] are aliased. I'll leave the aliasing - optimizations to a later patch. - - * CMakeLists.txt: - * GNUmakefile.list.am: - * JavaScriptCore.xcodeproj/project.pbxproj: - * Target.pri: - * bytecode/DFGExitProfile.h: - (FrequentExitSite): - (JSC::DFG::FrequentExitSite::FrequentExitSite): - (JSC::DFG::QueryableExitProfile::hasExitSite): - (QueryableExitProfile): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGArgumentsSimplificationPhase.cpp: Added. - (DFG): - (ArgumentsSimplificationPhase): - (JSC::DFG::ArgumentsSimplificationPhase::ArgumentsSimplificationPhase): - (JSC::DFG::ArgumentsSimplificationPhase::run): - (JSC::DFG::performArgumentsSimplification): - * dfg/DFGArgumentsSimplificationPhase.h: Added. - (DFG): - * dfg/DFGAssemblyHelpers.cpp: - (JSC::DFG::AssemblyHelpers::executableFor): - (DFG): - * dfg/DFGAssemblyHelpers.h: - (AssemblyHelpers): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::getLocalLoadElimination): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::Graph): - (JSC::DFG::Graph::executableFor): - (Graph): - (JSC::DFG::Graph::clobbersWorld): - * dfg/DFGNode.h: - (JSC::DFG::Node::convertToConstant): - (JSC::DFG::Node::convertToGetLocalUnlinked): - (Node): - (JSC::DFG::Node::unlinkedLocal): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOSRExit.cpp: - (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-05-13 Filip Pizlo <fpizlo@apple.com> - - DFG should be able to optimize foo.apply(bar, arguments) - https://bugs.webkit.org/show_bug.cgi?id=86306 - - Reviewed by Gavin Barraclough. - - Merge r116912 from dfgopt. - - Enables compilation of op_jneq_ptr and some forms of op_call_varargs. - - Also includes a bunch of bug fixes that were made necessary by the increased - pressure on the CFG simplifier. - - This is a 1-2% win on V8. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::printCallOp): - (JSC::CodeBlock::CodeBlock): - (JSC::ProgramCodeBlock::canCompileWithDFGInternal): - (JSC::EvalCodeBlock::canCompileWithDFGInternal): - (JSC::FunctionCodeBlock::canCompileWithDFGInternal): - * bytecode/CodeBlock.h: - (CodeBlock): - (JSC::CodeBlock::canCompileWithDFG): - (JSC::CodeBlock::canCompileWithDFGState): - (ProgramCodeBlock): - (EvalCodeBlock): - (FunctionCodeBlock): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - (JSC::DFG::ByteCodeParser::processPhiStack): - (JSC::DFG::ByteCodeParser::parse): - * dfg/DFGCFGSimplificationPhase.cpp: - (JSC::DFG::CFGSimplificationPhase::run): - (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal): - (JSC::DFG::CFGSimplificationPhase::fixTailOperand): - (JSC::DFG::CFGSimplificationPhase::mergeBlocks): - * dfg/DFGCSEPhase.cpp: - (JSC::DFG::CSEPhase::getLocalLoadElimination): - (CSEPhase): - (JSC::DFG::CSEPhase::setReplacement): - (JSC::DFG::CSEPhase::performNodeCSE): - * dfg/DFGCapabilities.cpp: - (JSC::DFG::debugFail): - (DFG): - (JSC::DFG::canHandleOpcodes): - (JSC::DFG::canCompileOpcodes): - (JSC::DFG::canInlineOpcodes): - * dfg/DFGCapabilities.h: - (JSC::DFG::canCompileOpcode): - (JSC::DFG::canInlineOpcode): - (DFG): - (JSC::DFG::canCompileOpcodes): - (JSC::DFG::canCompileEval): - (JSC::DFG::canCompileProgram): - (JSC::DFG::canCompileFunctionForCall): - (JSC::DFG::canCompileFunctionForConstruct): - * dfg/DFGCommon.h: - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dump): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::emitCall): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGValidate.cpp: - (Validate): - (JSC::DFG::Validate::validate): - (JSC::DFG::Validate::checkOperand): - (JSC::DFG::Validate::reportValidationContext): - * jit/JIT.cpp: - (JSC::JIT::emitOptimizationCheck): - (JSC::JIT::privateCompileSlowCases): - (JSC::JIT::privateCompile): - * jit/JIT.h: - * jit/JITArithmetic.cpp: - (JSC::JIT::compileBinaryArithOp): - * jit/JITPropertyAccess.cpp: - (JSC::JIT::privateCompilePutByIdTransition): - * jit/JITPropertyAccess32_64.cpp: - (JSC::JIT::privateCompilePutByIdTransition): - * tools/CodeProfile.cpp: - (JSC::CodeProfile::sample): - -2012-05-23 Geoffrey Garen <ggaren@apple.com> - - Refactored WeakBlock to use malloc, clarify behavior - https://bugs.webkit.org/show_bug.cgi?id=87318 - - Reviewed by Filip Pizlo. - - We want to use malloc so we can make these smaller than 4KB, - since an individual MarkedBlock will usually have fewer than - 4KB worth of weak pointers. - - * heap/Heap.cpp: - (JSC::Heap::markRoots): Renamed visitLiveWeakImpls to visit, since - we no longer need to distinguish from "visitDeadWeakImpls". - - Renamed "visitDeadWeakImpls" to "reap" because we're not actually - doing any visiting -- we're just tagging things as dead. - - * heap/WeakBlock.cpp: - (JSC::WeakBlock::create): - (JSC::WeakBlock::destroy): - (JSC::WeakBlock::WeakBlock): Malloc! - - (JSC::WeakBlock::visit): - (JSC::WeakBlock::reap): Renamed as above. - - * heap/WeakBlock.h: - (WeakBlock): Reduced to 3KB, as explained above. - - * heap/WeakSet.cpp: - (JSC::WeakSet::visit): - (JSC::WeakSet::reap): - * heap/WeakSet.h: - (WeakSet): Updated for renames, and to match WebKit style. - -2012-05-23 Filip Pizlo <fpizlo@apple.com> - - Use after free in JSC::DFG::ByteCodeParser::processPhiStack - https://bugs.webkit.org/show_bug.cgi?id=87312 - <rdar://problem/11518848> - - Reviewed by Oliver Hunt. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::processPhiStack): - (JSC::DFG::ByteCodeParser::parse): - -2012-05-23 Filip Pizlo <fpizlo@apple.com> - - It should be possible to make C function calls from DFG code on ARM in debug mode - https://bugs.webkit.org/show_bug.cgi?id=87313 - - Reviewed by Gavin Barraclough. - - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - -2012-05-11 Filip Pizlo <fpizlo@apple.com> - - DFG should be able to inline functions that use arguments reflectively - https://bugs.webkit.org/show_bug.cgi?id=86132 - - Reviewed by Oliver Hunt. - - Merged r116838 from dfgopt. - - This turns on inlining of functions that use arguments reflectively, but it - does not do any of the obvious optimizations that this exposes. I'll save that - for another patch - the important thing for now is that this contains all of - the plumbing necessary to make this kind of inlining sound even in bizarro - cases like an inline callee escaping the arguments object to parts of the - inline caller where the arguments are otherwise dead. Or even more fun cases - like where you've inlined to an inline stack that is three-deep, and the - function on top of the inline stack reflectively accesses the arguments of a - function that is in the middle of the inline stack. Any subsequent - optimizations that we do for the obvious cases of arguments usage in inline - functions will have to take care not to break the baseline functionality that - this patch plumbs together. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::printCallOp): - (JSC::CodeBlock::dump): - * bytecode/CodeBlock.h: - * dfg/DFGAssemblyHelpers.h: - (JSC::DFG::AssemblyHelpers::argumentsRegisterFor): - (AssemblyHelpers): - * dfg/DFGByteCodeParser.cpp: - (InlineStackEntry): - (JSC::DFG::ByteCodeParser::handleCall): - (JSC::DFG::ByteCodeParser::handleInlining): - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - (JSC::DFG::ByteCodeParser::parse): - * dfg/DFGCCallHelpers.h: - (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): - (CCallHelpers): - * dfg/DFGCapabilities.h: - (JSC::DFG::canInlineOpcode): - * dfg/DFGDriver.cpp: - (JSC::DFG::compile): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * interpreter/CallFrame.cpp: + * runtime/RegExpObject.cpp: Inheritance cleanup. (JSC): - (JSC::CallFrame::someCodeBlockForPossiblyInlinedCode): - * interpreter/CallFrame.h: - (ExecState): - (JSC::ExecState::someCodeBlockForPossiblyInlinedCode): - * interpreter/Interpreter.cpp: - (JSC::Interpreter::retrieveArgumentsFromVMCode): - * runtime/Arguments.cpp: - (JSC::Arguments::tearOff): + * runtime/SparseArrayValueMap.h: Has immortal Structure. (JSC): - (JSC::Arguments::tearOffForInlineCallFrame): - * runtime/Arguments.h: - (Arguments): - (JSC::Arguments::create): - (JSC::Arguments::finishCreation): + * runtime/Structure.h: Has immortal Structure. (JSC): - -2012-05-23 Filip Pizlo <fpizlo@apple.com> - - Every OSR exit on ARM results in a crash - https://bugs.webkit.org/show_bug.cgi?id=87307 - - Reviewed by Geoffrey Garen. - - * dfg/DFGThunks.cpp: - (JSC::DFG::osrExitGenerationThunkGenerator): - -2012-05-23 Geoffrey Garen <ggaren@apple.com> - - Refactored heap tear-down to use normal value semantics (i.e., destructors) - https://bugs.webkit.org/show_bug.cgi?id=87302 - - Reviewed by Oliver Hunt. - - This is a step toward incremental DOM finalization. - - * heap/CopiedSpace.cpp: - (JSC::CopiedSpace::~CopiedSpace): - * heap/CopiedSpace.h: - (CopiedSpace): Just use our destructor, instead of relying on the heap - to send us a special message at a special time. - - * heap/Heap.cpp: - (JSC::Heap::Heap): Use OwnPtr for m_markListSet because this is not Sparta. - - (JSC::Heap::~Heap): No need for delete or freeAllBlocks because normal - destructors do this work automatically now. - - (JSC::Heap::lastChanceToFinalize): Just call lastChanceToFinalize on our - sub-objects, and assume it does the right thing. This improves encapsulation, - so we can add items requiring finalization to our sub-objects. - - * heap/Heap.h: Moved m_blockAllocator to get the right destruction order. - - * heap/MarkedSpace.cpp: - (Take): + * runtime/StructureChain.h: Ditto. (JSC): - (JSC::Take::Take): - (JSC::Take::operator()): - (JSC::Take::returnValue): Moved to the top of the file so it can be used - in another function. - - (JSC::MarkedSpace::~MarkedSpace): Delete all outstanding memory, like a good - destructor should. - - (JSC::MarkedSpace::lastChanceToFinalize): Moved some code here from the heap, - since it pertains to our internal implementation details. - - * heap/MarkedSpace.h: - (MarkedSpace): - * heap/WeakBlock.cpp: - (JSC::WeakBlock::lastChanceToFinalize): - * heap/WeakBlock.h: - (WeakBlock): - * heap/WeakSet.cpp: - (JSC::WeakSet::lastChanceToFinalize): - * heap/WeakSet.h: - (WeakSet): Stop using a special freeAllBlocks() callback and just implement - lastChanceToFinalize. - -2011-05-22 Geoffrey Garen <ggaren@apple.com> - - Encapsulated some calculations for whether portions of the heap are empty - https://bugs.webkit.org/show_bug.cgi?id=87210 - - Reviewed by Gavin Barraclough. - - This is a step toward incremental DOM finalization. - - * heap/Heap.cpp: - (JSC::Heap::~Heap): Explicitly call freeAllBlocks() instead of relying - implicitly on all blocks thinking they're empty. In future, we may - choose to tear down the heap without first setting all data structures - to "empty". - - * heap/MarkedBlock.h: - (JSC::MarkedBlock::isEmpty): - (JSC::MarkedBlock::gatherDirtyCells): Renamed markCountIsZero to isEmpty, - in preparation for making it check for outstanding finalizers in addition - to marked cells. - - * heap/MarkedSpace.cpp: - (Take): - (JSC::Take::Take): - (JSC::Take::operator()): - (JSC::Take::returnValue): - (JSC::MarkedSpace::shrink): - (JSC::MarkedSpace::freeAllBlocks): Refactored the "Take" functor to support - a conditional isEmpty check, so it dould be shared by shrink() and freeAllBlocks(). - - * heap/WeakBlock.cpp: - (JSC::WeakBlock::WeakBlock): - (JSC::WeakBlock::visitLiveWeakImpls): - (JSC::WeakBlock::visitDeadWeakImpls): - * heap/WeakBlock.h: - (WeakBlock): - (JSC::WeakBlock::isEmpty): - * heap/WeakSet.cpp: - (JSC::WeakSet::sweep): - (JSC::WeakSet::shrink): Use isEmpty(), in preparation for changes in - its implementation. - -2012-05-23 Oswald Buddenhagen <oswald.buddenhagen@nokia.com> - - [Qt] Remove references to $$QT_SOURCE_TREE - - With a modularized Qt, it's ambigious. What we really want is qtbase, - which qtcore is a proxy for (we assume it will always live in qtbase). - - Reviewed by Tor Arne Vestbø. - - * JavaScriptCore.pri: - * Target.pri: - -2012-05-09 Filip Pizlo <fpizlo@apple.com> - - DFG should allow inlining in case of certain arity mismatches - https://bugs.webkit.org/show_bug.cgi?id=86059 - - Reviewed by Geoff Garen. - - Merge r116620 from dfgopt. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleInlining): - -2012-05-08 Filip Pizlo <fpizlo@apple.com> - - DFG variable capture analysis should work even if the variables arose through inlining - https://bugs.webkit.org/show_bug.cgi?id=85945 - - Reviewed by Oliver Hunt. - - Merged r116555 from dfgopt. - - This just changes how the DFG queries whether a variable is captured. It does not - change any user-visible behavior. - - As part of this change, I further solidified the policy that the CFA behaves in an - undefined way for captured locals and queries about their values will not yield - reliable results. This will likely be changed in the future, but for now it makes - sense. - - One fun part about this change is that it recognizes that the same variable may - be both captured and not, at the same time, because their live interval spans - inlining boundaries. This only happens in the case of arguments to functions that - capture their arguments, and this change treats them with just the right touch of - conservatism: they will be treated as if captured by the caller as well as the - callee. - - Finally, this also adds captured variable reasoning to the InlineCallFrame, which - I thought might be useful for later tooling. - - This is perf-neutral, since it does it does not make the DFG take advantage of this - new functionality in any way. In particular, it is still the case that the DFG will - not inline functions that use arguments reflectively or that create activations. - - * bytecode/CodeBlock.h: - (CodeBlock): - (JSC::CodeBlock::needsActivation): - (JSC::CodeBlock::argumentIsCaptured): - (JSC::CodeBlock::localIsCaptured): - (JSC::CodeBlock::isCaptured): - * bytecode/CodeOrigin.h: - (InlineCallFrame): - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::initialize): - (JSC::DFG::AbstractState::endBasicBlock): - (JSC::DFG::AbstractState::execute): - (JSC::DFG::AbstractState::merge): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::newVariableAccessData): - (JSC::DFG::ByteCodeParser::getLocal): - (JSC::DFG::ByteCodeParser::setLocal): - (JSC::DFG::ByteCodeParser::getArgument): - (JSC::DFG::ByteCodeParser::setArgument): - (JSC::DFG::ByteCodeParser::flushArgument): - (JSC::DFG::ByteCodeParser::parseBlock): - (JSC::DFG::ByteCodeParser::processPhiStack): - (JSC::DFG::ByteCodeParser::fixVariableAccessPredictions): - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - * dfg/DFGCFGSimplificationPhase.cpp: - (CFGSimplificationPhase): - (JSC::DFG::CFGSimplificationPhase::keepOperandAlive): - (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal): - (JSC::DFG::CFGSimplificationPhase::fixTailOperand): - * dfg/DFGCommon.h: - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::nameOfVariableAccessData): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::needsActivation): - (JSC::DFG::Graph::usesArguments): - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGVariableAccessData.h: - (JSC::DFG::VariableAccessData::VariableAccessData): - (JSC::DFG::VariableAccessData::mergeIsCaptured): - (VariableAccessData): - (JSC::DFG::VariableAccessData::isCaptured): - -2012-05-08 Filip Pizlo <fpizlo@apple.com> - - DFG should support op_get_argument_by_val and op_get_arguments_length - https://bugs.webkit.org/show_bug.cgi?id=85911 - - Reviewed by Oliver Hunt. - - Merged r116467 from dfgopt. - - This adds a simple and relatively conservative implementation of op_get_argument_by_val - and op_get_arguments_length. We can optimize these later. For now it's great to have - the additional coverage. - - This patch appears to be perf-neutral. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGAssemblyHelpers.h: - (JSC::DFG::AssemblyHelpers::addressFor): - (JSC::DFG::AssemblyHelpers::tagFor): - (JSC::DFG::AssemblyHelpers::payloadFor): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCapabilities.h: - (JSC::DFG::canCompileOpcode): - (JSC::DFG::canInlineOpcode): - * dfg/DFGNode.h: - (JSC::DFG::Node::hasHeapPrediction): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::callOperation): - (SpeculativeJIT): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_get_argument_by_val): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_get_argument_by_val): - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2012-05-07 Filip Pizlo <fpizlo@apple.com> - - DFG should support op_tear_off_arguments - https://bugs.webkit.org/show_bug.cgi?id=85847 - - Reviewed by Michael Saboff. - - Merged r116378 from dfgopt. - - * dfg/DFGAbstractState.cpp: - (JSC::DFG::AbstractState::execute): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCapabilities.h: - (JSC::DFG::canCompileOpcode): - (JSC::DFG::canInlineOpcode): - * dfg/DFGNodeType.h: - (DFG): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - (JSC::DFG::PredictionPropagationPhase::propagate): - * dfg/DFGSpeculativeJIT.h: - (SpeculativeJIT): - (JSC::DFG::SpeculativeJIT::callOperation): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - -2012-05-22 Mark Hahnenberg <mhahnenberg@apple.com> - - CopiedSpace::contains doesn't check for oversize blocks - https://bugs.webkit.org/show_bug.cgi?id=87180 - - Reviewed by Geoffrey Garen. - - When doing a conservative scan we use CopiedSpace::contains to determine if a particular - address points into the CopiedSpace. Currently contains() only checks if the address - points to a block in to-space, which means that pointers to oversize blocks may not get scanned. - - * heap/CopiedSpace.cpp: - (JSC::CopiedSpace::tryAllocateOversize): - (JSC::CopiedSpace::tryReallocateOversize): - (JSC::CopiedSpace::doneFillingBlock): - (JSC::CopiedSpace::doneCopying): - * heap/CopiedSpace.h: Refactored CopiedSpace so that all blocks (oversize and to-space) are - in a single hash set and bloom filter for membership testing. - (CopiedSpace): - * heap/CopiedSpaceInlineMethods.h: - (JSC::CopiedSpace::contains): We check for the normal block first. Since the oversize blocks are - only page aligned, rather than block aligned, we have to re-mask the ptr to check if it's in - CopiedSpace. Also added a helper function of the same name that takes a CopiedBlock* and checks - if it's in CopiedSpace so that check isn't typed out twice. + * runtime/SymbolTable.h: Ditto. + (SharedSymbolTable): (JSC): - (JSC::CopiedSpace::startedCopying): - (JSC::CopiedSpace::addNewBlock): - -2012-05-22 Geoffrey Garen <ggaren@apple.com> - - CopiedBlock and MarkedBlock should have proper value semantics (i.e., destructors) - https://bugs.webkit.org/show_bug.cgi?id=87172 - - Reviewed by Oliver Hunt and Phil Pizlo. - - This enables MarkedBlock to own non-trivial sub-objects that require - destruction. It also fixes a FIXME about casting a CopiedBlock to a - MarkedBlock at destroy time. - - CopiedBlock and MarkedBlock now accept an allocation chunk at create - time and return it at destroy time. Their client is expected to - allocate, recycle, and destroy these chunks. - - * heap/BlockAllocator.cpp: - (JSC::BlockAllocator::releaseFreeBlocks): - (JSC::BlockAllocator::blockFreeingThreadMain): Don't call MarkedBlock::destroy - because we expect that to be called before a block is put on our free - list now. Do manually deallocate our allocation chunk because that's - our job now. - - * heap/BlockAllocator.h: - (BlockAllocator): - (JSC::BlockAllocator::allocate): Allocate never fails now. This is a - cleaner abstraction because only one object does all the VM allocation - and deallocation. Caching is an implementation detail. - - (JSC::BlockAllocator::deallocate): We take an allocation chunk argument - instead of a block because we now expect the block to have been destroyed - before we recycle its memory. For convenience, we still use the HeapBlock - class as our linked list node. This is OK because HeapBlock is a POD type. - - * heap/CopiedBlock.h: - (CopiedBlock): - (JSC::CopiedBlock::create): - (JSC::CopiedBlock::destroy): - (JSC::CopiedBlock::CopiedBlock): Added proper create and destroy functions, - to match MarkedBlock. - - * heap/CopiedSpace.cpp: - (JSC::CopiedSpace::tryAllocateOversize): - (JSC::CopiedSpace::tryReallocateOversize): - (JSC::CopiedSpace::doneCopying): - (JSC::CopiedSpace::getFreshBlock): - (JSC::CopiedSpace::freeAllBlocks): - * heap/CopiedSpaceInlineMethods.h: - (JSC::CopiedSpace::recycleBlock): Make sure to call destroy before - returning a block to the BlockAllocator. Otherwise, our destructors - won't run. (If we get this wrong now, we'll get a compile error.) - - * heap/HeapBlock.h: - (JSC::HeapBlock::HeapBlock): const! - - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::allocateBlock): No need to distinguish between - create and recycle -- MarkedBlock always accepts memory allocated by - its client now. - - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::create): Don't allocate memory -- we assume that we're - passed already-allocated memory, to clarify the responsibility for VM - recycling. - - (JSC::MarkedBlock::destroy): Do run our destructor before giving back - our VM -- that is the whole point of this patch. - - (JSC::MarkedBlock::MarkedBlock): - * heap/MarkedBlock.h: - (MarkedBlock): - * heap/MarkedSpace.cpp: const! - - (JSC::MarkedSpace::freeBlocks): Make sure to call destroy before - returning a block to the BlockAllocator. Otherwise, our destructors - won't run. (If we get this wrong now, we'll get a compile error.) -== Rolled over to ChangeLog-2012-05-22 == +== Rolled over to ChangeLog-2012-10-02 == diff --git a/Source/JavaScriptCore/ChangeLog-2012-10-02 b/Source/JavaScriptCore/ChangeLog-2012-10-02 new file mode 100644 index 000000000..ded22e693 --- /dev/null +++ b/Source/JavaScriptCore/ChangeLog-2012-10-02 @@ -0,0 +1,20888 @@ +2012-10-02 Filip Pizlo <fpizlo@apple.com> + + REGRESSION(r128400): ASSERT (crash in release) @ app.asana.com + https://bugs.webkit.org/show_bug.cgi?id=98175 + + Reviewed by Oliver Hunt. + + It's bad karma to create a new structure while stealing another structure's property table + while leaving the m_offset unset. Eventually someone will then steal your property table, and + then you won't know how many properties you have anymore. + + * runtime/Structure.cpp: + (JSC::Structure::nonPropertyTransition): + +2012-10-02 Michael Saboff <msaboff@apple.com> + + Comment additions after r130109 + + Rubber stamped by Geoffrey Garen. + + Updated comments to how array storage works. + + * runtime/ArrayStorage.h: + * runtime/JSArray.cpp: + +2012-10-01 Mark Hahnenberg <mhahnenberg@apple.com> + + Block freeing thread should sleep indefinitely when there's no work to do + https://bugs.webkit.org/show_bug.cgi?id=98084 + + Reviewed by Geoffrey Garen. + + Currently the block freeing thread wakes up once a second to check if there are any blocks + for it to release back to the OS. This is wasteful. We should change it to sleep when it + realizes there are no more blocks to free. Any thread that returns a block to the BlockAllocator + should then notify the block freeing thread that there is more work to do now. + + * heap/BlockAllocator.cpp: + (JSC::BlockAllocator::BlockAllocator): + (JSC::BlockAllocator::blockFreeingThreadMain): + * heap/BlockAllocator.h: + (BlockAllocator): + (JSC::BlockAllocator::deallocate): + +2012-10-01 Michael Saboff <msaboff@apple.com> + + JSArray::unshiftCountSlowCase needs to clear array slots when adding space to end of array + https://bugs.webkit.org/show_bug.cgi?id=98101 + + Reviewed by Filip Pizlo. + + Cleared new array entries when adding to end due to shifting contents to lower memory. Also + checnaged the order of moving array contents and metadata in the shift left case to avoid + clobbering the metadata with array contents. Optimized the to only make a memmove if the + count is non-zero. + + * runtime/JSArray.cpp: + (JSC::JSArray::unshiftCountSlowCase): + (JSC::JSArray::unshiftCount): + +2012-10-01 Filip Pizlo <fpizlo@apple.com> + + Address a FIXME in JSArray::sort + https://bugs.webkit.org/show_bug.cgi?id=98080 + <rdar://problem/12407844> + + Reviewed by Oliver Hunt. + + Get rid of fast sorting of sparse maps. I don't know that it's broken but I do know that we don't + have coverage for it. Then also address the FIXME in JSArray::sort regarding side-effecting + compare functions. + + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncSort): + * runtime/JSArray.cpp: + (JSC::JSArray::sortNumeric): + (JSC::JSArray::sort): + (JSC::JSArray::compactForSorting): + * runtime/JSArray.h: + (JSArray): + * runtime/JSObject.h: + (JSC::JSObject::hasSparseMap): + (JSObject): + +2012-10-01 Jonathan Liu <net147@gmail.com> + + Remove unused sys/mman.h include + https://bugs.webkit.org/show_bug.cgi?id=97995 + + Reviewed by Kentaro Hara. + + The sys/mman.h is not used and removing it improves portability as not + all systems have sys/mman.h. + + * jit/ExecutableAllocatorFixedVMPool.cpp: + +2012-09-28 Filip Pizlo <fpizlo@apple.com> + + ASSERTION in m_graph[tailNodeIndex].op() == Flush || m_graph[tailNodeIndex].op() == SetLocal on plus.google.com + https://bugs.webkit.org/show_bug.cgi?id=97656 + + Reviewed by Mark Hahnenberg. + + There were two bugs here: + + 1) In case of multiple GetLocals to the same captured variable, the bytecode parser would linke the first, + rather than the last, of the GetLocals into the vars-at-tail table. + + 2) The constant folding phase was asserting that any GetLocal it eliminates must be linked into the + vars-at-tail table, when for captured variables only the last of those should be. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::getLocal): + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::foldConstants): + +2012-09-28 Filip Pizlo <fpizlo@apple.com> + + DFGStructureHoistingPhase SetLocal assumes StructureTransitionWatchpoint has a structure set + https://bugs.webkit.org/show_bug.cgi?id=97810 + + Reviewed by Mark Hahnenberg. + + No tests because this can't happen in ToT: the structure check hoisting phase runs before any + CFA or folding, so the only StructureTransitionWatchpoints it will see are the ones inserted + by the parser. But the parser will only insert StructureTransitinWatchpoints on constants, which + will not be subject to SetLocals. + + Still, it would be good to fix this in case things changed. + + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-09-27 Mark Lam <mark.lam@apple.com> + + Put initializeHostCallReturnValue() behind #if ENABLE(JIT). + Fixes non JIT builds. + https://bugs.webkit.org/show_bug.cgi?id=97838. + + Reviewed by John Sullivan. + + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + +2012-09-27 Mark Lam <mark.lam@apple.com> + + Fixed CallFrameClosure::resetCallFrame() to use the valid + range of argument index values. + https://bugs.webkit.org/show_bug.cgi?id=97836. + + Reviewed by Gavin Barraclough. + + * interpreter/CallFrame.h: + (ExecState): + * interpreter/CallFrameClosure.h: + (JSC::CallFrameClosure::resetCallFrame): + +2012-09-27 Patrick Gansterer <paroga@webkit.org> + + Fix usage of COMPILER() macros + https://bugs.webkit.org/show_bug.cgi?id=97642 + + Reviewed by Geoffrey Garen. + + Add COMPILER(GCC) around compiler specific code and remove it from generic code. + This allows us to implement the DFG code for other compilers to in a next step. + + * dfg/DFGOperations.cpp: + * jit/HostCallReturnValue.h: + +2012-09-27 Andreas Kling <kling@webkit.org> + + 3.20MB below FunctionParameters::create() on Membuster3. + <http://webkit.org/b/97730> + + Reviewed by Anders Carlsson. + + Figure out the exact space needed for parameter identifiers and use reserveInitialCapacity(). + Reduces memory consumption on Membuster3 by ~1.60 MB. + + * parser/Nodes.cpp: + (JSC::FunctionParameters::FunctionParameters): + +2012-09-27 Csaba Osztrogonác <ossy@webkit.org>, Tor Arne Vestbø <vestbo@webkit.org> + + [Qt] Enable the LLInt on Linux + https://bugs.webkit.org/show_bug.cgi?id=95749 + + Reviewed by Simon Hausmann. + + * DerivedSources.pri: + * JavaScriptCore.pro: + * LLIntOffsetsExtractor.pro: Added. + * Target.pri: + +2012-09-27 Patrick Gansterer <paroga@webkit.org> + + [CMake] Fix build with static JavaScriptCore library + + * shell/CMakeLists.txt: Define STATICALLY_LINKED_WITH_JavaScriptCore if + JavaScriptCore_LIBRARY_TYPE is set to STATIC. + +2012-09-26 Gavin Barraclough <barraclough@apple.com> + + Proxy the global this in JSC + https://bugs.webkit.org/show_bug.cgi?id=97734 + + Reviewed by Filip Pizlo. + + Eeep – fix a bug - was leaving the global this proxy's structure's globalObject as 0, + and setting the proxy's prototype as the global object, rather than its prototype. + + * jsc.cpp: + (GlobalObject::create): + * runtime/JSProxy.h: + (JSC::JSProxy::createStructure): + +2012-09-26 Gavin Barraclough <barraclough@apple.com> + + Speculative Windows build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-09-26 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, 32-bit build fix. + + * llint/LowLevelInterpreter32_64.asm: + +2012-09-26 Filip Pizlo <fpizlo@apple.com> + + jneq_ptr shouldn't have a pointer + https://bugs.webkit.org/show_bug.cgi?id=97739 + + Reviewed by Oliver Hunt. + + Slamming pointers directly into bytecode is sometimes cool, but in this case it's + unwieldy and confusing. Switched the instruction to use an enum instead. This has + zero effect on code gen behavior in the JITs. In the LLInt, there is now more + indirection, but that doesn't affect benchmarks. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/Instruction.h: + (JSC::Instruction::Instruction): + (Instruction): + * bytecode/SpecialPointer.cpp: Added. + (JSC): + (JSC::actualPointerFor): + * bytecode/SpecialPointer.h: Added. + (JSC): + (JSC::pointerIsFunction): + (JSC::pointerIsCell): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitJumpIfNotFunctionCall): + (JSC::BytecodeGenerator::emitJumpIfNotFunctionApply): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_jneq_ptr): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_jneq_ptr): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + (JSC): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::actualPointerFor): + +2012-09-26 Gavin Barraclough <barraclough@apple.com> + + REGRESSION (r129456): http/tests/security/xss-eval.html is failing on JSC platforms + https://bugs.webkit.org/show_bug.cgi?id=97529 + + Reviewed by Filip Pizlo. + + A recent patch changed JSC's EvalError behaviour; bring this more into line with other browsers. + + JSC currently throws an EvalError if you try to call eval with a this object that doesn't + match the given eval function. This does not match other browsers, which generally just + ignore the this value that was passed, and eval the string in the eval function's environment. + + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::globalFuncEval): + - Remove EvalError, ignore passed this value. + +2012-09-26 Gavin Barraclough <barraclough@apple.com> + + Proxy the global this in JSC + https://bugs.webkit.org/show_bug.cgi?id=97734 + + Reviewed by Oliver Hunt. + + Having jsc diverge from WebCore here is not beneficial; it potentially masks bugs and/or performance + problems from command line testing. + + * jsc.cpp: + (GlobalObject::create): + - Create a this value proxy for the global object. + * runtime/JSGlobalObject.h: + (JSGlobalObject): + - Make setGlobalThis protected. + * runtime/JSProxy.h: + (JSC::JSProxy::create): + (JSC::JSProxy::target): + (JSC::JSProxy::finishCreation): + (JSProxy): + - Allow proxy target to be a JSObject, add target to create method. + +2012-09-26 Gavin Barraclough <barraclough@apple.com> + + Speculative Windows build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-09-26 Filip Pizlo <fpizlo@apple.com> + + JSObject::ensureArrayStorage() ignores the possibility that extensions have been prevented + https://bugs.webkit.org/show_bug.cgi?id=97719 + + Reviewed by Gavin Barraclough. + + * runtime/JSObject.cpp: + (JSC::JSObject::ensureArrayStorageSlow): + (JSC): + * runtime/JSObject.h: + (JSC::JSObject::ensureArrayStorage): + (JSObject): + +2012-09-26 Gavin Barraclough <barraclough@apple.com> + + Generalize JSGlobalThis as JSProxy + https://bugs.webkit.org/show_bug.cgi?id=97716 + + Reviewed by Oliver Hunt. + + Generalize JSGlobalThis as JSProxy and move proxying functionality up from the window shell into JSProxy. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::toThisObject): + - Hoist toThisObject from WebCore. + (JSC): + * runtime/JSGlobalObject.h: + - removed include. + (JSC::JSGlobalObject::finishCreation): + - JSGlobalThis -> JSObject + (JSGlobalObject): + - Hoist toThisObject from WebCore. + * runtime/JSGlobalThis.cpp: Removed. + * runtime/JSGlobalThis.h: Removed. + * runtime/JSObject.cpp: + - removed include. + * runtime/JSObject.h: + (JSObject): + (JSC::JSObject::isProxy): + - isGlobalThis -> isProxy + - GlobalThisType -> ProxyType + * runtime/JSProxy.cpp: Copied from Source/JavaScriptCore/runtime/JSGlobalThis.cpp. + (JSC): + (JSC::JSProxy::visitChildren): + (JSC::JSProxy::setTarget): + (JSC::JSProxy::className): + (JSC::JSProxy::getOwnPropertySlot): + (JSC::JSProxy::getOwnPropertySlotByIndex): + (JSC::JSProxy::getOwnPropertyDescriptor): + (JSC::JSProxy::put): + (JSC::JSProxy::putByIndex): + (JSC::JSProxy::putDirectVirtual): + (JSC::JSProxy::defineOwnProperty): + (JSC::JSProxy::deleteProperty): + (JSC::JSProxy::deletePropertyByIndex): + (JSC::JSProxy::getPropertyNames): + (JSC::JSProxy::getOwnPropertyNames): + - Class cretaed from JSGlobalThis, JSDOMWindowShell. + * runtime/JSProxy.h: Copied from Source/JavaScriptCore/runtime/JSGlobalThis.h. + (JSC::JSProxy::create): + (JSC::JSProxy::createStructure): + (JSProxy): + (JSC::JSProxy::target): + (JSC::JSProxy::JSProxy): + - Class cretaed from JSGlobalThis, JSDOMWindowShell. + * runtime/JSType.h: + - GlobalThisType -> ProxyType + +2012-09-26 Michael Saboff <msaboff@apple.com> + + Add ability for JSArray::unshiftCount to unshift in middle of an array + https://bugs.webkit.org/show_bug.cgi?id=97691 + + Reviewed by Filip Pizlo. + + Changed JSArray::unshiftCount and unshiftCountSlowCase to handle unshifting from the middle of an + array. Depending on where the unshift point is, either the front part of the array will be moved + "left" or the back part will be moved right. Given that unshiftCount only works on contiguous + arrays it is safe to use memmove for the moves. + + This change is worth 25% performance improvement on pdfjs. It doesn't seem to have any impact on + any other benchmarks. + + * runtime/ArrayPrototype.cpp: + (JSC::unshift): + * runtime/JSArray.cpp: + (JSC::JSArray::unshiftCountSlowCase): + (JSC::JSArray::unshiftCount): + * runtime/JSArray.h: + (JSArray): + +2012-09-26 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r129592. + http://trac.webkit.org/changeset/129592 + https://bugs.webkit.org/show_bug.cgi?id=97670 + + Failures in Chromium security tests (Requested by schenney on + #webkit). + + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::globalFuncEval): + +2012-09-25 Gavin Barraclough <barraclough@apple.com> + + REGRESSION (r129456): http/tests/security/xss-eval.html is failing on JSC platforms + https://bugs.webkit.org/show_bug.cgi?id=97529 + + Reviewed by Filip Pizlo. + + A recent patch changed JSC's EvalError behaviour; bring this more into line with other browsers. + + JSC currently throws an EvalError if you try to call eval with a this object that doesn't + match the given eval function. This does not match other browsers, which generally just + ignore the this value that was passed, and eval the string in the eval function's environment. + + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::globalFuncEval): + - Remove EvalError, ignore passed this value. + +2012-09-25 Filip Pizlo <fpizlo@apple.com> + + DFG ArrayPush, ArrayPop don't handle clobbering or having a bad time correctly + https://bugs.webkit.org/show_bug.cgi?id=97535 + + Reviewed by Oliver Hunt. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleIntrinsic): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-09-25 Geoffrey Garen <ggaren@apple.com> + + JSC should dump object size inference statistics + https://bugs.webkit.org/show_bug.cgi?id=97618 + + Reviewed by Filip Pizlo. + + Added an option to dump object size inference statistics. + + To see statistics on live objects: + + jsc --showHeapStatistics=1 + + To see cumulative statistics on all objects ever allocated: + + jsc --showHeapStatistics=1 --objectsAreImmortal=1 + + (This is useful for showing GC churn caused by over-allocation.) + + To support this second mode, I refactored Zombies to separate out their + immortality feature so I could reuse it. + + * heap/Heap.cpp: + (JSC::MarkObject): Helper for making things immortal. We have to checked + for being zapped because blocks start out in this state. + + (JSC::StorageStatistics): Gather statistics by walking the heap. Ignore + arrays and hash tables for now because they're not our focus. (We'll + remove these exceptions in future.) + + (JSC::Heap::collect): Moved zombify to the end so it wouldn't interfere + with statistics gathering. + + (JSC::Heap::showStatistics): + (JSC::Heap::markAllObjects): Factored out helper, so statistics could + take advantage of immortal objects. + + (Zombify): Don't mark immortal objects -- that's another class's job now. + + (JSC::Zombify::operator()): + (JSC::Heap::zombifyDeadObjects): Take advantage of forEachDeadCell instead + of rolling our own. + + * heap/Heap.h: + (Heap): + * heap/MarkedSpace.h: + (MarkedSpace): + (JSC::MarkedSpace::forEachDeadCell): Added, so clients don't have to do + the iteration logic themselves. + + * runtime/Options.cpp: + (JSC::Options::initialize): + * runtime/Options.h: New options, listed above. Make sure to initialize + based on environment variable first, so we can override with specific settings. + +2012-09-25 Filip Pizlo <fpizlo@apple.com> + + We shouldn't use the optimized versions of shift/unshift if the user is doing crazy things to the array + https://bugs.webkit.org/show_bug.cgi?id=97603 + <rdar://problem/12370864> + + Reviewed by Gavin Barraclough. + + You changed the length behind our backs? No optimizations for you then! + + * runtime/ArrayPrototype.cpp: + (JSC::shift): + (JSC::unshift): + * runtime/JSArray.cpp: + (JSC::JSArray::shiftCount): + +2012-09-25 Filip Pizlo <fpizlo@apple.com> + + JSC bindings appear to sometimes ignore the possibility of arrays being in sparse mode + https://bugs.webkit.org/show_bug.cgi?id=95610 + + Reviewed by Oliver Hunt. + + Add better support for quickly accessing the indexed storage from bindings. + + * runtime/JSObject.h: + (JSC::JSObject::tryGetIndexQuickly): + (JSObject): + (JSC::JSObject::getDirectIndex): + (JSC::JSObject::getIndex): + +2012-09-25 Filip Pizlo <fpizlo@apple.com> + + Structure check hoisting phase doesn't know about the side-effecting nature of Arrayify + https://bugs.webkit.org/show_bug.cgi?id=97537 + + Reviewed by Mark Hahnenberg. + + No tests because if we use Arrayify then we also use PutByVal(BlankToXYZ), and the latter is + already known to be side-effecting. So this bug shouldn't have had any symptoms, as far as I + can tell. + + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-09-25 Gavin Barraclough <barraclough@apple.com> + + Regression: put beyond vector length prefers prototype setters to sparse properties + https://bugs.webkit.org/show_bug.cgi?id=97593 + + Reviewed by Geoff Garen & Filip Pizlo. + + * runtime/JSObject.cpp: + (JSC::JSObject::putByIndexBeyondVectorLength): + - Check for self properties in the sparse map - if present, don't examine the protochain. + +2012-09-24 Gavin Barraclough <barraclough@apple.com> + + https://bugs.webkit.org/show_bug.cgi?id=97530 + Regression, freeze applied to numeric properties of non-array objects + + Reviewed by Filip Pizlo. + + Object.freeze has a fast implementation in JSObject, but this hasn't been updated to take into account numeric properties in butterflies. + For now, just fall back to the generic implementation if the object has numeric properties. + + * runtime/ObjectConstructor.cpp: + (JSC::objectConstructorFreeze): + - fallback if the object has a non-zero indexed property vector length. + +2012-09-24 Gavin Barraclough <barraclough@apple.com> + + Bug in numeric accessors on global environment + https://bugs.webkit.org/show_bug.cgi?id=97526 + + Reviewed by Geoff Garen. + + I've hit this assert in test262 in browser, but haven't yet worked out how to repro in a test case :-/ + The sparsemap is failing to map back from the global object to the window shell. + A test case would need to resolve a numeric property name against the global environment. + + (JSC::SparseArrayEntry::get): + (JSC::SparseArrayEntry::put): + - Add missing toThisObject calls. + +2012-09-24 Filip Pizlo <fpizlo@apple.com> + + SerializedScriptValue isn't aware of indexed storage, but should be + https://bugs.webkit.org/show_bug.cgi?id=97515 + <rdar://problem/12361874> + + Reviewed by Sam Weinig. + + Export a method that WebCore now uses. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * runtime/JSObject.h: + (JSObject): + +2012-09-24 Gavin Barraclough <barraclough@apple.com> + + Remove JSObject::unwrappedGlobalObject(), JSObject::unwrappedObject() + https://bugs.webkit.org/show_bug.cgi?id=97519 + + Reviewed by Geoff Garen. + + unwrappedGlobalObject() was only needed because globalObject() doesn't always return a helpful result - + specifically for WebCore's window shell the structure's globalObject is set to null. We can fix this by + simply keeping the structure up to date as the window navigates, obviating the need for this function. + + The only other use of unwrappedObject() came from globalFuncEval(), and this can be trivially removed + by flipping the way we perform this globalObject check (which we may also be able to remove!) - instead + of getting the globalObject from the provided this value & comparing to the expected globalObject, we + can get the this value from the expected globalObject, and compare to that provided. + + * runtime/JSGlobalObject.cpp: + - Call globalObject() instead of unwrappedGlobalObject(). + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::globalFuncEval): + - Changed to compare this object values, instead of globalObjects - + this means we only need to be able to map globalObject -> this, + and not vice versa. + * runtime/JSObject.cpp: + (JSC::JSObject::allowsAccessFrom): + (JSC::JSObject::createInheritorID): + - Call globalObject() instead of unwrappedGlobalObject(). + * runtime/JSObject.h: + (JSObject): + - Removed unwrappedGlobalObject(), unwrappedObject(). + +2012-09-24 Mark Lam <mark.lam@apple.com> + + Deleting the classic interpreter and cleaning up some build options. + https://bugs.webkit.org/show_bug.cgi?id=96969. + + Reviewed by Geoffrey Garen. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + (JSC::CodeBlock::finalizeUnconditionally): + (JSC::CodeBlock::stronglyVisitStrongReferences): + (JSC): + * bytecode/Instruction.h: + (JSC::Instruction::Instruction): + * interpreter/AbstractPC.cpp: + (JSC::AbstractPC::AbstractPC): + * interpreter/AbstractPC.h: + (AbstractPC): + * interpreter/CallFrame.h: + (ExecState): + * interpreter/Interpreter.cpp: + (JSC): + (JSC::Interpreter::Interpreter): + (JSC::Interpreter::~Interpreter): + (JSC::Interpreter::initialize): + (JSC::Interpreter::isOpcode): + (JSC::Interpreter::unwindCallFrame): + (JSC::getLineNumberForCallFrame): + (JSC::getCallerInfo): + (JSC::getSourceURLFromCallFrame): + (JSC::Interpreter::execute): + (JSC::Interpreter::executeCall): + (JSC::Interpreter::executeConstruct): + (JSC::Interpreter::retrieveArgumentsFromVMCode): + (JSC::Interpreter::retrieveCallerFromVMCode): + (JSC::Interpreter::retrieveLastCaller): + * interpreter/Interpreter.h: + (JSC::Interpreter::getOpcodeID): + (Interpreter): + * jit/ExecutableAllocatorFixedVMPool.cpp: + (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator): + * offlineasm/asm.rb: + * offlineasm/offsets.rb: + * runtime/Executable.cpp: + (JSC::EvalExecutable::compileInternal): + (JSC::ProgramExecutable::compileInternal): + (JSC::FunctionExecutable::compileForCallInternal): + (JSC::FunctionExecutable::compileForConstructInternal): + * runtime/Executable.h: + (JSC::NativeExecutable::create): + (NativeExecutable): + (JSC::NativeExecutable::finishCreation): + * runtime/JSGlobalData.cpp: + (JSC): + (JSC::JSGlobalData::JSGlobalData): + (JSC::JSGlobalData::getHostFunction): + * runtime/JSGlobalData.h: + (JSGlobalData): + (JSC::JSGlobalData::canUseJIT): + (JSC::JSGlobalData::canUseRegExpJIT): + * runtime/Options.cpp: + (JSC::Options::initialize): + +2012-09-24 Filip Pizlo <fpizlo@apple.com> + + Nested try/finally should not confuse the finally unpopper in BytecodeGenerator::emitComplexJumpScopes + https://bugs.webkit.org/show_bug.cgi?id=97508 + <rdar://problem/12361132> + + Reviewed by Sam Weinig. + + We're reusing some vector for multiple iterations of a loop, but we were forgetting to clear its + contents from one iteration to the next. Hence if you did multiple iterations of finally unpopping + (like in a nested try/finally and a jump out of both of them) then you'd get a corrupted try + context stack afterwards. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitComplexJumpScopes): + +2012-09-24 Filip Pizlo <fpizlo@apple.com> + + ValueToInt32 bool case does bad things to registers + https://bugs.webkit.org/show_bug.cgi?id=97505 + <rdar://problem/12356331> + + Reviewed by Mark Hahnenberg. + + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileValueToInt32): + +2012-09-24 Mark Lam <mark.lam@apple.com> + + Add cloopDo instruction for debugging the llint C++ backend. + https://bugs.webkit.org/show_bug.cgi?id=97502. + + Reviewed by Geoffrey Garen. + + * offlineasm/cloop.rb: + * offlineasm/instructions.rb: + * offlineasm/parser.rb: + +2012-09-24 Filip Pizlo <fpizlo@apple.com> + + JSArray::putByIndex asserts with readonly property on prototype + https://bugs.webkit.org/show_bug.cgi?id=97435 + <rdar://problem/12357084> + + Reviewed by Geoffrey Garen. + + Boy, there were some problems: + + - putDirectIndex() should know that it can set the index quickly even if it's a hole and we're + in SlowPut mode, since that's the whole point of PutDirect. + + - We should have a fast path for putByIndex(). + + - The LiteralParser should not use push(), since that may throw if we're having a bad time. + + * interpreter/Interpreter.cpp: + (JSC::eval): + * runtime/JSObject.h: + (JSC::JSObject::putByIndexInline): + (JSObject): + (JSC::JSObject::putDirectIndex): + * runtime/LiteralParser.cpp: + (JSC::::parse): + +2012-09-24 Mark Lam <mark.lam@apple.com> + + Added a missing "if VALUE_PROFILER" around an access to ArrayProfile record. + https://bugs.webkit.org/show_bug.cgi?id=97496. + + Reviewed by Filip Pizlo. + + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-09-24 Geoffrey Garen <ggaren@apple.com> + + Inlined activation tear-off in the DFG + https://bugs.webkit.org/show_bug.cgi?id=97487 + + Reviewed by Filip Pizlo. + + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: Activation tear-off is always inlined now, so I + removed its out-of-line implementation. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): Inlined the variable copy and update + of JSVariableObject::m_registers. This usually turns into < 10 instructions, + which is close to pure win as compared to the operation function call. + + * runtime/JSActivation.h: + (JSActivation): + (JSC::JSActivation::registersOffset): + (JSC::JSActivation::tearOff): + (JSC::JSActivation::isTornOff): + (JSC): + (JSC::JSActivation::storageOffset): + (JSC::JSActivation::storage): Tiny bit of refactoring so the JIT can + share the pointer math helper functions we use internally. + +2012-09-24 Balazs Kilvady <kilvadyb@homejinni.com> + + MIPS: store8 functions added to MacroAssembler. + + MIPS store8 functions + https://bugs.webkit.org/show_bug.cgi?id=97243 + + Reviewed by Oliver Hunt. + + Add MIPS store8 functions. + + * assembler/MIPSAssembler.h: + (JSC::MIPSAssembler::lhu): New function. + (MIPSAssembler): + (JSC::MIPSAssembler::sb): New function. + (JSC::MIPSAssembler::sh): New function. + * assembler/MacroAssemblerMIPS.h: + (JSC::MacroAssemblerMIPS::store8): New function. + (MacroAssemblerMIPS): + (JSC::MacroAssemblerMIPS::store16): New function. + +2012-09-23 Geoffrey Garen <ggaren@apple.com> + + PutScopedVar should not be marked as clobbering the world + https://bugs.webkit.org/show_bug.cgi?id=97416 + + Reviewed by Filip Pizlo. + + No performance change. + + PutScopedVar doesn't have arbitrary side-effects, so it shouldn't be marked + as such. + + * dfg/DFGNodeType.h: + (DFG): + +2012-09-23 Geoffrey Garen <ggaren@apple.com> + + I accidentally the whole 32-bit :(. + + Unbreak the DFG in 32-bit with the 32-bit path I forgot in my last patch. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-09-23 Byungwoo Lee <bw80.lee@gmail.com> + + Fix build warnings : -Wunused-parameter, -Wparentheses, -Wuninitialized. + https://bugs.webkit.org/show_bug.cgi?id=97306 + + Reviewed by Benjamin Poulain. + + Fix build warning about -Wunused-parameter on MachineStackMarker.cpp, + LLIntSlowPaths.cpp, DatePrototype.cpp, Options.cpp by using + UNUSED_PARAM() macro or remove parameter name. + + * heap/MachineStackMarker.cpp: + (JSC::pthreadSignalHandlerSuspendResume): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::entryOSR): + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + * runtime/Options.cpp: + (JSC::computeNumberOfGCMarkers): + +2012-09-23 Gavin Barraclough <barraclough@apple.com> + + Sorting a non-array creates propreties (spec-violation) + https://bugs.webkit.org/show_bug.cgi?id=25477 + + Reviewed by Oliver Hunt. + + We're just calling get() to get properties, which is converting missing properties to + undefined. Hole values should be retained, and moved to the end of the array. + + * runtime/ArrayPrototype.cpp: + (JSC::getOrHole): + - Helper function, returns JSValue() instead of undefined for missing properties. + (JSC::arrayProtoFuncSort): + - Implemented per 15.4.4.11, see comments above. + +2012-09-23 Geoffrey Garen <ggaren@apple.com> + + CSE for access to closure variables (get_/put_scoped_var) + https://bugs.webkit.org/show_bug.cgi?id=97414 + + Reviewed by Oliver Hunt. + + I separated loading a scope from loading its storage pointer, so we can + CSE the storage pointer load. Then, I copied the global var CSE and adjusted + it for closure vars. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): Renamed GetScopeChain => GetScope to + reflect renames from a few weeks ago. + + Added a case for the storage pointer load, similar to object storage pointer load. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): Added an independent node for + the storage pointer. + + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::scopedVarLoadElimination): + (CSEPhase): + (JSC::DFG::CSEPhase::scopedVarStoreElimination): + (JSC::DFG::CSEPhase::getScopeLoadElimination): + (JSC::DFG::CSEPhase::getScopeRegistersLoadElimination): + (JSC::DFG::CSEPhase::setLocalStoreElimination): + (JSC::DFG::CSEPhase::performNodeCSE): Copied globalVarLoad/StoreElimination + and adapted the same logic to closure vars. + + * dfg/DFGNode.h: + (JSC::DFG::Node::hasScopeChainDepth): + (JSC::DFG::Node::scope): + (Node): + * dfg/DFGNodeType.h: + (DFG): GetScopedVar and GetGlobalVar are no longer MustGenerate. I'm not + sure why they ever were. But these are simple load operations so, if they're + unused, they're truly dead. + + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): Updated for renames and split-out + node for getting the storage pointer. + +2012-09-21 Geoffrey Garen <ggaren@apple.com> + + Unreviewed, rolled out a line I committed by accident. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::execute): + +2012-09-21 Geoffrey Garen <ggaren@apple.com> + + Optimized closures that capture arguments + https://bugs.webkit.org/show_bug.cgi?id=97358 + + Reviewed by Oliver Hunt. + + Previously, the activation object was responsible for capturing all + arguments in a way that was convenient for the arguments object. Now, + we move all captured variables into a contiguous region in the stack, + allocate an activation for exactly that size, and make the arguments + object responsible for knowing all the places to which arguments could + have moved. + + This seems like the right tradeoff because + + (a) Closures are common and long-lived, so we want them to be small. + + (b) Our primary strategy for optimizing the arguments object is to make + it go away. If you're allocating arguments objects, you're already having + a bad time. + + (c) It's common to use either the arguments object or named argument + closure, but not both. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + (JSC::CodeBlock::CodeBlock): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::argumentsRegister): + (JSC::CodeBlock::activationRegister): + (JSC::CodeBlock::isCaptured): + (JSC::CodeBlock::argumentIndexAfterCapture): m_numCapturedVars is gone + now -- we have an explicit range instead. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): Move captured arguments + into the captured region of local variables for space efficiency. Record + precise data about where they moved for the sake of the arguments object. + + Some of this data was previously wrong, but it didn't cause any problems + because the arguments weren't actually moving. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::flushArgumentsAndCapturedVariables): Don't + assume that captured vars are in any particular location -- always ask + the CodeBlock. This is better encapsulation. + + (JSC::DFG::ByteCodeParser::parseCodeBlock): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): I rename things sometimes. + + * runtime/Arguments.cpp: + (JSC::Arguments::tearOff): Account for a particularly nasty edge case. + + (JSC::Arguments::didTearOffActivation): Don't allocate our slow arguments + data on tear-off. We need to allocate it eagerly instead, since we need + to know about displaced, captured arguments during access before tear-off. + + * runtime/Arguments.h: + (JSC::Arguments::allocateSlowArguments): + (JSC::Arguments::argument): Tell our slow arguments array where all arguments + are, even if they are not captured. This simplifies some things, so we don't + have to account explicitly for the full matrix of (not torn off, torn off) + * (captured, not captured). + + (JSC::Arguments::finishCreation): Allocate our slow arguments array eagerly + because we need to know about displaced, captured arguments during access + before tear-off. + + * runtime/Executable.cpp: + (JSC::FunctionExecutable::FunctionExecutable): + (JSC::FunctionExecutable::compileForCallInternal): + (JSC::FunctionExecutable::compileForConstructInternal): + * runtime/Executable.h: + (JSC::FunctionExecutable::parameterCount): + (FunctionExecutable): + * runtime/JSActivation.cpp: + (JSC::JSActivation::visitChildren): + * runtime/JSActivation.h: + (JSActivation): + (JSC::JSActivation::create): + (JSC::JSActivation::JSActivation): + (JSC::JSActivation::registerOffset): + (JSC::JSActivation::tearOff): + (JSC::JSActivation::allocationSize): + (JSC::JSActivation::isValid): This is really the point of the patch. All + the pointer math in Activations basically boils away, since we always + copy a contiguous region of captured variables now. + + * runtime/SymbolTable.h: + (JSC::SlowArgument::SlowArgument): + (SlowArgument): + (SharedSymbolTable): + (JSC::SharedSymbolTable::captureCount): + (JSC::SharedSymbolTable::SharedSymbolTable): AllOfTheThings capture mode + is gone now -- that's the point of the patch. indexIfCaptured gets renamed + to index because we always have an index, even if not captured. (The only + time when the index is meaningless is when we're Deleted.) + +2012-09-21 Gavin Barraclough <barraclough@apple.com> + + Eeeep - broke early boyer in bug#97382 + https://bugs.webkit.org/show_bug.cgi?id=97383 + + Rubber stamped by Sam Weinig. + + missed a child3 -> child2! + + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileInstanceOf): + +2012-09-21 Gavin Barraclough <barraclough@apple.com> + + Unreviewed windows build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-09-21 Gavin Barraclough <barraclough@apple.com> + + Pedantic test in Mozilla's JavaScript test suite fails. function-001.js function-001-n.js + https://bugs.webkit.org/show_bug.cgi?id=27219 + + Reviewed by Sam Weinig. + + These tests are just wrong. + See ECMA 262 A.5, FunctionDelcaration does not require a semicolon. + + * tests/mozilla/expected.html: + * tests/mozilla/js1_2/function/function-001-n.js: + * tests/mozilla/js1_3/Script/function-001-n.js: + * tests/mozilla/js1_3/regress/function-001-n.js: + +2012-09-21 Gavin Barraclough <barraclough@apple.com> + + Remove redundant argument to op_instanceof + https://bugs.webkit.org/show_bug.cgi?id=97382 + + Reviewed by Geoff Garen. + + No longer needed after my last change. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitInstanceOf): + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + * bytecompiler/NodesCodegen.cpp: + (JSC::InstanceOfNode::emitBytecode): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileInstanceOf): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emitSlow_op_instanceof): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emitSlow_op_instanceof): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-09-21 Gavin Barraclough <barraclough@apple.com> + + Unreviewed windows build fix. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-09-21 Gavin Barraclough <barraclough@apple.com> + + instanceof should not get the prototype for non-default HasInstance + https://bugs.webkit.org/show_bug.cgi?id=68656 + + Reviewed by Oliver Hunt. + + Instanceof is currently implemented as a sequance of three opcodes: + check_has_instance + get_by_id(prototype) + op_instanceof + There are three interesting types of base value that instanceof can be applied to: + (A) Objects supporting default instanceof behaviour (functions, other than those created with bind) + (B) Objects overriding the default instancecof behaviour with a custom one (API objects, bound functions) + (C) Values that do not respond to the [[HasInstance]] trap. + Currently check_has_instance handles case (C), leaving the op_instanceof opcode to handle (A) & (B). There are + two problems with this apporach. Firstly, this is suboptimal for case (A), since we have to check for + hasInstance support twice (once in check_has_instance, then for default behaviour in op_instanceof). Secondly, + this means that in cases (B) we also perform the get_by_id, which is both suboptimal and an observable spec + violation. + + The fix here is to move handing of non-default instanceof (cases (B)) to the check_has_instance op, leaving + op_instanceof to handle only cases (A). + + * API/JSCallbackObject.h: + (JSCallbackObject): + * API/JSCallbackObjectFunctions.h: + (JSC::::customHasInstance): + * API/JSValueRef.cpp: + (JSValueIsInstanceOfConstructor): + - renamed hasInstance to customHasInstance + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + - added additional parameters to check_has_instance opcode + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + - added additional parameters to check_has_instance opcode + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitCheckHasInstance): + - added additional parameters to check_has_instance opcode + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + - added additional parameters to check_has_instance opcode + * bytecompiler/NodesCodegen.cpp: + (JSC::InstanceOfNode::emitBytecode): + - added additional parameters to check_has_instance opcode + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + - added additional parameters to check_has_instance opcode + * interpreter/Interpreter.cpp: + (JSC::isInvalidParamForIn): + (JSC::Interpreter::privateExecute): + - Add handling for non-default instanceof to op_check_has_instance + * jit/JITInlineMethods.h: + (JSC::JIT::emitArrayProfilingSiteForBytecodeIndex): + - Fixed no-LLInt no_DFG build + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_check_has_instance): + (JSC::JIT::emitSlow_op_check_has_instance): + - check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance. + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emitSlow_op_instanceof): + - no need to check for ImplementsDefaultHasInstance. + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_check_has_instance): + (JSC::JIT::emitSlow_op_check_has_instance): + - check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance. + (JSC::JIT::emit_op_instanceof): + (JSC::JIT::emitSlow_op_instanceof): + - no need to check for ImplementsDefaultHasInstance. + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: + - Add handling for non-default instanceof to op_check_has_instance + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + - move check for ImplementsDefaultHasInstance, handle additional arguments to op_check_has_instance. + * runtime/ClassInfo.h: + (MethodTable): + (JSC): + - renamed hasInstance to customHasInstance + * runtime/CommonSlowPaths.h: + (CommonSlowPaths): + - removed opInstanceOfSlow (this was whittled down to one function call!) + * runtime/JSBoundFunction.cpp: + (JSC::JSBoundFunction::customHasInstance): + * runtime/JSBoundFunction.h: + (JSBoundFunction): + - renamed hasInstance to customHasInstance, reimplemented. + * runtime/JSCell.cpp: + (JSC::JSCell::customHasInstance): + * runtime/JSCell.h: + (JSCell): + * runtime/JSObject.cpp: + (JSC::JSObject::hasInstance): + (JSC): + (JSC::JSObject::defaultHasInstance): + * runtime/JSObject.h: + (JSObject): + +2012-09-21 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, fix ARM build. + + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::store8): + (MacroAssemblerARMv7): + * offlineasm/armv7.rb: + +2012-09-21 Filip Pizlo <fpizlo@apple.com> + + REGRESSION (r128400): Opening Google Web Fonts page hangs or crashes + https://bugs.webkit.org/show_bug.cgi?id=97328 + + Reviewed by Mark Hahnenberg. + + It's a bad idea to emit stub code that reallocates property storage when we're in indexed + storage mode. DFGRepatch.cpp knew this and had the appropriate check in one of the places, + but it didn't have it in all of the places. + + This change also adds some more handy disassembly support, which I used to find the bug. + + * assembler/LinkBuffer.h: + (JSC): + * dfg/DFGRepatch.cpp: + (JSC::DFG::generateProtoChainAccessStub): + (JSC::DFG::tryCacheGetByID): + (JSC::DFG::tryBuildGetByIDList): + (JSC::DFG::emitPutReplaceStub): + (JSC::DFG::emitPutTransitionStub): + (JSC::DFG::tryCachePutByID): + * jit/JITStubRoutine.h: + (JSC): + +2012-09-21 Filip Pizlo <fpizlo@apple.com> + + DFG CSE assumes that a holy PutByVal does not interfere with GetArrayLength, when it clearly does + https://bugs.webkit.org/show_bug.cgi?id=97373 + + Reviewed by Mark Hahnenberg. + + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::pureCSE): + (JSC::DFG::CSEPhase::getArrayLengthElimination): + (JSC::DFG::CSEPhase::putStructureStoreElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGGraph.h: + (Graph): + +2012-09-21 Chris Rogers <crogers@google.com> + + Add Web Audio support for deprecated/legacy APIs + https://bugs.webkit.org/show_bug.cgi?id=97050 + + Reviewed by Eric Carlson. + + * Configurations/FeatureDefines.xcconfig: + +2012-09-21 Gavin Barraclough <barraclough@apple.com> + + Global Math object should be configurable but isn't + https://bugs.webkit.org/show_bug.cgi?id=55343 + + Reviewed by Oliver Hunt. + + This has no performance impact. + + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + - Make 'Math' a regular property. + +2012-09-21 Chao-ying Fu <fu@mips.com> + + Add MIPS or32 function + https://bugs.webkit.org/show_bug.cgi?id=97157 + + Reviewed by Gavin Barraclough. + + Add a missing or32 function. + + * assembler/MacroAssemblerMIPS.h: + (JSC::MacroAssemblerMIPS::or32): New function. + (MacroAssemblerMIPS): + +2012-09-20 Filip Pizlo <fpizlo@apple.com> + + CHECK_ARRAY_CONSISTENCY isn't being used or tested, so we should remove it + https://bugs.webkit.org/show_bug.cgi?id=97260 + + Rubber stamped by Geoffrey Garen. + + Supporting it will become difficult as we add more indexing types. It makes more + sense to kill, especially since we don't appear to use it or test it, ever. + + * runtime/ArrayConventions.h: + (JSC): + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncSplice): + * runtime/ArrayStorage.h: + (JSC::ArrayStorage::copyHeaderFromDuringGC): + (ArrayStorage): + * runtime/FunctionPrototype.cpp: + (JSC::functionProtoFuncBind): + * runtime/JSArray.cpp: + (JSC::createArrayButterflyInDictionaryIndexingMode): + (JSC::JSArray::setLength): + (JSC::JSArray::pop): + (JSC::JSArray::push): + (JSC::JSArray::sortNumeric): + (JSC::JSArray::sort): + (JSC::JSArray::compactForSorting): + * runtime/JSArray.h: + (JSArray): + (JSC::createArrayButterfly): + (JSC::JSArray::tryCreateUninitialized): + (JSC::constructArray): + * runtime/JSObject.cpp: + (JSC::JSObject::putByIndex): + (JSC::JSObject::createArrayStorage): + (JSC::JSObject::deletePropertyByIndex): + (JSC): + * runtime/JSObject.h: + (JSC::JSObject::initializeIndex): + (JSObject): + +2012-09-20 Mark Lam <mark.lam@apple.com> + + Fixed a missing semicolon in the C++ llint backend. + https://bugs.webkit.org/show_bug.cgi?id=97252. + + Reviewed by Geoff Garen. + + * offlineasm/cloop.rb: + +2012-09-20 Geoffrey Garen <ggaren@apple.com> + + Refactored the interpreter and JIT so they don't dictate closure layout + https://bugs.webkit.org/show_bug.cgi?id=97221 + + Reviewed by Oliver Hunt. + + Capture may change the location of an argument for space efficiency. This + patch removes static assumptions about argument location from the interpreter + and JIT. + + * bytecode/CodeBlock.h: + (JSC::CodeBlock::argumentIndexAfterCapture): + (JSC::ExecState::argumentAfterCapture): Factored out a helper function + so the compiler could share this logic. + + * bytecompiler/NodesCodegen.cpp: + (JSC::BracketAccessorNode::emitBytecode): Don't emit optimized bracket + access on arguments if a parameter has been captured by name. This case is + rare and, where I've seen it in the wild, the optimization mostly failed + anyway due to arguments escape, so I didn't feel like writing and testing + five copies of the code that would handle it in the baseline engines. + + The DFG can still synthesize this optimization even if we don't emit the + optimized bytecode for it. + + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + * dfg/DFGAssemblyHelpers.h: + (JSC::DFG::AssemblyHelpers::symbolTableFor): + (AssemblyHelpers): Use the right helper function to account for the fact + that a parameter may have been captured by name and moved. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): ASSERT that we haven't inlined + a .apply on captured arguments. Once we do start inlining such things, + we'll need to do a little bit of math here to get them right. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): Added support for bracket access on + an arguments object where arguments have also been captured by name. We + load the true index of the argument from a side vector. Arguments elision + is very powerful in the DFG, so I wanted to keep it working, even in this + rare case. + + * interpreter/Interpreter.cpp: + (JSC::loadVarargs): Use the right helper function to account for the fact + that a parameter may have been captured by name and moved. + + * jit/JITCall.cpp: + (JSC::JIT::compileLoadVarargs): + * jit/JITCall32_64.cpp: + (JSC::JIT::compileLoadVarargs): Don't use the inline copy loop if some + of our arguments have moved, since it would copy stale values. (We still + optimize the actual call, and elide the arguments object.) + +2012-09-20 Gabor Rapcsanyi <rgabor@webkit.org> + + [Qt] r129045 broke the ARM build + https://bugs.webkit.org/show_bug.cgi?id=97195 + + Reviewed by Zoltan Herczeg. + + Implementing missing store8 function. + + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::store8): + (MacroAssemblerARM): + +2012-09-19 Geoffrey Garen <ggaren@apple.com> + + OSR exit sometimes neglects to create the arguments object + https://bugs.webkit.org/show_bug.cgi?id=97162 + + Reviewed by Filip Pizlo. + + No performance change. + + I don't know of any case where this is a real problem in TOT, but it + will become a problem if we start compiling eval, with, or catch, and/or + sometimes stop doing arguments optimizations in the bytecode. + + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): Account for a + CreateArguments that has transformed into PhantomArguments. We used to + clear our reference to the CreateArguments node, but now we hold onto it, + so we need to account for it transforming. + + Don't replace a SetLocal(CreateArguments) with a SetLocal(JSValue()) + because that doesn't leave enough information behind for OSR exit to do + the right thing. Instead, maintain our reference to CreateArguments, and + rely on CreateArguments transforming into PhantomArguments after + optimization. SetLocal(PhantomArguments) is efficient, and it's a marker + for OSR exit to create the arguments object. + + Don't ASSERT that all PhantomArguments are unreferenced because we now + leave them in the graph as SetLocal(PhantomArguments), and that's harmless. + + * dfg/DFGArgumentsSimplificationPhase.h: + (NullableHashTraits): + (JSC::DFG::NullableHashTraits::emptyValue): Export our special hash table + for inline call frames so the OSR exit compiler can use it. + + * dfg/DFGOSRExitCompiler32_64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGOSRExitCompiler64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): Don't load the 'arguments' + register to decide if we need to create the arguments object. Optimization + may have eliminated the initializing store to this register, in which + case we'll load garbage. Instead, use the global knowledge that all call + frames that optimized out 'arguments' now need to create it, and use a hash + table to make sure we do so only once per call frame. + + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): SetLocal(PhantomArguments) is unique + because we haven't just changed a value's format or elided a load or store; + instead, we've replaced an object with JSValue(). We could try to account + for this in a general way, but for now it's a special-case optimization, + so we give it a specific OSR hint instead. + +2012-09-19 Filip Pizlo <fpizlo@apple.com> + + REGRESSION(r128802): It made some JS tests crash + https://bugs.webkit.org/show_bug.cgi?id=97001 + + Reviewed by Mark Hahnenberg. + + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::visitChildren): + +2012-09-19 Filip Pizlo <fpizlo@apple.com> + + DFG should not assume that a ByVal access is generic just because it was unprofiled + https://bugs.webkit.org/show_bug.cgi?id=97088 + + Reviewed by Geoffrey Garen. + + We were not disambiguating between "Undecided" in the sense that the array profile + has no useful information versus "Undecided" in the sense that the array profile + knows that the access has not executed. That's an important distinction, since + the former form of "Undecided" means that we should consult value profiling, while + the latter means that we should force exit unless the value profiling indicates + that the access must be generic (base is not cell or property is not int). + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGArrayMode.cpp: + (JSC::DFG::fromObserved): + (JSC::DFG::refineArrayMode): + (JSC::DFG::modeAlreadyChecked): + (JSC::DFG::modeToString): + * dfg/DFGArrayMode.h: + (JSC::DFG::canCSEStorage): + (JSC::DFG::modeIsSpecific): + (JSC::DFG::modeSupportsLength): + (JSC::DFG::benefitsFromStructureCheck): + +2012-09-19 Filip Pizlo <fpizlo@apple.com> + + DFG should not emit PutByVal hole case unless it has to + https://bugs.webkit.org/show_bug.cgi?id=97080 + + Reviewed by Geoffrey Garen. + + This causes us to generate less code for typical PutByVal's. But if profiling tells us + that the hole case is being hit, we generate the same code as we would have generated + before. This seems like a slight speed-up across the board. + + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::store8): + (MacroAssemblerARMv7): + * assembler/MacroAssemblerX86.h: + (MacroAssemblerX86): + (JSC::MacroAssemblerX86::store8): + * assembler/MacroAssemblerX86_64.h: + (MacroAssemblerX86_64): + (JSC::MacroAssemblerX86_64::store8): + * assembler/X86Assembler.h: + (X86Assembler): + (JSC::X86Assembler::movb_i8m): + * bytecode/ArrayProfile.h: + (JSC::ArrayProfile::ArrayProfile): + (JSC::ArrayProfile::addressOfMayStoreToHole): + (JSC::ArrayProfile::mayStoreToHole): + (ArrayProfile): + * dfg/DFGArrayMode.cpp: + (JSC::DFG::fromObserved): + (JSC::DFG::modeAlreadyChecked): + (JSC::DFG::modeToString): + * dfg/DFGArrayMode.h: + (DFG): + (JSC::DFG::mayStoreToHole): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * jit/JIT.h: + (JIT): + * jit/JITInlineMethods.h: + (JSC::JIT::emitArrayProfileStoreToHoleSpecialCase): + (JSC): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_put_by_val): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_put_by_val): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-09-18 Filip Pizlo <fpizlo@apple.com> + + DFG should not call out to C++ every time that it tries to put to an object that doesn't yet have array storage + https://bugs.webkit.org/show_bug.cgi?id=96983 + + Reviewed by Oliver Hunt. + + Introduce more polymorphism into the DFG's array mode support. Use that to + introduce the notion of effectul array modes, where the check for the mode + will perform actions necessary to ensure that we have the mode we want, if + the object is not already in that mode. Also added profiling support for + checking if an object is of a type that would not allow us to create array + storage (like a typed array or a string for example). + + This is a ~2x speed-up on loops that transform an object that did not have + indexed storage into one that does. + + * JSCTypedArrayStubs.h: + (JSC): + * bytecode/ArrayProfile.cpp: + (JSC::ArrayProfile::computeUpdatedPrediction): + * bytecode/ArrayProfile.h: + (JSC::ArrayProfile::ArrayProfile): + (JSC::ArrayProfile::mayInterceptIndexedAccesses): + (ArrayProfile): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGArrayMode.cpp: + (JSC::DFG::fromObserved): + (DFG): + (JSC::DFG::modeAlreadyChecked): + (JSC::DFG::modeToString): + * dfg/DFGArrayMode.h: + (DFG): + (JSC::DFG::modeUsesButterfly): + (JSC::DFG::isSlowPutAccess): + (JSC::DFG::benefitsFromStructureCheck): + (JSC::DFG::isEffectful): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::getArrayMode): + (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks): + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + (JSC::DFG::FixupPhase::checkArray): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::byValIsPure): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasArrayMode): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::checkArray): + (JSC::DFG::SpeculativeJIT::arrayify): + (DFG): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * runtime/Arguments.h: + (Arguments): + * runtime/JSNotAnObject.h: + (JSNotAnObject): + * runtime/JSObject.h: + (JSObject): + (JSC::JSObject::ensureArrayStorage): + * runtime/JSString.h: + (JSC::JSString::createStructure): + +2012-09-18 Filip Pizlo <fpizlo@apple.com> + + Include PhantomArguments in DFGDisassembly + https://bugs.webkit.org/show_bug.cgi?id=97043 + + Reviewed by Geoffrey Garen. + + * dfg/DFGNode.h: + (JSC::DFG::Node::willHaveCodeGenOrOSR): + +2012-09-18 Filip Pizlo <fpizlo@apple.com> + + REGRESSION(r128802): It made some JS tests crash + https://bugs.webkit.org/show_bug.cgi?id=97001 + + Reviewed by Mark Hahnenberg. + + IndexingHeaderInlineMethods was incorrectly assuming that if the HasArrayStorage bit is clear, then that means that indexing payload capacity is zero. + + * runtime/IndexingHeaderInlineMethods.h: + (JSC::IndexingHeader::preCapacity): + (JSC::IndexingHeader::indexingPayloadSizeInBytes): + +2012-09-18 Mark Hahnenberg <mhahnenberg@apple.com> + + Use WTF::HasTrivialDestructor instead of compiler-specific versions in JSC::NeedsDestructor + https://bugs.webkit.org/show_bug.cgi?id=96980 + + Reviewed by Benjamin Poulain. + + * runtime/JSCell.h: + (JSC): + (NeedsDestructor): + +2012-09-18 Filip Pizlo <fpizlo@apple.com> + + DFGOperations doesn't use NativeCallFrameTracer in enough places + https://bugs.webkit.org/show_bug.cgi?id=96987 + + Reviewed by Mark Hahnenberg. + + Anything that can GC should use it. + + * dfg/DFGOperations.cpp: + +2012-09-18 Mark Lam <mark.lam@apple.com> + + Not reviewed. Attempt at greening the WinCairo bot. Touching + LowLevelInterpreter.asm to trigger a rebuild of LLIntDesiredOffsets. + https://bugs.webkit.org/show_bug.cgi?id=96992. + + * llint/LowLevelInterpreter.asm: + +2012-09-18 Peter Gal <galpeter@inf.u-szeged.hu> + + [Qt] REGRESSION(r128790): It broke the ARM build + https://bugs.webkit.org/show_bug.cgi?id=96968 + + Reviewed by Filip Pizlo. + + Implement the missing or32 method in the MacroAssemblerARM.h. + + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::or32): + (MacroAssemblerARM): + +2012-09-18 Mark Lam <mark.lam@apple.com> + + Fix for WinCairo builds. + https://bugs.webkit.org/show_bug.cgi?id=96992. + + Reviewed by Filip Pizlo. + + Adding additional vcproj build targets in LLIntDesiredOffsets.vcproj, + LLIntOffsetsExtractor.vcproj, and LLIntAssembly.vcproj to match those + in jsc.vcproj. + + * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj: + * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj: + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj: + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops: Added property svn:eol-style. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops: Added property svn:eol-style. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugAll.vsprops: Added. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebugCairoCFLite.vsprops: Added. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorProduction.vsprops: Added. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops: Added property svn:eol-style. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleaseCairoCFLite.vsprops: Added. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorReleasePGO.vsprops: Added. + +2012-09-18 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, fix sloppy English in comment. + + * runtime/JSGlobalObject.cpp: + (JSC): + +2012-09-17 Csaba Osztrogonác <ossy@webkit.org> + + Unreviewed, rolling out r128826 and r128813. + + * API/JSCallbackConstructor.cpp: + (JSC): + (JSC::JSCallbackConstructor::JSCallbackConstructor): + * API/JSCallbackConstructor.h: + (JSCallbackConstructor): + * API/JSCallbackObject.cpp: + (JSC): + (JSC::::createStructure): + * API/JSCallbackObject.h: + (JSC::JSCallbackObject::create): + (JSCallbackObject): + * API/JSClassRef.cpp: + (OpaqueJSClass::prototype): + * API/JSObjectRef.cpp: + (JSObjectMake): + (JSObjectGetPrivate): + (JSObjectSetPrivate): + (JSObjectGetPrivateProperty): + (JSObjectSetPrivateProperty): + (JSObjectDeletePrivateProperty): + * API/JSValueRef.cpp: + (JSValueIsObjectOfClass): + * API/JSWeakObjectMapRefPrivate.cpp: + * GNUmakefile.list.am: + * JSCTypedArrayStubs.h: + (JSC): + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): + (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject): + * heap/Heap.cpp: + (JSC::Heap::isSafeToSweepStructures): + (JSC): + * heap/Heap.h: + (JSC::Heap::allocatorForObjectWithDestructor): + (Heap): + (JSC::Heap::allocateWithDestructor): + (JSC::Heap::allocateStructure): + (JSC): + * heap/IncrementalSweeper.cpp: + (JSC::IncrementalSweeper::IncrementalSweeper): + (JSC::IncrementalSweeper::sweepNextBlock): + (JSC::IncrementalSweeper::startSweeping): + (JSC::IncrementalSweeper::willFinishSweeping): + (JSC::IncrementalSweeper::structuresCanBeSwept): + (JSC): + * heap/IncrementalSweeper.h: + (IncrementalSweeper): + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::tryAllocateHelper): + (JSC::MarkedAllocator::allocateBlock): + * heap/MarkedAllocator.h: + (JSC::MarkedAllocator::cellsNeedDestruction): + (JSC::MarkedAllocator::onlyContainsStructures): + (MarkedAllocator): + (JSC::MarkedAllocator::MarkedAllocator): + (JSC::MarkedAllocator::init): + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::create): + (JSC::MarkedBlock::MarkedBlock): + (JSC): + (JSC::MarkedBlock::specializedSweep): + (JSC::MarkedBlock::sweep): + (JSC::MarkedBlock::sweepHelper): + * heap/MarkedBlock.h: + (JSC): + (MarkedBlock): + (JSC::MarkedBlock::cellsNeedDestruction): + (JSC::MarkedBlock::onlyContainsStructures): + * heap/MarkedSpace.cpp: + (JSC::MarkedSpace::MarkedSpace): + (JSC::MarkedSpace::resetAllocators): + (JSC::MarkedSpace::canonicalizeCellLivenessData): + (JSC::MarkedSpace::isPagedOut): + (JSC::MarkedSpace::freeBlock): + * heap/MarkedSpace.h: + (MarkedSpace): + (Subspace): + (JSC::MarkedSpace::allocatorFor): + (JSC::MarkedSpace::destructorAllocatorFor): + (JSC::MarkedSpace::allocateWithDestructor): + (JSC::MarkedSpace::allocateStructure): + (JSC::MarkedSpace::forEachBlock): + * heap/SlotVisitor.cpp: + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + (JSC::JIT::emitAllocateJSFinalObject): + (JSC::JIT::emitAllocateJSArray): + * jsc.cpp: + (GlobalObject::create): + * runtime/Arguments.cpp: + (JSC): + * runtime/Arguments.h: + (Arguments): + (JSC::Arguments::Arguments): + * runtime/ErrorPrototype.cpp: + (JSC): + * runtime/Executable.h: + * runtime/InternalFunction.cpp: + (JSC): + (JSC::InternalFunction::InternalFunction): + * runtime/InternalFunction.h: + (InternalFunction): + * runtime/JSCell.h: + (JSC): + (JSC::allocateCell): + * runtime/JSDestructibleObject.h: Removed. + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + (JSC): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::createRareDataIfNeeded): + (JSC::JSGlobalObject::create): + * runtime/JSGlobalThis.h: + (JSGlobalThis): + (JSC::JSGlobalThis::JSGlobalThis): + * runtime/JSPropertyNameIterator.h: + * runtime/JSScope.cpp: + (JSC): + * runtime/JSString.h: + (JSC): + * runtime/JSWrapperObject.h: + (JSWrapperObject): + (JSC::JSWrapperObject::JSWrapperObject): + * runtime/MathObject.cpp: + (JSC): + * runtime/NameInstance.h: + (NameInstance): + * runtime/RegExp.h: + * runtime/RegExpObject.cpp: + (JSC): + * runtime/SparseArrayValueMap.h: + * runtime/Structure.h: + (JSC::Structure): + (JSC::JSCell::classInfo): + (JSC): + * runtime/StructureChain.h: + * runtime/SymbolTable.h: + * testRegExp.cpp: + (GlobalObject::create): + +2012-09-17 Geoffrey Garen <ggaren@apple.com> + + Refactored the arguments object so it doesn't dictate closure layout + https://bugs.webkit.org/show_bug.cgi?id=96955 + + Reviewed by Oliver Hunt. + + * bytecode/CodeBlock.h: + (JSC::ExecState::argumentAfterCapture): Helper function for accessing an + argument that has been moved for capture. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): Generate metadata for arguments + that are captured. We don't move any arguments yet, but we do use this + metadata to tell the arguments object if an argument is stored in the + activation. + + * dfg/DFGOperations.cpp: + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): + (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): Updated for the arguments object not + malloc'ing a separate backing store, and for a rename from deletedArguments + to slowArguments. + + * interpreter/CallFrame.h: + (ExecState): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::unwindCallFrame): + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): Updated for small interface changes. + + * runtime/Arguments.cpp: + (JSC::Arguments::visitChildren): + (JSC::Arguments::copyToArguments): + (JSC::Arguments::fillArgList): + (JSC::Arguments::getOwnPropertySlotByIndex): + (JSC::Arguments::createStrictModeCallerIfNecessary): + (JSC::Arguments::createStrictModeCalleeIfNecessary): + (JSC::Arguments::getOwnPropertySlot): + (JSC::Arguments::getOwnPropertyDescriptor): + (JSC::Arguments::getOwnPropertyNames): + (JSC::Arguments::putByIndex): + (JSC::Arguments::put): + (JSC::Arguments::deletePropertyByIndex): + (JSC::Arguments::deleteProperty): + (JSC::Arguments::defineOwnProperty): + (JSC::Arguments::tearOff): Moved all data inline into the object, for speed, + and refactored all internal argument accesses to use helper functions, so + we can change the implementation without changing lots of code. + + (JSC::Arguments::didTearOffActivation): This function needs to account + for arguments that were moved by the activation object. We do this accounting + through a side vector that tells us where our arguments will be in the + activation. + + (JSC::Arguments::tearOffForInlineCallFrame): + * runtime/Arguments.h: + (Arguments): + (JSC::Arguments::length): + (JSC::Arguments::isTornOff): + (JSC::Arguments::Arguments): + (JSC::Arguments::allocateSlowArguments): + (JSC::Arguments::tryDeleteArgument): + (JSC::Arguments::trySetArgument): + (JSC::Arguments::tryGetArgument): + (JSC::Arguments::isDeletedArgument): + (JSC::Arguments::isArgument): + (JSC::Arguments::argument): + (JSC::Arguments::finishCreation): + + * runtime/JSActivation.h: + (JSC::JSActivation::create): + (JSActivation): + (JSC::JSActivation::captureStart): + (JSC::JSActivation::storageSize): + (JSC::JSActivation::registerOffset): + (JSC::JSActivation::isValid): The activation object is no longer responsible + for copying extra arguments provided by the caller. The argumnents object + does this instead. This means we can allocate and initialize an activation + without worrying about the call frame's argument count. + + * runtime/SymbolTable.h: + (JSC::SlowArgument::SlowArgument): + (SlowArgument): + (JSC): + (JSC::SharedSymbolTable::parameterCount): + (SharedSymbolTable): + (JSC::SharedSymbolTable::slowArguments): + (JSC::SharedSymbolTable::setSlowArguments): Added data structures to back + the algorithms above. + +2012-09-17 Filip Pizlo <fpizlo@apple.com> + + 32-bit LLInt get_by_val does vector length checks incorrectly + https://bugs.webkit.org/show_bug.cgi?id=96893 + <rdar://problem/12311678> + + Reviewed by Mark Hahnenberg. + + * llint/LowLevelInterpreter32_64.asm: + +2012-09-17 Filip Pizlo <fpizlo@apple.com> + + We don't have a bad enough time if an object's prototype chain crosses global objects + https://bugs.webkit.org/show_bug.cgi?id=96962 + + Reviewed by Geoffrey Garen. + + * runtime/JSGlobalObject.cpp: + (JSC): + +2012-09-17 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, fix a broken assertion in offlineasm. + + * offlineasm/armv7.rb: + * offlineasm/backends.rb: + +2012-09-16 Mark Hahnenberg <mhahnenberg@apple.com> + + Delayed structure sweep can leak structures without bound + https://bugs.webkit.org/show_bug.cgi?id=96546 + + Reviewed by Gavin Barraclough. + + This patch gets rid of the separate Structure allocator in the MarkedSpace and adds two new destructor-only + allocators. We now have separate allocators for our three types of objects: those objects with no destructors, + those objects with destructors and with immortal structures, and those objects with destructors that don't have + immortal structures. All of the objects of the third type (destructors without immortal structures) now + inherit from a new class named JSDestructibleObject (which in turn is a subclass of JSNonFinalObject), which stores + the ClassInfo for these classes at a fixed offset for safe retrieval during sweeping/destruction. + + * API/JSCallbackConstructor.cpp: Use JSDestructibleObject for JSCallbackConstructor. + (JSC): + (JSC::JSCallbackConstructor::JSCallbackConstructor): + * API/JSCallbackConstructor.h: + (JSCallbackConstructor): + * API/JSCallbackObject.cpp: Inherit from JSDestructibleObject for normal JSCallbackObjects and use a finalizer for + JSCallbackObject<JSGlobalObject>, since JSGlobalObject also uses a finalizer. + (JSC): + (JSC::::create): We need to move the create function for JSCallbackObject<JSGlobalObject> out of line so we can add + the finalizer for it. We don't want to add the finalizer is something like finishCreation in case somebody decides + to subclass this. We use this same technique for many other subclasses of JSGlobalObject. + (JSC::::createStructure): + * API/JSCallbackObject.h: + (JSCallbackObject): + (JSC): + * API/JSClassRef.cpp: Change all the JSCallbackObject<JSNonFinalObject> to use JSDestructibleObject instead. + (OpaqueJSClass::prototype): + * API/JSObjectRef.cpp: Ditto. + (JSObjectMake): + (JSObjectGetPrivate): + (JSObjectSetPrivate): + (JSObjectGetPrivateProperty): + (JSObjectSetPrivateProperty): + (JSObjectDeletePrivateProperty): + * API/JSValueRef.cpp: Ditto. + (JSValueIsObjectOfClass): + * API/JSWeakObjectMapRefPrivate.cpp: Ditto. + * JSCTypedArrayStubs.h: + (JSC): + * JavaScriptCore.xcodeproj/project.pbxproj: + * dfg/DFGSpeculativeJIT.h: Use the proper allocator type when doing inline allocation in the DFG. + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): + (JSC::DFG::SpeculativeJIT::emitAllocateJSFinalObject): + * heap/Heap.cpp: + (JSC): + * heap/Heap.h: Add accessors for the various types of allocators now. Also remove the isSafeToSweepStructures function + since it's always safe to sweep Structures now. + (JSC::Heap::allocatorForObjectWithNormalDestructor): + (JSC::Heap::allocatorForObjectWithImmortalStructureDestructor): + (Heap): + (JSC::Heap::allocateWithNormalDestructor): + (JSC): + (JSC::Heap::allocateWithImmortalStructureDestructor): + * heap/IncrementalSweeper.cpp: Remove all the logic to detect when it's safe to sweep Structures from the + IncrementalSweeper since it's always safe to sweep Structures now. + (JSC::IncrementalSweeper::IncrementalSweeper): + (JSC::IncrementalSweeper::sweepNextBlock): + (JSC::IncrementalSweeper::startSweeping): + (JSC::IncrementalSweeper::willFinishSweeping): + (JSC): + * heap/IncrementalSweeper.h: + (IncrementalSweeper): + * heap/MarkedAllocator.cpp: Remove the logic that was preventing us from sweeping Structures if it wasn't safe. Add + tracking of the specific destructor type of allocator. + (JSC::MarkedAllocator::tryAllocateHelper): + (JSC::MarkedAllocator::allocateBlock): + * heap/MarkedAllocator.h: + (JSC::MarkedAllocator::destructorType): + (MarkedAllocator): + (JSC::MarkedAllocator::MarkedAllocator): + (JSC::MarkedAllocator::init): + * heap/MarkedBlock.cpp: Add all the destructor type stuff to MarkedBlocks so that we do the right thing when sweeping. + We also use the stored destructor type to determine the right thing to do in all JSCell::classInfo() calls. + (JSC::MarkedBlock::create): + (JSC::MarkedBlock::MarkedBlock): + (JSC): + (JSC::MarkedBlock::specializedSweep): + (JSC::MarkedBlock::sweep): + (JSC::MarkedBlock::sweepHelper): + * heap/MarkedBlock.h: + (JSC): + (JSC::MarkedBlock::allocator): + (JSC::MarkedBlock::destructorType): + * heap/MarkedSpace.cpp: Add the new destructor allocators to MarkedSpace. + (JSC::MarkedSpace::MarkedSpace): + (JSC::MarkedSpace::resetAllocators): + (JSC::MarkedSpace::canonicalizeCellLivenessData): + (JSC::MarkedSpace::isPagedOut): + (JSC::MarkedSpace::freeBlock): + * heap/MarkedSpace.h: + (MarkedSpace): + (JSC::MarkedSpace::immortalStructureDestructorAllocatorFor): + (JSC::MarkedSpace::normalDestructorAllocatorFor): + (JSC::MarkedSpace::allocateWithImmortalStructureDestructor): + (JSC::MarkedSpace::allocateWithNormalDestructor): + (JSC::MarkedSpace::forEachBlock): + * heap/SlotVisitor.cpp: Add include because the symbol was needed in an inlined function. + * jit/JIT.h: Make sure we use the correct allocator when doing inline allocations in the baseline JIT. + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + (JSC::JIT::emitAllocateJSFinalObject): + (JSC::JIT::emitAllocateJSArray): + * jsc.cpp: + (GlobalObject::create): Add finalizer here since JSGlobalObject needs to use a finalizer instead of inheriting from + JSDestructibleObject. + * runtime/Arguments.cpp: Inherit from JSDestructibleObject. + (JSC): + * runtime/Arguments.h: + (Arguments): + (JSC::Arguments::Arguments): + * runtime/ErrorPrototype.cpp: Added an assert to make sure we have a trivial destructor. + (JSC): + * runtime/Executable.h: Indicate that all of the Executable* classes have immortal Structures. + (JSC): + * runtime/InternalFunction.cpp: Inherit from JSDestructibleObject. + (JSC): + (JSC::InternalFunction::InternalFunction): + * runtime/InternalFunction.h: + (InternalFunction): + * runtime/JSCell.h: Added the NEEDS_DESTRUCTOR macro to make it easier for classes to indicate that instead of being + allocated in a destructor MarkedAllocator that they will handle their destruction themselves through the + use of a finalizer. + (JSC): + (HasImmortalStructure): New template to help us determine at compile-time if a particular class + should be allocated in the immortal structure MarkedAllocator. The default value is false. In order + to be allocated in the immortal structure allocator, classes must specialize this template. Also added + a macro to make it easier for classes to specialize the template. + (JSC::allocateCell): Use the appropriate allocator depending on the destructor type. + * runtime/JSDestructibleObject.h: Added. New class that stores the ClassInfo of any subclass so that it can be + accessed safely when the object is being destroyed. + (JSC): + (JSDestructibleObject): + (JSC::JSDestructibleObject::classInfo): + (JSC::JSDestructibleObject::JSDestructibleObject): + (JSC::JSCell::classInfo): Checks the current MarkedBlock to see where it should get the ClassInfo from so that it's always safe. + * runtime/JSGlobalObject.cpp: JSGlobalObject now uses a finalizer instead of a destructor so that it can avoid forcing all + of its relatives in the inheritance hierarchy (e.g. JSScope) to use destructors as well. + (JSC::JSGlobalObject::reset): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::createRareDataIfNeeded): Since we always create a finalizer now, we don't have to worry about adding one + for the m_rareData field when it's created. + (JSC::JSGlobalObject::create): + (JSC): + * runtime/JSGlobalThis.h: Inherit from JSDestructibleObject. + (JSGlobalThis): + (JSC::JSGlobalThis::JSGlobalThis): + * runtime/JSPropertyNameIterator.h: Has an immortal Structure. + (JSC): + * runtime/JSScope.cpp: + (JSC): + * runtime/JSString.h: Has an immortal Structure. + (JSC): + * runtime/JSWrapperObject.h: Inherit from JSDestructibleObject. + (JSWrapperObject): + (JSC::JSWrapperObject::JSWrapperObject): + * runtime/MathObject.cpp: Cleaning up some of the inheritance stuff. + (JSC): + * runtime/NameInstance.h: Inherit from JSDestructibleObject. + (NameInstance): + * runtime/RegExp.h: Has immortal Structure. + (JSC): + * runtime/RegExpObject.cpp: Inheritance cleanup. + (JSC): + * runtime/SparseArrayValueMap.h: Has immortal Structure. + (JSC): + * runtime/Structure.h: Has immortal Structure. + (JSC): + * runtime/StructureChain.h: Ditto. + (JSC): + * runtime/SymbolTable.h: Ditto. + (SharedSymbolTable): + (JSC): + +2012-09-17 Filip Pizlo <fpizlo@apple.com> + + If a prototype has indexed setters and its instances have indexed storage, then all put_by_val's should have a bad time + https://bugs.webkit.org/show_bug.cgi?id=96596 + + Reviewed by Gavin Barraclough. + + Added comprehensive support for accessors and read-only indexed properties on the + prototype chain. This is done without any performance regression on benchmarks that + we're aware of, by having the entire VM's strategy with respect to arrays tilted + heavily in favor of: + + - The prototype chain of JSArrays never having any accessors or read-only indexed + properties. If that changes, you're going to have a bad time. + + - Prototypes of non-JSArray objects either having no indexed accessors or read-only + indexed properties, or, having those indexed accessor thingies inserted before + any instance object (i.e. object with that prototype as its prototype) is created. + If you add indexed accessors or read-only indexed properties to an object that is + already used as a prototype, you're going to have a bad time. + + See below for the exact definition of having a bad time. + + Put another way, "fair" uses of indexed accessors and read-only indexed properties + are: + + - Put indexed accessors and read-only indexed properties on an object that is never + used as a prototype. This will slow down accesses to that object, but will not + have any effect on any other object. + + - Put those indexed accessor thingies on an object before it is used as a prototype + and then start instantiating objects that claim that object as their prototype. + This will slightly slow down indexed stores to the instance objects, and greatly + slow down all indexed accesses to the prototype, but will have no other effect. + + In short, "fair" uses only affect the object itself and any instance objects. But + if you start using indexed accessors in more eclectic ways, you're going to have + a bad time. + + Specifically, if an object that may be used as a prototype has an indexed accessor + added, the VM performs a whole-heap scan to find all objects that belong to the + same global object as the prototype you modified. If any of those objects has + indexed storage, their indexed storage is put into slow-put mode, just as if their + prototype chain had indexed accessors. This will happen even for objects that do + not currently have indexed accessors in their prototype chain. As well, all JSArray + allocations are caused to create arrays with slow-put storage, and all future + allocations of indexed storage for non-JSArray objects are also flipped to slow-put + mode. Note there are two aspects to having a bad time: (i) the whole-heap scan and + (ii) the poisoning of all indexed storage in the entire global object. (i) is + necessary for correctness. If we detect that an object that may be used as a + prototype has had an indexed accessor or indexed read-only property inserted into + it, then we need to ensure that henceforth all instances of that object inspect + the prototype chain whenever an indexed hole is stored to. But by default, indexed + stores do no such checking because doing so would be unnecessarily slow. So, we must + find all instances of the affected object and flip them into a different array + storage mode that omits all hole optimizations. Since prototypes never keep a list + of instance objects, the only way to find those objects is a whole-heap scan. But + (i) alone would be a potential disaster, if a program frequently allocated an + object without indexed accessors, then allocated a bunch of objects that used that + one as their prototype, and then added indexed accessors to the prototype. So, to + prevent massive heap scan storms in such awkward programs, having a bad time also + implies (ii): henceforth *all* objects belonging to that global object will use + slow put indexed storage, so that we don't ever have to scan the heap again. Note + that here we are using the global object as just an approximation of a program + module; it may be worth investigating in the future if other approximations can be + used instead. + + * bytecode/ArrayProfile.h: + (JSC): + (JSC::arrayModeFromStructure): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGArrayMode.cpp: + (JSC::DFG::fromObserved): + (JSC::DFG::modeAlreadyChecked): + (JSC::DFG::modeToString): + * dfg/DFGArrayMode.h: + (DFG): + (JSC::DFG::isSlowPutAccess): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::checkArray): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateJSArray): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_new_array): + * runtime/ArrayPrototype.cpp: + (JSC::ArrayPrototype::finishCreation): + (JSC::arrayProtoFuncSort): + * runtime/IndexingType.h: + (JSC): + (JSC::hasIndexedProperties): + (JSC::hasIndexingHeader): + (JSC::hasArrayStorage): + (JSC::shouldUseSlowPut): + * runtime/JSArray.cpp: + (JSC::JSArray::pop): + (JSC::JSArray::push): + (JSC::JSArray::fillArgList): + (JSC::JSArray::copyToArguments): + * runtime/JSArray.h: + (JSC::JSArray::createStructure): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::JSGlobalObject): + (JSC::JSGlobalObject::reset): + (JSC): + (JSC::JSGlobalObject::haveABadTime): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::addressOfArrayStructure): + (JSC::JSGlobalObject::havingABadTimeWatchpoint): + (JSC::JSGlobalObject::isHavingABadTime): + * runtime/JSObject.cpp: + (JSC::JSObject::visitButterfly): + (JSC::JSObject::getOwnPropertySlotByIndex): + (JSC::JSObject::put): + (JSC::JSObject::putByIndex): + (JSC::JSObject::enterDictionaryIndexingMode): + (JSC::JSObject::notifyPresenceOfIndexedAccessors): + (JSC): + (JSC::JSObject::createArrayStorage): + (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode): + (JSC::JSObject::switchToSlowPutArrayStorage): + (JSC::JSObject::setPrototype): + (JSC::JSObject::resetInheritorID): + (JSC::JSObject::inheritorID): + (JSC::JSObject::allowsAccessFrom): + (JSC::JSObject::deletePropertyByIndex): + (JSC::JSObject::getOwnPropertyNames): + (JSC::JSObject::unwrappedGlobalObject): + (JSC::JSObject::notifyUsedAsPrototype): + (JSC::JSObject::createInheritorID): + (JSC::JSObject::defineOwnIndexedProperty): + (JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype): + (JSC::JSObject::attemptToInterceptPutByIndexOnHole): + (JSC::JSObject::putByIndexBeyondVectorLength): + (JSC::JSObject::putDirectIndexBeyondVectorLength): + (JSC::JSObject::getNewVectorLength): + (JSC::JSObject::getOwnPropertyDescriptor): + * runtime/JSObject.h: + (JSC::JSObject::mayBeUsedAsPrototype): + (JSObject): + (JSC::JSObject::mayInterceptIndexedAccesses): + (JSC::JSObject::getArrayLength): + (JSC::JSObject::getVectorLength): + (JSC::JSObject::canGetIndexQuickly): + (JSC::JSObject::getIndexQuickly): + (JSC::JSObject::canSetIndexQuickly): + (JSC::JSObject::setIndexQuickly): + (JSC::JSObject::initializeIndex): + (JSC::JSObject::completeInitialization): + (JSC::JSObject::inSparseIndexingMode): + (JSC::JSObject::arrayStorage): + (JSC::JSObject::arrayStorageOrNull): + (JSC::JSObject::ensureArrayStorage): + (JSC): + (JSC::JSValue::putByIndex): + * runtime/JSValue.cpp: + (JSC::JSValue::putToPrimitive): + (JSC::JSValue::putToPrimitiveByIndex): + (JSC): + * runtime/JSValue.h: + (JSValue): + * runtime/ObjectPrototype.cpp: + (JSC::ObjectPrototype::finishCreation): + * runtime/SparseArrayValueMap.cpp: + (JSC::SparseArrayValueMap::putEntry): + (JSC::SparseArrayEntry::put): + (JSC): + * runtime/SparseArrayValueMap.h: + (JSC): + (SparseArrayEntry): + * runtime/Structure.cpp: + (JSC::Structure::anyObjectInChainMayInterceptIndexedAccesses): + (JSC): + (JSC::Structure::suggestedIndexingTransition): + * runtime/Structure.h: + (Structure): + (JSC::Structure::mayInterceptIndexedAccesses): + * runtime/StructureTransitionTable.h: + (JSC::newIndexingType): + +2012-09-17 Filip Pizlo <fpizlo@apple.com> + + Array profiling has convergence issues + https://bugs.webkit.org/show_bug.cgi?id=96891 + + Reviewed by Gavin Barraclough. + + Now each array profiling site merges in the indexing type it observed into + the m_observedArrayModes bitset. The ArrayProfile also uses this to detect + cases where the structure must have gone polymorphic (if the bitset is + polymorphic then the structure must be). This achieves something like the + best of both worlds: on the one hand, we get a probabilistic structure that + we can use to optimize the monomorphic structure case, but on the other hand, + we get an accurate view of the set of types that were encountered. + + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::or32): + (MacroAssemblerARMv7): + * assembler/MacroAssemblerX86.h: + (JSC::MacroAssemblerX86::or32): + (MacroAssemblerX86): + * assembler/MacroAssemblerX86_64.h: + (JSC::MacroAssemblerX86_64::or32): + (MacroAssemblerX86_64): + * assembler/X86Assembler.h: + (X86Assembler): + (JSC::X86Assembler::orl_rm): + * bytecode/ArrayProfile.cpp: + (JSC::ArrayProfile::computeUpdatedPrediction): + * bytecode/ArrayProfile.h: + (JSC::ArrayProfile::addressOfArrayModes): + (JSC::ArrayProfile::structureIsPolymorphic): + * jit/JIT.h: + (JIT): + * jit/JITInlineMethods.h: + (JSC): + (JSC::JIT::emitArrayProfilingSite): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * llint/LowLevelInterpreter.asm: + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-09-17 Mark Lam <mark.lam@apple.com> + + Not reviewed. Added svn:eol-style native to unbreak some build bots. + https://bugs.webkit.org/show_bug.cgi?id=96175. + + * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj: Added property svn:eol-style. + * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj: Added property svn:eol-style. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj: Added property svn:eol-style. + +2012-09-16 Mark Lam <mark.lam@apple.com> + + Added MSVC project changes to enable building the llint. + https://bugs.webkit.org/show_bug.cgi?id=96175. + + Reviewed by Geoff Garen. + + This only adds the ability to build the llint, but currently, only the + C++ backend is supported. By default, the Windows port will remain + running with the baseline JIT. The llint will not be enabled. + + * JavaScriptCore.vcproj/JavaScriptCore.sln: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.vcproj/LLIntAssembly: Added. + * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.make: Added. + * JavaScriptCore.vcproj/LLIntAssembly/LLIntAssembly.vcproj: Added. + * JavaScriptCore.vcproj/LLIntAssembly/build-LLIntAssembly.sh: Added. + * JavaScriptCore.vcproj/LLIntDesiredOffsets: Added. + * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.make: Added. + * JavaScriptCore.vcproj/LLIntDesiredOffsets/LLIntDesiredOffsets.vcproj: Added. + * JavaScriptCore.vcproj/LLIntDesiredOffsets/build-LLIntDesiredOffsets.sh: Added. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor: Added. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractor.vcproj: Added. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorCommon.vsprops: Added. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorDebug.vsprops: Added. + * JavaScriptCore.vcproj/LLIntOffsetsExtractor/LLIntOffsetsExtractorRelease.vsprops: Added. + +2012-09-16 Filip Pizlo <fpizlo@apple.com> + + JSObject.cpp and JSArray.cpp have inconsistent tests for the invalid array index case + https://bugs.webkit.org/show_bug.cgi?id=96878 + + Reviewed by Sam Weinig. + + Removed the uses of UNLIKELY() because I don't believe they are buying us anything, + since we're already on the slow path. Also found other places where we're testing for + the invalid array index case using unusual predicates rather than just using + MAX_ARRAY_INDEX. With this change, I believe that all of our tests for invalid + array indices (i.e. indices that should be treated as non-indexed properties) + uniformly use MAX_ARRAY_INDEX and PropertyName::NotAnIndex. + + * runtime/JSArray.cpp: + (JSC::JSArray::push): + * runtime/JSObject.cpp: + (JSC::JSObject::putByIndex): + (JSC::JSObject::defineOwnIndexedProperty): + +2012-09-15 Filip Pizlo <fpizlo@apple.com> + + Following the Butterfly refactoring, the comment for lastArraySize was not updated + https://bugs.webkit.org/show_bug.cgi?id=96877 + + Reviewed by Sam Weinig. + + * runtime/JSObject.cpp: + (JSC): + +2012-09-15 Mark Lam <mark.lam@apple.com> + + Fixed JSLock to use the platform abstraction for Mutex instead of + depending on pthreads. + https://bugs.webkit.org/show_bug.cgi?id=96858. + + Reviewed by Filip Pizlo. + + This fixes a synchronization problem on the Windows port and makes + it more reliable when running the layout tests. + + * runtime/InitializeThreading.cpp: + (JSC::initializeThreadingOnce): + * runtime/JSLock.cpp: + (JSC): + (JSC::GlobalJSLock::GlobalJSLock): + (JSC::GlobalJSLock::~GlobalJSLock): + (JSC::GlobalJSLock::initialize): + * runtime/JSLock.h: + (GlobalJSLock): + (JSLock): + +2012-09-15 Filip Pizlo <fpizlo@apple.com> + + Structure check hoisting fails to consider the possibility of conflicting checks on the source of the first assignment to the hoisted variable + https://bugs.webkit.org/show_bug.cgi?id=96872 + + Reviewed by Oliver Hunt. + + This does a few related things: + + - It turns off the use of ForceOSRExit for sure-to-fail CheckStructures, because + I noticed that this would sometimes happen for a ForwardCheckStructure. The + problem is that ForceOSRExit exits backwards, not forwards. Since the code that + led to those ForceOSRExit's being inserted was written out of paranoia rather + than need, I removed it. Specifically, I removed the m_isValid = false code + for CheckStructure/StructureTransitionWatchpoint in AbstractState. + + - If a structure check causes a structure set to go empty, we don't want a + PutStructure to revive the set. It should instead be smart enough to realize + that an empty set implies that the code can't execute. This was the only "bug" + that the use of m_isValid = false was preventing. + + - Finally, the main change: structure check hoisting looks at the source of the + SetLocals on structure-check-hoistable variables and ensures that the source + is not checked with a conflicting structure. This is O(n^2) but it does not + show up at all in performance tests. + + The first two parts of this change were auxiliary bugs that were revealed by + the structure check hoister doing bad things. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::initialize): + (JSC::DFG::AbstractState::execute): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-09-14 Filip Pizlo <fpizlo@apple.com> + + All of the things in SparseArrayValueMap should be out-of-line + https://bugs.webkit.org/show_bug.cgi?id=96854 + + Reviewed by Andy Estes. + + Those inline methods were buying us nothing. + + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/JSArray.cpp: + * runtime/JSGlobalData.cpp: + * runtime/JSObject.cpp: + * runtime/RegExpMatchesArray.cpp: + * runtime/SparseArrayValueMap.cpp: + (JSC::SparseArrayValueMap::SparseArrayValueMap): + (JSC): + (JSC::SparseArrayValueMap::~SparseArrayValueMap): + (JSC::SparseArrayValueMap::finishCreation): + (JSC::SparseArrayValueMap::create): + (JSC::SparseArrayValueMap::destroy): + (JSC::SparseArrayValueMap::createStructure): + (JSC::SparseArrayValueMap::add): + (JSC::SparseArrayValueMap::putEntry): + (JSC::SparseArrayValueMap::putDirect): + (JSC::SparseArrayEntry::get): + (JSC::SparseArrayEntry::getNonSparseMode): + (JSC::SparseArrayValueMap::visitChildren): + * runtime/SparseArrayValueMapInlineMethods.h: Removed. + +2012-09-14 Mike West <mkwst@chromium.org> + + JSC should throw a more descriptive exception when blocking 'eval' via CSP. + https://bugs.webkit.org/show_bug.cgi?id=94331 + + Reviewed by Geoffrey Garen. + + Unless explicitly whitelisted, the 'script-src' Content Security Policy + directive blocks 'eval' and 'eval'-like constructs such as + 'new Function()'. When 'eval' is encountered in code, an 'EvalError' is + thrown, but the associated message is poor: "Eval is disabled" doesn't + give developers enough information about why their code isn't behaving + as expected. + + This patch adds an 'errorMessage' parameter to the JavaScriptCore method + used to disable 'eval'; ContentSecurityPolicy has the opportunity to + pass in a more detailed and descriptive error that contains more context + for the developer. + + * runtime/Executable.cpp: + (JSC::EvalExecutable::compileInternal): + Drop the hard-coded "Eval is disabled" error message in favor of + reading the error message off the global object. + * runtime/FunctionConstructor.cpp: + (JSC::FunctionConstructor::getCallData): + Drop the hard-coded "Function constructor is disabled" error message + in favor of reading the error message off the global object. + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::evalEnabled): + Making this accessor method const. + (JSC::JSGlobalObject::evalDisabledErrorMessage): + Accessor for the error message set via 'setEvalDisabled'. + (JSC::JSGlobalObject::setEvalEnabled): + Adding an 'errorMessage' parameter which is stored on the global + object, and used when exceptions are thrown. + +2012-09-14 Filip Pizlo <fpizlo@apple.com> + + bbc homepage crashes immediately + https://bugs.webkit.org/show_bug.cgi?id=96812 + <rdar://problem/12081386> + + Reviewed by Oliver Hunt. + + If you use the old storage pointer to write to space you thought was newly allocated, + you're going to have a bad time. + + * runtime/JSArray.cpp: + (JSC::JSArray::unshiftCount): + +2012-09-14 Adam Barth <abarth@webkit.org> + + Remove webkitPostMessage + https://bugs.webkit.org/show_bug.cgi?id=96577 + + Reviewed by Ojan Vafai. + + Add ENABLE_LEGACY_VENDOR_PREFIXES flag. + + * Configurations/FeatureDefines.xcconfig: + +2012-09-14 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + [Qt] Make force_static_libs_as_shared work on Mac OS + + We had to move a few LIBS += around that were in the wrong place, + and not caught when everything was just linked into the final + QtWebKit library. + + Reviewed by Simon Hausmann. + + * jsc.pro: No need for AppKit, we get it from WTF.pri + +2012-09-14 Kevin Funk <kevin.funk@kdab.com> + + Fix interpreter build + https://bugs.webkit.org/show_bug.cgi?id=96617 + + Reviewed by Simon Hausmann. + + Make compile. + + * interpreter/Interpreter.cpp: + +2012-09-14 Parth Patel <parpatel@rim.com> + + [BlackBerry] Switching from Slogger to Slogger2 requires changes in CMakeList of + webkit in order to include libraries of slog2 + https://bugs.webkit.org/show_bug.cgi?id=96391 + + Reviewed by Yong Li. + + Changes in Cmake files of JavaScriptCore of webkit to include slog2 libs in build + files of webkit in response to switching from Slogger to Slogger2. + + * shell/PlatformBlackBerry.cmake: + +2012-09-14 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove the Zapped BlockState + https://bugs.webkit.org/show_bug.cgi?id=96708 + + Reviewed by Geoffrey Garen. + + The Zapped block state is rather confusing. It indicates that a block is in one of two different states that we + can't tell the difference between: + + 1) I have run all destructors of things that are zapped, and I have not allocated any more objects. This block + is ready for reclaiming if you so choose. + 2) I have run all the destructors of things that are zapped, but I have allocated more stuff since then, so it + is not safe to reclaim this block. + + This state adds a lot of complexity to our state transition model for MarkedBlocks. We should get rid of it. + We can replace this state by making sure mark bits represent all of the liveness information we need when running + our conservative stack scan. Instead of zapping the free list when canonicalizing cell liveness data prior to + a conservative scan, we can instead mark all objects in the block except for those in the free list. This should + incur no performance penalty since we're doing it on a very small O(1) number of blocks at the beginning of the collection. + + For the time being we still need to use zapping to determine whether we have run an object's destructor or not. + + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::tryAllocateHelper): Renaming stuff. + * heap/MarkedAllocator.h: Renamed zapFreeList to canonicalizeCellLivenessData to match. + (MarkedAllocator): + (JSC::MarkedAllocator::canonicalizeCellLivenessData): Same as old zapFreeList, but just call canonicalize instead. + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::specializedSweep): Remove the check for Zapped block stuff. Also change the block state to Marked + instead of Zapped if we're not producing a FreeList since that's the only other state that really makes any sense. + (JSC::MarkedBlock::sweepHelper): Remove Zapped related code. + (SetAllMarksFunctor): Functor to set all the mark bits in the block since there's not a simple function to call on + the Bitmap itself. + (JSC::SetAllMarksFunctor::operator()): + (JSC): + (JSC::MarkedBlock::canonicalizeCellLivenessData): Remove all the stuff for Zapped. For FreeListed, set all the mark bits + and then clear the ones for the objects in the FreeList. This ensures that only the things that were in the FreeList + are considered to be dead by the conservative scan, just like if we were to have zapped the FreeList like before. + * heap/MarkedBlock.h: + (MarkedBlock): + (JSC::MarkedBlock::clearMarked): Add function to clear individual mark bits, since we need that functionality now. + (JSC): + (JSC::MarkedBlock::isLive): Remove code for Zapped stuff. Marked handles all interesting cases now. + (JSC::MarkedBlock::forEachCell): Add new iterator function that iterates over all cells in the block, regardless of + whether they're live or a dead. + * heap/MarkedSpace.cpp: + (JSC::MarkedSpace::canonicalizeCellLivenessData): Change to call the renamed canonicalize function. + +2012-09-13 Kevin Funk <kevin.funk@kdab.com> + + Make compile with both OS(WINCE) and PLATFORM(QT) support + https://bugs.webkit.org/show_bug.cgi?id=95536 + + Reviewed by Simon Hausmann. + + Do not link against advapi32 on wince + + * jsc.pro: + +2012-09-13 Geoffrey Garen <ggaren@apple.com> + + Refactored the DFG to make fewer assumptions about variable capture + https://bugs.webkit.org/show_bug.cgi?id=96680 + + Reviewed by Gavin Barraclough. + + A variable capture optimization patch I'm working on broke DFG + correctness and the arguments simplification optimization phase, so I've + refactored both to make fewer assumptions about variable capture. + + * bytecode/CodeBlock.h: + (JSC::CodeBlock::isCaptured): This is the new One True Way to find out + if a variable was captured. This gives us a single point of maintenance + as we chagne capture behavior. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::clobberCapturedVars): Don't assume that captured + variables have any particular location. Instead, ask the One True Function. + + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): Mechanical + changes to separate being captured from being 'arguments'. What used + to be + if (captured) + if (arguments) + x + y + is now + if (arguments) + x + y + else if (captured) + y + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::getLocal): + (JSC::DFG::ByteCodeParser::setLocal): + (JSC::DFG::ByteCodeParser::getArgument): + (JSC::DFG::ByteCodeParser::setArgument): + (JSC::DFG::ByteCodeParser::flushDirect): + (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compile): Use the One True Function. + +2012-09-13 Benjamin Poulain <bpoulain@apple.com> + + Improve the SourceProvider hierarchy + https://bugs.webkit.org/show_bug.cgi?id=95635 + + Reviewed by Geoffrey Garen. + + SourceProvider was designed to have subclasses magically handling the data without + decoding all of it. The virtual methods length() and getRange() were based + on these assumptions. + + In practice, the magic was in our head, there is no implementation that takes + advantage of that. + + SourceProvider is modified to adopt WebCore's ScriptSourceProvider::source() and base + everything on it. + The code using SourceProvider is also simplified. + + * interpreter/Interpreter.cpp: + (JSC::appendSourceToError): Keep a reference to the string instead of querying it for + each time it is used. + * parser/Lexer.cpp: + (JSC::::setCode): + (JSC::::sourceCode): + * parser/Parser.h: + (JSC::parse): + * parser/SourceCode.h: + (JSC::SourceCode::SourceCode): + (JSC::SourceCode::subExpression): + * parser/SourceProvider.h: + (SourceProvider): + (JSC::SourceProvider::getRange): + +2012-09-13 Filip Pizlo <fpizlo@apple.com> + + DFG: Dead GetButterfly's shouldn't be subject to CSE + https://bugs.webkit.org/show_bug.cgi?id=96707 + <rdar://problem/12296311> + + Reviewed by Oliver Hunt. + + There were a number of cases of this that creeped into the CSE: it would + match something even though it was dead. + + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::checkArrayElimination): + (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::getScopeChainLoadElimination): + (JSC::DFG::CSEPhase::getLocalLoadElimination): + +2012-09-13 Oliver Hunt <oliver@apple.com> + + Make global const initialisation explicit in the bytecode + https://bugs.webkit.org/show_bug.cgi?id=96711 + + Reviewed by Gavin Barraclough. + + Added op_init_global_const to make initialisation of global const + fields explicit. This will help us keep correct semantics in the + upcoming variable resolution refactoring. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitInitGlobalConst): + (JSC): + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + * bytecompiler/NodesCodegen.cpp: + (JSC::ConstDeclNode::emitCodeSingle): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-09-13 Mark Hahnenberg <mhahnenberg@apple.com> + + Rename forEachCell to forEachLiveCell + https://bugs.webkit.org/show_bug.cgi?id=96685 + + Reviewed by Oliver Hunt. + + forEachCell actually only iterates over live cells. We should rename it to + reflect what it actually does. This is also helpful because we want to add a new + forEachCell that actually does iterate each and every cell in a MarkedBlock + regardless of whether or not it is live. + + * debugger/Debugger.cpp: + (JSC::Debugger::recompileAllJSFunctions): + * heap/Heap.cpp: + (JSC::Heap::globalObjectCount): + (JSC::Heap::objectTypeCounts): + * heap/MarkedBlock.h: + (MarkedBlock): + (JSC::MarkedBlock::forEachLiveCell): + * heap/MarkedSpace.h: + (MarkedSpace): + (JSC::MarkedSpace::forEachLiveCell): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::releaseExecutableMemory): + +2012-09-13 Filip Pizlo <fpizlo@apple.com> + + [Qt][Win] REGRESSION(r128400): It broke the build + https://bugs.webkit.org/show_bug.cgi?id=96617 + + Reviewed by Simon Hausmann. + + Changed "JSC::Array" to "JSC::ArrayClass" because it's not used often enough + for the brevity to be beneficial, and because "Array" causes too much namespace + pollution. + + * runtime/IndexingType.h: + (JSC): + * runtime/JSArray.cpp: + (JSC::JSArray::pop): + (JSC::JSArray::push): + (JSC::JSArray::sortNumeric): + (JSC::JSArray::sort): + (JSC::JSArray::fillArgList): + (JSC::JSArray::copyToArguments): + (JSC::JSArray::compactForSorting): + * runtime/JSObject.cpp: + (JSC::JSObject::getOwnPropertySlotByIndex): + (JSC::JSObject::putByIndex): + (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode): + (JSC::JSObject::deletePropertyByIndex): + (JSC::JSObject::getOwnPropertyNames): + (JSC::JSObject::putByIndexBeyondVectorLength): + (JSC::JSObject::putDirectIndexBeyondVectorLength): + (JSC::JSObject::getNewVectorLength): + (JSC::JSObject::getOwnPropertyDescriptor): + * runtime/JSObject.h: + (JSC::JSObject::getArrayLength): + (JSC::JSObject::getVectorLength): + (JSC::JSObject::canGetIndexQuickly): + (JSC::JSObject::canSetIndexQuickly): + (JSC::JSObject::inSparseIndexingMode): + (JSC::JSObject::ensureArrayStorage): + +2012-09-13 Filip Pizlo <fpizlo@apple.com> + + Testing whether indexing type is ArrayWithArrayStorage should not compare against ArrayWithArrayStorage + https://bugs.webkit.org/show_bug.cgi?id=96611 + + Reviewed by Gavin Barraclough. + + * dfg/DFGRepatch.cpp: + (JSC::DFG::tryCacheGetByID): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::checkArray): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::privateCompilePatchGetArrayLength): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::privateCompilePatchGetArrayLength): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-09-09 Filip Pizlo <fpizlo@apple.com> + + JSC should have property butterflies + https://bugs.webkit.org/show_bug.cgi?id=91933 + + Reviewed by Geoffrey Garen. + + This changes the JSC object model. Previously, all objects had fast lookup for + named properties. Integer indexed properties were only fast if you used a + JSArray. With this change, all objects have fast indexed properties. This is + accomplished without any space overhead by using a bidirectional object layout, + aka butterflies. Each JSObject has a m_butterfly pointer where previously it + had a m_outOfLineStorage pointer. To the left of the location pointed to by + m_butterfly, we place all named out-of-line properties. To the right, we place + all indexed properties along with indexing meta-data. Though, some indexing + meta-data is placed in the 8-byte word immediately left of the pointed-to + location; this is in anticipation of the indexing meta-data being small enough + in the common case that m_butterfly always points to the first indexed + property. + + This is performance neutral, except on tests that use indexed properties on + plain objects, where the speed-up is in excess of an order of magnitude. + + One notable aspect of what this change brings is that it allows indexing + storage to morph over time. Currently this is only used to allow all non-array + objects to start out without any indexed storage. But it could be used for + some kinds of array type inference in the future. + + * API/JSCallbackObject.h: + (JSCallbackObject): + * API/JSCallbackObjectFunctions.h: + (JSC::::getOwnPropertySlotByIndex): + (JSC): + (JSC::::getOwnNonIndexPropertyNames): + * API/JSObjectRef.cpp: + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/ArrayProfile.h: + (JSC): + (JSC::arrayModeFromStructure): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitDirectPutById): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGAdjacencyList.h: + (JSC::DFG::AdjacencyList::AdjacencyList): + (AdjacencyList): + * dfg/DFGArrayMode.cpp: + (JSC::DFG::fromObserved): + (JSC::DFG::modeAlreadyChecked): + (JSC::DFG::modeToString): + * dfg/DFGArrayMode.h: + (DFG): + (JSC::DFG::modeUsesButterfly): + (JSC::DFG::modeIsJSArray): + (JSC::DFG::isInBoundsAccess): + (JSC::DFG::modeSupportsLength): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleGetByOffset): + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + (JSC::DFG::FixupPhase::addNode): + (FixupPhase): + (JSC::DFG::FixupPhase::checkArray): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::byValIsPure): + * dfg/DFGNode.h: + (JSC::DFG::Node::Node): + (Node): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOperations.cpp: + (JSC::DFG::putByVal): + * dfg/DFGOperations.h: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGRepatch.cpp: + (JSC::DFG::generateProtoChainAccessStub): + (JSC::DFG::tryCacheGetByID): + (JSC::DFG::tryBuildGetByIDList): + (JSC::DFG::emitPutReplaceStub): + (JSC::DFG::emitPutTransitionStub): + (JSC::DFG::tryBuildPutByIdList): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::checkArray): + (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): + (JSC::DFG::SpeculativeJIT::compileGetArrayLength): + (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): + (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::cachedGetById): + (JSC::DFG::SpeculativeJIT::cachedPutById): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::cachedGetById): + (JSC::DFG::SpeculativeJIT::cachedPutById): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + * heap/CopiedSpace.h: + (CopiedSpace): + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + (JSC::JIT::emitAllocateBasicStorage): + (JSC::JIT::emitAllocateJSArray): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_new_array): + (JSC::JIT::emitSlow_op_new_array): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::compileGetDirectOffset): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::emit_op_put_by_id): + (JSC::JIT::compilePutDirectOffset): + (JSC::JIT::privateCompilePatchGetArrayLength): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::emit_op_put_by_id): + (JSC::JIT::compilePutDirectOffset): + (JSC::JIT::compileGetDirectOffset): + (JSC::JIT::privateCompilePatchGetArrayLength): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jsc.cpp: + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter.asm: + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/Arguments.cpp: + (JSC::Arguments::deletePropertyByIndex): + (JSC::Arguments::defineOwnProperty): + * runtime/ArrayConstructor.cpp: + * runtime/ArrayConventions.h: Added. + (JSC): + (JSC::isDenseEnoughForVector): + (JSC::indexingHeaderForArray): + (JSC::baseIndexingHeaderForArray): + * runtime/ArrayPrototype.cpp: + (JSC::ArrayPrototype::create): + (JSC): + (JSC::ArrayPrototype::ArrayPrototype): + (JSC::arrayProtoFuncToString): + (JSC::arrayProtoFuncJoin): + (JSC::arrayProtoFuncSort): + (JSC::arrayProtoFuncFilter): + (JSC::arrayProtoFuncMap): + (JSC::arrayProtoFuncEvery): + (JSC::arrayProtoFuncForEach): + (JSC::arrayProtoFuncSome): + (JSC::arrayProtoFuncReduce): + (JSC::arrayProtoFuncReduceRight): + * runtime/ArrayPrototype.h: + (ArrayPrototype): + (JSC::ArrayPrototype::createStructure): + * runtime/ArrayStorage.h: Added. + (JSC): + (ArrayStorage): + (JSC::ArrayStorage::ArrayStorage): + (JSC::ArrayStorage::from): + (JSC::ArrayStorage::butterfly): + (JSC::ArrayStorage::indexingHeader): + (JSC::ArrayStorage::length): + (JSC::ArrayStorage::setLength): + (JSC::ArrayStorage::vectorLength): + (JSC::ArrayStorage::setVectorLength): + (JSC::ArrayStorage::copyHeaderFromDuringGC): + (JSC::ArrayStorage::inSparseMode): + (JSC::ArrayStorage::lengthOffset): + (JSC::ArrayStorage::vectorLengthOffset): + (JSC::ArrayStorage::numValuesInVectorOffset): + (JSC::ArrayStorage::vectorOffset): + (JSC::ArrayStorage::indexBiasOffset): + (JSC::ArrayStorage::sparseMapOffset): + (JSC::ArrayStorage::sizeFor): + * runtime/Butterfly.h: Added. + (JSC): + (Butterfly): + (JSC::Butterfly::Butterfly): + (JSC::Butterfly::totalSize): + (JSC::Butterfly::fromBase): + (JSC::Butterfly::offsetOfIndexingHeader): + (JSC::Butterfly::offsetOfPublicLength): + (JSC::Butterfly::offsetOfVectorLength): + (JSC::Butterfly::indexingHeader): + (JSC::Butterfly::propertyStorage): + (JSC::Butterfly::indexingPayload): + (JSC::Butterfly::arrayStorage): + (JSC::Butterfly::offsetOfPropertyStorage): + (JSC::Butterfly::indexOfPropertyStorage): + (JSC::Butterfly::base): + * runtime/ButterflyInlineMethods.h: Added. + (JSC): + (JSC::Butterfly::createUninitialized): + (JSC::Butterfly::create): + (JSC::Butterfly::createUninitializedDuringCollection): + (JSC::Butterfly::base): + (JSC::Butterfly::growPropertyStorage): + (JSC::Butterfly::growArrayRight): + (JSC::Butterfly::resizeArray): + (JSC::Butterfly::unshift): + (JSC::Butterfly::shift): + * runtime/ClassInfo.h: + (MethodTable): + (JSC): + * runtime/IndexingHeader.h: Added. + (JSC): + (IndexingHeader): + (JSC::IndexingHeader::offsetOfIndexingHeader): + (JSC::IndexingHeader::offsetOfPublicLength): + (JSC::IndexingHeader::offsetOfVectorLength): + (JSC::IndexingHeader::IndexingHeader): + (JSC::IndexingHeader::vectorLength): + (JSC::IndexingHeader::setVectorLength): + (JSC::IndexingHeader::publicLength): + (JSC::IndexingHeader::setPublicLength): + (JSC::IndexingHeader::from): + (JSC::IndexingHeader::fromEndOf): + (JSC::IndexingHeader::propertyStorage): + (JSC::IndexingHeader::arrayStorage): + (JSC::IndexingHeader::butterfly): + * runtime/IndexingHeaderInlineMethods.h: Added. + (JSC): + (JSC::IndexingHeader::preCapacity): + (JSC::IndexingHeader::indexingPayloadSizeInBytes): + * runtime/IndexingType.h: Added. + (JSC): + (JSC::hasIndexingHeader): + * runtime/JSActivation.cpp: + (JSC::JSActivation::JSActivation): + (JSC::JSActivation::visitChildren): + (JSC::JSActivation::getOwnNonIndexPropertyNames): + * runtime/JSActivation.h: + (JSActivation): + (JSC::JSActivation::tearOff): + * runtime/JSArray.cpp: + (JSC): + (JSC::createArrayButterflyInDictionaryIndexingMode): + (JSC::JSArray::setLengthWritable): + (JSC::JSArray::defineOwnProperty): + (JSC::JSArray::getOwnPropertySlot): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::put): + (JSC::JSArray::deleteProperty): + (JSC::JSArray::getOwnNonIndexPropertyNames): + (JSC::JSArray::unshiftCountSlowCase): + (JSC::JSArray::setLength): + (JSC::JSArray::pop): + (JSC::JSArray::push): + (JSC::JSArray::shiftCount): + (JSC::JSArray::unshiftCount): + (JSC::JSArray::sortNumeric): + (JSC::JSArray::sort): + (JSC::JSArray::fillArgList): + (JSC::JSArray::copyToArguments): + (JSC::JSArray::compactForSorting): + * runtime/JSArray.h: + (JSC): + (JSArray): + (JSC::JSArray::JSArray): + (JSC::JSArray::length): + (JSC::JSArray::createStructure): + (JSC::JSArray::isLengthWritable): + (JSC::createArrayButterfly): + (JSC::JSArray::create): + (JSC::JSArray::tryCreateUninitialized): + * runtime/JSBoundFunction.cpp: + (JSC::boundFunctionCall): + (JSC::boundFunctionConstruct): + (JSC::JSBoundFunction::finishCreation): + * runtime/JSCell.cpp: + (JSC::JSCell::getOwnNonIndexPropertyNames): + (JSC): + * runtime/JSCell.h: + (JSCell): + * runtime/JSFunction.cpp: + (JSC::JSFunction::getOwnPropertySlot): + (JSC::JSFunction::getOwnPropertyDescriptor): + (JSC::JSFunction::getOwnNonIndexPropertyNames): + (JSC::JSFunction::defineOwnProperty): + * runtime/JSFunction.h: + (JSFunction): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSGlobalData): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + * runtime/JSONObject.cpp: + (JSC::Stringifier::Holder::appendNextProperty): + (JSC::Walker::walk): + * runtime/JSObject.cpp: + (JSC): + (JSC::JSObject::visitButterfly): + (JSC::JSObject::visitChildren): + (JSC::JSFinalObject::visitChildren): + (JSC::JSObject::getOwnPropertySlotByIndex): + (JSC::JSObject::put): + (JSC::JSObject::putByIndex): + (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists): + (JSC::JSObject::enterDictionaryIndexingMode): + (JSC::JSObject::createArrayStorage): + (JSC::JSObject::createInitialArrayStorage): + (JSC::JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode): + (JSC::JSObject::putDirectAccessor): + (JSC::JSObject::deleteProperty): + (JSC::JSObject::deletePropertyByIndex): + (JSC::JSObject::getOwnPropertyNames): + (JSC::JSObject::getOwnNonIndexPropertyNames): + (JSC::JSObject::preventExtensions): + (JSC::JSObject::fillGetterPropertySlot): + (JSC::JSObject::putIndexedDescriptor): + (JSC::JSObject::defineOwnIndexedProperty): + (JSC::JSObject::allocateSparseIndexMap): + (JSC::JSObject::deallocateSparseIndexMap): + (JSC::JSObject::putByIndexBeyondVectorLengthWithArrayStorage): + (JSC::JSObject::putByIndexBeyondVectorLength): + (JSC::JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage): + (JSC::JSObject::putDirectIndexBeyondVectorLength): + (JSC::JSObject::getNewVectorLength): + (JSC::JSObject::increaseVectorLength): + (JSC::JSObject::checkIndexingConsistency): + (JSC::JSObject::growOutOfLineStorage): + (JSC::JSObject::getOwnPropertyDescriptor): + (JSC::putDescriptor): + (JSC::JSObject::putDirectMayBeIndex): + (JSC::JSObject::defineOwnNonIndexProperty): + (JSC::JSObject::defineOwnProperty): + (JSC::JSObject::getOwnPropertySlotSlow): + * runtime/JSObject.h: + (JSC::JSObject::getArrayLength): + (JSObject): + (JSC::JSObject::getVectorLength): + (JSC::JSObject::putDirectIndex): + (JSC::JSObject::canGetIndexQuickly): + (JSC::JSObject::getIndexQuickly): + (JSC::JSObject::canSetIndexQuickly): + (JSC::JSObject::setIndexQuickly): + (JSC::JSObject::initializeIndex): + (JSC::JSObject::completeInitialization): + (JSC::JSObject::inSparseIndexingMode): + (JSC::JSObject::butterfly): + (JSC::JSObject::outOfLineStorage): + (JSC::JSObject::offsetForLocation): + (JSC::JSObject::indexingShouldBeSparse): + (JSC::JSObject::butterflyOffset): + (JSC::JSObject::butterflyAddress): + (JSC::JSObject::arrayStorage): + (JSC::JSObject::arrayStorageOrZero): + (JSC::JSObject::ensureArrayStorage): + (JSC::JSObject::checkIndexingConsistency): + (JSC::JSNonFinalObject::JSNonFinalObject): + (JSC): + (JSC::JSObject::setButterfly): + (JSC::JSObject::setButterflyWithoutChangingStructure): + (JSC::JSObject::JSObject): + (JSC::JSObject::inlineGetOwnPropertySlot): + (JSC::JSObject::putDirectInternal): + (JSC::JSObject::setStructureAndReallocateStorageIfNecessary): + (JSC::JSObject::putDirectWithoutTransition): + (JSC::offsetInButterfly): + (JSC::offsetRelativeToPatchedStorage): + (JSC::indexRelativeToBase): + (JSC::offsetRelativeToBase): + * runtime/JSPropertyNameIterator.cpp: + (JSC::JSPropertyNameIterator::create): + * runtime/JSSymbolTableObject.cpp: + (JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames): + * runtime/JSSymbolTableObject.h: + (JSSymbolTableObject): + * runtime/JSTypeInfo.h: + (JSC): + (JSC::TypeInfo::interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero): + (JSC::TypeInfo::overridesGetPropertyNames): + * runtime/LiteralParser.cpp: + (JSC::::parse): + * runtime/ObjectConstructor.cpp: + * runtime/ObjectPrototype.cpp: + (JSC::ObjectPrototype::ObjectPrototype): + (JSC): + * runtime/ObjectPrototype.h: + (ObjectPrototype): + * runtime/PropertyOffset.h: + (JSC::offsetInOutOfLineStorage): + * runtime/PropertyStorage.h: Added. + (JSC): + * runtime/PutDirectIndexMode.h: Added. + (JSC): + * runtime/RegExpMatchesArray.cpp: + (JSC::RegExpMatchesArray::RegExpMatchesArray): + (JSC): + (JSC::RegExpMatchesArray::create): + (JSC::RegExpMatchesArray::finishCreation): + * runtime/RegExpMatchesArray.h: + (RegExpMatchesArray): + (JSC::RegExpMatchesArray::createStructure): + * runtime/RegExpObject.cpp: + (JSC::RegExpObject::getOwnNonIndexPropertyNames): + * runtime/RegExpObject.h: + (RegExpObject): + * runtime/Reject.h: Added. + (JSC): + (JSC::reject): + * runtime/SparseArrayValueMap.cpp: Added. + (JSC): + * runtime/SparseArrayValueMap.h: Added. + (JSC): + (SparseArrayEntry): + (JSC::SparseArrayEntry::SparseArrayEntry): + (SparseArrayValueMap): + (JSC::SparseArrayValueMap::sparseMode): + (JSC::SparseArrayValueMap::setSparseMode): + (JSC::SparseArrayValueMap::lengthIsReadOnly): + (JSC::SparseArrayValueMap::setLengthIsReadOnly): + (JSC::SparseArrayValueMap::find): + (JSC::SparseArrayValueMap::remove): + (JSC::SparseArrayValueMap::notFound): + (JSC::SparseArrayValueMap::isEmpty): + (JSC::SparseArrayValueMap::contains): + (JSC::SparseArrayValueMap::size): + (JSC::SparseArrayValueMap::begin): + (JSC::SparseArrayValueMap::end): + * runtime/SparseArrayValueMapInlineMethods.h: Added. + (JSC): + (JSC::SparseArrayValueMap::SparseArrayValueMap): + (JSC::SparseArrayValueMap::~SparseArrayValueMap): + (JSC::SparseArrayValueMap::finishCreation): + (JSC::SparseArrayValueMap::create): + (JSC::SparseArrayValueMap::destroy): + (JSC::SparseArrayValueMap::createStructure): + (JSC::SparseArrayValueMap::add): + (JSC::SparseArrayValueMap::putEntry): + (JSC::SparseArrayValueMap::putDirect): + (JSC::SparseArrayEntry::get): + (JSC::SparseArrayEntry::getNonSparseMode): + (JSC::SparseArrayValueMap::visitChildren): + * runtime/StorageBarrier.h: Removed. + * runtime/StringObject.cpp: + (JSC::StringObject::putByIndex): + (JSC): + (JSC::StringObject::deletePropertyByIndex): + * runtime/StringObject.h: + (StringObject): + * runtime/StringPrototype.cpp: + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC::Structure::materializePropertyMap): + (JSC::Structure::nonPropertyTransition): + (JSC): + * runtime/Structure.h: + (Structure): + (JSC::Structure::indexingType): + (JSC::Structure::indexingTypeIncludingHistory): + (JSC::Structure::indexingTypeOffset): + (JSC::Structure::create): + * runtime/StructureTransitionTable.h: + (JSC): + (JSC::toAttributes): + (JSC::newIndexingType): + (JSC::StructureTransitionTable::Hash::hash): + * tests/mozilla/js1_6/Array/regress-304828.js: + +2012-09-12 Mark Lam <mark.lam@apple.com> + + Refactor Opcodes to distinguish between core and extension opcodes. + https://bugs.webkit.org/show_bug.cgi?id=96466. + + Reviewed by Filip Pizlo. + + * bytecode/Opcode.h: + (JSC): Added FOR_EACH_CORE_OPCODE_ID() macro. + * llint/LowLevelInterpreter.h: + (JSC): Auto-generate llint opcode aliases using the + FOR_EACH_CORE_OPCODE_ID() macro. + +2012-09-11 Geoffrey Garen <ggaren@apple.com> + + Second step to fixing the Windows build: Add new symbols. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-09-11 Geoffrey Garen <ggaren@apple.com> + + First step to fixing the Windows build: Remove old symbols. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-09-11 Geoffrey Garen <ggaren@apple.com> + + Don't allocate a backing store just for a function's name + https://bugs.webkit.org/show_bug.cgi?id=96468 + + Reviewed by Oliver Hunt. + + Treat function.name like function.length etc., and use a custom getter. + This saves space in closures. + + * debugger/DebuggerCallFrame.cpp: + (JSC::DebuggerCallFrame::functionName): + * debugger/DebuggerCallFrame.h: + (DebuggerCallFrame): Updated for interface change. + + * runtime/Executable.h: + (JSC::JSFunction::JSFunction): Do a little inlining. + + * runtime/JSFunction.cpp: + (JSC::JSFunction::finishCreation): Gone now. That's the point of the patch. + + (JSC::JSFunction::name): + (JSC::JSFunction::displayName): + (JSC::JSFunction::nameGetter): + (JSC::JSFunction::getOwnPropertySlot): + (JSC::JSFunction::getOwnPropertyDescriptor): + (JSC::JSFunction::getOwnPropertyNames): + (JSC::JSFunction::put): + (JSC::JSFunction::deleteProperty): + (JSC::JSFunction::defineOwnProperty): Added custom accessors for .name + just like .length and others. + + * runtime/JSFunction.h: + (JSC::JSFunction::create): + (JSFunction): Updated for interface changes. + +2012-09-11 Mark Hahnenberg <mhahnenberg@apple.com> + + IncrementalSweeper should not sweep/free Zapped blocks + https://bugs.webkit.org/show_bug.cgi?id=96464 + + Reviewed by Filip Pizlo. + + This is not beneficial in terms of performance because there isn't any way a block can emerge + in the Zapped state from a call to Heap::collect() unless we run an eager sweep on it, in which + case we've already run all the destructors we possibly can. This also causes bugs since we don't + take zapped-ness into account when determining whether or not a block is empty to free it. The + incremental sweeper can then accidentally free blocks that it thinks are empty but are in fact + zapped with still-live objects in them. + + * heap/MarkedBlock.h: + (JSC::MarkedBlock::needsSweeping): It is only valid to sweep a block if it is in the Marked state. + +2012-09-11 Geoffrey Garen <ggaren@apple.com> + + JSActivation should inline allocate its registers, and eliminate + 'arguments' registers in the common case + https://bugs.webkit.org/show_bug.cgi?id=96427 + + Reviewed by Filip Pizlo. + + This cuts the size class for simple closures down to 64 bytes. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): Set the usesNonStrictEval + flag, which is new. Use a more specific test for whether a function + uses 'arguments', so we can avoid allocating, initializing, and tearing + off those registers in the common case. Distinguish between capturing + arguments and not, so we can avoid allocating space for arguments in + the torn-off object. + + We can make this even more general in the future, with some bytecode + generator refactoring. + + (JSC::BytecodeGenerator::resolve): Updated for new interface. + + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + (JSC::BytecodeGenerator::symbolTable): Updated some types. + + * heap/Heap.cpp: + (JSC::Heap::isValidAllocation): Allow large allocations, now that they + are both supported and used. + + * heap/Heap.h: + (Heap): Added a new form of allocateCell that specifies the full size + of the allocation, to allow for extra space on the end. + + * interpreter/CallFrame.h: + (JSC::ExecState::argumentOffset): + (JSC::ExecState::argumentOffsetIncludingThis): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::unwindCallFrame): Refactored this code to be more + specific about tearing off 'arguments' vs activations. This is something + I forgot in my last patch, and it is required now that we can have + acitvations without 'arguments' registers. + + * runtime/Arguments.h: + (JSC::Arguments::setRegisters): No need for setRegisters anymore because + the activation object's storage doesn't change. + + * runtime/JSActivation.cpp: + (JSC::JSActivation::JSActivation): Initialize our storage manually because + it's not declared to the C++ compiler. + + (JSC::JSActivation::visitChildren): No copyAndAppend because our storage + is not out-of-line anymore. + + (JSC::JSActivation::symbolTableGet): + (JSC::JSActivation::symbolTablePut): + (JSC::JSActivation::getOwnPropertyNames): + (JSC::JSActivation::symbolTablePutWithAttributes): + (JSC::JSActivation::getOwnPropertySlot): + (JSC::JSActivation::getOwnPropertyDescriptor): + (JSC::JSActivation::argumentsGetter): Refactored isTornOff() testing to + avoid using a data member and to avoid hard-coding any offset assumptions. + + * runtime/JSActivation.h: + (JSC): + (JSActivation): + (JSC::JSActivation::create): + (JSC::JSActivation::isDynamicScope): + (JSC::JSActivation::captureStart): + (JSC::JSActivation::storageSize): + (JSC::JSActivation::storageSizeInBytes): + (JSC::JSActivation::registerOffset): + (JSC::JSActivation::tearOff): + (JSC::JSActivation::isTornOff): + (JSC::JSActivation::storage): + (JSC::JSActivation::allocationSize): + (JSC::JSActivation::isValid): New helper functions for doing the math + on our inline storage. Note that in the "AllOfTheThings" tear-off case, + the number of things is not known at compile time, so we store the + number in the argument count register. We can't just copy the raw contents + of the register beacuse we need a value that is safe for precise marking, + and the value in the register file has an invalid tag. + + * runtime/JSCell.h: + (JSC::allocateCell): New function for allocating with extra storage + on the end. + + * runtime/JSSymbolTableObject.h: + (JSC::JSSymbolTableObject::JSSymbolTableObject): + (JSC::JSSymbolTableObject::finishCreation): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::JSVariableObject): + (JSVariableObject): Make it easier for subclasses to use their symbol + tables during construction, by passing the table as a constructor argument. + + * runtime/SymbolTable.h: + (JSC::SharedSymbolTable::usesNonStrictEval): + (JSC::SharedSymbolTable::setUsesNonStrictEval): + (SharedSymbolTable): + (JSC::SharedSymbolTable::captureMode): + (JSC::SharedSymbolTable::setCaptureMode): + (JSC::SharedSymbolTable::captureStart): + (JSC::SharedSymbolTable::setCaptureStart): + (JSC::SharedSymbolTable::captureEnd): + (JSC::SharedSymbolTable::setCaptureEnd): + (JSC::SharedSymbolTable::parameterCountIncludingThis): + (JSC::SharedSymbolTable::setParameterCountIncludingThis): + (JSC::SharedSymbolTable::SharedSymbolTable): Added data members to more + precisely describe what kind of capture is in play, and to avoid having + data members in the activation. We expect N activations per symbol table, + so this can be a big savings in heavy closure usage. + +2012-09-11 Ryuan Choi <ryuan.choi@samsung.com> + + Fix build break with LLINT on 32bit machine after r128219 + https://bugs.webkit.org/show_bug.cgi?id=96461 + + Unreviewed build fix. + + * llint/LowLevelInterpreter32_64.asm: Fixed typo. + +2012-09-11 Michael Saboff <msaboff@apple.com> + + Build fixed for http://trac.webkit.org/changeset/128243 + + Rubber stamped by Stephanie Lewis. + + Added missing include file needed by 96422. + + * icu/unicode/unorm2.h: Added. + +2012-09-11 Michael Saboff <msaboff@apple.com> + + Build fixed for http://trac.webkit.org/changeset/128243 + + Rubber stamped by Stephanie Lewis. + + Added missing include file needed by 96422. + + * icu/unicode/ptypes.h: Added. + +2012-09-11 Michael Saboff <msaboff@apple.com> + + Update ICU header files to more recent version + https://bugs.webkit.org/show_bug.cgi?id=96422 + + Reviewed by Geoff Garen. + + Updated ICU header files to 4.6.1. Modifications made as part of the merge are: + platform.h - Changed ifndef / define / endif for U_HAVE_UINT8_T, U_HAVE_UINT16_T, U_HAVE_UINT32_T, + U_HAVE_UINT64_T, U_IS_BIG_ENDIAN and U_ENABLE_TRACING to match the existing platform.h + putil.h (line 132) - Changes defined(U_WINDOWS) to defined(WIN32) || defined(OS2) to match existing putil.h + ustring.h (line 945) - Wrapped macro argument cs with { (const UChar *)cs } to match existing ustring.h + utypes.h (line 545) - Changed defined(U_WINDOWS) to defined(WIN32) to match existing utypes.h + + * icu/unicode/localpointer.h: Added. + * 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/uscript.h: + * icu/unicode/uset.h: + * icu/unicode/ustring.h: + * icu/unicode/utf.h: + * icu/unicode/utf16.h: + * icu/unicode/utf8.h: + * icu/unicode/utypes.h: + * icu/unicode/uvernum.h: Added. + * icu/unicode/uversion.h: + +2012-09-11 Matt Lilek <mrl@apple.com> + + OS X port should compile with newer versions of clang + https://bugs.webkit.org/show_bug.cgi?id=96434 + + m_identIsVarDecl is unused - remove it. + + Reviewed by Anders Carlsson. + + * parser/NodeConstructors.h: + (JSC::ForInNode::ForInNode): + * parser/Nodes.h: + (ForInNode): + +2012-09-11 Filip Pizlo <fpizlo@apple.com> + + LLInt should optimize and profile array length accesses + https://bugs.webkit.org/show_bug.cgi?id=96417 + + Reviewed by Oliver Hunt. + + This fixes the following hole in our array profiling strategy, where the array + is large (more than 1000 elements): + + for (var i = 0; i < array.length; ++i) ... + + The peeled use of array.length (in the array prologue) will execute only once + before DFG optimization kicks in from the loop's OSR point. Since it executed + only once, it executed in the LLInt. And prior to this patch, the LLInt did + not profile array.length accesses - so the DFG will assume, based on the lack + of profiling, that the access is in fact not an access to the JSArray length + property. That could then impede our ability to hoist the array structure + check, and may make us pessimistic in other ways as well, since the generic + GetById used for the array length access will be viewed as a side-effecting + operation. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::printGetByIdCacheStatus): + (JSC::CodeBlock::finalizeUnconditionally): + * bytecode/GetByIdStatus.cpp: + (JSC::GetByIdStatus::computeFromLLInt): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter.asm: + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-09-11 Raphael Kubo da Costa <rakuco@webkit.org> + + [EFL] Rewrite the EFL-related Find modules + https://bugs.webkit.org/show_bug.cgi?id=95237 + + Reviewed by Kenneth Rohde Christiansen. + + * CMakeLists.txt: Stop setting the LINK_FLAGS property. + * PlatformEfl.cmake: Ditto. + * shell/PlatformEfl.cmake: Ditto. + +2012-09-11 Raphael Kubo da Costa <rakuco@webkit.org> + + [EFL] Unreviewed build fix after r128065. + + * CMakeLists.txt: Link against WTF for FastMalloc symbols, which + are needed when building with SYSTEM_MALLOC off. + +2012-09-10 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove m_classInfo from JSCell + https://bugs.webkit.org/show_bug.cgi?id=96311 + + Reviewed by Oliver Hunt. + + Now that no one is using the ClassInfo in JSCell, we can remove it for the greater good. This is a 1.5% win on v8v7 and + a 1.7% win on kraken, and is an overall performance progression. + + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): Had to rearrange the order of when we take things off the free list + and when we store the Structure in the object because we would clobber the free list otherwise. This made it not okay for + the structure argument and the scratch register to alias one another. Also removed the store of the ClassInfo pointer in the + object. Yay! + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: Since it's no longer okay for for the scratch register and structure register to alias + one another as stated above, had to add an extra temporary for passing the Structure. + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: Ditto. + (JSC::DFG::SpeculativeJIT::compile): + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): Similar changes to DFG's inline allocation except that it removed the object from + the free list first, so no changes were necessary there. + * llint/LowLevelInterpreter.asm: Change the constants for amount of inline storage to match PropertyOffset.h and remove + the store of the ClassInfo pointer during inline allocation. + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/JSCell.h: Remove the m_classInfo field and associated methods. + (JSCell): + * runtime/JSObject.h: + (JSObject): + * runtime/PropertyOffset.h: Expand the number of inline storage properties to take up the extra space that we're freeing + with the removal of the ClassInfo pointer. + (JSC): + * runtime/Structure.h: + (JSC): + (JSC::JSCell::JSCell): + (JSC::JSCell::finishCreation): + +2012-09-10 Geoffrey Garen <ggaren@apple.com> + + Added large allocation support to MarkedSpace + https://bugs.webkit.org/show_bug.cgi?id=96214 + + Originally reviewed by Oliver Hunt, then I added a design revision by + suggested by Phil Pizlo. + + I expanded the imprecise size classes to cover up to 32KB, then added + an mmap-based allocator for everything bigger. There's a lot of tuning + we could do in these size classes, but currently they're almost + completely unused, so I haven't done any tuning. + + Subtle point: the large allocator is a degenerate case of our free list + logic. Its list only ever contains zero or one items. + + * heap/Heap.h: + (JSC::Heap::allocateStructure): Pipe in size information. + + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::tryAllocateHelper): Handle the case where we + find a free item in the sweep list but the item isn't big enough. This + can happen in the large allocator because it mixes sizes. + + (JSC::MarkedAllocator::tryAllocate): + (JSC::MarkedAllocator::allocateSlowCase): More piping. + + (JSC::MarkedAllocator::allocateBlock): Handle the oversize case. + + (JSC::MarkedAllocator::addBlock): I moved the call to didAddBlock here + because it made more sense. + + * heap/MarkedAllocator.h: + (MarkedAllocator): + (JSC::MarkedAllocator::allocate): + * heap/MarkedSpace.cpp: + (JSC::MarkedSpace::MarkedSpace): + (JSC::MarkedSpace::resetAllocators): + (JSC::MarkedSpace::canonicalizeCellLivenessData): + (JSC::MarkedSpace::isPagedOut): + (JSC::MarkedSpace::freeBlock): + * heap/MarkedSpace.h: + (MarkedSpace): + (JSC::MarkedSpace::allocatorFor): + (JSC::MarkedSpace::destructorAllocatorFor): + (JSC::MarkedSpace::allocateWithoutDestructor): + (JSC::MarkedSpace::allocateWithDestructor): + (JSC::MarkedSpace::allocateStructure): + (JSC::MarkedSpace::forEachBlock): + * runtime/Structure.h: + (JSC::Structure): More piping. + +2012-09-10 Geoffrey Garen <ggaren@apple.com> + + Try to fix the Windows (32-bit) build. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_tear_off_arguments): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_tear_off_arguments): Get operands 1 and 2, not 1 and 1. :( + + Also took this opportunity to rename to indicate that these values are + not destinations anymore. + +2012-09-10 Geoffrey Garen <ggaren@apple.com> + + DFG misses arguments tear-off for function.arguments if 'arguments' is used + https://bugs.webkit.org/show_bug.cgi?id=96227 + + Reviewed by Gavin Barraclough. + + We've decided not to allow function.arguments to alias the local + 'arguments' object, or a local var or function named 'arguments'. + Aliasing complicates the implementation (cf, this bug) and can produce + surprising behavior for web programmers. + + Eliminating the aliasing has the side-effect of fixing this bug. + + The compatibilty story: function.arguments is deprecated, was never + specified, and throws an exception in strict mode, so we expect it to + disappear over time. Firefox does not alias to 'arguments'; Chrome + does, but not if you use eval or with; IE does; Safari did. + + * dfg/DFGByteCodeParser.cpp: Noticed a little cleanup while verifying + this code. Use the CodeBlock method for better encapsulation. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::retrieveArgumentsFromVMCode): Behavior change: don't + alias. + + * tests/mozilla/js1_4/Functions/function-001.js: + (TestFunction_4): Updated test expectations for changed behavior. + +2012-09-10 Filip Pizlo <fpizlo@apple.com> + + offlineasm has some impossible to implement, and unused, instructions + https://bugs.webkit.org/show_bug.cgi?id=96310 + + Reviewed by Mark Hahnenberg. + + * offlineasm/armv7.rb: + * offlineasm/instructions.rb: + * offlineasm/x86.rb: + +2012-09-09 Geoffrey Garen <ggaren@apple.com> + + Refactored op_tear_off* to support activations that don't allocate space for 'arguments' + https://bugs.webkit.org/show_bug.cgi?id=96231 + + Reviewed by Gavin Barraclough. + + This is a step toward smaller activations. + + As a side-effect, this patch eliminates a load and branch from the hot path + of activation tear-off by moving it to the cold path of arguments tear-off. Our + optimizing assumptions are that activations are common and that reifying the + arguments object is less common. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + (JSC::padOpcodeName): Updated for new opcode lengths. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::addConstantValue): Added support for JSValue() + in the bytecode, which we use when we have 'arguments' but no activation. + + (JSC::BytecodeGenerator::emitReturn): Always emit tear_off_arguments + if we've allocated the arguments registers. This allows tear_off_activation + not to worry about the arguments object anymore. + + Also, pass the activation and arguments values directly to these opcodes + instead of requiring the opcodes to infer the values through special + registers. This gives us more flexibility to move or eliminate registers. + + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGNode.h: + (Node): Updated for new opcode lengths. + + * dfg/DFGOperations.cpp: Activation tear-off doesn't worry about the + arguments object anymore. If 'arguments' is in use and reified, it's + responsible for aliasing back to the activation object in tear_off_arguments. + + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): Don't pass the arguments object to + activation tear-off; do pass the activation object to arguments tear-off. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): Ditto. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_tear_off_activation): + (JSC::JIT::emit_op_tear_off_arguments): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_tear_off_activation): + (JSC::JIT::emit_op_tear_off_arguments): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: Same change in a few more execution engines. + +2012-09-10 Patrick Gansterer <paroga@webkit.org> + + [JSC] Use StringBuilder::appendNumber() instead of String::number() + https://bugs.webkit.org/show_bug.cgi?id=96236 + + Reviewed by Benjamin Poulain. + + * API/JSContextRef.cpp: + (JSContextCreateBacktrace): + +2012-09-06 Mark Hahnenberg <mhahnenberg@apple.com> + + Combine MarkStack and SlotVisitor into single class + https://bugs.webkit.org/show_bug.cgi?id=96043 + + Reviewed by Geoff Garen. + + Move all of MarkStack into SlotVisitor. The remaining stuff in MarkStack.cpp actually has to do + with MarkStack management/allocation. Cleaned up a few of the header files while I was at it. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/CodeBlock.cpp: + * dfg/DFGCommon.h: + * heap/GCThreadSharedData.cpp: + * heap/GCThreadSharedData.h: + (GCThreadSharedData): + * heap/HeapRootVisitor.h: + * heap/MarkStack.cpp: + (JSC): + * heap/MarkStack.h: + (JSC): + (MarkStackSegment): + (JSC::MarkStackSegment::data): + (JSC::MarkStackSegment::capacityFromSize): + (JSC::MarkStackSegment::sizeFromCapacity): + (MarkStackSegmentAllocator): + (MarkStackArray): + * heap/MarkStackInlineMethods.h: + (JSC::MarkStackArray::postIncTop): + (JSC): + (JSC::MarkStackArray::preDecTop): + (JSC::MarkStackArray::setTopForFullSegment): + (JSC::MarkStackArray::setTopForEmptySegment): + (JSC::MarkStackArray::top): + (JSC::MarkStackArray::validatePrevious): + (JSC::MarkStackArray::append): + (JSC::MarkStackArray::canRemoveLast): + (JSC::MarkStackArray::removeLast): + (JSC::MarkStackArray::isEmpty): + (JSC::MarkStackArray::size): + * heap/SlotVisitor.cpp: Added. + (JSC): + (JSC::SlotVisitor::SlotVisitor): + (JSC::SlotVisitor::~SlotVisitor): + (JSC::SlotVisitor::setup): + (JSC::SlotVisitor::reset): + (JSC::SlotVisitor::append): + (JSC::visitChildren): + (JSC::SlotVisitor::donateKnownParallel): + (JSC::SlotVisitor::drain): + (JSC::SlotVisitor::drainFromShared): + (JSC::SlotVisitor::mergeOpaqueRoots): + (JSC::SlotVisitor::startCopying): + (JSC::SlotVisitor::allocateNewSpaceSlow): + (JSC::SlotVisitor::allocateNewSpaceOrPin): + (JSC::JSString::tryHashConstLock): + (JSC::JSString::releaseHashConstLock): + (JSC::JSString::shouldTryHashConst): + (JSC::SlotVisitor::internalAppend): + (JSC::SlotVisitor::copyAndAppend): + (JSC::SlotVisitor::doneCopying): + (JSC::SlotVisitor::harvestWeakReferences): + (JSC::SlotVisitor::finalizeUnconditionalFinalizers): + (JSC::SlotVisitor::validate): + * heap/SlotVisitor.h: + (JSC): + (SlotVisitor): + (JSC::SlotVisitor::sharedData): + (JSC::SlotVisitor::isEmpty): + (JSC::SlotVisitor::visitCount): + (JSC::SlotVisitor::resetChildCount): + (JSC::SlotVisitor::childCount): + (JSC::SlotVisitor::incrementChildCount): + (ParallelModeEnabler): + (JSC::ParallelModeEnabler::ParallelModeEnabler): + (JSC::ParallelModeEnabler::~ParallelModeEnabler): + * heap/SlotVisitorInlineMethods.h: + (JSC::SlotVisitor::append): + (JSC): + (JSC::SlotVisitor::appendUnbarrieredPointer): + (JSC::SlotVisitor::appendUnbarrieredValue): + (JSC::SlotVisitor::internalAppend): + (JSC::SlotVisitor::addWeakReferenceHarvester): + (JSC::SlotVisitor::addUnconditionalFinalizer): + (JSC::SlotVisitor::addOpaqueRoot): + (JSC::SlotVisitor::containsOpaqueRoot): + (JSC::SlotVisitor::opaqueRootCount): + (JSC::SlotVisitor::mergeOpaqueRootsIfNecessary): + (JSC::SlotVisitor::mergeOpaqueRootsIfProfitable): + (JSC::SlotVisitor::donate): + (JSC::SlotVisitor::donateAndDrain): + * jit/JITWriteBarrier.h: + (JSC::SlotVisitor::append): + * jit/JumpReplacementWatchpoint.cpp: + * runtime/JSCell.h: + * runtime/Structure.h: + (JSC::SlotVisitor::internalAppend): + * runtime/WriteBarrier.h: + (JSC): + (JSC::SlotVisitor::append): + (JSC::SlotVisitor::appendValues): + * yarr/YarrJIT.cpp: + +2012-09-10 Hojong Han <hojong.han@samsung.com> + + [EFL] JIT memory usage is not retrieved + https://bugs.webkit.org/show_bug.cgi?id=96095 + + Reviewed by Geoffrey Garen. + + Fill JITBytes for EFL port. + + * runtime/MemoryStatistics.cpp: + (JSC::globalMemoryStatistics): + +2012-09-10 Thiago Marcos P. Santos <thiago.santos@intel.com> + + [CMake][EFL] Enable the LLInt + https://bugs.webkit.org/show_bug.cgi?id=92682 + + Reviewed by Csaba Osztrogonác. + + Generate the headers needed by LLint when LLint is enabled. + + * CMakeLists.txt: + +2012-09-10 Carlos Garcia Campos <cgarcia@igalia.com> + + Unreviewed. Fix make distcheck. + + * GNUmakefile.list.am: Add missing files. + +2012-09-09 Mark Lam <mark.lam@apple.com> + + Fixed a few llint C++ interpreter bugs. + https://bugs.webkit.org/show_bug.cgi?id=96127. + + Reviewed by Geoffrey Garen. + + * llint/LLIntCLoop.h: + CLoop::execute()'s bootstrapOpcodeId does not need a default + value. There is no case when this function is called without + that parameter being specified. + * llint/LowLevelInterpreter.asm: + Moved the dispatchAfterCall() call to where it is needed. + For the C_LOOP back-end, it generates unreachable code. + * llint/LowLevelInterpreter.cpp: + #include <wtf/Assertions.h> because LLIntAssembly.h needs it. + (JSC): + Fixed bug in SIGN_BIT32() macro. + Placate a MSVC warning for t0, and t1 being uninitialized. + (JSC::CLoop::execute): + The bootstrapOpcodeId arg should always be specified. + MSVC doesn't like UNUSED_PARAM() for labels. Switch to using + the new UNUSED_LABEL() macro. + * offlineasm/cloop.rb: + * offlineasm/generate_offset_extractor.rb: + Resolved a compiler warning found via MSVC. + +2012-09-09 Patrick Gansterer <paroga@webkit.org> + + Add StringBuilder::appendNumber() and use it + https://bugs.webkit.org/show_bug.cgi?id=96030 + + Reviewed by Eric Seidel. + + Also fix a bunch of append() vs. appendLiteral() issues in the surrounding code. + + * API/JSContextRef.cpp: + (JSContextCreateBacktrace): + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * interpreter/Interpreter.h: + (JSC::StackFrame::toString): + +2012-09-09 Patrick Gansterer <paroga@webkit.org> + + Make the String initialization on the function side of String::number() + https://bugs.webkit.org/show_bug.cgi?id=95940 + + Reviewed by Benjamin Poulain. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-09-09 Geoffrey Garen <ggaren@apple.com> + + Rolled out <http://trac.webkit.org/changeset/127939> because it broke + fast/js/named-function-expression.html. + + Refactored bytecode generator initialization to support moving captured vars around + https://bugs.webkit.org/show_bug.cgi?id=96159 + + Reviewed by Gavin Barraclough. + +2012-09-08 Csaba Osztrogonác <ossy@webkit.org> + + LLInt buildfix for case sensitive filesystems + https://bugs.webkit.org/show_bug.cgi?id=96099 + + Reviewed by Michael Saboff. + + * llint/LowLevelInterpreter.cpp: Fix filenames. + +2012-09-07 Benjamin Poulain <bpoulain@apple.com> + + Rename the ustring() accessor to string() + https://bugs.webkit.org/show_bug.cgi?id=95919 + + Reviewed by Geoffrey Garen. + + Rename ustring() to string() to make the accessor name more logical after + r127191. + + * API/JSBase.cpp: + (JSEvaluateScript): + (JSCheckScriptSyntax): + * API/JSObjectRef.cpp: + (JSObjectMakeFunctionWithCallback): + (JSObjectMakeFunction): + (JSObjectCopyPropertyNames): + * API/JSProfilerPrivate.cpp: + (JSStartProfiling): + (JSEndProfiling): + * API/JSValueRef.cpp: + (JSValueMakeString): + (JSValueMakeFromJSONString): + * API/OpaqueJSString.cpp: + (OpaqueJSString::string): + * API/OpaqueJSString.h: + (OpaqueJSString): + * bytecode/CodeBlock.cpp: + (JSC::idName): + (JSC::CodeBlock::dump): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitLoad): + (JSC::BytecodeGenerator::addStringConstant): + * bytecompiler/NodesCodegen.cpp: + (JSC::RegExpNode::emitBytecode): + (JSC::processClauseList): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::dump): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jsc.cpp: + (GlobalObject::addFunction): + (GlobalObject::addConstructableFunction): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * parser/ASTBuilder.h: + (JSC::ASTBuilder::createRegExp): + * parser/Parser.cpp: + (JSC::::parsePrimaryExpression): + * parser/Parser.h: + (JSC::Scope::declareVariable): + (JSC::Scope::declareParameter): + (JSC::Scope::useVariable): + * parser/SyntaxChecker.h: + (JSC::SyntaxChecker::createRegExp): + * runtime/ExceptionHelpers.cpp: + (JSC::createUndefinedVariableError): + * runtime/Executable.cpp: + (JSC::FunctionExecutable::paramString): + * runtime/Executable.h: + (JSC::FunctionExecutable::finishCreation): + * runtime/FunctionPrototype.cpp: + (JSC::FunctionPrototype::addFunctionProperties): + * runtime/Identifier.h: + (JSC::Identifier::string): + * runtime/JSFunction.cpp: + (JSC::JSFunction::calculatedDisplayName): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + * runtime/JSONObject.cpp: + (JSC::PropertyNameForFunctionCall::value): + (JSC::Stringifier::Holder::appendNextProperty): + (JSC::Walker::walk): + * runtime/JSPropertyNameIterator.h: + (JSC::JSPropertyNameIterator::finishCreation): + * runtime/JSScope.cpp: + (JSC::JSScope::resolveBase): + * runtime/JSString.h: + (JSC::inlineJSValueNotStringtoString): + * runtime/LiteralParser.cpp: + (JSC::::parse): + * runtime/ObjectConstructor.cpp: + (JSC::ObjectConstructor::finishCreation): + (JSC::objectConstructorGetOwnPropertyNames): + (JSC::objectConstructorKeys): + * runtime/RegExpConstructor.cpp: + (JSC::RegExpConstructor::finishCreation): + +2012-09-07 Gavin Barraclough <barraclough@apple.com> + + CALLFRAME_OFFSET and EXCEPTION_OFFSET are same in ctiTrampoline on ARM Thumb2 + https://bugs.webkit.org/show_bug.cgi?id=82013 + + Reviewed by Geoff Garen. + + Neither of these values need to be stored. At all. + + * jit/JITStubs.cpp: + (JSC): + (JSC::ctiTrampoline): + (JSC::JITThunks::JITThunks): + - Nothing to see here. Move along. + +2012-09-07 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r127938. + http://trac.webkit.org/changeset/127938 + https://bugs.webkit.org/show_bug.cgi?id=96166 + + It broke the build (Requested by smfr on #webkit). + + * llint/LowLevelInterpreter.cpp: + (JSC): + (JSC::CLoop::execute): + * offlineasm/cloop.rb: + +2012-09-07 Geoffrey Garen <ggaren@apple.com> + + Refactored bytecode generator initialization to support moving captured vars around + https://bugs.webkit.org/show_bug.cgi?id=96159 + + Reviewed by Gavin Barraclough. + + This patch separates the stages of allocating registers, declaring identifiers + in the symbol table, and initializing registers, so you can change + allocation decisions without breaking the world. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): Call a set of helper functions + instead of inlining all the code, to help clarity. + + (JSC::BytecodeGenerator::allocateCapturedVars): + (JSC::BytecodeGenerator::allocateUncapturedVars): + (JSC::BytecodeGenerator::allocateActivationVar): + (JSC::BytecodeGenerator::allocateArgumentsVars): + (JSC::BytecodeGenerator::allocateCalleeVarUndeclared): + (JSC::BytecodeGenerator::declareParameters): + (JSC::BytecodeGenerator::declareCallee): + (JSC::BytecodeGenerator::initCalleeVar): + (JSC::BytecodeGenerator::initArgumentsVars): + (JSC::BytecodeGenerator::initActivationVar): + (JSC::BytecodeGenerator::initThisParameter): + (JSC::BytecodeGenerator::initFunctionDeclarations): + (JSC::BytecodeGenerator::declareParameter): + (JSC::BytecodeGenerator::createLazyRegisterIfNecessary): + (JSC::BytecodeGenerator::createActivationIfNecessary): Factored these + helper functions out from pre-existing code. + + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + * parser/ASTBuilder.h: + (JSC::ASTBuilder::createFuncDeclStatement): + (JSC::ASTBuilder::addVar): + * parser/Nodes.h: + (JSC::DeclarationStacks::VarDeclaration::VarDeclaration): + (VarDeclaration): + (JSC::DeclarationStacks::FunctionDeclaration::FunctionDeclaration): + (FunctionDeclaration): Declaration stacks get a little more data now, + to support allocating registers before putting things in the symbol + table. I'm convinced that we should eventually just expand the symbol + table to understand these things. + +2012-09-07 Mark Lam <mark.lam@apple.com> + + Fix a llint C++ interpreter bugs. + https://bugs.webkit.org/show_bug.cgi?id=96127. + + Reviewed by Filip Pizlo. + + * llint/LowLevelInterpreter.cpp: + (JSC): + (JSC::CLoop::execute): + * offlineasm/cloop.rb: + +2012-09-07 Gavin Barraclough <barraclough@apple.com> + + Object.prototype.__define{G,S}etter__ with non-callable second parameter should throw TypeError instead of SyntaxError + https://bugs.webkit.org/show_bug.cgi?id=93873 + + Reviewed by Sam Weinig. + + * runtime/ObjectPrototype.cpp: + (JSC::objectProtoFuncDefineGetter): + - throw TypeError instead of SyntaxError + (JSC::objectProtoFuncDefineSetter): + - throw TypeError instead of SyntaxError + +2012-09-06 Mark Hahnenberg <mhahnenberg@apple.com> + + JSC should have a zombie mode + https://bugs.webkit.org/show_bug.cgi?id=96047 + + Reviewed by Geoffrey Garen. + + To aid clients of JSC while they are debugging memory issues, we should add a zombie + mode that scribbles into objects in the MarkedSpace after they are found to be dead + to prevent a sort of "use after free" situation. As a first cut we should support a + mode that just scribbles on objects prior to their being reused (i.e. while they are + "zombies") and a mode in which, in addition to scribbling on zombies, once an object + has been marked its mark bit will never be cleared, thus giving us "immortal" zombies. + + These two modes will be enabled through the use of environment variables. For now these + will be "JSZombieEnabled" and "JSImmortalZombieEnabled". Setting them to any value will + result in the use of the appropriate mode. + + * heap/Heap.cpp: + (JSC::Heap::collect): Zombifies dead objects at the end of collection if zombie mode is enabled. + (ZombifyCellFunctor): + (JSC::ZombifyCellFunctor::ZombifyCellFunctor): Sets marked bits for dead objects if in immortal mode and writes 0xbbadbeef into them. + (JSC::ZombifyCellFunctor::operator()): + (JSC): + (ZombifyBlockFunctor): + (JSC::ZombifyBlockFunctor::operator()): + (JSC::Heap::zombifyDeadObjects): Eagerly sweeps so that we don't write garbage into an object before it + is finalized/destroyed. + * heap/Heap.h: + (Heap): + * heap/MarkedBlock.h: + (MarkedBlock): + (JSC::MarkedBlock::forEachDeadCell): Used to iterate over dead cells at the end of collection if zombie mode is enabled. + (JSC): + * runtime/Options.cpp: + (JSC::Options::initialize): + * runtime/Options.h: + (JSC): + +2012-09-05 Geoffrey Garen <ggaren@apple.com> + + Rolled back in <http://trac.webkit.org/changeset/127698> with a fix for + fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html, which + is to make sure that function declarations don't put their names in scope. + + Reviewed by Gavin Barraclough. + + Named functions should not allocate scope objects for their names + https://bugs.webkit.org/show_bug.cgi?id=95659 + + Reviewed by Oliver Hunt. + +2012-09-06 Michael Saboff <msaboff@apple.com> + + 16 bit JSRopeString up converts an 8 bit fibers to 16 bits during resolution + https://bugs.webkit.org/show_bug.cgi?id=95810 + + Reviewed by Benjamin Poulain. + + Added 8 bit path that copies the contents of an 8 bit fiber to the 16 bit buffer + when resolving a 16 bit rope. + + * runtime/JSString.cpp: + (JSC::JSRopeString::resolveRopeSlowCase): + +2012-09-06 Gavin Barraclough <barraclough@apple.com> + + JS test suite puts incorrect limitations on Function.toString() + https://bugs.webkit.org/show_bug.cgi?id=3975 + + Reviewed by Geoff Garen. + + The result of function toString is implementation defined; + these test cases were looking for specific whitespace formatting + that matches mozilla's, and for redundant braces to be inserted + around if/else blocks. Stop that. + + * tests/mozilla/expected.html: + * tests/mozilla/js1_2/function/tostring-1.js: + (simplify): + - reduce whitespace differences + * tests/mozilla/js1_2/function/tostring-2.js: + (simplify): + - reduce whitespace differences + (TestOr): + (TestAnd): + - added braces to match expected output + +2012-09-06 Yuqiang Xian <yuqiang.xian@intel.com> + + Performance regressions on 32-bit platforms with revisions 125637 and 126387 + https://bugs.webkit.org/show_bug.cgi?id=95953 + + Reviewed by Filip Pizlo. + + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_by_val): Fix the typo. + +2012-09-05 Geoffrey Garen <ggaren@apple.com> + + Rolled out <http://trac.webkit.org/changeset/127698> because it broke + fast/dom/HTMLScriptElement/script-reexecution-pretty-diff.html + + Named functions should not allocate scope objects for their names + https://bugs.webkit.org/show_bug.cgi?id=95659 + + Reviewed by Oliver Hunt. + +2012-09-06 Mark Lam <mark.lam@apple.com> + + Renamed useYarrJIT() option to useRegExpJIT(). Also fixed regression in + which inadvertantly allows the ASM llint to use the baseline JIT when + useRegExpJIT() is true. + https://bugs.webkit.org/show_bug.cgi?id=95918. + + Reviewed by Geoffrey Garen. + + * runtime/JSGlobalData.cpp: + (JSC::enableAssembler): + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSC::JSGlobalData::canUseJIT): + (JSC::JSGlobalData::canUseRegExpJIT): + (JSGlobalData): + * runtime/Options.cpp: + (JSC::Options::initialize): + * runtime/Options.h: + (JSC): + +2012-09-06 Patrick Gansterer <paroga@webkit.org> + + Build fix for Interpreter after r127698. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + +2012-09-05 Geoffrey Garen <ggaren@apple.com> + + Named functions should not allocate scope objects for their names + https://bugs.webkit.org/show_bug.cgi?id=95659 + + Reviewed by Oliver Hunt. + + In most cases, we can merge a function expression's name into its symbol + table. This reduces memory footprint per closure from three objects + (function + activation + name scope) to two (function + activation), + speeds up closure allocation, and speeds up recursive calls. + + In the case of a named function expression that contains a non-strict + eval, the rules are so bat-poop crazy that I don't know how to model + them without an extra object. Since functions now default to not having + such an object, this case needs to allocate the object on function + entry. + + Therefore, this patch makes the slow case a bit slower so the fast case + can be faster and more memory-efficient. (Note that the slow case already + allocates an activation on entry, and until recently also allocated a + scope chain node on entry, so adding one allocation on entry shouldn't + break the bank.) + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::CodeBlock): Caught a missed initializer. No behavior change. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): Put the callee in static scope + during compilation so it doesn't need to be in dynamic scope at runtime. + + (JSC::BytecodeGenerator::resolveCallee): + (JSC::BytecodeGenerator::addCallee): Helper functions for either statically + resolving the callee or adding a dynamic scope that will resolve to it, + depending on whether you're in the fast path. + + We move the callee into a var location if it's captured because activations + prefer to have contiguous ranges of captured variables. + + * bytecompiler/BytecodeGenerator.h: + (JSC::BytecodeGenerator::registerFor): + (BytecodeGenerator): + + * dfg/DFGOperations.cpp: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): This is the point of the patch: remove + one allocation in the case of a named function expression. + + * parser/Parser.cpp: + (JSC::::Parser): + * parser/Parser.h: + (JSC::Scope::declareCallee): + (Scope): + (Parser): + (JSC::parse): + * runtime/Executable.cpp: + (JSC::EvalExecutable::compileInternal): + (JSC::ProgramExecutable::checkSyntax): + (JSC::ProgramExecutable::compileInternal): + (JSC::FunctionExecutable::produceCodeBlockFor): + (JSC::FunctionExecutable::fromGlobalCode): Pipe the callee's name through + the parser so we get accurate information on whether the callee was captured. + + (JSC::FunctionExecutable::FunctionExecutable): + (JSC::EvalExecutable::compileInternal): + (JSC::ProgramExecutable::checkSyntax): + (JSC::ProgramExecutable::compileInternal): + (JSC::FunctionExecutable::produceCodeBlockFor): + (JSC::FunctionExecutable::fromGlobalCode): + * runtime/Executable.h: + (JSC::FunctionExecutable::create): + (FunctionExecutable): + (JSC::FunctionExecutable::finishCreation): I had to refactor function + creation to support the following function constructor quirk: the function + gets a name, but its name is not in lexical scope. + + To simplify this, FunctionExecutable now automatically extracts all the + data it needs from the parsed node. The special "fromGlobalCode" path + used by the function constructor creates an anonymous function, and then + quirkily sets the value used by the .name property to be non-null, even + though the parsed name is null. + + * runtime/JSNameScope.h: + (JSC::JSNameScope::create): + (JSC::JSNameScope::JSNameScope): Added support for explicitly specifying + your container scope. The compiler uses this for named function expressions. + +2012-09-05 Gavin Barraclough <barraclough@apple.com> + + a = data[a]++; sets the wrong key in data + https://bugs.webkit.org/show_bug.cgi?id=91270 + + Reviewed by Oliver Hunt. + + Postfix inc/dec is unsafely using finalDestination, can trample base/subscript prior to the result being put. + + * bytecompiler/NodesCodegen.cpp: + (JSC::PostfixNode::emitResolve): + - Remove redundant parens. + (JSC::PostfixNode::emitBracket): + (JSC::PostfixNode::emitDot): + - Refactored to use tempDestination instead of finalDestination. + (JSC::PrefixNode::emitBracket): + (JSC::PrefixNode::emitDot): + - Should be using emitPreIncOrDec. + +2012-09-05 Gavin Barraclough <barraclough@apple.com> + + Bug, assignment within subscript of prefix/postfix increment of bracket access + https://bugs.webkit.org/show_bug.cgi?id=95913 + + Reviewed by Oliver Hunt. + + javascript:alert((function(){ var a = { x:1 }; var b = { x:1 }; a[a=b,"x"]++; return a.x; })()) + + * bytecompiler/NodesCodegen.cpp: + (JSC::PostfixNode::emitBracket): + (JSC::PrefixNode::emitBracket): + - Should check for assigments in the subscript when loading the base. + * parser/Nodes.h: + (JSC::BracketAccessorNode::subscriptHasAssignments): + (BracketAccessorNode): + - Used by emitBracket methods. + +2012-09-05 Gavin Barraclough <barraclough@apple.com> + + Merge prefix/postfix nodes + https://bugs.webkit.org/show_bug.cgi?id=95898 + + Reviewed by Geoff Garen. + + Simplify the AST. + This will also mean we have access to m_subscriptHasAssignments when generating a prefix/postfix op applied to a bracket access. + + * bytecompiler/NodesCodegen.cpp: + (JSC::PostfixNode::emitResolve): + - was PostfixResolveNode::emitBytecode + (JSC::PostfixNode::emitBracket): + - was PostfixBracketNode::emitBytecode + (JSC::PostfixNode::emitDot): + - was PostfixDotNode::emitBytecode + (JSC::PostfixNode::emitBytecode): + - was PostfixErrorNode::emitBytecode, call resolve/bracket/dot version as appropriate. + (JSC::PrefixNode::emitResolve): + - was PrefixResolveNode::emitBytecode + (JSC::PrefixNode::emitBracket): + - was PrefixBracketNode::emitBytecode + (JSC::PrefixNode::emitDot): + - was PrefixDotNode::emitBytecode + (JSC::PrefixNode::emitBytecode): + - was PrefixErrorNode::emitBytecode, call resolve/bracket/dot version as appropriate. + * parser/ASTBuilder.h: + (JSC::ASTBuilder::makePrefixNode): + - Just makes a PrefixNode! + (JSC::ASTBuilder::makePostfixNode): + - Just makes a PostfixNode! + * parser/NodeConstructors.h: + (JSC::PostfixNode::PostfixNode): + - Added, merge of PostfixResolveNode/PostfixBracketNode/PostfixDotNode/PostfixErrorNode. + (JSC::PrefixNode::PrefixNode): + - Added, merge of PrefixResolveNode/PrefixBracketNode/PrefixDotNode/PrefixErrorNode. + * parser/Nodes.h: + (PostfixNode): + - Added, merge of PostfixResolveNode/PostfixBracketNode/PostfixDotNode/PostfixErrorNode. + (PrefixNode): + - Added, merge of PrefixResolveNode/PrefixBracketNode/PrefixDotNode/PrefixErrorNode. + +2012-09-05 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove use of JSCell::classInfoOffset() from tryCacheGetByID + https://bugs.webkit.org/show_bug.cgi?id=95860 + + Reviewed by Oliver Hunt. + + We should just do the indirection through the Structure instead. + + * dfg/DFGRepatch.cpp: + (JSC::DFG::tryCacheGetByID): + +2012-09-05 Geoffrey Garen <ggaren@apple.com> + + Throw exceptions when assigning to const in strict mode + https://bugs.webkit.org/show_bug.cgi?id=95894 + + Reviewed by Oliver Hunt. + + Currently, this never happens; but it will start happening once the + callee is a local const register. In this patch, there's no change in + behavior. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitReadOnlyExceptionIfNeeded): Helper function + for doing the throwing. + * bytecompiler/BytecodeGenerator.h: + + * bytecompiler/NodesCodegen.cpp: + (JSC::PostfixResolveNode::emitBytecode): + (JSC::PrefixResolveNode::emitBytecode): + (JSC::ReadModifyResolveNode::emitBytecode): + (JSC::AssignResolveNode::emitBytecode): Call the helper function. + +2012-09-05 Geoffrey Garen <ggaren@apple.com> + + Refactored callee access in the DFG to support it in the general case + https://bugs.webkit.org/show_bug.cgi?id=95887 + + Reviewed by Phil Pizlo and Gavin Barraclough. + + To support named function expressions, the DFG needs to understand the + callee register being used in arbitrary expressions, and not just + create_this. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::getDirect): + (JSC::DFG::ByteCodeParser::getCallee): Remap access to the callee register + into a GetCallee node. Otherwise, we get confused and think we have a + negatively indexed argument. + + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::InlineStackEntry::remapOperand): Inlining also + needs to remap, but to the callee in the inline frame, and not the caller's + callee. + + (JSC::DFG::ByteCodeParser::parseBlock): Since we support the callee in + the general case now, there's no need to handle it in a special way for + create_this. + +2012-09-05 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove use of JSCell::classInfoOffset() from virtualForThunkGenerator + https://bugs.webkit.org/show_bug.cgi?id=95821 + + Reviewed by Oliver Hunt. + + We can replace the load of the ClassInfo from the object with a load from the Structure. + + * dfg/DFGThunks.cpp: + (JSC::DFG::virtualForThunkGenerator): + +2012-09-05 Benjamin Poulain <bpoulain@apple.com> + + Fix the uses of String::operator+=() for Mac + https://bugs.webkit.org/show_bug.cgi?id=95818 + + Reviewed by Dan Bernstein. + + * jsc.cpp: + (functionJSCStack): Use StringBuilder to create the stack dump, it is faster + and avoid String::operator+=(). + + * parser/Parser.h: + (JSC::Parser::updateErrorMessageSpecialCase): + (JSC::Parser::updateErrorMessage): + (JSC::Parser::updateErrorWithNameAndMessage): + Use the String operators (and makeString) to concatenate the strings. + +2012-09-05 Gabor Rapcsanyi <rgabor@webkit.org> + + DFG JIT doesn't work properly on ARM hardfp + https://bugs.webkit.org/show_bug.cgi?id=95684 + + Reviewed by Filip Pizlo. + + Add hardfp support to DFG JIT. The patch is created with the + help of Zoltan Herczeg. + + * dfg/DFGCCallHelpers.h: + (CCallHelpers): + (JSC::DFG::CCallHelpers::setupArguments): + * dfg/DFGFPRInfo.h: + (FPRInfo): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheckSetResult): + (JSC::DFG::SpeculativeJIT::appendCallSetResult): + +2012-09-04 Mark Lam <mark.lam@apple.com> + + Allow the YarrJIT to use the assembler even when useJIT() is false. + Introduce the useYarrJIT() option. + https://bugs.webkit.org/show_bug.cgi?id=95809. + + Reviewed by Geoffrey Garen. + + * runtime/JSGlobalData.cpp: + (JSC::enableAssembler): + * runtime/Options.cpp: + (JSC::Options::initialize): + * runtime/Options.h: + (JSC): + +2012-09-04 Gavin Barraclough <barraclough@apple.com> + + inc/dec behave incorrectly operating on a resolved const + https://bugs.webkit.org/show_bug.cgi?id=95815 + + Reviewed by Geoff Garen. + + There are two bugs here. + + (1) When the value being incremented is const, and the result is ignored, we assume this cannot be observed, and emit no code. + However if the value being incremented is not a primitive & has a valueOf conversion, then this should be being called. + + (2) In the case of a pre-increment of a const value where the result is not ignored, we'll move +/-1 to the destination, then + add the resolved const value being incremented to this. This is problematic if the destination is a local, and the const + value being incremented has a valueOf conversion that throws - the destination will be modified erroneously. Instead, we + need to use a temporary location. + + * bytecompiler/NodesCodegen.cpp: + (JSC::PostfixResolveNode::emitBytecode): + (JSC::PrefixResolveNode::emitBytecode): + - always at least perform a toNumber conversion, use tempDestination when reducing inc/dec to an add +/-1. + +2012-09-04 Filip Pizlo <fpizlo@apple.com> + + DFG GetByVal for JSArrays shouldn't OSR exit every time that the index is out of bound + https://bugs.webkit.org/show_bug.cgi?id=95717 + + Reviewed by Oliver Hunt. + + Rolling back in after fixing the negative index case. + + Make GetByVal for JSArrayOutOfBounds do meaningful things. The profiling was already + there so we should just use it! + + * bytecode/DFGExitProfile.h: + (JSC::DFG::exitKindToString): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-09-04 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r127503. + http://trac.webkit.org/changeset/127503 + https://bugs.webkit.org/show_bug.cgi?id=95788 + + broke some tests (fast/js/dfg-negative-array-index, fast/js + /dfg-put-by-val-setter-then-get-by-val) (Requested by thorton + on #webkit). + + * bytecode/DFGExitProfile.h: + (JSC::DFG::exitKindToString): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-09-04 Benjamin Poulain <bpoulain@apple.com> + + Improve JSC use of Strings after the UString->String change + https://bugs.webkit.org/show_bug.cgi?id=95633 + + Reviewed by Geoffrey Garen. + + This patch improve the use of strings in the JSC runtime. + + The initialization of Identifier is left for future patches. + + The improvements are the following: + -5% faster to raise one of the modified exception. + -3 times faster to execute Boolean::toString() + + Most of the changes are just about using the new methods + for string literals. + + With the changes, the binary on x86_64 gets 176 bytes smaller. + + * API/JSCallbackObjectFunctions.h: + (JSC::::staticFunctionGetter): + (JSC::::callbackGetter): + * API/JSContextRef.cpp: + (JSContextCreateBacktrace): + * API/JSObjectRef.cpp: + (JSObjectMakeFunctionWithCallback): + * bytecode/CodeBlock.cpp: + (JSC::valueToSourceString): + (JSC::CodeBlock::nameForRegister): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::addStackTraceIfNecessary): + * runtime/ArrayConstructor.cpp: + (JSC::constructArrayWithSizeQuirk): + * runtime/ArrayPrototype.cpp: + (JSC::shift): + (JSC::unshift): + (JSC::arrayProtoFuncPop): + (JSC::arrayProtoFuncReverse): + * runtime/BooleanPrototype.cpp: + (JSC::booleanProtoFuncToString): Instead of instanciating new strings, reuse the + keywords available in SmallStrings. Avoiding the creation of the JSString and StringImpl + makes the method significantly faster. + + * runtime/DateConversion.cpp: + (JSC::formatDateTime): + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + (JSC::formateDateInstance): + (JSC::dateProtoFuncToISOString): + Change the way we use snprintf() for clarity and performance. + + Instead of allocating one extra byte to put a zero "just in case", we use the size returned + by snprintf(). + To prevent any overflow from a programming mistake, we explicitely test for overflow and + return an empty string. + + (JSC::dateProtoFuncToJSON): + * runtime/Error.cpp: + (JSC::createNotEnoughArgumentsError): + (JSC::throwTypeError): + (JSC::throwSyntaxError): + * runtime/Error.h: + (JSC::StrictModeTypeErrorFunction::create): + * runtime/ErrorPrototype.cpp: + (JSC::ErrorPrototype::finishCreation): + (JSC::errorProtoFuncToString): + Using a null String is correct because (8) uses jsString(), (9) tests for a length of 0. + + * runtime/ExceptionHelpers.cpp: + (JSC::InterruptedExecutionError::defaultValue): + (JSC::TerminatedExecutionError::defaultValue): + (JSC::createStackOverflowError): + (JSC::createOutOfMemoryError): + * runtime/Executable.cpp: + (JSC::EvalExecutable::compileInternal): + (JSC::FunctionExecutable::paramString): + * runtime/FunctionConstructor.cpp: + (JSC::constructFunction): + (JSC::constructFunctionSkippingEvalEnabledCheck): + * runtime/FunctionPrototype.h: + (JSC::FunctionPrototype::create): + Using a null String for the name is correct because InternalFunction uses jsString() + to create the name value. + + * runtime/InternalFunction.cpp: + (JSC::InternalFunction::finishCreation): + There is no need to create an empty string for a null string, jsString() handle both + cases as empty JSString. + + * runtime/JSArray.cpp: + (JSC::reject): + (JSC::SparseArrayValueMap::put): + (JSC::JSArray::put): + (JSC::JSArray::putByIndexBeyondVectorLength): + (JSC::JSArray::putDirectIndexBeyondVectorLength): + (JSC::JSArray::setLength): + (JSC::JSArray::pop): + (JSC::JSArray::push): + * runtime/JSFunction.cpp: + (JSC::JSFunction::finishCreation): Same issue as InternalFunction::finishCreation. + + (JSC::JSFunction::callerGetter): + (JSC::JSFunction::defineOwnProperty): + * runtime/JSGlobalData.cpp: + (JSC::enableAssembler): Use CFSTR() instead of CFStringCreateWithCString(). + CFStringCreateWithCString() copy the content and may choose to decode the data. + CFSTR() is much more efficient. + + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + JSFunction uses jsString() to create the name, we can use null strings instead + of creating empty strings. + + (JSC::JSGlobalObject::createThrowTypeError): ditto. + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::encode): + (JSC::decode): + (JSC::globalFuncEval): + * runtime/JSONObject.cpp: + (JSC::Stringifier::appendStringifiedValue): + (JSC::Stringifier::Holder::appendNextProperty): + (JSC::JSONProtoFuncParse): + (JSC::JSONProtoFuncStringify): + * runtime/JSObject.cpp: + (JSC::JSObject::put): + (JSC::JSObject::defaultValue): + (JSC::JSObject::hasInstance): + (JSC::JSObject::defineOwnProperty): + * runtime/JSString.cpp: + Return an empty JSString to avoid the creation of a temporary empty String. + + (JSC::JSRopeString::getIndexSlowCase): + * runtime/JSString.h: + (JSC): Remove the versions of jsNontrivialString() taking a char*. All the callers + have been replaced by calls using ASCIILiteral. + + * runtime/JSValue.cpp: + (JSC::JSValue::putToPrimitive): + * runtime/LiteralParser.cpp: + (JSC::::Lexer::lex): + (JSC::::Lexer::lexString): + (JSC::::Lexer::lexNumber): + (JSC::::parse): + * runtime/LiteralParser.h: + (JSC::LiteralParser::getErrorMessage): + * runtime/NumberPrototype.cpp: + (JSC::numberProtoFuncToExponential): + (JSC::numberProtoFuncToFixed): + (JSC::numberProtoFuncToPrecision): + (JSC::numberProtoFuncToString): + * runtime/ObjectConstructor.cpp: + (JSC::objectConstructorGetPrototypeOf): + (JSC::objectConstructorGetOwnPropertyDescriptor): + (JSC::objectConstructorGetOwnPropertyNames): + (JSC::objectConstructorKeys): + (JSC::toPropertyDescriptor): + (JSC::objectConstructorDefineProperty): + (JSC::objectConstructorDefineProperties): + (JSC::objectConstructorCreate): + (JSC::objectConstructorSeal): + (JSC::objectConstructorFreeze): + (JSC::objectConstructorPreventExtensions): + (JSC::objectConstructorIsSealed): + (JSC::objectConstructorIsFrozen): + (JSC::objectConstructorIsExtensible): + * runtime/ObjectPrototype.cpp: + (JSC::objectProtoFuncDefineGetter): + (JSC::objectProtoFuncDefineSetter): + (JSC::objectProtoFuncToString): + * runtime/RegExpConstructor.cpp: + (JSC::constructRegExp): + * runtime/RegExpObject.cpp: + (JSC::reject): + (JSC::regExpObjectSource): + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncCompile): + * runtime/StringObject.cpp: + (JSC::StringObject::defineOwnProperty): + * runtime/StringPrototype.cpp: + (JSC::jsSpliceSubstrings): + (JSC::jsSpliceSubstringsWithSeparators): + +2012-09-04 Filip Pizlo <fpizlo@apple.com> + + DFG GetByVal for JSArrays shouldn't OSR exit every time that the index is out of bound + https://bugs.webkit.org/show_bug.cgi?id=95717 + + Reviewed by Oliver Hunt. + + Make GetByVal for JSArrayOutOfBounds do meaningful things. The profiling was already + there so we should just use it! + + * bytecode/DFGExitProfile.h: + (JSC::DFG::exitKindToString): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-09-04 Zoltan Horvath <zoltan@webkit.org> + + Extend the coverage of the Custom Allocation Framework in WTF and in JavaScriptCore + https://bugs.webkit.org/show_bug.cgi?id=95737 + + Reviewed by Eric Seidel. + + Add WTF_MAKE_FAST_ALLOCATED macro to the following class declarations because these are instantiated by operator new. + + * wtf/CryptographicallyRandomNumber.cpp: CryptographicallyRandomNumber is instantiated at wtf/CryptographicallyRandomNumber.cpp:162. + + * heap/MachineStackMarker.cpp: + (MachineThreads::Thread): Thread is instantiated at heap/MachineStackMarker.cpp:196. + * jit/ExecutableAllocatorFixedVMPool.cpp: + (FixedVMPoolExecutableAllocator): FixedVMPoolExecutableAllocator is instantiated at jit/ExecutableAllocatorFixedVMPool.cpp:111 + * parser/SourceProviderCache.h: + (SourceProviderCache): SourceProviderCache is instantiated at parser/SourceProvider.h:49. + * parser/SourceProviderCacheItem.h: + (SourceProviderCacheItem): SourceProviderCacheItem is instantiated at parser/Parser.cpp:843. + * runtime/GCActivityCallback.h: + (GCActivityCallback): GCActivityCallback is instantiated at runtime/GCActivityCallback.h:96. + * tools/CodeProfile.h: + (CodeProfile): CodeProfile is instantiated at JavaScriptCore/tools/CodeProfiling.cpp:140. + +2012-09-04 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove uses of ClassInfo from SpeculativeJIT::compileObjectOrOtherLogicalNot + https://bugs.webkit.org/show_bug.cgi?id=95510 + + Reviewed by Oliver Hunt. + + More refactoring to get rid of ClassInfo checks in the DFG. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compileNonStringCellOrOtherLogicalNot): + (JSC::DFG::SpeculativeJIT::compileLogicalNot): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compileNonStringCellOrOtherLogicalNot): + (JSC::DFG::SpeculativeJIT::compileLogicalNot): + +2012-09-03 Patrick Gansterer <paroga@webkit.org> + + Unreviewed. Build fix for ENABLE(CLASSIC_INTERPRETER) after r127393. + + * interpreter/Interpreter.h: + +2012-09-02 Geoffrey Garen <ggaren@apple.com> + + Fixed failures seen on Linux bots. + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_push_with_scope): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_push_with_scope): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: push_*_scope doesn't have a destination operand anymore. + Accordingly, update these places in the baseline JIT, which I missed in my last patch. + +2012-09-02 Geoffrey Garen <ggaren@apple.com> + + Refactored scope chain opcodes to support optimization for named function expressions + https://bugs.webkit.org/show_bug.cgi?id=95658 + + Reviewed by Sam Weinig. + + Renamed + push_scope => push_with_scope + push_new_scope => push_name_scope + to clarify the difference between them. + + Changed push_with_scope and push_name_scope not to save the new scope in + a temporary register, since doing so made optimization harder. + + (The old behavior was a hold-over from when the scope chain wasn't + a GC object, and wouldn't be marked otherwise. Now, the scope chain is + marked because it is a GC object pointed to by the call frame.) + + Changed push_name_scope to accept an operand specifying the attributes + for the named property, instead of assuming DontDelete, because a named + function expression needs ReadOnly|DontDelete. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::highestUsedRegister): Removed this function, + which used to be related to preserving saved scope object temporaries, + because it had no callers. + +2012-09-01 Geoffrey Garen <ggaren@apple.com> + + Rolled back out a piece of <http://trac.webkit.org/changeset/127293> + because it broke inspector tests on Windows. + + Shrink activation objects by half + https://bugs.webkit.org/show_bug.cgi?id=95591 + + Reviewed by Sam Weinig. + +2012-09-01 Mark Lam <mark.lam@apple.com> + + LLInt C loop backend. + https://bugs.webkit.org/show_bug.cgi?id=91052. + + Reviewed by Filip Pizlo. + + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + (JSC::CodeBlock::bytecodeOffset): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::execute): + (JSC::Interpreter::executeCall): + (JSC::Interpreter::executeConstruct): + (JSC): + * interpreter/Interpreter.h: + * jit/JITStubs.h: + (JITStackFrame): + (JSC): + * llint/LLIntCLoop.cpp: Added. + (JSC): + (LLInt): + (JSC::LLInt::CLoop::initialize): + (JSC::LLInt::CLoop::catchRoutineFor): + (JSC::LLInt::CLoop::hostCodeEntryFor): + (JSC::LLInt::CLoop::jsCodeEntryWithArityCheckFor): + (JSC::LLInt::CLoop::jsCodeEntryFor): + * llint/LLIntCLoop.h: Added. + (JSC): + (LLInt): + (CLoop): + * llint/LLIntData.cpp: + (JSC::LLInt::initialize): + * llint/LLIntData.h: + (JSC): + * llint/LLIntOfflineAsmConfig.h: + * llint/LLIntOpcode.h: + * llint/LLIntThunks.cpp: + (LLInt): + * llint/LowLevelInterpreter.asm: + * llint/LowLevelInterpreter.cpp: + (LLInt): + (JSC::LLInt::Ints2Double): + (JSC): + (JSC::CLoop::execute): + * llint/LowLevelInterpreter.h: + (JSC): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * offlineasm/asm.rb: + * offlineasm/backends.rb: + * offlineasm/cloop.rb: Added. + * offlineasm/instructions.rb: + * runtime/Executable.h: + (ExecutableBase): + (JSC::ExecutableBase::hostCodeEntryFor): + (JSC::ExecutableBase::jsCodeEntryFor): + (JSC::ExecutableBase::jsCodeWithArityCheckEntryFor): + (JSC::ExecutableBase::catchRoutineFor): + (NativeExecutable): + * runtime/JSValue.h: + (JSC): + (LLInt): + (JSValue): + * runtime/JSValueInlineMethods.h: + (JSC): + (JSC::JSValue::JSValue): + * runtime/Options.cpp: + (JSC::Options::initialize): + +2012-09-01 Geoffrey Garen <ggaren@apple.com> + + Rolled back in a piece of <http://trac.webkit.org/changeset/127293>. + + Shrink activation objects by half + https://bugs.webkit.org/show_bug.cgi?id=95591 + + Reviewed by Sam Weinig. + + * runtime/JSActivation.h: + (JSActivation): + +2012-09-01 Geoffrey Garen <ggaren@apple.com> + + Rolled back in a piece of <http://trac.webkit.org/changeset/127293>. + + Shrink activation objects by half + https://bugs.webkit.org/show_bug.cgi?id=95591 + + Reviewed by Sam Weinig. + + * runtime/JSActivation.cpp: + (JSC::JSActivation::JSActivation): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::JSGlobalObject): + (JSC::JSGlobalObject::setGlobalThis): + (JSC): + (JSC::JSGlobalObject::visitChildren): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSScope::globalThis): + (JSC): + (JSC::JSGlobalObject::globalThis): + * runtime/JSNameScope.h: + (JSC::JSNameScope::JSNameScope): + * runtime/JSScope.cpp: + (JSC::JSScope::visitChildren): + * runtime/JSScope.h: + (JSScope): + (JSC::JSScope::JSScope): + (JSC::JSScope::globalObject): + (JSC::JSScope::globalData): + * runtime/JSSegmentedVariableObject.h: + (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject): + * runtime/JSSymbolTableObject.h: + (JSC::JSSymbolTableObject::JSSymbolTableObject): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::JSVariableObject): + * runtime/JSWithScope.h: + (JSC::JSWithScope::JSWithScope): + * runtime/StrictEvalActivation.cpp: + (JSC::StrictEvalActivation::StrictEvalActivation): + +2012-09-01 Geoffrey Garen <ggaren@apple.com> + + Rolled back out a piece of <http://trac.webkit.org/changeset/127293> + because it broke Window inspector tests. + + Shrink activation objects by half + https://bugs.webkit.org/show_bug.cgi?id=95591 + + Reviewed by Sam Weinig. + + * runtime/JSActivation.h: + (JSActivation): + +2012-08-31 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, attempt to fix Windows, take two. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-08-31 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, attempt to fix Windows. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-08-31 Filip Pizlo <fpizlo@apple.com> + + JSArray::putDirectIndex should by default behave like JSObject::putDirect + https://bugs.webkit.org/show_bug.cgi?id=95630 + + Reviewed by Gavin Barraclough. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jsc.cpp: + (GlobalObject::finishCreation): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * runtime/JSArray.cpp: + (JSC::SparseArrayValueMap::putDirect): + (JSC::JSArray::defineOwnNumericProperty): + (JSC::JSArray::putDirectIndexBeyondVectorLength): + * runtime/JSArray.h: + (SparseArrayValueMap): + (JSArray): + (JSC::JSArray::putDirectIndex): + * runtime/JSONObject.cpp: + (JSC::Walker::walk): + * runtime/RegExpMatchesArray.cpp: + (JSC::RegExpMatchesArray::reifyAllProperties): + (JSC::RegExpMatchesArray::reifyMatchProperty): + * runtime/StringPrototype.cpp: + (JSC::splitStringByOneCharacterImpl): + (JSC::stringProtoFuncSplit): + +2012-08-31 Geoffrey Garen <ggaren@apple.com> + + Rolled back in a piece of <http://trac.webkit.org/changeset/127293>. + + Shrink activation objects by half + https://bugs.webkit.org/show_bug.cgi?id=95591 + + Reviewed by Sam Weinig. + + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSGlobalData): + * runtime/JSNameScope.h: + (JSC::JSNameScope::JSNameScope): + * runtime/JSWithScope.h: + (JSC::JSWithScope::JSWithScope): + * runtime/StrictEvalActivation.cpp: + (JSC::StrictEvalActivation::StrictEvalActivation): + +2012-08-31 Geoffrey Garen <ggaren@apple.com> + + Rolled back in a piece of <http://trac.webkit.org/changeset/127293>. + + Shrink activation objects by half + https://bugs.webkit.org/show_bug.cgi?id=95591 + + Reviewed by Sam Weinig. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_resolve_global_dynamic): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/JSActivation.cpp: + (JSC::JSActivation::JSActivation): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSGlobalData): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + (JSC::JSGlobalObject::visitChildren): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::withScopeStructure): + (JSC::JSGlobalObject::strictEvalActivationStructure): + (JSC::JSGlobalObject::activationStructure): + (JSC::JSGlobalObject::nameScopeStructure): + +2012-08-31 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove use of ClassInfo in SpeculativeJIT::emitBranch + https://bugs.webkit.org/show_bug.cgi?id=95623 + + Reviewed by Filip Pizlo. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::emitNonStringCellOrOtherBranch): + (JSC::DFG::SpeculativeJIT::emitBranch): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::emitNonStringCellOrOtherBranch): + (JSC::DFG::SpeculativeJIT::emitBranch): + +2012-08-31 Geoffrey Garen <ggaren@apple.com> + + Rolled back in a piece of <http://trac.webkit.org/changeset/127293>. + + Shrink activation objects by half + https://bugs.webkit.org/show_bug.cgi?id=95591 + + Reviewed by Sam Weinig. + + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::MarkedBlock): + * heap/MarkedBlock.h: + (MarkedBlock): + (JSC::MarkedBlock::globalData): + (JSC): + * heap/WeakSet.cpp: + (JSC::WeakSet::addAllocator): + * heap/WeakSet.h: + (WeakSet): + (JSC::WeakSet::WeakSet): + (JSC::WeakSet::globalData): + * runtime/JSGlobalData.h: + (JSC::WeakSet::heap): + (JSC): + +2012-08-31 Mark Lam <mark.lam@apple.com> + + Refactor LLInt and supporting code in preparation for the C Loop backend. + https://bugs.webkit.org/show_bug.cgi?id=95531. + + Reviewed by Filip Pizlo. + + * bytecode/GetByIdStatus.cpp: + (JSC::GetByIdStatus::computeFromLLInt): + * bytecode/PutByIdStatus.cpp: + (JSC::PutByIdStatus::computeFromLLInt): + * jit/JITExceptions.cpp: + (JSC::genericThrow): Use ExecutableBase::catchRoutineFor() to fetch + fetch the catch routine for a thrown exception. This will allow + us to redefine that for the C loop later, and still keep this + code readable. + * llint/LLIntOfflineAsmConfig.h: Moved ASM macros to + LowLevelInterpreter.cpp which is the only place they are used. This + will make it more convenient to redefine them for the C loop later. + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::setUpCall): Use ExecutableBase's hostCodeEntry() + jsCodeEntryFor(), and jsCodeWithArityCheckEntryFor() for computing + the entry points to functions being called. + * llint/LLIntSlowPaths.h: + (SlowPathReturnType): + (JSC::LLInt::encodeResult): + (LLInt): + (JSC::LLInt::decodeResult): Added. Needed by LLInt C Loop later. + * llint/LowLevelInterpreter.asm: + * llint/LowLevelInterpreter.cpp: + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * offlineasm/asm.rb: Disambiguate between opcodes and other labels. + * offlineasm/config.rb: + * runtime/Executable.h: + (JSC::ExecutableBase::hostCodeEntryFor): Added. + (ExecutableBase): + (JSC::ExecutableBase::jsCodeEntryFor): Added. + (JSC::ExecutableBase::jsCodeWithArityCheckEntryFor): Added. + (JSC::ExecutableBase::catchRoutineFor): Added. + * runtime/JSValueInlineMethods.h: + (JSC): + +2012-08-31 Tony Chang <tony@chromium.org> + + Remove ENABLE_CSS3_FLEXBOX compile time flag + https://bugs.webkit.org/show_bug.cgi?id=95382 + + Reviewed by Ojan Vafai. + + Everyone is already enabling this by default and the spec has stablized. + + * Configurations/FeatureDefines.xcconfig: + +2012-08-31 Geoffrey Garen <ggaren@apple.com> + + Not reviewed. + + Rolled out http://trac.webkit.org/changeset/127293 because it broke + inspector tests on Windows. + + Shrink activation objects by half + https://bugs.webkit.org/show_bug.cgi?id=95591 + + Reviewed by Sam Weinig. + +2012-08-31 Geoffrey Garen <ggaren@apple.com> + + Shrink activation objects by half + https://bugs.webkit.org/show_bug.cgi?id=95591 + + Reviewed by Sam Weinig. + + Removed the global object, global data, and global this pointers from + JSScope, and changed an int to a bitfield. This gets the JSActivation + class down to 64 bytes, which in practice cuts it in half by getting it + out of the 128 byte size class. + + Now, it's one extra indirection to get these pointers. These pointers + aren't accessed by JIT code, so I thought there would be no cost to the + extra indirection. However, some C++-heavy SunSpider tests regressed a + bit in an early version of the patch, which added even more indirection. + This suggests that calls to exec->globalData() and/or exec->lexicalGlobalObject() + are common and probably duplicated in lots of places, and could stand + further optimization in C++. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): Test against the specific activation + for our global object, since there's no VM-shared activation structure + anymore. This is guaranteed to have the same success rate as the old test + because activation scope is fixed at compile time. + + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::MarkedBlock): + * heap/MarkedBlock.h: + (JSC::MarkedBlock::globalData): + * heap/WeakSet.cpp: + (JSC::WeakSet::addAllocator): + * heap/WeakSet.h: + (WeakSet): + (JSC::WeakSet::WeakSet): + (JSC::WeakSet::globalData): Store a JSGlobalData* instead of a Heap* + because JSGlobalData->Heap is just a constant fold in the addressing + mode, while Heap->JSGlobalData is an extra pointer dereference. (These + objects should eventually just merge.) + + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_resolve_global_dynamic): See DFGAbstractState.cpp. + + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: Load the activation structure from + the code block instead of the global data because the structure is not + VM-shared anymore. (See DFGAbstractState.cpp.) + + * runtime/JSActivation.cpp: + (JSC::JSActivation::JSActivation): + * runtime/JSActivation.h: + (JSActivation): This is the point of the patch: Remove the data. + + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSGlobalData): No longer VM-shared. (See DFGAbstractState.cpp.) + + (JSC::WeakSet::heap): (See WeakSet.h.) + + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::JSGlobalObject): + (JSC::JSGlobalObject::setGlobalThis): + (JSC::JSGlobalObject::reset): + (JSC::JSGlobalObject::visitChildren): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::withScopeStructure): + (JSC::JSGlobalObject::strictEvalActivationStructure): + (JSC::JSGlobalObject::activationStructure): + (JSC::JSGlobalObject::nameScopeStructure): + (JSC::JSScope::globalThis): + (JSC::JSGlobalObject::globalThis): Data that used to be in the JSScope + class goes here now, so it's not duplicated across all activations. + + * runtime/JSNameScope.h: + (JSC::JSNameScope::JSNameScope): + * runtime/JSScope.cpp: + (JSC::JSScope::visitChildren): This is the point of the patch: Remove the data. + + * runtime/JSScope.h: + (JSScope): + (JSC::JSScope::JSScope): + (JSC::JSScope::globalObject): + (JSC::JSScope::globalData): + * runtime/JSSegmentedVariableObject.h: + (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject): + * runtime/JSSymbolTableObject.h: + (JSC::JSSymbolTableObject::JSSymbolTableObject): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::JSVariableObject): + * runtime/JSWithScope.h: + (JSC::JSWithScope::JSWithScope): + * runtime/StrictEvalActivation.cpp: + (JSC::StrictEvalActivation::StrictEvalActivation): Simplified now that + we don't need to pass so much data to JSScope. + +2012-08-31 Patrick Gansterer <paroga@webkit.org> + + Build fix for WinCE after r127191. + + * bytecode/JumpTable.h: + +2012-08-30 Filip Pizlo <fpizlo@apple.com> + + ASSERTION FAILURE in JSC::JSGlobalData::float32ArrayDescriptor when running fast/js/dfg-float64array.html + https://bugs.webkit.org/show_bug.cgi?id=95398 + + Reviewed by Mark Hahnenberg. + + Trying to get the build failure to be a bit more informative. + + * runtime/JSGlobalData.h: + (JSGlobalData): + +2012-08-30 Geoffrey Garen <ggaren@apple.com> + + Try to fix the Qt build: add some #includes that, for some reason, only the Qt linker requires. + + * runtime/BooleanObject.cpp: + * runtime/ErrorInstance.cpp: + * runtime/NameInstance.cpp: + +2012-08-30 Geoffrey Garen <ggaren@apple.com> + + Fix the Qt build: Removed a now-dead variable. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::execute): + +2012-08-30 Benjamin Poulain <bpoulain@apple.com> + + Ambiguous operator[] after r127191 on some compiler + https://bugs.webkit.org/show_bug.cgi?id=95509 + + Reviewed by Simon Fraser. + + On some compilers, the operator[] conflicts with the Obj-C++ operators. This attempts to solve + the issue. + + * runtime/JSString.h: + (JSC::jsSingleCharacterSubstring): + (JSC::jsString): + (JSC::jsSubstring8): + (JSC::jsSubstring): + (JSC::jsOwnedString): + +2012-08-30 Geoffrey Garen <ggaren@apple.com> + + Try to fix the Qt build: Remove the inline keyword at the declaration + site. + + The Qt compiler seems to be confused, complaining about these functions + not being defined in a translation unit, even though no generated code + in the unit calls these functions. Maybe removing the keyword at the + declaration site will change its mind. + + This shouldn't change the inlining decision at all: the definition is + still inline. + + * interpreter/CallFrame.h: + (ExecState): + +2012-08-30 Geoffrey Garen <ggaren@apple.com> + + Undo Qt build fix guess, since it breaks other builds. + + * runtime/JSArray.h: + +2012-08-30 Geoffrey Garen <ggaren@apple.com> + + Try to fix the Qt build: add an #include to JSArray.h, since + it's included by some of the files Qt complains about, and + some of is functions call the functions Qt complains about. + + * runtime/JSArray.h: + +2012-08-30 Geoffrey Garen <ggaren@apple.com> + + Second step toward fixing the Windows build: Add new symbols. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-08-30 Geoffrey Garen <ggaren@apple.com> + + Try to fix the Qt build: add an #include. + + * bytecode/GetByIdStatus.cpp: + +2012-08-30 Geoffrey Garen <ggaren@apple.com> + + First step toward fixing the Windows build: Remove old symbols. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-08-30 Geoffrey Garen <ggaren@apple.com> + + Use one object instead of two for closures, eliminating ScopeChainNode + https://bugs.webkit.org/show_bug.cgi?id=95501 + + Reviewed by Filip Pizlo. + + This patch removes ScopeChainNode, and moves all the data and related + functions that used to be in ScopeChainNode into JSScope. + + Most of this patch is mechanical changes to use a JSScope* where we used + to use a ScopeChainNode*. I've only specifically commented about items + that were non-mechanical. + + * runtime/Completion.cpp: + (JSC::evaluate): + * runtime/Completion.h: Don't require an explicit scope chain argument + when evaluating code. Clients never wanted anything other than the + global scope, and other arbitrary scopes probably wouldn't work + correctly, anyway. + + * runtime/JSScope.cpp: + * runtime/JSScope.h: + (JSC::JSScope::JSScope): JSScope now requires the data we used to pass to + ScopeChainNode, so it can link itself into the scope chain correctly. + + * runtime/JSWithScope.h: + (JSC::JSWithScope::create): + (JSC::JSWithScope::JSWithScope): JSWithScope gets an extra constructor + for specifically supplying your own scope chain. The DOM needs this + interface for setting up the scope chain for certain event handlers. + Other clients always just push the JSWithScope to the head of the current + scope chain. + +2012-08-30 Mark Lam <mark.lam@apple.com> + + Render unto #ifdef's that which belong to them. + https://bugs.webkit.org/show_bug.cgi?id=95482. + + Reviewed by Filip Pizlo. + + Refining / disambiguating between #ifdefs and adding some. For + example, ENABLE(JIT) is conflated with ENABLE(LLINT) in some places. + Also, we need to add ENABLE(COMPUTED_GOTO_OPCODES) to indicate that we + want interpreted opcodes to use COMPUTED GOTOs apart from ENABLE(LLINT) + and ENABLE(COMPUTED_GOTO_CLASSIC_INTERPRETER). Also cleaned up #ifdefs + in certain places which were previously incorrect. + + * bytecode/CodeBlock.cpp: + (JSC): + (JSC::CodeBlock::bytecodeOffset): + * bytecode/CodeBlock.h: + (CodeBlock): + * bytecode/Opcode.h: + (JSC::padOpcodeName): + * config.h: + * dfg/DFGOperations.cpp: + * interpreter/AbstractPC.cpp: + (JSC::AbstractPC::AbstractPC): + * interpreter/CallFrame.h: + (ExecState): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::~Interpreter): + (JSC::Interpreter::initialize): + (JSC::Interpreter::isOpcode): + (JSC::Interpreter::unwindCallFrame): + (JSC::getLineNumberForCallFrame): + (JSC::getCallerInfo): + (JSC::Interpreter::execute): + (JSC::Interpreter::executeCall): + (JSC::Interpreter::executeConstruct): + (JSC::Interpreter::privateExecute): + * interpreter/Interpreter.h: + (JSC::Interpreter::getOpcode): + (JSC::Interpreter::getOpcodeID): + (Interpreter): + * jit/HostCallReturnValue.h: + * jit/JITCode.h: + (JITCode): + * jit/JITExceptions.cpp: + * jit/JITExceptions.h: + * jit/JSInterfaceJIT.h: + * llint/LLIntData.h: + (JSC::LLInt::getOpcode): + * llint/LLIntEntrypoints.cpp: + (JSC::LLInt::getFunctionEntrypoint): + (JSC::LLInt::getEvalEntrypoint): + (JSC::LLInt::getProgramEntrypoint): + * llint/LLIntOffsetsExtractor.cpp: + (JSC::LLIntOffsetsExtractor::dummy): + * llint/LLIntSlowPaths.cpp: + (LLInt): + * runtime/JSGlobalData.cpp: + (JSC): + +2012-08-30 JungJik Lee <jungjik.lee@samsung.com> + + [EFL][WK2] Add WebMemorySampler feature. + https://bugs.webkit.org/show_bug.cgi?id=91214 + + Reviewed by Kenneth Rohde Christiansen. + + WebMemorySampler collects Javascript stack and JIT memory usage in globalMemoryStatistics. + + * PlatformEfl.cmake: + +2012-08-30 Benjamin Poulain <bpoulain@apple.com> + + Replace JSC::UString by WTF::String + https://bugs.webkit.org/show_bug.cgi?id=95271 + + Reviewed by Geoffrey Garen. + + Having JSC::UString and WTF::String increase the complexity of working on WebKit, and + add useless conversions in the bindings. It also cause some code bloat. + + The performance advantages of UString have been ported over in previous patches. This patch + is the last step: getting rid of UString. + + In addition to the simplified code, this also reduce the binary size by 15kb on x86_64. + + * API/OpaqueJSString.cpp: + (OpaqueJSString::ustring): + * runtime/Identifier.h: + (JSC::Identifier::ustring): + To avoid changing everything at once, the function named ustring() were kept as is. They + will be renamed in a follow up patch. + + * runtime/JSString.h: + (JSC::JSString::string): + (JSC::JSValue::toWTFString): + (JSC::inlineJSValueNotStringtoString): + (JSC::JSValue::toWTFStringInline): + Since JSValue::toString() already exist (and return the JSString), the direct accessor is renamed + to ::toWTFString(). We may change ::string() to ::jsString() and ::toWTFString() to ::toString() + in the future. + + * runtime/StringPrototype.cpp: + (JSC::substituteBackreferencesSlow): Replace the use of UString::getCharacters<>() by String::getCharactersWithUpconvert<>(). + +2012-08-24 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove uses of ClassInfo in StrictEq and CompareEq in the DFG + https://bugs.webkit.org/show_bug.cgi?id=93401 + + Reviewed by Filip Pizlo. + + Another incremental step in removing the dependence on ClassInfo pointers in object headers. + + * bytecode/SpeculatedType.h: + (JSC::isCellOrOtherSpeculation): + (JSC): + * dfg/DFGAbstractState.cpp: Updated the CFA to reflect the changes to the backend. + (JSC::DFG::AbstractState::execute): + * dfg/DFGNode.h: + (Node): + (JSC::DFG::Node::shouldSpeculateString): Added this new function since it was conspicuously absent. + (JSC::DFG::Node::shouldSpeculateNonStringCellOrOther): Also add this function for use in the CFA. + * dfg/DFGSpeculativeJIT.cpp: Refactored how we handle CompareEq and CompareStrictEq in the DFG. We now just + check for Strings by comparing the object's Structure to the global Structure for strings. We only + check for MasqueradesAsUndefined if the watchpoint has fired. These changes allow us to remove our + uses of the ClassInfo pointer for compiling these nodes. + (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality): + (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch): + (JSC::DFG::SpeculativeJIT::compare): + (JSC::DFG::SpeculativeJIT::compileStrictEq): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: Same changes for 32 bit as for 64 bit. + (JSC::DFG::SpeculativeJIT::compileObjectEquality): + (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): + (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compileObjectEquality): + (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): + (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): + +2012-08-30 Yong Li <yoli@rim.com> + + [BlackBerry] Implement IncrementalSweeper for PLATFORM(BLACKBERRY) + https://bugs.webkit.org/show_bug.cgi?id=95469 + + Reviewed by Rob Buis. + + RIM PR# 200595. + Share most code with USE(CF) and implement timer-related methods + for PLATFORM(BLACKBERRY). + + * heap/IncrementalSweeper.cpp: + (JSC): + (JSC::IncrementalSweeper::IncrementalSweeper): + (JSC::IncrementalSweeper::create): + (JSC::IncrementalSweeper::scheduleTimer): + (JSC::IncrementalSweeper::cancelTimer): + (JSC::IncrementalSweeper::doSweep): + * heap/IncrementalSweeper.h: + (IncrementalSweeper): + +2012-08-30 Mark Lam <mark.lam@apple.com> + + Fix broken classic intrpreter build. + https://bugs.webkit.org/show_bug.cgi?id=95484. + + Reviewed by Filip Pizlo. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + +2012-08-30 Byungwoo Lee <bw80.lee@samsung.com> + + Build warning : -Wsign-compare on DFGByteCodeParser.cpp. + https://bugs.webkit.org/show_bug.cgi?id=95418 + + Reviewed by Filip Pizlo. + + There is a build warning '-Wsign-compare' on + findArgumentPositionForLocal() in DFGByteCodeParser.cpp. + + For removing this warning, casting statement is added explicitly. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::findArgumentPositionForLocal): + (JSC::DFG::ByteCodeParser::findArgumentPosition): + +2012-08-30 Yong Li <yoli@rim.com> + + [BlackBerry] Set timer client on platform timer used in HeapTimer + https://bugs.webkit.org/show_bug.cgi?id=95464 + + Reviewed by Rob Buis. + + Otherwise the timer won't work. + + * heap/HeapTimer.cpp: + (JSC::HeapTimer::HeapTimer): + +2012-08-30 Julien BRIANCEAU <jbrianceau@nds.com> + + [sh4] Add missing implementation for JavaScriptCore JIT + https://bugs.webkit.org/show_bug.cgi?id=95452 + + Reviewed by Oliver Hunt. + + * assembler/MacroAssemblerSH4.h: + (JSC::MacroAssemblerSH4::isCompactPtrAlignedAddressOffset): + (MacroAssemblerSH4): + (JSC::MacroAssemblerSH4::add32): + (JSC::MacroAssemblerSH4::convertibleLoadPtr): + * assembler/SH4Assembler.h: + (JSC::SH4Assembler::labelIgnoringWatchpoints): + (SH4Assembler): + (JSC::SH4Assembler::replaceWithLoad): + (JSC::SH4Assembler::replaceWithAddressComputation): + +2012-08-30 Charles Wei <charles.wei@torchmobile.com.cn> + + [BlackBerry] Eliminate build warnings + https://bugs.webkit.org/show_bug.cgi?id=95338 + + Reviewed by Filip Pizlo. + + static_cast to the same type to eliminate the build time warnings. + + * assembler/AssemblerBufferWithConstantPool.h: + (JSC::AssemblerBufferWithConstantPool::flushWithoutBarrier): + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::branch32): + +2012-08-29 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove use of ClassInfo from compileGetByValOnArguments and compileGetArgumentsLength + https://bugs.webkit.org/show_bug.cgi?id=95131 + + Reviewed by Filip Pizlo. + + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): We don't need this speculation check. We can replace it + with an assert to guarantee this. + +2012-08-29 Mark Lam <mark.lam@apple.com> + + Refactoring LLInt::Data. + https://bugs.webkit.org/show_bug.cgi?id=95316. + + Reviewed by Geoff Garen. + + This change allows its opcodeMap to be easily queried from any function + without needing to go through a GlobalData object. It also introduces + the LLInt::getCodePtr() methods that will be used by the LLInt C loop + later to redefine how llint symbols (opcodes and trampoline glue + labels) get resolved. + + * assembler/MacroAssemblerCodeRef.h: + (MacroAssemblerCodePtr): + (JSC::MacroAssemblerCodePtr::createLLIntCodePtr): + (MacroAssemblerCodeRef): + (JSC::MacroAssemblerCodeRef::createLLIntCodeRef): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::adjustPCIfAtCallSite): + (JSC::CodeBlock::bytecodeOffset): + * bytecode/Opcode.h: + Remove the 'const' to simplify things and avoid having to do + additional casts and #ifdefs in many places. + * bytecode/ResolveGlobalStatus.cpp: + (JSC::computeForLLInt): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::generate): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::initialize): + * interpreter/Interpreter.h: + (Interpreter): + * jit/JITExceptions.cpp: + (JSC::genericThrow): + * llint/LLIntData.cpp: + (LLInt): + (JSC::LLInt::initialize): + * llint/LLIntData.h: + (JSC): + (LLInt): + (Data): + (JSC::LLInt::exceptionInstructions): + (JSC::LLInt::opcodeMap): + (JSC::LLInt::getOpcode): + (JSC::LLInt::getCodePtr): + (JSC::LLInt::Data::performAssertions): + * llint/LLIntExceptions.cpp: + (JSC::LLInt::returnToThrowForThrownException): + (JSC::LLInt::returnToThrow): + (JSC::LLInt::callToThrow): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + (JSC::LLInt::handleHostCall): + * runtime/InitializeThreading.cpp: + (JSC::initializeThreadingOnce): Initialize the singleton LLInt data. + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSGlobalData): Removed the now unneeded LLInt::Data instance in + JSGlobalData. + * runtime/JSValue.h: + (JSValue): + +2012-08-29 Gavin Barraclough <barraclough@apple.com> + + PutById uses DataLabel32, not DataLabelCompact + https://bugs.webkit.org/show_bug.cgi?id=95245 + + Reviewed by Geoff Garen. + + JIT::resetPatchPutById calls the the wrong thing on x86-64 – this is moot right now, + since they currently both do the same thing, but if we were to ever make compact mean + 8-bit this could be a real problem. Also, relying on the object still being in eax + on entry to the transition stub isn't very robust - added nonArgGPR1 to at least make + this explicit. + + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emitSlow_op_put_by_id): + - copy regT0 to nonArgGPR1 + (JSC::JIT::privateCompilePutByIdTransition): + - DataLabelCompact -> DataLabel32 + (JSC::JIT::resetPatchPutById): + - reload regT0 from nonArgGPR1 + * jit/JSInterfaceJIT.h: + (JSInterfaceJIT): + - added nonArgGPR1 + +2012-08-28 Yong Li <yoli@rim.com> + + ExecutableAllocator should be destructed after Heap + https://bugs.webkit.org/show_bug.cgi?id=95244 + + Reviewed by Rob Buis. + + RIM PR# 199364. + Make ExecutableAllocator the first member in JSGlobalData. + Existing Web Worker tests can show the issue. + + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSGlobalData): + +2012-08-29 Geoffrey Garen <ggaren@apple.com> + + Try to fix the Windows build. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Export! + +2012-08-28 Geoffrey Garen <ggaren@apple.com> + + Introduced JSWithScope, making all scope objects subclasses of JSScope + https://bugs.webkit.org/show_bug.cgi?id=95295 + + Reviewed by Filip Pizlo. + + This is a step toward removing ScopeChainNode. With a uniform representation + for objects in the scope chain, we can move data from ScopeChainNode + into JSScope. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: Build! + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): Use an explicit JSWithScope object + for 'with' statements. Since 'with' can put any object in the scope + chain, we'll need an adapter object to hold the data ScopeChainNode + currently holds. + + (JSGlobalData): Support for JSWithScope. + + * runtime/JSScope.cpp: + (JSC::JSScope::objectAtScope): + * runtime/JSScope.h: Check for and unwrap JSWithScope. + + * runtime/JSType.h: Support for JSWithScope. + + * runtime/StrictEvalActivation.cpp: + (JSC::StrictEvalActivation::StrictEvalActivation): + * runtime/StrictEvalActivation.h: + (StrictEvalActivation): Inherit from JSScope, to make the scope chain uniform. + + * runtime/JSWithScope.cpp: Added. + (JSC::JSWithScope::visitChildren): + * runtime/JSWithScope.h: Added. + (JSWithScope): + (JSC::JSWithScope::create): + (JSC::JSWithScope::object): + (JSC::JSWithScope::createStructure): + (JSC::JSWithScope::JSWithScope): New adapter object. Since this object + is never exposed to scripts, it doesn't need any meaningful implementation + of property access or other callbacks. + +2012-08-29 Patrick Gansterer <paroga@webkit.org> + + Unreviewed. Build fix for !ENABLE(JIT) after r126962. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + +2012-08-28 Geoffrey Garen <ggaren@apple.com> + + Added JSScope::objectInScope(), and refactored callers to use it + https://bugs.webkit.org/show_bug.cgi?id=95281 + + Reviewed by Gavin Barraclough. + + This is a step toward removing ScopeChainNode. We need a layer of + indirection so that 'with' scopes can proxy for an object. + JSScope::objectInScope() will be that layer. + + * bytecode/EvalCodeCache.h: + (JSC::EvalCodeCache::tryGet): + (JSC::EvalCodeCache::getSlow): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::resolve): + (JSC::BytecodeGenerator::resolveConstDecl): . vs -> + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::unwindCallFrame): + (JSC::Interpreter::execute): + * runtime/JSScope.cpp: + (JSC::JSScope::resolve): + (JSC::JSScope::resolveSkip): + (JSC::JSScope::resolveGlobalDynamic): + (JSC::JSScope::resolveBase): + (JSC::JSScope::resolveWithBase): + (JSC::JSScope::resolveWithThis): Added JSScope::objectAtScope() calls. + + * runtime/JSScope.h: + (JSScope): + (JSC::JSScope::objectAtScope): + (JSC): + (ScopeChainIterator): + (JSC::ScopeChainIterator::ScopeChainIterator): + (JSC::ScopeChainIterator::get): + (JSC::ScopeChainIterator::operator->): + (JSC::ScopeChainIterator::operator++): + (JSC::ScopeChainIterator::operator==): + (JSC::ScopeChainIterator::operator!=): + (JSC::ScopeChainNode::begin): + (JSC::ScopeChainNode::end): I moved ScopeChainIterator to this file + to resolve a circular #include problem. Eventually, I'll probably rename + it to JSScope::iterator, so I think it belongs here. + + * runtime/ScopeChain.cpp: + (JSC::ScopeChainNode::print): + (JSC::ScopeChainNode::localDepth): . vs -> + + * runtime/ScopeChain.h: + (ScopeChainNode): I made the 'object' data member private because it's + no longer safe to access -- you need to call JSScope::objectAtScope() + instead. + + The JITs need to be friends because of the private declaration. + + Subtly, JIT/LLInt code is correct without any changes because JIT/LLInt + code never compiles direct access to a with scope. + +2012-08-28 Mark Lam <mark.lam@apple.com> + + Adding support for adding LLInt opcode extensions. This will be needed + by the LLInt C loop interpreter later. + https://bugs.webkit.org/show_bug.cgi?id=95277. + + Reviewed by Geoffrey Garen. + + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/Opcode.h: + * llint/LLIntOpcode.h: Added. + * llint/LowLevelInterpreter.h: + +2012-08-28 Gavin Barraclough <barraclough@apple.com> + + Rolled out r126928, this broke stuff :'-( + + * jit/JITPropertyAccess.cpp: + (JSC::JIT::privateCompilePutByIdTransition): + (JSC::JIT::resetPatchPutById): + +2012-08-28 Gavin Barraclough <barraclough@apple.com> + + PutById uses DataLabel32, not DataLabelCompact + https://bugs.webkit.org/show_bug.cgi?id=95245 + + Reviewed by Geoff Garen. + + JIT::resetPatchPutById calls the the wrong thing on x86-64 – this is moot right now, + since they currently both do the same thing, but if we were to ever make compact mean + 8-bit this could be a real problem. Also, don't rely on the object still being in eax + on entry to the transition stub – this isn't very robust. + + * jit/JITPropertyAccess.cpp: + (JSC::JIT::privateCompilePutByIdTransition): + - DataLabelCompact -> DataLabel32 + (JSC::JIT::resetPatchPutById): + - reload regT0 from the stack + +2012-08-28 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r126914. + http://trac.webkit.org/changeset/126914 + https://bugs.webkit.org/show_bug.cgi?id=95239 + + it breaks everything and fixes nothing (Requested by pizlo on + #webkit). + + * API/JSCallbackObject.h: + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty): + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): + * API/JSCallbackObjectFunctions.h: + (JSC::::getOwnPropertyNames): + * API/JSClassRef.cpp: + (OpaqueJSClass::~OpaqueJSClass): + (OpaqueJSClassContextData::OpaqueJSClassContextData): + (OpaqueJSClass::contextData): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + (JSC::EvalCodeCache::visitAggregate): + (JSC::CodeBlock::nameForRegister): + * bytecode/JumpTable.h: + (JSC::StringJumpTable::offsetForValue): + (JSC::StringJumpTable::ctiForValue): + * bytecode/LazyOperandValueProfile.cpp: + (JSC::LazyOperandValueProfileParser::getIfPresent): + * bytecode/SamplingTool.cpp: + (JSC::SamplingTool::dump): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::addVar): + (JSC::BytecodeGenerator::addGlobalVar): + (JSC::BytecodeGenerator::addConstant): + (JSC::BytecodeGenerator::addConstantValue): + (JSC::BytecodeGenerator::emitLoad): + (JSC::BytecodeGenerator::addStringConstant): + (JSC::BytecodeGenerator::emitLazyNewFunction): + * bytecompiler/NodesCodegen.cpp: + (JSC::PropertyListNode::emitBytecode): + * debugger/Debugger.cpp: + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): + (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild): + * dfg/DFGAssemblyHelpers.cpp: + (JSC::DFG::AssemblyHelpers::decodedCodeMapFor): + * dfg/DFGByteCodeCache.h: + (JSC::DFG::ByteCodeCache::~ByteCodeCache): + (JSC::DFG::ByteCodeCache::get): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::cellConstant): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): + (JSC::DFG::StructureCheckHoistingPhase::noticeClobber): + * heap/Heap.cpp: + (JSC::Heap::markProtectedObjects): + * heap/Heap.h: + (JSC::Heap::forEachProtectedCell): + * heap/JITStubRoutineSet.cpp: + (JSC::JITStubRoutineSet::markSlow): + (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): + * heap/MarkStack.cpp: + (JSC::MarkStack::internalAppend): + * heap/Weak.h: + (JSC::weakRemove): + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + * jit/JITStubs.cpp: + (JSC::JITThunks::ctiStub): + * parser/Parser.cpp: + (JSC::::parseStrictObjectLiteral): + * profiler/Profile.cpp: + (JSC::functionNameCountPairComparator): + (JSC::Profile::debugPrintDataSampleStyle): + * runtime/Identifier.cpp: + (JSC::Identifier::add): + * runtime/JSActivation.cpp: + (JSC::JSActivation::getOwnPropertyNames): + (JSC::JSActivation::symbolTablePutWithAttributes): + * runtime/JSArray.cpp: + (JSC::SparseArrayValueMap::put): + (JSC::SparseArrayValueMap::putDirect): + (JSC::SparseArrayValueMap::visitChildren): + (JSC::JSArray::enterDictionaryMode): + (JSC::JSArray::defineOwnNumericProperty): + (JSC::JSArray::getOwnPropertySlotByIndex): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::putByIndexBeyondVectorLength): + (JSC::JSArray::putDirectIndexBeyondVectorLength): + (JSC::JSArray::deletePropertyByIndex): + (JSC::JSArray::getOwnPropertyNames): + (JSC::JSArray::setLength): + (JSC::JSArray::sort): + (JSC::JSArray::compactForSorting): + (JSC::JSArray::checkConsistency): + * runtime/JSSymbolTableObject.cpp: + (JSC::JSSymbolTableObject::getOwnPropertyNames): + * runtime/JSSymbolTableObject.h: + (JSC::symbolTableGet): + (JSC::symbolTablePut): + (JSC::symbolTablePutWithAttributes): + * runtime/RegExpCache.cpp: + (JSC::RegExpCache::invalidateCode): + * runtime/WeakGCMap.h: + (JSC::WeakGCMap::clear): + (JSC::WeakGCMap::set): + * tools/ProfileTreeNode.h: + (JSC::ProfileTreeNode::sampleChild): + (JSC::ProfileTreeNode::childCount): + (JSC::ProfileTreeNode::dumpInternal): + (JSC::ProfileTreeNode::compareEntries): + +2012-08-28 Filip Pizlo <fpizlo@apple.com> + + LLInt should not rely on ordering of global labels + https://bugs.webkit.org/show_bug.cgi?id=95221 + + Reviewed by Oliver Hunt. + + * llint/LowLevelInterpreter.asm: + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-08-28 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + Rename first/second to key/value in HashMap iterators + https://bugs.webkit.org/show_bug.cgi?id=82784 + + Reviewed by Eric Seidel. + + * API/JSCallbackObject.h: + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty): + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): + * API/JSCallbackObjectFunctions.h: + (JSC::::getOwnPropertyNames): + * API/JSClassRef.cpp: + (OpaqueJSClass::~OpaqueJSClass): + (OpaqueJSClassContextData::OpaqueJSClassContextData): + (OpaqueJSClass::contextData): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + (JSC::EvalCodeCache::visitAggregate): + (JSC::CodeBlock::nameForRegister): + * bytecode/JumpTable.h: + (JSC::StringJumpTable::offsetForValue): + (JSC::StringJumpTable::ctiForValue): + * bytecode/LazyOperandValueProfile.cpp: + (JSC::LazyOperandValueProfileParser::getIfPresent): + * bytecode/SamplingTool.cpp: + (JSC::SamplingTool::dump): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::addVar): + (JSC::BytecodeGenerator::addGlobalVar): + (JSC::BytecodeGenerator::addConstant): + (JSC::BytecodeGenerator::addConstantValue): + (JSC::BytecodeGenerator::emitLoad): + (JSC::BytecodeGenerator::addStringConstant): + (JSC::BytecodeGenerator::emitLazyNewFunction): + * bytecompiler/NodesCodegen.cpp: + (JSC::PropertyListNode::emitBytecode): + * debugger/Debugger.cpp: + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): + (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild): + * dfg/DFGAssemblyHelpers.cpp: + (JSC::DFG::AssemblyHelpers::decodedCodeMapFor): + * dfg/DFGByteCodeCache.h: + (JSC::DFG::ByteCodeCache::~ByteCodeCache): + (JSC::DFG::ByteCodeCache::get): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::cellConstant): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): + (JSC::DFG::StructureCheckHoistingPhase::noticeClobber): + * heap/Heap.cpp: + (JSC::Heap::markProtectedObjects): + * heap/Heap.h: + (JSC::Heap::forEachProtectedCell): + * heap/JITStubRoutineSet.cpp: + (JSC::JITStubRoutineSet::markSlow): + (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): + * heap/MarkStack.cpp: + (JSC::MarkStack::internalAppend): + * heap/Weak.h: + (JSC::weakRemove): + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + * jit/JITStubs.cpp: + (JSC::JITThunks::ctiStub): + * parser/Parser.cpp: + (JSC::::parseStrictObjectLiteral): + * profiler/Profile.cpp: + (JSC::functionNameCountPairComparator): + (JSC::Profile::debugPrintDataSampleStyle): + * runtime/Identifier.cpp: + (JSC::Identifier::add): + * runtime/JSActivation.cpp: + (JSC::JSActivation::getOwnPropertyNames): + (JSC::JSActivation::symbolTablePutWithAttributes): + * runtime/JSArray.cpp: + (JSC::SparseArrayValueMap::put): + (JSC::SparseArrayValueMap::putDirect): + (JSC::SparseArrayValueMap::visitChildren): + (JSC::JSArray::enterDictionaryMode): + (JSC::JSArray::defineOwnNumericProperty): + (JSC::JSArray::getOwnPropertySlotByIndex): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::putByIndexBeyondVectorLength): + (JSC::JSArray::putDirectIndexBeyondVectorLength): + (JSC::JSArray::deletePropertyByIndex): + (JSC::JSArray::getOwnPropertyNames): + (JSC::JSArray::setLength): + (JSC::JSArray::sort): + (JSC::JSArray::compactForSorting): + (JSC::JSArray::checkConsistency): + * runtime/JSSymbolTableObject.cpp: + (JSC::JSSymbolTableObject::getOwnPropertyNames): + * runtime/JSSymbolTableObject.h: + (JSC::symbolTableGet): + (JSC::symbolTablePut): + (JSC::symbolTablePutWithAttributes): + * runtime/RegExpCache.cpp: + (JSC::RegExpCache::invalidateCode): + * runtime/WeakGCMap.h: + (JSC::WeakGCMap::clear): + (JSC::WeakGCMap::set): + * tools/ProfileTreeNode.h: + (JSC::ProfileTreeNode::sampleChild): + (JSC::ProfileTreeNode::childCount): + (JSC::ProfileTreeNode::dumpInternal): + (JSC::ProfileTreeNode::compareEntries): + +2012-08-28 Geoffrey Garen <ggaren@apple.com> + + GCC warning in JSActivation is causing Mac EWS errors + https://bugs.webkit.org/show_bug.cgi?id=95103 + + Reviewed by Sam Weinig. + + Try to fix a strict aliasing violation by using bitwise_cast. The + union in the cast should signal to the compiler that aliasing between + types is happening. + + * runtime/JSActivation.cpp: + (JSC::JSActivation::visitChildren): + +2012-08-28 Geoffrey Garen <ggaren@apple.com> + + Build fix: svn add two files I forgot in my last patch. + +2012-08-27 Geoffrey Garen <ggaren@apple.com> + + Refactored and consolidated variable resolution functions + https://bugs.webkit.org/show_bug.cgi?id=95166 + + Reviewed by Filip Pizlo. + + This patch does a few things: + + (1) Introduces a new class, JSScope, which is the base class for all + objects that represent a scope in the scope chain. + + (2) Refactors and consolidates duplicate implementations of variable + resolution into the JSScope class. + + (3) Renames JSStaticScopeObject to JSNameScope because, as distinct from + something like a 'let' scope, JSStaticScopeObject only has storage for a + single name. + + These changes makes logical sense to me as-is. I will also use them in an + upcoming optimization. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: Build! + + * bytecode/CodeBlock.cpp: + (JSC): Build fix for LLInt-only builds. + + * bytecode/GlobalResolveInfo.h: + (GlobalResolveInfo): Use PropertyOffset to be consistent with other parts + of the engine. + + * bytecompiler/NodesCodegen.cpp: + * dfg/DFGOperations.cpp: Use the shared code in JSScope instead of rolling + our own. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::execute): + (JSC::Interpreter::createExceptionScope): + (JSC::Interpreter::privateExecute): + * interpreter/Interpreter.h: Use the shared code in JSScope instead of rolling + our own. + + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): Use the shared code in JSScope instead of rolling + our own. + + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + (LLInt): Use the shared code in JSScope instead of rolling our own. Note + that one of these slow paths calls the wrong helper function. I left it + that way to avoid a behavior change in a refactoring patch. + + * parser/Nodes.cpp: Updated for rename. + + * runtime/CommonSlowPaths.h: + (CommonSlowPaths): Removed resolve slow paths because were duplicative. + + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSGlobalData): Updated for renames. + + * runtime/JSNameScope.cpp: Copied from Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp. + (JSC): + (JSC::JSNameScope::visitChildren): + (JSC::JSNameScope::toThisObject): + (JSC::JSNameScope::put): + (JSC::JSNameScope::getOwnPropertySlot): + * runtime/JSNameScope.h: Copied from Source/JavaScriptCore/runtime/JSStaticScopeObject.h. + (JSC): + (JSC::JSNameScope::create): + (JSC::JSNameScope::createStructure): + (JSNameScope): + (JSC::JSNameScope::JSNameScope): + (JSC::JSNameScope::isDynamicScope): Used do-webcore-rename script here. + It is fabulous! + + * runtime/JSObject.h: + (JSObject): + (JSC::JSObject::isNameScopeObject): More rename. + + * runtime/JSScope.cpp: Added. + (JSC): + (JSC::JSScope::isDynamicScope): + (JSC::JSScope::resolve): + (JSC::JSScope::resolveSkip): + (JSC::JSScope::resolveGlobal): + (JSC::JSScope::resolveGlobalDynamic): + (JSC::JSScope::resolveBase): + (JSC::JSScope::resolveWithBase): + (JSC::JSScope::resolveWithThis): + * runtime/JSScope.h: Added. + (JSC): + (JSScope): + (JSC::JSScope::JSScope): All the code here is a port from the + Interpreter.cpp implementations of this functionality. + + * runtime/JSStaticScopeObject.cpp: Removed. + * runtime/JSStaticScopeObject.h: Removed. + + * runtime/JSSymbolTableObject.cpp: + (JSC): + * runtime/JSSymbolTableObject.h: + (JSSymbolTableObject): + * runtime/JSType.h: Updated for rename. + + * runtime/Operations.h: + (JSC::resolveBase): Removed because it was duplicative. + +2012-08-28 Alban Browaeys <prahal@yahoo.com> + + [GTK] LLint build fails with -g -02 + https://bugs.webkit.org/show_bug.cgi?id=90098 + + Reviewed by Filip Pizlo. + + Avoid duplicate offsets for llint, discarding them. + + * offlineasm/offsets.rb: + +2012-08-27 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r126836. + http://trac.webkit.org/changeset/126836 + https://bugs.webkit.org/show_bug.cgi?id=95163 + + Broke all Apple ports, EFL, and Qt. (Requested by tkent on + #webkit). + + * API/JSCallbackObject.h: + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty): + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): + * API/JSCallbackObjectFunctions.h: + (JSC::::getOwnPropertyNames): + * API/JSClassRef.cpp: + (OpaqueJSClass::~OpaqueJSClass): + (OpaqueJSClassContextData::OpaqueJSClassContextData): + (OpaqueJSClass::contextData): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + (JSC::EvalCodeCache::visitAggregate): + (JSC::CodeBlock::nameForRegister): + * bytecode/JumpTable.h: + (JSC::StringJumpTable::offsetForValue): + (JSC::StringJumpTable::ctiForValue): + * bytecode/LazyOperandValueProfile.cpp: + (JSC::LazyOperandValueProfileParser::getIfPresent): + * bytecode/SamplingTool.cpp: + (JSC::SamplingTool::dump): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::addVar): + (JSC::BytecodeGenerator::addGlobalVar): + (JSC::BytecodeGenerator::addConstant): + (JSC::BytecodeGenerator::addConstantValue): + (JSC::BytecodeGenerator::emitLoad): + (JSC::BytecodeGenerator::addStringConstant): + (JSC::BytecodeGenerator::emitLazyNewFunction): + * bytecompiler/NodesCodegen.cpp: + (JSC::PropertyListNode::emitBytecode): + * debugger/Debugger.cpp: + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): + (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild): + * dfg/DFGAssemblyHelpers.cpp: + (JSC::DFG::AssemblyHelpers::decodedCodeMapFor): + * dfg/DFGByteCodeCache.h: + (JSC::DFG::ByteCodeCache::~ByteCodeCache): + (JSC::DFG::ByteCodeCache::get): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::cellConstant): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): + (JSC::DFG::StructureCheckHoistingPhase::noticeClobber): + * heap/Heap.cpp: + (JSC::Heap::markProtectedObjects): + * heap/Heap.h: + (JSC::Heap::forEachProtectedCell): + * heap/JITStubRoutineSet.cpp: + (JSC::JITStubRoutineSet::markSlow): + (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): + * heap/MarkStack.cpp: + (JSC::MarkStack::internalAppend): + * heap/Weak.h: + (JSC::weakRemove): + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + * jit/JITStubs.cpp: + (JSC::JITThunks::ctiStub): + * parser/Parser.cpp: + (JSC::::parseStrictObjectLiteral): + * profiler/Profile.cpp: + (JSC::functionNameCountPairComparator): + (JSC::Profile::debugPrintDataSampleStyle): + * runtime/Identifier.cpp: + (JSC::Identifier::add): + * runtime/JSActivation.cpp: + (JSC::JSActivation::getOwnPropertyNames): + (JSC::JSActivation::symbolTablePutWithAttributes): + * runtime/JSArray.cpp: + (JSC::SparseArrayValueMap::put): + (JSC::SparseArrayValueMap::putDirect): + (JSC::SparseArrayValueMap::visitChildren): + (JSC::JSArray::enterDictionaryMode): + (JSC::JSArray::defineOwnNumericProperty): + (JSC::JSArray::getOwnPropertySlotByIndex): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::putByIndexBeyondVectorLength): + (JSC::JSArray::putDirectIndexBeyondVectorLength): + (JSC::JSArray::deletePropertyByIndex): + (JSC::JSArray::getOwnPropertyNames): + (JSC::JSArray::setLength): + (JSC::JSArray::sort): + (JSC::JSArray::compactForSorting): + (JSC::JSArray::checkConsistency): + * runtime/JSSymbolTableObject.cpp: + (JSC::JSSymbolTableObject::getOwnPropertyNames): + * runtime/JSSymbolTableObject.h: + (JSC::symbolTableGet): + (JSC::symbolTablePut): + (JSC::symbolTablePutWithAttributes): + * runtime/RegExpCache.cpp: + (JSC::RegExpCache::invalidateCode): + * runtime/WeakGCMap.h: + (JSC::WeakGCMap::clear): + (JSC::WeakGCMap::set): + * tools/ProfileTreeNode.h: + (JSC::ProfileTreeNode::sampleChild): + (JSC::ProfileTreeNode::childCount): + (JSC::ProfileTreeNode::dumpInternal): + (JSC::ProfileTreeNode::compareEntries): + +2012-08-27 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + Rename first/second to key/value in HashMap iterators + https://bugs.webkit.org/show_bug.cgi?id=82784 + + Reviewed by Eric Seidel. + + * API/JSCallbackObject.h: + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty): + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): + (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): + * API/JSCallbackObjectFunctions.h: + (JSC::::getOwnPropertyNames): + * API/JSClassRef.cpp: + (OpaqueJSClass::~OpaqueJSClass): + (OpaqueJSClassContextData::OpaqueJSClassContextData): + (OpaqueJSClass::contextData): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + (JSC::EvalCodeCache::visitAggregate): + (JSC::CodeBlock::nameForRegister): + * bytecode/JumpTable.h: + (JSC::StringJumpTable::offsetForValue): + (JSC::StringJumpTable::ctiForValue): + * bytecode/LazyOperandValueProfile.cpp: + (JSC::LazyOperandValueProfileParser::getIfPresent): + * bytecode/SamplingTool.cpp: + (JSC::SamplingTool::dump): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::addVar): + (JSC::BytecodeGenerator::addGlobalVar): + (JSC::BytecodeGenerator::addConstant): + (JSC::BytecodeGenerator::addConstantValue): + (JSC::BytecodeGenerator::emitLoad): + (JSC::BytecodeGenerator::addStringConstant): + (JSC::BytecodeGenerator::emitLazyNewFunction): + * bytecompiler/NodesCodegen.cpp: + (JSC::PropertyListNode::emitBytecode): + * debugger/Debugger.cpp: + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): + (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild): + * dfg/DFGAssemblyHelpers.cpp: + (JSC::DFG::AssemblyHelpers::decodedCodeMapFor): + * dfg/DFGByteCodeCache.h: + (JSC::DFG::ByteCodeCache::~ByteCodeCache): + (JSC::DFG::ByteCodeCache::get): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::cellConstant): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): + (JSC::DFG::StructureCheckHoistingPhase::noticeClobber): + * heap/Heap.cpp: + (JSC::Heap::markProtectedObjects): + * heap/Heap.h: + (JSC::Heap::forEachProtectedCell): + * heap/JITStubRoutineSet.cpp: + (JSC::JITStubRoutineSet::markSlow): + (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): + * heap/MarkStack.cpp: + (JSC::MarkStack::internalAppend): + * heap/Weak.h: + (JSC::weakRemove): + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + * jit/JITStubs.cpp: + (JSC::JITThunks::ctiStub): + * parser/Parser.cpp: + (JSC::::parseStrictObjectLiteral): + * profiler/Profile.cpp: + (JSC::functionNameCountPairComparator): + (JSC::Profile::debugPrintDataSampleStyle): + * runtime/Identifier.cpp: + (JSC::Identifier::add): + * runtime/JSActivation.cpp: + (JSC::JSActivation::getOwnPropertyNames): + (JSC::JSActivation::symbolTablePutWithAttributes): + * runtime/JSArray.cpp: + (JSC::SparseArrayValueMap::put): + (JSC::SparseArrayValueMap::putDirect): + (JSC::SparseArrayValueMap::visitChildren): + (JSC::JSArray::enterDictionaryMode): + (JSC::JSArray::defineOwnNumericProperty): + (JSC::JSArray::getOwnPropertySlotByIndex): + (JSC::JSArray::getOwnPropertyDescriptor): + (JSC::JSArray::putByIndexBeyondVectorLength): + (JSC::JSArray::putDirectIndexBeyondVectorLength): + (JSC::JSArray::deletePropertyByIndex): + (JSC::JSArray::getOwnPropertyNames): + (JSC::JSArray::setLength): + (JSC::JSArray::sort): + (JSC::JSArray::compactForSorting): + (JSC::JSArray::checkConsistency): + * runtime/JSSymbolTableObject.cpp: + (JSC::JSSymbolTableObject::getOwnPropertyNames): + * runtime/JSSymbolTableObject.h: + (JSC::symbolTableGet): + (JSC::symbolTablePut): + (JSC::symbolTablePutWithAttributes): + * runtime/RegExpCache.cpp: + (JSC::RegExpCache::invalidateCode): + * runtime/WeakGCMap.h: + (JSC::WeakGCMap::clear): + (JSC::WeakGCMap::set): + * tools/ProfileTreeNode.h: + (JSC::ProfileTreeNode::sampleChild): + (JSC::ProfileTreeNode::childCount): + (JSC::ProfileTreeNode::dumpInternal): + (JSC::ProfileTreeNode::compareEntries): + +2012-08-27 Filip Pizlo <fpizlo@apple.com> + + Structure check hoisting should abstain if the OSR entry's must-handle value for the respective variable has a different structure + https://bugs.webkit.org/show_bug.cgi?id=95141 + <rdar://problem/12170401> + + Reviewed by Mark Hahnenberg. + + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-08-27 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove use of ClassInfo from SpeculativeJIT::compileGetByValOnArguments + https://bugs.webkit.org/show_bug.cgi?id=95131 + + Reviewed by Filip Pizlo. + + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): We don't need this speculation check. We can replace it + with an assert to guarantee this. + +2012-08-27 Oliver Hunt <oliver@apple.com> + + Remove opcode definition autogen for now + https://bugs.webkit.org/show_bug.cgi?id=95148 + + Reviewed by Mark Hahnenberg. + + This isn't worth doing at the moment. + + * DerivedSources.make: + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecode/OpcodeDefinitions.h: Removed. + * bytecode/opcodes: Removed. + * opcode_definition_generator.py: Removed. + * opcode_generator.py: Removed. + * opcode_parser.py: Removed. + +2012-08-27 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove uses of TypedArray ClassInfo from SpeculativeJIT::checkArgumentTypes + https://bugs.webkit.org/show_bug.cgi?id=95112 + + Reviewed by Filip Pizlo. + + Removing these checks since we no longer need them. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::initialize): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::checkArgumentTypes): + +2012-08-27 Benjamin Poulain <benjamin@webkit.org> + + Add ECMAScript Number to String conversion to WTF::String + https://bugs.webkit.org/show_bug.cgi?id=95016 + + Reviewed by Geoffrey Garen. + + Rename UString::number(double) to UString::numberToStringECMAScript(double) to + differenciate it from the fixed-width conversion performed by String::number(). + + * parser/ParserArena.h: + (JSC::IdentifierArena::makeNumericIdentifier): + * runtime/JSONObject.cpp: + (JSC::Stringifier::appendStringifiedValue): + * runtime/NumberPrototype.cpp: + (JSC::numberProtoFuncToExponential): + (JSC::numberProtoFuncToFixed): + (JSC::numberProtoFuncToPrecision): + (JSC::numberProtoFuncToString): + * runtime/NumericStrings.h: + (JSC::NumericStrings::add): + * runtime/UString.cpp: + (JSC::UString::numberToStringECMAScript): + * runtime/UString.h: + (UString): + +2012-08-27 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com> + + Rename RegisterProtocolHandler API to NavigatorContentUtils + https://bugs.webkit.org/show_bug.cgi?id=94920 + + Reviewed by Adam Barth. + + ENABLE_REGISTER_PROTOCOL_HANDLER is renamed to ENABLE_NAVIGATOR_CONTENT_UTILS. + + * Configurations/FeatureDefines.xcconfig: + +2012-08-26 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, fix for builds without VALUE_PROFILING. I had forgotten that shouldEmitProfiling() + is designed to return true if DFG_JIT is disabled. I should be using canBeOptimized() instead. + + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): + * jit/JITCall32_64.cpp: + (JSC::JIT::compileOpCall): + +2012-08-26 Geoffrey Garen <ggaren@apple.com> + + Don't allocate space for arguments and call frame if arguments aren't captured + https://bugs.webkit.org/show_bug.cgi?id=95024 + + Reviewed by Phil Pizlo. + + 27% on v8-real-earley. + + * runtime/JSActivation.h: + (JSC::JSActivation::registerOffset): The offset is zero if we're skipping + the arguments and call frame because "offset" means space reserved for + those things. + + (JSC::JSActivation::tearOff): Don't copy the scope chain and callee. We + don't need them for anything, and we're no longer guaranteed to have + space for them. + +2012-08-26 Geoffrey Garen <ggaren@apple.com> + + Removed the NULL checks from visitChildren functions + https://bugs.webkit.org/show_bug.cgi?id=95021 + + Reviewed by Oliver Hunt. + + As of http://trac.webkit.org/changeset/126624, all values are NULL-checked + during GC, so explicit NULL checks aren't needed anymore. + +2011-08-26 Geoffrey Garen <ggaren@apple.com> + + Removed a JSC-specific hack from the web inspector + https://bugs.webkit.org/show_bug.cgi?id=95033 + + Reviewed by Filip Pizlo. + + Added support for what the web inspector really wanted instead. + + * runtime/JSActivation.cpp: + (JSC::JSActivation::symbolTableGet): + (JSC::JSActivation::symbolTablePut): Added some explanation for these + checks, which were non-obvious to me. + + (JSC::JSActivation::getOwnPropertySlot): It's impossible to access the + arguments property of an activation after it's been torn off, since the + only way to tear off an activation is to instantiate a new function, + which has its own arguments property in scope. However, the inspector + get special access to activations, and may try to perform this access, + so we need a special guard to maintain coherence and avoid crashing in + case the activation optimized out the arguments property. + + * runtime/JSActivation.cpp: + (JSC::JSActivation::symbolTableGet): + (JSC::JSActivation::symbolTablePut): + (JSC::JSActivation::getOwnPropertyNames): + (JSC::JSActivation::getOwnPropertyDescriptor): Provide getOwnPropertyNames + and getOwnPropertyDescriptor implementations, to meet the web inspector's + needs. (User code can never call these.) + +2012-08-24 Filip Pizlo <fpizlo@apple.com> + + Finally inlining should correctly track the catch context + https://bugs.webkit.org/show_bug.cgi?id=94986 + <rdar://problem/11753784> + + Reviewed by Sam Weinig. + + This fixes two behaviors: + + 1) Throwing from a finally block. Previously, we would seem to reenter the finally + block - though only once. + + 2) Executing a finally block from some nested context, for example due to a + 'continue', 'break', or 'return' in the try. This would execute the finally + block in the context of of the try block, which could lead to either scope depth + mismatches or reexecutions of the finally block on throw, similarly to (1) but + for different reasons. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC): + (JSC::BytecodeGenerator::pushFinallyContext): + (JSC::BytecodeGenerator::emitComplexJumpScopes): + (JSC::BytecodeGenerator::pushTry): + (JSC::BytecodeGenerator::popTryAndEmitCatch): + * bytecompiler/BytecodeGenerator.h: + (FinallyContext): + (TryData): + (JSC): + (TryContext): + (TryRange): + (BytecodeGenerator): + * bytecompiler/NodesCodegen.cpp: + (JSC::TryNode::emitBytecode): + +2012-08-26 Filip Pizlo <fpizlo@apple.com> + + Array type checks and storage accesses should be uniformly represented and available to CSE + https://bugs.webkit.org/show_bug.cgi?id=95013 + + Reviewed by Oliver Hunt. + + This uniformly breaks up all array accesses into up to three parts: + + 1) The type check, using a newly introduced CheckArray node, in addition to possibly + a CheckStructure node. We were already inserting the CheckStructure prior to this + patch. The CheckArray node will be automatically eliminated if the thing it was + checking for had already been checked for, either intentionally (a CheckStructure + inserted based on the array profile of this access) or accidentally (some checks, + typically a CheckStructure, inserted for some unrelated operations). The + CheckArray node may not be inserted if the array type is non-specific (Generic or + ForceExit). + + 2) The storage load using GetIndexedPropertyStorage. Previously, this only worked for + GetByVal. Now it works for all array accesses. The storage load may not be + inserted if the mode of array access does not permit CSE of storage loads (like + non-specific modes or Arguments). + + 3) The access itself: one of GetByVal, PutByVal, PutByValAlias, ArrayPush, ArrayPop, + GetArrayLength, StringCharAt, or StringCharCodeAt. + + This means that the type check can be subjected to CSE even if the CFA isn't smart + enough to reason about it (yet!). It also means that the storage load can always be + subjected to CSE; previously CSE on storage load only worked for array loads and not + other forms of access. Finally, it removes the bizarre behavior that + GetIndexedPropertyStorage previously had: previously, it was responsible for the type + check in some cases, but not others; this made reasoning about the CFA really + confusing. + + This change also disables late refinement of array mode, since I decided that + supporting that feature is both confusing and likely unprofitable. The array modes are + now locked in in the first fixup run after prediction propagation. Of course, + refinements from Generic to something else would not have been a problem; we could + reenable those if we thought we really needed to. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + * dfg/DFGArrayMode.cpp: + (JSC::DFG::fromStructure): + (DFG): + (JSC::DFG::refineArrayMode): + * dfg/DFGArrayMode.h: + (DFG): + (JSC::DFG::modeIsJSArray): + (JSC::DFG::lengthNeedsStorage): + (JSC::DFG::modeIsSpecific): + (JSC::DFG::modeSupportsLength): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::ByteCodeParser): + (JSC::DFG::ByteCodeParser::getArrayMode): + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::getArrayModeAndEmitChecks): + (JSC::DFG::ByteCodeParser::handleIntrinsic): + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::mergeBlocks): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::CSEPhase): + (JSC::DFG::CSEPhase::checkStructureElimination): + (CSEPhase): + (JSC::DFG::CSEPhase::checkArrayElimination): + (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + (JSC::DFG::performCSE): + * dfg/DFGCSEPhase.h: + (DFG): + * dfg/DFGCommon.h: + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::foldConstants): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + (JSC::DFG::FixupPhase::checkArray): + (FixupPhase): + (JSC::DFG::FixupPhase::blessArrayOperation): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::Graph): + (DFG): + (JSC::DFG::Graph::dump): + (JSC::DFG::Graph::collectGarbage): + * dfg/DFGGraph.h: + (Graph): + (JSC::DFG::Graph::vote): + (JSC::DFG::Graph::substitute): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasArrayMode): + (JSC::DFG::Node::setArrayMode): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOperations.cpp: + * dfg/DFGPhase.h: + (DFG): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + (JSC::DFG::PredictionPropagationPhase::mergeDefaultFlags): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::checkArray): + (JSC::DFG::SpeculativeJIT::useChildren): + (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): + (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray): + (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): + (JSC::DFG::SpeculativeJIT::compileGetArrayLength): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-08-26 Filip Pizlo <fpizlo@apple.com> + + DFGGraph.h has a bogus comment about the nature of StorageAccessData + https://bugs.webkit.org/show_bug.cgi?id=95035 + + Reviewed by Oliver Hunt. + + The comment is both wrong (storage access instructions don't reference CheckStructure) + and highly redundant: of course it's the case that two structures may have the same + identifier. Our interference analyses currently don't care about this and make the + conservative assumptions when necessary (same identifier, same object -> must be same + property; same identifier, may be same object -> may be the same property). Better to + remove the bogus comment since the code that operates over this data structure is + fairly self-explanatory already. + + * dfg/DFGGraph.h: + (StorageAccessData): + +2012-08-25 Geoffrey Garen <ggaren@apple.com> + + Try a little harder to fix the Linux build. + + * runtime/JSActivation.cpp: + * runtime/JSActivation.h: + +2012-08-25 Geoffrey Garen <ggaren@apple.com> + + Try to fix the Linux build. + + * runtime/JSActivation.cpp: + +2012-08-25 Geoffrey Garen <ggaren@apple.com> + + Don't use malloc / destructors for activation objects + https://bugs.webkit.org/show_bug.cgi?id=94897 + + Reviewed by Oliver Hunt. + + 65% faster on v8-real-earley. + + Lots of boilerplate here, but the jist is this: + + (1) Use CopiedSpace instead of malloc to allocate the activation's + backing store. + + (2) Use MarkedSpace instead of ref-counting to allocate the symbol table. + + (3) ==> No more destructor. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::CodeBlock): + (JSC::CodeBlock::stronglyVisitStrongReferences): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::symbolTable): + (CodeBlock): + (JSC::GlobalCodeBlock::GlobalCodeBlock): + (JSC::FunctionCodeBlock::FunctionCodeBlock): + (FunctionCodeBlock): SymbolTable is a GC object now, so it gets a write + barrier and visit calls instead of ref-counting. I changed all CodeBlocks + to use shared symbol tables because the distinction between shared and + unshared hurt my head. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::resolve): + (JSC::BytecodeGenerator::resolveConstDecl): + (JSC::BytecodeGenerator::emitPutStaticVar): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): Sometimes, a period just wants + to be an arrow. And then C++ is there to accommodate. + + * jit/JITDriver.h: + (JSC::jitCompileFunctionIfAppropriate): + * runtime/Arguments.h: + (ArgumentsData): + (JSC::Arguments::setRegisters): + (Arguments): + (JSC::Arguments::argument): + (JSC::Arguments::finishCreation): + * runtime/Executable.cpp: + (JSC::FunctionExecutable::FunctionExecutable): + (JSC::ProgramExecutable::compileInternal): + (JSC::FunctionExecutable::compileForCallInternal): + (JSC::FunctionExecutable::compileForConstructInternal): + (JSC::FunctionExecutable::visitChildren): + * runtime/Executable.h: + (JSC::FunctionExecutable::symbolTable): + (FunctionExecutable): + * runtime/ExecutionHarness.h: + (JSC::prepareFunctionForExecution): I changed from WriteBarrier to + WriteBarrierBase so activations could reuse StorageBarrier and PropertyStorage. + + * runtime/JSActivation.cpp: + (JSC::JSActivation::JSActivation): + (JSC::JSActivation::finishCreation): Allocate the symbol table here, + after we're fully constructed, to avoid GC during initialization. + + (JSC::JSActivation::visitChildren): + (JSC::JSActivation::symbolTableGet): + (JSC::JSActivation::symbolTablePut): + (JSC::JSActivation::getOwnPropertyNames): + (JSC::JSActivation::symbolTablePutWithAttributes): + * runtime/JSActivation.h: + (JSC::JSActivation::create): + (JSActivation): + (JSC::JSActivation::registerOffset): + (JSC): + (JSC::JSActivation::registerArraySize): + (JSC::JSActivation::registerArraySizeInBytes): + (JSC::JSActivation::tearOff): Tear-off zero-initializes all uncopied + registers. This makes it safe to copyAndAppend the full buffer in + visitChildren, without any extra checks. + + * runtime/JSCell.h: + (JSCell): Moved a shared default set of flags into this base class, so + I could use it in a few places. + + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSGlobalData): New structure for symbol tables. + + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::JSGlobalObject): + (JSC::JSGlobalObject::addStaticGlobals): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::symbolTableHasProperty): We don't need an inline + symbol table -- JSSymbolTableObject will GC allocate one for us. + + * runtime/JSObject.h: + (JSObject): + * runtime/JSSegmentedVariableObject.h: + (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject): + * runtime/JSStaticScopeObject.cpp: + (JSC): + (JSC::JSStaticScopeObject::visitChildren): NULL check our register store + because finishCreation allocates an object now, so we may get marked + before we've assigned to our register store. + + * runtime/JSStaticScopeObject.h: + (JSC::JSStaticScopeObject::finishCreation): + (JSC::JSStaticScopeObject::JSStaticScopeObject): + (JSStaticScopeObject): No more destructor for this object, either, since + it no longer embeds a hash table. + + * runtime/JSSymbolTableObject.cpp: + (JSC::JSSymbolTableObject::visitChildren): + (JSC::JSSymbolTableObject::deleteProperty): + (JSC::JSSymbolTableObject::getOwnPropertyNames): + * runtime/JSSymbolTableObject.h: + (JSC::JSSymbolTableObject::symbolTable): + (JSSymbolTableObject): + (JSC::JSSymbolTableObject::JSSymbolTableObject): + (JSC::JSSymbolTableObject::finishCreation): + (JSC::symbolTableGet): + (JSC::symbolTablePut): + (JSC::symbolTablePutWithAttributes): SymbolTableObject allocates a symbol + table automatically if one isn't provided. (Activations provide their + own, which they get from compiled code.) + + * runtime/JSVariableObject.cpp: + (JSC): + * runtime/JSVariableObject.h: + (JSC::JSVariableObject::registerAt): + (JSC::JSVariableObject::addressOfRegisters): + (JSVariableObject): + (JSC::JSVariableObject::JSVariableObject): + (JSC::JSVariableObject::finishCreation): Removed a bunch of obsolete code. + Activations manage their registers directly now. + + * runtime/StorageBarrier.h: + (StorageBarrier): + (JSC::StorageBarrier::operator!): + + * runtime/SymbolTable.cpp: + (JSC): + (JSC::SharedSymbolTable::destroy): + * runtime/SymbolTable.h: + (JSC::SharedSymbolTable::create): + (SharedSymbolTable): + (JSC::SharedSymbolTable::createStructure): + (JSC::SharedSymbolTable::SharedSymbolTable): Boilerplat code to + make shared symbol table GC-allocated. + +2012-08-25 Filip Pizlo <fpizlo@apple.com> + + op_call should have ArrayProfiling for the benefit of array intrinsics + https://bugs.webkit.org/show_bug.cgi?id=95014 + + Reviewed by Sam Weinig. + + This is a performance-neutral change that just adds the profiling but does not + use it, yet. If in the future we wanted to make this kind of profiling cheaper + we could move it into specialized thunks for the relevant array intrinsics, but + I figure that if this much simpler change gives us what we need without any + discernable performance penalty then that's for the best. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitCall): + * jit/JITCall.cpp: + (JSC::JIT::compileOpCall): + * jit/JITCall32_64.cpp: + (JSC::JIT::compileOpCall): + * llint/LowLevelInterpreter.asm: + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-08-25 Filip Pizlo <fpizlo@apple.com> + + The redundant phi elimination phase is not used and should be removed + https://bugs.webkit.org/show_bug.cgi?id=95006 + + Reviewed by Dan Bernstein. + + Just removing dead code. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * dfg/DFGDriver.cpp: + * dfg/DFGRedundantPhiEliminationPhase.cpp: Removed. + * dfg/DFGRedundantPhiEliminationPhase.h: Removed. + +2012-08-24 Benjamin Poulain <bpoulain@apple.com> + + Unify Number to StringImpl conversion + https://bugs.webkit.org/show_bug.cgi?id=94879 + + Reviewed by Geoffrey Garen. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * runtime/UString.cpp: + * runtime/UString.h: + (JSC::UString::number): + Update UString to directly use the common NumberToString implementation. + +2012-08-24 Oliver Hunt <oliver@apple.com> + + Always null check cells before marking + https://bugs.webkit.org/show_bug.cgi?id=94968 + + Reviewed by Geoffrey Garen. + + Originally we tried to minimise null checks by only null checking values + that we knew could be null, however given that we can't ever guarantee + when a GC will happen, we're better off just always assuming that a null + check will be necessary. This results in a much less fragile code base + as we can add GC allocations to object initialisers without having to + subsequently worry about whether the object we are initialising will need + to add a bunch of null checks in its visitChildren implementation. + + * heap/MarkStack.cpp: + (JSC::MarkStack::internalAppend): + * heap/MarkStackInlineMethods.h: + (JSC::MarkStack::append): + (JSC::MarkStack::appendUnbarrieredPointer): + * runtime/Structure.h: + (JSC::MarkStack::internalAppend): + +2012-08-23 Oliver Hunt <oliver@apple.com> + + Autogenerate Opcode definitions + https://bugs.webkit.org/show_bug.cgi?id=94840 + + Reviewed by Gavin Barraclough. + + Start the process of autogenerating the code emission for the bytecode. + We'll just start with automatic generation of the list of Opcodes as that + requires the actual definition of the opcodes, and the logic for parsing + them. + + Due to some rather annoying dependency cycles, this initial version has + the OpcodeDefinitions.h file checked into the tree, although with some + work I hope to be able to fix that. + + * DerivedSources.make: + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/Opcode.h: + Include OpcodeDefinitions.h as our definitive source of info + about the opcodes. + * bytecode/OpcodeDefinitions.h: Added. + Autogenerated file + * bytecode/opcodes: Added. + The new opcode definition file + * opcode_definition_generator.py: Added. + (generateOpcodeDefinition): + (generate): + Module that generates the content for OpcodeDefinitions.h + * opcode_generator.py: Added. + (printUsage): + (main): + Driver script + * opcode_parser.py: Added. + Simple parser for the opcode definitions. + +2011-08-23 Geoffrey Garen <ggaren@apple.com> + + Unreviewed, rolling out r126505. + http://trac.webkit.org/changeset/126505 + https://bugs.webkit.org/show_bug.cgi?id=94840 + + Caused testapi to crash on launch + + * DerivedSources.make: + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecode/OpcodeDefinitions.h: Removed. + * bytecode/opcodes: Removed. + * opcode_definition_generator.py: Removed. + * opcode_generator.py: Removed. + * opcode_parser.py: Removed. + +2012-08-23 Oliver Hunt <oliver@apple.com> + + Autogenerate Opcode definitions + https://bugs.webkit.org/show_bug.cgi?id=94840 + + Reviewed by Gavin Barraclough. + + Start the process of autogenerating the code emission for the bytecode. + We'll just start with automatic generation of the list of Opcodes as that + requires the actual definition of the opcodes, and the logic for parsing + them. + + Due to some rather annoying dependency cycles, this initial version has + the OpcodeDefinitions.h file checked into the tree, although with some + work I hope to be able to fix that. + + * DerivedSources.make: + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/Opcode.h: + Include OpcodeDefinitions.h as our definitive source of info + about the opcodes. + * bytecode/OpcodeDefinitions.h: Added. + Autogenerated file + * bytecode/opcodes: Added. + The new opcode definition file + * opcode_definition_generator.py: Added. + (generateOpcodeDefinition): + (generate): + Module that generates the content for OpcodeDefinitions.h + * opcode_generator.py: Added. + (printUsage): + (main): + Driver script + * opcode_parser.py: Added. + Simple parser for the opcode definitions. + +2012-08-23 Mark Hahnenberg <mhahnenberg@apple.com> + + Change behavior of MasqueradesAsUndefined to better accommodate DFG changes + https://bugs.webkit.org/show_bug.cgi?id=93884 + + Reviewed by Filip Pizlo. + + With some upcoming changes to the DFG to remove uses of ClassInfo, we will be changing the behavior of + MasqueradesAsUndefined. In order to make this change consistent across all of our execution engines, + we will make this change to MasqueradesAsUndefined as a separate patch. After this patch, MasqueradesAsUndefined + objects will only masquerade as undefined in their original context (i.e. their original JSGlobalObject). + For example, if an object that masquerades as undefined in frame A is passed to frame B, it will not + masquerade as undefined within frame B, but it will continue to masquerade in frame A. + + There are two primary changes that are taking place here. One is to thread the ExecState* through + JSValue::toBoolean and JSCell::toBoolean so that JSCell::toBoolean can check the object's + JSGlobalObject to compare it to the lexical JSGlobalObject of the currently running code. If the two + are distinct, then the object cannot MasqueradeAsUndefined. + + The other change is to perform this comparison of JSGlobalObjects everywhere where the MasqueradesAsUndefined + flag in the Structure is checked. For C++ code, this check has been factored into its own function in + Structure::masqueradesAsUndefined. We only perform this check in the DFG if the current JSGlobalObject has + had a MasqueradesAsUndefined object allocated within its context. This conditional compilation is managed + through the use of a WatchpointSet in each JSGlobalObject and alternate create() functions for JS DOM wrappers + that are MasqueradesAsUndefined. + + * API/JSValueRef.cpp: + (JSValueToBoolean): + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * bytecode/Watchpoint.h: + (WatchpointSet): + * debugger/DebuggerCallFrame.h: + (JSC::DebuggerCallFrame::callFrame): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::run): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): + (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): + (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): + (JSC::DFG::SpeculativeJIT::compile): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_is_undefined): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_eq_null): + (JSC::JIT::emit_op_neq_null): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_is_undefined): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_eq_null): + (JSC::JIT::emit_op_neq_null): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncFilter): + (JSC::arrayProtoFuncEvery): + (JSC::arrayProtoFuncSome): + * runtime/BooleanConstructor.cpp: + (JSC::constructBoolean): + (JSC::callBooleanConstructor): + * runtime/JSCell.h: + (JSCell): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::JSGlobalObject): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::masqueradesAsUndefinedWatchpoint): + * runtime/JSString.h: + (JSC::JSCell::toBoolean): + (JSC::JSValue::toBoolean): + * runtime/JSValue.h: + * runtime/ObjectConstructor.cpp: + (JSC::toPropertyDescriptor): + * runtime/Operations.cpp: + (JSC::jsTypeStringForValue): + (JSC::jsIsObjectType): + * runtime/Operations.h: + (JSC): + (JSC::JSValue::equalSlowCaseInline): + * runtime/RegExpConstructor.cpp: + (JSC::setRegExpConstructorMultiline): + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncToString): + * runtime/Structure.h: + (Structure): + (JSC::Structure::globalObjectOffset): + (JSC::Structure::masqueradesAsUndefined): + (JSC): + +2012-08-23 Mark Rowe <mrowe@apple.com> + + Make JavaScriptCore build with the latest version of clang. + + Reviewed by Dan Bernstein. + + * heap/MachineStackMarker.cpp: + (JSC::MachineThreads::MachineThreads): The m_heap member is only used within + assertions, so guard its initialization with !ASSERT_DISABLED. + * heap/MachineStackMarker.h: + (MachineThreads): Ditto for its declaration. + * jit/JITStubCall.h: + (JSC::JITStubCall::JITStubCall): The m_returnType member is only used within + assertions or if we're using JSVALUE32_64, so guard its uses with the appropriate + #if. + (JITStubCall): Ditto. + +2012-08-23 Christophe Dumez <christophe.dumez@intel.com> + + Serialization of JavaScript values does not appear to respect new HTML5 Structured Clone semantics + https://bugs.webkit.org/show_bug.cgi?id=65292 + + Reviewed by Oliver Hunt. + + Add function to construct a StringObject from a JSValue. + Similar functions already exist for NumberObject and + BooleanObject for example. + + Export several symbols so address linking errors in + WebCore. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * runtime/BooleanObject.h: + (BooleanObject): + * runtime/NumberObject.h: + (NumberObject): + (JSC): + * runtime/StringObject.cpp: + (JSC::constructString): + (JSC): + * runtime/StringObject.h: + (JSC): + +2012-08-22 Filip Pizlo <fpizlo@apple.com> + + Array accesses should remember what kind of array they are predicted to access + https://bugs.webkit.org/show_bug.cgi?id=94448 + + Reviewed by Gavin Barraclough. + + Introduced the notion of DFG::Array::Mode, stored in node.arrayMode(), which allows nodes + to remember how they decided to access arrays. This permits the bytecode parser to "lock in" + the mode of access if it has profiling at its disposal, and it also allows the prediction + propagator to do a fixup of the array mode later in the optimization fixpoint. + + This patch adds a healthy amount of new capability (specifically the ability of the parser + to lock in an array mode regardless of type predictions) and it also blows away a lot of + messy code. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + * dfg/DFGArrayMode.cpp: Added. + (DFG): + (JSC::DFG::fromObserved): + (JSC::DFG::refineArrayMode): + (JSC::DFG::modeAlreadyChecked): + (JSC::DFG::modeToString): + * dfg/DFGArrayMode.h: Added. + (DFG): + (JSC::DFG::canCSEStorage): + (JSC::DFG::modeForPut): + (JSC::DFG::modesCompatibleForStorageLoad): + (JSC::DFG::modeSupportsLength): + * dfg/DFGByteCodeParser.cpp: + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::getArrayModeWithoutOSRExit): + (JSC::DFG::ByteCodeParser::getArrayMode): + (JSC::DFG::ByteCodeParser::handleIntrinsic): + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getByValLoadElimination): + (JSC::DFG::CSEPhase::checkStructureLoadElimination): + (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): + (JSC::DFG::CSEPhase::getByOffsetLoadElimination): + (JSC::DFG::CSEPhase::putByOffsetStoreElimination): + (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::dump): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::byValIsPure): + (JSC::DFG::Graph::clobbersWorld): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasArrayMode): + (Node): + (JSC::DFG::Node::arrayMode): + (JSC::DFG::Node::setArrayMode): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::typedArrayDescriptor): + (DFG): + (JSC::DFG::SpeculativeJIT::speculateArray): + (JSC::DFG::SpeculativeJIT::compileGetByValOnString): + (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray): + (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): + (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray): + (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray): + (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): + (JSC::DFG::SpeculativeJIT::compileGetArrayLength): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-08-22 Geoffrey Garen <ggaren@apple.com> + + ThreadRestrictionVerifier should be opt-in, not opt-out + https://bugs.webkit.org/show_bug.cgi?id=94761 + + Reviewed by Mark Hahnenberg. + + Removed explicit calls to disable the verifier, since it's off by default now. + + * parser/SourceProvider.h: + (JSC::SourceProvider::SourceProvider): + (SourceProvider): + * runtime/SymbolTable.h: + (JSC::SharedSymbolTable::SharedSymbolTable): + +2012-08-22 Mark Hahnenberg <mhahnenberg@apple.com> + + Separate MarkStackThreadSharedData from MarkStack + https://bugs.webkit.org/show_bug.cgi?id=94294 + + Reviewed by Filip Pizlo. + + MarkStackThreadSharedData is soon going to have data to allow for a parallel copying + mode too, so to separate our concerns we should split it out into its own set of files + and rename it to GCThreadSharedData. For now this is purely a cosmetic refactoring. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * heap/GCThreadSharedData.cpp: Added. + (JSC): + (JSC::GCThreadSharedData::resetChildren): + (JSC::GCThreadSharedData::childVisitCount): + (JSC::GCThreadSharedData::markingThreadMain): + (JSC::GCThreadSharedData::markingThreadStartFunc): + (JSC::GCThreadSharedData::GCThreadSharedData): + (JSC::GCThreadSharedData::~GCThreadSharedData): + (JSC::GCThreadSharedData::reset): + * heap/GCThreadSharedData.h: Added. + (JSC): + (GCThreadSharedData): + * heap/Heap.h: + (Heap): + * heap/ListableHandler.h: + (ListableHandler): + * heap/MarkStack.cpp: + (JSC::MarkStack::MarkStack): + (JSC::MarkStack::~MarkStack): + * heap/MarkStack.h: + (JSC): + (MarkStack): + (JSC::MarkStack::sharedData): + * heap/MarkStackInlineMethods.h: Added. + (JSC): + (JSC::MarkStack::append): + (JSC::MarkStack::appendUnbarrieredPointer): + (JSC::MarkStack::appendUnbarrieredValue): + (JSC::MarkStack::internalAppend): + (JSC::MarkStack::addWeakReferenceHarvester): + (JSC::MarkStack::addUnconditionalFinalizer): + (JSC::MarkStack::addOpaqueRoot): + (JSC::MarkStack::containsOpaqueRoot): + (JSC::MarkStack::opaqueRootCount): + * heap/SlotVisitor.h: + (JSC): + (SlotVisitor): + (JSC::SlotVisitor::SlotVisitor): + +2012-08-22 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + Fix JSC build when DFG-JIT is disabled + https://bugs.webkit.org/show_bug.cgi?id=94694 + + Reviewed by Csaba Osztrogonác. + + Adding an appropriate guard for fixing the build. + + * bytecode/ResolveGlobalStatus.cpp: + (JSC): + +2012-08-21 Mark Lam <mark.lam@apple.com> + + Introducing the VMInspector for VM debugging use. + https://bugs.webkit.org/show_bug.cgi?id=94613. + + Reviewed by Filip Pizlo. + + Adding some utility functions for debugging the VM. This code is + presently #ifdef'd out by default. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * interpreter/CallFrame.h: + (ExecState): + * interpreter/VMInspector.cpp: Added. + (JSC): + (JSC::VMInspector::getTypeName): + (JSC::VMInspector::dumpFrame0): + (JSC::VMInspector::dumpFrame): + (JSC::VMInspector::countFrames): + * interpreter/VMInspector.h: Added. + (JSC): + (VMInspector): + +2012-08-21 Filip Pizlo <fpizlo@apple.com> + + A patchable GetById right after a watchpoint should have the appropriate nop padding + https://bugs.webkit.org/show_bug.cgi?id=94635 + + Reviewed by Mark Hahnenberg. + + * assembler/AbstractMacroAssembler.h: + (JSC::AbstractMacroAssembler::padBeforePatch): + (AbstractMacroAssembler): + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::load32WithCompactAddressOffsetPatch): + (JSC::MacroAssemblerARMv7::moveWithPatch): + (JSC::MacroAssemblerARMv7::patchableJump): + * assembler/MacroAssemblerX86.h: + (JSC::MacroAssemblerX86::moveWithPatch): + (JSC::MacroAssemblerX86::branchPtrWithPatch): + (JSC::MacroAssemblerX86::storePtrWithPatch): + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::load32WithAddressOffsetPatch): + (JSC::MacroAssemblerX86Common::load32WithCompactAddressOffsetPatch): + (JSC::MacroAssemblerX86Common::loadCompactWithAddressOffsetPatch): + (JSC::MacroAssemblerX86Common::store32WithAddressOffsetPatch): + * assembler/MacroAssemblerX86_64.h: + (JSC::MacroAssemblerX86_64::loadPtrWithAddressOffsetPatch): + (JSC::MacroAssemblerX86_64::loadPtrWithCompactAddressOffsetPatch): + (JSC::MacroAssemblerX86_64::storePtrWithAddressOffsetPatch): + (JSC::MacroAssemblerX86_64::moveWithPatch): + * jit/JumpReplacementWatchpoint.cpp: + (JSC::JumpReplacementWatchpoint::fireInternal): + +2012-08-20 Mark Lam <mark.lam@apple.com> + + Fix broken non-JIT build. + https://bugs.webkit.org/show_bug.cgi?id=94564. + + Reviewed by Filip Pizlo. + + Added some UNUSED_PARAM() macros to make the compiler happy. + + * runtime/Executable.cpp: + (JSC::EvalExecutable::compileInternal): + (JSC::ProgramExecutable::compileInternal): + (JSC::FunctionExecutable::compileForCallInternal): + (JSC::FunctionExecutable::compileForConstructInternal): + +2012-08-20 Mark Lam <mark.lam@apple.com> + + Fixed erroneous line number for LLint frame when throwing exceptions. + https://bugs.webkit.org/show_bug.cgi?id=94051. + + Reviewed by Filip Pizlo. + + For LLInt frames, before throwing an exception, adjust the PC from the + return PC back to the call PC if we are indeed at a call site. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::adjustPCIfAtCallSite): + (JSC): + (JSC::CodeBlock::bytecodeOffset): + * bytecode/CodeBlock.h: + (CodeBlock): + * llint/LLIntExceptions.cpp: + (JSC::LLInt::fixupPCforExceptionIfNeeded): + (LLInt): + (JSC::LLInt::interpreterThrowInCaller): + (JSC::LLInt::returnToThrow): + (JSC::LLInt::callToThrow): + +2012-08-20 Filip Pizlo <fpizlo@apple.com> + + fast/js/dfg-peephole-compare-final-object-to-final-object-or-other-when-both-proven-final-object.html on 32-bit + https://bugs.webkit.org/show_bug.cgi?id=94538 + + Reviewed by Mark Hahnenberg. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): + +2012-08-20 Filip Pizlo <fpizlo@apple.com> + + fast/js/dfg-compare-final-object-to-final-object-or-other-when-both-proven-final-object.html crashes on 32-bit + https://bugs.webkit.org/show_bug.cgi?id=94026 + + Reviewed by Mark Hahnenberg. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): + +2012-08-19 Filip Pizlo <fpizlo@apple.com> + + The relationship between abstract values and structure transition watchpoints should be rationalized + https://bugs.webkit.org/show_bug.cgi?id=94205 + + Reviewed by Geoffrey Garen. + + This patch does a number of things related to the handling of the abstract values + arrising from values with structures known to be watchpointable: + + - This rationalizes the relationship between the structure that we know an object + to have *right now* based on having executed a check against that structure, and + the structure that we know the object could have *in the future* based on a type + check executed in the past over a structure that was watchpointable. + + - We use the above to assert that structure transition watchpoints are being used + soundly. + + - We use the above to strength reduce CheckStructure into StructureTransitionWatchpoint + whenever possible. + + - This rationalizes the handling of CFA over constants that appeared in the bytecode. + If at compile-time the constant has a watchpointable structure, then we can prove + what structures it may have in the future. The analysis uses this to both assert + that structure transition watchpoints are being used correctly, and to find + opportunities for using them more aggressively. + + The net effect of all of these changes is that OSR entry should work more smoothly. + It may also be a slight win due to strength reductions, though most of those strength + reductions would have already been done by the parser and the structure check hoister. + + * GNUmakefile.list.am: + * JavaScriptCore.xcodeproj/project.pbxproj: + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::beginBasicBlock): + (JSC::DFG::AbstractState::execute): + * dfg/DFGAbstractValue.h: + (DFG): + (JSC::DFG::AbstractValue::clear): + (JSC::DFG::AbstractValue::isClear): + (JSC::DFG::AbstractValue::makeTop): + (JSC::DFG::AbstractValue::clobberStructures): + (JSC::DFG::AbstractValue::isTop): + (JSC::DFG::AbstractValue::setFuturePossibleStructure): + (AbstractValue): + (JSC::DFG::AbstractValue::filterFuturePossibleStructure): + (JSC::DFG::AbstractValue::setMostSpecific): + (JSC::DFG::AbstractValue::set): + (JSC::DFG::AbstractValue::operator==): + (JSC::DFG::AbstractValue::merge): + (JSC::DFG::AbstractValue::filter): + (JSC::DFG::AbstractValue::filterValueByType): + (JSC::DFG::AbstractValue::validateType): + (JSC::DFG::AbstractValue::validate): + (JSC::DFG::AbstractValue::checkConsistency): + (JSC::DFG::AbstractValue::dump): + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::checkStructureLoadElimination): + (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::foldConstants): + * dfg/DFGNode.h: + (JSC::DFG::Node::convertToStructureTransitionWatchpoint): + (Node): + (JSC::DFG::Node::hasStructure): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOSREntry.cpp: + (JSC::DFG::prepareOSREntry): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::convertLastOSRExitToForward): + (JSC::DFG::SpeculativeJIT::forwardSpeculationWatchpoint): + (DFG): + (JSC::DFG::SpeculativeJIT::speculationWatchpointWithConditionalDirection): + (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): + (JSC::DFG::SpeculativeJIT::speculateArray): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGStructureAbstractValue.h: Added. + (DFG): + (StructureAbstractValue): + (JSC::DFG::StructureAbstractValue::StructureAbstractValue): + (JSC::DFG::StructureAbstractValue::clear): + (JSC::DFG::StructureAbstractValue::makeTop): + (JSC::DFG::StructureAbstractValue::top): + (JSC::DFG::StructureAbstractValue::add): + (JSC::DFG::StructureAbstractValue::addAll): + (JSC::DFG::StructureAbstractValue::contains): + (JSC::DFG::StructureAbstractValue::isSubsetOf): + (JSC::DFG::StructureAbstractValue::doesNotContainAnyOtherThan): + (JSC::DFG::StructureAbstractValue::isSupersetOf): + (JSC::DFG::StructureAbstractValue::filter): + (JSC::DFG::StructureAbstractValue::isClear): + (JSC::DFG::StructureAbstractValue::isTop): + (JSC::DFG::StructureAbstractValue::isClearOrTop): + (JSC::DFG::StructureAbstractValue::isNeitherClearNorTop): + (JSC::DFG::StructureAbstractValue::size): + (JSC::DFG::StructureAbstractValue::at): + (JSC::DFG::StructureAbstractValue::operator[]): + (JSC::DFG::StructureAbstractValue::last): + (JSC::DFG::StructureAbstractValue::speculationFromStructures): + (JSC::DFG::StructureAbstractValue::hasSingleton): + (JSC::DFG::StructureAbstractValue::singleton): + (JSC::DFG::StructureAbstractValue::operator==): + (JSC::DFG::StructureAbstractValue::dump): + (JSC::DFG::StructureAbstractValue::topValue): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-08-17 Filip Pizlo <fpizlo@apple.com> + + The current state of the call frame should be taken into account in the DFG for both predictions and proofs + https://bugs.webkit.org/show_bug.cgi?id=94412 + + Reviewed by Geoffrey Garen. + + This ensures that no matter how smart the DFG gets, it'll always know through + which entrypoint OSR will try to enter, and with which values it will attempt + to do so. For prologue OSR, this has no effect other than adding the current + arguments to the argument predictions. For loop OSR, this makes our treatment + of the loop slightly more conservative - just conservative enough to ensure + that OSR succeeds. + + * bytecode/CodeBlock.cpp: + (JSC::ProgramCodeBlock::compileOptimized): + (JSC::EvalCodeBlock::compileOptimized): + (JSC::FunctionCodeBlock::compileOptimized): + * bytecode/CodeBlock.h: + (CodeBlock): + (ProgramCodeBlock): + (EvalCodeBlock): + (FunctionCodeBlock): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::initialize): + * dfg/DFGAbstractValue.h: + (JSC::DFG::AbstractValue::setMostSpecific): + (AbstractValue): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::fixVariableAccessPredictions): + (JSC::DFG::ByteCodeParser::parse): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + (JSC::DFG::tryCompile): + (JSC::DFG::tryCompileFunction): + * dfg/DFGDriver.h: + (DFG): + (JSC::DFG::tryCompile): + (JSC::DFG::tryCompileFunction): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::Graph): + (Graph): + * jit/JITDriver.h: + (JSC::jitCompileIfAppropriate): + (JSC::jitCompileFunctionIfAppropriate): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/Executable.cpp: + (JSC::EvalExecutable::compileOptimized): + (JSC::EvalExecutable::compileInternal): + (JSC::ProgramExecutable::compileOptimized): + (JSC::ProgramExecutable::compileInternal): + (JSC::FunctionExecutable::compileOptimizedForCall): + (JSC::FunctionExecutable::compileOptimizedForConstruct): + (JSC::FunctionExecutable::compileForCallInternal): + (JSC::FunctionExecutable::compileForConstructInternal): + * runtime/Executable.h: + (EvalExecutable): + (ProgramExecutable): + (FunctionExecutable): + (JSC::FunctionExecutable::compileOptimizedFor): + * runtime/ExecutionHarness.h: + (JSC::prepareForExecution): + (JSC::prepareFunctionForExecution): + +2012-08-17 Filip Pizlo <fpizlo@apple.com> + + DFG CSE should be more honest about when it changed the IR + https://bugs.webkit.org/show_bug.cgi?id=94408 + + Reviewed by Geoffrey Garen. + + The CSE phase now always returns true if it changed the IR. + + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::setReplacement): + (JSC::DFG::CSEPhase::eliminate): + (JSC::DFG::CSEPhase::performNodeCSE): + +2012-08-17 Filip Pizlo <fpizlo@apple.com> + + DFG is still too pessimistic about what constitutes a side-effect on array accesses + https://bugs.webkit.org/show_bug.cgi?id=94309 + + Reviewed by Geoffrey Garen. + + This change means that even if structure transition watchpoints are not used for + hoisting of clobbered structure checks, we still retain good performance on the + benchmarks we care about. That's important, since butterflies will likely make + most array structures not watchpointable. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-08-17 Milian Wolff <milian.wolff@kdab.com> + + [Qt] QNX build fails due to ctype usage in system headers + https://bugs.webkit.org/show_bug.cgi?id=93849 + + Reviewed by Simon Hausmann. + + Move the check for whether DisallowCType should be active or not + to the DisallowCType.h header. This way, we can update the list + of platforms or OSes which do not work with this header in a + central place. All users can now safely include the header + and do not need to place custom guards around it. + + * config.h: + +2012-08-16 Simon Hausmann <simon.hausmann@nokia.com> + + [Qt] Replace use of internal Weak smart pointer with JSWeakObjectMap + https://bugs.webkit.org/show_bug.cgi?id=93872 + + Reviewed by Kenneth Rohde Christiansen. + + * Target.pri: Add missing JSWeakObjectMap file to build. + +2012-08-16 Filip Pizlo <fpizlo@apple.com> + + Structure check hoisting should be less expensive + https://bugs.webkit.org/show_bug.cgi?id=94201 + + Reviewed by Mark Hahnenberg. + + This appears like a broad win on short-running programs. + + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::compareAndSwap): + (Graph): + (JSC::DFG::Graph::substitute): + (JSC::DFG::Graph::substituteGetLocal): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-08-16 Filip Pizlo <fpizlo@apple.com> + + All op_resolve_global instructions should end up in the list of global resolve instructions + https://bugs.webkit.org/show_bug.cgi?id=94247 + <rdar://problem/12103500> + + Reviewed by Mark Hahnenberg. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitResolveWithBase): + +2012-08-15 Bruno de Oliveira Abinader <bruno.abinader@basyskom.com> + + [css3-text] Add CSS3 Text decoration compile flag + https://bugs.webkit.org/show_bug.cgi?id=93863 + + Reviewed by Julien Chaffraix. + + This patch handles the compile flag implementation, which will come disabled by + default, thus not exposing the CSS3 text decoration features to the web, unless + when explicitly enabling it with "--css3-text-decoration" build parameter. + + * Configurations/FeatureDefines.xcconfig: + +2012-08-15 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r125687. + http://trac.webkit.org/changeset/125687 + https://bugs.webkit.org/show_bug.cgi?id=94147 + + It broke the whole world (Requested by Ossy_night on #webkit). + + * API/JSValueRef.cpp: + (JSValueToBoolean): + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * bytecode/Watchpoint.h: + (WatchpointSet): + * debugger/DebuggerCallFrame.h: + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::run): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): + (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): + (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): + (JSC::DFG::SpeculativeJIT::compile): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_is_undefined): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_eq_null): + (JSC::JIT::emit_op_neq_null): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_is_undefined): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_eq_null): + (JSC::JIT::emit_op_neq_null): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncFilter): + (JSC::arrayProtoFuncEvery): + (JSC::arrayProtoFuncSome): + * runtime/BooleanConstructor.cpp: + (JSC::constructBoolean): + (JSC::callBooleanConstructor): + * runtime/JSCell.h: + (JSCell): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::JSGlobalObject): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + * runtime/JSString.h: + (JSC::JSCell::toBoolean): + (JSC::JSValue::toBoolean): + * runtime/JSValue.h: + * runtime/ObjectConstructor.cpp: + (JSC::toPropertyDescriptor): + * runtime/Operations.cpp: + (JSC::jsTypeStringForValue): + (JSC::jsIsObjectType): + * runtime/Operations.h: + (JSC): + (JSC::JSValue::equalSlowCaseInline): + * runtime/RegExpConstructor.cpp: + (JSC::setRegExpConstructorMultiline): + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncToString): + * runtime/Structure.h: + +2012-08-15 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + Buildfix after r125541 + https://bugs.webkit.org/show_bug.cgi?id=94097 + + Reviewed by Filip Pizlo. + + r125541 has broken the traditional ARM port build of JSC. + + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::neg32): + (JSC::MacroAssemblerARM::xor32): + +2012-08-14 Mark Hahnenberg <mhahnenberg@apple.com> + + Change behavior of MasqueradesAsUndefined to better accommodate DFG changes + https://bugs.webkit.org/show_bug.cgi?id=93884 + + Reviewed by Geoffrey Garen. + + With some upcoming changes to the DFG to remove uses of ClassInfo, we will be changing the behavior of + MasqueradesAsUndefined. In order to make this change consistent across all of our execution engines, + we will make this change to MasqueradesAsUndefined as a separate patch. After this patch, MasqueradesAsUndefined + objects will only masquerade as undefined in their original context (i.e. their original JSGlobalObject). + For example, if an object that masquerades as undefined in frame A is passed to frame B, it will not + masquerade as undefined within frame B, but it will continue to masquerade in frame A. + + There are two primary changes that are taking place here. One is to thread the ExecState* through + JSValue::toBoolean and JSCell::toBoolean so that JSCell::toBoolean can check the object's + JSGlobalObject to compare it to the lexical JSGlobalObject of the currently running code. If the two + are distinct, then the object cannot MasqueradeAsUndefined. + + The other change is to perform this comparison of JSGlobalObjects everywhere where the MasqueradesAsUndefined + flag in the Structure is checked. For C++ code, this check has been factored into its own function in + Structure::masqueradesAsUndefined. We only perform this check in the DFG if the current JSGlobalObject has + had a MasqueradesAsUndefined object allocated within its context. This conditional compilation is managed + through the use of a WatchpointSet in each JSGlobalObject and alternate create() functions for JS DOM wrappers + that are MasqueradesAsUndefined. + + * API/JSValueRef.cpp: + (JSValueToBoolean): + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * bytecode/Watchpoint.h: + (WatchpointSet): + * debugger/DebuggerCallFrame.h: + (JSC::DebuggerCallFrame::callFrame): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::run): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): + (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull): + (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull): + (JSC::DFG::SpeculativeJIT::compile): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_is_undefined): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_eq_null): + (JSC::JIT::emit_op_neq_null): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_is_undefined): + (JSC::JIT::emit_op_jeq_null): + (JSC::JIT::emit_op_jneq_null): + (JSC::JIT::emit_op_eq_null): + (JSC::JIT::emit_op_neq_null): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncFilter): + (JSC::arrayProtoFuncEvery): + (JSC::arrayProtoFuncSome): + * runtime/BooleanConstructor.cpp: + (JSC::constructBoolean): + (JSC::callBooleanConstructor): + * runtime/JSCell.h: + (JSCell): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::JSGlobalObject): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::masqueradesAsUndefinedWatchpoint): + * runtime/JSString.h: + (JSC::JSCell::toBoolean): + (JSC::JSValue::toBoolean): + * runtime/JSValue.h: + * runtime/ObjectConstructor.cpp: + (JSC::toPropertyDescriptor): + * runtime/Operations.cpp: + (JSC::jsTypeStringForValue): + (JSC::jsIsObjectType): + * runtime/Operations.h: + (JSC): + (JSC::JSValue::equalSlowCaseInline): + * runtime/RegExpConstructor.cpp: + (JSC::setRegExpConstructorMultiline): + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncToString): + * runtime/Structure.h: + (Structure): + (JSC::Structure::globalObjectOffset): + (JSC::Structure::masqueradesAsUndefined): + (JSC): + +2012-08-14 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, build fix for !ENABLE(DFG_JIT) + + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-08-13 Filip Pizlo <fpizlo@apple.com> + + Array checks should use the structure, not the class info + https://bugs.webkit.org/show_bug.cgi?id=93150 + + Reviewed by Mark Hahnenberg. + + This changes all array checks used in array accesses (get, put, get length, + push, pop) to use the structure, not the class info. Additionally, these + checks in the LLInt and baseline JIT record the structure in an ArrayProfile, + so that the DFG can know exactly what structure to check for. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/ArrayProfile.cpp: Added. + (JSC): + (JSC::ArrayProfile::computeUpdatedPrediction): + * bytecode/ArrayProfile.h: Added. + (JSC): + (JSC::arrayModeFromStructure): + (ArrayProfile): + (JSC::ArrayProfile::ArrayProfile): + (JSC::ArrayProfile::bytecodeOffset): + (JSC::ArrayProfile::addressOfLastSeenStructure): + (JSC::ArrayProfile::observeStructure): + (JSC::ArrayProfile::expectedStructure): + (JSC::ArrayProfile::structureIsPolymorphic): + (JSC::ArrayProfile::hasDefiniteStructure): + (JSC::ArrayProfile::observedArrayModes): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + (JSC::CodeBlock::getArrayProfile): + (JSC): + (JSC::CodeBlock::getOrAddArrayProfile): + (JSC::CodeBlock::updateAllPredictionsAndCountLiveness): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::executionEntryCount): + (JSC::CodeBlock::numberOfArrayProfiles): + (JSC::CodeBlock::arrayProfiles): + (JSC::CodeBlock::addArrayProfile): + (CodeBlock): + * bytecode/Instruction.h: + (JSC): + (JSC::Instruction::Instruction): + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitGetArgumentByVal): + (JSC::BytecodeGenerator::emitGetByVal): + (JSC::BytecodeGenerator::emitPutByVal): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::initialize): + (JSC::DFG::AbstractState::execute): + * dfg/DFGAbstractValue.h: + (JSC::DFG::StructureAbstractValue::hasSingleton): + (StructureAbstractValue): + (JSC::DFG::StructureAbstractValue::singleton): + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::speculateArray): + (DFG): + (JSC::DFG::SpeculativeJIT::compile): + (JSC::DFG::SpeculativeJIT::checkArgumentTypes): + (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_by_val): + (JSC::JIT::emit_op_put_by_val): + (JSC::JIT::privateCompilePatchGetArrayLength): + * llint/LLIntOffsetsExtractor.cpp: + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/Structure.h: + (Structure): + (JSC::Structure::classInfoOffset): + +2012-08-14 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + Rename functions in the ARM port of DFG-JIT for better code readability. + https://bugs.webkit.org/show_bug.cgi?id=93609 + + Reviewed by Zoltan Herczeg. + + Rename functions in the ARM port of DFG-JIT for better code + readability, and for following the WebKit coding style + wherever it is possible. + + * assembler/ARMAssembler.cpp: + (JSC::ARMAssembler::genInt): + (JSC::ARMAssembler::getImm): + (JSC::ARMAssembler::moveImm): + (JSC::ARMAssembler::encodeComplexImm): + (JSC::ARMAssembler::dataTransfer32): + (JSC::ARMAssembler::baseIndexTransfer32): + (JSC::ARMAssembler::dataTransfer16): + (JSC::ARMAssembler::baseIndexTransfer16): + (JSC::ARMAssembler::dataTransferFloat): + (JSC::ARMAssembler::baseIndexTransferFloat): + * assembler/ARMAssembler.h: + (JSC::ARMAssembler::bitAnd): + (JSC::ARMAssembler::bitAnds): + (JSC::ARMAssembler::eor): + (JSC::ARMAssembler::eors): + (JSC::ARMAssembler::sub): + (JSC::ARMAssembler::subs): + (JSC::ARMAssembler::rsb): + (JSC::ARMAssembler::rsbs): + (JSC::ARMAssembler::add): + (JSC::ARMAssembler::adds): + (JSC::ARMAssembler::adc): + (JSC::ARMAssembler::adcs): + (JSC::ARMAssembler::sbc): + (JSC::ARMAssembler::sbcs): + (JSC::ARMAssembler::rsc): + (JSC::ARMAssembler::rscs): + (JSC::ARMAssembler::tst): + (JSC::ARMAssembler::teq): + (JSC::ARMAssembler::cmp): + (JSC::ARMAssembler::cmn): + (JSC::ARMAssembler::orr): + (JSC::ARMAssembler::orrs): + (JSC::ARMAssembler::mov): + (JSC::ARMAssembler::movw): + (JSC::ARMAssembler::movt): + (JSC::ARMAssembler::movs): + (JSC::ARMAssembler::bic): + (JSC::ARMAssembler::bics): + (JSC::ARMAssembler::mvn): + (JSC::ARMAssembler::mvns): + (JSC::ARMAssembler::mul): + (JSC::ARMAssembler::muls): + (JSC::ARMAssembler::mull): + (JSC::ARMAssembler::vmov_f64): + (JSC::ARMAssembler::vadd_f64): + (JSC::ARMAssembler::vdiv_f64): + (JSC::ARMAssembler::vsub_f64): + (JSC::ARMAssembler::vmul_f64): + (JSC::ARMAssembler::vcmp_f64): + (JSC::ARMAssembler::vsqrt_f64): + (JSC::ARMAssembler::vabs_f64): + (JSC::ARMAssembler::vneg_f64): + (JSC::ARMAssembler::ldrImmediate): + (JSC::ARMAssembler::ldrUniqueImmediate): + (JSC::ARMAssembler::dtrUp): + (JSC::ARMAssembler::dtrUpRegister): + (JSC::ARMAssembler::dtrDown): + (JSC::ARMAssembler::dtrDownRegister): + (JSC::ARMAssembler::halfDtrUp): + (JSC::ARMAssembler::halfDtrUpRegister): + (JSC::ARMAssembler::halfDtrDown): + (JSC::ARMAssembler::halfDtrDownRegister): + (JSC::ARMAssembler::doubleDtrUp): + (JSC::ARMAssembler::doubleDtrDown): + (JSC::ARMAssembler::push): + (JSC::ARMAssembler::pop): + (JSC::ARMAssembler::poke): + (JSC::ARMAssembler::peek): + (JSC::ARMAssembler::vmov_vfp64): + (JSC::ARMAssembler::vmov_arm64): + (JSC::ARMAssembler::vmov_vfp32): + (JSC::ARMAssembler::vmov_arm32): + (JSC::ARMAssembler::vcvt_f64_s32): + (JSC::ARMAssembler::vcvt_s32_f64): + (JSC::ARMAssembler::vcvt_u32_f64): + (JSC::ARMAssembler::vcvt_f64_f32): + (JSC::ARMAssembler::vcvt_f32_f64): + (JSC::ARMAssembler::clz): + (JSC::ARMAssembler::lslRegister): + (JSC::ARMAssembler::lsrRegister): + (JSC::ARMAssembler::asrRegister): + (JSC::ARMAssembler::align): + (JSC::ARMAssembler::loadBranchTarget): + (JSC::ARMAssembler::vmov): + * assembler/MacroAssemblerARM.cpp: + (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::add32): + (JSC::MacroAssemblerARM::and32): + (JSC::MacroAssemblerARM::lshift32): + (JSC::MacroAssemblerARM::mul32): + (JSC::MacroAssemblerARM::or32): + (JSC::MacroAssemblerARM::rshift32): + (JSC::MacroAssemblerARM::urshift32): + (JSC::MacroAssemblerARM::sub32): + (JSC::MacroAssemblerARM::xor32): + (JSC::MacroAssemblerARM::countLeadingZeros32): + (JSC::MacroAssemblerARM::convertibleLoadPtr): + (JSC::MacroAssemblerARM::load32WithAddressOffsetPatch): + (JSC::MacroAssemblerARM::load32WithCompactAddressOffsetPatch): + (JSC::MacroAssemblerARM::store32WithAddressOffsetPatch): + (JSC::MacroAssemblerARM::store32): + (JSC::MacroAssemblerARM::pop): + (JSC::MacroAssemblerARM::push): + (JSC::MacroAssemblerARM::move): + (JSC::MacroAssemblerARM::swap): + (JSC::MacroAssemblerARM::branch32): + (JSC::MacroAssemblerARM::branchTest32): + (JSC::MacroAssemblerARM::mull32): + (JSC::MacroAssemblerARM::branchSub32): + (JSC::MacroAssemblerARM::compare32): + (JSC::MacroAssemblerARM::test32): + (JSC::MacroAssemblerARM::load32): + (JSC::MacroAssemblerARM::relativeTableJump): + (JSC::MacroAssemblerARM::moveWithPatch): + (JSC::MacroAssemblerARM::loadDouble): + (JSC::MacroAssemblerARM::moveDouble): + (JSC::MacroAssemblerARM::addDouble): + (JSC::MacroAssemblerARM::divDouble): + (JSC::MacroAssemblerARM::subDouble): + (JSC::MacroAssemblerARM::mulDouble): + (JSC::MacroAssemblerARM::sqrtDouble): + (JSC::MacroAssemblerARM::absDouble): + (JSC::MacroAssemblerARM::negateDouble): + (JSC::MacroAssemblerARM::convertInt32ToDouble): + (JSC::MacroAssemblerARM::convertFloatToDouble): + (JSC::MacroAssemblerARM::convertDoubleToFloat): + (JSC::MacroAssemblerARM::branchDouble): + (JSC::MacroAssemblerARM::branchTruncateDoubleToInt32): + (JSC::MacroAssemblerARM::branchTruncateDoubleToUint32): + (JSC::MacroAssemblerARM::truncateDoubleToInt32): + (JSC::MacroAssemblerARM::truncateDoubleToUint32): + (JSC::MacroAssemblerARM::branchConvertDoubleToInt32): + (JSC::MacroAssemblerARM::branchDoubleNonZero): + (JSC::MacroAssemblerARM::branchDoubleZeroOrNaN): + +2012-08-13 Simon Hausmann <simon.hausmann@nokia.com> + + Unreviewed, rolling out r125444. + http://trac.webkit.org/changeset/125444 + https://bugs.webkit.org/show_bug.cgi?id=93872 + + Broke some tests + + * Target.pri: + +2012-08-13 Simon Hausmann <simon.hausmann@nokia.com> + + [Qt] Replace use of internal Weak smart pointer with JSWeakObjectMap + https://bugs.webkit.org/show_bug.cgi?id=93872 + + Reviewed by Kenneth Rohde Christiansen. + + * Target.pri: Add missing JSWeakObjectMap file to build. + +2012-08-13 Raphael Kubo da Costa <rakuco@webkit.org> + + [CMake] Remove glib-related Find modules and write single new one instead. + https://bugs.webkit.org/show_bug.cgi?id=93786 + + Reviewed by Rob Buis. + + * shell/PlatformEfl.cmake: Use GLIB_* instead of Glib_*. + +2012-08-12 Allan Sandfeld Jensen <allan.jensen@nokia.com> + + Doesn't build with ENABLE_JIT=0 + https://bugs.webkit.org/show_bug.cgi?id=85042 + + Reviewed by Eric Seidel. + + Include headers without which CallFrame.h does not build, and + fix gcc warning about comparing unsigned int with 0. + + * dfg/DFGDriver.cpp: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::isOpcode): + +2012-08-10 Yong Li <yoli@rim.com> + + [BlackBerry] GCActivityCallback should always schedule GC even allocated bytes is a small number + https://bugs.webkit.org/show_bug.cgi?id=93650 + + Reviewed by Rob Buis. + + Even a small number of allocated JS objects could hold expensive resources. + + * runtime/GCActivityCallbackBlackBerry.cpp: + (JSC::DefaultGCActivityCallback::didAllocate): + +2012-08-09 Yong Li <yoli@rim.com> + + [QNX] Implement getCPUTime() for OS(QNX) + https://bugs.webkit.org/show_bug.cgi?id=93516 + + Reviewed by George Staikos. + + Implement getCPUTime() with CLOCK_THREAD_CPUTIME_ID so it will tell + exactly how long the current thread has spent without being impacted + by other things. + + * runtime/TimeoutChecker.cpp: + (JSC::getCPUTime): + +2012-08-08 Shane Stephens <shanestephens@google.com> + + Compile flag for CSS Hierarchies + https://bugs.webkit.org/show_bug.cgi?id=92433 + + Reviewed by Tony Chang. + + * Configurations/FeatureDefines.xcconfig: + +2012-08-08 Benjamin Poulain <bpoulain@apple.com> + + Use char* instead of LChar* for the public interface of String construction from literals + https://bugs.webkit.org/show_bug.cgi?id=93402 + + Reviewed by Michael Saboff. + + Update JSC' Identifier to use StringImpl::createFromLiteral with a char*. + + * runtime/Identifier.cpp: + (JSC::IdentifierASCIIStringTranslator::translate): + +2012-08-08 Patrick Gansterer <paroga@webkit.org> + + Remove ce_time.(cpp|h) from list of source files + https://bugs.webkit.org/show_bug.cgi?id=93446 + + Reviewed by Simon Hausmann. + + r125004 removed the last dependency on functions defined in ce_time.cpp. + + * Target.pri: + +2012-08-08 Patrick Gansterer <paroga@webkit.org> + + [WIN] Use GetTimeZoneInformation() for getting the timezone name + https://bugs.webkit.org/show_bug.cgi?id=91936 + + Reviewed by Ryosuke Niwa. + + The MS CRT implementation of strftime calls the same functions in the background. + Using them directly avoids the overhead of parsing the format string and removes + the dependency on strftime() for WinCE where this function does not exist. + + * runtime/DateConversion.cpp: + (JSC::formatTime): + +2012-08-07 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + Refactor magic numbers in the ARM port of DFG-JIT + https://bugs.webkit.org/show_bug.cgi?id=93348 + + Reviewed by Eric Seidel. + + Introduce new names for hard-coded magic numbers. + Refactor constant with confusing names to more descriptive ones. + + * assembler/ARMAssembler.cpp: + (JSC::ARMAssembler::patchConstantPoolLoad): + (JSC::ARMAssembler::getOp2): + (JSC::ARMAssembler::genInt): + (JSC::ARMAssembler::getImm): + (JSC::ARMAssembler::moveImm): + (JSC::ARMAssembler::encodeComplexImm): + (JSC::ARMAssembler::dataTransfer32): + (JSC::ARMAssembler::dataTransfer16): + (JSC::ARMAssembler::dataTransferFloat): + (JSC::ARMAssembler::executableCopy): + * assembler/ARMAssembler.h: + (JSC::ARMAssembler::emitInstruction): + (JSC::ARMAssembler::ands_r): + (JSC::ARMAssembler::eors_r): + (JSC::ARMAssembler::subs_r): + (JSC::ARMAssembler::rsbs_r): + (JSC::ARMAssembler::adds_r): + (JSC::ARMAssembler::adcs_r): + (JSC::ARMAssembler::sbcs_r): + (JSC::ARMAssembler::rscs_r): + (JSC::ARMAssembler::tst_r): + (JSC::ARMAssembler::teq_r): + (JSC::ARMAssembler::cmp_r): + (JSC::ARMAssembler::cmn_r): + (JSC::ARMAssembler::orrs_r): + (JSC::ARMAssembler::movs_r): + (JSC::ARMAssembler::bics_r): + (JSC::ARMAssembler::mvns_r): + (JSC::ARMAssembler::muls_r): + (JSC::ARMAssembler::ldr_imm): + (JSC::ARMAssembler::ldr_un_imm): + (JSC::ARMAssembler::dtr_u): + (JSC::ARMAssembler::dtr_ur): + (JSC::ARMAssembler::dtr_dr): + (JSC::ARMAssembler::dtrh_u): + (JSC::ARMAssembler::dtrh_ur): + (JSC::ARMAssembler::fdtr_u): + (JSC::ARMAssembler::push_r): + (JSC::ARMAssembler::pop_r): + (JSC::ARMAssembler::getLdrImmAddress): + (JSC::ARMAssembler::getLdrImmAddressOnPool): + (JSC::ARMAssembler::patchConstantPoolLoad): + (JSC::ARMAssembler::repatchCompact): + (JSC::ARMAssembler::replaceWithJump): + (JSC::ARMAssembler::replaceWithLoad): + (JSC::ARMAssembler::replaceWithAddressComputation): + (JSC::ARMAssembler::getOp2Byte): + (JSC::ARMAssembler::getOp2Half): + (JSC::ARMAssembler::getImm16Op2): + (JSC::ARMAssembler::placeConstantPoolBarrier): + (JSC::ARMAssembler::getConditionalField): + * assembler/MacroAssemblerARM.cpp: + (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::and32): + (JSC::MacroAssemblerARM::branch32): + (JSC::MacroAssemblerARM::branchTest32): + (JSC::MacroAssemblerARM::branchTruncateDoubleToInt32): + +2012-08-07 Benjamin Poulain <benjamin@webkit.org> + + Use the initialization from literal for JSC's Identifiers + https://bugs.webkit.org/show_bug.cgi?id=93193 + + Reviewed by Geoffrey Garen. + + This patches modify Identifier ot take advantage of the new initialization from literal. + + In addition to the memory savings (~600bytes per instance), this gives us a 2% speed + improvement on CommonIdentifiers on average. + + * runtime/CommonIdentifiers.cpp: + (JSC::CommonIdentifiers::CommonIdentifiers): + Null and empty strings are forbidden for literal initialization. Use the most efficient constructors + instead of a literal. + + * runtime/Identifier.cpp: + (IdentifierASCIIStringTranslator): + Rename IdentifierCStringTranslator to IdentifierASCIIStringTranslator to make the text encoding + explicit. + (JSC::IdentifierASCIIStringTranslator::hash): + (JSC::IdentifierASCIIStringTranslator::equal): + (JSC::IdentifierASCIIStringTranslator::translate): Use the fast initialization from literal. + (JSC::Identifier::add): + * runtime/Identifier.h: + (JSC::Identifier::Identifier): + +2012-08-07 Simon Hausmann <simon.hausmann@nokia.com> + + [Qt][Win] Remove pthreads linkage + + Reviewed by Csaba Osztrogonác. + + After r124823 linkage to pthreads is not needed anymore for the Windows + build. + + * JavaScriptCore.pri: + +2012-08-07 Gabor Ballabas <gaborb@inf.u-szeged.hu> + + Refactor emit*Inst functions and introduce toARMWord functions in DFG-JIT's traditional ARM port + https://bugs.webkit.org/show_bug.cgi?id=93266 + + Reviewed by Csaba Osztrogonác. + + First part of a bigger refactoring issue trying to make traditional + ARM DFG-JIT port easier to read and understand. + + + * assembler/ARMAssembler.h: + (JSC::ARMAssembler::emitInstruction): + (JSC::ARMAssembler::emitDoublePrecisionInstruction): + (JSC::ARMAssembler::emitSinglePrecisionInstruction): + (JSC::ARMAssembler::and_r): + (JSC::ARMAssembler::ands_r): + (JSC::ARMAssembler::eor_r): + (JSC::ARMAssembler::eors_r): + (JSC::ARMAssembler::sub_r): + (JSC::ARMAssembler::subs_r): + (JSC::ARMAssembler::rsb_r): + (JSC::ARMAssembler::rsbs_r): + (JSC::ARMAssembler::add_r): + (JSC::ARMAssembler::adds_r): + (JSC::ARMAssembler::adc_r): + (JSC::ARMAssembler::adcs_r): + (JSC::ARMAssembler::sbc_r): + (JSC::ARMAssembler::sbcs_r): + (JSC::ARMAssembler::rsc_r): + (JSC::ARMAssembler::rscs_r): + (JSC::ARMAssembler::tst_r): + (JSC::ARMAssembler::teq_r): + (JSC::ARMAssembler::cmp_r): + (JSC::ARMAssembler::cmn_r): + (JSC::ARMAssembler::orr_r): + (JSC::ARMAssembler::orrs_r): + (JSC::ARMAssembler::mov_r): + (JSC::ARMAssembler::movw_r): + (JSC::ARMAssembler::movt_r): + (JSC::ARMAssembler::movs_r): + (JSC::ARMAssembler::bic_r): + (JSC::ARMAssembler::bics_r): + (JSC::ARMAssembler::mvn_r): + (JSC::ARMAssembler::mvns_r): + (JSC::ARMAssembler::mul_r): + (JSC::ARMAssembler::muls_r): + (JSC::ARMAssembler::mull_r): + (JSC::ARMAssembler::vmov_f64_r): + (JSC::ARMAssembler::vadd_f64_r): + (JSC::ARMAssembler::vdiv_f64_r): + (JSC::ARMAssembler::vsub_f64_r): + (JSC::ARMAssembler::vmul_f64_r): + (JSC::ARMAssembler::vcmp_f64_r): + (JSC::ARMAssembler::vsqrt_f64_r): + (JSC::ARMAssembler::vabs_f64_r): + (JSC::ARMAssembler::vneg_f64_r): + (JSC::ARMAssembler::ldr_imm): + (JSC::ARMAssembler::ldr_un_imm): + (JSC::ARMAssembler::dtr_u): + (JSC::ARMAssembler::dtr_ur): + (JSC::ARMAssembler::dtr_d): + (JSC::ARMAssembler::dtr_dr): + (JSC::ARMAssembler::dtrh_u): + (JSC::ARMAssembler::dtrh_ur): + (JSC::ARMAssembler::dtrh_d): + (JSC::ARMAssembler::dtrh_dr): + (JSC::ARMAssembler::fdtr_u): + (JSC::ARMAssembler::fdtr_d): + (JSC::ARMAssembler::push_r): + (JSC::ARMAssembler::pop_r): + (JSC::ARMAssembler::vmov_vfp64_r): + (JSC::ARMAssembler::vmov_arm64_r): + (JSC::ARMAssembler::vmov_vfp32_r): + (JSC::ARMAssembler::vmov_arm32_r): + (JSC::ARMAssembler::vcvt_f64_s32_r): + (JSC::ARMAssembler::vcvt_s32_f64_r): + (JSC::ARMAssembler::vcvt_u32_f64_r): + (JSC::ARMAssembler::vcvt_f64_f32_r): + (JSC::ARMAssembler::vcvt_f32_f64_r): + (JSC::ARMAssembler::vmrs_apsr): + (JSC::ARMAssembler::clz_r): + (JSC::ARMAssembler::bx): + (JSC::ARMAssembler::blx): + (JSC::ARMAssembler::linkJump): + (JSC::ARMAssembler::toARMWord): + (ARMAssembler): + +2012-08-06 Patrick Gansterer <paroga@webkit.org> + + [WIN] Remove dependency on pthread from MachineStackMarker + https://bugs.webkit.org/show_bug.cgi?id=68429 + + Reviewed by Geoffrey Garen. + + Windows has no support for calling a destructor for thread specific data. + Since we need more control over creating and deleting thread specific keys + we can not simply extend WTF::ThreadSpecific with this functionality. + + All thread specific keys created via the new API get stored in a list. + After a thread function finished we iterate over this list and call + the registered destructor for every item if needed. + + * heap/MachineStackMarker.cpp: Use the new functions instead of pthread directly. + (JSC::MachineThreads::~MachineThreads): + (JSC::MachineThreads::makeUsableFromMultipleThreads): + (JSC::MachineThreads::addCurrentThread): + * heap/MachineStackMarker.h: + (MachineThreads): + +2012-08-06 Patrick Gansterer <paroga@webkit.org> + + Unify JSC date and time formating functions + https://bugs.webkit.org/show_bug.cgi?id=92282 + + Reviewed by Geoffrey Garen. + + Replace the existing functions for formating GregorianDateTime + with one single function. This removes some code duplications + in DatePrototype and is a preperation to fix encoding issues, + since we can add UChar* values to the resulting string now. + + * runtime/DateConstructor.cpp: + (JSC::callDate): + * runtime/DateConversion.cpp: + (JSC::formatDateTime): + * runtime/DateConversion.h: + (JSC): + * runtime/DatePrototype.cpp: + (JSC::formateDateInstance): + (JSC::dateProtoFuncToString): + (JSC::dateProtoFuncToUTCString): + (JSC::dateProtoFuncToDateString): + (JSC::dateProtoFuncToTimeString): + (JSC::dateProtoFuncToGMTString): + +2012-08-06 Carlos Garcia Campos <cgarcia@igalia.com> + + Unreviewed. Fix make distcheck. + + * GNUmakefile.list.am: Add missing header file. + +2012-08-05 Peter Wang <peter.wang@torchmobile.com.cn> + + Web Inspector: [JSC] implement setting breakpoints by line:column + https://bugs.webkit.org/show_bug.cgi?id=53003 + + Reviewed by Geoffrey Garen. + + Add a counter to Lexer to record the column info of each Token. Add a column parameter to + op_debug, cti_op_debug, and _llint_op_debug byte-code command. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::resolve): + (JSC::BytecodeGenerator::emitDebugHook): + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + * bytecompiler/NodesCodegen.cpp: + (JSC::ArrayNode::toArgumentList): + (JSC::ApplyFunctionCallDotNode::emitBytecode): + (JSC::ConstStatementNode::emitBytecode): + (JSC::EmptyStatementNode::emitBytecode): + (JSC::DebuggerStatementNode::emitBytecode): + (JSC::ExprStatementNode::emitBytecode): + (JSC::VarStatementNode::emitBytecode): + (JSC::IfNode::emitBytecode): + (JSC::IfElseNode::emitBytecode): + (JSC::DoWhileNode::emitBytecode): + (JSC::WhileNode::emitBytecode): + (JSC::ForNode::emitBytecode): + (JSC::ForInNode::emitBytecode): + (JSC::ContinueNode::emitBytecode): + (JSC::BreakNode::emitBytecode): + (JSC::ReturnNode::emitBytecode): + (JSC::WithNode::emitBytecode): + (JSC::SwitchNode::emitBytecode): + (JSC::LabelNode::emitBytecode): + (JSC::ThrowNode::emitBytecode): + (JSC::TryNode::emitBytecode): + (JSC::ProgramNode::emitBytecode): + (JSC::EvalNode::emitBytecode): + (JSC::FunctionBodyNode::emitBytecode): + * debugger/Debugger.h: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::unwindCallFrame): + (JSC::Interpreter::throwException): + (JSC::Interpreter::debug): + (JSC::Interpreter::privateExecute): + * interpreter/Interpreter.h: + (Interpreter): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_debug): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_debug): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter.asm: + * parser/ASTBuilder.h: + (ASTBuilder): + (JSC::ASTBuilder::createCommaExpr): + (JSC::ASTBuilder::createLogicalNot): + (JSC::ASTBuilder::createUnaryPlus): + (JSC::ASTBuilder::createVoid): + (JSC::ASTBuilder::thisExpr): + (JSC::ASTBuilder::createResolve): + (JSC::ASTBuilder::createObjectLiteral): + (JSC::ASTBuilder::createArray): + (JSC::ASTBuilder::createNumberExpr): + (JSC::ASTBuilder::createString): + (JSC::ASTBuilder::createBoolean): + (JSC::ASTBuilder::createNull): + (JSC::ASTBuilder::createBracketAccess): + (JSC::ASTBuilder::createDotAccess): + (JSC::ASTBuilder::createRegExp): + (JSC::ASTBuilder::createNewExpr): + (JSC::ASTBuilder::createConditionalExpr): + (JSC::ASTBuilder::createAssignResolve): + (JSC::ASTBuilder::createFunctionExpr): + (JSC::ASTBuilder::createFunctionBody): + (JSC::ASTBuilder::createGetterOrSetterProperty): + (JSC::ASTBuilder::createArgumentsList): + (JSC::ASTBuilder::createPropertyList): + (JSC::ASTBuilder::createFuncDeclStatement): + (JSC::ASTBuilder::createBlockStatement): + (JSC::ASTBuilder::createExprStatement): + (JSC::ASTBuilder::createIfStatement): + (JSC::ASTBuilder::createForLoop): + (JSC::ASTBuilder::createForInLoop): + (JSC::ASTBuilder::createEmptyStatement): + (JSC::ASTBuilder::createVarStatement): + (JSC::ASTBuilder::createReturnStatement): + (JSC::ASTBuilder::createBreakStatement): + (JSC::ASTBuilder::createContinueStatement): + (JSC::ASTBuilder::createTryStatement): + (JSC::ASTBuilder::createSwitchStatement): + (JSC::ASTBuilder::createWhileStatement): + (JSC::ASTBuilder::createDoWhileStatement): + (JSC::ASTBuilder::createLabelStatement): + (JSC::ASTBuilder::createWithStatement): + (JSC::ASTBuilder::createThrowStatement): + (JSC::ASTBuilder::createDebugger): + (JSC::ASTBuilder::createConstStatement): + (JSC::ASTBuilder::appendConstDecl): + (JSC::ASTBuilder::combineCommaNodes): + (JSC::ASTBuilder::appendBinaryOperation): + (JSC::ASTBuilder::createAssignment): + (JSC::ASTBuilder::createNumber): + (JSC::ASTBuilder::makeTypeOfNode): + (JSC::ASTBuilder::makeDeleteNode): + (JSC::ASTBuilder::makeNegateNode): + (JSC::ASTBuilder::makeBitwiseNotNode): + (JSC::ASTBuilder::makeMultNode): + (JSC::ASTBuilder::makeDivNode): + (JSC::ASTBuilder::makeModNode): + (JSC::ASTBuilder::makeAddNode): + (JSC::ASTBuilder::makeSubNode): + (JSC::ASTBuilder::makeLeftShiftNode): + (JSC::ASTBuilder::makeRightShiftNode): + (JSC::ASTBuilder::makeURightShiftNode): + (JSC::ASTBuilder::makeBitOrNode): + (JSC::ASTBuilder::makeBitAndNode): + (JSC::ASTBuilder::makeBitXOrNode): + (JSC::ASTBuilder::makeFunctionCallNode): + (JSC::ASTBuilder::makeBinaryNode): + (JSC::ASTBuilder::makeAssignNode): + (JSC::ASTBuilder::makePrefixNode): + (JSC::ASTBuilder::makePostfixNode): + * parser/Lexer.cpp: + (JSC::::setCode): + (JSC::::internalShift): + (JSC::::shift): + (JSC::::lex): + * parser/Lexer.h: + (Lexer): + (JSC::Lexer::currentColumnNumber): + (JSC::::lexExpectIdentifier): + * parser/NodeConstructors.h: + (JSC::Node::Node): + (JSC::ExpressionNode::ExpressionNode): + (JSC::StatementNode::StatementNode): + (JSC::NullNode::NullNode): + (JSC::BooleanNode::BooleanNode): + (JSC::NumberNode::NumberNode): + (JSC::StringNode::StringNode): + (JSC::RegExpNode::RegExpNode): + (JSC::ThisNode::ThisNode): + (JSC::ResolveNode::ResolveNode): + (JSC::ArrayNode::ArrayNode): + (JSC::PropertyListNode::PropertyListNode): + (JSC::ObjectLiteralNode::ObjectLiteralNode): + (JSC::BracketAccessorNode::BracketAccessorNode): + (JSC::DotAccessorNode::DotAccessorNode): + (JSC::ArgumentListNode::ArgumentListNode): + (JSC::NewExprNode::NewExprNode): + (JSC::EvalFunctionCallNode::EvalFunctionCallNode): + (JSC::FunctionCallValueNode::FunctionCallValueNode): + (JSC::FunctionCallResolveNode::FunctionCallResolveNode): + (JSC::FunctionCallBracketNode::FunctionCallBracketNode): + (JSC::FunctionCallDotNode::FunctionCallDotNode): + (JSC::CallFunctionCallDotNode::CallFunctionCallDotNode): + (JSC::ApplyFunctionCallDotNode::ApplyFunctionCallDotNode): + (JSC::PrePostResolveNode::PrePostResolveNode): + (JSC::PostfixResolveNode::PostfixResolveNode): + (JSC::PostfixBracketNode::PostfixBracketNode): + (JSC::PostfixDotNode::PostfixDotNode): + (JSC::PostfixErrorNode::PostfixErrorNode): + (JSC::DeleteResolveNode::DeleteResolveNode): + (JSC::DeleteBracketNode::DeleteBracketNode): + (JSC::DeleteDotNode::DeleteDotNode): + (JSC::DeleteValueNode::DeleteValueNode): + (JSC::VoidNode::VoidNode): + (JSC::TypeOfResolveNode::TypeOfResolveNode): + (JSC::TypeOfValueNode::TypeOfValueNode): + (JSC::PrefixResolveNode::PrefixResolveNode): + (JSC::PrefixBracketNode::PrefixBracketNode): + (JSC::PrefixDotNode::PrefixDotNode): + (JSC::PrefixErrorNode::PrefixErrorNode): + (JSC::UnaryOpNode::UnaryOpNode): + (JSC::UnaryPlusNode::UnaryPlusNode): + (JSC::NegateNode::NegateNode): + (JSC::BitwiseNotNode::BitwiseNotNode): + (JSC::LogicalNotNode::LogicalNotNode): + (JSC::BinaryOpNode::BinaryOpNode): + (JSC::MultNode::MultNode): + (JSC::DivNode::DivNode): + (JSC::ModNode::ModNode): + (JSC::AddNode::AddNode): + (JSC::SubNode::SubNode): + (JSC::LeftShiftNode::LeftShiftNode): + (JSC::RightShiftNode::RightShiftNode): + (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode): + (JSC::LessNode::LessNode): + (JSC::GreaterNode::GreaterNode): + (JSC::LessEqNode::LessEqNode): + (JSC::GreaterEqNode::GreaterEqNode): + (JSC::ThrowableBinaryOpNode::ThrowableBinaryOpNode): + (JSC::InstanceOfNode::InstanceOfNode): + (JSC::InNode::InNode): + (JSC::EqualNode::EqualNode): + (JSC::NotEqualNode::NotEqualNode): + (JSC::StrictEqualNode::StrictEqualNode): + (JSC::NotStrictEqualNode::NotStrictEqualNode): + (JSC::BitAndNode::BitAndNode): + (JSC::BitOrNode::BitOrNode): + (JSC::BitXOrNode::BitXOrNode): + (JSC::LogicalOpNode::LogicalOpNode): + (JSC::ConditionalNode::ConditionalNode): + (JSC::ReadModifyResolveNode::ReadModifyResolveNode): + (JSC::AssignResolveNode::AssignResolveNode): + (JSC::ReadModifyBracketNode::ReadModifyBracketNode): + (JSC::AssignBracketNode::AssignBracketNode): + (JSC::AssignDotNode::AssignDotNode): + (JSC::ReadModifyDotNode::ReadModifyDotNode): + (JSC::AssignErrorNode::AssignErrorNode): + (JSC::CommaNode::CommaNode): + (JSC::ConstStatementNode::ConstStatementNode): + (JSC::EmptyStatementNode::EmptyStatementNode): + (JSC::DebuggerStatementNode::DebuggerStatementNode): + (JSC::ExprStatementNode::ExprStatementNode): + (JSC::VarStatementNode::VarStatementNode): + (JSC::IfNode::IfNode): + (JSC::IfElseNode::IfElseNode): + (JSC::DoWhileNode::DoWhileNode): + (JSC::WhileNode::WhileNode): + (JSC::ForNode::ForNode): + (JSC::ContinueNode::ContinueNode): + (JSC::BreakNode::BreakNode): + (JSC::ReturnNode::ReturnNode): + (JSC::WithNode::WithNode): + (JSC::LabelNode::LabelNode): + (JSC::ThrowNode::ThrowNode): + (JSC::TryNode::TryNode): + (JSC::FuncExprNode::FuncExprNode): + (JSC::FuncDeclNode::FuncDeclNode): + (JSC::SwitchNode::SwitchNode): + (JSC::ConstDeclNode::ConstDeclNode): + (JSC::BlockNode::BlockNode): + (JSC::ForInNode::ForInNode): + * parser/Nodes.cpp: + (JSC::StatementNode::setLoc): + (JSC): + (JSC::ScopeNode::ScopeNode): + (JSC::ProgramNode::ProgramNode): + (JSC::ProgramNode::create): + (JSC::EvalNode::EvalNode): + (JSC::EvalNode::create): + (JSC::FunctionBodyNode::FunctionBodyNode): + (JSC::FunctionBodyNode::create): + * parser/Nodes.h: + (Node): + (JSC::Node::columnNo): + (ExpressionNode): + (StatementNode): + (JSC::StatementNode::column): + (NullNode): + (BooleanNode): + (NumberNode): + (StringNode): + (RegExpNode): + (ThisNode): + (ResolveNode): + (ArrayNode): + (PropertyListNode): + (ObjectLiteralNode): + (BracketAccessorNode): + (DotAccessorNode): + (ArgumentListNode): + (NewExprNode): + (EvalFunctionCallNode): + (FunctionCallValueNode): + (FunctionCallResolveNode): + (FunctionCallBracketNode): + (FunctionCallDotNode): + (CallFunctionCallDotNode): + (ApplyFunctionCallDotNode): + (PrePostResolveNode): + (PostfixResolveNode): + (PostfixBracketNode): + (PostfixDotNode): + (PostfixErrorNode): + (DeleteResolveNode): + (DeleteBracketNode): + (DeleteDotNode): + (DeleteValueNode): + (VoidNode): + (TypeOfResolveNode): + (TypeOfValueNode): + (PrefixResolveNode): + (PrefixBracketNode): + (PrefixDotNode): + (PrefixErrorNode): + (UnaryOpNode): + (UnaryPlusNode): + (NegateNode): + (BitwiseNotNode): + (LogicalNotNode): + (BinaryOpNode): + (MultNode): + (DivNode): + (ModNode): + (AddNode): + (SubNode): + (LeftShiftNode): + (RightShiftNode): + (UnsignedRightShiftNode): + (LessNode): + (GreaterNode): + (LessEqNode): + (GreaterEqNode): + (ThrowableBinaryOpNode): + (InstanceOfNode): + (InNode): + (EqualNode): + (NotEqualNode): + (StrictEqualNode): + (NotStrictEqualNode): + (BitAndNode): + (BitOrNode): + (BitXOrNode): + (LogicalOpNode): + (ConditionalNode): + (ReadModifyResolveNode): + (AssignResolveNode): + (ReadModifyBracketNode): + (AssignBracketNode): + (AssignDotNode): + (ReadModifyDotNode): + (AssignErrorNode): + (CommaNode): + (ConstDeclNode): + (ConstStatementNode): + (BlockNode): + (EmptyStatementNode): + (DebuggerStatementNode): + (ExprStatementNode): + (VarStatementNode): + (IfNode): + (IfElseNode): + (DoWhileNode): + (WhileNode): + (ForNode): + (ForInNode): + (ContinueNode): + (BreakNode): + (ReturnNode): + (WithNode): + (LabelNode): + (ThrowNode): + (TryNode): + (ScopeNode): + (ProgramNode): + (EvalNode): + (FunctionBodyNode): + (FuncExprNode): + (FuncDeclNode): + (SwitchNode): + * parser/Parser.cpp: + (JSC::::parseSourceElements): + (JSC::::parseVarDeclaration): + (JSC::::parseConstDeclaration): + (JSC::::parseDoWhileStatement): + (JSC::::parseWhileStatement): + (JSC::::parseVarDeclarationList): + (JSC::::parseConstDeclarationList): + (JSC::::parseForStatement): + (JSC::::parseBreakStatement): + (JSC::::parseContinueStatement): + (JSC::::parseReturnStatement): + (JSC::::parseThrowStatement): + (JSC::::parseWithStatement): + (JSC::::parseSwitchStatement): + (JSC::::parseTryStatement): + (JSC::::parseDebuggerStatement): + (JSC::::parseBlockStatement): + (JSC::::parseStatement): + (JSC::::parseFunctionBody): + (JSC::::parseFunctionInfo): + (JSC::::parseFunctionDeclaration): + (JSC::::parseExpressionOrLabelStatement): + (JSC::::parseExpressionStatement): + (JSC::::parseIfStatement): + (JSC::::parseExpression): + (JSC::::parseAssignmentExpression): + (JSC::::parseConditionalExpression): + (JSC::::parseBinaryExpression): + (JSC::::parseProperty): + (JSC::::parseObjectLiteral): + (JSC::::parseStrictObjectLiteral): + (JSC::::parseArrayLiteral): + (JSC::::parsePrimaryExpression): + (JSC::::parseArguments): + (JSC::::parseMemberExpression): + (JSC::::parseUnaryExpression): + * parser/Parser.h: + (JSC::Parser::next): + (JSC::Parser::nextExpectIdentifier): + (JSC::Parser::tokenStart): + (JSC::Parser::tokenLine): + (JSC::Parser::tokenEnd): + (JSC::Parser::tokenLocation): + (Parser): + (JSC::Parser::getTokenName): + (JSC::::parse): + * parser/ParserTokens.h: + (JSC::JSTokenLocation::JSTokenLocation): + (JSTokenLocation): + (JSToken): + * parser/SourceProviderCacheItem.h: + (JSC::SourceProviderCacheItem::closeBraceToken): + * parser/SyntaxChecker.h: + (JSC::SyntaxChecker::makeFunctionCallNode): + (JSC::SyntaxChecker::createCommaExpr): + (JSC::SyntaxChecker::makeAssignNode): + (JSC::SyntaxChecker::makePrefixNode): + (JSC::SyntaxChecker::makePostfixNode): + (JSC::SyntaxChecker::makeTypeOfNode): + (JSC::SyntaxChecker::makeDeleteNode): + (JSC::SyntaxChecker::makeNegateNode): + (JSC::SyntaxChecker::makeBitwiseNotNode): + (JSC::SyntaxChecker::createLogicalNot): + (JSC::SyntaxChecker::createUnaryPlus): + (JSC::SyntaxChecker::createVoid): + (JSC::SyntaxChecker::thisExpr): + (JSC::SyntaxChecker::createResolve): + (JSC::SyntaxChecker::createObjectLiteral): + (JSC::SyntaxChecker::createArray): + (JSC::SyntaxChecker::createNumberExpr): + (JSC::SyntaxChecker::createString): + (JSC::SyntaxChecker::createBoolean): + (JSC::SyntaxChecker::createNull): + (JSC::SyntaxChecker::createBracketAccess): + (JSC::SyntaxChecker::createDotAccess): + (JSC::SyntaxChecker::createRegExp): + (JSC::SyntaxChecker::createNewExpr): + (JSC::SyntaxChecker::createConditionalExpr): + (JSC::SyntaxChecker::createAssignResolve): + (JSC::SyntaxChecker::createFunctionExpr): + (JSC::SyntaxChecker::createFunctionBody): + (JSC::SyntaxChecker::createArgumentsList): + (JSC::SyntaxChecker::createPropertyList): + (JSC::SyntaxChecker::createFuncDeclStatement): + (JSC::SyntaxChecker::createBlockStatement): + (JSC::SyntaxChecker::createExprStatement): + (JSC::SyntaxChecker::createIfStatement): + (JSC::SyntaxChecker::createForLoop): + (JSC::SyntaxChecker::createForInLoop): + (JSC::SyntaxChecker::createEmptyStatement): + (JSC::SyntaxChecker::createVarStatement): + (JSC::SyntaxChecker::createReturnStatement): + (JSC::SyntaxChecker::createBreakStatement): + (JSC::SyntaxChecker::createContinueStatement): + (JSC::SyntaxChecker::createTryStatement): + (JSC::SyntaxChecker::createSwitchStatement): + (JSC::SyntaxChecker::createWhileStatement): + (JSC::SyntaxChecker::createWithStatement): + (JSC::SyntaxChecker::createDoWhileStatement): + (JSC::SyntaxChecker::createLabelStatement): + (JSC::SyntaxChecker::createThrowStatement): + (JSC::SyntaxChecker::createDebugger): + (JSC::SyntaxChecker::createConstStatement): + (JSC::SyntaxChecker::appendConstDecl): + (JSC::SyntaxChecker::createGetterOrSetterProperty): + (JSC::SyntaxChecker::combineCommaNodes): + (JSC::SyntaxChecker::operatorStackPop): + +2012-08-03 Filip Pizlo <fpizlo@apple.com> + + Crashes in dfgBuildPutByIdList when clicking on just about anything on Google Maps + https://bugs.webkit.org/show_bug.cgi?id=92691 + + Reviewed by Mark Hahnenberg. + + The state of the stubs was changing after we determined the type (by virtue of the slow path + function that was called), since the get or put (in this case put) could cause arbitrary + side effects. Perhaps a full-blown fix would be to eliminate our reliance of the slow path + function to determine what to do, but an easier fix for now is to have the slow path give up + if its assumptions were invalidated by a side effect. + + * dfg/DFGOperations.cpp: + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + +2012-08-03 Filip Pizlo <fpizlo@apple.com> + + DFG handling of get_by_id should always inject a ForceOSRExit node if there is no prediction + https://bugs.webkit.org/show_bug.cgi?id=93162 + + Reviewed by Mark Hahnenberg. + + This simplifies the DFG IR by ensuring that all nodes that use value profiles will be preceded + by a ForceOSRExit if the value profile had no data. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + +2012-08-03 Filip Pizlo <fpizlo@apple.com> + + DFG::StructureCheckHoistingPhase keeps a Node& around for too long + https://bugs.webkit.org/show_bug.cgi?id=93157 + + Reviewed by Mark Hahnenberg. + + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-08-02 Patrick Gansterer <paroga@webkit.org> + + Move getLocalTime() as static inline function to DateMath + https://bugs.webkit.org/show_bug.cgi?id=92955 + + Reviewed by Ryosuke Niwa. + + getCurrentLocalTime() and getLocalTime() has been superseded with the + GregorianDateTime class. So we can move it into DateMath.cpp as an static inline + function. This allows us to remove the dependecy on time() and localtime() + for Windows CE, where this functions require the ce_time library to work. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-08-02 Filip Pizlo <fpizlo@apple.com> + + ASSERTION FAILED: at(m_compileIndex).canExit() || m_isCheckingArgumentTypes + https://bugs.webkit.org/show_bug.cgi?id=91074 + + Reviewed by Mark Hahnenberg. + + Fixes a bug where the speculative JIT was performing an unnecessary speculation that the + CFA had proven shouldn't be performed, leading to asserts that a node should not have + exit sites. This is a debug-only assert with no release symptom - we were just emitting + a check that was not reachable. + + Also found, and fixed, a bug where structure check hoisting was slightly confusing the + CFA by inserting GetLocal's into the graph. CSE would clean the GetLocal's up, which + would make the backend happy - but the CFA would produce subtly wrong results. + + * bytecode/SpeculatedType.h: + (JSC::isOtherOrEmptySpeculation): + (JSC): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::dump): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): + (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): + +2012-08-02 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, build fix for DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE). + + * dfg/DFGStructureCheckHoistingPhase.cpp: + (JSC::DFG::StructureCheckHoistingPhase::run): + +2012-08-01 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove all uses of ClassInfo for JSStrings in JIT code + https://bugs.webkit.org/show_bug.cgi?id=92935 + + Reviewed by Geoffrey Garen. + + This is the first step in removing our dependence on in-object ClassInfo pointers + in JIT code. Most of the changes are to check the Structure, which is unique for + JSString primitives. + + * bytecode/SpeculatedType.cpp: + (JSC::speculationFromClassInfo): + (JSC::speculationFromStructure): Changed to check the TypeInfo in the Structure + since there wasn't a JSGlobalData immediately available to grab the JSString + Structure out of. + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * jit/JITInlineMethods.h: + (JSC::JIT::emitLoadCharacterString): + * jit/JITOpcodes.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + (JSC::JIT::emit_op_to_primitive): + (JSC::JIT::emit_op_convert_this): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + (JSC::JIT::emit_op_to_primitive): + (JSC::JIT::emitSlow_op_eq): + (JSC::JIT::emitSlow_op_neq): + (JSC::JIT::compileOpStrictEq): + (JSC::JIT::emit_op_convert_this): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::stringGetByValStubGenerator): + (JSC::JIT::emitSlow_op_get_by_val): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::stringGetByValStubGenerator): + (JSC::JIT::emitSlow_op_get_by_val): + * jit/SpecializedThunkJIT.h: + (JSC::SpecializedThunkJIT::loadJSStringArgument): + * jit/ThunkGenerators.cpp: + (JSC::stringCharLoad): + (JSC::charCodeAtThunkGenerator): + (JSC::charAtThunkGenerator): + +2012-08-02 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, missed a style goof in the previous patch: "NodeIndex nodeIndex" + in a method signature is painfully redundant. + + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + +2012-08-02 Filip Pizlo <fpizlo@apple.com> + + DFGSpeculativeJIT.h has too many inline method bodies + https://bugs.webkit.org/show_bug.cgi?id=92957 + + Reviewed by Antti Koivisto. + + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::speculationCheck): + (DFG): + (JSC::DFG::SpeculativeJIT::speculationWatchpoint): + (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): + (JSC::DFG::SpeculativeJIT::speculationCheckWithConditionalDirection): + (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution): + (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + +2012-08-01 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r124406. + http://trac.webkit.org/changeset/124406 + https://bugs.webkit.org/show_bug.cgi?id=92951 + + it set the Mac bots on fire (Requested by pizlo on #webkit). + + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitDebugHook): + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + * bytecompiler/NodesCodegen.cpp: + (JSC::ArrayNode::toArgumentList): + (JSC::ApplyFunctionCallDotNode::emitBytecode): + (JSC::ConditionalNode::emitBytecode): + (JSC::ConstStatementNode::emitBytecode): + (JSC::EmptyStatementNode::emitBytecode): + (JSC::DebuggerStatementNode::emitBytecode): + (JSC::ExprStatementNode::emitBytecode): + (JSC::VarStatementNode::emitBytecode): + (JSC::IfNode::emitBytecode): + (JSC::IfElseNode::emitBytecode): + (JSC::DoWhileNode::emitBytecode): + (JSC::WhileNode::emitBytecode): + (JSC::ForNode::emitBytecode): + (JSC::ForInNode::emitBytecode): + (JSC::ContinueNode::emitBytecode): + (JSC::BreakNode::emitBytecode): + (JSC::ReturnNode::emitBytecode): + (JSC::WithNode::emitBytecode): + (JSC::SwitchNode::emitBytecode): + (JSC::LabelNode::emitBytecode): + (JSC::ThrowNode::emitBytecode): + (JSC::TryNode::emitBytecode): + (JSC::ProgramNode::emitBytecode): + (JSC::EvalNode::emitBytecode): + (JSC::FunctionBodyNode::emitBytecode): + * debugger/Debugger.h: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::unwindCallFrame): + (JSC::Interpreter::throwException): + (JSC::Interpreter::debug): + * interpreter/Interpreter.h: + (Interpreter): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_debug): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_debug): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * parser/ASTBuilder.h: + (ASTBuilder): + (JSC::ASTBuilder::createCommaExpr): + (JSC::ASTBuilder::createLogicalNot): + (JSC::ASTBuilder::createUnaryPlus): + (JSC::ASTBuilder::createVoid): + (JSC::ASTBuilder::thisExpr): + (JSC::ASTBuilder::createResolve): + (JSC::ASTBuilder::createObjectLiteral): + (JSC::ASTBuilder::createArray): + (JSC::ASTBuilder::createNumberExpr): + (JSC::ASTBuilder::createString): + (JSC::ASTBuilder::createBoolean): + (JSC::ASTBuilder::createNull): + (JSC::ASTBuilder::createBracketAccess): + (JSC::ASTBuilder::createDotAccess): + (JSC::ASTBuilder::createRegExp): + (JSC::ASTBuilder::createNewExpr): + (JSC::ASTBuilder::createConditionalExpr): + (JSC::ASTBuilder::createAssignResolve): + (JSC::ASTBuilder::createFunctionExpr): + (JSC::ASTBuilder::createFunctionBody): + (JSC::ASTBuilder::createGetterOrSetterProperty): + (JSC::ASTBuilder::createArgumentsList): + (JSC::ASTBuilder::createPropertyList): + (JSC::ASTBuilder::createFuncDeclStatement): + (JSC::ASTBuilder::createBlockStatement): + (JSC::ASTBuilder::createExprStatement): + (JSC::ASTBuilder::createIfStatement): + (JSC::ASTBuilder::createForLoop): + (JSC::ASTBuilder::createForInLoop): + (JSC::ASTBuilder::createEmptyStatement): + (JSC::ASTBuilder::createVarStatement): + (JSC::ASTBuilder::createReturnStatement): + (JSC::ASTBuilder::createBreakStatement): + (JSC::ASTBuilder::createContinueStatement): + (JSC::ASTBuilder::createTryStatement): + (JSC::ASTBuilder::createSwitchStatement): + (JSC::ASTBuilder::createWhileStatement): + (JSC::ASTBuilder::createDoWhileStatement): + (JSC::ASTBuilder::createLabelStatement): + (JSC::ASTBuilder::createWithStatement): + (JSC::ASTBuilder::createThrowStatement): + (JSC::ASTBuilder::createDebugger): + (JSC::ASTBuilder::createConstStatement): + (JSC::ASTBuilder::appendConstDecl): + (JSC::ASTBuilder::combineCommaNodes): + (JSC::ASTBuilder::appendBinaryOperation): + (JSC::ASTBuilder::createAssignment): + (JSC::ASTBuilder::createNumber): + (JSC::ASTBuilder::makeTypeOfNode): + (JSC::ASTBuilder::makeDeleteNode): + (JSC::ASTBuilder::makeNegateNode): + (JSC::ASTBuilder::makeBitwiseNotNode): + (JSC::ASTBuilder::makeMultNode): + (JSC::ASTBuilder::makeDivNode): + (JSC::ASTBuilder::makeModNode): + (JSC::ASTBuilder::makeAddNode): + (JSC::ASTBuilder::makeSubNode): + (JSC::ASTBuilder::makeLeftShiftNode): + (JSC::ASTBuilder::makeRightShiftNode): + (JSC::ASTBuilder::makeURightShiftNode): + (JSC::ASTBuilder::makeBitOrNode): + (JSC::ASTBuilder::makeBitAndNode): + (JSC::ASTBuilder::makeBitXOrNode): + (JSC::ASTBuilder::makeFunctionCallNode): + (JSC::ASTBuilder::makeBinaryNode): + (JSC::ASTBuilder::makeAssignNode): + (JSC::ASTBuilder::makePrefixNode): + (JSC::ASTBuilder::makePostfixNode): + * parser/Lexer.cpp: + (JSC::::setCode): + (JSC::::internalShift): + (JSC::::shift): + (JSC::::lex): + * parser/Lexer.h: + (Lexer): + (JSC::::lexExpectIdentifier): + * parser/NodeConstructors.h: + (JSC::Node::Node): + (JSC::ExpressionNode::ExpressionNode): + (JSC::StatementNode::StatementNode): + (JSC::NullNode::NullNode): + (JSC::BooleanNode::BooleanNode): + (JSC::NumberNode::NumberNode): + (JSC::StringNode::StringNode): + (JSC::RegExpNode::RegExpNode): + (JSC::ThisNode::ThisNode): + (JSC::ResolveNode::ResolveNode): + (JSC::ArrayNode::ArrayNode): + (JSC::PropertyListNode::PropertyListNode): + (JSC::ObjectLiteralNode::ObjectLiteralNode): + (JSC::BracketAccessorNode::BracketAccessorNode): + (JSC::DotAccessorNode::DotAccessorNode): + (JSC::ArgumentListNode::ArgumentListNode): + (JSC::NewExprNode::NewExprNode): + (JSC::EvalFunctionCallNode::EvalFunctionCallNode): + (JSC::FunctionCallValueNode::FunctionCallValueNode): + (JSC::FunctionCallResolveNode::FunctionCallResolveNode): + (JSC::FunctionCallBracketNode::FunctionCallBracketNode): + (JSC::FunctionCallDotNode::FunctionCallDotNode): + (JSC::CallFunctionCallDotNode::CallFunctionCallDotNode): + (JSC::ApplyFunctionCallDotNode::ApplyFunctionCallDotNode): + (JSC::PrePostResolveNode::PrePostResolveNode): + (JSC::PostfixResolveNode::PostfixResolveNode): + (JSC::PostfixBracketNode::PostfixBracketNode): + (JSC::PostfixDotNode::PostfixDotNode): + (JSC::PostfixErrorNode::PostfixErrorNode): + (JSC::DeleteResolveNode::DeleteResolveNode): + (JSC::DeleteBracketNode::DeleteBracketNode): + (JSC::DeleteDotNode::DeleteDotNode): + (JSC::DeleteValueNode::DeleteValueNode): + (JSC::VoidNode::VoidNode): + (JSC::TypeOfResolveNode::TypeOfResolveNode): + (JSC::TypeOfValueNode::TypeOfValueNode): + (JSC::PrefixResolveNode::PrefixResolveNode): + (JSC::PrefixBracketNode::PrefixBracketNode): + (JSC::PrefixDotNode::PrefixDotNode): + (JSC::PrefixErrorNode::PrefixErrorNode): + (JSC::UnaryOpNode::UnaryOpNode): + (JSC::UnaryPlusNode::UnaryPlusNode): + (JSC::NegateNode::NegateNode): + (JSC::BitwiseNotNode::BitwiseNotNode): + (JSC::LogicalNotNode::LogicalNotNode): + (JSC::BinaryOpNode::BinaryOpNode): + (JSC::MultNode::MultNode): + (JSC::DivNode::DivNode): + (JSC::ModNode::ModNode): + (JSC::AddNode::AddNode): + (JSC::SubNode::SubNode): + (JSC::LeftShiftNode::LeftShiftNode): + (JSC::RightShiftNode::RightShiftNode): + (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode): + (JSC::LessNode::LessNode): + (JSC::GreaterNode::GreaterNode): + (JSC::LessEqNode::LessEqNode): + (JSC::GreaterEqNode::GreaterEqNode): + (JSC::ThrowableBinaryOpNode::ThrowableBinaryOpNode): + (JSC::InstanceOfNode::InstanceOfNode): + (JSC::InNode::InNode): + (JSC::EqualNode::EqualNode): + (JSC::NotEqualNode::NotEqualNode): + (JSC::StrictEqualNode::StrictEqualNode): + (JSC::NotStrictEqualNode::NotStrictEqualNode): + (JSC::BitAndNode::BitAndNode): + (JSC::BitOrNode::BitOrNode): + (JSC::BitXOrNode::BitXOrNode): + (JSC::LogicalOpNode::LogicalOpNode): + (JSC::ConditionalNode::ConditionalNode): + (JSC::ReadModifyResolveNode::ReadModifyResolveNode): + (JSC::AssignResolveNode::AssignResolveNode): + (JSC::ReadModifyBracketNode::ReadModifyBracketNode): + (JSC::AssignBracketNode::AssignBracketNode): + (JSC::AssignDotNode::AssignDotNode): + (JSC::ReadModifyDotNode::ReadModifyDotNode): + (JSC::AssignErrorNode::AssignErrorNode): + (JSC::CommaNode::CommaNode): + (JSC::ConstStatementNode::ConstStatementNode): + (JSC::EmptyStatementNode::EmptyStatementNode): + (JSC::DebuggerStatementNode::DebuggerStatementNode): + (JSC::ExprStatementNode::ExprStatementNode): + (JSC::VarStatementNode::VarStatementNode): + (JSC::IfNode::IfNode): + (JSC::IfElseNode::IfElseNode): + (JSC::DoWhileNode::DoWhileNode): + (JSC::WhileNode::WhileNode): + (JSC::ForNode::ForNode): + (JSC::ContinueNode::ContinueNode): + (JSC::BreakNode::BreakNode): + (JSC::ReturnNode::ReturnNode): + (JSC::WithNode::WithNode): + (JSC::LabelNode::LabelNode): + (JSC::ThrowNode::ThrowNode): + (JSC::TryNode::TryNode): + (JSC::FuncExprNode::FuncExprNode): + (JSC::FuncDeclNode::FuncDeclNode): + (JSC::SwitchNode::SwitchNode): + (JSC::ConstDeclNode::ConstDeclNode): + (JSC::BlockNode::BlockNode): + (JSC::ForInNode::ForInNode): + * parser/Nodes.cpp: + (JSC): + (JSC::StatementNode::setLoc): + (JSC::ScopeNode::ScopeNode): + (JSC::ProgramNode::ProgramNode): + (JSC::ProgramNode::create): + (JSC::EvalNode::EvalNode): + (JSC::EvalNode::create): + (JSC::FunctionBodyNode::FunctionBodyNode): + (JSC::FunctionBodyNode::create): + * parser/Nodes.h: + (Node): + (ExpressionNode): + (StatementNode): + (NullNode): + (BooleanNode): + (NumberNode): + (StringNode): + (RegExpNode): + (ThisNode): + (ResolveNode): + (ArrayNode): + (PropertyListNode): + (ObjectLiteralNode): + (BracketAccessorNode): + (DotAccessorNode): + (ArgumentListNode): + (NewExprNode): + (EvalFunctionCallNode): + (FunctionCallValueNode): + (FunctionCallResolveNode): + (FunctionCallBracketNode): + (FunctionCallDotNode): + (CallFunctionCallDotNode): + (ApplyFunctionCallDotNode): + (PrePostResolveNode): + (PostfixResolveNode): + (PostfixBracketNode): + (PostfixDotNode): + (PostfixErrorNode): + (DeleteResolveNode): + (DeleteBracketNode): + (DeleteDotNode): + (DeleteValueNode): + (VoidNode): + (TypeOfResolveNode): + (TypeOfValueNode): + (PrefixResolveNode): + (PrefixBracketNode): + (PrefixDotNode): + (PrefixErrorNode): + (UnaryOpNode): + (UnaryPlusNode): + (NegateNode): + (BitwiseNotNode): + (LogicalNotNode): + (BinaryOpNode): + (MultNode): + (DivNode): + (ModNode): + (AddNode): + (SubNode): + (LeftShiftNode): + (RightShiftNode): + (UnsignedRightShiftNode): + (LessNode): + (GreaterNode): + (LessEqNode): + (GreaterEqNode): + (ThrowableBinaryOpNode): + (InstanceOfNode): + (InNode): + (EqualNode): + (NotEqualNode): + (StrictEqualNode): + (NotStrictEqualNode): + (BitAndNode): + (BitOrNode): + (BitXOrNode): + (LogicalOpNode): + (ConditionalNode): + (ReadModifyResolveNode): + (AssignResolveNode): + (ReadModifyBracketNode): + (AssignBracketNode): + (AssignDotNode): + (ReadModifyDotNode): + (AssignErrorNode): + (CommaNode): + (ConstDeclNode): + (ConstStatementNode): + (BlockNode): + (EmptyStatementNode): + (DebuggerStatementNode): + (ExprStatementNode): + (VarStatementNode): + (IfNode): + (IfElseNode): + (DoWhileNode): + (WhileNode): + (ForNode): + (ForInNode): + (ContinueNode): + (BreakNode): + (ReturnNode): + (WithNode): + (LabelNode): + (ThrowNode): + (TryNode): + (ScopeNode): + (ProgramNode): + (EvalNode): + (FunctionBodyNode): + (FuncExprNode): + (FuncDeclNode): + (SwitchNode): + * parser/Parser.cpp: + (JSC::::parseSourceElements): + (JSC::::parseVarDeclaration): + (JSC::::parseConstDeclaration): + (JSC::::parseDoWhileStatement): + (JSC::::parseWhileStatement): + (JSC::::parseVarDeclarationList): + (JSC::::parseConstDeclarationList): + (JSC::::parseForStatement): + (JSC::::parseBreakStatement): + (JSC::::parseContinueStatement): + (JSC::::parseReturnStatement): + (JSC::::parseThrowStatement): + (JSC::::parseWithStatement): + (JSC::::parseSwitchStatement): + (JSC::::parseTryStatement): + (JSC::::parseDebuggerStatement): + (JSC::::parseBlockStatement): + (JSC::::parseStatement): + (JSC::::parseFunctionBody): + (JSC::::parseFunctionInfo): + (JSC::::parseFunctionDeclaration): + (JSC::::parseExpressionOrLabelStatement): + (JSC::::parseExpressionStatement): + (JSC::::parseIfStatement): + (JSC::::parseExpression): + (JSC::::parseAssignmentExpression): + (JSC::::parseConditionalExpression): + (JSC::::parseBinaryExpression): + (JSC::::parseProperty): + (JSC::::parseObjectLiteral): + (JSC::::parseStrictObjectLiteral): + (JSC::::parseArrayLiteral): + (JSC::::parsePrimaryExpression): + (JSC::::parseArguments): + (JSC::::parseMemberExpression): + (JSC::::parseUnaryExpression): + * parser/Parser.h: + (JSC::Parser::next): + (JSC::Parser::nextExpectIdentifier): + (JSC::Parser::tokenStart): + (JSC::Parser::tokenLine): + (JSC::Parser::tokenEnd): + (JSC::Parser::getTokenName): + (JSC::::parse): + * parser/ParserTokens.h: + (JSC::JSTokenInfo::JSTokenInfo): + (JSTokenInfo): + (JSToken): + * parser/SourceProviderCacheItem.h: + (JSC::SourceProviderCacheItem::closeBraceToken): + * parser/SyntaxChecker.h: + (JSC::SyntaxChecker::makeFunctionCallNode): + (JSC::SyntaxChecker::createCommaExpr): + (JSC::SyntaxChecker::makeAssignNode): + (JSC::SyntaxChecker::makePrefixNode): + (JSC::SyntaxChecker::makePostfixNode): + (JSC::SyntaxChecker::makeTypeOfNode): + (JSC::SyntaxChecker::makeDeleteNode): + (JSC::SyntaxChecker::makeNegateNode): + (JSC::SyntaxChecker::makeBitwiseNotNode): + (JSC::SyntaxChecker::createLogicalNot): + (JSC::SyntaxChecker::createUnaryPlus): + (JSC::SyntaxChecker::createVoid): + (JSC::SyntaxChecker::thisExpr): + (JSC::SyntaxChecker::createResolve): + (JSC::SyntaxChecker::createObjectLiteral): + (JSC::SyntaxChecker::createArray): + (JSC::SyntaxChecker::createNumberExpr): + (JSC::SyntaxChecker::createString): + (JSC::SyntaxChecker::createBoolean): + (JSC::SyntaxChecker::createNull): + (JSC::SyntaxChecker::createBracketAccess): + (JSC::SyntaxChecker::createDotAccess): + (JSC::SyntaxChecker::createRegExp): + (JSC::SyntaxChecker::createNewExpr): + (JSC::SyntaxChecker::createConditionalExpr): + (JSC::SyntaxChecker::createAssignResolve): + (JSC::SyntaxChecker::createFunctionExpr): + (JSC::SyntaxChecker::createFunctionBody): + (JSC::SyntaxChecker::createArgumentsList): + (JSC::SyntaxChecker::createPropertyList): + (JSC::SyntaxChecker::createFuncDeclStatement): + (JSC::SyntaxChecker::createBlockStatement): + (JSC::SyntaxChecker::createExprStatement): + (JSC::SyntaxChecker::createIfStatement): + (JSC::SyntaxChecker::createForLoop): + (JSC::SyntaxChecker::createForInLoop): + (JSC::SyntaxChecker::createEmptyStatement): + (JSC::SyntaxChecker::createVarStatement): + (JSC::SyntaxChecker::createReturnStatement): + (JSC::SyntaxChecker::createBreakStatement): + (JSC::SyntaxChecker::createContinueStatement): + (JSC::SyntaxChecker::createTryStatement): + (JSC::SyntaxChecker::createSwitchStatement): + (JSC::SyntaxChecker::createWhileStatement): + (JSC::SyntaxChecker::createWithStatement): + (JSC::SyntaxChecker::createDoWhileStatement): + (JSC::SyntaxChecker::createLabelStatement): + (JSC::SyntaxChecker::createThrowStatement): + (JSC::SyntaxChecker::createDebugger): + (JSC::SyntaxChecker::createConstStatement): + (JSC::SyntaxChecker::appendConstDecl): + (JSC::SyntaxChecker::createGetterOrSetterProperty): + (JSC::SyntaxChecker::combineCommaNodes): + (JSC::SyntaxChecker::operatorStackPop): + +2012-08-01 Peter Wang <peter.wang@torchmobile.com.cn> + + Web Inspector: [JSC] implement setting breakpoints by line:column + https://bugs.webkit.org/show_bug.cgi?id=53003 + + Reviewed by Geoffrey Garen. + + Add a counter in lexer to record the column of each token. Debugger will use column info + in "Pretty Print" debug mode of Inspector. + + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::emitDebugHook): + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + * bytecompiler/NodesCodegen.cpp: + (JSC::ArrayNode::toArgumentList): + (JSC::ApplyFunctionCallDotNode::emitBytecode): + (JSC::ConditionalNode::emitBytecode): + (JSC::ConstStatementNode::emitBytecode): + (JSC::EmptyStatementNode::emitBytecode): + (JSC::DebuggerStatementNode::emitBytecode): + (JSC::ExprStatementNode::emitBytecode): + (JSC::VarStatementNode::emitBytecode): + (JSC::IfNode::emitBytecode): + (JSC::IfElseNode::emitBytecode): + (JSC::DoWhileNode::emitBytecode): + (JSC::WhileNode::emitBytecode): + (JSC::ForNode::emitBytecode): + (JSC::ForInNode::emitBytecode): + (JSC::ContinueNode::emitBytecode): + (JSC::BreakNode::emitBytecode): + (JSC::ReturnNode::emitBytecode): + (JSC::WithNode::emitBytecode): + (JSC::SwitchNode::emitBytecode): + (JSC::LabelNode::emitBytecode): + (JSC::ThrowNode::emitBytecode): + (JSC::TryNode::emitBytecode): + (JSC::ProgramNode::emitBytecode): + (JSC::EvalNode::emitBytecode): + (JSC::FunctionBodyNode::emitBytecode): + * debugger/Debugger.h: + * interpreter/Interpreter.cpp: + (JSC::Interpreter::unwindCallFrame): + (JSC::Interpreter::throwException): + (JSC::Interpreter::debug): + * interpreter/Interpreter.h: + (Interpreter): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_debug): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_debug): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * parser/ASTBuilder.h: + (ASTBuilder): + (JSC::ASTBuilder::createCommaExpr): + (JSC::ASTBuilder::createLogicalNot): + (JSC::ASTBuilder::createUnaryPlus): + (JSC::ASTBuilder::createVoid): + (JSC::ASTBuilder::thisExpr): + (JSC::ASTBuilder::createResolve): + (JSC::ASTBuilder::createObjectLiteral): + (JSC::ASTBuilder::createArray): + (JSC::ASTBuilder::createNumberExpr): + (JSC::ASTBuilder::createString): + (JSC::ASTBuilder::createBoolean): + (JSC::ASTBuilder::createNull): + (JSC::ASTBuilder::createBracketAccess): + (JSC::ASTBuilder::createDotAccess): + (JSC::ASTBuilder::createRegExp): + (JSC::ASTBuilder::createNewExpr): + (JSC::ASTBuilder::createConditionalExpr): + (JSC::ASTBuilder::createAssignResolve): + (JSC::ASTBuilder::createFunctionExpr): + (JSC::ASTBuilder::createFunctionBody): + (JSC::ASTBuilder::createGetterOrSetterProperty): + (JSC::ASTBuilder::createArgumentsList): + (JSC::ASTBuilder::createPropertyList): + (JSC::ASTBuilder::createFuncDeclStatement): + (JSC::ASTBuilder::createBlockStatement): + (JSC::ASTBuilder::createExprStatement): + (JSC::ASTBuilder::createIfStatement): + (JSC::ASTBuilder::createForLoop): + (JSC::ASTBuilder::createForInLoop): + (JSC::ASTBuilder::createEmptyStatement): + (JSC::ASTBuilder::createVarStatement): + (JSC::ASTBuilder::createReturnStatement): + (JSC::ASTBuilder::createBreakStatement): + (JSC::ASTBuilder::createContinueStatement): + (JSC::ASTBuilder::createTryStatement): + (JSC::ASTBuilder::createSwitchStatement): + (JSC::ASTBuilder::createWhileStatement): + (JSC::ASTBuilder::createDoWhileStatement): + (JSC::ASTBuilder::createLabelStatement): + (JSC::ASTBuilder::createWithStatement): + (JSC::ASTBuilder::createThrowStatement): + (JSC::ASTBuilder::createDebugger): + (JSC::ASTBuilder::createConstStatement): + (JSC::ASTBuilder::appendConstDecl): + (JSC::ASTBuilder::combineCommaNodes): + (JSC::ASTBuilder::appendBinaryOperation): + (JSC::ASTBuilder::createAssignment): + (JSC::ASTBuilder::createNumber): + (JSC::ASTBuilder::makeTypeOfNode): + (JSC::ASTBuilder::makeDeleteNode): + (JSC::ASTBuilder::makeNegateNode): + (JSC::ASTBuilder::makeBitwiseNotNode): + (JSC::ASTBuilder::makeMultNode): + (JSC::ASTBuilder::makeDivNode): + (JSC::ASTBuilder::makeModNode): + (JSC::ASTBuilder::makeAddNode): + (JSC::ASTBuilder::makeSubNode): + (JSC::ASTBuilder::makeLeftShiftNode): + (JSC::ASTBuilder::makeRightShiftNode): + (JSC::ASTBuilder::makeURightShiftNode): + (JSC::ASTBuilder::makeBitOrNode): + (JSC::ASTBuilder::makeBitAndNode): + (JSC::ASTBuilder::makeBitXOrNode): + (JSC::ASTBuilder::makeFunctionCallNode): + (JSC::ASTBuilder::makeBinaryNode): + (JSC::ASTBuilder::makeAssignNode): + (JSC::ASTBuilder::makePrefixNode): + (JSC::ASTBuilder::makePostfixNode): + * parser/Lexer.cpp: + (JSC::::setCode): + (JSC::::internalShift): + (JSC::::shift): + (JSC::::lex): + * parser/Lexer.h: + (Lexer): + (JSC::Lexer::currentColumnNumber): + (JSC::::lexExpectIdentifier): + * parser/NodeConstructors.h: + (JSC::Node::Node): + (JSC::ExpressionNode::ExpressionNode): + (JSC::StatementNode::StatementNode): + (JSC::NullNode::NullNode): + (JSC::BooleanNode::BooleanNode): + (JSC::NumberNode::NumberNode): + (JSC::StringNode::StringNode): + (JSC::RegExpNode::RegExpNode): + (JSC::ThisNode::ThisNode): + (JSC::ResolveNode::ResolveNode): + (JSC::ArrayNode::ArrayNode): + (JSC::PropertyListNode::PropertyListNode): + (JSC::ObjectLiteralNode::ObjectLiteralNode): + (JSC::BracketAccessorNode::BracketAccessorNode): + (JSC::DotAccessorNode::DotAccessorNode): + (JSC::ArgumentListNode::ArgumentListNode): + (JSC::NewExprNode::NewExprNode): + (JSC::EvalFunctionCallNode::EvalFunctionCallNode): + (JSC::FunctionCallValueNode::FunctionCallValueNode): + (JSC::FunctionCallResolveNode::FunctionCallResolveNode): + (JSC::FunctionCallBracketNode::FunctionCallBracketNode): + (JSC::FunctionCallDotNode::FunctionCallDotNode): + (JSC::CallFunctionCallDotNode::CallFunctionCallDotNode): + (JSC::ApplyFunctionCallDotNode::ApplyFunctionCallDotNode): + (JSC::PrePostResolveNode::PrePostResolveNode): + (JSC::PostfixResolveNode::PostfixResolveNode): + (JSC::PostfixBracketNode::PostfixBracketNode): + (JSC::PostfixDotNode::PostfixDotNode): + (JSC::PostfixErrorNode::PostfixErrorNode): + (JSC::DeleteResolveNode::DeleteResolveNode): + (JSC::DeleteBracketNode::DeleteBracketNode): + (JSC::DeleteDotNode::DeleteDotNode): + (JSC::DeleteValueNode::DeleteValueNode): + (JSC::VoidNode::VoidNode): + (JSC::TypeOfResolveNode::TypeOfResolveNode): + (JSC::TypeOfValueNode::TypeOfValueNode): + (JSC::PrefixResolveNode::PrefixResolveNode): + (JSC::PrefixBracketNode::PrefixBracketNode): + (JSC::PrefixDotNode::PrefixDotNode): + (JSC::PrefixErrorNode::PrefixErrorNode): + (JSC::UnaryOpNode::UnaryOpNode): + (JSC::UnaryPlusNode::UnaryPlusNode): + (JSC::NegateNode::NegateNode): + (JSC::BitwiseNotNode::BitwiseNotNode): + (JSC::LogicalNotNode::LogicalNotNode): + (JSC::BinaryOpNode::BinaryOpNode): + (JSC::MultNode::MultNode): + (JSC::DivNode::DivNode): + (JSC::ModNode::ModNode): + (JSC::AddNode::AddNode): + (JSC::SubNode::SubNode): + (JSC::LeftShiftNode::LeftShiftNode): + (JSC::RightShiftNode::RightShiftNode): + (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode): + (JSC::LessNode::LessNode): + (JSC::GreaterNode::GreaterNode): + (JSC::LessEqNode::LessEqNode): + (JSC::GreaterEqNode::GreaterEqNode): + (JSC::ThrowableBinaryOpNode::ThrowableBinaryOpNode): + (JSC::InstanceOfNode::InstanceOfNode): + (JSC::InNode::InNode): + (JSC::EqualNode::EqualNode): + (JSC::NotEqualNode::NotEqualNode): + (JSC::StrictEqualNode::StrictEqualNode): + (JSC::NotStrictEqualNode::NotStrictEqualNode): + (JSC::BitAndNode::BitAndNode): + (JSC::BitOrNode::BitOrNode): + (JSC::BitXOrNode::BitXOrNode): + (JSC::LogicalOpNode::LogicalOpNode): + (JSC::ConditionalNode::ConditionalNode): + (JSC::ReadModifyResolveNode::ReadModifyResolveNode): + (JSC::AssignResolveNode::AssignResolveNode): + (JSC::ReadModifyBracketNode::ReadModifyBracketNode): + (JSC::AssignBracketNode::AssignBracketNode): + (JSC::AssignDotNode::AssignDotNode): + (JSC::ReadModifyDotNode::ReadModifyDotNode): + (JSC::AssignErrorNode::AssignErrorNode): + (JSC::CommaNode::CommaNode): + (JSC::ConstStatementNode::ConstStatementNode): + (JSC::EmptyStatementNode::EmptyStatementNode): + (JSC::DebuggerStatementNode::DebuggerStatementNode): + (JSC::ExprStatementNode::ExprStatementNode): + (JSC::VarStatementNode::VarStatementNode): + (JSC::IfNode::IfNode): + (JSC::IfElseNode::IfElseNode): + (JSC::DoWhileNode::DoWhileNode): + (JSC::WhileNode::WhileNode): + (JSC::ForNode::ForNode): + (JSC::ContinueNode::ContinueNode): + (JSC::BreakNode::BreakNode): + (JSC::ReturnNode::ReturnNode): + (JSC::WithNode::WithNode): + (JSC::LabelNode::LabelNode): + (JSC::ThrowNode::ThrowNode): + (JSC::TryNode::TryNode): + (JSC::FuncExprNode::FuncExprNode): + (JSC::FuncDeclNode::FuncDeclNode): + (JSC::SwitchNode::SwitchNode): + (JSC::ConstDeclNode::ConstDeclNode): + (JSC::BlockNode::BlockNode): + (JSC::ForInNode::ForInNode): + * parser/Nodes.cpp: + (JSC::StatementNode::setLoc): + (JSC): + (JSC::ScopeNode::ScopeNode): + (JSC::ProgramNode::ProgramNode): + (JSC::ProgramNode::create): + (JSC::EvalNode::EvalNode): + (JSC::EvalNode::create): + (JSC::FunctionBodyNode::FunctionBodyNode): + (JSC::FunctionBodyNode::create): + * parser/Nodes.h: + (Node): + (JSC::Node::columnNo): + (ExpressionNode): + (StatementNode): + (JSC::StatementNode::column): + (NullNode): + (BooleanNode): + (NumberNode): + (StringNode): + (RegExpNode): + (ThisNode): + (ResolveNode): + (ArrayNode): + (PropertyListNode): + (ObjectLiteralNode): + (BracketAccessorNode): + (DotAccessorNode): + (ArgumentListNode): + (NewExprNode): + (EvalFunctionCallNode): + (FunctionCallValueNode): + (FunctionCallResolveNode): + (FunctionCallBracketNode): + (FunctionCallDotNode): + (CallFunctionCallDotNode): + (ApplyFunctionCallDotNode): + (PrePostResolveNode): + (PostfixResolveNode): + (PostfixBracketNode): + (PostfixDotNode): + (PostfixErrorNode): + (DeleteResolveNode): + (DeleteBracketNode): + (DeleteDotNode): + (DeleteValueNode): + (VoidNode): + (TypeOfResolveNode): + (TypeOfValueNode): + (PrefixResolveNode): + (PrefixBracketNode): + (PrefixDotNode): + (PrefixErrorNode): + (UnaryOpNode): + (UnaryPlusNode): + (NegateNode): + (BitwiseNotNode): + (LogicalNotNode): + (BinaryOpNode): + (MultNode): + (DivNode): + (ModNode): + (AddNode): + (SubNode): + (LeftShiftNode): + (RightShiftNode): + (UnsignedRightShiftNode): + (LessNode): + (GreaterNode): + (LessEqNode): + (GreaterEqNode): + (ThrowableBinaryOpNode): + (InstanceOfNode): + (InNode): + (EqualNode): + (NotEqualNode): + (StrictEqualNode): + (NotStrictEqualNode): + (BitAndNode): + (BitOrNode): + (BitXOrNode): + (LogicalOpNode): + (ConditionalNode): + (ReadModifyResolveNode): + (AssignResolveNode): + (ReadModifyBracketNode): + (AssignBracketNode): + (AssignDotNode): + (ReadModifyDotNode): + (AssignErrorNode): + (CommaNode): + (ConstDeclNode): + (ConstStatementNode): + (BlockNode): + (EmptyStatementNode): + (DebuggerStatementNode): + (ExprStatementNode): + (VarStatementNode): + (IfNode): + (IfElseNode): + (DoWhileNode): + (WhileNode): + (ForNode): + (ForInNode): + (ContinueNode): + (BreakNode): + (ReturnNode): + (WithNode): + (LabelNode): + (ThrowNode): + (TryNode): + (ScopeNode): + (ProgramNode): + (EvalNode): + (FunctionBodyNode): + (FuncExprNode): + (FuncDeclNode): + (SwitchNode): + * parser/Parser.cpp: + (JSC::::parseSourceElements): + (JSC::::parseVarDeclaration): + (JSC::::parseConstDeclaration): + (JSC::::parseDoWhileStatement): + (JSC::::parseWhileStatement): + (JSC::::parseVarDeclarationList): + (JSC::::parseConstDeclarationList): + (JSC::::parseForStatement): + (JSC::::parseBreakStatement): + (JSC::::parseContinueStatement): + (JSC::::parseReturnStatement): + (JSC::::parseThrowStatement): + (JSC::::parseWithStatement): + (JSC::::parseSwitchStatement): + (JSC::::parseTryStatement): + (JSC::::parseDebuggerStatement): + (JSC::::parseBlockStatement): + (JSC::::parseStatement): + (JSC::::parseFunctionBody): + (JSC::::parseFunctionInfo): + (JSC::::parseFunctionDeclaration): + (JSC::::parseExpressionOrLabelStatement): + (JSC::::parseExpressionStatement): + (JSC::::parseIfStatement): + (JSC::::parseExpression): + (JSC::::parseAssignmentExpression): + (JSC::::parseConditionalExpression): + (JSC::::parseBinaryExpression): + (JSC::::parseProperty): + (JSC::::parseObjectLiteral): + (JSC::::parseStrictObjectLiteral): + (JSC::::parseArrayLiteral): + (JSC::::parsePrimaryExpression): + (JSC::::parseArguments): + (JSC::::parseMemberExpression): + (JSC::::parseUnaryExpression): + * parser/Parser.h: + (JSC::Parser::next): + (JSC::Parser::nextExpectIdentifier): + (JSC::Parser::tokenStart): + (JSC::Parser::tokenLine): + (JSC::Parser::tokenEnd): + (JSC::Parser::tokenLocation): + (Parser): + (JSC::Parser::getTokenName): + (JSC::::parse): + * parser/ParserTokens.h: + (JSC::JSTokenLocation::JSTokenLocation): + (JSTokenLocation): + (JSToken): + * parser/SourceProviderCacheItem.h: + (JSC::SourceProviderCacheItem::closeBraceToken): + * parser/SyntaxChecker.h: + (JSC::SyntaxChecker::makeFunctionCallNode): + (JSC::SyntaxChecker::createCommaExpr): + (JSC::SyntaxChecker::makeAssignNode): + (JSC::SyntaxChecker::makePrefixNode): + (JSC::SyntaxChecker::makePostfixNode): + (JSC::SyntaxChecker::makeTypeOfNode): + (JSC::SyntaxChecker::makeDeleteNode): + (JSC::SyntaxChecker::makeNegateNode): + (JSC::SyntaxChecker::makeBitwiseNotNode): + (JSC::SyntaxChecker::createLogicalNot): + (JSC::SyntaxChecker::createUnaryPlus): + (JSC::SyntaxChecker::createVoid): + (JSC::SyntaxChecker::thisExpr): + (JSC::SyntaxChecker::createResolve): + (JSC::SyntaxChecker::createObjectLiteral): + (JSC::SyntaxChecker::createArray): + (JSC::SyntaxChecker::createNumberExpr): + (JSC::SyntaxChecker::createString): + (JSC::SyntaxChecker::createBoolean): + (JSC::SyntaxChecker::createNull): + (JSC::SyntaxChecker::createBracketAccess): + (JSC::SyntaxChecker::createDotAccess): + (JSC::SyntaxChecker::createRegExp): + (JSC::SyntaxChecker::createNewExpr): + (JSC::SyntaxChecker::createConditionalExpr): + (JSC::SyntaxChecker::createAssignResolve): + (JSC::SyntaxChecker::createFunctionExpr): + (JSC::SyntaxChecker::createFunctionBody): + (JSC::SyntaxChecker::createArgumentsList): + (JSC::SyntaxChecker::createPropertyList): + (JSC::SyntaxChecker::createFuncDeclStatement): + (JSC::SyntaxChecker::createBlockStatement): + (JSC::SyntaxChecker::createExprStatement): + (JSC::SyntaxChecker::createIfStatement): + (JSC::SyntaxChecker::createForLoop): + (JSC::SyntaxChecker::createForInLoop): + (JSC::SyntaxChecker::createEmptyStatement): + (JSC::SyntaxChecker::createVarStatement): + (JSC::SyntaxChecker::createReturnStatement): + (JSC::SyntaxChecker::createBreakStatement): + (JSC::SyntaxChecker::createContinueStatement): + (JSC::SyntaxChecker::createTryStatement): + (JSC::SyntaxChecker::createSwitchStatement): + (JSC::SyntaxChecker::createWhileStatement): + (JSC::SyntaxChecker::createWithStatement): + (JSC::SyntaxChecker::createDoWhileStatement): + (JSC::SyntaxChecker::createLabelStatement): + (JSC::SyntaxChecker::createThrowStatement): + (JSC::SyntaxChecker::createDebugger): + (JSC::SyntaxChecker::createConstStatement): + (JSC::SyntaxChecker::appendConstDecl): + (JSC::SyntaxChecker::createGetterOrSetterProperty): + (JSC::SyntaxChecker::combineCommaNodes): + (JSC::SyntaxChecker::operatorStackPop): + +2012-08-01 Filip Pizlo <fpizlo@apple.com> + + DFG should hoist structure checks + https://bugs.webkit.org/show_bug.cgi?id=92696 + + Reviewed by Gavin Barraclough. + + This hoists structure checks in the same way that we would hoist array checks, but with added + complexity to cope with the fact that the structure of an object may change. This is handled + by performing a side effects analysis over the region in which the respective variable is + live. If a structure clobbering side effect may happen then we either hoist the structure + checks and fall back on structure transition watchpoints (if the watchpoint set is still + valid), or we avoid hoisting altogether. + + Doing this required teaching the CFA that we may have an expectation that an object has a + particular structure even after structure clobbering happens, in the sense that structure + proofs that were cobbered can be revived using watchpoints. CFA must know about this so that + OSR entry may know about it, since we cannot allow entry to happen if the variable has a + clobbered structure proof, will have a watchpoint to revive the proof, and the variable in + the baseline JIT has a completely unrelated structure. + + This is mostly performance neutral. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/ValueRecovery.h: + (JSC::ValueRecovery::isSet): + (JSC::ValueRecovery::operator!): + (ValueRecovery): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + (JSC::DFG::AbstractState::clobberWorld): + (DFG): + (JSC::DFG::AbstractState::clobberCapturedVars): + * dfg/DFGAbstractState.h: + (AbstractState): + * dfg/DFGAbstractValue.h: + (JSC::DFG::AbstractValue::clear): + (JSC::DFG::AbstractValue::isClear): + (JSC::DFG::AbstractValue::makeTop): + (JSC::DFG::AbstractValue::isTop): + (JSC::DFG::AbstractValue::set): + (JSC::DFG::AbstractValue::operator==): + (JSC::DFG::AbstractValue::merge): + (JSC::DFG::AbstractValue::filter): + (JSC::DFG::AbstractValue::validate): + (JSC::DFG::AbstractValue::validateForEntry): + (AbstractValue): + (JSC::DFG::AbstractValue::checkConsistency): + (JSC::DFG::AbstractValue::dump): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::setLocal): + (JSC::DFG::ByteCodeParser::getArgument): + (JSC::DFG::ByteCodeParser::setArgument): + (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::fixVariableAccessSpeculations): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::checkStructureLoadElimination): + (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): + (JSC::DFG::CSEPhase::putStructureStoreElimination): + (JSC::DFG::CSEPhase::getLocalLoadElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::dump): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::vote): + (Graph): + * dfg/DFGNode.h: + (JSC::DFG::Node::convertToStructureTransitionWatchpoint): + (Node): + (JSC::DFG::Node::hasStructureSet): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOSREntry.cpp: + (JSC::DFG::prepareOSREntry): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + (PredictionPropagationPhase): + (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): + (JSC::DFG::SpeculativeJIT::speculationCheckWithConditionalDirection): + (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecutionWithConditionalDirection): + (JSC::DFG::SpeculateCellOperand::SpeculateCellOperand): + (JSC::DFG::SpeculateCellOperand::gpr): + (SpeculateCellOperand): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::fillSpeculateCell): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::fillSpeculateCell): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGStructureCheckHoistingPhase.cpp: Added. + (DFG): + (StructureCheckHoistingPhase): + (JSC::DFG::StructureCheckHoistingPhase::StructureCheckHoistingPhase): + (JSC::DFG::StructureCheckHoistingPhase::run): + (JSC::DFG::StructureCheckHoistingPhase::noticeStructureCheck): + (JSC::DFG::StructureCheckHoistingPhase::noticeClobber): + (JSC::DFG::StructureCheckHoistingPhase::clobber): + (CheckData): + (JSC::DFG::StructureCheckHoistingPhase::CheckData::CheckData): + (JSC::DFG::performStructureCheckHoisting): + * dfg/DFGStructureCheckHoistingPhase.h: Added. + (DFG): + * dfg/DFGVariableAccessData.h: + (VariableAccessData): + (JSC::DFG::VariableAccessData::VariableAccessData): + (JSC::DFG::VariableAccessData::mergeStructureCheckHoistingFailed): + (JSC::DFG::VariableAccessData::structureCheckHoistingFailed): + (JSC::DFG::VariableAccessData::clearVotes): + (JSC::DFG::VariableAccessData::vote): + (JSC::DFG::VariableAccessData::voteRatio): + (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote): + * runtime/Options.h: + (JSC): + +2012-08-01 Filip Pizlo <fpizlo@apple.com> + + DFG should distinguish between PutByVal's that clobber the world and ones that don't + https://bugs.webkit.org/show_bug.cgi?id=92923 + + Reviewed by Mark Hahnenberg. + + This is performance-neutral. I also confirmed that it's neutral if we make the + clobbering variant (PutByValSafe) clobber all knowledge of what is an array, + which should feed nicely into work on removing uses of ClassInfo. + + * bytecode/DFGExitProfile.h: + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getByValLoadElimination): + (JSC::DFG::CSEPhase::checkStructureLoadElimination): + (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): + (JSC::DFG::CSEPhase::getByOffsetLoadElimination): + (JSC::DFG::CSEPhase::putByOffsetStoreElimination): + (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::byValIsPure): + (JSC::DFG::Graph::clobbersWorld): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-08-01 Jian Li <jianli@chromium.org> + + Add new CSS property "-webkit-widget-region" to expose dashboard region support for other port + https://bugs.webkit.org/show_bug.cgi?id=90298 + + Reviewed by Adam Barth. + + * Configurations/FeatureDefines.xcconfig: Add ENABLE_WIDGET_REGION define. + +2012-08-01 Patrick Gansterer <paroga@webkit.org> + + Replace WTF::getCurrentLocalTime() with GregorianDateTime::setToCurrentLocalTime() + https://bugs.webkit.org/show_bug.cgi?id=92286 + + Reviewed by Geoffrey Garen. + + Add a method to GregorianDateTime to set its values to the current locale time. + Replacing all occurrences of getCurrentLocalTime with the new function allows + us to remove getCurrentLocalTime in a next step. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-08-01 Mark Hahnenberg <mhahnenberg@apple.com> + + C++ code should get ClassInfo from the Structure + https://bugs.webkit.org/show_bug.cgi?id=92892 + + Reviewed by Geoffrey Garen. + + In our march to remove ClassInfo from our JSCell object headers, we can switch + C++ code over to grabbing the ClassInfo from the Structure since it is finally + safe to do so now that Structure access is safe during finalization/destruction. + The remaining JIT code changes can be done in a separate patch. + + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::callDestructor): We don't want to clear the Structure any more + since the Structure should still be valid at this point. + * heap/WeakSetInlines.h: + (JSC::WeakBlock::finalize): Ditto. + * runtime/JSCell.h: + (JSC): + * runtime/Structure.h: + (JSC::JSCell::classInfo): Move JSCell's classInfo() to Structure.h so it can be + inline. Use a different method of getting the JSCell's Structure based on + whether we're in GC_VALIDATION mode or not, since always using get() will cause + infinite recursion in GC_VALIDATION mode. + (JSC): + +2012-07-31 Mark Hahnenberg <mhahnenberg@apple.com> + + MarkedBlock::sweep() should sweep another block if it can't sweep a Structure block + https://bugs.webkit.org/show_bug.cgi?id=92819 + + Reviewed by Geoffrey Garen. + + If we are forced to allocate a new block for Structures because we are unable to safely + sweep our pre-existing Structure blocks, we should sweep another random block so that we + can start sweeping Structure blocks sooner. + + * heap/IncrementalSweeper.cpp: + (JSC::IncrementalSweeper::doSweep): Change to use sweepNextBlock. + (JSC): + (JSC::IncrementalSweeper::sweepNextBlock): + * heap/IncrementalSweeper.h: + (IncrementalSweeper): + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::tryAllocateHelper): When we can't safely sweep + our Structure blocks, call sweepNextBlock instead. + +2012-07-31 Sam Weinig <sam@webkit.org> + + Fix the Windows build. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-07-31 Geoffrey Garen <ggaren@apple.com> + + Maybe fix the GCC build. + + * heap/HeapBlock.h: + (HeapBlock): Accommodate incorrect parsing in GCC. + +2012-07-31 Sam Weinig <sam@webkit.org> + + Stop masking 8 bits off of the visited link hash. We need all the bits! + https://bugs.webkit.org/show_bug.cgi?id=92799 + + Reviewed by Anders Carlsson. + + * runtime/Identifier.cpp: + (JSC::IdentifierCStringTranslator::hash): + (JSC::IdentifierLCharFromUCharTranslator::hash): + * runtime/Identifier.h: + (JSC::IdentifierCharBufferTranslator::hash): + Update for new function names. + +2012-07-31 Geoffrey Garen <ggaren@apple.com> + + Maybe break the Windows build. + + Reviewed by Anders Carlsson. + + Formally objected to by Sam Weinig. + + * heap/HeapBlock.h: + (HeapBlock): Try to slightly improve this because we don't want Windows to control our lives. + +2012-07-30 Mark Hahnenberg <mhahnenberg@apple.com> + + Structures should be swept after all other objects + https://bugs.webkit.org/show_bug.cgi?id=92679 + + Reviewed by Filip Pizlo. + + In order to get rid of ClassInfo from our objects, we need to be able to safely get the + ClassInfo during the destruction of objects. We'd like to get the ClassInfo out of the + Structure, but currently it is not safe to do so because the order of destruction of objects + is not guaranteed to sweep objects before their corresponding Structure. We can fix this by + sweeping Structures after everything else. + + * heap/Heap.cpp: + (JSC::Heap::isSafeToSweepStructures): Add a function that checks if it is safe to sweep Structures. + If the Heap's IncrementalSweeper member is null, that means we're shutting down this VM and it is + safe to sweep structures since we'll always do Structures last anyways due to the ordering of + MarkedSpace::forEachBlock. + (JSC): + (JSC::Heap::didStartVMShutdown): Add this intermediate function to the Heap that ~JSGlobalData now + calls rather than calling the two HeapTimer objects individually. This allows the Heap to null out + these pointers after it has invalidated them to prevent accidental use-after-free in the sweep() + calls during lastChanceToFinalize(). + * heap/Heap.h: + (Heap): + * heap/HeapTimer.h: + (HeapTimer): + * heap/IncrementalSweeper.cpp: + (JSC::IncrementalSweeper::structuresCanBeSwept): Determines if it is currently safe to sweep Structures. + This decision is based on whether we have gotten to the end of the vector of blocks that need sweeping + the first time. + (JSC): + (JSC::IncrementalSweeper::doSweep): We add a second pass over the vector to sweep Structures after we + make our first pass. We now null out the slots as we sweep them so that we can quickly find the + Structures during the second pass. + (JSC::IncrementalSweeper::startSweeping): Initialize our new Structure sweeping index. + (JSC::IncrementalSweeper::willFinishSweeping): Callback that is called by MarkedSpace::sweep to notify + the IncrementalSweeper that we are going to sweep all of the remaining blocks in the Heap so it can + assume that everything is taken care of in the correct order. Since MarkedSpace::forEachBlock + iterates over the Structure blocks after all other blocks, the ordering property for sweeping Structures holds. + (JSC::IncrementalSweeper::IncrementalSweeper): Initialize Structure sweeping index. + * heap/IncrementalSweeper.h: Add declarations for new stuff. + (IncrementalSweeper): + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::tryAllocateHelper): We now check if the current block only contains structures and + if so and it isn't safe to sweep Structures according to the Heap, we just return early instead of doing + the normal lazy sweep. If this proves to be too much of a waste in the future we can add an extra clause that + will sweep some number of other blocks in place of the current block to mitigate the cost of the floating + Structure garbage. + (JSC::MarkedAllocator::addBlock): + * heap/MarkedAllocator.h: + (JSC::MarkedAllocator::zapFreeList): When we zap the free list in the MarkedAllocator, the current block is no + longer valid to allocate from, so we set the current block to null. + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::sweepHelper): Added a couple assertions to make sure that we weren't trying to sweep Structures + at an unsafe time. + * heap/MarkedSpace.cpp: + (JSC::MarkedSpace::sweep): Notify the IncrementalSweeper that the MarkedSpace will finish all currently remaining sweeping. + (JSC): + * heap/MarkedSpace.h: + (JSC): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::~JSGlobalData): Call the new Heap::didStartVMShutdown. + +2012-07-31 Geoffrey Garen <ggaren@apple.com> + + Fix all the other builds I just broke. Maybe fix the Windows build. + + * heap/HeapBlock.h: + (HeapBlock): WTF? + +2012-07-31 Geoffrey Garen <ggaren@apple.com> + + Maybe fix the Windows build. + + * heap/HeapBlock.h: + (HeapBlock): WTF? + +2012-07-31 Geoffrey Garen <ggaren@apple.com> + + Maybe fix the Windows build. + + * heap/HeapBlock.h: + (HeapBlock): WTF? + +2012-07-31 Geoffrey Garen <ggaren@apple.com> + + Removed some public data and casting from the Heap + https://bugs.webkit.org/show_bug.cgi?id=92777 + + Reviewed by Oliver Hunt. + + * heap/BlockAllocator.cpp: + (JSC::BlockAllocator::releaseFreeBlocks): + (JSC::BlockAllocator::blockFreeingThreadMain): Use the DeadBlock class + since HeapBlock is a template, and not a class, now. Call destroy() + instead of monkeying around with DeadBlock's internal data because + encapsulation is good. + + * heap/BlockAllocator.h: + (DeadBlock): Added a class to represent a dead block, since HeapBlock is + a template now, and can't be instantiated directly. + + (JSC::DeadBlock::DeadBlock): + (JSC::DeadBlock::create): + (BlockAllocator): + (JSC::BlockAllocator::allocate): + (JSC::BlockAllocator::deallocate): Use the DeadBlock class because + encapsulation is good. + + * heap/CopiedBlock.h: + (CopiedBlock::destroy): No need for a destroy() function, since we + inherit one now. + + (JSC::CopiedBlock::CopiedBlock): + (JSC::CopiedBlock::payloadEnd): + (JSC::CopiedBlock::capacity): Updated for some encapsulation inside + HeapBlock. + + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::~CopiedSpace): + (JSC::CopiedSpace::doneCopying): + (JSC::CopiedSpace::size): + (JSC::CopiedSpace::capacity): + (JSC::isBlockListPagedOut): Removed a bunch of casting. This is no longer + necessary, now that our list and its nodes have the right type. + + * heap/CopiedSpace.h: Use the right type in our data structures because + it improves clarity. + + * heap/CopiedSpaceInlineMethods.h: + (JSC::CopiedSpace::startedCopying): Use swap to avoid duplicating it. + + * heap/HeapBlock.h: + (HeapBlock): Made this a class template so we can return the right type + in linked list operations. Made our data private because encapsulation + is good. + + (JSC::HeapBlock::destroy): Since we know our type, we can also eliminate + duplicate destroy() functions in our subclasses. + + (JSC::HeapBlock::allocation): Added an accessor so we can hide our data. + By using const, this accessor prevents clients from accidentally deleting + our allocation. + + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::isPagedOut): + (JSC::MarkedAllocator::tryAllocateHelper): + (JSC::MarkedAllocator::removeBlock): Removed a bunch of casting. This is + no longer necessary, now that our list and its nodes have the right type. + + * heap/MarkedAllocator.h: + (MarkedAllocator): + (JSC::MarkedAllocator::reset): + (JSC::MarkedAllocator::forEachBlock): Use the right type, do less casting. + + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::destroy): Removed this function because our parent + class provides it for us now. + + (JSC::MarkedBlock::MarkedBlock): + * heap/MarkedBlock.h: + (MarkedBlock): + (JSC::MarkedBlock::capacity): Updated for encapsulation. + +2012-07-31 Filip Pizlo <fpizlo@apple.com> + + DFG OSR exit profiling has unusual oversights + https://bugs.webkit.org/show_bug.cgi?id=92728 + + Reviewed by Geoffrey Garen. + + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::speculationWatchpoint): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-07-31 Chao-ying Fu <fu@mips.com> + + Add MIPS add32 function + https://bugs.webkit.org/show_bug.cgi?id=91522 + + Reviewed by Oliver Hunt. + + Add isCompactPtrAlignedAddressOffset. + Add a new version of add32 that accepts AbsoluteAddress as inputs. + + * assembler/MacroAssemblerMIPS.h: + (JSC::MacroAssemblerMIPS::isCompactPtrAlignedAddressOffset): New. + (MacroAssemblerMIPS): + (JSC::MacroAssemblerMIPS::add32): Support AbsoluteAddress as inputs. + +2012-07-30 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r124123. + http://trac.webkit.org/changeset/124123 + https://bugs.webkit.org/show_bug.cgi?id=92700 + + ASSERT crashes terminate webkit Layout tests (Requested by + msaboff on #webkit). + + * heap/Heap.cpp: + * heap/Heap.h: + (Heap): + * heap/IncrementalSweeper.cpp: + (JSC::IncrementalSweeper::doSweep): + (JSC::IncrementalSweeper::startSweeping): + (JSC::IncrementalSweeper::IncrementalSweeper): + (JSC): + * heap/IncrementalSweeper.h: + (IncrementalSweeper): + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::tryAllocateHelper): + (JSC::MarkedAllocator::addBlock): + * heap/MarkedAllocator.h: + (JSC::MarkedAllocator::zapFreeList): + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::sweepHelper): + * heap/MarkedSpace.cpp: + * heap/MarkedSpace.h: + (JSC::MarkedSpace::sweep): + (JSC): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::~JSGlobalData): + +2012-07-30 Mark Hahnenberg <mhahnenberg@apple.com> + + Structures should be swept after all other objects + https://bugs.webkit.org/show_bug.cgi?id=92679 + + Reviewed by Filip Pizlo. + + In order to get rid of ClassInfo from our objects, we need to be able to safely get the + ClassInfo during the destruction of objects. We'd like to get the ClassInfo out of the + Structure, but currently it is not safe to do so because the order of destruction of objects + is not guaranteed to sweep objects before their corresponding Structure. We can fix this by + sweeping Structures after everything else. + + * heap/Heap.cpp: + (JSC::Heap::isSafeToSweepStructures): Add a function that checks if it is safe to sweep Structures. + If the Heap's IncrementalSweeper member is null, that means we're shutting down this VM and it is + safe to sweep structures since we'll always do Structures last anyways due to the ordering of + MarkedSpace::forEachBlock. + (JSC): + (JSC::Heap::didStartVMShutdown): Add this intermediate function to the Heap that ~JSGlobalData now + calls rather than calling the two HeapTimer objects individually. This allows the Heap to null out + these pointers after it has invalidated them to prevent accidental use-after-free in the sweep() + calls during lastChanceToFinalize(). + * heap/Heap.h: + (Heap): + * heap/HeapTimer.h: + (HeapTimer): + * heap/IncrementalSweeper.cpp: + (JSC::IncrementalSweeper::structuresCanBeSwept): Determines if it is currently safe to sweep Structures. + This decision is based on whether we have gotten to the end of the vector of blocks that need sweeping + the first time. + (JSC): + (JSC::IncrementalSweeper::doSweep): We add a second pass over the vector to sweep Structures after we + make our first pass. We now null out the slots as we sweep them so that we can quickly find the + Structures during the second pass. + (JSC::IncrementalSweeper::startSweeping): Initialize our new Structure sweeping index. + (JSC::IncrementalSweeper::willFinishSweeping): Callback that is called by MarkedSpace::sweep to notify + the IncrementalSweeper that we are going to sweep all of the remaining blocks in the Heap so it can + assume that everything is taken care of in the correct order. Since MarkedSpace::forEachBlock + iterates over the Structure blocks after all other blocks, the ordering property for sweeping Structures holds. + (JSC::IncrementalSweeper::IncrementalSweeper): Initialize Structure sweeping index. + * heap/IncrementalSweeper.h: Add declarations for new stuff. + (IncrementalSweeper): + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::tryAllocateHelper): We now check if the current block only contains structures and + if so and it isn't safe to sweep Structures according to the Heap, we just return early instead of doing + the normal lazy sweep. If this proves to be too much of a waste in the future we can add an extra clause that + will sweep some number of other blocks in place of the current block to mitigate the cost of the floating + Structure garbage. + (JSC::MarkedAllocator::addBlock): + * heap/MarkedAllocator.h: + (JSC::MarkedAllocator::zapFreeList): When we zap the free list in the MarkedAllocator, the current block is no + longer valid to allocate from, so we set the current block to null. + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::sweepHelper): Added a couple assertions to make sure that we weren't trying to sweep Structures + at an unsafe time. + * heap/MarkedSpace.cpp: + (JSC::MarkedSpace::sweep): Notify the IncrementalSweeper that the MarkedSpace will finish all currently remaining sweeping. + (JSC): + * heap/MarkedSpace.h: + (JSC): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::~JSGlobalData): Call the new Heap::didStartVMShutdown. + +2012-07-29 Filip Pizlo <fpizlo@apple.com> + + PropertyNameArray::m_shouldCache is only assigned and never used + https://bugs.webkit.org/show_bug.cgi?id=92598 + + Reviewed by Dan Bernstein. + + * runtime/PropertyNameArray.h: + (JSC::PropertyNameArray::PropertyNameArray): + (PropertyNameArray): + +2012-07-29 Rik Cabanier <cabanier@adobe.com> + + Add ENABLE_CSS_COMPOSITING flag + https://bugs.webkit.org/show_bug.cgi?id=92553 + + Reviewed by Dirk Schulze. + + Adds compiler flag CSS_COMPOSITING to build systems to enable CSS blending and compositing. See spec https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html + + * Configurations/FeatureDefines.xcconfig: + +2012-07-27 Mark Hahnenberg <mhahnenberg@apple.com> + + Split functionality of MarkedAllocator::m_currentBlock + https://bugs.webkit.org/show_bug.cgi?id=92550 + + Reviewed by Filip Pizlo. + + MarkedAllocator::m_currentBlock serves two purposes right now; it indicates the block that is currently + being used for allocation and the beginning of the list of blocks that need to be swept. We should split + these two functionalities into two separate fields. + + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::tryAllocateHelper): Use m_blocksToSweep instead of m_currentBlock as the + initializer/reference of the loop. Only change m_currentBlock when we know what the result will be. + (JSC::MarkedAllocator::addBlock): When we add a new block we know that both m_blocksToSweep and + m_currentBlock are null. In order to preserve the invariant that m_currentBlock <= m_blocksToSweep, + we assign both of them to point to the new block. + (JSC::MarkedAllocator::removeBlock): We need a separate check to see if the block we're removing is + m_blocksToSweep and if so, advance it to the next block in the list. + * heap/MarkedAllocator.h: + (MarkedAllocator): Initialize m_blocksToSweep. + (JSC::MarkedAllocator::MarkedAllocator): + (JSC::MarkedAllocator::reset): We set m_blocksToSweep to be the head of our list. This function is called + at the end of a collection, so all of the blocks in our allocator need to be swept. We need to sweep a + block before we can start allocating, so m_currentBlock is set to null. We also set the freeList to + the empty FreeList to emphasize the fact that we can't start allocating until we do some sweeping. + +2012-07-27 Mark Hahnenberg <mhahnenberg@apple.com> + + Increase inline storage for JSFinalObjects by one + https://bugs.webkit.org/show_bug.cgi?id=92526 + + Reviewed by Geoffrey Garen. + + Now that we've removed the inheritorID from objects, we can increase our inline storage for JSFinalObjects on + 64-bit platforms by 1. + + * llint/LowLevelInterpreter.asm: Change the constant. + * runtime/PropertyOffset.h: Change the constant. + (JSC): + +2012-07-27 Jer Noble <jer.noble@apple.com> + + Support a rational time class for use by media elements. + https://bugs.webkit.org/show_bug.cgi?id=88787 + + Re-export WTF::MediaTime from JavaScriptCore. + + Reviewed by Eric Carlson. + + * JavaScriptCore.order: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-07-26 Filip Pizlo <fpizlo@apple.com> + + JSObject::reallocateStorageIfNecessary is neither used nor defined + https://bugs.webkit.org/show_bug.cgi?id=92417 + + Reviewed by Mark Rowe. + + * runtime/JSObject.h: + (JSObject): + +2012-07-26 Mark Hahnenberg <mhahnenberg@apple.com> + + Allocate Structures in a separate part of the Heap + https://bugs.webkit.org/show_bug.cgi?id=92420 + + Reviewed by Filip Pizlo. + + To fix our issue with destruction/finalization of Structures before their objects, we can move Structures to a separate + part of the Heap that will be swept after all other objects. This first patch will just be separating Structures + out into their own separate MarkedAllocator. Everything else will behave identically. + + * heap/Heap.h: New function to allocate Structures in the Heap. + (Heap): + (JSC): + (JSC::Heap::allocateStructure): + * heap/MarkedAllocator.cpp: Pass whether or not we're allocated Structures to the MarkedBlock. + (JSC::MarkedAllocator::allocateBlock): + * heap/MarkedAllocator.h: Add tracking for whether or not we're allocating only Structures. + (JSC::MarkedAllocator::onlyContainsStructures): + (MarkedAllocator): + (JSC::MarkedAllocator::MarkedAllocator): + (JSC::MarkedAllocator::init): + * heap/MarkedBlock.cpp: Add tracking for whether or not we're allocating only Structures. We need this to be able to + distinguish the various MarkedBlock types in MarkedSpace::allocatorFor(MarkedBlock*). + (JSC::MarkedBlock::create): + (JSC::MarkedBlock::MarkedBlock): + * heap/MarkedBlock.h: + (MarkedBlock): + (JSC::MarkedBlock::onlyContainsStructures): + (JSC): + * heap/MarkedSpace.cpp: Include the new Structure allocator in all the places that all the other allocators are used/modified. + (JSC::MarkedSpace::MarkedSpace): + (JSC::MarkedSpace::resetAllocators): + (JSC::MarkedSpace::canonicalizeCellLivenessData): + (JSC::MarkedSpace::isPagedOut): + * heap/MarkedSpace.h: Add new MarkedAllocator just for Structures. + (MarkedSpace): + (JSC::MarkedSpace::allocatorFor): + (JSC::MarkedSpace::allocateStructure): + (JSC): + (JSC::MarkedSpace::forEachBlock): + * runtime/Structure.h: Move all of the functions that call allocateCell<Structure> down below the explicit template specialization + for allocateCell<Structure>. The new inline specialization for allocateCell directly calls the allocateStructure() function in the + Heap. + (Structure): + (JSC::Structure): + (JSC): + (JSC::Structure::create): + (JSC::Structure::createStructure): + +2012-07-26 Filip Pizlo <fpizlo@apple.com> + + JSArray has methods that are neither used nor defined + https://bugs.webkit.org/show_bug.cgi?id=92416 + + Reviewed by Simon Fraser. + + * runtime/JSArray.h: + (JSArray): + +2012-07-26 Zoltan Herczeg <zherczeg@webkit.org> + + [Qt][ARM]ARMAssembler needs buildfix afert r123417 + https://bugs.webkit.org/show_bug.cgi?id=92086 + + Reviewed by Csaba Osztrogonác. + + The ARM implementation of this should be optimized code path + is covered by a non-optimized code path. This patch fixes this, + and adds a new function which returns with the offset range. + + * assembler/ARMAssembler.h: + (JSC::ARMAssembler::readPointer): + (ARMAssembler): + (JSC::ARMAssembler::repatchInt32): + (JSC::ARMAssembler::repatchCompact): + * assembler/MacroAssemblerARM.h: + (MacroAssemblerARM): + (JSC::MacroAssemblerARM::isCompactPtrAlignedAddressOffset): + (JSC::MacroAssemblerARM::load32WithCompactAddressOffsetPatch): + +2012-07-25 Mark Hahnenberg <mhahnenberg@apple.com> + + Build fix for 32-bit after r123682 + + * runtime/JSObject.h: Need to pad out JSObjects on 32-bit so that they're the correct size since + we only removed one 4-byte word and we need to be 8-byte aligned. + (JSObject): + +2012-07-25 Filip Pizlo <fpizlo@apple.com> + + JSC GC object copying APIs should allow for greater flexibility + https://bugs.webkit.org/show_bug.cgi?id=92316 + + Reviewed by Mark Hahnenberg. + + It's now the case that visitChildren() methods can directly pin and allocate in new space during copying. + They can also do the copying and marking themselves. This new API is only used for JSObjects for now. + + * JavaScriptCore.xcodeproj/project.pbxproj: + * heap/MarkStack.cpp: + (JSC::SlotVisitor::allocateNewSpaceSlow): + (JSC::SlotVisitor::allocateNewSpaceOrPin): + (JSC): + (JSC::SlotVisitor::copyAndAppend): + * heap/MarkStack.h: + (MarkStack): + (JSC::MarkStack::appendUnbarrieredValue): + (JSC): + * heap/SlotVisitor.h: + * heap/SlotVisitorInlineMethods.h: Added. + (JSC): + (JSC::SlotVisitor::checkIfShouldCopyAndPinOtherwise): + (JSC::SlotVisitor::allocateNewSpace): + * runtime/JSObject.cpp: + (JSC::JSObject::visitOutOfLineStorage): + (JSC): + (JSC::JSObject::visitChildren): + (JSC::JSFinalObject::visitChildren): + * runtime/JSObject.h: + (JSObject): + +2012-07-25 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove JSObject::m_inheritorID + https://bugs.webkit.org/show_bug.cgi?id=88378 + + Reviewed by Filip Pizlo. + + This is rarely used, and not performance critical (the commonly accessed copy is cached on JSFunction), + and most objects don't need an inheritorID (this value is only used if the object is used as a prototype). + Instead use a private named value in the object's property storage. + + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): No need m_inheritorID to initialize! + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): No need m_inheritorID to initialize! + * llint/LowLevelInterpreter.asm: No need m_inheritorID to initialize! + * runtime/JSGlobalData.h: + (JSGlobalData): Added private name 'm_inheritorIDKey'. + * runtime/JSGlobalThis.cpp: + (JSC::JSGlobalThis::setUnwrappedObject): resetInheritorID is now passed a JSGlobalData&. + * runtime/JSObject.cpp: + (JSC::JSObject::visitChildren): No m_inheritorID to be marked. + (JSC::JSFinalObject::visitChildren): No m_inheritorID to be marked. + (JSC::JSObject::createInheritorID): Store the newly created inheritorID in the property map. Make sure + it's got the DontEnum attribute!! + * runtime/JSObject.h: + (JSObject): + (JSC::JSObject::resetInheritorID): Remove the inheritorID from property storage. + (JSC): + (JSC::JSObject::inheritorID): Read the inheritorID from property storage. + +2012-07-25 Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> + + Create a specialized pair for use in HashMap iterators + https://bugs.webkit.org/show_bug.cgi?id=92137 + + Reviewed by Ryosuke Niwa. + + Update a couple of sites that relied on the fact that "contents" of iterators were + std::pairs. + + * profiler/Profile.cpp: + (JSC): This code kept a vector of the pairs that were the "contents" of the iterators. This + is changed to use a KeyValuePair. We make use HashCount's ValueType (which represents only + the key) to get the proper key parameter for KeyValuePair. + * tools/ProfileTreeNode.h: + (ProfileTreeNode): Use HashMap::ValueType to declare the type of the contents of the hash + instead of declaring it manually. This will make use of the new KeyValuePair. + +2012-07-25 Patrick Gansterer <paroga@webkit.org> + + REGRESSION(r123505): Date.getYear() returns the same as Date.getFullYear() + https://bugs.webkit.org/show_bug.cgi?id=92218 + + Reviewed by Csaba Osztrogonác. + + * runtime/DatePrototype.cpp: + (JSC::dateProtoFuncGetYear): Added the missing offset of 1900 to the return value. + +2012-07-24 Filip Pizlo <fpizlo@apple.com> + + REGRESSION(r123417): It made tests assert/crash on 32 bit + https://bugs.webkit.org/show_bug.cgi?id=92088 + + Reviewed by Mark Hahnenberg. + + The pointer arithmetic was wrong, because negative numbers are hard to think about. + + * dfg/DFGRepatch.cpp: + (JSC::DFG::emitPutTransitionStub): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): + +2012-07-24 Patrick Gansterer <paroga@webkit.org> + + Store the full year in GregorianDateTime + https://bugs.webkit.org/show_bug.cgi?id=92067 + + Reviewed by Geoffrey Garen. + + Use the full year instead of the offset from year 1900 + for the year member variable of GregorianDateTime. + + * runtime/DateConstructor.cpp: + (JSC::constructDate): + (JSC::dateUTC): + * runtime/DateConversion.cpp: + (JSC::formatDate): + (JSC::formatDateUTCVariant): + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + (JSC::fillStructuresUsingDateArgs): + (JSC::dateProtoFuncToISOString): + (JSC::dateProtoFuncGetFullYear): + (JSC::dateProtoFuncGetUTCFullYear): + (JSC::dateProtoFuncSetYear): + * runtime/JSDateMath.cpp: + (JSC::gregorianDateTimeToMS): + (JSC::msToGregorianDateTime): + +2012-07-24 Patrick Gansterer <paroga@webkit.org> + + [WIN] Build fix after r123417. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + +2012-07-23 Patrick Gansterer <paroga@webkit.org> + + Move GregorianDateTime from JSC to WTF namespace + https://bugs.webkit.org/show_bug.cgi?id=91948 + + Reviewed by Geoffrey Garen. + + Moving GregorianDateTime into the WTF namespace allows us to us to + use it in WebCore too. The new class has the same behaviour as the + old struct. Only the unused timeZone member has been removed. + + * runtime/DateConstructor.cpp: + * runtime/DateConversion.cpp: + * runtime/DateConversion.h: + * runtime/DateInstance.h: + * runtime/DatePrototype.cpp: + * runtime/JSDateMath.cpp: + * runtime/JSDateMath.h: + +2012-07-23 Filip Pizlo <fpizlo@apple.com> + + Property storage should grow in reverse address direction, to support butterflies + https://bugs.webkit.org/show_bug.cgi?id=91788 + + Reviewed by Geoffrey Garen. + + Changes property storage to grow to the left, and changes the property storage pointer to point + one 8-byte word (i.e. JSValue) to the right of the first value in the storage. + + Also improved debug support somewhat, by adding a describe() function to the jsc command-line, + and a slow mode of object access in LLInt. + + * assembler/ARMv7Assembler.h: + (JSC::ARMv7Assembler::repatchCompact): + * assembler/MacroAssemblerARMv7.h: + (MacroAssemblerARMv7): + (JSC::MacroAssemblerARMv7::isCompactPtrAlignedAddressOffset): + (JSC::MacroAssemblerARMv7::load32WithCompactAddressOffsetPatch): + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::isCompactPtrAlignedAddressOffset): + (JSC::MacroAssemblerX86Common::repatchCompact): + * assembler/X86Assembler.h: + (JSC::X86Assembler::repatchCompact): + * bytecode/CodeBlock.cpp: + (JSC::dumpStructure): + * bytecode/GetByIdStatus.h: + (JSC::GetByIdStatus::GetByIdStatus): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGRepatch.cpp: + (JSC::DFG::tryCacheGetByID): + (JSC::DFG::emitPutTransitionStub): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): + (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * heap/ConservativeRoots.cpp: + (JSC::ConservativeRoots::genericAddPointer): + * heap/CopiedSpace.h: + (CopiedSpace): + * heap/CopiedSpaceInlineMethods.h: + (JSC::CopiedSpace::pinIfNecessary): + (JSC): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::compileGetDirectOffset): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::compileGetDirectOffset): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCacheGetByID): + * jsc.cpp: + (GlobalObject::finishCreation): + (functionDescribe): + * llint/LLIntCommon.h: + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/JSObject.cpp: + (JSC::JSObject::visitChildren): + (JSC::JSFinalObject::visitChildren): + (JSC::JSObject::growOutOfLineStorage): + * runtime/JSObject.h: + (JSC::JSObject::getDirectLocation): + (JSC::JSObject::offsetForLocation): + * runtime/JSValue.h: + (JSValue): + * runtime/PropertyOffset.h: + (JSC::offsetInOutOfLineStorage): + +2012-07-23 Filip Pizlo <fpizlo@apple.com> + + DFG is too aggressive in performing the specific value optimization on loads + https://bugs.webkit.org/show_bug.cgi?id=92034 + + Reviewed by Mark Hahnenberg. + + This ensures that we don't do optimizations based on a structure having a specific + value, if there is no way to detect that the value is despecified. This is the + case for dictionaries, since despecifying a value in a dictionary does not lead to + a transition and so cannot be caught by either structure checks or structure + transition watchpoints. + + * bytecode/GetByIdStatus.cpp: + (JSC::GetByIdStatus::computeFromLLInt): + (JSC::GetByIdStatus::computeForChain): + (JSC::GetByIdStatus::computeFor): + * bytecode/ResolveGlobalStatus.cpp: + (JSC::computeForStructure): + +2012-07-23 Filip Pizlo <fpizlo@apple.com> + + REGRESSION(r123169): It made fast/js/dfg-inline-arguments-use-from-uninlined-code.html fail on 32 bit platforms + https://bugs.webkit.org/show_bug.cgi?id=92002 + + Reviewed by Mark Hahnenberg. + + In the process of changing the nature of local variable typing, I forgot to modify one of the places where + we glue the DFG's notion of variable prediction to the runtime's notion of variable tagging. + + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-07-23 Simon Fraser <simon.fraser@apple.com> + + Part 2 of: Implement sticky positioning + https://bugs.webkit.org/show_bug.cgi?id=90046 + + Reviewed by Ojan Vafai. + + Turn on ENABLE_CSS_STICKY_POSITION. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-23 Patrick Gansterer <paroga@webkit.org> + + Move JSC::parseDate() from DateConversion to JSDateMath + https://bugs.webkit.org/show_bug.cgi?id=91982 + + Reviewed by Geoffrey Garen. + + Moveing this function into the other files removes the dependency + on JSC spcific classes in DateConversion.{cpp|h}. + + * runtime/DateConversion.cpp: + * runtime/DateConversion.h: + (JSC): + * runtime/JSDateMath.cpp: + (JSC::parseDate): + (JSC): + * runtime/JSDateMath.h: + (JSC): + +2012-07-23 Simon Fraser <simon.fraser@apple.com> + + Part 1 of: Implement sticky positioning + https://bugs.webkit.org/show_bug.cgi?id=90046 + + Reviewed by Ojan Vafai. + + Add ENABLE_CSS_STICKY_POSITION, defaulting to off initially. + + Sort the ENABLE_CSS lines in the file. Make sure all the flags + are in FEATURE_DEFINES. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-23 Yong Li <yoli@rim.com> + + [BlackBerry] Implement GCActivityCallback with platform timer + https://bugs.webkit.org/show_bug.cgi?id=90175 + + Reviewed by Rob Buis. + + Use JSLock when performing GC to avoid assertions. + + * runtime/GCActivityCallbackBlackBerry.cpp: + (JSC::DefaultGCActivityCallback::doWork): + +2012-07-23 Kent Tamura <tkent@chromium.org> + + Rename ENABLE_METER_TAG and ENABLE_PROGRESS_TAG to ENABLE_METER_ELEMENT and ENABLE_PROGRESS_ELEMENT respectively + https://bugs.webkit.org/show_bug.cgi?id=91941 + + Reviewed by Kentaro Hara. + + A flag name for an elmement should be ENABLE_*_ELEMENT. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-22 Kent Tamura <tkent@chromium.org> + + Rename ENABLE_DETAILS to ENABLE_DETAILS_ELEMENT + https://bugs.webkit.org/show_bug.cgi?id=91928 + + Reviewed by Kentaro Hara. + + A flag name for an elmement should be ENABLE_*_ELEMENT. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-21 Patrick Gansterer <paroga@webkit.org> + + [WIN] Use GetDateFormat and GetTimeFormat instead of strftime + https://bugs.webkit.org/show_bug.cgi?id=83436 + + Reviewed by Brent Fulgham. + + The MS CRT implementation of strftime calls the same two functions. + Using them directly avoids the overhead of parsing the format string and removes + the dependency on strftime() for WinCE where this function does not exist. + + * runtime/DatePrototype.cpp: + (JSC::formatLocaleDate): + +2012-07-20 Kent Tamura <tkent@chromium.org> + + Rename ENABLE_DATALIST to ENABLE_DATALIST_ELEMENT + https://bugs.webkit.org/show_bug.cgi?id=91846 + + Reviewed by Kentaro Hara. + + A flag name for an elmement should be ENABLE_*_ELEMENT. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-20 Han Shen <shenhan@google.com> + + [Chromium] Compilation fails under gcc 4.7 + https://bugs.webkit.org/show_bug.cgi?id=90227 + + Reviewed by Tony Chang. + + Disable warnings about c++0x compatibility in gcc newer than 4.6. + + * JavaScriptCore.gyp/JavaScriptCore.gyp: + +2012-07-18 Filip Pizlo <fpizlo@apple.com> + + DFG cell checks should be hoisted + https://bugs.webkit.org/show_bug.cgi?id=91717 + + Reviewed by Geoffrey Garen. + + The DFG has always had the policy of hoisting array and integer checks to + the point of variable assignment. Eventually, we added doubles and booleans + to the mix. But cells should really be part of this as well, particularly + for 32-bit where accessing a known-type variable is dramatically cheaper + than accessing a variable whose types is only predicted but otherwise + unproven. + + This appears to be a definite speed-up for V8 on 32-bit, a possible speed-up + for Kraken, and a possible slow-down for V8 on 64-bit (around 0.2% if at + all). Any slow-downs can, and should, be addressed by making the hoisting + logic cognizant of variables that are never used in a manner that requires + type checks, and by sinking argument checks to the point(s) of first use. + + To make this work I had to change some OSR machinery, and special-case the + type predictions of the 'this' argument for constructors. OSR exit normally + assumes that arguments are boxed, which happens to be true because the + type prediction used for check hoisting is LUB'd with the type of the + argument that was passed in - so either the arguments are always stored to + with the full tag+payload, or if only the payload is stored then the tag + matches whatever the caller would have set. But not so with the 'this' + argument for constructors, which is not initialized by the caller. We + could make this more precise by having argument types for OSR be inferred + using similar machinery to other locals, but I figured that for this patch + I should use the surgical fix. + + * assembler/MacroAssemblerX86_64.h: + (JSC::MacroAssemblerX86_64::branchTestPtr): + (MacroAssemblerX86_64): + * assembler/X86Assembler.h: + (JSC::X86Assembler::testq_rm): + (X86Assembler): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::initialize): + (JSC::DFG::AbstractState::execute): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::isCreatedThisArgument): + (Graph): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::checkArgumentTypes): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGValueSource.h: + (JSC::DFG::ValueSource::forSpeculation): + +2012-07-19 Filip Pizlo <fpizlo@apple.com> + + Fast path of storage resize should be removed from property storage reallocation, since it is only useful for arrays + https://bugs.webkit.org/show_bug.cgi?id=91796 + + Reviewed by Geoffrey Garen. + + * dfg/DFGRepatch.cpp: + (JSC::DFG::emitPutTransitionStub): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): + * runtime/JSObject.cpp: + (JSC::JSObject::growOutOfLineStorage): + +2012-07-19 Mark Lam <mark.lam@apple.com> + + Bug fixes and enhancements for OfflineASM annotation system. + https://bugs.webkit.org/show_bug.cgi?id=91690 + + Reviewed by Filip Pizlo. + + * offlineasm/armv7.rb: added default handling of Instruction lower(). + * offlineasm/asm.rb: added more support for annotations and more pretty printing. + * offlineasm/ast.rb: added more support for annotations. + * offlineasm/config.rb: added $preferredCommentStartColumn, simplified $enableInstrAnnotations. + * offlineasm/parser.rb: added more support for annotations. + * offlineasm/transform.rb: added more support for annotations. + * offlineasm/x86.rb: added default handling of Instruction lower(). + +2012-07-19 Patrick Gansterer <paroga@webkit.org> + + [WIN] Fix compilation of JSGlobalData.h with ENABLE(DFG_JIT) + https://bugs.webkit.org/show_bug.cgi?id=91243 + + Reviewed by Geoffrey Garen. + + Disable MSVC warning 4200 "zero-sized array in struct/union" for JSC::ScratchBuffer. + + * runtime/JSGlobalData.h: + (JSC): + +2012-07-19 Mark Lam <mark.lam@apple.com> + + Fixed broken ENABLE_JIT=0 build. + https://bugs.webkit.org/show_bug.cgi?id=91725 + + Reviewed by Oliver Hunt. + + * bytecode/Watchpoint.cpp: + * heap/JITStubRoutineSet.h: + (JSC): + (JITStubRoutineSet): + (JSC::JITStubRoutineSet::JITStubRoutineSet): + (JSC::JITStubRoutineSet::~JITStubRoutineSet): + (JSC::JITStubRoutineSet::add): + (JSC::JITStubRoutineSet::clearMarks): + (JSC::JITStubRoutineSet::mark): + (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): + (JSC::JITStubRoutineSet::traceMarkedStubRoutines): + +2012-07-19 Kristóf Kosztyó <kkristof@inf.u-szeged.hu> + + [Qt] Unreviewed buildfix after r123042. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::dumpRegisters): + +2012-07-18 Filip Pizlo <fpizlo@apple.com> + + DFG should emit inline code for property storage (re)allocation + https://bugs.webkit.org/show_bug.cgi?id=91597 + + Reviewed by Oliver Hunt. + + This adds two new ops to the DFG IR: AllocatePropertyStorage and + ReallocatePropertyStorage. It enables these to interact properly with + CSE so that a GetPropertyStorage on something for which we have + obviously done a (Re)AllocatePropertyStorage will result in the + GetPropertyStorage being eliminated. Other than that, the code + emitted for these ops is identical to the code we were emitting in + the corresponding PutById stub. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::putStructureStoreElimination): + (JSC::DFG::CSEPhase::getPropertyStorageLoadElimination): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasStructureTransitionData): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): + (DFG): + (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * runtime/Structure.cpp: + (JSC::nextOutOfLineStorageCapacity): + * runtime/Structure.h: + (JSC): + +2012-07-16 Oliver Hunt <oliver@apple.com> + + dumpCallFrame is broken in ToT + https://bugs.webkit.org/show_bug.cgi?id=91444 + + Reviewed by Gavin Barraclough. + + Various changes have been made to the SF calling convention, but + dumpCallFrame has not been updated to reflect these changes. + That resulted in both bogus information, as well as numerous + assertions of sadness. + + This patch makes dumpCallFrame actually work again and adds the + wonderful feature of telling you the name of the variable that a + register reflects, or what value it contains. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::nameForRegister): + A really innefficient mechanism for finding the name of a local register. + This should only ever be used by debug code so this should be okay. + * bytecode/CodeBlock.h: + (CodeBlock): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::generate): + Debug builds no longer throw away a functions symbol table, this allows + us to actually perform a register# to name mapping + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + We weren't propogating the bytecode offset here leading to assertions + in debug builds when dumping bytecode of DFG compiled code. + * interpreter/Interpreter.cpp: + (JSC): + (JSC::Interpreter::dumpRegisters): + Rework to actually be correct. + (JSC::getCallerInfo): + Return the byteocde offset as well now, given we have to determine it + anyway. + (JSC::Interpreter::getStackTrace): + (JSC::Interpreter::retrieveCallerFromVMCode): + * interpreter/Interpreter.h: + (Interpreter): + * jsc.cpp: + (GlobalObject::finishCreation): + (functionDumpCallFrame): + Give debug builds of JSC a method for calling dumpCallFrame so we can + inspect a callframe without requiring us to break in a debugger. + +2012-07-18 Filip Pizlo <fpizlo@apple.com> + + DFG 32-bit PutById transition stub storage reallocation case copies the first pointer of each JSValue instead of the whole JSValue + https://bugs.webkit.org/show_bug.cgi?id=91599 + + Reviewed by Geoffrey Garen. + + * dfg/DFGRepatch.cpp: + (JSC::DFG::emitPutTransitionStub): + +2012-07-17 Filip Pizlo <fpizlo@apple.com> + + DFG 32-bit PutById transition stub passes the payload/tag arguments to a DFG operation in the wrong order + https://bugs.webkit.org/show_bug.cgi?id=91576 + + Reviewed by Gavin Barraclough. + + * dfg/DFGRepatch.cpp: + (JSC::DFG::emitPutTransitionStub): + +2012-07-17 Filip Pizlo <fpizlo@apple.com> + + [Qt] REGRESSION(r122768, r122771): They broke jquery/data.html and inspector/elements/edit-dom-actions.html + https://bugs.webkit.org/show_bug.cgi?id=91476 + + Reviewed by Mark Hahnenberg. + + The 32-bit repatching code was not correctly adapted to the new world where there may not always + be an available scratch register. Fixed it by ensuring that the scratch register we select does + not overlap with the value tag. + + * dfg/DFGRepatch.cpp: + (JSC::DFG::generateProtoChainAccessStub): + (JSC::DFG::tryCacheGetByID): + (JSC::DFG::tryBuildGetByIDList): + (JSC::DFG::emitPutReplaceStub): + +2012-07-17 Gabor Rapcsanyi <rgabor@webkit.org> + + Unreviewed buildfix from Zoltan Herczeg after 122768. + + * dfg/DFGCCallHelpers.h: + (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): + (CCallHelpers): + +2012-07-17 David Barr <davidbarr@chromium.org> + + Introduce ENABLE_CSS_IMAGE_ORIENTATION compile flag + https://bugs.webkit.org/show_bug.cgi?id=89055 + + Reviewed by Kent Tamura. + + The css3-images module is at candidate recommendation. + http://www.w3.org/TR/2012/CR-css3-images-20120417/#the-image-orientation + + Add a configuration option for CSS image-orientation support, disabling it by default. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-16 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, roll out 122790 because it broke the Windows build. I'm not + sure what to do with exported symbols that are predicated on NDEBUG. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * bytecode/CodeBlock.cpp: + (JSC): + * bytecode/CodeBlock.h: + (CodeBlock): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::generate): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + * interpreter/Interpreter.cpp: + (JSC): + (JSC::Interpreter::dumpRegisters): + (JSC::getCallerInfo): + (JSC::Interpreter::getStackTrace): + (JSC::Interpreter::retrieveCallerFromVMCode): + * interpreter/Interpreter.h: + (Interpreter): + * jsc.cpp: + (GlobalObject::finishCreation): + +2012-07-16 Oliver Hunt <oliver@apple.com> + + dumpCallFrame is broken in ToT + https://bugs.webkit.org/show_bug.cgi?id=91444 + + Reviewed by Gavin Barraclough. + + Various changes have been made to the SF calling convention, but + dumpCallFrame has not been updated to reflect these changes. + That resulted in both bogus information, as well as numerous + assertions of sadness. + + This patch makes dumpCallFrame actually work again and adds the + wonderful feature of telling you the name of the variable that a + register reflects, or what value it contains. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::nameForRegister): + A really innefficient mechanism for finding the name of a local register. + This should only ever be used by debug code so this should be okay. + * bytecode/CodeBlock.h: + (CodeBlock): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::generate): + Debug builds no longer throw away a functions symbol table, this allows + us to actually perform a register# to name mapping + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + We weren't propogating the bytecode offset here leading to assertions + in debug builds when dumping bytecode of DFG compiled code. + * interpreter/Interpreter.cpp: + (JSC): + (JSC::Interpreter::dumpRegisters): + Rework to actually be correct. + (JSC::getCallerInfo): + Return the byteocde offset as well now, given we have to determine it + anyway. + (JSC::Interpreter::getStackTrace): + (JSC::Interpreter::retrieveCallerFromVMCode): + * interpreter/Interpreter.h: + (Interpreter): + * jsc.cpp: + (GlobalObject::finishCreation): + (functionDumpCallFrame): + Give debug builds of JSC a method for calling dumpCallFrame so we can + inspect a callframe without requiring us to break in a debugger. + +2012-07-16 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, adding forgotten files. + + * dfg/DFGRegisterSet.h: Added. + (DFG): + (RegisterSet): + (JSC::DFG::RegisterSet::RegisterSet): + (JSC::DFG::RegisterSet::asPOD): + (JSC::DFG::RegisterSet::copyInfo): + (JSC::DFG::RegisterSet::set): + (JSC::DFG::RegisterSet::setGPRByIndex): + (JSC::DFG::RegisterSet::clear): + (JSC::DFG::RegisterSet::get): + (JSC::DFG::RegisterSet::getGPRByIndex): + (JSC::DFG::RegisterSet::getFreeGPR): + (JSC::DFG::RegisterSet::setFPRByIndex): + (JSC::DFG::RegisterSet::getFPRByIndex): + (JSC::DFG::RegisterSet::setByIndex): + (JSC::DFG::RegisterSet::getByIndex): + (JSC::DFG::RegisterSet::numberOfSetGPRs): + (JSC::DFG::RegisterSet::numberOfSetFPRs): + (JSC::DFG::RegisterSet::numberOfSetRegisters): + (JSC::DFG::RegisterSet::setBit): + (JSC::DFG::RegisterSet::clearBit): + (JSC::DFG::RegisterSet::getBit): + * dfg/DFGScratchRegisterAllocator.h: Added. + (DFG): + (ScratchRegisterAllocator): + (JSC::DFG::ScratchRegisterAllocator::ScratchRegisterAllocator): + (JSC::DFG::ScratchRegisterAllocator::lock): + (JSC::DFG::ScratchRegisterAllocator::allocateScratch): + (JSC::DFG::ScratchRegisterAllocator::allocateScratchGPR): + (JSC::DFG::ScratchRegisterAllocator::allocateScratchFPR): + (JSC::DFG::ScratchRegisterAllocator::didReuseRegisters): + (JSC::DFG::ScratchRegisterAllocator::preserveReusedRegistersByPushing): + (JSC::DFG::ScratchRegisterAllocator::restoreReusedRegistersByPopping): + (JSC::DFG::ScratchRegisterAllocator::desiredScratchBufferSize): + (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer): + (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer): + +2012-07-15 Filip Pizlo <fpizlo@apple.com> + + DFG PutById transition should handle storage allocation, and inline it + https://bugs.webkit.org/show_bug.cgi?id=91337 + + Reviewed by Oliver Hunt. + + This enables the patching of DFG PutById to handle the out-of-line storage + allocation case. Furthermore, it inlines out-of-line storage allocation (and + reallocation) into the generated stubs. + + To do this, this patch adds the ability to store the relevant register + allocation state (i.e. the set of in-use registers) in the structure stub + info so that the stub generation code can more flexibly select scratch + registers: sometimes it needs none, sometimes one - or sometimes up to + three. Moreover, to make the stub generation register allocation simple and + maintainable, this patch introduces a reusable scratch register allocator + class. This register allocator understands that some registers are in use by + the main path code and so must be spilled as necessary, other registers are + locked for use in the stub itself and so cannot even be spilled, while still + others may be allocated for scratch purposes. A scratch register that is + used must be spilled. If a register is locked, it cannot be used as a + scratch register. If a register is used, it can be used as a scratch + register so long as it is spilled. + + This is a sub-1% speed-up on V8 and neutral elsewhere. + + * GNUmakefile.list.am: + * JavaScriptCore.xcodeproj/project.pbxproj: + * assembler/MacroAssemblerCodeRef.h: + (FunctionPtr): + (JSC::FunctionPtr::FunctionPtr): + * bytecode/StructureStubInfo.h: + * dfg/DFGCCallHelpers.h: + (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): + (CCallHelpers): + * dfg/DFGGPRInfo.h: + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + * dfg/DFGJITCompiler.h: + (JSC::DFG::PropertyAccessRecord::PropertyAccessRecord): + (PropertyAccessRecord): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGRegisterBank.h: + (JSC::DFG::RegisterBank::isInUse): + (RegisterBank): + * dfg/DFGRegisterSet.h: Added. + (DFG): + (RegisterSet): + (JSC::DFG::RegisterSet::RegisterSet): + (JSC::DFG::RegisterSet::asPOD): + (JSC::DFG::RegisterSet::copyInfo): + (JSC::DFG::RegisterSet::set): + (JSC::DFG::RegisterSet::setGPRByIndex): + (JSC::DFG::RegisterSet::clear): + (JSC::DFG::RegisterSet::get): + (JSC::DFG::RegisterSet::getGPRByIndex): + (JSC::DFG::RegisterSet::getFreeGPR): + (JSC::DFG::RegisterSet::setFPRByIndex): + (JSC::DFG::RegisterSet::getFPRByIndex): + (JSC::DFG::RegisterSet::setByIndex): + (JSC::DFG::RegisterSet::getByIndex): + (JSC::DFG::RegisterSet::numberOfSetGPRs): + (JSC::DFG::RegisterSet::numberOfSetFPRs): + (JSC::DFG::RegisterSet::numberOfSetRegisters): + (JSC::DFG::RegisterSet::setBit): + (JSC::DFG::RegisterSet::clearBit): + (JSC::DFG::RegisterSet::getBit): + * dfg/DFGRepatch.cpp: + (JSC::DFG::generateProtoChainAccessStub): + (JSC::DFG::tryCacheGetByID): + (JSC::DFG::tryBuildGetByIDList): + (JSC::DFG::emitPutReplaceStub): + (JSC::DFG::emitPutTransitionStub): + (JSC::DFG::tryCachePutByID): + (JSC::DFG::tryBuildPutByIdList): + * dfg/DFGScratchRegisterAllocator.h: Added. + (DFG): + (ScratchRegisterAllocator): + (JSC::DFG::ScratchRegisterAllocator::ScratchRegisterAllocator): + (JSC::DFG::ScratchRegisterAllocator::lock): + (JSC::DFG::ScratchRegisterAllocator::allocateScratch): + (JSC::DFG::ScratchRegisterAllocator::allocateScratchGPR): + (JSC::DFG::ScratchRegisterAllocator::allocateScratchFPR): + (JSC::DFG::ScratchRegisterAllocator::didReuseRegisters): + (JSC::DFG::ScratchRegisterAllocator::preserveReusedRegistersByPushing): + (JSC::DFG::ScratchRegisterAllocator::restoreReusedRegistersByPopping): + (JSC::DFG::ScratchRegisterAllocator::desiredScratchBufferSize): + (JSC::DFG::ScratchRegisterAllocator::preserveUsedRegistersToScratchBuffer): + (JSC::DFG::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBuffer): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::usedRegisters): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::cachedGetById): + (JSC::DFG::SpeculativeJIT::cachedPutById): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::cachedGetById): + (JSC::DFG::SpeculativeJIT::cachedPutById): + (JSC::DFG::SpeculativeJIT::compile): + * heap/CopiedAllocator.h: + (CopiedAllocator): + (JSC::CopiedAllocator::fastPathShouldSucceed): + (JSC): + +2012-07-16 Patrick Gansterer <paroga@webkit.org> + + Add dfg switch to create_jit_stubs script + https://bugs.webkit.org/show_bug.cgi?id=91256 + + Reviewed by Geoffrey Garen. + + * create_jit_stubs: Add a switch to enable or disable the generation of + stub functions in #if ENABLE(DFG_JIT) conditions. + +2012-07-16 Gabor Rapcsanyi <rgabor@webkit.org> + + Unreviewed buildfix after r122729. Typo fix. + + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::add32): + +2012-07-16 Gabor Rapcsanyi <rgabor@webkit.org> + + Unreviewed buildfix from Zoltan Herczeg after r122677. + Implement missing add32 function to MacroAssemblerARM. + + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::add32): + (MacroAssemblerARM): + +2012-07-14 Filip Pizlo <fpizlo@apple.com> + + DFG PutByVal opcodes should accept more than 3 operands + https://bugs.webkit.org/show_bug.cgi?id=91332 + + Reviewed by Oliver Hunt. + + Turned PutByVal/PutByValAlias into var-arg nodes, so that we can give them + 4 or more operands in the future. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getByValLoadElimination): + (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + (JSC::DFG::FixupPhase::fixDoubleEdge): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::byValIsPure): + (JSC::DFG::Graph::varArgNumChildren): + (Graph): + (JSC::DFG::Graph::numChildren): + (JSC::DFG::Graph::varArgChild): + (JSC::DFG::Graph::child): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): + (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-07-14 Filip Pizlo <fpizlo@apple.com> + + Rationalize and optimize storage allocation + https://bugs.webkit.org/show_bug.cgi?id=91303 + + Reviewed by Oliver Hunt. + + This implements a backwards bump allocator for copied space storage + allocation, shown in pseudo-code below: + + pointer bump(size) { + pointer tmp = allocator->remaining; + tmp -= size; + if (tmp < 0) + fail; + allocator->remaining = tmp; + return allocator->payloadEnd - tmp - size; + } + + The advantage of this allocator is that it: + + - Only requires one comparison in the common case where size is known to + not be huge, and this comparison can be done by checking the sign bit + of the subtraction. + + - Can be implemented even when only one register is available. This + register is reused for both temporary storage during allocation and + for the result. + + - Preserves the behavior that memory in a block is filled in from lowest + address to highest address, which allows for a cheap reallocation fast + path. + + - Is resilient against the block used for allocation being the last one + in virtual memory, thereby otherwise leading to the risk of overflow + in the bump pointer, despite only doing one branch. + + In order to implement this allocator using the smallest possible chunk + of code, I refactored the copied space code so that all of the allocation + logic is in CopiedAllocator, and all of the state is in either + CopiedBlock or CopiedAllocator. This should make changing the allocation + fast path easier in the future. + + In order to do this, I needed to add some new assembler support, + particularly for various forms of add(address, register) and negPtr(). + + This is performance neutral. The purpose of this change is to facilitate + further inlining of storage allocation without having to reserve + additional registers or emit too much code. + + * assembler/MacroAssembler.h: + (JSC::MacroAssembler::addPtr): + (MacroAssembler): + (JSC::MacroAssembler::negPtr): + * assembler/MacroAssemblerARMv7.h: + (MacroAssemblerARMv7): + (JSC::MacroAssemblerARMv7::add32): + * assembler/MacroAssemblerX86.h: + (JSC::MacroAssemblerX86::add32): + (MacroAssemblerX86): + * assembler/MacroAssemblerX86_64.h: + (MacroAssemblerX86_64): + (JSC::MacroAssemblerX86_64::addPtr): + (JSC::MacroAssemblerX86_64::negPtr): + * assembler/X86Assembler.h: + (X86Assembler): + (JSC::X86Assembler::addl_mr): + (JSC::X86Assembler::addq_mr): + (JSC::X86Assembler::negq_r): + * heap/CopiedAllocator.h: + (CopiedAllocator): + (JSC::CopiedAllocator::isValid): + (JSC::CopiedAllocator::CopiedAllocator): + (JSC::CopiedAllocator::tryAllocate): + (JSC): + (JSC::CopiedAllocator::tryReallocate): + (JSC::CopiedAllocator::forceAllocate): + (JSC::CopiedAllocator::resetCurrentBlock): + (JSC::CopiedAllocator::setCurrentBlock): + (JSC::CopiedAllocator::currentCapacity): + * heap/CopiedBlock.h: + (CopiedBlock): + (JSC::CopiedBlock::create): + (JSC::CopiedBlock::zeroFillWilderness): + (JSC::CopiedBlock::CopiedBlock): + (JSC::CopiedBlock::payloadEnd): + (JSC): + (JSC::CopiedBlock::payloadCapacity): + (JSC::CopiedBlock::data): + (JSC::CopiedBlock::dataEnd): + (JSC::CopiedBlock::dataSize): + (JSC::CopiedBlock::wilderness): + (JSC::CopiedBlock::wildernessEnd): + (JSC::CopiedBlock::wildernessSize): + (JSC::CopiedBlock::size): + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::tryAllocateSlowCase): + (JSC::CopiedSpace::tryAllocateOversize): + (JSC::CopiedSpace::tryReallocate): + (JSC::CopiedSpace::doneFillingBlock): + (JSC::CopiedSpace::doneCopying): + * heap/CopiedSpace.h: + (CopiedSpace): + * heap/CopiedSpaceInlineMethods.h: + (JSC::CopiedSpace::startedCopying): + (JSC::CopiedSpace::allocateBlockForCopyingPhase): + (JSC::CopiedSpace::allocateBlock): + (JSC::CopiedSpace::tryAllocate): + (JSC): + * heap/MarkStack.cpp: + (JSC::SlotVisitor::startCopying): + (JSC::SlotVisitor::allocateNewSpace): + (JSC::SlotVisitor::doneCopying): + * heap/SlotVisitor.h: + (JSC::SlotVisitor::SlotVisitor): + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicStorage): + (JSC::JIT::emitAllocateJSArray): + +2012-07-13 Mark Lam <mark.lam@apple.com> + + OfflineASM Pretty printing and commenting enhancements. + https://bugs.webkit.org/show_bug.cgi?id=91281 + + Reviewed by Filip Pizlo. + + Added some minor pretty printing in the OfflineASM. + Also added infrastruture for adding multiple types of comments and + annotations with the ability to enable/disable them in the generated + output as desired. + + * GNUmakefile.list.am: add new file config.rb. + * llint/LLIntOfflineAsmConfig.h: + Added OFFLINE_ASM_BEGIN, OFFLINE_ASM_END, and OFFLINE_ASM_LOCAL_LABEL macros. + This will allow us to redefine these for other backends later. + * llint/LowLevelInterpreter32_64.asm: + Add a small example of instruction annotations for now. + * llint/LowLevelInterpreter64.asm: + Add a small example of instruction annotations for now. + * offlineasm/armv7.rb: Added handling of annotations. + * offlineasm/asm.rb: + Added machinery to dump the new comments and annotations. + Also added some indentations to make the output a little prettier. + * offlineasm/ast.rb: Added annotation field in class Instruction. + * offlineasm/backends.rb: + * offlineasm/config.rb: Added. + Currently only contains commenting options. This file is meant to be + a centralized place for build config values much like config.h for + JavaScriptCore. + * offlineasm/generate_offset_extractor.rb: + * offlineasm/instructions.rb: + * offlineasm/offsets.rb: + * offlineasm/opt.rb: + * offlineasm/parser.rb: Parse and record annotations. + * offlineasm/registers.rb: + * offlineasm/self_hash.rb: + * offlineasm/settings.rb: + * offlineasm/transform.rb: + * offlineasm/x86.rb: Added handling of annotations. + +2012-07-13 Filip Pizlo <fpizlo@apple.com> + + ASSERTION FAILED: use.useKind() != DoubleUse + https://bugs.webkit.org/show_bug.cgi?id=91082 + + Reviewed by Geoffrey Garen. + + The implementation of Branch() was unwisely relying on register allocation state + to decide what speculations to perform. That's never correct. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-07-13 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122640. + http://trac.webkit.org/changeset/122640 + https://bugs.webkit.org/show_bug.cgi?id=91298 + + LLInt apparently does not expect to mark these (Requested by + olliej on #webkit). + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::visitStructures): + (JSC::CodeBlock::stronglyVisitStrongReferences): + +2012-07-13 Oliver Hunt <oliver@apple.com> + + LLInt fails to mark structures stored in the bytecode + https://bugs.webkit.org/show_bug.cgi?id=91296 + + Reviewed by Geoffrey Garen. + + LLInt stores structures in the bytecode, so we need to visit the appropriate + instructions as we would if we were running in the classic interpreter. + This requires adding additional checks for the LLInt specific opcodes, and + the lint specific variants of operand ordering. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::visitStructures): + (JSC::CodeBlock::stronglyVisitStrongReferences): + +2012-07-13 Yong Li <yoli@rim.com> + + [BlackBerry] Implement GCActivityCallback with platform timer + https://bugs.webkit.org/show_bug.cgi?id=90175 + + Reviewed by Rob Buis. + + Implement GCActivityCallback and HeapTimer for BlackBerry port. + + * heap/HeapTimer.cpp: + (JSC): + (JSC::HeapTimer::HeapTimer): + (JSC::HeapTimer::~HeapTimer): + (JSC::HeapTimer::timerDidFire): + (JSC::HeapTimer::synchronize): + (JSC::HeapTimer::invalidate): + (JSC::HeapTimer::didStartVMShutdown): + * heap/HeapTimer.h: + (HeapTimer): + * runtime/GCActivityCallbackBlackBerry.cpp: + (JSC): + (JSC::DefaultGCActivityCallback::doWork): + (JSC::DefaultGCActivityCallback::didAllocate): + (JSC::DefaultGCActivityCallback::willCollect): + (JSC::DefaultGCActivityCallback::cancel): + +2012-07-13 Patrick Gansterer <paroga@webkit.org> + + [WIN] Fix compilation of DFGRepatch.cpp + https://bugs.webkit.org/show_bug.cgi?id=91241 + + Reviewed by Geoffrey Garen. + + Use intptr_t instead of uintptr_t when calling CodeLocationCommon::dataLabelPtrAtOffset(int) + to fix MSVC "unary minus operator applied to unsigned type, result still unsigned" warning. + + * dfg/DFGRepatch.cpp: + (JSC::DFG::dfgResetGetByID): + (JSC::DFG::dfgResetPutByID): + +2012-07-13 Patrick Gansterer <paroga@webkit.org> + + Fix ARM_TRADITIONAL JIT for COMPILER(MSVC) and COMPILER(RVCT) after r121885 + https://bugs.webkit.org/show_bug.cgi?id=91238 + + Reviewed by Zoltan Herczeg. + + r121885 changed the assembler instruction only for COMPILER(GCC). + Use the same instructions for the other compilers too. + + * jit/JITStubs.cpp: + (JSC::ctiTrampoline): + (JSC::ctiTrampolineEnd): + (JSC::ctiVMThrowTrampoline): + +2012-07-12 Filip Pizlo <fpizlo@apple.com> + + DFG property access stubs should use structure transition watchpoints + https://bugs.webkit.org/show_bug.cgi?id=91135 + + Reviewed by Geoffrey Garen. + + This adds a Watchpoint subclass that will clear a structure stub (i.e. + a property access stub) when fired. The DFG stub generation code now + uses this optimization. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/CodeBlock.cpp: + (JSC): + (JSC::CodeBlock::finalizeUnconditionally): + (JSC::CodeBlock::resetStub): + (JSC::CodeBlock::resetStubInternal): + * bytecode/CodeBlock.h: + (JSC): + (CodeBlock): + * bytecode/StructureStubClearingWatchpoint.cpp: Added. + (JSC): + (JSC::StructureStubClearingWatchpoint::~StructureStubClearingWatchpoint): + (JSC::StructureStubClearingWatchpoint::push): + (JSC::StructureStubClearingWatchpoint::fireInternal): + (JSC::WatchpointsOnStructureStubInfo::~WatchpointsOnStructureStubInfo): + (JSC::WatchpointsOnStructureStubInfo::addWatchpoint): + (JSC::WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint): + * bytecode/StructureStubClearingWatchpoint.h: Added. + (JSC): + (StructureStubClearingWatchpoint): + (JSC::StructureStubClearingWatchpoint::StructureStubClearingWatchpoint): + (WatchpointsOnStructureStubInfo): + (JSC::WatchpointsOnStructureStubInfo::WatchpointsOnStructureStubInfo): + (JSC::WatchpointsOnStructureStubInfo::codeBlock): + (JSC::WatchpointsOnStructureStubInfo::stubInfo): + * bytecode/StructureStubInfo.h: + (JSC::StructureStubInfo::reset): + (JSC::StructureStubInfo::addWatchpoint): + (StructureStubInfo): + * dfg/DFGRepatch.cpp: + (JSC::DFG::addStructureTransitionCheck): + (DFG): + (JSC::DFG::generateProtoChainAccessStub): + (JSC::DFG::emitPutTransitionStub): + * jit/JumpReplacementWatchpoint.h: + +2012-07-12 Filip Pizlo <fpizlo@apple.com> + + DFG CFA may get overzealous in loops that have code that must exit + https://bugs.webkit.org/show_bug.cgi?id=91188 + + Reviewed by Gavin Barraclough. + + Ensure that if the CFA assumes that an operation must exit, then it will always exit + no matter what happens after. That's necessary to preserve soundness. + + Remove a broken fixup done by the DFG simplifier, where it was trying to say that the + variable-at-head was the first access in the second block in the merge, if the first + block did not read the variable. That's totally wrong, if the first block was in fact + doing a phantom read. I removed that fixup and instead hardened the rest of the + compiler. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::endBasicBlock): + * dfg/DFGBasicBlock.h: + (JSC::DFG::BasicBlock::BasicBlock): + (BasicBlock): + * dfg/DFGCFAPhase.cpp: + (JSC::DFG::CFAPhase::performBlockCFA): + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::mergeBlocks): + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::ConstantFoldingPhase): + (JSC::DFG::ConstantFoldingPhase::run): + (ConstantFoldingPhase): + (JSC::DFG::ConstantFoldingPhase::foldConstants): + (JSC::DFG::ConstantFoldingPhase::paintUnreachableCode): + * dfg/DFGVariableEventStream.cpp: + (JSC::DFG::VariableEventStream::reconstruct): + +2012-07-12 Allan Sandfeld Jensen <allan.jensen@nokia.com> + + [Qt] Implement MemoryUsageSupport + https://bugs.webkit.org/show_bug.cgi?id=91094 + + Reviewed by Adam Barth. + + Compile in MemoryStatistics so we can make use of the interface. + + * Target.pri: + +2012-07-12 Csaba Osztrogonác <ossy@webkit.org> + + Remove dead code after r122392. + https://bugs.webkit.org/show_bug.cgi?id=91049 + + Reviewed by Filip Pizlo. + + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::emitCall): + +2012-07-11 Adenilson Cavalcanti <cavalcantii@gmail.com> + + Build fix + remove dead code + https://bugs.webkit.org/show_bug.cgi?id=91039 + + Reviewed by Filip Pizlo. + + An unused variable was breaking compilation (thanks to warnings being treated as errors). + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::emitCall): + +2012-07-11 Mark Rowe <mrowe@apple.com> + + <http://webkit.org/b/91024> Build against the latest SDK when targeting older OS X versions. + + Reviewed by Dan Bernstein. + + The deployment target is already set to the version that we're targeting, and it's that setting + which determines which functionality from the SDK is available to us. + + * Configurations/Base.xcconfig: + +2012-07-11 Filip Pizlo <fpizlo@apple.com> + + DFG should have fast virtual calls + https://bugs.webkit.org/show_bug.cgi?id=90924 + + Reviewed by Gavin Barraclough. + + Implements virtual call support in the style of the old JIT, with the + caveat that we still use the same slow path for both InternalFunction + calls and JSFunction calls. Also rationalized the way that our + CodeOrigin indices tie into exception checks (previously it was a + strange one-to-one mapping with fairly limited assertions; now it's a + one-to-many mapping for CodeOrigins to exception checks, respectively). + I also took the opportunity to clean up + CallLinkInfo::callReturnLocation, which previously was either a Call or + a NearCall. Now it's just a NearCall. As well, exceptions during slow + path call resolution are now handled by returning an exception throwing + thunk rather than returning null. And finally, I made a few things + public that were previously private-with-lots-of-friends, because I + truly despise the thought of listing each thunk generating function as + a friend of JSValue and friends. + + * bytecode/CallLinkInfo.cpp: + (JSC::CallLinkInfo::unlink): + * bytecode/CallLinkInfo.h: + (CallLinkInfo): + * bytecode/CodeOrigin.h: + (JSC::CodeOrigin::CodeOrigin): + (JSC::CodeOrigin::isSet): + * dfg/DFGAssemblyHelpers.h: + (JSC::DFG::AssemblyHelpers::AssemblyHelpers): + * dfg/DFGCCallHelpers.h: + (JSC::DFG::CCallHelpers::CCallHelpers): + * dfg/DFGGPRInfo.h: + (GPRInfo): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + (JSC::DFG::JITCompiler::compileFunction): + * dfg/DFGJITCompiler.h: + (JSC::DFG::CallBeginToken::CallBeginToken): + (JSC::DFG::CallBeginToken::~CallBeginToken): + (CallBeginToken): + (JSC::DFG::CallBeginToken::set): + (JSC::DFG::CallBeginToken::registerWithExceptionCheck): + (JSC::DFG::CallBeginToken::codeOrigin): + (JSC::DFG::CallExceptionRecord::CallExceptionRecord): + (CallExceptionRecord): + (JSC::DFG::JITCompiler::currentCodeOriginIndex): + (JITCompiler): + (JSC::DFG::JITCompiler::beginCall): + (JSC::DFG::JITCompiler::notifyCall): + (JSC::DFG::JITCompiler::prepareForExceptionCheck): + (JSC::DFG::JITCompiler::addExceptionCheck): + (JSC::DFG::JITCompiler::addFastExceptionCheck): + * dfg/DFGOperations.cpp: + * dfg/DFGRepatch.cpp: + (JSC::DFG::dfgLinkFor): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheck): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::emitCall): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::emitCall): + * dfg/DFGThunks.cpp: + (JSC::DFG::emitPointerValidation): + (DFG): + (JSC::DFG::throwExceptionFromCallSlowPathGenerator): + (JSC::DFG::slowPathFor): + (JSC::DFG::linkForThunkGenerator): + (JSC::DFG::linkCallThunkGenerator): + (JSC::DFG::linkConstructThunkGenerator): + (JSC::DFG::virtualForThunkGenerator): + (JSC::DFG::virtualCallThunkGenerator): + (JSC::DFG::virtualConstructThunkGenerator): + * dfg/DFGThunks.h: + (DFG): + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + (JSC::JIT::linkFor): + * runtime/Executable.h: + (ExecutableBase): + (JSC::ExecutableBase::offsetOfJITCodeFor): + (JSC::ExecutableBase::offsetOfNumParametersFor): + * runtime/JSValue.h: + (JSValue): + +2012-07-11 Filip Pizlo <fpizlo@apple.com> + + Accidentally used the wrong license (3-clause instead of 2-clause) in some + files I just committed. + + Rubber stamped by Oliver Hunt. + + * bytecode/Watchpoint.cpp: + * bytecode/Watchpoint.h: + * jit/JumpReplacementWatchpoint.cpp: + * jit/JumpReplacementWatchpoint.h: + +2012-07-11 Filip Pizlo <fpizlo@apple.com> + + Watchpoints and jump replacement should be decoupled + https://bugs.webkit.org/show_bug.cgi?id=91016 + + Reviewed by Oliver Hunt. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * assembler/AbstractMacroAssembler.h: + (JSC): + (Label): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::appendWatchpoint): + (JSC::CodeBlock::watchpoint): + (DFGData): + * bytecode/Watchpoint.cpp: + (JSC): + * bytecode/Watchpoint.h: + (JSC::Watchpoint::Watchpoint): + (Watchpoint): + (JSC::Watchpoint::fire): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::speculationWatchpoint): + * jit/JumpReplacementWatchpoint.cpp: Added. + (JSC): + (JSC::JumpReplacementWatchpoint::correctLabels): + (JSC::JumpReplacementWatchpoint::fireInternal): + * jit/JumpReplacementWatchpoint.h: Added. + (JSC): + (JumpReplacementWatchpoint): + (JSC::JumpReplacementWatchpoint::JumpReplacementWatchpoint): + (JSC::JumpReplacementWatchpoint::setDestination): + +2012-07-11 Kevin Ollivier <kevino@theolliviers.com> + + [wx] Unreviewed build fix. Don't try to build udis86_itab.c since it's included by + another file. + + * wscript: + +2012-07-11 Chao-ying Fu <fu@mips.com> + + Add MIPS convertibleLoadPtr and other functions + https://bugs.webkit.org/show_bug.cgi?id=90714 + + Reviewed by Oliver Hunt. + + * assembler/MIPSAssembler.h: + (JSC::MIPSAssembler::labelIgnoringWatchpoints): + (MIPSAssembler): + (JSC::MIPSAssembler::replaceWithLoad): + (JSC::MIPSAssembler::replaceWithAddressComputation): + * assembler/MacroAssemblerMIPS.h: + (JSC::MacroAssemblerMIPS::convertibleLoadPtr): + (MacroAssemblerMIPS): + +2012-07-11 Anders Carlsson <andersca@apple.com> + + Add -Wtautological-compare and -Wsign-compare warning flags + https://bugs.webkit.org/show_bug.cgi?id=90994 + + Reviewed by Mark Rowe. + + * Configurations/Base.xcconfig: + +2012-07-11 Benjamin Poulain <bpoulain@apple.com> + + Simplify the copying of JSC ARMv7's LinkRecord + https://bugs.webkit.org/show_bug.cgi?id=90930 + + Reviewed by Filip Pizlo. + + The class LinkRecord is used by value everywhere in ARMv7Assembler. The compiler uses + memmove() to move the objects. + + The problem is memmove() is overkill for this object, moving the value can be done with + 3 load-store. This patch adds an operator= to the class doing more efficient copying. + This reduces the link time by 19%. + + * assembler/ARMv7Assembler.h: + (JSC::ARMv7Assembler::LinkRecord::LinkRecord): + (JSC::ARMv7Assembler::LinkRecord::operator=): + (JSC::ARMv7Assembler::LinkRecord::from): + (JSC::ARMv7Assembler::LinkRecord::setFrom): + (JSC::ARMv7Assembler::LinkRecord::to): + (JSC::ARMv7Assembler::LinkRecord::type): + (JSC::ARMv7Assembler::LinkRecord::linkType): + (JSC::ARMv7Assembler::LinkRecord::setLinkType): + (JSC::ARMv7Assembler::LinkRecord::condition): + +2012-07-11 Andy Wingo <wingo@igalia.com> + + jsc: Parse options before creating global data + https://bugs.webkit.org/show_bug.cgi?id=90975 + + Reviewed by Filip Pizlo. + + This patch moves the options parsing in "jsc" before the creation + of the JSGlobalData, so that --useJIT=no has a chance to take + effect. + + * jsc.cpp: + (CommandLine::parseArguments): Refactor to be a class, and take + argc and argv as constructor arguments. + (jscmain): Move arg parsing before JSGlobalData creation. + +2012-07-10 Filip Pizlo <fpizlo@apple.com> + + REGRESSION(r122166): It made 170 tests crash on 32 bit platforms + https://bugs.webkit.org/show_bug.cgi?id=90852 + + Reviewed by Zoltan Herczeg. + + If we can't use the range filter, we should still make sure that the + address is remotely sane, otherwise the hashtables will assert. + + * jit/JITStubRoutine.h: + (JSC::JITStubRoutine::passesFilter): + +2012-07-10 Filip Pizlo <fpizlo@apple.com> + + DFG recompilation heuristics should be based on count, not rate + https://bugs.webkit.org/show_bug.cgi?id=90146 + + Reviewed by Oliver Hunt. + + Rolling r121511 back in after fixing the DFG's interpretation of op_div + profiling, with Gavin's rubber stamp. + + This removes a bunch of code that was previously trying to prevent spurious + reoptimizations if a large enough majority of executions of a code block did + not result in OSR exit. It turns out that this code was purely harmful. This + patch removes all of that logic and replaces it with a dead-simple + heuristic: if you exit more than N times (where N is an exponential function + of the number of times the code block has already been recompiled) then we + will recompile. + + This appears to be a broad ~1% win on many benchmarks large and small. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::CodeBlock): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::couldTakeSpecialFastCase): + (CodeBlock): + (JSC::CodeBlock::osrExitCounter): + (JSC::CodeBlock::countOSRExit): + (JSC::CodeBlock::addressOfOSRExitCounter): + (JSC::CodeBlock::offsetOfOSRExitCounter): + (JSC::CodeBlock::adjustedExitCountThreshold): + (JSC::CodeBlock::exitCountThresholdForReoptimization): + (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop): + (JSC::CodeBlock::shouldReoptimizeNow): + (JSC::CodeBlock::shouldReoptimizeFromLoopNow): + * bytecode/ExecutionCounter.cpp: + (JSC::ExecutionCounter::setThreshold): + * bytecode/ExecutionCounter.h: + (ExecutionCounter): + (JSC::ExecutionCounter::clippedThreshold): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::makeDivSafe): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::compileBody): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): + * dfg/DFGOSRExitCompiler.cpp: + (JSC::DFG::OSRExitCompiler::handleExitCounts): + * dfg/DFGOperations.cpp: + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/Options.h: + (JSC): + +2012-07-09 Matt Falkenhagen <falken@chromium.org> + + Add ENABLE_DIALOG_ELEMENT and skeleton files + https://bugs.webkit.org/show_bug.cgi?id=90521 + + Reviewed by Kent Tamura. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-09 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, roll out http://trac.webkit.org/changeset/121511 + It made in-browser V8v7 10% slower. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::CodeBlock): + * bytecode/CodeBlock.h: + (CodeBlock): + (JSC::CodeBlock::countSpeculationSuccess): + (JSC::CodeBlock::countSpeculationFailure): + (JSC::CodeBlock::speculativeSuccessCounter): + (JSC::CodeBlock::speculativeFailCounter): + (JSC::CodeBlock::forcedOSRExitCounter): + (JSC::CodeBlock::addressOfSpeculativeSuccessCounter): + (JSC::CodeBlock::addressOfSpeculativeFailCounter): + (JSC::CodeBlock::addressOfForcedOSRExitCounter): + (JSC::CodeBlock::offsetOfSpeculativeSuccessCounter): + (JSC::CodeBlock::offsetOfSpeculativeFailCounter): + (JSC::CodeBlock::offsetOfForcedOSRExitCounter): + (JSC::CodeBlock::largeFailCountThreshold): + (JSC::CodeBlock::largeFailCountThresholdForLoop): + (JSC::CodeBlock::shouldReoptimizeNow): + (JSC::CodeBlock::shouldReoptimizeFromLoopNow): + * bytecode/ExecutionCounter.cpp: + (JSC::ExecutionCounter::setThreshold): + * bytecode/ExecutionCounter.h: + (ExecutionCounter): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::compileBody): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): + * dfg/DFGOSRExitCompiler.cpp: + (JSC::DFG::OSRExitCompiler::handleExitCounts): + * dfg/DFGOperations.cpp: + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/Options.h: + (JSC): + +2012-07-09 Filip Pizlo <fpizlo@apple.com> + + DFG may get stuck in an infinite fix point if it constant folds a mispredicted node + https://bugs.webkit.org/show_bug.cgi?id=90829 + <rdar://problem/11823843> + + Reviewed by Oliver Hunt. + + If a node is shown to have been mispredicted during CFA, then don't allow constant + folding to make the graph even more degenerate. Instead, pull back on constant folding + and allow the normal OSR machinery to fix our profiling so that a future recompilation + doesn't see the same mistake. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGAbstractState.h: + (JSC::DFG::AbstractState::trySetConstant): + (AbstractState): + * dfg/DFGPhase.h: + (JSC::DFG::Phase::name): + (Phase): + (JSC::DFG::runAndLog): + (DFG): + (JSC::DFG::runPhase): + +2012-07-09 Filip Pizlo <fpizlo@apple.com> + + It should be possible to jettison JIT stub routines even if they are currently running + https://bugs.webkit.org/show_bug.cgi?id=90731 + + Reviewed by Gavin Barraclough. + + This gives the GC awareness of all JIT-generated stubs for inline caches. That + means that if you want to delete a JIT-generated stub, you don't have to worry + about whether or not it is currently running: if there is a chance that it might + be, the GC will kindly defer deletion until non-running-ness is proved. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/Instruction.h: + (JSC): + (PolymorphicStubInfo): + (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set): + (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList): + * bytecode/PolymorphicPutByIdList.cpp: + (JSC::PutByIdAccess::fromStructureStubInfo): + * bytecode/PolymorphicPutByIdList.h: + (JSC::PutByIdAccess::transition): + (JSC::PutByIdAccess::replace): + (JSC::PutByIdAccess::stubRoutine): + (PutByIdAccess): + (JSC::PolymorphicPutByIdList::currentSlowPathTarget): + * bytecode/StructureStubInfo.h: + (JSC::StructureStubInfo::reset): + * dfg/DFGRepatch.cpp: + (JSC::DFG::generateProtoChainAccessStub): + (JSC::DFG::tryCacheGetByID): + (JSC::DFG::tryBuildGetByIDList): + (JSC::DFG::tryBuildGetByIDProtoList): + (JSC::DFG::emitPutReplaceStub): + (JSC::DFG::emitPutTransitionStub): + (JSC::DFG::tryCachePutByID): + (JSC::DFG::tryBuildPutByIdList): + * heap/ConservativeRoots.cpp: + (JSC): + (DummyMarkHook): + (JSC::DummyMarkHook::mark): + (JSC::ConservativeRoots::add): + (CompositeMarkHook): + (JSC::CompositeMarkHook::CompositeMarkHook): + (JSC::CompositeMarkHook::mark): + * heap/ConservativeRoots.h: + (JSC): + (ConservativeRoots): + * heap/Heap.cpp: + (JSC::Heap::markRoots): + (JSC::Heap::deleteUnmarkedCompiledCode): + * heap/Heap.h: + (JSC): + (Heap): + * heap/JITStubRoutineSet.cpp: Added. + (JSC): + (JSC::JITStubRoutineSet::JITStubRoutineSet): + (JSC::JITStubRoutineSet::~JITStubRoutineSet): + (JSC::JITStubRoutineSet::add): + (JSC::JITStubRoutineSet::clearMarks): + (JSC::JITStubRoutineSet::markSlow): + (JSC::JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines): + (JSC::JITStubRoutineSet::traceMarkedStubRoutines): + * heap/JITStubRoutineSet.h: Added. + (JSC): + (JITStubRoutineSet): + (JSC::JITStubRoutineSet::mark): + * heap/MachineStackMarker.h: + (JSC): + * interpreter/RegisterFile.cpp: + (JSC::RegisterFile::gatherConservativeRoots): + * interpreter/RegisterFile.h: + (JSC): + * jit/ExecutableAllocator.cpp: + (JSC::DemandExecutableAllocator::DemandExecutableAllocator): + * jit/ExecutableAllocator.h: + (JSC): + * jit/ExecutableAllocatorFixedVMPool.cpp: + (JSC): + (JSC::FixedVMPoolExecutableAllocator::FixedVMPoolExecutableAllocator): + * jit/GCAwareJITStubRoutine.cpp: Added. + (JSC): + (JSC::GCAwareJITStubRoutine::GCAwareJITStubRoutine): + (JSC::GCAwareJITStubRoutine::~GCAwareJITStubRoutine): + (JSC::GCAwareJITStubRoutine::observeZeroRefCount): + (JSC::GCAwareJITStubRoutine::deleteFromGC): + (JSC::GCAwareJITStubRoutine::markRequiredObjectsInternal): + (JSC::MarkingGCAwareJITStubRoutineWithOneObject::MarkingGCAwareJITStubRoutineWithOneObject): + (JSC::MarkingGCAwareJITStubRoutineWithOneObject::~MarkingGCAwareJITStubRoutineWithOneObject): + (JSC::MarkingGCAwareJITStubRoutineWithOneObject::markRequiredObjectsInternal): + (JSC::createJITStubRoutine): + * jit/GCAwareJITStubRoutine.h: Added. + (JSC): + (GCAwareJITStubRoutine): + (JSC::GCAwareJITStubRoutine::markRequiredObjects): + (MarkingGCAwareJITStubRoutineWithOneObject): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::privateCompilePutByIdTransition): + (JSC::JIT::privateCompilePatchGetArrayLength): + (JSC::JIT::privateCompileGetByIdProto): + (JSC::JIT::privateCompileGetByIdSelfList): + (JSC::JIT::privateCompileGetByIdProtoList): + (JSC::JIT::privateCompileGetByIdChainList): + (JSC::JIT::privateCompileGetByIdChain): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::privateCompilePutByIdTransition): + (JSC::JIT::privateCompilePatchGetArrayLength): + (JSC::JIT::privateCompileGetByIdProto): + (JSC::JIT::privateCompileGetByIdSelfList): + (JSC::JIT::privateCompileGetByIdProtoList): + (JSC::JIT::privateCompileGetByIdChainList): + (JSC::JIT::privateCompileGetByIdChain): + * jit/JITStubRoutine.cpp: Added. + (JSC): + (JSC::JITStubRoutine::~JITStubRoutine): + (JSC::JITStubRoutine::observeZeroRefCount): + * jit/JITStubRoutine.h: Added. + (JSC): + (JITStubRoutine): + (JSC::JITStubRoutine::JITStubRoutine): + (JSC::JITStubRoutine::createSelfManagedRoutine): + (JSC::JITStubRoutine::code): + (JSC::JITStubRoutine::asCodePtr): + (JSC::JITStubRoutine::ref): + (JSC::JITStubRoutine::deref): + (JSC::JITStubRoutine::startAddress): + (JSC::JITStubRoutine::endAddress): + (JSC::JITStubRoutine::addressStep): + (JSC::JITStubRoutine::canPerformRangeFilter): + (JSC::JITStubRoutine::filteringStartAddress): + (JSC::JITStubRoutine::filteringExtentSize): + (JSC::JITStubRoutine::passesFilter): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + (JSC::getPolymorphicAccessStructureListSlot): + +2012-07-09 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r122107. + http://trac.webkit.org/changeset/122107 + https://bugs.webkit.org/show_bug.cgi?id=90794 + + Build failure on Mac debug bots (Requested by falken_ on + #webkit). + + * Configurations/FeatureDefines.xcconfig: + +2012-07-09 Matt Falkenhagen <falken@chromium.org> + + Add ENABLE_DIALOG_ELEMENT and skeleton files + https://bugs.webkit.org/show_bug.cgi?id=90521 + + Reviewed by Kent Tamura. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-08 Ryosuke Niwa <rniwa@webkit.org> + + gcc build fix after r121925. + + * runtime/JSObject.h: + (JSC::JSFinalObject::finishCreation): + +2012-07-08 Zoltan Herczeg <zherczeg@webkit.org> + + [Qt][ARM] Implementing missing macro assembler instructions after r121925 + https://bugs.webkit.org/show_bug.cgi?id=90657 + + Reviewed by Csaba Osztrogonác. + + Implementing convertibleLoadPtr, replaceWithLoad and + replaceWithAddressComputation. + + * assembler/ARMAssembler.h: + (JSC::ARMAssembler::replaceWithLoad): + (ARMAssembler): + (JSC::ARMAssembler::replaceWithAddressComputation): + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::convertibleLoadPtr): + (MacroAssemblerARM): + +2012-07-06 Filip Pizlo <fpizlo@apple.com> + + WebKit Version 5.1.7 (6534.57.2, r121935): Double-click no longer works on OpenStreetMap + https://bugs.webkit.org/show_bug.cgi?id=90703 + + Reviewed by Michael Saboff. + + It turns out that in my object model refactoring, I managed to fix get_by_pname in all + execution engines except 64-bit baseline JIT. + + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_by_pname): + +2012-07-06 Pravin D <pravind.2k4@gmail.com> + + Build Error on Qt Linux build + https://bugs.webkit.org/show_bug.cgi?id=90699 + + Reviewed by Laszlo Gombos. + + * parser/Parser.cpp: + (JSC::::parseForStatement): + Removed unused boolean variable as this was causing build error on Qt Linux. + +2012-07-06 Nuno Lopes <nlopes@apple.com> + + Fix build with recent clang. + https://bugs.webkit.org/show_bug.cgi?id=90634 + + Reviewed by Oliver Hunt. + + * jit/SpecializedThunkJIT.h: + (JSC::SpecializedThunkJIT::SpecializedThunkJIT): + (SpecializedThunkJIT): + * jit/ThunkGenerators.cpp: + (JSC::charCodeAtThunkGenerator): + (JSC::charAtThunkGenerator): + (JSC::fromCharCodeThunkGenerator): + (JSC::sqrtThunkGenerator): + (JSC::floorThunkGenerator): + (JSC::ceilThunkGenerator): + (JSC::roundThunkGenerator): + (JSC::expThunkGenerator): + (JSC::logThunkGenerator): + (JSC::absThunkGenerator): + (JSC::powThunkGenerator): + * parser/ASTBuilder.h: + (JSC::ASTBuilder::createAssignResolve): + (JSC::ASTBuilder::createForLoop): + (JSC::ASTBuilder::createForInLoop): + (JSC::ASTBuilder::makeAssignNode): + (JSC::ASTBuilder::makePrefixNode): + (JSC::ASTBuilder::makePostfixNode): + * parser/NodeConstructors.h: + (JSC::PostfixErrorNode::PostfixErrorNode): + (JSC::PrefixErrorNode::PrefixErrorNode): + (JSC::AssignResolveNode::AssignResolveNode): + (JSC::AssignErrorNode::AssignErrorNode): + (JSC::ForNode::ForNode): + (JSC::ForInNode::ForInNode): + * parser/Nodes.h: + (FunctionCallResolveNode): + (PostfixErrorNode): + (PrefixErrorNode): + (ReadModifyResolveNode): + (AssignResolveNode): + (AssignErrorNode): + (ForNode): + (ForInNode): + * parser/Parser.cpp: + (JSC::::parseVarDeclarationList): + (JSC::::parseForStatement): + * parser/SyntaxChecker.h: + (JSC::SyntaxChecker::createAssignResolve): + (JSC::SyntaxChecker::createForLoop): + +2012-07-06 Zoltan Herczeg <zherczeg@webkit.org> + + [Qt][ARM] REGRESSION(r121885): It broke 30 jsc tests, 500+ layout tests + https://bugs.webkit.org/show_bug.cgi?id=90656 + + Reviewed by Csaba Osztrogonác. + + Typo fixes. + + * assembler/MacroAssemblerARM.cpp: + (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): + Rename getOp2Byte() -> getOp2Half() + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::convertibleLoadPtr): + Add a necessary space. + * jit/JITStubs.cpp: + (JSC): + Revert INLINE_ARM_FUNCTION macro. + +2012-07-05 Filip Pizlo <fpizlo@apple.com> + + REGRESSION(r121925): It broke 5 sputnik tests on x86 platforms + https://bugs.webkit.org/show_bug.cgi?id=90658 + + Reviewed by Zoltan Herczeg. + + Under the new object model, out-of-line property accesses such as those + in ResolveGlobal must account for the fact that the offset to the Kth + property is represented by K + inlineStorageCapacity. Hence, the property + loads in ResolveGlobal must have an additional -inlineStorageCapacity * + sizeof(JSValue) offset. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-07-05 Csaba Osztrogonác <ossy@webkit.org> + + [Qt] Unreviewed 64 bit buildfix after r121925. + + * bytecode/PutByIdStatus.cpp: + (JSC::PutByIdStatus::computeFromLLInt): + +2012-07-05 Michael Saboff <msaboff@apple.com> + + JSString::tryHashConstLock() fails to get exclusive lock + https://bugs.webkit.org/show_bug.cgi?id=90639 + + Reviewed by Oliver Hunt. + + Added check that the string is already locked even before compare and swap. + + * heap/MarkStack.cpp: + (JSC::JSString::tryHashConstLock): + +2012-07-04 Filip Pizlo <fpizlo@apple.com> + + Inline property storage should not be wasted when it is exhausted + https://bugs.webkit.org/show_bug.cgi?id=90347 + + Reviewed by Gavin Barraclough. + + Previously, if we switched an object from using inline storage to out-of-line + storage, we would abandon the inline storage. This would have two main implications: + (i) all accesses to the object, even for properties that were previously in inline + storage, must now take an extra indirection; and (ii) we waste a non-trivial amount + of space since we must allocate additional out-of-line storage to hold properties + that would have fit in the inline storage. There's also the copying cost when + switching to out-of-line storage - we must copy all inline properties into ouf-of-line + storage. + + This patch changes the way that object property storage works so that we can use both + inline and out-of-line storage concurrently. This is accomplished by introducing a + new notion of property offset. This PropertyOffset is a 32-bit signed integer and it + behaves as follows: + + offset == -1: invalid offset, indicating a property that does not exist. + + 0 <= offset <= inlineStorageCapacity: offset into inline storage. + + inlineStorageCapacity < offset: offset into out-of-line storage. + + Because non-final objects don't have inline storage, the only valid PropertyOffsets + for those objects' properties are -1 or > inlineStorageCapacity. + + This now means that the decision to use inline or out-of-line storage for an access is + made based on the offset, rather than the structure. It also means that any access + where the offset is a variable must have an extra branch, unless the type of the + object is also known (if it's known to be a non-final object then we can just assert + that the offset is >= inlineStorageCapacity). + + This looks like a big Kraken speed-up and a slight V8 speed-up. + + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * assembler/ARMv7Assembler.h: + (ARMv7Assembler): + (JSC::ARMv7Assembler::ldrWide8BitImmediate): + (JSC::ARMv7Assembler::replaceWithLoad): + (JSC::ARMv7Assembler::replaceWithAddressComputation): + * assembler/AbstractMacroAssembler.h: + (AbstractMacroAssembler): + (ConvertibleLoadLabel): + (JSC::AbstractMacroAssembler::ConvertibleLoadLabel::ConvertibleLoadLabel): + (JSC::AbstractMacroAssembler::ConvertibleLoadLabel::isSet): + (JSC::AbstractMacroAssembler::labelIgnoringWatchpoints): + (JSC::AbstractMacroAssembler::replaceWithLoad): + (JSC::AbstractMacroAssembler::replaceWithAddressComputation): + * assembler/CodeLocation.h: + (JSC): + (CodeLocationCommon): + (CodeLocationConvertibleLoad): + (JSC::CodeLocationConvertibleLoad::CodeLocationConvertibleLoad): + (JSC::CodeLocationCommon::convertibleLoadAtOffset): + * assembler/LinkBuffer.cpp: + (JSC::LinkBuffer::finalizeCodeWithDisassembly): + * assembler/LinkBuffer.h: + (LinkBuffer): + (JSC::LinkBuffer::locationOf): + * assembler/MacroAssemblerARMv7.h: + (MacroAssemblerARMv7): + (JSC::MacroAssemblerARMv7::convertibleLoadPtr): + * assembler/MacroAssemblerX86.h: + (JSC::MacroAssemblerX86::convertibleLoadPtr): + (MacroAssemblerX86): + * assembler/MacroAssemblerX86_64.h: + (JSC::MacroAssemblerX86_64::convertibleLoadPtr): + (MacroAssemblerX86_64): + * assembler/RepatchBuffer.h: + (RepatchBuffer): + (JSC::RepatchBuffer::replaceWithLoad): + (JSC::RepatchBuffer::replaceWithAddressComputation): + (JSC::RepatchBuffer::setLoadInstructionIsActive): + * assembler/X86Assembler.h: + (JSC::X86Assembler::replaceWithLoad): + (X86Assembler): + (JSC::X86Assembler::replaceWithAddressComputation): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::printGetByIdOp): + (JSC::CodeBlock::dump): + (JSC::CodeBlock::finalizeUnconditionally): + * bytecode/GetByIdStatus.cpp: + (JSC::GetByIdStatus::computeFromLLInt): + (JSC::GetByIdStatus::computeForChain): + (JSC::GetByIdStatus::computeFor): + * bytecode/GetByIdStatus.h: + (JSC::GetByIdStatus::GetByIdStatus): + (JSC::GetByIdStatus::offset): + (GetByIdStatus): + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecode/PutByIdStatus.cpp: + (JSC::PutByIdStatus::computeFromLLInt): + (JSC::PutByIdStatus::computeFor): + * bytecode/PutByIdStatus.h: + (JSC::PutByIdStatus::PutByIdStatus): + (JSC::PutByIdStatus::offset): + (PutByIdStatus): + * bytecode/ResolveGlobalStatus.cpp: + (JSC): + (JSC::computeForStructure): + * bytecode/ResolveGlobalStatus.h: + (JSC::ResolveGlobalStatus::ResolveGlobalStatus): + (JSC::ResolveGlobalStatus::offset): + (ResolveGlobalStatus): + * bytecode/StructureSet.h: + (StructureSet): + * bytecode/StructureStubInfo.h: + * dfg/DFGByteCodeParser.cpp: + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::handleGetByOffset): + (JSC::DFG::ByteCodeParser::handleGetById): + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + * dfg/DFGJITCompiler.h: + (JSC::DFG::PropertyAccessRecord::PropertyAccessRecord): + (PropertyAccessRecord): + * dfg/DFGRepatch.cpp: + (JSC::DFG::dfgRepatchByIdSelfAccess): + (JSC::DFG::generateProtoChainAccessStub): + (JSC::DFG::tryCacheGetByID): + (JSC::DFG::tryBuildGetByIDList): + (JSC::DFG::tryBuildGetByIDProtoList): + (JSC::DFG::emitPutReplaceStub): + (JSC::DFG::emitPutTransitionStub): + (JSC::DFG::tryCachePutByID): + (JSC::DFG::tryBuildPutByIdList): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::cachedGetById): + (JSC::DFG::SpeculativeJIT::cachedPutById): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::cachedGetById): + (JSC::DFG::SpeculativeJIT::cachedPutById): + (JSC::DFG::SpeculativeJIT::compile): + * heap/MarkStack.cpp: + (JSC::visitChildren): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::tryCacheGetByID): + (JSC::Interpreter::privateExecute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + (JSC::PropertyStubCompilationInfo::copyToStubInfo): + * jit/JIT.h: + (JSC::PropertyStubCompilationInfo::PropertyStubCompilationInfo): + (JSC::JIT::compileGetByIdProto): + (JSC::JIT::compileGetByIdSelfList): + (JSC::JIT::compileGetByIdProtoList): + (JSC::JIT::compileGetByIdChainList): + (JSC::JIT::compileGetByIdChain): + (JSC::JIT::compilePutByIdTransition): + (JIT): + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_resolve_global): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_resolve_global): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::compileGetDirectOffset): + (JSC::JIT::emit_op_method_check): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::emit_op_put_by_id): + (JSC::JIT::compilePutDirectOffset): + (JSC::JIT::privateCompilePutByIdTransition): + (JSC::JIT::patchGetByIdSelf): + (JSC::JIT::patchPutByIdReplace): + (JSC::JIT::privateCompileGetByIdProto): + (JSC::JIT::privateCompileGetByIdSelfList): + (JSC::JIT::privateCompileGetByIdProtoList): + (JSC::JIT::privateCompileGetByIdChainList): + (JSC::JIT::privateCompileGetByIdChain): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_method_check): + (JSC::JIT::compileGetByIdHotPath): + (JSC::JIT::emit_op_put_by_id): + (JSC::JIT::compilePutDirectOffset): + (JSC::JIT::compileGetDirectOffset): + (JSC::JIT::privateCompilePutByIdTransition): + (JSC::JIT::patchGetByIdSelf): + (JSC::JIT::patchPutByIdReplace): + (JSC::JIT::privateCompileGetByIdProto): + (JSC::JIT::privateCompileGetByIdSelfList): + (JSC::JIT::privateCompileGetByIdProtoList): + (JSC::JIT::privateCompileGetByIdChainList): + (JSC::JIT::privateCompileGetByIdChain): + (JSC::JIT::emit_op_get_by_pname): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCacheGetByID): + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter.asm: + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * offlineasm/x86.rb: + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::functionNameOffset): + * runtime/JSObject.cpp: + (JSC::JSObject::visitChildren): + (JSC): + (JSC::JSFinalObject::visitChildren): + (JSC::JSObject::put): + (JSC::JSObject::deleteProperty): + (JSC::JSObject::getPropertySpecificValue): + (JSC::JSObject::removeDirect): + (JSC::JSObject::growOutOfLineStorage): + (JSC::JSObject::getOwnPropertyDescriptor): + * runtime/JSObject.h: + (JSObject): + (JSC::JSObject::getDirect): + (JSC::JSObject::getDirectLocation): + (JSC::JSObject::hasInlineStorage): + (JSC::JSObject::inlineStorageUnsafe): + (JSC::JSObject::inlineStorage): + (JSC::JSObject::outOfLineStorage): + (JSC::JSObject::locationForOffset): + (JSC::JSObject::offsetForLocation): + (JSC::JSObject::getDirectOffset): + (JSC::JSObject::putDirectOffset): + (JSC::JSObject::putUndefinedAtDirectOffset): + (JSC::JSObject::addressOfOutOfLineStorage): + (JSC::JSObject::finishCreation): + (JSC::JSNonFinalObject::JSNonFinalObject): + (JSC::JSNonFinalObject::finishCreation): + (JSFinalObject): + (JSC::JSFinalObject::finishCreation): + (JSC::JSFinalObject::JSFinalObject): + (JSC::JSObject::offsetOfOutOfLineStorage): + (JSC::JSObject::setOutOfLineStorage): + (JSC::JSObject::JSObject): + (JSC): + (JSC::JSCell::fastGetOwnProperty): + (JSC::JSObject::putDirectInternal): + (JSC::JSObject::setStructureAndReallocateStorageIfNecessary): + (JSC::JSObject::putDirectWithoutTransition): + (JSC::offsetRelativeToPatchedStorage): + (JSC::indexRelativeToBase): + (JSC::offsetRelativeToBase): + * runtime/JSPropertyNameIterator.cpp: + (JSC::JSPropertyNameIterator::create): + * runtime/JSPropertyNameIterator.h: + (JSPropertyNameIterator): + (JSC::JSPropertyNameIterator::getOffset): + (JSC::JSPropertyNameIterator::finishCreation): + * runtime/JSValue.cpp: + (JSC::JSValue::putToPrimitive): + * runtime/Operations.h: + (JSC::normalizePrototypeChain): + * runtime/Options.cpp: + (JSC): + (JSC::Options::initialize): + * runtime/PropertyMapHashTable.h: + (PropertyMapEntry): + (JSC::PropertyMapEntry::PropertyMapEntry): + (PropertyTable): + (JSC::PropertyTable::PropertyTable): + (JSC::PropertyTable::getDeletedOffset): + (JSC::PropertyTable::addDeletedOffset): + (JSC::PropertyTable::nextOffset): + (JSC): + (JSC::PropertyTable::sizeInMemory): + * runtime/PropertyOffset.h: Added. + (JSC): + (JSC::checkOffset): + (JSC::validateOffset): + (JSC::isValidOffset): + (JSC::isInlineOffset): + (JSC::isOutOfLineOffset): + (JSC::offsetInInlineStorage): + (JSC::offsetInOutOfLineStorage): + (JSC::offsetInRespectiveStorage): + (JSC::numberOfOutOfLineSlotsForLastOffset): + (JSC::numberOfSlotsForLastOffset): + (JSC::nextPropertyOffsetFor): + (JSC::firstPropertyOffsetFor): + * runtime/PropertySlot.h: + (JSC::PropertySlot::cachedOffset): + (JSC::PropertySlot::setValue): + (JSC::PropertySlot::setCacheableGetterSlot): + (JSC::PropertySlot::clearOffset): + * runtime/PutPropertySlot.h: + (JSC::PutPropertySlot::setExistingProperty): + (JSC::PutPropertySlot::setNewProperty): + (JSC::PutPropertySlot::cachedOffset): + (PutPropertySlot): + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC::Structure::materializePropertyMap): + (JSC::nextOutOfLineStorageCapacity): + (JSC::Structure::growOutOfLineCapacity): + (JSC::Structure::suggestedNewOutOfLineStorageCapacity): + (JSC::Structure::addPropertyTransitionToExistingStructure): + (JSC::Structure::addPropertyTransition): + (JSC::Structure::removePropertyTransition): + (JSC::Structure::flattenDictionaryStructure): + (JSC::Structure::addPropertyWithoutTransition): + (JSC::Structure::removePropertyWithoutTransition): + (JSC::Structure::copyPropertyTableForPinning): + (JSC::Structure::get): + (JSC::Structure::putSpecificValue): + (JSC::Structure::remove): + * runtime/Structure.h: + (Structure): + (JSC::Structure::putWillGrowOutOfLineStorage): + (JSC::Structure::previousID): + (JSC::Structure::outOfLineCapacity): + (JSC::Structure::outOfLineSizeForKnownFinalObject): + (JSC::Structure::outOfLineSizeForKnownNonFinalObject): + (JSC::Structure::outOfLineSize): + (JSC::Structure::hasInlineStorage): + (JSC::Structure::inlineCapacity): + (JSC::Structure::inlineSizeForKnownFinalObject): + (JSC::Structure::inlineSize): + (JSC::Structure::totalStorageSize): + (JSC::Structure::totalStorageCapacity): + (JSC::Structure::firstValidOffset): + (JSC::Structure::lastValidOffset): + (JSC::Structure::isValidOffset): + (JSC::Structure::isEmpty): + (JSC::Structure::transitionCount): + (JSC::Structure::get): + +2012-07-05 Oliver Hunt <oliver@apple.com> + + JSObjectCallAsFunction should thisConvert the provided thisObject + https://bugs.webkit.org/show_bug.cgi?id=90628 + + Reviewed by Gavin Barraclough. + + Perform this conversion on the provided this object. + + * API/JSObjectRef.cpp: + (JSObjectCallAsFunction): + +2012-07-05 Zoltan Herczeg <zherczeg@webkit.org> + + [Qt] Unreviewed buildfix after r121886. Typo fix. + + * assembler/MacroAssemblerARM.cpp: + (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): + +2012-07-05 Zoltan Herczeg <zherczeg@webkit.org> + + Port DFG JIT to traditional ARM + https://bugs.webkit.org/show_bug.cgi?id=90198 + + Reviewed by Filip Pizlo. + + This patch contains the macro assembler part of the + DFG JIT support on ARM systems with fixed 32 bit instruction + width. A large amount of old code was refactored, and the ARMv4 + or lower support is removed from the macro assembler. + + Sunspider is improved by 8%, and V8 is 92%. + + * assembler/ARMAssembler.cpp: + (JSC::ARMAssembler::dataTransfer32): + (JSC::ARMAssembler::baseIndexTransfer32): + (JSC): + (JSC::ARMAssembler::dataTransfer16): + (JSC::ARMAssembler::baseIndexTransfer16): + (JSC::ARMAssembler::dataTransferFloat): + (JSC::ARMAssembler::baseIndexTransferFloat): + (JSC::ARMAssembler::executableCopy): + * assembler/ARMAssembler.h: + (JSC::ARMAssembler::ARMAssembler): + (JSC::ARMAssembler::emitInst): + (JSC::ARMAssembler::vmov_f64_r): + (ARMAssembler): + (JSC::ARMAssembler::vabs_f64_r): + (JSC::ARMAssembler::vneg_f64_r): + (JSC::ARMAssembler::ldr_imm): + (JSC::ARMAssembler::ldr_un_imm): + (JSC::ARMAssembler::dtr_u): + (JSC::ARMAssembler::dtr_ur): + (JSC::ARMAssembler::dtr_d): + (JSC::ARMAssembler::dtr_dr): + (JSC::ARMAssembler::dtrh_u): + (JSC::ARMAssembler::dtrh_ur): + (JSC::ARMAssembler::dtrh_d): + (JSC::ARMAssembler::dtrh_dr): + (JSC::ARMAssembler::fdtr_u): + (JSC::ARMAssembler::fdtr_d): + (JSC::ARMAssembler::push_r): + (JSC::ARMAssembler::pop_r): + (JSC::ARMAssembler::poke_r): + (JSC::ARMAssembler::peek_r): + (JSC::ARMAssembler::vmov_vfp64_r): + (JSC::ARMAssembler::vmov_arm64_r): + (JSC::ARMAssembler::vmov_vfp32_r): + (JSC::ARMAssembler::vmov_arm32_r): + (JSC::ARMAssembler::vcvt_u32_f64_r): + (JSC::ARMAssembler::vcvt_f64_f32_r): + (JSC::ARMAssembler::vcvt_f32_f64_r): + (JSC::ARMAssembler::clz_r): + (JSC::ARMAssembler::bkpt): + (JSC::ARMAssembler::bx): + (JSC::ARMAssembler::blx): + (JSC::ARMAssembler::labelIgnoringWatchpoints): + (JSC::ARMAssembler::labelForWatchpoint): + (JSC::ARMAssembler::label): + (JSC::ARMAssembler::getLdrImmAddress): + (JSC::ARMAssembler::replaceWithJump): + (JSC::ARMAssembler::maxJumpReplacementSize): + (JSC::ARMAssembler::getOp2Byte): + (JSC::ARMAssembler::getOp2Half): + (JSC::ARMAssembler::RM): + (JSC::ARMAssembler::RS): + (JSC::ARMAssembler::RD): + (JSC::ARMAssembler::RN): + * assembler/AssemblerBufferWithConstantPool.h: + (JSC::AssemblerBufferWithConstantPool::ensureSpaceForAnyInstruction): + * assembler/MacroAssemblerARM.cpp: + (JSC::MacroAssemblerARM::load32WithUnalignedHalfWords): + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::add32): + (MacroAssemblerARM): + (JSC::MacroAssemblerARM::and32): + (JSC::MacroAssemblerARM::lshift32): + (JSC::MacroAssemblerARM::mul32): + (JSC::MacroAssemblerARM::neg32): + (JSC::MacroAssemblerARM::rshift32): + (JSC::MacroAssemblerARM::urshift32): + (JSC::MacroAssemblerARM::xor32): + (JSC::MacroAssemblerARM::load8): + (JSC::MacroAssemblerARM::load8Signed): + (JSC::MacroAssemblerARM::load16): + (JSC::MacroAssemblerARM::load16Signed): + (JSC::MacroAssemblerARM::load32): + (JSC::MacroAssemblerARM::load32WithAddressOffsetPatch): + (JSC::MacroAssemblerARM::store32WithAddressOffsetPatch): + (JSC::MacroAssemblerARM::store8): + (JSC::MacroAssemblerARM::store16): + (JSC::MacroAssemblerARM::store32): + (JSC::MacroAssemblerARM::move): + (JSC::MacroAssemblerARM::jump): + (JSC::MacroAssemblerARM::branchAdd32): + (JSC::MacroAssemblerARM::mull32): + (JSC::MacroAssemblerARM::branchMul32): + (JSC::MacroAssemblerARM::nearCall): + (JSC::MacroAssemblerARM::compare32): + (JSC::MacroAssemblerARM::test32): + (JSC::MacroAssemblerARM::sub32): + (JSC::MacroAssemblerARM::call): + (JSC::MacroAssemblerARM::loadFloat): + (JSC::MacroAssemblerARM::loadDouble): + (JSC::MacroAssemblerARM::storeFloat): + (JSC::MacroAssemblerARM::storeDouble): + (JSC::MacroAssemblerARM::moveDouble): + (JSC::MacroAssemblerARM::addDouble): + (JSC::MacroAssemblerARM::divDouble): + (JSC::MacroAssemblerARM::subDouble): + (JSC::MacroAssemblerARM::mulDouble): + (JSC::MacroAssemblerARM::absDouble): + (JSC::MacroAssemblerARM::negateDouble): + (JSC::MacroAssemblerARM::convertInt32ToDouble): + (JSC::MacroAssemblerARM::convertFloatToDouble): + (JSC::MacroAssemblerARM::convertDoubleToFloat): + (JSC::MacroAssemblerARM::branchTruncateDoubleToInt32): + (JSC::MacroAssemblerARM::branchTruncateDoubleToUint32): + (JSC::MacroAssemblerARM::truncateDoubleToInt32): + (JSC::MacroAssemblerARM::truncateDoubleToUint32): + (JSC::MacroAssemblerARM::branchConvertDoubleToInt32): + (JSC::MacroAssemblerARM::branchDoubleNonZero): + (JSC::MacroAssemblerARM::branchDoubleZeroOrNaN): + (JSC::MacroAssemblerARM::invert): + (JSC::MacroAssemblerARM::replaceWithJump): + (JSC::MacroAssemblerARM::maxJumpReplacementSize): + (JSC::MacroAssemblerARM::call32): + * assembler/SH4Assembler.h: + (JSC::SH4Assembler::label): + * dfg/DFGAssemblyHelpers.h: + (JSC::DFG::AssemblyHelpers::debugCall): + (JSC::DFG::AssemblyHelpers::boxDouble): + (JSC::DFG::AssemblyHelpers::unboxDouble): + * dfg/DFGCCallHelpers.h: + (CCallHelpers): + (JSC::DFG::CCallHelpers::setupArguments): + * dfg/DFGFPRInfo.h: + (DFG): + * dfg/DFGGPRInfo.h: + (DFG): + (GPRInfo): + * dfg/DFGOperations.cpp: + (JSC): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::appendCallWithExceptionCheckSetResult): + (JSC::DFG::SpeculativeJIT::appendCallSetResult): + * jit/JITStubs.cpp: + (JSC): + * jit/JITStubs.h: + (JITStackFrame): + * jit/JSInterfaceJIT.h: + (JSInterfaceJIT): + +2012-07-04 Anthony Scian <ascian@rim.com> + + Web Inspector [JSC]: Implement ScriptCallStack::stackTrace + https://bugs.webkit.org/show_bug.cgi?id=40118 + + Reviewed by Yong Li. + + Added member functions to expose function name, urlString, and line #. + Refactored toString to make use of these member functions to reduce + duplicated code for future maintenance. + + Manually tested refactoring of toString by tracing thrown exceptions. + + * interpreter/Interpreter.h: + (JSC::StackFrame::toString): + (JSC::StackFrame::friendlySourceURL): + (JSC::StackFrame::friendlyFunctionName): + (JSC::StackFrame::friendlyLineNumber): + +2012-07-04 Andy Wingo <wingo@igalia.com> + + [GTK] Enable parallel GC + https://bugs.webkit.org/show_bug.cgi?id=90568 + + Reviewed by Martin Robinson. + + * runtime/Options.cpp: Include <algorithm.h> for std::min. + +2012-07-04 John Mellor <johnme@chromium.org> + + Text Autosizing: Add compile flag and runtime setting + https://bugs.webkit.org/show_bug.cgi?id=87394 + + This patch renames Font Boosting to Text Autosizing. + + Reviewed by Adam Barth. + + * Configurations/FeatureDefines.xcconfig: + +2012-07-03 Michael Saboff <msaboff@apple.com> + + Enh: Hash Const JSString in Backing Stores to Save Memory + https://bugs.webkit.org/show_bug.cgi?id=86024 + + Reviewed by Oliver Hunt. + + During garbage collection, each marking thread keeps a HashMap of + strings. While visiting via MarkStack::copyAndAppend(), we check to + see if the string we are visiting is already in the HashMap. If not + we add it. If so, we change the reference to the current string we're + visiting to the prior string. + + To reduce the performance impact of this change, two throttles have + ben added. 1) We only try hash consting if a significant number of new + strings have been created since the last hash const. Currently this is + set at 100 strings. 2) If a string is unique at the end of a marking + it will not be checked during further GC phases. In some cases this + won't catch all duplicates, but we are trying to catch the growth of + duplicate strings. + + * heap/Heap.cpp: + (JSC::Heap::markRoots): + * heap/MarkStack.cpp: + (JSC::MarkStackThreadSharedData::resetChildren): + (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData): + (JSC::MarkStackThreadSharedData::reset): + (JSC::MarkStack::setup): Check to see if enough strings have been created + to hash const. + (JSC::MarkStack::reset): Added call to clear m_uniqueStrings. + (JSC::JSString::tryHashConstLock): New method to lock JSString for + hash consting. + (JSC::JSString::releaseHashConstLock): New unlock method. + (JSC::JSString::shouldTryHashConst): Set of checks to see if we should + try to hash const the string. + (JSC::MarkStack::internalAppend): New method that performs the hash consting. + (JSC::SlotVisitor::copyAndAppend): Changed to call the new hash + consting internalAppend(). + * heap/MarkStack.h: + (MarkStackThreadSharedData): + (MarkStack): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSGlobalData): + (JSC::JSGlobalData::haveEnoughNewStringsToHashConst): + (JSC::JSGlobalData::resetNewStringsSinceLastHashConst): + * runtime/JSString.h: + (JSString): Changed from using bool flags to using an unsigned + m_flags field. This works better with the weakCompareAndSwap in + JSString::tryHashConstLock(). Changed the 8bitness setting and + checking to use new accessors. + (JSC::JSString::JSString): + (JSC::JSString::finishCreation): + (JSC::JSString::is8Bit): Updated for new m_flags. + (JSC::JSString::setIs8Bit): New setter. + New hash const flags accessors: + (JSC::JSString::isHashConstSingleton): + (JSC::JSString::clearHashConstSingleton): + (JSC::JSString::setHashConstSingleton): + (JSC::JSRopeString::finishCreation): + (JSC::JSRopeString::append): + +2012-07-03 Tony Chang <tony@chromium.org> + + [chromium] Unreviewed, update .gitignore to handle VS2010 files. + + * JavaScriptCore.gyp/.gitignore: + +2012-07-03 Mark Lam <mark.lam@apple.com> + + Add ability to symbolically set and dump JSC VM options. + See comments in runtime/Options.h for details on how the options work. + https://bugs.webkit.org/show_bug.cgi?id=90420 + + Reviewed by Filip Pizlo. + + * assembler/LinkBuffer.cpp: + (JSC::LinkBuffer::finalizeCodeWithDisassembly): + * assembler/LinkBuffer.h: + (JSC): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::shouldOptimizeNow): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::likelyToTakeSlowCase): + (JSC::CodeBlock::couldTakeSlowCase): + (JSC::CodeBlock::likelyToTakeSpecialFastCase): + (JSC::CodeBlock::likelyToTakeDeepestSlowCase): + (JSC::CodeBlock::likelyToTakeAnySlowCase): + (JSC::CodeBlock::jitAfterWarmUp): + (JSC::CodeBlock::jitSoon): + (JSC::CodeBlock::reoptimizationRetryCounter): + (JSC::CodeBlock::countReoptimization): + (JSC::CodeBlock::counterValueForOptimizeAfterWarmUp): + (JSC::CodeBlock::counterValueForOptimizeAfterLongWarmUp): + (JSC::CodeBlock::optimizeSoon): + (JSC::CodeBlock::exitCountThresholdForReoptimization): + (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop): + * bytecode/ExecutionCounter.h: + (JSC::ExecutionCounter::clippedThreshold): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleInlining): + * dfg/DFGCapabilities.h: + (JSC::DFG::mightCompileEval): + (JSC::DFG::mightCompileProgram): + (JSC::DFG::mightCompileFunctionForCall): + (JSC::DFG::mightCompileFunctionForConstruct): + (JSC::DFG::mightInlineFunctionForCall): + (JSC::DFG::mightInlineFunctionForConstruct): + * dfg/DFGCommon.h: + (JSC::DFG::shouldShowDisassembly): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): + * dfg/DFGVariableAccessData.h: + (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote): + * heap/MarkStack.cpp: + (JSC::MarkStackSegmentAllocator::allocate): + (JSC::MarkStackSegmentAllocator::shrinkReserve): + (JSC::MarkStackArray::MarkStackArray): + (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData): + (JSC::SlotVisitor::donateKnownParallel): + (JSC::SlotVisitor::drain): + (JSC::SlotVisitor::drainFromShared): + * heap/MarkStack.h: + (JSC::MarkStack::mergeOpaqueRootsIfProfitable): + (JSC::MarkStack::addOpaqueRoot): + * heap/SlotVisitor.h: + (JSC::SlotVisitor::donate): + * jit/JIT.cpp: + (JSC::JIT::emitOptimizationCheck): + * jsc.cpp: + (printUsageStatement): + (parseArguments): + * runtime/InitializeThreading.cpp: + (JSC::initializeThreadingOnce): + * runtime/JSGlobalData.cpp: + (JSC::enableAssembler): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::JSGlobalObject): + * runtime/Options.cpp: + (JSC): + (JSC::overrideOptionWithHeuristic): + (JSC::Options::initialize): + (JSC::Options::setOption): + (JSC::Options::dumpAllOptions): + (JSC::Options::dumpOption): + * runtime/Options.h: + (JSC): + (Options): + (EntryInfo): + +2012-07-03 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> Joel Dillon <joel.dillon@codethink.co.uk> + + [Qt][Win] Fix broken QtWebKit5.lib linking + https://bugs.webkit.org/show_bug.cgi?id=88321 + + Reviewed by Kenneth Rohde Christiansen. + + The goal is to have different ports build systems define STATICALLY_LINKED_WITH_WTF + when building JavaScriptCore, if both are packaged in the same DLL, instead + of relying on the code to handle this. + The effects of BUILDING_* and STATICALLY_LINKED_WITH_* are currently the same + except for a check in Source/JavaScriptCore/config.h. + + Keeping the old way for the WX port as requested by the port's contributors. + For non-Windows ports there is no difference between IMPORT and EXPORT, no + change is needed. + + * API/JSBase.h: + JS symbols shouldn't be included by WTF objects anymore. Remove the export when BUILDING_WTF. + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops: + Make sure that JavaScriptCore uses import symbols of WTF for the Win port. + * runtime/JSExportMacros.h: + +2012-07-02 Filip Pizlo <fpizlo@apple.com> + + DFG OSR exit value recoveries should be computed lazily + https://bugs.webkit.org/show_bug.cgi?id=82155 + + Reviewed by Gavin Barraclough. + + This change aims to reduce one aspect of DFG compile times: the fact + that we currently compute the value recoveries for each local and + argument on every speculation check. We compile many speculation checks, + so this can add up quick. The strategy that this change takes is to + have the DFG save just enough information about how the compiler is + choosing to represent state, that the DFG::OSRExitCompiler can reify + the value recoveries lazily. + + This appears to be an 0.3% SunSpider speed-up and is neutral elsewhere. + + I also took the opportunity to fix the sampling regions profiler (it + was missing an export macro) and to put in more sampling regions in + the DFG (which are disabled so long as ENABLE(SAMPLING_REGIONS) is + false). + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/CodeBlock.cpp: + (JSC): + (JSC::CodeBlock::shrinkDFGDataToFit): + * bytecode/CodeBlock.h: + (CodeBlock): + (JSC::CodeBlock::minifiedDFG): + (JSC::CodeBlock::variableEventStream): + (DFGData): + * bytecode/Operands.h: + (JSC::Operands::hasOperand): + (Operands): + (JSC::Operands::size): + (JSC::Operands::at): + (JSC::Operands::operator[]): + (JSC::Operands::isArgument): + (JSC::Operands::isVariable): + (JSC::Operands::argumentForIndex): + (JSC::Operands::variableForIndex): + (JSC::Operands::operandForIndex): + (JSC): + (JSC::dumpOperands): + * bytecode/SamplingTool.h: + (SamplingRegion): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::parse): + * dfg/DFGCFAPhase.cpp: + (JSC::DFG::performCFA): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::performCSE): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::performFixup): + * dfg/DFGGenerationInfo.h: + (JSC::DFG::GenerationInfo::GenerationInfo): + (JSC::DFG::GenerationInfo::initConstant): + (JSC::DFG::GenerationInfo::initInteger): + (JSC::DFG::GenerationInfo::initJSValue): + (JSC::DFG::GenerationInfo::initCell): + (JSC::DFG::GenerationInfo::initBoolean): + (JSC::DFG::GenerationInfo::initDouble): + (JSC::DFG::GenerationInfo::initStorage): + (GenerationInfo): + (JSC::DFG::GenerationInfo::noticeOSRBirth): + (JSC::DFG::GenerationInfo::use): + (JSC::DFG::GenerationInfo::spill): + (JSC::DFG::GenerationInfo::setSpilled): + (JSC::DFG::GenerationInfo::fillJSValue): + (JSC::DFG::GenerationInfo::fillCell): + (JSC::DFG::GenerationInfo::fillInteger): + (JSC::DFG::GenerationInfo::fillBoolean): + (JSC::DFG::GenerationInfo::fillDouble): + (JSC::DFG::GenerationInfo::fillStorage): + (JSC::DFG::GenerationInfo::appendFill): + (JSC::DFG::GenerationInfo::appendSpill): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + (JSC::DFG::JITCompiler::compile): + (JSC::DFG::JITCompiler::compileFunction): + * dfg/DFGMinifiedGraph.h: Added. + (DFG): + (MinifiedGraph): + (JSC::DFG::MinifiedGraph::MinifiedGraph): + (JSC::DFG::MinifiedGraph::at): + (JSC::DFG::MinifiedGraph::append): + (JSC::DFG::MinifiedGraph::prepareAndShrink): + (JSC::DFG::MinifiedGraph::setOriginalGraphSize): + (JSC::DFG::MinifiedGraph::originalGraphSize): + * dfg/DFGMinifiedNode.cpp: Added. + (DFG): + (JSC::DFG::MinifiedNode::fromNode): + * dfg/DFGMinifiedNode.h: Added. + (DFG): + (JSC::DFG::belongsInMinifiedGraph): + (MinifiedNode): + (JSC::DFG::MinifiedNode::MinifiedNode): + (JSC::DFG::MinifiedNode::index): + (JSC::DFG::MinifiedNode::op): + (JSC::DFG::MinifiedNode::hasChild1): + (JSC::DFG::MinifiedNode::child1): + (JSC::DFG::MinifiedNode::hasConstant): + (JSC::DFG::MinifiedNode::hasConstantNumber): + (JSC::DFG::MinifiedNode::constantNumber): + (JSC::DFG::MinifiedNode::hasWeakConstant): + (JSC::DFG::MinifiedNode::weakConstant): + (JSC::DFG::MinifiedNode::getIndex): + (JSC::DFG::MinifiedNode::compareByNodeIndex): + (JSC::DFG::MinifiedNode::hasChild): + * dfg/DFGNode.h: + (Node): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::OSRExit): + * dfg/DFGOSRExit.h: + (OSRExit): + * dfg/DFGOSRExitCompiler.cpp: + * dfg/DFGOSRExitCompiler.h: + (OSRExitCompiler): + * dfg/DFGOSRExitCompiler32_64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGOSRExitCompiler64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::performPredictionPropagation): + * dfg/DFGRedundantPhiEliminationPhase.cpp: + (JSC::DFG::performRedundantPhiElimination): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::SpeculativeJIT): + (DFG): + (JSC::DFG::SpeculativeJIT::fillStorage): + (JSC::DFG::SpeculativeJIT::noticeOSRBirth): + (JSC::DFG::SpeculativeJIT::compileMovHint): + (JSC::DFG::SpeculativeJIT::compile): + (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): + * dfg/DFGSpeculativeJIT.h: + (DFG): + (JSC::DFG::SpeculativeJIT::use): + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::spill): + (JSC::DFG::SpeculativeJIT::speculationCheck): + (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): + (JSC::DFG::SpeculativeJIT::recordSetLocal): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::fillInteger): + (JSC::DFG::SpeculativeJIT::fillDouble): + (JSC::DFG::SpeculativeJIT::fillJSValue): + (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): + (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): + (JSC::DFG::SpeculativeJIT::fillSpeculateCell): + (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::fillInteger): + (JSC::DFG::SpeculativeJIT::fillDouble): + (JSC::DFG::SpeculativeJIT::fillJSValue): + (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): + (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): + (JSC::DFG::SpeculativeJIT::fillSpeculateCell): + (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGValueRecoveryOverride.h: Added. + (DFG): + (ValueRecoveryOverride): + (JSC::DFG::ValueRecoveryOverride::ValueRecoveryOverride): + * dfg/DFGValueSource.cpp: Added. + (DFG): + (JSC::DFG::ValueSource::dump): + * dfg/DFGValueSource.h: Added. + (DFG): + (JSC::DFG::dataFormatToValueSourceKind): + (JSC::DFG::valueSourceKindToDataFormat): + (JSC::DFG::isInRegisterFile): + (ValueSource): + (JSC::DFG::ValueSource::ValueSource): + (JSC::DFG::ValueSource::forPrediction): + (JSC::DFG::ValueSource::forDataFormat): + (JSC::DFG::ValueSource::isSet): + (JSC::DFG::ValueSource::kind): + (JSC::DFG::ValueSource::isInRegisterFile): + (JSC::DFG::ValueSource::dataFormat): + (JSC::DFG::ValueSource::valueRecovery): + (JSC::DFG::ValueSource::nodeIndex): + (JSC::DFG::ValueSource::nodeIndexFromKind): + (JSC::DFG::ValueSource::kindFromNodeIndex): + * dfg/DFGVariableEvent.cpp: Added. + (DFG): + (JSC::DFG::VariableEvent::dump): + (JSC::DFG::VariableEvent::dumpFillInfo): + (JSC::DFG::VariableEvent::dumpSpillInfo): + * dfg/DFGVariableEvent.h: Added. + (DFG): + (VariableEvent): + (JSC::DFG::VariableEvent::VariableEvent): + (JSC::DFG::VariableEvent::reset): + (JSC::DFG::VariableEvent::fillGPR): + (JSC::DFG::VariableEvent::fillPair): + (JSC::DFG::VariableEvent::fillFPR): + (JSC::DFG::VariableEvent::spill): + (JSC::DFG::VariableEvent::death): + (JSC::DFG::VariableEvent::setLocal): + (JSC::DFG::VariableEvent::movHint): + (JSC::DFG::VariableEvent::kind): + (JSC::DFG::VariableEvent::nodeIndex): + (JSC::DFG::VariableEvent::dataFormat): + (JSC::DFG::VariableEvent::gpr): + (JSC::DFG::VariableEvent::tagGPR): + (JSC::DFG::VariableEvent::payloadGPR): + (JSC::DFG::VariableEvent::fpr): + (JSC::DFG::VariableEvent::virtualRegister): + (JSC::DFG::VariableEvent::operand): + (JSC::DFG::VariableEvent::variableRepresentation): + * dfg/DFGVariableEventStream.cpp: Added. + (DFG): + (JSC::DFG::VariableEventStream::logEvent): + (MinifiedGenerationInfo): + (JSC::DFG::MinifiedGenerationInfo::MinifiedGenerationInfo): + (JSC::DFG::MinifiedGenerationInfo::update): + (JSC::DFG::VariableEventStream::reconstruct): + * dfg/DFGVariableEventStream.h: Added. + (DFG): + (VariableEventStream): + (JSC::DFG::VariableEventStream::appendAndLog): + * dfg/DFGVirtualRegisterAllocationPhase.cpp: + (JSC::DFG::performVirtualRegisterAllocation): + +2012-07-02 Filip Pizlo <fpizlo@apple.com> + + DFG::ArgumentsSimplificationPhase should assert that the PhantomArguments nodes it creates are not shouldGenerate() + https://bugs.webkit.org/show_bug.cgi?id=90407 + + Reviewed by Mark Hahnenberg. + + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + +2012-07-02 Gavin Barraclough <barraclough@apple.com> + + Array.prototype.pop should throw if property is not configurable + https://bugs.webkit.org/show_bug.cgi?id=75788 + + Rubber Stamped by Oliver Hunt. + + No real bug here any more, but the error we throw sometimes has a misleading message. + + * runtime/JSArray.cpp: + (JSC::JSArray::pop): + +2012-06-29 Filip Pizlo <fpizlo@apple.com> + + JSObject wastes too much memory on unused property slots + https://bugs.webkit.org/show_bug.cgi?id=90255 + + Reviewed by Mark Hahnenberg. + + Rolling back in after applying a simple fix: it appears that + JSObject::setStructureAndReallocateStorageIfNecessary() was allocating more + property storage than necessary. Fixing this appears to resolve the crash. + + This does a few things: + + - JSNonFinalObject no longer has inline property storage. + + - Initial out-of-line property storage size is 4 slots for JSNonFinalObject, + or 2x the inline storage for JSFinalObject. + + - Property storage is only reallocated if it needs to be. Previously, we + would reallocate the property storage on any transition where the original + structure said shouldGrowProperyStorage(), but this led to spurious + reallocations when doing transitionless property adds and there are + deleted property slots available. That in turn led to crashes, because we + would switch to out-of-line storage even if the capacity matched the + criteria for inline storage. + + - Inline JSFunction allocation is killed off because we don't have a good + way of inlining property storage allocation. This didn't hurt performance. + Killing off code is better than fixing it if that code wasn't doing any + good. + + This looks like a 1% progression on V8. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + (JSC): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_new_func): + (JSC): + (JSC::JIT::emit_op_new_func_exp): + * runtime/JSFunction.cpp: + (JSC::JSFunction::finishCreation): + * runtime/JSObject.h: + (JSC::JSObject::isUsingInlineStorage): + (JSObject): + (JSC::JSObject::finishCreation): + (JSC): + (JSC::JSNonFinalObject::hasInlineStorage): + (JSNonFinalObject): + (JSC::JSNonFinalObject::JSNonFinalObject): + (JSC::JSNonFinalObject::finishCreation): + (JSC::JSFinalObject::hasInlineStorage): + (JSC::JSFinalObject::finishCreation): + (JSC::JSObject::offsetOfInlineStorage): + (JSC::JSObject::setPropertyStorage): + (JSC::Structure::inlineStorageCapacity): + (JSC::Structure::isUsingInlineStorage): + (JSC::JSObject::putDirectInternal): + (JSC::JSObject::setStructureAndReallocateStorageIfNecessary): + (JSC::JSObject::putDirectWithoutTransition): + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC::nextPropertyStorageCapacity): + (JSC): + (JSC::Structure::growPropertyStorageCapacity): + (JSC::Structure::suggestedNewPropertyStorageSize): + * runtime/Structure.h: + (JSC::Structure::putWillGrowPropertyStorage): + (Structure): + +2012-06-29 Filip Pizlo <fpizlo@apple.com> + + Webkit crashes in DFG on Google Docs when creating a new document + https://bugs.webkit.org/show_bug.cgi?id=90209 + + Reviewed by Gavin Barraclough. + + Don't attempt to short-circuit Phantom(GetLocal) if the GetLocal is for a + captured variable. + + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::mergeBlocks): + +2012-06-30 Zan Dobersek <zandobersek@gmail.com> + + Unreviewed, rolling out r121605. + http://trac.webkit.org/changeset/121605 + https://bugs.webkit.org/show_bug.cgi?id=90336 + + Changes caused flaky crashes in sputnik/Unicode tests on Apple + WK1 and GTK Linux builders + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + (JSC::JIT::emitAllocateJSFinalObject): + (JSC): + (JSC::JIT::emitAllocateJSFunction): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_new_func): + (JSC::JIT::emitSlow_op_new_func): + (JSC): + (JSC::JIT::emit_op_new_func_exp): + (JSC::JIT::emitSlow_op_new_func_exp): + * runtime/JSFunction.cpp: + (JSC::JSFunction::finishCreation): + * runtime/JSObject.h: + (JSC::JSObject::isUsingInlineStorage): + (JSObject): + (JSC::JSObject::finishCreation): + (JSC): + (JSNonFinalObject): + (JSC::JSNonFinalObject::JSNonFinalObject): + (JSC::JSNonFinalObject::finishCreation): + (JSFinalObject): + (JSC::JSFinalObject::finishCreation): + (JSC::JSObject::offsetOfInlineStorage): + (JSC::JSObject::setPropertyStorage): + (JSC::Structure::isUsingInlineStorage): + (JSC::JSObject::putDirectInternal): + (JSC::JSObject::putDirectWithoutTransition): + (JSC::JSObject::transitionTo): + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC): + (JSC::Structure::growPropertyStorageCapacity): + (JSC::Structure::suggestedNewPropertyStorageSize): + * runtime/Structure.h: + (JSC::Structure::shouldGrowPropertyStorage): + (JSC::Structure::propertyStorageSize): + +2012-06-29 Mark Hahnenberg <mhahnenberg@apple.com> + + Remove warning about protected values when the Heap is being destroyed + https://bugs.webkit.org/show_bug.cgi?id=90302 + + Reviewed by Geoffrey Garen. + + Having to do book-keeping about whether values allocated from a certain + VM are or are not protected makes the JSC API much more difficult to use + correctly. Clients should be able to throw an entire VM away and not have + to worry about unprotecting all of the values that they protected earlier. + + * heap/Heap.cpp: + (JSC::Heap::lastChanceToFinalize): + +2012-06-29 Filip Pizlo <fpizlo@apple.com> + + JSObject wastes too much memory on unused property slots + https://bugs.webkit.org/show_bug.cgi?id=90255 + + Reviewed by Mark Hahnenberg. + + This does a few things: + + - JSNonFinalObject no longer has inline property storage. + + - Initial out-of-line property storage size is 4 slots for JSNonFinalObject, + or 2x the inline storage for JSFinalObject. + + - Property storage is only reallocated if it needs to be. Previously, we + would reallocate the property storage on any transition where the original + structure said shouldGrowProperyStorage(), but this led to spurious + reallocations when doing transitionless property adds and there are + deleted property slots available. That in turn led to crashes, because we + would switch to out-of-line storage even if the capacity matched the + criteria for inline storage. + + - Inline JSFunction allocation is killed off because we don't have a good + way of inlining property storage allocation. This didn't hurt performance. + Killing off code is better than fixing it if that code wasn't doing any + good. + + This looks like a 1% progression on V8. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + (JSC): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_new_func): + (JSC): + (JSC::JIT::emit_op_new_func_exp): + * runtime/JSFunction.cpp: + (JSC::JSFunction::finishCreation): + * runtime/JSObject.h: + (JSC::JSObject::isUsingInlineStorage): + (JSObject): + (JSC::JSObject::finishCreation): + (JSC): + (JSC::JSNonFinalObject::hasInlineStorage): + (JSNonFinalObject): + (JSC::JSNonFinalObject::JSNonFinalObject): + (JSC::JSNonFinalObject::finishCreation): + (JSC::JSFinalObject::hasInlineStorage): + (JSC::JSFinalObject::finishCreation): + (JSC::JSObject::offsetOfInlineStorage): + (JSC::JSObject::setPropertyStorage): + (JSC::Structure::inlineStorageCapacity): + (JSC::Structure::isUsingInlineStorage): + (JSC::JSObject::putDirectInternal): + (JSC::JSObject::setStructureAndReallocateStorageIfNecessary): + (JSC::JSObject::putDirectWithoutTransition): + * runtime/Structure.cpp: + (JSC::Structure::Structure): + (JSC::nextPropertyStorageCapacity): + (JSC): + (JSC::Structure::growPropertyStorageCapacity): + (JSC::Structure::suggestedNewPropertyStorageSize): + * runtime/Structure.h: + (JSC::Structure::putWillGrowPropertyStorage): + (Structure): + +2012-06-28 Filip Pizlo <fpizlo@apple.com> + + DFG recompilation heuristics should be based on count, not rate + https://bugs.webkit.org/show_bug.cgi?id=90146 + + Reviewed by Oliver Hunt. + + This removes a bunch of code that was previously trying to prevent spurious + reoptimizations if a large enough majority of executions of a code block did + not result in OSR exit. It turns out that this code was purely harmful. This + patch removes all of that logic and replaces it with a dead-simple + heuristic: if you exit more than N times (where N is an exponential function + of the number of times the code block has already been recompiled) then we + will recompile. + + This appears to be a broad ~1% win on many benchmarks large and small. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::CodeBlock): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::osrExitCounter): + (JSC::CodeBlock::countOSRExit): + (CodeBlock): + (JSC::CodeBlock::addressOfOSRExitCounter): + (JSC::CodeBlock::offsetOfOSRExitCounter): + (JSC::CodeBlock::adjustedExitCountThreshold): + (JSC::CodeBlock::exitCountThresholdForReoptimization): + (JSC::CodeBlock::exitCountThresholdForReoptimizationFromLoop): + (JSC::CodeBlock::shouldReoptimizeNow): + (JSC::CodeBlock::shouldReoptimizeFromLoopNow): + * bytecode/ExecutionCounter.cpp: + (JSC::ExecutionCounter::setThreshold): + * bytecode/ExecutionCounter.h: + (ExecutionCounter): + (JSC::ExecutionCounter::clippedThreshold): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::compileBody): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): + * dfg/DFGOSRExitCompiler.cpp: + (JSC::DFG::OSRExitCompiler::handleExitCounts): + * dfg/DFGOperations.cpp: + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/Options.cpp: + (Options): + (JSC::Options::initializeOptions): + * runtime/Options.h: + (Options): + +2012-06-28 Mark Lam <mark.lam@apple.com> + + Adding a commenting utility to record BytecodeGenerator comments + with opcodes that are emitted. Presently, the comments can only + be constant strings. Adding comments for opcodes is optional. + If a comment is added, the comment will be printed following the + opcode when CodeBlock::dump() is called. + + This utility is disabled by default, and is only meant for VM + development purposes. It should not be enabled for product builds. + + To enable this utility, set ENABLE_BYTECODE_COMMENTS in CodeBlock.h + to 1. + + https://bugs.webkit.org/show_bug.cgi?id=90095 + + Reviewed by Geoffrey Garen. + + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dumpBytecodeCommentAndNewLine): Dumps the comment. + (JSC): + (JSC::CodeBlock::printUnaryOp): Add comment dumps. + (JSC::CodeBlock::printBinaryOp): Add comment dumps. + (JSC::CodeBlock::printConditionalJump): Add comment dumps. + (JSC::CodeBlock::printCallOp): Add comment dumps. + (JSC::CodeBlock::printPutByIdOp): Add comment dumps. + (JSC::CodeBlock::dump): Add comment dumps. + (JSC::CodeBlock::CodeBlock): + (JSC::CodeBlock::commentForBytecodeOffset): + Finds the comment for an opcode if available. + (JSC::CodeBlock::dumpBytecodeComments): + For debugging whether comments are collected. + It is not being called anywhere. + * bytecode/CodeBlock.h: + (CodeBlock): + (JSC::CodeBlock::bytecodeComments): + * bytecode/Comment.h: Added. + (JSC): + (Comment): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::emitOpcode): Calls emitComment(). + (JSC): + (JSC::BytecodeGenerator::emitComment): Adds comment to CodeBlock. + (JSC::BytecodeGenerator::prependComment): + Registers a comment for emitComemnt() to use later. + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + (JSC::BytecodeGenerator::emitComment): + (JSC::BytecodeGenerator::prependComment): + These are inlined versions of these functions that nullify them + when ENABLE_BYTECODE_COMMENTS is 0. + (JSC::BytecodeGenerator::comments): + +2012-06-28 Oliver Hunt <oliver@apple.com> + + 32bit DFG incorrectly claims an fpr is fillable even if it has not been proven double + https://bugs.webkit.org/show_bug.cgi?id=90127 + + Reviewed by Filip Pizlo. + + The 32-bit version of fillSpeculateDouble doesn't handle Number->fpr loads + correctly. This patch fixes this by killing the fill info in the GenerationInfo + when the spillFormat doesn't guarantee the value is a double. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): + +2012-06-28 Kent Tamura <tkent@chromium.org> + + Classify form control states by their owner forms + https://bugs.webkit.org/show_bug.cgi?id=89950 + + Reviewed by Hajime Morita. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + Expose WTF::StringBuilder::canShrink() + +2012-06-27 Michael Saboff <msaboff@apple.com> + + [Win] jscore-tests flakey + https://bugs.webkit.org/show_bug.cgi?id=88118 + + Reviewed by Jessie Berlin. + + jsDriver.pl on windows intermittently doesn't get the returned value from jsc, + instead it gets 126. Added a new option to jsc (-x) which prints the exit + code before exiting. jsDriver.pl uses this option on Windows and parses the + exit code output for the exit code, removing it before comparing the actual + and expected outputs. Filed a follow on "FIXME" defect: + [WIN] Intermittent failure for jsc return value to propagate through jsDriver.pl + https://bugs.webkit.org/show_bug.cgi?id=90119 + + * jsc.cpp: + (CommandLine::CommandLine): + (CommandLine): + (printUsageStatement): + (parseArguments): + (jscmain): + * tests/mozilla/jsDriver.pl: + (execute_tests): + +2012-06-27 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r121359. + http://trac.webkit.org/changeset/121359 + https://bugs.webkit.org/show_bug.cgi?id=90115 + + Broke many inspector tests (Requested by jpfau on #webkit). + + * interpreter/Interpreter.h: + (JSC::StackFrame::toString): + +2012-06-27 Filip Pizlo <fpizlo@apple.com> + + Javascript SHA-512 gives wrong hash on second and subsequent runs unless Web Inspector Javascript Debugging is on + https://bugs.webkit.org/show_bug.cgi?id=90053 + <rdar://problem/11764613> + + Reviewed by Mark Hahnenberg. + + The problem is that the code was assuming that the recovery should be Undefined if the source of + the SetLocal was !shouldGenerate(). But that's wrong, since the DFG optimizer may skip around a + UInt32ToNumber node (hence making it !shouldGenerate()) and keep the source of that node alive. + In that case we should base the recovery on the source of the UInt32ToNumber. The logic for this + was already in place but the fast check for !shouldGenerate() broke it. + + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): + +2012-06-27 Filip Pizlo <fpizlo@apple.com> + + DFG disassembly should be easier to read + https://bugs.webkit.org/show_bug.cgi?id=90106 + + Reviewed by Mark Hahnenberg. + + Did a few things: + + - Options::showDFGDisassembly now shows OSR exit disassembly as well. + + - Phi node dumping doesn't attempt to do line wrapping since it just made the dump harder + to read. + + - DFG graph disassembly view shows a few additional node types that turn out to be + essential for understanding OSR exits. + + Put together, these changes reinforce the philosophy that anything needed for computing + OSR exit is just as important as the machine code itself. Of course, we still don't take + that philosophy to its full extreme - for example Phantom nodes are not dumped. We may + revisit that in the future. + + * assembler/LinkBuffer.cpp: + (JSC::LinkBuffer::finalizeCodeWithDisassembly): + * assembler/LinkBuffer.h: + (JSC): + * dfg/DFGDisassembler.cpp: + (JSC::DFG::Disassembler::dump): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::dumpBlockHeader): + * dfg/DFGNode.h: + (JSC::DFG::Node::willHaveCodeGenOrOSR): + * dfg/DFGOSRExitCompiler.cpp: + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + +2012-06-25 Mark Hahnenberg <mhahnenberg@apple.com> + + JSLock should be per-JSGlobalData + https://bugs.webkit.org/show_bug.cgi?id=89123 + + Reviewed by Geoffrey Garen. + + * API/APIShims.h: + (APIEntryShimWithoutLock): + (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): Added an extra parameter to the constructor to + determine whether we should ref the JSGlobalData or not. We want to ref all the time except for in the + HeapTimer class because timerDidFire could run after somebody has started to tear down that particular + JSGlobalData, so we wouldn't want to resurrect the ref count of that JSGlobalData from 0 back to 1 after + its destruction has begun. + (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock): + (JSC::APIEntryShim::APIEntryShim): + (APIEntryShim): + (JSC::APIEntryShim::~APIEntryShim): + (JSC::APIEntryShim::init): Factored out common initialization code for the various APIEntryShim constructors. + Also moved the timeoutChecker stop and start here because we need to start after we've grabbed the API lock + and before we've released it, which can only done in APIEntryShim. + (JSC::APICallbackShim::~APICallbackShim): We no longer need to synchronize here. + * API/JSContextRef.cpp: + (JSGlobalContextCreate): + (JSGlobalContextCreateInGroup): + (JSGlobalContextRelease): + (JSContextCreateBacktrace): + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::tryAllocateSlowCase): + * heap/Heap.cpp: + (JSC::Heap::protect): + (JSC::Heap::unprotect): + (JSC::Heap::collect): + (JSC::Heap::setActivityCallback): + (JSC::Heap::activityCallback): + (JSC::Heap::sweeper): + * heap/Heap.h: Changed m_activityCallback and m_sweeper to be raw pointers rather than OwnPtrs because they + are now responsible for their own lifetime. Also changed the order of declaration of the GCActivityCallback + and the IncrementalSweeper to make sure they're the last things that get initialized during construction to + prevent any issues with uninitialized memory in the JSGlobalData/Heap they might care about. + (Heap): + * heap/HeapTimer.cpp: Refactored to allow for thread-safe operation and shutdown. + (JSC::HeapTimer::~HeapTimer): + (JSC::HeapTimer::invalidate): + (JSC): + (JSC::HeapTimer::didStartVMShutdown): Called at the beginning of ~JSGlobalData. If we're on the same thread + that the HeapTimer is running on, we kill the HeapTimer ourselves. If not, then we set some state in the + HeapTimer and schedule it to fire immediately so that it can notice and kill itself. + (JSC::HeapTimer::timerDidFire): We grab our mutex and check our JSGlobalData pointer. If it has been zero-ed + out, then we know the VM has started to shutdown and we should kill ourselves. Otherwise, grab the APIEntryShim, + but without ref-ing the JSGlobalData (we don't want to bring the JSGlobalData's ref-count from 0 to 1) in case + we were interrupted between releasing our mutex and trying to grab the APILock. + * heap/HeapTimer.h: + (HeapTimer): + * heap/IncrementalSweeper.cpp: + (JSC::IncrementalSweeper::doWork): We no longer need the API shim here since HeapTimer::timerDidFire handles + all of that for us. + (JSC::IncrementalSweeper::create): + * heap/IncrementalSweeper.h: + (IncrementalSweeper): + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::allocateSlowCase): + * heap/WeakBlock.cpp: + (JSC::WeakBlock::reap): + * jsc.cpp: + (functionGC): + (functionReleaseExecutableMemory): + (jscmain): + * runtime/Completion.cpp: + (JSC::checkSyntax): + (JSC::evaluate): + * runtime/GCActivityCallback.h: + (DefaultGCActivityCallback): + (JSC::DefaultGCActivityCallback::create): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + (JSC::JSGlobalData::~JSGlobalData): Signals to the two HeapTimers (GCActivityCallback and IncrementalSweeper) + that the VM has started shutting down. It then waits until the HeapTimer is done with whatever activity + it needs to do before continuing with any further destruction. Also asserts that we do not currently hold the + APILock because this could potentially cause deadlock when we try to signal to the HeapTimers using their mutexes. + (JSC::JSGlobalData::sharedInstance): Protect the initialization for the shared instance with the GlobalJSLock. + (JSC::JSGlobalData::sharedInstanceInternal): + * runtime/JSGlobalData.h: Change to be ThreadSafeRefCounted so that we don't have to worry about refing and + de-refing JSGlobalDatas on separate threads since we don't do it that often anyways. + (JSGlobalData): + (JSC::JSGlobalData::apiLock): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::~JSGlobalObject): + (JSC::JSGlobalObject::init): + * runtime/JSLock.cpp: + (JSC): + (JSC::GlobalJSLock::GlobalJSLock): For accessing the shared instance. + (JSC::GlobalJSLock::~GlobalJSLock): + (JSC::JSLockHolder::JSLockHolder): MutexLocker for JSLock. Also refs the JSGlobalData to keep it alive so that + it can successfully unlock it later without it disappearing from underneath it. + (JSC::JSLockHolder::~JSLockHolder): + (JSC::JSLock::JSLock): + (JSC::JSLock::~JSLock): + (JSC::JSLock::lock): Uses the spin lock for guarding the lock count and owner thread fields. Uses the mutex for + actually waiting for long periods. + (JSC::JSLock::unlock): + (JSC::JSLock::currentThreadIsHoldingLock): + (JSC::JSLock::dropAllLocks): + (JSC::JSLock::dropAllLocksUnconditionally): + (JSC::JSLock::grabAllLocks): + (JSC::JSLock::DropAllLocks::DropAllLocks): + (JSC::JSLock::DropAllLocks::~DropAllLocks): + * runtime/JSLock.h: + (JSC): + (GlobalJSLock): + (JSLockHolder): + (JSLock): + (DropAllLocks): + * runtime/WeakGCMap.h: + (JSC::WeakGCMap::set): + * testRegExp.cpp: + (realMain): + +2012-06-27 Filip Pizlo <fpizlo@apple.com> + + x86 disassembler confuses immediates with addresses + https://bugs.webkit.org/show_bug.cgi?id=90099 + + Reviewed by Mark Hahnenberg. + + Prepend "$" to immediates to disambiguate between immediates and addresses. This is in + accordance with the gas and AT&T syntax. + + * disassembler/udis86/udis86_syn-att.c: + (gen_operand): + +2012-06-27 Filip Pizlo <fpizlo@apple.com> + + Add a comment clarifying Options::showDisassembly versus Options::showDFGDisassembly. + + Rubber stamped by Mark Hahnenberg. + + * runtime/Options.cpp: + (JSC::Options::initializeOptions): + +2012-06-27 Anthony Scian <ascian@rim.com> + + Web Inspector [JSC]: Implement ScriptCallStack::stackTrace + https://bugs.webkit.org/show_bug.cgi?id=40118 + + Reviewed by Yong Li. + + Added member functions to expose function name, urlString, and line #. + Refactored toString to make use of these member functions to reduce + duplicated code for future maintenance. + + Manually tested refactoring of toString by tracing thrown exceptions. + + * interpreter/Interpreter.h: + (StackFrame): + (JSC::StackFrame::toString): + (JSC::StackFrame::friendlySourceURL): + (JSC::StackFrame::friendlyFunctionName): + (JSC::StackFrame::friendlyLineNumber): + +2012-06-27 Oswald Buddenhagen <oswald.buddenhagen@nokia.com> + + [Qt] Remove redundant c++11 warning suppression code + + This is already handled in default_post. + + Reviewed by Tor Arne Vestbø. + + * Target.pri: + +2012-06-26 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + [Qt] Add missing heades to HEADERS + + For JavaScriptCore there aren't any Qt specific files, so we include all + headers for easy editing in Qt Creator. + + Reviewed by Simon Hausmann. + + * Target.pri: + +2012-06-26 Dominic Cooney <dominicc@chromium.org> + + [Chromium] Remove unused build scripts and empty folders for JavaScriptCore w/ gyp + https://bugs.webkit.org/show_bug.cgi?id=90029 + + Reviewed by Adam Barth. + + * gyp: Removed. + * gyp/generate-derived-sources.sh: Removed. + * gyp/generate-dtrace-header.sh: Removed. + * gyp/run-if-exists.sh: Removed. + * gyp/update-info-plist.sh: Removed. + +2012-06-26 Geoffrey Garen <ggaren@apple.com> + + Reduced (but did not eliminate) use of "berzerker GC" + https://bugs.webkit.org/show_bug.cgi?id=89237 + + Reviewed by Gavin Barraclough. + + (PART 2) + + This part turns off "berzerker GC" and turns on incremental shrinking. + + * heap/IncrementalSweeper.cpp: + (JSC::IncrementalSweeper::doSweep): Free or shrink after sweeping to + maintain the behavior we used to get from the occasional berzerker GC, + which would run all finalizers and then free or shrink all blocks + synchronously. + + * heap/MarkedBlock.h: + (JSC::MarkedBlock::needsSweeping): Sweep zapped blocks, too. It's always + safe to sweep a zapped block (that's the point of zapping), and it's + sometimes profitable. For example, consider this case: Block A does some + allocation (transitioning Block A from Marked to FreeListed), then GC + happens (transitioning Block A to Zapped), then all objects in Block A + are free, then the incremental sweeper visits Block A. If we skipped + Zapped blocks, we'd skip Block A, even though it would be profitable to + run its destructors and free its memory. + + * runtime/GCActivityCallback.cpp: + (JSC::DefaultGCActivityCallback::doWork): Don't sweep eagerly; we'll do + this incrementally. + +2012-06-26 Filip Pizlo <fpizlo@apple.com> + + DFG PutByValAlias is too aggressive + https://bugs.webkit.org/show_bug.cgi?id=90026 + <rdar://problem/11751830> + + Reviewed by Gavin Barraclough. + + For CSE on normal arrays, we now treat PutByVal as impure. This does not appear to affect + performance by much. + + For CSE on typed arrays, we fix PutByValAlias by making GetByVal speculate that the access + is within bounds. This also has the effect of making our out-of-bounds handling consistent + with WebCore. + + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::byValIsPure): + (JSC::DFG::Graph::clobbersWorld): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray): + (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray): + +2012-06-26 Yong Li <yoli@rim.com> + + [BlackBerry] Add JSC statistics into about:memory + https://bugs.webkit.org/show_bug.cgi?id=89779 + + Reviewed by Rob Buis. + + Fix non-JIT build on BlackBerry broken by r121196. + + * runtime/MemoryStatistics.cpp: + (JSC::globalMemoryStatistics): + +2012-06-25 Filip Pizlo <fpizlo@apple.com> + + DFG::operationNewArray is unnecessarily slow, and may use the wrong array + prototype when inlined + https://bugs.webkit.org/show_bug.cgi?id=89821 + + Reviewed by Geoffrey Garen. + + Fixes all array allocations to use the right structure, and hence the right prototype. Adds + inlining of new Array(...) with a non-zero number of arguments. Optimizes allocations of + empty arrays. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleConstantInternalFunction): + * dfg/DFGCCallHelpers.h: + (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): + (CCallHelpers): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * runtime/JSArray.h: + (JSC): + (JSC::constructArray): + * runtime/JSGlobalObject.h: + (JSC): + (JSC::constructArray): + +2012-06-26 Filip Pizlo <fpizlo@apple.com> + + New fast/js/dfg-store-unexpected-value-into-argument-and-osr-exit.html fails on 32 bit + https://bugs.webkit.org/show_bug.cgi?id=89953 + + Reviewed by Zoltan Herczeg. + + DFG 32-bit JIT was confused about the difference between a predicted type and a + proven type. This is easy to get confused about, since a local that is predicted int32 + almost always means that the local must be an int32 since speculations are hoisted to + stores to locals. But that is less likely to be the case for arguments, where there is + an additional least-upper-bounding step: any store to an argument with a weird type + may force the argument to be any type. + + This patch basically duplicates the functionality in DFGSpeculativeJIT64.cpp for + GetLocal: the decision of whether to load a local as an int32 (or as an array, or as + a boolean) is made based on the AbstractValue::m_type, which is a type proof, rather + than the VariableAccessData::prediction(), which is a predicted type. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-06-25 Filip Pizlo <fpizlo@apple.com> + + JSC should try to make profiling deterministic because otherwise reproducing failures is + nearly impossible + https://bugs.webkit.org/show_bug.cgi?id=89940 + + Rubber stamped by Gavin Barraclough. + + This rolls out the part of http://trac.webkit.org/changeset/121215 that introduced randomness + into the system. Now, instead of randomizing the tier-up threshold, we always set it to an + artificially low (and statically predetermined!) value. This gives most of the benefit of + threshold randomization without actually making the system behave completely differently on + each invocation. + + * bytecode/ExecutionCounter.cpp: + (JSC::ExecutionCounter::setThreshold): + * runtime/Options.cpp: + (Options): + (JSC::Options::initializeOptions): + * runtime/Options.h: + (Options): + +2012-06-22 Filip Pizlo <fpizlo@apple.com> + + Value profiling should use tier-up threshold randomization to get more coverage + https://bugs.webkit.org/show_bug.cgi?id=89802 + + Reviewed by Gavin Barraclough. + + This patch causes both LLInt and Baseline JIT code to take the OSR slow path several + times before actually doing OSR. If we take the OSR slow path before the execution + count threshold is reached, then we just call CodeBlock::updateAllPredictions() to + compute the current latest least-upper-bound SpecType of all values seen in each + ValueProfile. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::stronglyVisitStrongReferences): + (JSC::CodeBlock::updateAllPredictionsAndCountLiveness): + (JSC): + (JSC::CodeBlock::updateAllPredictions): + (JSC::CodeBlock::shouldOptimizeNow): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::llintExecuteCounter): + (JSC::CodeBlock::jitExecuteCounter): + (CodeBlock): + (JSC::CodeBlock::updateAllPredictions): + * bytecode/ExecutionCounter.cpp: + (JSC::ExecutionCounter::setThreshold): + (JSC::ExecutionCounter::status): + (JSC): + * bytecode/ExecutionCounter.h: + (JSC::ExecutionCounter::count): + (ExecutionCounter): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGOperations.cpp: + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::jitCompileAndSetHeuristics): + (JSC::LLInt::entryOSR): + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::JSGlobalObject): + (JSC): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::weakRandomInteger): + * runtime/Options.cpp: + (Options): + (JSC::Options::initializeOptions): + * runtime/Options.h: + (Options): + * runtime/WeakRandom.h: + (WeakRandom): + (JSC::WeakRandom::seedUnsafe): + +2012-06-25 Yong Li <yoli@rim.com> + + [BlackBerry] Add JSC statistics into about:memory + https://bugs.webkit.org/show_bug.cgi?id=89779 + + Reviewed by Rob Buis. + + Add MemoryStatistics.cpp into build, and fill JITBytes for BlackBerry port. + + * PlatformBlackBerry.cmake: + * runtime/MemoryStatistics.cpp: + (JSC::globalMemoryStatistics): + +2012-06-23 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r121058. + http://trac.webkit.org/changeset/121058 + https://bugs.webkit.org/show_bug.cgi?id=89809 + + Patch causes plugins tests to crash in GTK debug builds + (Requested by zdobersek on #webkit). + + * API/APIShims.h: + (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): + (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock): + (APIEntryShimWithoutLock): + (JSC::APIEntryShim::APIEntryShim): + (APIEntryShim): + (JSC::APICallbackShim::~APICallbackShim): + * API/JSContextRef.cpp: + (JSGlobalContextCreate): + (JSGlobalContextCreateInGroup): + (JSGlobalContextRelease): + (JSContextCreateBacktrace): + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::tryAllocateSlowCase): + * heap/Heap.cpp: + (JSC::Heap::protect): + (JSC::Heap::unprotect): + (JSC::Heap::collect): + (JSC::Heap::setActivityCallback): + (JSC::Heap::activityCallback): + (JSC::Heap::sweeper): + * heap/Heap.h: + (Heap): + * heap/HeapTimer.cpp: + (JSC::HeapTimer::~HeapTimer): + (JSC::HeapTimer::invalidate): + (JSC::HeapTimer::timerDidFire): + (JSC): + * heap/HeapTimer.h: + (HeapTimer): + * heap/IncrementalSweeper.cpp: + (JSC::IncrementalSweeper::doWork): + (JSC::IncrementalSweeper::create): + * heap/IncrementalSweeper.h: + (IncrementalSweeper): + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::allocateSlowCase): + * heap/WeakBlock.cpp: + (JSC::WeakBlock::reap): + * jsc.cpp: + (functionGC): + (functionReleaseExecutableMemory): + (jscmain): + * runtime/Completion.cpp: + (JSC::checkSyntax): + (JSC::evaluate): + * runtime/GCActivityCallback.h: + (DefaultGCActivityCallback): + (JSC::DefaultGCActivityCallback::create): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + (JSC::JSGlobalData::~JSGlobalData): + (JSC::JSGlobalData::sharedInstance): + (JSC::JSGlobalData::sharedInstanceInternal): + * runtime/JSGlobalData.h: + (JSGlobalData): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::~JSGlobalObject): + (JSC::JSGlobalObject::init): + * runtime/JSLock.cpp: + (JSC): + (JSC::createJSLockCount): + (JSC::JSLock::lockCount): + (JSC::setLockCount): + (JSC::JSLock::JSLock): + (JSC::JSLock::lock): + (JSC::JSLock::unlock): + (JSC::JSLock::currentThreadIsHoldingLock): + (JSC::JSLock::DropAllLocks::DropAllLocks): + (JSC::JSLock::DropAllLocks::~DropAllLocks): + * runtime/JSLock.h: + (JSC): + (JSLock): + (JSC::JSLock::JSLock): + (JSC::JSLock::~JSLock): + (DropAllLocks): + * runtime/WeakGCMap.h: + (JSC::WeakGCMap::set): + * testRegExp.cpp: + (realMain): + +2012-06-22 Alexandru Chiculita <achicu@adobe.com> + + [CSS Shaders] Re-enable the CSS Shaders compile time flag on Safari Mac + https://bugs.webkit.org/show_bug.cgi?id=89781 + + Reviewed by Dean Jackson. + + Added ENABLE_CSS_SHADERS flag as enabled by default on Safari for Mac. + + * Configurations/FeatureDefines.xcconfig: + +2012-06-22 Filip Pizlo <fpizlo@apple.com> + + DFG tier-up should happen in prologues, not epilogues + https://bugs.webkit.org/show_bug.cgi?id=89752 + + Reviewed by Geoffrey Garen. + + This change has two outcomes: + + 1) Slightly reduces the likelihood that a function will be optimized both + standalone and via inlining. Previously, if you had a call sequence like foo() + calls bar() exactly once, and nobody else calls bar(), then bar() would get + optimized first (because it returns first) and then foo() gets optimized. If foo() + can inline bar() then that means that bar() gets optimized twice. But now, if we + optimize in prologues, then foo() will be optimized first. If it inlines bar(), + that means that there will no longer be any calls to bar(). + + 2) It lets us kill some code in JITStubs. Epilogue tier-up was very different from + loop tier-up, since epilogue tier-up should not attempt OSR. But prologue tier-up + requires OSR (albeit really easy OSR since it's the top of the compilation unit), + so it becomes just like loop tier-up. As a result, we now have one optimization + hook (cti_optimize) instead of two (cti_optimize_from_loop and + cti_optimize_from_ret). + + As a consequence of not having an optimization check in epilogues, the OSR exit + code must now trigger reoptimization itself instead of just signaling the epilogue + check to fire. + + This also adds the ability to count the number of DFG compilations, which was + useful for debugging this patch and might be useful for other things in the future. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::reoptimize): + (JSC): + * bytecode/CodeBlock.h: + (CodeBlock): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseCodeBlock): + * dfg/DFGDriver.cpp: + (DFG): + (JSC::DFG::getNumCompilations): + (JSC::DFG::compile): + * dfg/DFGDriver.h: + (DFG): + * dfg/DFGOSRExitCompiler.cpp: + (JSC::DFG::OSRExitCompiler::handleExitCounts): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * jit/JIT.cpp: + (JSC::JIT::emitOptimizationCheck): + * jit/JIT.h: + * jit/JITCall32_64.cpp: + (JSC::JIT::emit_op_ret): + (JSC::JIT::emit_op_ret_object_or_this): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_ret): + (JSC::JIT::emit_op_ret_object_or_this): + (JSC::JIT::emit_op_enter): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_enter): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * jit/JITStubs.h: + +2012-06-20 Mark Hahnenberg <mhahnenberg@apple.com> + + JSLock should be per-JSGlobalData + https://bugs.webkit.org/show_bug.cgi?id=89123 + + Reviewed by Gavin Barraclough. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * API/APIShims.h: + (APIEntryShimWithoutLock): + (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock): Added an extra parameter to the constructor to + determine whether we should ref the JSGlobalData or not. We want to ref all the time except for in the + HeapTimer class because timerDidFire could run after somebody has started to tear down that particular + JSGlobalData, so we wouldn't want to resurrect the ref count of that JSGlobalData from 0 back to 1 after + its destruction has begun. + (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock): Now derefs if it also refed. + (JSC::APIEntryShim::APIEntryShim): + (APIEntryShim): + (JSC::APIEntryShim::~APIEntryShim): + (JSC::APIEntryShim::init): Factored out common initialization code for the various APIEntryShim constructors. + Also moved the timeoutChecker stop and start here because we need to start after we've grabbed the API lock + and before we've released it, which can only done in APIEntryShim. + (JSC::APICallbackShim::~APICallbackShim): We no longer need to synchronize here. + * API/JSContextRef.cpp: + (JSGlobalContextCreate): + (JSGlobalContextCreateInGroup): + (JSGlobalContextRelease): + (JSContextCreateBacktrace): + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::tryAllocateSlowCase): + * heap/Heap.cpp: + (JSC::Heap::protect): + (JSC::Heap::unprotect): + (JSC::Heap::collect): + (JSC::Heap::setActivityCallback): + (JSC::Heap::activityCallback): + (JSC::Heap::sweeper): + * heap/Heap.h: Changed m_activityCallback and m_sweeper to be raw pointers rather than OwnPtrs because they + are now responsible for their own lifetime. Also changed the order of declaration of the GCActivityCallback + and the IncrementalSweeper to make sure they're the last things that get initialized during construction to + prevent any issues with uninitialized memory in the JSGlobalData/Heap they might care about. + (Heap): + * heap/HeapTimer.cpp: Refactored to allow for thread-safe operation and shutdown. + (JSC::HeapTimer::~HeapTimer): + (JSC::HeapTimer::invalidate): + (JSC): + (JSC::HeapTimer::didStartVMShutdown): Called at the beginning of ~JSGlobalData. If we're on the same thread + that the HeapTimer is running on, we kill the HeapTimer ourselves. If not, then we set some state in the + HeapTimer and schedule it to fire immediately so that it can notice and kill itself. + (JSC::HeapTimer::timerDidFire): We grab our mutex and check our JSGlobalData pointer. If it has been zero-ed + out, then we know the VM has started to shutdown and we should kill ourselves. Otherwise, grab the APIEntryShim, + but without ref-ing the JSGlobalData (we don't want to bring the JSGlobalData's ref-count from 0 to 1) in case + we were interrupted between releasing our mutex and trying to grab the APILock. + * heap/HeapTimer.h: + (HeapTimer): + * heap/IncrementalSweeper.cpp: + (JSC::IncrementalSweeper::doWork): We no longer need the API shim here since HeapTimer::timerDidFire handles + all of that for us. + (JSC::IncrementalSweeper::create): + * heap/IncrementalSweeper.h: + (IncrementalSweeper): + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::allocateSlowCase): + * heap/WeakBlock.cpp: + (JSC::WeakBlock::reap): + * jsc.cpp: + (functionGC): + (functionReleaseExecutableMemory): + (jscmain): + * runtime/Completion.cpp: + (JSC::checkSyntax): + (JSC::evaluate): + * runtime/GCActivityCallback.h: + (DefaultGCActivityCallback): + (JSC::DefaultGCActivityCallback::create): + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + (JSC::JSGlobalData::~JSGlobalData): Signals to the two HeapTimers (GCActivityCallback and IncrementalSweeper) + that the VM has started shutting down. It then waits until the HeapTimer is done with whatever activity + it needs to do before continuing with any further destruction. Also asserts that we do not currently hold the + APILock because this could potentially cause deadlock when we try to signal to the HeapTimers using their mutexes. + (JSC::JSGlobalData::sharedInstance): Protect the initialization for the shared instance with the GlobalJSLock. + (JSC::JSGlobalData::sharedInstanceInternal): + * runtime/JSGlobalData.h: Change to be ThreadSafeRefCounted so that we don't have to worry about refing and + de-refing JSGlobalDatas on separate threads since we don't do it that often anyways. + (JSGlobalData): + (JSC::JSGlobalData::apiLock): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::~JSGlobalObject): + (JSC::JSGlobalObject::init): + * runtime/JSLock.cpp: + (JSC): + (JSC::GlobalJSLock::GlobalJSLock): For accessing the shared instance. + (JSC::GlobalJSLock::~GlobalJSLock): + (JSC::JSLockHolder::JSLockHolder): MutexLocker for JSLock. Also refs the JSGlobalData to keep it alive so that + it can successfully unlock it later without it disappearing from underneath it. + (JSC::JSLockHolder::~JSLockHolder): + (JSC::JSLock::JSLock): + (JSC::JSLock::~JSLock): + (JSC::JSLock::lock): Uses the spin lock for guarding the lock count and owner thread fields. Uses the mutex for + actually waiting for long periods. + (JSC::JSLock::unlock): + (JSC::JSLock::currentThreadIsHoldingLock): + (JSC::JSLock::dropAllLocks): + (JSC::JSLock::dropAllLocksUnconditionally): + (JSC::JSLock::grabAllLocks): + (JSC::JSLock::DropAllLocks::DropAllLocks): + (JSC::JSLock::DropAllLocks::~DropAllLocks): + * runtime/JSLock.h: + (JSC): + (GlobalJSLock): + (JSLockHolder): + (JSLock): + (DropAllLocks): + * runtime/WeakGCMap.h: + (JSC::WeakGCMap::set): + * testRegExp.cpp: + (realMain): + +2012-06-22 Peter Beverloo <peter@chromium.org> + + [Chromium] Disable c++0x compatibility warnings in JavaScriptCore.gyp when building for Android + https://bugs.webkit.org/show_bug.cgi?id=88853 + + Reviewed by Steve Block. + + The Android exclusions were necessary to fix a gyp generation error, as + the gcc_version variable wasn't being defined for Android. Remove these + exceptions when Chromium is able to define the gcc_version variable. + + * JavaScriptCore.gyp/JavaScriptCore.gyp: + +2012-06-21 Filip Pizlo <fpizlo@apple.com> + + op_resolve_global should not prevent DFG inlining + https://bugs.webkit.org/show_bug.cgi?id=89726 + + Reviewed by Gavin Barraclough. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::CodeBlock): + (JSC::CodeBlock::shrinkToFit): + * bytecode/GlobalResolveInfo.h: + (JSC::GlobalResolveInfo::GlobalResolveInfo): + (GlobalResolveInfo): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGCapabilities.h: + (JSC::DFG::canInlineOpcode): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-06-20 Filip Pizlo <fpizlo@apple.com> + + DFG should inline 'new Array()' + https://bugs.webkit.org/show_bug.cgi?id=89632 + + Reviewed by Geoffrey Garen. + + This adds support for treating InternalFunction like intrinsics. The code + to do so is actually quite clean, so I don't feel bad about perpetuating + the InternalFunction vs. JSFunction-with-NativeExecutable dichotomy. + + Currently this newfound power is only used to inline 'new Array()'. + + * dfg/DFGByteCodeParser.cpp: + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::handleCall): + (JSC::DFG::ByteCodeParser::handleConstantInternalFunction): + (DFG): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::isInternalFunctionConstant): + (JSC::DFG::Graph::valueOfInternalFunctionConstant): + +2012-06-21 Mark Hahnenberg <mhahnenberg@apple.com> + + Adding copyrights to new files. + + * heap/HeapTimer.cpp: + * heap/HeapTimer.h: + * heap/IncrementalSweeper.cpp: + * heap/IncrementalSweeper.h: + +2012-06-21 Arnaud Renevier <arno@renevier.net> + + make sure headers are included only once per file + https://bugs.webkit.org/show_bug.cgi?id=88922 + + Reviewed by Alexey Proskuryakov. + + * bytecode/CodeBlock.h: + * heap/MachineStackMarker.cpp: + * runtime/JSVariableObject.h: + +2012-06-21 Ryuan Choi <ryuan.choi@gmail.com> + + [EFL][WK2] Make WebKit2/Efl headers and resources installable. + https://bugs.webkit.org/show_bug.cgi?id=88207 + + Reviewed by Chang Shu. + + * shell/CMakeLists.txt: Use ${EXEC_INSTALL_DIR} instead of hardcoding "bin" + +2012-06-20 Geoffrey Garen <ggaren@apple.com> + + Reduced (but did not eliminate) use of "berzerker GC" + https://bugs.webkit.org/show_bug.cgi?id=89237 + + Reviewed by Gavin Barraclough. + + (PART 1) + + This patch turned out to be crashy, so I'm landing the non-crashy bits + first. + + This part is pre-requisite refactoring. I didn't actually turn off + "berzerker GC" or turn on incremental shrinking. + + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::removeBlock): Make sure to clear the free list when + we throw away the block we're currently allocating out of. Otherwise, we'll + allocate out of a stale free list. + + * heap/MarkedSpace.cpp: + (JSC::Free::Free): + (JSC::Free::operator()): + (JSC::Free::returnValue): Refactored this functor to use a shared helper + function, so we can share our implementation with the incremental sweeper. + + Also changed to freeing individual blocks immediately instead of linking + them into a list for later freeing. This makes the programming interface + simpler, and it's slightly more efficient to boot. + + (JSC::MarkedSpace::~MarkedSpace): Updated for rename. + + (JSC::MarkedSpace::freeBlock): + (JSC::MarkedSpace::freeOrShrinkBlock): New helper functions to share behavior + with the incremental sweeper. + + (JSC::MarkedSpace::shrink): Updated for new functor behavior. + + * heap/MarkedSpace.h: Statically typed languages are awesome. + +2012-06-20 Filip Pizlo <fpizlo@apple.com> + + DFG should optimize ResolveGlobal + https://bugs.webkit.org/show_bug.cgi?id=89617 + + Reviewed by Oliver Hunt. + + This adds inlining of ResolveGlobal accesses that are known monomorphic. It also + adds the specific function optimization to ResolveGlobal, when it is inlined. And, + it makes internal functions act like specific functions, since that will be the + most common use-case of this optimization. + + This is only a slighy speed-up (sub 1%), since we don't yet do the obvious thing + with this optimization, which is to completely inline common "globally resolved" + function and constructor calls, like "new Array()". + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::globalResolveInfoForBytecodeOffset): + * bytecode/CodeBlock.h: + (CodeBlock): + (JSC::CodeBlock::numberOfGlobalResolveInfos): + * bytecode/GlobalResolveInfo.h: + (JSC::getGlobalResolveInfoBytecodeOffset): + (JSC): + * bytecode/ResolveGlobalStatus.cpp: Added. + (JSC): + (JSC::computeForStructure): + (JSC::computeForLLInt): + (JSC::ResolveGlobalStatus::computeFor): + * bytecode/ResolveGlobalStatus.h: Added. + (JSC): + (ResolveGlobalStatus): + (JSC::ResolveGlobalStatus::ResolveGlobalStatus): + (JSC::ResolveGlobalStatus::state): + (JSC::ResolveGlobalStatus::isSet): + (JSC::ResolveGlobalStatus::operator!): + (JSC::ResolveGlobalStatus::isSimple): + (JSC::ResolveGlobalStatus::takesSlowPath): + (JSC::ResolveGlobalStatus::structure): + (JSC::ResolveGlobalStatus::offset): + (JSC::ResolveGlobalStatus::specificValue): + * dfg/DFGByteCodeParser.cpp: + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::handleGetByOffset): + (DFG): + (JSC::DFG::ByteCodeParser::handleGetById): + (JSC::DFG::ByteCodeParser::parseBlock): + * runtime/JSObject.cpp: + (JSC::getCallableObjectSlow): + (JSC): + (JSC::JSObject::put): + (JSC::JSObject::putDirectVirtual): + (JSC::JSObject::putDirectAccessor): + * runtime/JSObject.h: + (JSC): + (JSC::getCallableObject): + (JSC::JSObject::putOwnDataProperty): + (JSC::JSObject::putDirect): + (JSC::JSObject::putDirectWithoutTransition): + +2012-06-20 Filip Pizlo <fpizlo@apple.com> + + Functions on global objects should be specializable + https://bugs.webkit.org/show_bug.cgi?id=89615 + + Reviewed by Oliver Hunt. + + I tested to see if this brought back the bug in https://bugs.webkit.org/show_bug.cgi?id=33343, + and it didn't. Bug 33343 was the reason why we disabled global object function specialization + to begin with. So I'm guessing this is safe. + + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::init): + +2012-06-20 Filip Pizlo <fpizlo@apple.com> + + build-webkit failure due to illegal 32-bit integer constants in code + generated by offlineasm + https://bugs.webkit.org/show_bug.cgi?id=89347 + + Reviewed by Geoffrey Garen. + + The offending constants are the magic numbers used by offlineasm to find + offsets in the generated machine code. Added code to turn them into what + the C++ compiler will believe to be valid 32-bit values. + + * offlineasm/offsets.rb: + +2012-06-19 Geoffrey Garen <ggaren@apple.com> + + Made the incremental sweeper more aggressive + https://bugs.webkit.org/show_bug.cgi?id=89527 + + Reviewed by Oliver Hunt. + + This is a pre-requisite to getting rid of "berzerker GC" because we need + the sweeper to reclaim memory in a timely fashion, or we'll see a memory + footprint regression. + + * heap/IncrementalSweeper.h: + * heap/IncrementalSweeper.cpp: + (JSC::IncrementalSweeper::scheduleTimer): Since the time slice is predictable, + no need to use a data member to record it. + + (JSC::IncrementalSweeper::doSweep): Sweep as many blocks as we can in a + small time slice. This is better than sweeping only one block per timer + fire because that strategy has a heavy timer overhead, and artificially + delays memory reclamation. + +2012-06-20 Filip Pizlo <fpizlo@apple.com> + + DFG should be able to print disassembly interleaved with the IR + https://bugs.webkit.org/show_bug.cgi?id=89551 + + Reviewed by Geoffrey Garen. + + This change also removes running Dominators unconditionally on every DFG + compile. Dominators are designed to be computed on-demand, and currently + the only demand is graph dumps. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * assembler/ARMv7Assembler.h: + (JSC::ARMv7Assembler::labelIgnoringWatchpoints): + (ARMv7Assembler): + * assembler/AbstractMacroAssembler.h: + (AbstractMacroAssembler): + (JSC::AbstractMacroAssembler::labelIgnoringWatchpoints): + * assembler/X86Assembler.h: + (X86Assembler): + (JSC::X86Assembler::labelIgnoringWatchpoints): + * dfg/DFGCommon.h: + (JSC::DFG::shouldShowDisassembly): + (DFG): + * dfg/DFGDisassembler.cpp: Added. + (DFG): + (JSC::DFG::Disassembler::Disassembler): + (JSC::DFG::Disassembler::dump): + (JSC::DFG::Disassembler::dumpDisassembly): + * dfg/DFGDisassembler.h: Added. + (DFG): + (Disassembler): + (JSC::DFG::Disassembler::setStartOfCode): + (JSC::DFG::Disassembler::setForBlock): + (JSC::DFG::Disassembler::setForNode): + (JSC::DFG::Disassembler::setEndOfMainPath): + (JSC::DFG::Disassembler::setEndOfCode): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::dumpCodeOrigin): + (JSC::DFG::Graph::amountOfNodeWhiteSpace): + (DFG): + (JSC::DFG::Graph::printNodeWhiteSpace): + (JSC::DFG::Graph::dump): + (JSC::DFG::Graph::dumpBlockHeader): + * dfg/DFGGraph.h: + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::JITCompiler): + (DFG): + (JSC::DFG::JITCompiler::compile): + (JSC::DFG::JITCompiler::compileFunction): + * dfg/DFGJITCompiler.h: + (JITCompiler): + (JSC::DFG::JITCompiler::setStartOfCode): + (JSC::DFG::JITCompiler::setForBlock): + (JSC::DFG::JITCompiler::setForNode): + (JSC::DFG::JITCompiler::setEndOfMainPath): + (JSC::DFG::JITCompiler::setEndOfCode): + * dfg/DFGNode.h: + (Node): + (JSC::DFG::Node::willHaveCodeGen): + * dfg/DFGNodeFlags.cpp: + (JSC::DFG::nodeFlagsAsString): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + * runtime/Options.cpp: + (Options): + (JSC::Options::initializeOptions): + * runtime/Options.h: + (Options): + +2012-06-19 Filip Pizlo <fpizlo@apple.com> + + JSC should be able to show disassembly for all generated JIT code + https://bugs.webkit.org/show_bug.cgi?id=89536 + + Reviewed by Gavin Barraclough. + + Now instead of doing linkBuffer.finalizeCode(), you do + FINALIZE_CODE(linkBuffer, (... explanation ...)). FINALIZE_CODE() then + prints your explanation and the disassembled code, if + Options::showDisassembly is set to true. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * assembler/LinkBuffer.cpp: Added. + (JSC): + (JSC::LinkBuffer::finalizeCodeWithoutDisassembly): + (JSC::LinkBuffer::finalizeCodeWithDisassembly): + (JSC::LinkBuffer::linkCode): + (JSC::LinkBuffer::performFinalization): + (JSC::LinkBuffer::dumpLinkStatistics): + (JSC::LinkBuffer::dumpCode): + * assembler/LinkBuffer.h: + (LinkBuffer): + (JSC): + * assembler/MacroAssemblerCodeRef.h: + (JSC::MacroAssemblerCodeRef::tryToDisassemble): + (MacroAssemblerCodeRef): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::compile): + (JSC::DFG::JITCompiler::compileFunction): + * dfg/DFGOSRExitCompiler.cpp: + * dfg/DFGRepatch.cpp: + (JSC::DFG::generateProtoChainAccessStub): + (JSC::DFG::tryCacheGetByID): + (JSC::DFG::tryBuildGetByIDList): + (JSC::DFG::emitPutReplaceStub): + (JSC::DFG::emitPutTransitionStub): + * dfg/DFGThunks.cpp: + (JSC::DFG::osrExitGenerationThunkGenerator): + * disassembler/Disassembler.h: + (JSC): + (JSC::tryToDisassemble): + * disassembler/UDis86Disassembler.cpp: + (JSC::tryToDisassemble): + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + * jit/JITCode.h: + (JSC::JITCode::tryToDisassemble): + * jit/JITOpcodes.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::privateCompileCTIMachineTrampolines): + (JSC::JIT::privateCompileCTINativeCall): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::stringGetByValStubGenerator): + (JSC::JIT::privateCompilePutByIdTransition): + (JSC::JIT::privateCompilePatchGetArrayLength): + (JSC::JIT::privateCompileGetByIdProto): + (JSC::JIT::privateCompileGetByIdSelfList): + (JSC::JIT::privateCompileGetByIdProtoList): + (JSC::JIT::privateCompileGetByIdChainList): + (JSC::JIT::privateCompileGetByIdChain): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::stringGetByValStubGenerator): + (JSC::JIT::privateCompilePutByIdTransition): + (JSC::JIT::privateCompilePatchGetArrayLength): + (JSC::JIT::privateCompileGetByIdProto): + (JSC::JIT::privateCompileGetByIdSelfList): + (JSC::JIT::privateCompileGetByIdProtoList): + (JSC::JIT::privateCompileGetByIdChainList): + (JSC::JIT::privateCompileGetByIdChain): + * jit/SpecializedThunkJIT.h: + (JSC::SpecializedThunkJIT::finalize): + * jit/ThunkGenerators.cpp: + (JSC::charCodeAtThunkGenerator): + (JSC::charAtThunkGenerator): + (JSC::fromCharCodeThunkGenerator): + (JSC::sqrtThunkGenerator): + (JSC::floorThunkGenerator): + (JSC::ceilThunkGenerator): + (JSC::roundThunkGenerator): + (JSC::expThunkGenerator): + (JSC::logThunkGenerator): + (JSC::absThunkGenerator): + (JSC::powThunkGenerator): + * llint/LLIntThunks.cpp: + (JSC::LLInt::generateThunkWithJumpTo): + (JSC::LLInt::functionForCallEntryThunkGenerator): + (JSC::LLInt::functionForConstructEntryThunkGenerator): + (JSC::LLInt::functionForCallArityCheckThunkGenerator): + (JSC::LLInt::functionForConstructArityCheckThunkGenerator): + (JSC::LLInt::evalEntryThunkGenerator): + (JSC::LLInt::programEntryThunkGenerator): + * runtime/Options.cpp: + (Options): + (JSC::Options::initializeOptions): + * runtime/Options.h: + (Options): + * yarr/YarrJIT.cpp: + (JSC::Yarr::YarrGenerator::compile): + +2012-06-19 Mark Hahnenberg <mhahnenberg@apple.com> + + [Qt][Mac] REGRESSION(r120742): It broke the build + https://bugs.webkit.org/show_bug.cgi?id=89516 + + Reviewed by Geoffrey Garen. + + Removing GCActivityCallbackCF.cpp because it doesn't mesh well with cross-platform + code on Darwin (e.g. Qt). We now use plain ol' vanilla ifdefs to handle platforms + without CF support. These if-defs will probably disappear in the future when we + use cross-platform timers in HeapTimer. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/GCActivityCallback.cpp: + (JSC): + (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback): + (JSC::DefaultGCActivityCallback::doWork): + (JSC::DefaultGCActivityCallback::scheduleTimer): + (JSC::DefaultGCActivityCallback::cancelTimer): + (JSC::DefaultGCActivityCallback::didAllocate): + (JSC::DefaultGCActivityCallback::willCollect): + (JSC::DefaultGCActivityCallback::cancel): + * runtime/GCActivityCallbackCF.cpp: Removed. + +2012-06-19 Filip Pizlo <fpizlo@apple.com> + + DFG CFA forgets to notify subsequent phases of found constants if it proves LogicalNot to be a constant + https://bugs.webkit.org/show_bug.cgi?id=89511 + <rdar://problem/11700089> + + Reviewed by Geoffrey Garen. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + +2012-06-19 Mark Lam <mark.lam@apple.com> + + CodeBlock::needsCallReturnIndices() is no longer needed. + https://bugs.webkit.org/show_bug.cgi?id=89490 + + Reviewed by Geoffrey Garen. + + * bytecode/CodeBlock.h: + (JSC::CodeBlock::needsCallReturnIndices): removed. + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::link): + * jit/JIT.cpp: + (JSC::JIT::privateCompile): + +2012-06-19 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, try to fix Windows build. + + * JavaScriptCore.vcproj/JavaScriptCore/copy-files.cmd: + +2012-06-17 Filip Pizlo <fpizlo@apple.com> + + It should be possible to look at disassembly + https://bugs.webkit.org/show_bug.cgi?id=89319 + + Reviewed by Sam Weinig. + + This imports the udis86 disassembler library. The library is placed + behind an abstraction in disassembler/Disassembler.h, so that we can + in the future use other disassemblers (for other platforms) whenever + appropriate. As a first step, the disassembler is being invoked for + DFG verbose dumps. + + If we ever want to merge a new version of udis86 in the future, I've + made notes about changes I made to the library in + disassembler/udis86/differences.txt. + + * CMakeLists.txt: + * DerivedSources.make: + * GNUmakefile.list.am: + * JavaScriptCore.pri: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops: + * JavaScriptCore.xcodeproj/project.pbxproj: + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::compile): + (JSC::DFG::JITCompiler::compileFunction): + * disassembler: Added. + * disassembler/Disassembler.h: Added. + (JSC): + (JSC::tryToDisassemble): + * disassembler/UDis86Disassembler.cpp: Added. + (JSC): + (JSC::tryToDisassemble): + * disassembler/udis86: Added. + * disassembler/udis86/differences.txt: Added. + * disassembler/udis86/itab.py: Added. + (UdItabGenerator): + (UdItabGenerator.__init__): + (UdItabGenerator.toGroupId): + (UdItabGenerator.genLookupTable): + (UdItabGenerator.genLookupTableList): + (UdItabGenerator.genInsnTable): + (genItabH): + (genItabH.UD_ITAB_H): + (genItabC): + (genItab): + (main): + * disassembler/udis86/optable.xml: Added. + * disassembler/udis86/ud_opcode.py: Added. + (UdOpcodeTables): + (UdOpcodeTables.sizeOfTable): + (UdOpcodeTables.nameOfTable): + (UdOpcodeTables.updateTable): + (UdOpcodeTables.Insn): + (UdOpcodeTables.Insn.__init__): + (UdOpcodeTables.Insn.__init__.opcode): + (UdOpcodeTables.parse): + (UdOpcodeTables.addInsnDef): + (UdOpcodeTables.print_table): + (UdOpcodeTables.print_tree): + * disassembler/udis86/ud_optable.py: Added. + (UdOptableXmlParser): + (UdOptableXmlParser.parseDef): + (UdOptableXmlParser.parse): + (printFn): + (parse): + (main): + * disassembler/udis86/udis86.c: Added. + (ud_init): + (ud_disassemble): + (ud_set_mode): + (ud_set_vendor): + (ud_set_pc): + (ud): + (ud_insn_asm): + (ud_insn_off): + (ud_insn_hex): + (ud_insn_ptr): + (ud_insn_len): + * disassembler/udis86/udis86.h: Added. + * disassembler/udis86/udis86_decode.c: Added. + (eff_adr_mode): + (ud_lookup_mnemonic): + (decode_prefixes): + (modrm): + (resolve_operand_size): + (resolve_mnemonic): + (decode_a): + (decode_gpr): + (resolve_gpr64): + (resolve_gpr32): + (resolve_reg): + (decode_imm): + (decode_modrm_reg): + (decode_modrm_rm): + (decode_o): + (decode_operand): + (decode_operands): + (clear_insn): + (resolve_mode): + (gen_hex): + (decode_insn): + (decode_3dnow): + (decode_ssepfx): + (decode_ext): + (decode_opcode): + (ud_decode): + * disassembler/udis86/udis86_decode.h: Added. + (ud_itab_entry_operand): + (ud_itab_entry): + (ud_lookup_table_list_entry): + (sse_pfx_idx): + (mode_idx): + (modrm_mod_idx): + (vendor_idx): + (is_group_ptr): + (group_idx): + * disassembler/udis86/udis86_extern.h: Added. + * disassembler/udis86/udis86_input.c: Added. + (inp_buff_hook): + (inp_file_hook): + (ud): + (ud_set_user_opaque_data): + (ud_get_user_opaque_data): + (ud_set_input_buffer): + (ud_set_input_file): + (ud_input_skip): + (ud_input_end): + (ud_inp_next): + (ud_inp_back): + (ud_inp_peek): + (ud_inp_move): + (ud_inp_uint8): + (ud_inp_uint16): + (ud_inp_uint32): + (ud_inp_uint64): + * disassembler/udis86/udis86_input.h: Added. + * disassembler/udis86/udis86_itab_holder.c: Added. + * disassembler/udis86/udis86_syn-att.c: Added. + (opr_cast): + (gen_operand): + (ud_translate_att): + * disassembler/udis86/udis86_syn-intel.c: Added. + (opr_cast): + (gen_operand): + (ud_translate_intel): + * disassembler/udis86/udis86_syn.c: Added. + * disassembler/udis86/udis86_syn.h: Added. + (mkasm): + * disassembler/udis86/udis86_types.h: Added. + (ud_operand): + (ud): + * jit/JITCode.h: + (JITCode): + (JSC::JITCode::tryToDisassemble): + +2012-06-19 Mark Hahnenberg <mhahnenberg@apple.com> + + GCActivityCallback and IncrementalSweeper should share code + https://bugs.webkit.org/show_bug.cgi?id=89400 + + Reviewed by Geoffrey Garen. + + A lot of functionality is duplicated between GCActivityCallback and IncrementalSweeper. + We should extract the common functionality out into a separate class that both of them + can inherit from. This refactoring will be an even greater boon when we add the ability + to shut these two agents down in a thread-safe fashion + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * heap/Heap.cpp: + (JSC::Heap::Heap): Move initialization down so that the JSGlobalData has a valid Heap when + we're initializing the GCActivityCallback and the IncrementalSweeper. + * heap/Heap.h: + (Heap): + * heap/HeapTimer.cpp: Added. + (JSC): + (JSC::HeapTimer::HeapTimer): Initialize the various base class data that + DefaultGCActivityCallback::commonConstructor() used to do. + (JSC::HeapTimer::~HeapTimer): Call to invalidate(). + (JSC::HeapTimer::synchronize): Same functionality as the old DefaultGCActivityCallback::synchronize(). + Virtual so that non-CF subclasses can override. + (JSC::HeapTimer::invalidate): Tears down the runloop timer to prevent any future firing. + (JSC::HeapTimer::timerDidFire): Callback to pass to the timer function. Casts and calls the virtual doWork(). + * heap/HeapTimer.h: Added. This is the class that serves as the common base class for + both GCActivityCallback and IncrementalSweeper. It handles setting up and tearing down run loops and synchronizing + across threads for its subclasses. + (JSC): + (HeapTimer): + * heap/IncrementalSweeper.cpp: Changes to accomodate the extraction of common functionality + between IncrementalSweeper and GCActivityCallback into a common ancestor. + (JSC): + (JSC::IncrementalSweeper::doWork): + (JSC::IncrementalSweeper::IncrementalSweeper): + (JSC::IncrementalSweeper::cancelTimer): + (JSC::IncrementalSweeper::create): + * heap/IncrementalSweeper.h: + (IncrementalSweeper): + * runtime/GCActivityCallback.cpp: + (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback): + (JSC::DefaultGCActivityCallback::doWork): + * runtime/GCActivityCallback.h: + (GCActivityCallback): + (JSC::GCActivityCallback::willCollect): + (JSC::GCActivityCallback::GCActivityCallback): + (JSC): + (DefaultGCActivityCallback): Remove the platform data struct. The platform data should be kept in + the class itself so as to be accessible by doWork(). Most of the platform data for CF is kept in + HeapTimer anyways, so we only need the m_delay field now. + * runtime/GCActivityCallbackBlackBerry.cpp: + (JSC): + (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback): + (JSC::DefaultGCActivityCallback::doWork): + (JSC::DefaultGCActivityCallback::didAllocate): + * runtime/GCActivityCallbackCF.cpp: + (JSC): + (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback): + (JSC::DefaultGCActivityCallback::doWork): + (JSC::DefaultGCActivityCallback::scheduleTimer): + (JSC::DefaultGCActivityCallback::cancelTimer): + (JSC::DefaultGCActivityCallback::didAllocate): + (JSC::DefaultGCActivityCallback::willCollect): + (JSC::DefaultGCActivityCallback::cancel): + + +2012-06-19 Mike West <mkwst@chromium.org> + + Introduce ENABLE_CSP_NEXT configuration flag. + https://bugs.webkit.org/show_bug.cgi?id=89300 + + Reviewed by Adam Barth. + + The 1.0 draft of the Content Security Policy spec is just about to + move to Last Call. We'll hide work on the upcoming 1.1 spec behind + this ENABLE flag, disabled by default. + + Spec: https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html + + * Configurations/FeatureDefines.xcconfig: + +2012-06-18 Mark Lam <mark.lam@apple.com> + + Changed JSC to always record line number information so that error.stack + and window.onerror() can report proper line numbers. + https://bugs.webkit.org/show_bug.cgi?id=89410 + + Reviewed by Geoffrey Garen. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::CodeBlock): + (JSC::CodeBlock::lineNumberForBytecodeOffset): + (JSC::CodeBlock::shrinkToFit): m_lineInfo is now available unconditionally. + + * bytecode/CodeBlock.h: + (JSC::CodeBlock::addLineInfo): + (JSC::CodeBlock::hasLineInfo): Unused. Now removed. + (JSC::CodeBlock::needsCallReturnIndices): + (CodeBlock): + (RareData): Hoisted m_lineInfo out of m_rareData. m_lineInfo is now + filled in unconditionally. + + * bytecompiler/BytecodeGenerator.h: + (JSC::BytecodeGenerator::addLineInfo): + +2012-06-18 Andy Estes <aestes@apple.com> + + Fix r120663, which didn't land the change that was reviewed. + +2012-06-18 Andy Estes <aestes@apple.com> + + [JSC] In JSGlobalData.cpp, enableAssembler() sometimes leaks two CF objects + https://bugs.webkit.org/show_bug.cgi?id=89415 + + Reviewed by Sam Weinig. + + In the case where canUseJIT was a non-NULL CFBooleanRef, + enableAssembler() would leak both canUseJITKey and canUseJIT by + returning before calling CFRelease. Fix this by using RetainPtr. + + * runtime/JSGlobalData.cpp: + (JSC::enableAssembler): + +2012-06-17 Geoffrey Garen <ggaren@apple.com> + + GC copy phase spends needless cycles zero-filling blocks + https://bugs.webkit.org/show_bug.cgi?id=89128 + + Reviewed by Gavin Barraclough. + + We only need to zero-fill when we're allocating memory that might not + get fully initialized before GC. + + * heap/CopiedBlock.h: + (JSC::CopiedBlock::createNoZeroFill): + (JSC::CopiedBlock::create): Added a way to create without zero-filling. + This is our optimization. + + (JSC::CopiedBlock::zeroFillToEnd): + (JSC::CopiedBlock::CopiedBlock): Split zero-filling out from creation, + so we can sometimes create without zero-filling. + + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::init): + (JSC::CopiedSpace::tryAllocateSlowCase): + (JSC::CopiedSpace::doneCopying): Renamed addNewBlock to allocateBlock() + to clarify that the new block is always newly-allocated. + + (JSC::CopiedSpace::doneFillingBlock): Make sure to zero-fill to the end + of a block that might be used in the future for allocation. (Most of the + time, this is a no-op, since we've already filled the block completely.) + + (JSC::CopiedSpace::getFreshBlock): Removed this function because the + abstraction of "allocation must succeed" is no longer useful. + + * heap/CopiedSpace.h: Updated declarations to match. + + * heap/CopiedSpaceInlineMethods.h: + (JSC::CopiedSpace::allocateBlockForCopyingPhase): New function, which + knows that it can skip zero-filling. + + Added tighter scoping to our lock, to improve parallelism. + + (JSC::CopiedSpace::allocateBlock): Folded getFreshBlock functionality + into this function, for simplicity. + + * heap/MarkStack.cpp: + (JSC::SlotVisitor::startCopying): + (JSC::SlotVisitor::allocateNewSpace): Use our new zero-fill-free helper + function for great good. + +2012-06-17 Filip Pizlo <fpizlo@apple.com> + + DFG should attempt to use structure watchpoints for all inlined get_by_id's and put_by_id's + https://bugs.webkit.org/show_bug.cgi?id=89316 + + Reviewed by Oliver Hunt. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::addStructureTransitionCheck): + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::handleGetById): + (JSC::DFG::ByteCodeParser::parseBlock): + +2012-06-15 Yong Li <yoli@rim.com> + + [BlackBerry] Put platform-specific GC policy in GCActivityCallback + https://bugs.webkit.org/show_bug.cgi?id=89236 + + Reviewed by Rob Buis. + + Add GCActivityCallbackBlackBerry.cpp and implement platform-specific + low memory GC policy there. + + * PlatformBlackBerry.cmake: + * heap/Heap.h: + (JSC::Heap::isSafeToCollect): Added. + * runtime/GCActivityCallbackBlackBerry.cpp: Added. + (JSC): + (JSC::DefaultGCActivityCallbackPlatformData::DefaultGCActivityCallbackPlatformData): + (DefaultGCActivityCallbackPlatformData): + (JSC::DefaultGCActivityCallback::DefaultGCActivityCallback): + (JSC::DefaultGCActivityCallback::~DefaultGCActivityCallback): + (JSC::DefaultGCActivityCallback::didAllocate): + (JSC::DefaultGCActivityCallback::willCollect): + (JSC::DefaultGCActivityCallback::synchronize): + (JSC::DefaultGCActivityCallback::cancel): + +2012-06-15 Filip Pizlo <fpizlo@apple.com> + + DFG should be able to set watchpoints on structure transitions in the + method check prototype chain + https://bugs.webkit.org/show_bug.cgi?id=89058 + + Adding the same assertion to 32-bit that I added to 64-bit. This change + does not affect correctness but it's a good thing for assertion coverage. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-06-13 Filip Pizlo <fpizlo@apple.com> + + DFG should be able to set watchpoints on structure transitions in the + method check prototype chain + https://bugs.webkit.org/show_bug.cgi?id=89058 + + Reviewed by Gavin Barraclough. + + This adds the ability to set watchpoints on Structures, and then does + the most modest thing we can do with this ability: the DFG now sets + watchpoints on structure transitions in the prototype chain of method + checks. + + This appears to be a >1% speed-up on V8. + + * bytecode/PutByIdStatus.cpp: + (JSC::PutByIdStatus::computeFromLLInt): + (JSC::PutByIdStatus::computeFor): + * bytecode/StructureSet.h: + (JSC::StructureSet::containsOnly): + (StructureSet): + * bytecode/Watchpoint.cpp: + (JSC::WatchpointSet::WatchpointSet): + (JSC::InlineWatchpointSet::add): + (JSC): + (JSC::InlineWatchpointSet::inflateSlow): + (JSC::InlineWatchpointSet::freeFat): + * bytecode/Watchpoint.h: + (WatchpointSet): + (JSC): + (InlineWatchpointSet): + (JSC::InlineWatchpointSet::InlineWatchpointSet): + (JSC::InlineWatchpointSet::~InlineWatchpointSet): + (JSC::InlineWatchpointSet::hasBeenInvalidated): + (JSC::InlineWatchpointSet::isStillValid): + (JSC::InlineWatchpointSet::startWatching): + (JSC::InlineWatchpointSet::notifyWrite): + (JSC::InlineWatchpointSet::isFat): + (JSC::InlineWatchpointSet::fat): + (JSC::InlineWatchpointSet::inflate): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::addStructureTransitionCheck): + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::structureTransitionWatchpointElimination): + (CSEPhase): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGCommon.h: + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::dump): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::isCellConstant): + * dfg/DFGJITCompiler.h: + (JSC::DFG::JITCompiler::addWeakReferences): + (JITCompiler): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasStructure): + (Node): + (JSC::DFG::Node::structure): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGRepatch.cpp: + (JSC::DFG::emitPutTransitionStub): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCachePutByID): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * runtime/Structure.cpp: + (JSC::Structure::Structure): + * runtime/Structure.h: + (JSC::Structure::transitionWatchpointSetHasBeenInvalidated): + (Structure): + (JSC::Structure::transitionWatchpointSetIsStillValid): + (JSC::Structure::addTransitionWatchpoint): + (JSC::Structure::notifyTransitionFromThisStructure): + (JSC::JSCell::setStructure): + * runtime/SymbolTable.cpp: + (JSC::SymbolTableEntry::attemptToWatch): + +2012-06-13 Filip Pizlo <fpizlo@apple.com> + + DFG should be able to set watchpoints on global variables + https://bugs.webkit.org/show_bug.cgi?id=88692 + + Reviewed by Geoffrey Garen. + + Rolling back in after fixing Windows build issues, and implementing + branchTest8 for the Qt port's strange assemblers. + + This implements global variable constant folding by allowing the optimizing + compiler to set a "watchpoint" on globals that it wishes to constant fold. + If the watchpoint fires, then an OSR exit is forced by overwriting the + machine code that the optimizing compiler generated with a jump. + + As such, this patch is adding quite a bit of stuff: + + - Jump replacement on those hardware targets supported by the optimizing + JIT. It is now possible to patch in a jump instruction over any recorded + watchpoint label. The jump must be "local" in the sense that it must be + within the range of the largest jump distance supported by a one + instruction jump. + + - WatchpointSets and Watchpoints. A Watchpoint is a doubly-linked list node + that records the location where a jump must be inserted and the + destination to which it should jump. Watchpoints can be added to a + WatchpointSet. The WatchpointSet can be fired all at once, which plants + all jumps. WatchpointSet also remembers if it had ever been invalidated, + which allows for monotonicity: we typically don't want to optimize using + watchpoints on something for which watchpoints had previously fired. The + act of notifying a WatchpointSet has a trivial fast path in case no + Watchpoints are registered (one-byte load+branch). + + - SpeculativeJIT::speculationWatchpoint(). It's like speculationCheck(), + except that you don't have to emit branches. But, you need to know what + WatchpointSet to add the resulting Watchpoint to. Not everything that + you could write a speculationCheck() for will have a WatchpointSet that + would get notified if the condition you were speculating against became + invalid. + + - SymbolTableEntry now has the ability to refer to a WatchpointSet. It can + do so without incurring any space overhead for those entries that don't + have WatchpointSets. + + - The bytecode generator infers all global function variables to be + watchable, and makes all stores perform the WatchpointSet's write check, + and marks all loads as being potentially watchable (i.e. you can compile + them to a watchpoint and a constant). + + Put together, this allows for fully sleazy inlining of calls to globally + declared functions. The inline prologue will no longer contain the load of + the function, or any checks of the function you're calling. I.e. it's + pretty much like the kind of inlining you would see in Java or C++. + Furthermore, the watchpointing functionality is built to be fairly general, + and should allow setting watchpoints on all sorts of interesting things + in the future. + + The sleazy inlining means that we will now sometimes inline in code paths + that have never executed. Previously, to inline we would have either had + to have executed the call (to read the call's inline cache) or have + executed the method check (to read the method check's inline cache). Now, + we might inline when the callee is a watched global variable. This + revealed some humorous bugs. First, constant folding disagreed with CFA + over what kinds of operations can clobber (example: code path A is dead + but stores a String into variable X, all other code paths store 0 into + X, and then you do CompareEq(X, 0) - CFA will say that this is a non- + clobbering constant, but constant folding thought it was clobbering + because it saw the String prediction). Second, inlining would crash if + the inline callee had not been compiled. This patch fixes both bugs, + since otherwise run-javascriptcore-tests would report regressions. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * assembler/ARMv7Assembler.h: + (ARMv7Assembler): + (JSC::ARMv7Assembler::ARMv7Assembler): + (JSC::ARMv7Assembler::labelForWatchpoint): + (JSC::ARMv7Assembler::label): + (JSC::ARMv7Assembler::replaceWithJump): + (JSC::ARMv7Assembler::maxJumpReplacementSize): + * assembler/AbstractMacroAssembler.h: + (JSC): + (AbstractMacroAssembler): + (Label): + (JSC::AbstractMacroAssembler::watchpointLabel): + (JSC::AbstractMacroAssembler::readPointer): + * assembler/AssemblerBuffer.h: + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::branchTest8): + (MacroAssemblerARM): + (JSC::MacroAssemblerARM::replaceWithJump): + (JSC::MacroAssemblerARM::maxJumpReplacementSize): + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::load8Signed): + (JSC::MacroAssemblerARMv7::load16Signed): + (MacroAssemblerARMv7): + (JSC::MacroAssemblerARMv7::replaceWithJump): + (JSC::MacroAssemblerARMv7::maxJumpReplacementSize): + (JSC::MacroAssemblerARMv7::branchTest8): + (JSC::MacroAssemblerARMv7::jump): + (JSC::MacroAssemblerARMv7::makeBranch): + * assembler/MacroAssemblerMIPS.h: + (JSC::MacroAssemblerMIPS::branchTest8): + (MacroAssemblerMIPS): + (JSC::MacroAssemblerMIPS::replaceWithJump): + (JSC::MacroAssemblerMIPS::maxJumpReplacementSize): + * assembler/MacroAssemblerSH4.h: + (JSC::MacroAssemblerSH4::branchTest8): + (MacroAssemblerSH4): + (JSC::MacroAssemblerSH4::replaceWithJump): + (JSC::MacroAssemblerSH4::maxJumpReplacementSize): + * assembler/MacroAssemblerX86.h: + (MacroAssemblerX86): + (JSC::MacroAssemblerX86::branchTest8): + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::replaceWithJump): + (MacroAssemblerX86Common): + (JSC::MacroAssemblerX86Common::maxJumpReplacementSize): + * assembler/MacroAssemblerX86_64.h: + (MacroAssemblerX86_64): + (JSC::MacroAssemblerX86_64::branchTest8): + * assembler/X86Assembler.h: + (JSC::X86Assembler::X86Assembler): + (X86Assembler): + (JSC::X86Assembler::cmpb_im): + (JSC::X86Assembler::testb_im): + (JSC::X86Assembler::labelForWatchpoint): + (JSC::X86Assembler::label): + (JSC::X86Assembler::replaceWithJump): + (JSC::X86Assembler::maxJumpReplacementSize): + (JSC::X86Assembler::X86InstructionFormatter::memoryModRM): + * bytecode/CodeBlock.cpp: + (JSC): + (JSC::CodeBlock::printGetByIdCacheStatus): + (JSC::CodeBlock::dump): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::appendOSRExit): + (JSC::CodeBlock::appendSpeculationRecovery): + (CodeBlock): + (JSC::CodeBlock::appendWatchpoint): + (JSC::CodeBlock::numberOfWatchpoints): + (JSC::CodeBlock::watchpoint): + (DFGData): + * bytecode/DFGExitProfile.h: + (JSC::DFG::exitKindToString): + (JSC::DFG::exitKindIsCountable): + * bytecode/GetByIdStatus.cpp: + (JSC::GetByIdStatus::computeForChain): + * bytecode/Instruction.h: + (Instruction): + (JSC::Instruction::Instruction): + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecode/Watchpoint.cpp: Added. + (JSC): + (JSC::Watchpoint::~Watchpoint): + (JSC::Watchpoint::correctLabels): + (JSC::Watchpoint::fire): + (JSC::WatchpointSet::WatchpointSet): + (JSC::WatchpointSet::~WatchpointSet): + (JSC::WatchpointSet::add): + (JSC::WatchpointSet::notifyWriteSlow): + (JSC::WatchpointSet::fireAllWatchpoints): + * bytecode/Watchpoint.h: Added. + (JSC): + (Watchpoint): + (JSC::Watchpoint::Watchpoint): + (JSC::Watchpoint::setDestination): + (WatchpointSet): + (JSC::WatchpointSet::isStillValid): + (JSC::WatchpointSet::hasBeenInvalidated): + (JSC::WatchpointSet::startWatching): + (JSC::WatchpointSet::notifyWrite): + (JSC::WatchpointSet::addressOfIsWatched): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::ResolveResult::checkValidity): + (JSC::BytecodeGenerator::addGlobalVar): + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::resolve): + (JSC::BytecodeGenerator::emitResolve): + (JSC::BytecodeGenerator::emitResolveWithBase): + (JSC::BytecodeGenerator::emitResolveWithThis): + (JSC::BytecodeGenerator::emitGetStaticVar): + (JSC::BytecodeGenerator::emitPutStaticVar): + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + * bytecompiler/NodesCodegen.cpp: + (JSC::FunctionCallResolveNode::emitBytecode): + (JSC::PostfixResolveNode::emitBytecode): + (JSC::PrefixResolveNode::emitBytecode): + (JSC::ReadModifyResolveNode::emitBytecode): + (JSC::AssignResolveNode::emitBytecode): + (JSC::ConstDeclNode::emitCodeSingle): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + (JSC::DFG::AbstractState::clobberStructures): + * dfg/DFGAbstractState.h: + (AbstractState): + (JSC::DFG::AbstractState::didClobber): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleInlining): + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCCallHelpers.h: + (CCallHelpers): + (JSC::DFG::CCallHelpers::setupArguments): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::globalVarWatchpointElimination): + (CSEPhase): + (JSC::DFG::CSEPhase::globalVarStoreElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::run): + * dfg/DFGCorrectableJumpPoint.h: + (JSC::DFG::CorrectableJumpPoint::isSet): + (CorrectableJumpPoint): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::linkOSRExits): + (JSC::DFG::JITCompiler::link): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasIdentifierNumberForCheck): + (Node): + (JSC::DFG::Node::identifierNumberForCheck): + (JSC::DFG::Node::hasRegisterPointer): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::OSRExit): + * dfg/DFGOSRExit.h: + (OSRExit): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + (JSC::DFG::SpeculativeJIT::appendCall): + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::speculationWatchpoint): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_put_global_var_check): + (JSC): + (JSC::JIT::emitSlow_op_put_global_var_check): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_put_global_var_check): + (JSC): + (JSC::JIT::emitSlow_op_put_global_var_check): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + (JSC): + * jit/JITStubs.h: + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + (LLInt): + * llint/LLIntSlowPaths.h: + (LLInt): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/JSObject.cpp: + (JSC::JSObject::removeDirect): + * runtime/JSObject.h: + (JSObject): + * runtime/JSSymbolTableObject.h: + (JSC::symbolTableGet): + (JSC::symbolTablePut): + (JSC::symbolTablePutWithAttributes): + * runtime/SymbolTable.cpp: Added. + (JSC): + (JSC::SymbolTableEntry::copySlow): + (JSC::SymbolTableEntry::freeFatEntrySlow): + (JSC::SymbolTableEntry::couldBeWatched): + (JSC::SymbolTableEntry::attemptToWatch): + (JSC::SymbolTableEntry::addressOfIsWatched): + (JSC::SymbolTableEntry::addWatchpoint): + (JSC::SymbolTableEntry::notifyWriteSlow): + (JSC::SymbolTableEntry::inflateSlow): + * runtime/SymbolTable.h: + (JSC): + (SymbolTableEntry): + (Fast): + (JSC::SymbolTableEntry::Fast::Fast): + (JSC::SymbolTableEntry::Fast::isNull): + (JSC::SymbolTableEntry::Fast::getIndex): + (JSC::SymbolTableEntry::Fast::isReadOnly): + (JSC::SymbolTableEntry::Fast::getAttributes): + (JSC::SymbolTableEntry::Fast::isFat): + (JSC::SymbolTableEntry::SymbolTableEntry): + (JSC::SymbolTableEntry::~SymbolTableEntry): + (JSC::SymbolTableEntry::operator=): + (JSC::SymbolTableEntry::isNull): + (JSC::SymbolTableEntry::getIndex): + (JSC::SymbolTableEntry::getFast): + (JSC::SymbolTableEntry::getAttributes): + (JSC::SymbolTableEntry::isReadOnly): + (JSC::SymbolTableEntry::watchpointSet): + (JSC::SymbolTableEntry::notifyWrite): + (FatEntry): + (JSC::SymbolTableEntry::FatEntry::FatEntry): + (JSC::SymbolTableEntry::isFat): + (JSC::SymbolTableEntry::fatEntry): + (JSC::SymbolTableEntry::inflate): + (JSC::SymbolTableEntry::bits): + (JSC::SymbolTableEntry::freeFatEntry): + (JSC::SymbolTableEntry::pack): + (JSC::SymbolTableEntry::isValidIndex): + +2012-06-13 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r120172. + http://trac.webkit.org/changeset/120172 + https://bugs.webkit.org/show_bug.cgi?id=88976 + + The patch causes compilation failures on Gtk, Qt and Apple Win + bots (Requested by zdobersek on #webkit). + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * assembler/ARMv7Assembler.h: + (JSC::ARMv7Assembler::nop): + (JSC::ARMv7Assembler::label): + (JSC::ARMv7Assembler::readPointer): + (ARMv7Assembler): + * assembler/AbstractMacroAssembler.h: + (JSC): + (AbstractMacroAssembler): + (Label): + * assembler/AssemblerBuffer.h: + * assembler/MacroAssemblerARM.h: + * assembler/MacroAssemblerARMv7.h: + (JSC::MacroAssemblerARMv7::nop): + (JSC::MacroAssemblerARMv7::jump): + (JSC::MacroAssemblerARMv7::makeBranch): + * assembler/MacroAssemblerMIPS.h: + * assembler/MacroAssemblerSH4.h: + * assembler/MacroAssemblerX86.h: + (MacroAssemblerX86): + (JSC::MacroAssemblerX86::moveWithPatch): + * assembler/MacroAssemblerX86Common.h: + * assembler/MacroAssemblerX86_64.h: + (JSC::MacroAssemblerX86_64::branchTest8): + * assembler/X86Assembler.h: + (JSC::X86Assembler::cmpb_im): + (JSC::X86Assembler::codeSize): + (JSC::X86Assembler::label): + (JSC::X86Assembler::X86InstructionFormatter::memoryModRM): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::appendOSRExit): + (JSC::CodeBlock::appendSpeculationRecovery): + (DFGData): + * bytecode/DFGExitProfile.h: + (JSC::DFG::exitKindToString): + (JSC::DFG::exitKindIsCountable): + * bytecode/Instruction.h: + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecode/Watchpoint.cpp: Removed. + * bytecode/Watchpoint.h: Removed. + * bytecompiler/BytecodeGenerator.cpp: + (JSC::ResolveResult::checkValidity): + (JSC::BytecodeGenerator::addGlobalVar): + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::resolve): + (JSC::BytecodeGenerator::emitResolve): + (JSC::BytecodeGenerator::emitResolveWithBase): + (JSC::BytecodeGenerator::emitResolveWithThis): + (JSC::BytecodeGenerator::emitGetStaticVar): + (JSC::BytecodeGenerator::emitPutStaticVar): + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + * bytecompiler/NodesCodegen.cpp: + (JSC::FunctionCallResolveNode::emitBytecode): + (JSC::PostfixResolveNode::emitBytecode): + (JSC::PrefixResolveNode::emitBytecode): + (JSC::ReadModifyResolveNode::emitBytecode): + (JSC::AssignResolveNode::emitBytecode): + (JSC::ConstDeclNode::emitCodeSingle): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + (JSC::DFG::AbstractState::clobberStructures): + * dfg/DFGAbstractState.h: + (AbstractState): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleInlining): + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCCallHelpers.h: + (JSC::DFG::CCallHelpers::setupArguments): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::globalVarStoreElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::run): + * dfg/DFGCorrectableJumpPoint.h: + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::linkOSRExits): + (JSC::DFG::JITCompiler::link): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasRegisterPointer): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::OSRExit): + * dfg/DFGOSRExit.h: + (OSRExit): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + (JSC::DFG::SpeculativeJIT::appendCallSetResult): + (JSC::DFG::SpeculativeJIT::speculationCheck): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + * jit/JITPropertyAccess32_64.cpp: + * jit/JITStubs.cpp: + * jit/JITStubs.h: + * llint/LLIntSlowPaths.cpp: + * llint/LLIntSlowPaths.h: + (LLInt): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/JSObject.cpp: + (JSC::JSObject::removeDirect): + * runtime/JSObject.h: + (JSObject): + * runtime/JSSymbolTableObject.h: + (JSC::symbolTableGet): + (JSC::symbolTablePut): + (JSC::symbolTablePutWithAttributes): + * runtime/SymbolTable.cpp: Removed. + * runtime/SymbolTable.h: + (JSC): + (JSC::SymbolTableEntry::isNull): + (JSC::SymbolTableEntry::getIndex): + (SymbolTableEntry): + (JSC::SymbolTableEntry::getAttributes): + (JSC::SymbolTableEntry::isReadOnly): + (JSC::SymbolTableEntry::pack): + (JSC::SymbolTableEntry::isValidIndex): + +2012-06-12 Filip Pizlo <fpizlo@apple.com> + + DFG should be able to set watchpoints on global variables + https://bugs.webkit.org/show_bug.cgi?id=88692 + + Reviewed by Geoffrey Garen. + + This implements global variable constant folding by allowing the optimizing + compiler to set a "watchpoint" on globals that it wishes to constant fold. + If the watchpoint fires, then an OSR exit is forced by overwriting the + machine code that the optimizing compiler generated with a jump. + + As such, this patch is adding quite a bit of stuff: + + - Jump replacement on those hardware targets supported by the optimizing + JIT. It is now possible to patch in a jump instruction over any recorded + watchpoint label. The jump must be "local" in the sense that it must be + within the range of the largest jump distance supported by a one + instruction jump. + + - WatchpointSets and Watchpoints. A Watchpoint is a doubly-linked list node + that records the location where a jump must be inserted and the + destination to which it should jump. Watchpoints can be added to a + WatchpointSet. The WatchpointSet can be fired all at once, which plants + all jumps. WatchpointSet also remembers if it had ever been invalidated, + which allows for monotonicity: we typically don't want to optimize using + watchpoints on something for which watchpoints had previously fired. The + act of notifying a WatchpointSet has a trivial fast path in case no + Watchpoints are registered (one-byte load+branch). + + - SpeculativeJIT::speculationWatchpoint(). It's like speculationCheck(), + except that you don't have to emit branches. But, you need to know what + WatchpointSet to add the resulting Watchpoint to. Not everything that + you could write a speculationCheck() for will have a WatchpointSet that + would get notified if the condition you were speculating against became + invalid. + + - SymbolTableEntry now has the ability to refer to a WatchpointSet. It can + do so without incurring any space overhead for those entries that don't + have WatchpointSets. + + - The bytecode generator infers all global function variables to be + watchable, and makes all stores perform the WatchpointSet's write check, + and marks all loads as being potentially watchable (i.e. you can compile + them to a watchpoint and a constant). + + Put together, this allows for fully sleazy inlining of calls to globally + declared functions. The inline prologue will no longer contain the load of + the function, or any checks of the function you're calling. I.e. it's + pretty much like the kind of inlining you would see in Java or C++. + Furthermore, the watchpointing functionality is built to be fairly general, + and should allow setting watchpoints on all sorts of interesting things + in the future. + + The sleazy inlining means that we will now sometimes inline in code paths + that have never executed. Previously, to inline we would have either had + to have executed the call (to read the call's inline cache) or have + executed the method check (to read the method check's inline cache). Now, + we might inline when the callee is a watched global variable. This + revealed some humorous bugs. First, constant folding disagreed with CFA + over what kinds of operations can clobber (example: code path A is dead + but stores a String into variable X, all other code paths store 0 into + X, and then you do CompareEq(X, 0) - CFA will say that this is a non- + clobbering constant, but constant folding thought it was clobbering + because it saw the String prediction). Second, inlining would crash if + the inline callee had not been compiled. This patch fixes both bugs, + since otherwise run-javascriptcore-tests would report regressions. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * assembler/ARMv7Assembler.h: + (ARMv7Assembler): + (JSC::ARMv7Assembler::ARMv7Assembler): + (JSC::ARMv7Assembler::labelForWatchpoint): + (JSC::ARMv7Assembler::label): + (JSC::ARMv7Assembler::replaceWithJump): + (JSC::ARMv7Assembler::maxJumpReplacementSize): + * assembler/AbstractMacroAssembler.h: + (JSC): + (AbstractMacroAssembler): + (Label): + (JSC::AbstractMacroAssembler::watchpointLabel): + * assembler/AssemblerBuffer.h: + * assembler/MacroAssemblerARM.h: + (JSC::MacroAssemblerARM::replaceWithJump): + (MacroAssemblerARM): + (JSC::MacroAssemblerARM::maxJumpReplacementSize): + * assembler/MacroAssemblerARMv7.h: + (MacroAssemblerARMv7): + (JSC::MacroAssemblerARMv7::replaceWithJump): + (JSC::MacroAssemblerARMv7::maxJumpReplacementSize): + (JSC::MacroAssemblerARMv7::branchTest8): + (JSC::MacroAssemblerARMv7::jump): + (JSC::MacroAssemblerARMv7::makeBranch): + * assembler/MacroAssemblerMIPS.h: + (JSC::MacroAssemblerMIPS::replaceWithJump): + (MacroAssemblerMIPS): + (JSC::MacroAssemblerMIPS::maxJumpReplacementSize): + * assembler/MacroAssemblerSH4.h: + (JSC::MacroAssemblerSH4::replaceWithJump): + (MacroAssemblerSH4): + (JSC::MacroAssemblerSH4::maxJumpReplacementSize): + * assembler/MacroAssemblerX86.h: + (MacroAssemblerX86): + (JSC::MacroAssemblerX86::branchTest8): + * assembler/MacroAssemblerX86Common.h: + (JSC::MacroAssemblerX86Common::replaceWithJump): + (MacroAssemblerX86Common): + (JSC::MacroAssemblerX86Common::maxJumpReplacementSize): + * assembler/MacroAssemblerX86_64.h: + (MacroAssemblerX86_64): + (JSC::MacroAssemblerX86_64::branchTest8): + * assembler/X86Assembler.h: + (JSC::X86Assembler::X86Assembler): + (X86Assembler): + (JSC::X86Assembler::cmpb_im): + (JSC::X86Assembler::testb_im): + (JSC::X86Assembler::labelForWatchpoint): + (JSC::X86Assembler::label): + (JSC::X86Assembler::replaceWithJump): + (JSC::X86Assembler::maxJumpReplacementSize): + (JSC::X86Assembler::X86InstructionFormatter::memoryModRM): + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::appendOSRExit): + (JSC::CodeBlock::appendSpeculationRecovery): + (CodeBlock): + (JSC::CodeBlock::appendWatchpoint): + (JSC::CodeBlock::numberOfWatchpoints): + (JSC::CodeBlock::watchpoint): + (DFGData): + * bytecode/DFGExitProfile.h: + (JSC::DFG::exitKindToString): + (JSC::DFG::exitKindIsCountable): + * bytecode/Instruction.h: + (Instruction): + (JSC::Instruction::Instruction): + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecode/Watchpoint.cpp: Added. + (JSC): + (JSC::Watchpoint::~Watchpoint): + (JSC::Watchpoint::correctLabels): + (JSC::Watchpoint::fire): + (JSC::WatchpointSet::WatchpointSet): + (JSC::WatchpointSet::~WatchpointSet): + (JSC::WatchpointSet::add): + (JSC::WatchpointSet::notifyWriteSlow): + (JSC::WatchpointSet::fireAllWatchpoints): + * bytecode/Watchpoint.h: Added. + (JSC): + (Watchpoint): + (JSC::Watchpoint::Watchpoint): + (JSC::Watchpoint::setDestination): + (WatchpointSet): + (JSC::WatchpointSet::isStillValid): + (JSC::WatchpointSet::hasBeenInvalidated): + (JSC::WatchpointSet::startWatching): + (JSC::WatchpointSet::notifyWrite): + (JSC::WatchpointSet::addressOfIsWatched): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::ResolveResult::checkValidity): + (JSC::BytecodeGenerator::addGlobalVar): + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::resolve): + (JSC::BytecodeGenerator::emitResolve): + (JSC::BytecodeGenerator::emitResolveWithBase): + (JSC::BytecodeGenerator::emitResolveWithThis): + (JSC::BytecodeGenerator::emitGetStaticVar): + (JSC::BytecodeGenerator::emitPutStaticVar): + * bytecompiler/BytecodeGenerator.h: + (BytecodeGenerator): + * bytecompiler/NodesCodegen.cpp: + (JSC::FunctionCallResolveNode::emitBytecode): + (JSC::PostfixResolveNode::emitBytecode): + (JSC::PrefixResolveNode::emitBytecode): + (JSC::ReadModifyResolveNode::emitBytecode): + (JSC::AssignResolveNode::emitBytecode): + (JSC::ConstDeclNode::emitCodeSingle): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + (JSC::DFG::AbstractState::clobberStructures): + * dfg/DFGAbstractState.h: + (AbstractState): + (JSC::DFG::AbstractState::didClobber): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleInlining): + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCCallHelpers.h: + (CCallHelpers): + (JSC::DFG::CCallHelpers::setupArguments): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::globalVarWatchpointElimination): + (CSEPhase): + (JSC::DFG::CSEPhase::globalVarStoreElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::run): + * dfg/DFGCorrectableJumpPoint.h: + (JSC::DFG::CorrectableJumpPoint::isSet): + (CorrectableJumpPoint): + * dfg/DFGJITCompiler.cpp: + (JSC::DFG::JITCompiler::linkOSRExits): + (JSC::DFG::JITCompiler::link): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasIdentifierNumberForCheck): + (Node): + (JSC::DFG::Node::identifierNumberForCheck): + (JSC::DFG::Node::hasRegisterPointer): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::OSRExit): + * dfg/DFGOSRExit.h: + (OSRExit): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + (JSC::DFG::SpeculativeJIT::appendCall): + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::speculationWatchpoint): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * jit/JIT.cpp: + (JSC::JIT::privateCompileMainPass): + (JSC::JIT::privateCompileSlowCases): + * jit/JIT.h: + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_put_global_var_check): + (JSC): + (JSC::JIT::emitSlow_op_put_global_var_check): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_put_global_var_check): + (JSC): + (JSC::JIT::emitSlow_op_put_global_var_check): + * jit/JITStubs.cpp: + (JSC::JITThunks::JITThunks): + (JSC::DEFINE_STUB_FUNCTION): + (JSC): + * jit/JITStubs.h: + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + (LLInt): + * llint/LLIntSlowPaths.h: + (LLInt): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/JSObject.cpp: + (JSC::JSObject::removeDirect): + * runtime/JSObject.h: + (JSObject): + * runtime/JSSymbolTableObject.h: + (JSC::symbolTableGet): + (JSC::symbolTablePut): + (JSC::symbolTablePutWithAttributes): + * runtime/SymbolTable.cpp: Added. + (JSC): + (JSC::SymbolTableEntry::copySlow): + (JSC::SymbolTableEntry::freeFatEntrySlow): + (JSC::SymbolTableEntry::couldBeWatched): + (JSC::SymbolTableEntry::attemptToWatch): + (JSC::SymbolTableEntry::addressOfIsWatched): + (JSC::SymbolTableEntry::addWatchpoint): + (JSC::SymbolTableEntry::notifyWriteSlow): + (JSC::SymbolTableEntry::inflateSlow): + * runtime/SymbolTable.h: + (JSC): + (SymbolTableEntry): + (Fast): + (JSC::SymbolTableEntry::Fast::Fast): + (JSC::SymbolTableEntry::Fast::isNull): + (JSC::SymbolTableEntry::Fast::getIndex): + (JSC::SymbolTableEntry::Fast::isReadOnly): + (JSC::SymbolTableEntry::Fast::getAttributes): + (JSC::SymbolTableEntry::Fast::isFat): + (JSC::SymbolTableEntry::SymbolTableEntry): + (JSC::SymbolTableEntry::~SymbolTableEntry): + (JSC::SymbolTableEntry::operator=): + (JSC::SymbolTableEntry::isNull): + (JSC::SymbolTableEntry::getIndex): + (JSC::SymbolTableEntry::getFast): + (JSC::SymbolTableEntry::getAttributes): + (JSC::SymbolTableEntry::isReadOnly): + (JSC::SymbolTableEntry::watchpointSet): + (JSC::SymbolTableEntry::notifyWrite): + (FatEntry): + (JSC::SymbolTableEntry::FatEntry::FatEntry): + (JSC::SymbolTableEntry::isFat): + (JSC::SymbolTableEntry::fatEntry): + (JSC::SymbolTableEntry::inflate): + (JSC::SymbolTableEntry::bits): + (JSC::SymbolTableEntry::freeFatEntry): + (JSC::SymbolTableEntry::pack): + (JSC::SymbolTableEntry::isValidIndex): + +2012-06-12 Filip Pizlo <fpizlo@apple.com> + + Unreviewed build fix for ARMv7 debug builds. + + * jit/JITStubs.cpp: + (JSC::JITThunks::JITThunks): + +2012-06-12 Geoffrey Garen <ggaren@apple.com> + + Build fix for case-sensitive file systems: use the right case. + + * heap/ListableHandler.h: + +2012-06-11 Geoffrey Garen <ggaren@apple.com> + + GC should be 1.7X faster + https://bugs.webkit.org/show_bug.cgi?id=88840 + + Reviewed by Oliver Hunt. + + I profiled, and removed anything that showed up as a concurrency + bottleneck. Then, I added 3 threads to our max thread count, since we + can scale up to more threads now. + + * heap/BlockAllocator.cpp: + (JSC::BlockAllocator::BlockAllocator): + (JSC::BlockAllocator::~BlockAllocator): + (JSC::BlockAllocator::releaseFreeBlocks): + (JSC::BlockAllocator::waitForRelativeTimeWhileHoldingLock): + (JSC::BlockAllocator::waitForRelativeTime): + (JSC::BlockAllocator::blockFreeingThreadMain): + * heap/BlockAllocator.h: + (BlockAllocator): + (JSC::BlockAllocator::allocate): + (JSC::BlockAllocator::deallocate): Use a spin lock for the common case + where we're just popping a linked list. (A pthread mutex would sleep our + thread even if the lock were only contended for a microsecond.) + + Scope the lock to avoid holding it while allocating VM, since that's a + slow activity and it doesn't modify any of our data structures. + + We still use a pthread mutex to handle our condition variable since we + have to, and it's not a hot path. + + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::CopiedSpace): + (JSC::CopiedSpace::doneFillingBlock): + * heap/CopiedSpace.h: + (JSC::CopiedSpace::CopiedSpace): Use a spin lock for the to space lock, + since it just guards linked list and hash table manipulation. + + * heap/MarkStack.cpp: + (JSC::MarkStackSegmentAllocator::MarkStackSegmentAllocator): + (JSC::MarkStackSegmentAllocator::allocate): + (JSC::MarkStackSegmentAllocator::release): + (JSC::MarkStackSegmentAllocator::shrinkReserve): Use a spin lock, since + we're just managing a linked list. + + (JSC::MarkStackArray::donateSomeCellsTo): Changed donation to be proportional + to our current stack size. This fixes cases where we used to donate too + much. Interestingly, donating too much was starving the donor (when it + ran out of work later) *and* the recipient (since it had to wait on a + long donation operation to complete before it could acquire the lock). + + In the worst case, we're still guaranteed to donate N cells in roughly log N time. + + This change also fixes cases where we used to donate too little, since + we would always keep a fixed minimum number of cells. In the worst case, + with N marking threads, would could have N large object graph roots in + our stack for the duration of GC, and scale to only 1 thread. + + It's an interesting observation that a single object in the mark stack + might represent an arbitrarily large object graph -- and only the act + of marking can find out. + + (JSC::MarkStackArray::stealSomeCellsFrom): Steal in proportion to idle + threads. Once again, this fixes cases where constants could cause us + to steal too much or too little. + + (JSC::SlotVisitor::donateKnownParallel): Always wake up other threads + if they're idle. We can afford to do this because we're conservative + about when we donate. + + (JSC::SlotVisitor::drainFromShared): + * heap/MarkStack.h: + (MarkStackSegmentAllocator): + (MarkStackArray): + (JSC): + * heap/SlotVisitor.h: Merged the "should I donate?" decision into a + single function, for simplicity. + + * runtime/Options.cpp: + (minimumNumberOfScansBetweenRebalance): Reduced the delay before donation + a lot. We can afford to do this because, in the common case, donation is + a single branch that decides not to donate. + + (cpusToUse): Use more CPUs now, since we scale better now. + + * runtime/Options.h: + (Options): Removed now-unused variables. + +2012-06-12 Filip Pizlo <fpizlo@apple.com> + + REGRESSION(120121): inspector tests crash in DFG + https://bugs.webkit.org/show_bug.cgi?id=88941 + + Reviewed by Geoffrey Garen. + + The CFG simplifier has two different ways of fixing up GetLocal, Phantom, and Flush. If we've + already fixed up the node one way, we shouldn't try the other way. The reason why we shouldn't + is that the second way depends on the node referring to other nodes in the to-be-jettisoned + block. After fixup they potentially will refer to nodes in the block being merged to. + + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal): + (JSC::DFG::CFGSimplificationPhase::mergeBlocks): + +2012-06-12 Leo Yang <leo.yang@torchmobile.com.cn> + + Dynamic hash table in DOMObjectHashTableMap is wrong in multiple threads + https://bugs.webkit.org/show_bug.cgi?id=87334 + + Reviewed by Geoffrey Garen. + + Add a copy member function to JSC::HasTable. This function will copy all data + members except for *table* which contains thread specific data that prevents + up copying it. When you want to copy a JSC::HashTable that was constructed + on another thread you should call JSC::HashTable::copy(). + + * runtime/Lookup.h: + (JSC::HashTable::copy): + (HashTable): + +2012-06-12 Filip Pizlo <fpizlo@apple.com> + + DFG should not ASSERT if you have a double use of a variable that is not revealed to be a double + until after CFG simplification + https://bugs.webkit.org/show_bug.cgi?id=88927 + <rdar://problem/11513971> + + Reviewed by Geoffrey Garen. + + Speculation fixup needs to run if simplification did things, because simplification can change + predictions - particularly if you had a control flow path that stored weird things into a + variable, but that path got axed by the simplifier. + + Running fixup in the fixpoint requires making it idempotent, which it previously wasn't. Only + one place needed to be changed, namely the un-MustGenerate-ion of ValueToInt32. + + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + +2012-06-12 Filip Pizlo <fpizlo@apple.com> + + REGRESSION (r119779): Javascript TypeError: 'undefined' is not an object + https://bugs.webkit.org/show_bug.cgi?id=88783 + <rdar://problem/11640299> + + Reviewed by Geoffrey Garen. + + If you don't keep alive the base of an object access over the various checks + you do for the prototype chain, you're going to have a bad time. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleGetById): + +2012-06-12 Hojong Han <hojong.han@samsung.com> + + Property names of the built-in object cannot be retrieved + after trying to delete one of its properties + https://bugs.webkit.org/show_bug.cgi?id=86461 + + Reviewed by Gavin Barraclough. + + * runtime/JSObject.cpp: + (JSC::getClassPropertyNames): + (JSC::JSObject::getOwnPropertyNames): + +2012-06-11 Gyuyoung Kim <gyuyoung.kim@samsung.com> + + [CMAKE][EFL] Remove duplicated executable output path + https://bugs.webkit.org/show_bug.cgi?id=88765 + + Reviewed by Daniel Bates. + + CMake files for EFL port have redefined executable output path. However, EFL port doesn't + need to define again because it is already defined in top-level CMake file. + + * shell/CMakeLists.txt: + +2012-06-11 Carlos Garcia Campos <cgarcia@igalia.com> + + Unreviewed. Fix make distcheck issues. + + * GNUmakefile.list.am: Remove non existent header file. + +2012-06-10 Patrick Gansterer <paroga@webkit.org> + + Unreviewed. Build fix for !ENABLE(JIT) after r119844 and r119925. + + * runtime/Executable.h: + (ExecutableBase): + (JSC::ExecutableBase::clearCodeVirtual): + +2012-06-10 Patrick Gansterer <paroga@webkit.org> + + Unreviewed. Build fix for !ENABLE(JIT) after r119844. + + * runtime/Executable.h: + (ExecutableBase): + (JSC): + +2012-06-09 Dominic Cooney <dominicc@chromium.org> + + [Chromium] Remove JavaScriptCore dependencies from gyp + https://bugs.webkit.org/show_bug.cgi?id=88510 + + Reviewed by Adam Barth. + + Chromium doesn't support JSC any more and there doesn't seem to be + a strong interest in using GYP as the common build system in other + ports. + + * JavaScriptCore.gyp/JavaScriptCore.gyp: WebCore still depends on YARR interpreter. + * JavaScriptCore.gypi: Only include YARR source. + * gyp/JavaScriptCore.gyp: Removed. + * gyp/gtk.gyp: Removed. + +2012-06-09 Geoffrey Garen <ggaren@apple.com> + + Unreviewed, rolling back in part2 of r118646. + + This patch removes eager finalization. + + Weak pointer finalization should be lazy + https://bugs.webkit.org/show_bug.cgi?id=87599 + + Reviewed by Sam Weinig. + + * heap/Heap.cpp: + (JSC::Heap::collect): Don't finalize eagerly -- we'll do it lazily. + + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::sweep): Do sweep weak sets when sweeping a block, + since we won't get another chance. + + * heap/MarkedBlock.h: + (JSC::MarkedBlock::sweepWeakSet): + * heap/MarkedSpace.cpp: + (MarkedSpace::WeakSetSweep): + * heap/MarkedSpace.h: + (JSC::MarkedSpace::sweepWeakSets): Removed now-unused code. + +2012-06-09 Sukolsak Sakshuwong <sukolsak@google.com> + + Add UNDO_MANAGER flag + https://bugs.webkit.org/show_bug.cgi?id=87908 + + Reviewed by Tony Chang. + + * Configurations/FeatureDefines.xcconfig: + +2012-06-08 Geoffrey Garen <ggaren@apple.com> + + Unreviewed, rolling back in part1 of r118646. + + This patch includes everything necessary for lazy finalization, but + keeps eager finalization enabled for the time being. + + Weak pointer finalization should be lazy + https://bugs.webkit.org/show_bug.cgi?id=87599 + + Reviewed by Sam Weinig. + + * heap/MarkedBlock.cpp: + * heap/MarkedBlock.h: + (JSC::MarkedBlock::resetAllocator): + * heap/MarkedSpace.cpp: + (JSC::MarkedSpace::resetAllocators): + * heap/MarkedSpace.h: + (JSC::MarkedSpace::resetAllocators): Don't force allocator reset anymore. + It will happen automatically when a weak set is swept. It's simpler to + have only one canonical way for this to happen, and it wasn't buying + us anything to do it eagerly. + * heap/WeakBlock.cpp: + (JSC::WeakBlock::sweep): Don't short-circuit a sweep unless we know + the sweep would be a no-op. If even one finalizer is pending, we need to + run it, since we won't get another chance. + * heap/WeakSet.cpp: + (JSC::WeakSet::sweep): This loop can be simpler now that + WeakBlock::sweep() does what we mean. + Reset our allocator after a sweep because this is the optimal time to + start trying to recycle old weak pointers. + (JSC::WeakSet::tryFindAllocator): Don't sweep when searching for an + allocator because we've swept already, and forcing a new sweep would be + wasteful. + * heap/WeakSet.h: + (JSC::WeakSet::shrink): Be sure to reset our allocator after a shrink + because the shrink may have removed the block the allocator was going to + allocate out of. + +2012-06-08 Gavin Barraclough <barraclough@apple.com> + + Unreviewed roll out r119795. + + This broke jquery/core.html + + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + * llint/LowLevelInterpreter.asm: + * runtime/JSGlobalData.h: + (JSGlobalData): + * runtime/JSGlobalThis.cpp: + (JSC::JSGlobalThis::setUnwrappedObject): + * runtime/JSObject.cpp: + (JSC::JSObject::visitChildren): + (JSC::JSObject::createInheritorID): + * runtime/JSObject.h: + (JSObject): + (JSC::JSObject::resetInheritorID): + (JSC): + (JSC::JSObject::offsetOfInheritorID): + (JSC::JSObject::inheritorID): + +2012-06-08 Filip Pizlo <fpizlo@apple.com> + + PredictedType should be called SpeculatedType + https://bugs.webkit.org/show_bug.cgi?id=88477 + + Unreviewed, fix a renaming goof from http://trac.webkit.org/changeset/119660. + I accidentally renamed ByteCodeParser::getPrediction to + ByteCodeParser::getSpeculation. That was not the intent. This changes it + back. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::addCall): + (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit): + (JSC::DFG::ByteCodeParser::getPrediction): + (JSC::DFG::ByteCodeParser::handleCall): + (JSC::DFG::ByteCodeParser::parseBlock): + +2012-06-08 Andy Wingo <wingo@igalia.com> + + Explictly mark stubs called by JIT as being internal + https://bugs.webkit.org/show_bug.cgi?id=88552 + + Reviewed by Filip Pizlo. + + * dfg/DFGOSRExitCompiler.h: + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * jit/HostCallReturnValue.h: + * jit/JITStubs.cpp: + * jit/JITStubs.h: + * jit/ThunkGenerators.cpp: + * llint/LLIntSlowPaths.h: Mark a bunch of stubs as being + WTF_INTERNAL. Change most calls to SYMBOL_STRING_RELOCATION to + LOCAL_REFERENCE, or GLOBAL_REFERENCE in the case of the wrappers + to truly global symbols. + * offlineasm/asm.rb: Generate LOCAL_REFERENCE instead of + SYMBOL_STRING_RELOCATION. + +2012-06-08 Geoffrey Garen <ggaren@apple.com> + + Don't rely on weak pointers for eager CodeBlock finalization + https://bugs.webkit.org/show_bug.cgi?id=88465 + + Reviewed by Gavin Barraclough. + + This is incompatible with lazy weak pointer finalization. + + I considered just making CodeBlock finalization lazy-friendly, but it + turns out that the heap is already way up in CodeBlock's business when + it comes to finalization, so I decided to finish the job and move full + responsibility for CodeBlock finalization into the heap. + + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Maybe this + will build. + + * debugger/Debugger.cpp: Updated for rename. + + * heap/Heap.cpp: + (JSC::Heap::deleteAllCompiledCode): Renamed for consistency. Fixed a bug + where we would not delete code for a code block that had been previously + jettisoned. I don't know if this happens in practice -- I mostly did + this to improve consistency with deleteUnmarkedCompiledCode. + + (JSC::Heap::deleteUnmarkedCompiledCode): New function, responsible for + eager finalization of unmarked code blocks. + + (JSC::Heap::collect): Updated for rename. Updated to call + deleteUnmarkedCompiledCode(), which takes care of jettisoned DFG code + blocks too. + + (JSC::Heap::addCompiledCode): Renamed, since this points to all code + now, not just functions. + + * heap/Heap.h: + (Heap): Keep track of all user code, not just functions. This is a + negligible additional overhead, since most code is function code. + + * runtime/Executable.cpp: + (JSC::*::finalize): Removed these functions, since we don't rely on + weak pointer finalization anymore. + + (JSC::FunctionExecutable::FunctionExecutable): Moved linked-list stuff + into base class so all executables can be in the list. + + (JSC::EvalExecutable::clearCode): + (JSC::ProgramExecutable::clearCode): + (JSC::FunctionExecutable::clearCode): All we need to do is delete our + CodeBlock -- that will delete all of its internal data structures. + + (JSC::FunctionExecutable::clearCodeIfNotCompiling): Factored out a helper + function to improve clarity. + + * runtime/Executable.h: + (JSC::ExecutableBase): Moved linked-list stuff + into base class so all executables can be in the list. + + (JSC::NativeExecutable::create): + (NativeExecutable): + (ScriptExecutable): + (JSC::ScriptExecutable::finishCreation): + (JSC::EvalExecutable::create): + (EvalExecutable): + (JSC::ProgramExecutable::create): + (ProgramExecutable): + (FunctionExecutable): + (JSC::FunctionExecutable::create): Don't use a finalizer -- the heap + will call us back to destroy our code block. + + (JSC::FunctionExecutable::discardCode): Renamed to clearCodeIfNotCompiling() + for clarity. + + (JSC::FunctionExecutable::isCompiling): New helper function, for clarity. + + (JSC::ScriptExecutable::clearCodeVirtual): New helper function, since + the heap needs to make polymorphic calls to clear code. + + * runtime/JSGlobalData.cpp: + (JSC::StackPreservingRecompiler::operator()): + * runtime/JSGlobalObject.cpp: + (JSC::DynamicGlobalObjectScope::DynamicGlobalObjectScope): Updated for + renames. + +2012-06-07 Filip Pizlo <fpizlo@apple.com> + + DFG should inline prototype chain accesses, and do the right things if the + specific function optimization is available + https://bugs.webkit.org/show_bug.cgi?id=88594 + + Reviewed by Gavin Barraclough. + + Looks like a 3% win on V8. + + * bytecode/CodeBlock.h: + (JSC::Structure::prototypeForLookup): + (JSC): + * bytecode/GetByIdStatus.cpp: + (JSC::GetByIdStatus::computeFromLLInt): + (JSC): + (JSC::GetByIdStatus::computeForChain): + (JSC::GetByIdStatus::computeFor): + * bytecode/GetByIdStatus.h: + (JSC::GetByIdStatus::GetByIdStatus): + (JSC::GetByIdStatus::isSimple): + (JSC::GetByIdStatus::chain): + (JSC::GetByIdStatus::specificValue): + (GetByIdStatus): + * bytecode/StructureSet.h: + (StructureSet): + (JSC::StructureSet::singletonStructure): + * bytecode/StructureStubInfo.h: + (JSC::StructureStubInfo::initGetByIdProto): + (JSC::StructureStubInfo::initGetByIdChain): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleGetById): + * dfg/DFGRepatch.cpp: + (JSC::DFG::tryCacheGetByID): + * jit/JITStubs.cpp: + (JSC::JITThunks::tryCacheGetByID): + * runtime/JSGlobalObject.h: + (JSC::Structure::prototypeForLookup): + (JSC): + * runtime/Structure.h: + (Structure): + +2012-06-07 Gavin Barraclough <barraclough@apple.com> + + Remove JSObject::m_inheritorID + https://bugs.webkit.org/show_bug.cgi?id=88378 + + Reviewed by Geoff Garen. + + This is rarely used, and not performance critical (the commonly accessed copy is cached on JSFunction), + and most objects don't need an inheritorID (this value is only used if the object is used as a prototype). + Instead use a private named value in the object's property storage. + + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): + - No need m_inheritorID to initialize! + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + - No need m_inheritorID to initialize! + * llint/LowLevelInterpreter.asm: + - No need m_inheritorID to initialize! + * runtime/JSGlobalData.h: + (JSGlobalData): + - Added private name 'm_inheritorIDKey'. + * runtime/JSGlobalThis.cpp: + (JSC::JSGlobalThis::setUnwrappedObject): + - resetInheritorID is now passed a JSGlobalData&. + * runtime/JSObject.cpp: + (JSC::JSObject::visitChildren): + - No m_inheritorID to be marked. + (JSC::JSObject::createInheritorID): + - Store the newly created inheritorID in the property map. + * runtime/JSObject.h: + (JSC::JSObject::resetInheritorID): + - Remove the inheritorID from property storage. + (JSC::JSObject::inheritorID): + - Read the inheritorID from property storage. + +2012-06-07 Gavin Barraclough <barraclough@apple.com> + + Math.pow on iOS does not support denormal numbers. + https://bugs.webkit.org/show_bug.cgi?id=88592 + + Reviewed by Filip Pizlo. + + Import an implementation from fdlibm, detect cases where it is safe to use the system + implementation & where we should fall back to fdlibm. + + * runtime/MathObject.cpp: + (JSC::isDenormal): + (JSC::isEdgeCase): + (JSC::mathPow): + - On iOS, detect cases where denormal support may be required & use fdlibm in these cases. + (JSC::mathProtoFuncPow): + - Changed to use mathPow. + (JSC::fdlibmScalbn): + (JSC::fdlibmPow): + - These functions imported from fdlibm; original style retained to ease future merging. + +2012-06-07 Patrick Gansterer <paroga@webkit.org> + + Unreviewed. Build fix for !ENABLE(JIT) after r119441. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + +2012-06-07 Andy Wingo <wingo@igalia.com> + + Unreviewed build fix after r119593. + + * llint/LLIntOfflineAsmConfig.h (OFFLINE_ASM_GLOBAL_LABEL): Fix + uses of "name" to be "label", the macro's parameter. Otherwise we + serialize mentions of the literal symbol "name" into the objcode. + Causes a build error using GNU ld (not gold). + +2012-06-06 Ryosuke Niwa <rniwa@webkit.org> + + Chromium build fix attempt. Why do we need to list these files in gyp!? + + * JavaScriptCore.gypi: + +2012-06-06 Filip Pizlo <fpizlo@apple.com> + + PredictedType should be called SpeculatedType + https://bugs.webkit.org/show_bug.cgi?id=88477 + + Rubber stamped by Gavin Barraclough. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::shouldOptimizeNow): + (JSC::CodeBlock::dumpValueProfiles): + * bytecode/CodeBlock.h: + (JSC::CodeBlock::valueProfilePredictionForBytecodeOffset): + * bytecode/LazyOperandValueProfile.cpp: + (JSC::LazyOperandValueProfileParser::prediction): + * bytecode/LazyOperandValueProfile.h: + (LazyOperandValueProfileParser): + * bytecode/PredictedType.cpp: Removed. + * bytecode/PredictedType.h: Removed. + * bytecode/SpeculatedType.cpp: Copied from Source/JavaScriptCore/bytecode/PredictedType.cpp. + (JSC::speculationToString): + (JSC::speculationToAbbreviatedString): + (JSC::speculationFromClassInfo): + (JSC::speculationFromStructure): + (JSC::speculationFromCell): + (JSC::speculationFromValue): + * bytecode/SpeculatedType.h: Copied from Source/JavaScriptCore/bytecode/PredictedType.h. + (JSC): + (JSC::isAnySpeculation): + (JSC::isCellSpeculation): + (JSC::isObjectSpeculation): + (JSC::isFinalObjectSpeculation): + (JSC::isFinalObjectOrOtherSpeculation): + (JSC::isFixedIndexedStorageObjectSpeculation): + (JSC::isStringSpeculation): + (JSC::isArraySpeculation): + (JSC::isFunctionSpeculation): + (JSC::isInt8ArraySpeculation): + (JSC::isInt16ArraySpeculation): + (JSC::isInt32ArraySpeculation): + (JSC::isUint8ArraySpeculation): + (JSC::isUint8ClampedArraySpeculation): + (JSC::isUint16ArraySpeculation): + (JSC::isUint32ArraySpeculation): + (JSC::isFloat32ArraySpeculation): + (JSC::isFloat64ArraySpeculation): + (JSC::isArgumentsSpeculation): + (JSC::isActionableIntMutableArraySpeculation): + (JSC::isActionableFloatMutableArraySpeculation): + (JSC::isActionableTypedMutableArraySpeculation): + (JSC::isActionableMutableArraySpeculation): + (JSC::isActionableArraySpeculation): + (JSC::isArrayOrOtherSpeculation): + (JSC::isMyArgumentsSpeculation): + (JSC::isInt32Speculation): + (JSC::isDoubleRealSpeculation): + (JSC::isDoubleSpeculation): + (JSC::isNumberSpeculation): + (JSC::isBooleanSpeculation): + (JSC::isOtherSpeculation): + (JSC::isEmptySpeculation): + (JSC::mergeSpeculations): + (JSC::mergeSpeculation): + * bytecode/StructureSet.h: + (JSC::StructureSet::speculationFromStructures): + * bytecode/ValueProfile.h: + (JSC::ValueProfileBase::ValueProfileBase): + (JSC::ValueProfileBase::dump): + (JSC::ValueProfileBase::computeUpdatedPrediction): + (ValueProfileBase): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::initialize): + (JSC::DFG::AbstractState::execute): + (JSC::DFG::AbstractState::mergeStateAtTail): + * dfg/DFGAbstractState.h: + (JSC::DFG::AbstractState::speculateInt32Unary): + (JSC::DFG::AbstractState::speculateNumberUnary): + (JSC::DFG::AbstractState::speculateBooleanUnary): + (JSC::DFG::AbstractState::speculateInt32Binary): + (JSC::DFG::AbstractState::speculateNumberBinary): + * dfg/DFGAbstractValue.h: + (JSC::DFG::StructureAbstractValue::filter): + (JSC::DFG::StructureAbstractValue::speculationFromStructures): + (JSC::DFG::AbstractValue::AbstractValue): + (JSC::DFG::AbstractValue::clear): + (JSC::DFG::AbstractValue::isClear): + (JSC::DFG::AbstractValue::makeTop): + (JSC::DFG::AbstractValue::clobberStructures): + (JSC::DFG::AbstractValue::isTop): + (JSC::DFG::AbstractValue::set): + (JSC::DFG::AbstractValue::merge): + (JSC::DFG::AbstractValue::filter): + (JSC::DFG::AbstractValue::validateIgnoringValue): + (JSC::DFG::AbstractValue::validate): + (JSC::DFG::AbstractValue::checkConsistency): + (JSC::DFG::AbstractValue::dump): + (AbstractValue): + * dfg/DFGArgumentPosition.h: + (JSC::DFG::ArgumentPosition::ArgumentPosition): + (JSC::DFG::ArgumentPosition::mergeArgumentAwareness): + (JSC::DFG::ArgumentPosition::prediction): + (ArgumentPosition): + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + * dfg/DFGByteCodeParser.cpp: + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::injectLazyOperandSpeculation): + (JSC::DFG::ByteCodeParser::getLocal): + (JSC::DFG::ByteCodeParser::getArgument): + (JSC::DFG::ByteCodeParser::addCall): + (JSC::DFG::ByteCodeParser::getSpeculationWithoutOSRExit): + (JSC::DFG::ByteCodeParser::getSpeculation): + (InlineStackEntry): + (JSC::DFG::ByteCodeParser::handleCall): + (JSC::DFG::ByteCodeParser::handleIntrinsic): + (JSC::DFG::ByteCodeParser::handleGetById): + (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::fixVariableAccessSpeculations): + (JSC::DFG::ByteCodeParser::parse): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getIndexedPropertyStorageLoadElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::run): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + (JSC::DFG::FixupPhase::fixDoubleEdge): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::nameOfVariableAccessData): + (JSC::DFG::Graph::dump): + (JSC::DFG::Graph::predictArgumentTypes): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::getJSConstantSpeculation): + (JSC::DFG::Graph::isPredictedNumerical): + (JSC::DFG::Graph::byValIsPure): + * dfg/DFGJITCompiler.h: + (JSC::DFG::JITCompiler::getSpeculation): + * dfg/DFGNode.h: + (JSC::DFG::Node::Node): + (JSC::DFG::Node::getHeapPrediction): + (JSC::DFG::Node::predictHeap): + (JSC::DFG::Node::prediction): + (JSC::DFG::Node::predict): + (JSC::DFG::Node::shouldSpeculateInteger): + (JSC::DFG::Node::shouldSpeculateDouble): + (JSC::DFG::Node::shouldSpeculateNumber): + (JSC::DFG::Node::shouldSpeculateBoolean): + (JSC::DFG::Node::shouldSpeculateFinalObject): + (JSC::DFG::Node::shouldSpeculateFinalObjectOrOther): + (JSC::DFG::Node::shouldSpeculateArray): + (JSC::DFG::Node::shouldSpeculateArguments): + (JSC::DFG::Node::shouldSpeculateInt8Array): + (JSC::DFG::Node::shouldSpeculateInt16Array): + (JSC::DFG::Node::shouldSpeculateInt32Array): + (JSC::DFG::Node::shouldSpeculateUint8Array): + (JSC::DFG::Node::shouldSpeculateUint8ClampedArray): + (JSC::DFG::Node::shouldSpeculateUint16Array): + (JSC::DFG::Node::shouldSpeculateUint32Array): + (JSC::DFG::Node::shouldSpeculateFloat32Array): + (JSC::DFG::Node::shouldSpeculateFloat64Array): + (JSC::DFG::Node::shouldSpeculateArrayOrOther): + (JSC::DFG::Node::shouldSpeculateObject): + (JSC::DFG::Node::shouldSpeculateCell): + (Node): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::setPrediction): + (JSC::DFG::PredictionPropagationPhase::mergePrediction): + (JSC::DFG::PredictionPropagationPhase::propagate): + (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::fillStorage): + (JSC::DFG::SpeculativeJIT::writeBarrier): + (JSC::DFG::GPRTemporary::GPRTemporary): + (JSC::DFG::FPRTemporary::FPRTemporary): + (JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch): + (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality): + (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch): + (JSC::DFG::SpeculativeJIT::compile): + (JSC::DFG::SpeculativeJIT::checkArgumentTypes): + (JSC::DFG::SpeculativeJIT::compileGetCharCodeAt): + (JSC::DFG::SpeculativeJIT::compileGetByValOnString): + (JSC::DFG::SpeculativeJIT::compileValueToInt32): + (JSC::DFG::SpeculativeJIT::compileDoubleAsInt32): + (JSC::DFG::SpeculativeJIT::compileInt32ToDouble): + (JSC::DFG::SpeculativeJIT::compileGetTypedArrayLength): + (JSC::DFG::SpeculativeJIT::compileGetByValOnIntTypedArray): + (JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray): + (JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray): + (JSC::DFG::SpeculativeJIT::compilePutByValForFloatTypedArray): + (JSC::DFG::SpeculativeJIT::compileInstanceOf): + (JSC::DFG::SpeculativeJIT::compileAdd): + (JSC::DFG::SpeculativeJIT::compileArithSub): + (JSC::DFG::SpeculativeJIT::compileArithNegate): + (JSC::DFG::SpeculativeJIT::compileArithMul): + (JSC::DFG::SpeculativeJIT::compileArithMod): + (JSC::DFG::SpeculativeJIT::compare): + (JSC::DFG::SpeculativeJIT::compileStrictEq): + (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): + (JSC::DFG::SpeculativeJIT::compileGetByValOnArguments): + (JSC::DFG::SpeculativeJIT::compileGetArgumentsLength): + (JSC::DFG::SpeculativeJIT::compileRegExpExec): + * dfg/DFGSpeculativeJIT.h: + (DFG): + (JSC::DFG::ValueSource::forSpeculation): + (SpeculativeJIT): + (GPRTemporary): + (FPRTemporary): + (JSC::DFG::SpecDoubleOperand::SpecDoubleOperand): + (JSC::DFG::SpecDoubleOperand::~SpecDoubleOperand): + (JSC::DFG::SpecDoubleOperand::fpr): + (JSC::DFG::SpecCellOperand::SpecCellOperand): + (JSC::DFG::SpecCellOperand::~SpecCellOperand): + (JSC::DFG::SpecCellOperand::gpr): + (JSC::DFG::SpecBooleanOperand::SpecBooleanOperand): + (JSC::DFG::SpecBooleanOperand::~SpecBooleanOperand): + (JSC::DFG::SpecBooleanOperand::gpr): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): + (JSC::DFG::SpeculativeJIT::fillSpecDouble): + (JSC::DFG::SpeculativeJIT::fillSpecCell): + (JSC::DFG::SpeculativeJIT::fillSpecBoolean): + (JSC::DFG::SpeculativeJIT::compileObjectEquality): + (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): + (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): + (JSC::DFG::SpeculativeJIT::compileDoubleCompare): + (JSC::DFG::SpeculativeJIT::compileLogicalNot): + (JSC::DFG::SpeculativeJIT::emitBranch): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): + (JSC::DFG::SpeculativeJIT::fillSpecDouble): + (JSC::DFG::SpeculativeJIT::fillSpecCell): + (JSC::DFG::SpeculativeJIT::fillSpecBoolean): + (JSC::DFG::SpeculativeJIT::compileObjectEquality): + (JSC::DFG::SpeculativeJIT::compileObjectToObjectOrOtherEquality): + (JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality): + (JSC::DFG::SpeculativeJIT::compileDoubleCompare): + (JSC::DFG::SpeculativeJIT::compileLogicalNot): + (JSC::DFG::SpeculativeJIT::emitBranch): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGVariableAccessData.h: + (JSC::DFG::VariableAccessData::VariableAccessData): + (JSC::DFG::VariableAccessData::predict): + (JSC::DFG::VariableAccessData::nonUnifiedPrediction): + (JSC::DFG::VariableAccessData::prediction): + (JSC::DFG::VariableAccessData::argumentAwarePrediction): + (JSC::DFG::VariableAccessData::mergeArgumentAwarePrediction): + (JSC::DFG::VariableAccessData::shouldUseDoubleFormatAccordingToVote): + (JSC::DFG::VariableAccessData::makePredictionForDoubleFormat): + (VariableAccessData): + +2012-06-06 Filip Pizlo <fpizlo@apple.com> + + Global object variable accesses should not require an extra load + https://bugs.webkit.org/show_bug.cgi?id=88385 + + Reviewed by Gavin Barraclough and Geoffrey Garen. + + Previously, if you wanted to access a global variable, you'd first have + to load the register array from the appropriate global object and then + either load or store at an offset to the register array. This is because + JSGlobalObject inherited from JSVariableObject, and JSVariableObject is + designed with the pessimistic assumption that its register array may + point into the call stack. This is never the case for global objects. + Hence, even though the global object may add more registers at any time, + it does not need to store them in a contiguous array. It can use a + SegmentedVector or similar. + + This patch refactors global objects and variable objects as follows: + + - The functionality to track variables in an indexable array using a + SymbolTable to map names to indices is moved into JSSymbolTableObject, + which is now a supertype of JSVariableObject. JSVariableObject is now + just a holder for a registers array and implements the registerAt() + method that is left abstract in JSSymbolTableObject. Because all users + of JSVariableObject know whether they are a JSStaticScopeObject, + JSActivation, or JSGlobalObject, this "abstract" method is not virtual; + instead the utility methods that would call registerAt() are now + template functions that require you to know statically what subtype of + JSSymbolTableObject you're using (JSVariableObject or something else), + so that registerAt() can be statically bound. + + - A new class is added called JSSegmentedVariableObject, which only + differs from JSVariableObject in how it allocates registers. It uses a + SegmentedVector instead of manually managing a pointer to a contiguous + slab of registers. This changes the interface somewhat; for example + with JSVariableObject if you wanted to add a register you had to do + it yourself since the JSVariableObject didn't know how the registers + array ought to be allocated. With JSSegmentedVariableObject you can + just call addRegisters(). JSSegmentedVariableObject preserves the + invariant that once you get a pointer into a register, that pointer + will continue to be valid so long as the JSSegmentedVariableObject is + alive. This allows the JITs and interpreters to skip the extra load. + + - JSGlobalObject now inherits from JSSegmentedVariableObject. For now + (and possibly forever) it is the only subtype of this new class. + + - The bytecode format is changed so that get_global_var and + put_global_var have a pointer to the register directly rather than + having an index. A convenience method is provided in + JSSegmentedVariableObject to get the index given a a pointer, which is + used for assertions and debug dumps. + + This appears to be a 1% across the board win. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * bytecode/Instruction.h: + (Instruction): + (JSC::Instruction::Instruction): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::ResolveResult::registerPointer): + (JSC): + (JSC::BytecodeGenerator::BytecodeGenerator): + (JSC::BytecodeGenerator::retrieveLastUnaryOp): + (JSC::BytecodeGenerator::resolve): + (JSC::BytecodeGenerator::resolveConstDecl): + (JSC::BytecodeGenerator::emitGetStaticVar): + (JSC::BytecodeGenerator::emitPutStaticVar): + * bytecompiler/BytecodeGenerator.h: + (ResolveResult): + (BytecodeGenerator): + * dfg/DFGAssemblyHelpers.h: + (AssemblyHelpers): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::globalVarLoadElimination): + (JSC::DFG::CSEPhase::globalVarStoreElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::dump): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::globalObjectFor): + (Graph): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasVarNumber): + (Node): + (JSC::DFG::Node::hasRegisterPointer): + (JSC::DFG::Node::registerPointer): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * heap/Heap.h: + (Heap): + (JSC::Heap::isWriteBarrierEnabled): + (JSC): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::execute): + (JSC::Interpreter::privateExecute): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::emit_op_get_global_var): + (JSC::JIT::emit_op_put_global_var): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::emit_op_get_global_var): + (JSC::JIT::emit_op_put_global_var): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/JSGlobalObject.cpp: + (JSC): + (JSC::JSGlobalObject::put): + (JSC::JSGlobalObject::putDirectVirtual): + (JSC::JSGlobalObject::defineOwnProperty): + (JSC::JSGlobalObject::visitChildren): + (JSC::JSGlobalObject::addStaticGlobals): + (JSC::JSGlobalObject::getOwnPropertySlot): + (JSC::JSGlobalObject::getOwnPropertyDescriptor): + * runtime/JSGlobalObject.h: + (JSGlobalObject): + (JSC::JSGlobalObject::JSGlobalObject): + (JSC): + (JSC::JSGlobalObject::hasOwnPropertyForWrite): + * runtime/JSSegmentedVariableObject.cpp: Added. + (JSC): + (JSC::JSSegmentedVariableObject::findRegisterIndex): + (JSC::JSSegmentedVariableObject::addRegisters): + (JSC::JSSegmentedVariableObject::visitChildren): + * runtime/JSSegmentedVariableObject.h: Added. + (JSC): + (JSSegmentedVariableObject): + (JSC::JSSegmentedVariableObject::registerAt): + (JSC::JSSegmentedVariableObject::assertRegisterIsInThisObject): + (JSC::JSSegmentedVariableObject::JSSegmentedVariableObject): + (JSC::JSSegmentedVariableObject::finishCreation): + * runtime/JSStaticScopeObject.cpp: + (JSC::JSStaticScopeObject::put): + (JSC::JSStaticScopeObject::putDirectVirtual): + (JSC::JSStaticScopeObject::getOwnPropertySlot): + * runtime/JSSymbolTableObject.cpp: Added. + (JSC): + (JSC::JSSymbolTableObject::destroy): + (JSC::JSSymbolTableObject::deleteProperty): + (JSC::JSSymbolTableObject::getOwnPropertyNames): + (JSC::JSSymbolTableObject::putDirectVirtual): + (JSC::JSSymbolTableObject::isDynamicScope): + * runtime/JSSymbolTableObject.h: Added. + (JSC): + (JSSymbolTableObject): + (JSC::JSSymbolTableObject::symbolTable): + (JSC::JSSymbolTableObject::JSSymbolTableObject): + (JSC::JSSymbolTableObject::finishCreation): + (JSC::symbolTableGet): + (JSC::symbolTablePut): + (JSC::symbolTablePutWithAttributes): + * runtime/JSVariableObject.cpp: + (JSC): + * runtime/JSVariableObject.h: + (JSVariableObject): + (JSC::JSVariableObject::JSVariableObject): + (JSC::JSVariableObject::finishCreation): + (JSC): + * runtime/WriteBarrier.h: + +2012-06-06 Filip Pizlo <fpizlo@apple.com> + + DFG arguments access slow path should not crash if the arguments haven't been created + https://bugs.webkit.org/show_bug.cgi?id=88471 + + Reviewed by Gavin Barraclough. + + * dfg/DFGCCallHelpers.h: + (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): + (CCallHelpers): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-06-06 Michael Saboff <msaboff@apple.com> + + ENH: Add Logging to GC Marking Phase + https://bugs.webkit.org/show_bug.cgi?id=88364 + + Reviewed by Filip Pizlo. + + Log GC marking to stderr or a file. The logging in controlled + with the define ENABLE_OBJECT_MARK_LOGGING in wtf/Platform.h. + If DATA_LOG_TO_FILE in wtf/DataLog.cpp is set to 1, output is + logged to a file otherwise it is logged to stderr. + + When logging is enabled, the GC is built single threaded since the + log output from the various threads isn't buffered and output in a + thread safe manner. + + * heap/Heap.cpp: + (JSC::Heap::markRoots): + * heap/MarkStack.cpp: + (JSC::MarkStackThreadSharedData::resetChildren): + (JSC::MarkStackThreadSharedData::childVisitCount): + (JSC::MarkStackThreadSharedData::markingThreadMain): + (JSC::MarkStackThreadSharedData::markingThreadStartFunc): + (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData): + (JSC::MarkStackThreadSharedData::reset): + * heap/MarkStack.h: + (MarkStackThreadSharedData): + (MarkStack): + (JSC::MarkStack::sharedData): + (JSC::MarkStack::resetChildCount): + (JSC::MarkStack::childCount): + (JSC::MarkStack::incrementChildCount): + * runtime/JSArray.cpp: + (JSC::JSArray::visitChildren): + * runtime/JSCell.cpp: + (JSC::JSCell::className): + * runtime/JSCell.h: + (JSCell): + (JSC::JSCell::visitChildren): + * runtime/JSString.cpp: + (JSC::JSString::visitChildren): + * runtime/JSString.h: + (JSString): + * runtime/Structure.h: + (JSC::MarkStack::internalAppend): + +2012-06-06 Gavin Barraclough <barraclough@apple.com> + + Assigning to a static property should not change iteration order + https://bugs.webkit.org/show_bug.cgi?id=88401 + + Reviewed by Geoff Garen. + + A specific iteration order is not defined by the spec, but test-262 somewhat tenuously + requires that it is at least stable, e.g. ch10/10.4/10.4.2/S10.4.2_A1.1_T1.js + + Whilst it is not clear that this behavior really arises from the specification, it + would seem like common sense to conform to this. + + The problem here is that we allow properties in the structure to shadow those in the + static table, and we iterate the properties in the structure first - which means that + as values of existing properties are modified, their iteration order changes too. + + The easy fix is to iterate the properties from the static table first. This has a + further benefit, since it will mean that user added properties will come after those + present in the static table (respected the expected insertion-order). + + * runtime/JSObject.cpp: + (JSC::JSObject::getOwnPropertyNames): + - Iterate static properties first. + +2012-06-06 Andy Wingo <wingo@igalia.com> + + Ensure consistent order of evaluation in LLInt slow paths + https://bugs.webkit.org/show_bug.cgi?id=88409 + + Reviewed by Geoffrey Garen. + + * llint/LLIntSlowPaths.cpp: + (slow_path_mul) + (slow_path_sub) + (slow_path_div) + (slow_path_mod) + (slow_path_lshift) + (slow_path_rshift) + (slow_path_urshift) + (slow_path_bitand) + (slow_path_bitor) + (slow_path_bitxor): Avoid calling toNumber, toInt32, or toUInt32 + multiple times without intervening sequence points. Fixes + fast/js/exception-sequencing-binops.html with GCC 4.7 on x86-64 + Linux, which reordered evaluation of the arguments to fmod. + +2012-06-06 Andy Wingo <wingo@igalia.com> + + [GTK] Enable the LLInt + https://bugs.webkit.org/show_bug.cgi?id=88315 + + Reviewed by Filip Pizlo. + + * GNUmakefile.am: Add rules to generate LLIntDesiredOffsets.h and + LLIntAssembly.h. + * GNUmakefile.list.am: Add offlineasm and llint files to the + dist. Add LLInt source files to the build. + * llint/LowLevelInterpreter.asm (crash): Generate a store of + 0xbbadbeef to a register, not to a constant. Otherwise, gas was + failing to assemble result. + * offlineasm/asm.rb (labelReference): Generate a + SYMBOL_STRING_RELOCATION instead of a SYMBOL_STRING, so that we go + through the PLT on ELF systems. + +2012-06-06 Andy Wingo <wingo@igalia.com> + + REGRESSION (r106478): None of the Paper.js JavaScript examples work + https://bugs.webkit.org/show_bug.cgi?id=87158 + + Reviewed by Michael Saboff. + + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::resolve): If we have to bail out to + dynamicResolve(), only skip static scopes from the head of the + scope chain. Before, we were also skipping activations with + direct eval as well, which was incorrect. + +2012-06-06 Dan Bernstein <mitz@apple.com> + + Reverted r119567, the fix for <http://webkit.org/b/88378>, because it broke the 32-bit build. + + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + * llint/LowLevelInterpreter.asm: + * runtime/JSGlobalData.h: + (JSGlobalData): + * runtime/JSGlobalThis.cpp: + (JSC::JSGlobalThis::setUnwrappedObject): + * runtime/JSObject.cpp: + (JSC::JSObject::visitChildren): + (JSC::JSObject::createInheritorID): + * runtime/JSObject.h: + (JSObject): + (JSC::JSObject::resetInheritorID): + (JSC): + (JSC::JSObject::offsetOfInheritorID): + (JSC::JSObject::inheritorID): + +2012-06-05 Yuqiang Xian <yuqiang.xian@intel.com> + + Improve Math.round and Math.floor intrinsic + https://bugs.webkit.org/show_bug.cgi?id=88314 + + Reviewed by Filip Pizlo. + + Currently we call a native function from the JIT code to complete the + "round" and "floor" operations. We could inline some fast paths + especially for those positive values on the platforms where floating + point truncation is supported. + This brings 3% gain on Kraken, especially 32% on audio-oscillator, + and slight win on SunSpider, measured on IA32. + + * jit/ThunkGenerators.cpp: + (JSC::floorThunkGenerator): + (JSC): + (JSC::roundThunkGenerator): + +2012-06-05 Gavin Barraclough <barraclough@apple.com> + + Remove JSObject::m_inheritorID + https://bugs.webkit.org/show_bug.cgi?id=88378 + + Reviewed by Geoff Garen. + + This is rarely used, and not performance critical (the commonly accessed copy is cached on JSFunction), + and most objects don't need an inheritorID (this value is only used if the object is used as a prototype). + Instead use a private named value in the object's property storage. + + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::emitAllocateBasicJSObject): + - No need m_inheritorID to initialize! + * jit/JITInlineMethods.h: + (JSC::JIT::emitAllocateBasicJSObject): + - No need m_inheritorID to initialize! + * llint/LowLevelInterpreter.asm: + - No need m_inheritorID to initialize! + * runtime/JSGlobalData.h: + (JSGlobalData): + - Added private name 'm_inheritorIDKey'. + * runtime/JSGlobalThis.cpp: + (JSC::JSGlobalThis::setUnwrappedObject): + - resetInheritorID is now passed a JSGlobalData&. + * runtime/JSObject.cpp: + (JSC::JSObject::visitChildren): + - No m_inheritorID to be marked. + (JSC::JSObject::createInheritorID): + - Store the newly created inheritorID in the property map. + * runtime/JSObject.h: + (JSC::JSObject::resetInheritorID): + - Remove the inheritorID from property storage. + (JSC::JSObject::inheritorID): + - Read the inheritorID from property storage. + +2012-06-05 Filip Pizlo <fpizlo@apple.com> + + DFG CFG simplification should not attempt to deref nodes inside of an unreachable subgraph + https://bugs.webkit.org/show_bug.cgi?id=88362 + + Reviewed by Gavin Barraclough. + + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::fixPhis): + (JSC::DFG::CFGSimplificationPhase::removePotentiallyDeadPhiReference): + +2012-06-05 Mark Hahnenberg <mhahnenberg@apple.com> + + Entry into JSC should CRASH() if the Heap is busy + https://bugs.webkit.org/show_bug.cgi?id=88355 + + Reviewed by Geoffrey Garen. + + Interpreter::execute() returns jsNull() right now if we try to enter it while + the Heap is busy (e.g. with a collection), which is okay, but some code paths + that call Interpreter::execute() allocate objects before checking if the Heap + is busy. Attempting to execute JS code while the Heap is busy should not be + allowed and should be enforced by a release-mode CRASH() to prevent vague, + unhelpful backtraces later on if somebody makes a mistake. Normally, recursively + executing JS code is okay, e.g. for evals, but it should not occur during a + Heap allocation or collection because the Heap is not guaranteed to be in a + consistent state (especially during collections). We are protected from + executing JS on the same Heap concurrently on two separate threads because + they must each take a JSLock first. However, we are not protected from reentrant + execution of JS on the same thread because JSLock allows reentrancy. Therefore, + we should fail early if we detect an entrance into JS code while the Heap is busy. + + * heap/Heap.cpp: Changed Heap::collect so that it sets the m_operationInProgress field + at the beginning of collection and then unsets it at the end so that it is set at all + times throughout the duration of a collection rather than sporadically during various + phases. There is no reason to unset during a collection because our collector does + not currently support running additional JS between the phases of a collection. + (JSC::Heap::getConservativeRegisterRoots): + (JSC::Heap::markRoots): + (JSC::Heap::collect): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::execute): Crash if the Heap is busy. + * runtime/Completion.cpp: Crash if the Heap is busy. We do it here before we call + Interpreter::execute() because we do some allocation prior to calling execute() which + could cause Heap corruption if, for example, that allocation caused a collection. + (JSC::evaluate): + +2012-06-05 Dongwoo Im <dw.im@samsung.com> + + Add 'isProtocolHandlerRegistered' and 'unregisterProtocolHandler'. + https://bugs.webkit.org/show_bug.cgi?id=73176 + + Reviewed by Adam Barth. + + Two more APIs are added in Custom Scheme Handler specification. + http://dev.w3.org/html5/spec/Overview.html#custom-handlers + One is 'isProtocolHandlerRegistered' to query whether the specific URL + is registered or not. + The other is 'unregisterProtocolHandler' to remove the registered URL. + + * Configurations/FeatureDefines.xcconfig: Add a macro 'ENABLE_CUSTOM_SCHEME_HANDLER'. + +2012-06-04 Filip Pizlo <fpizlo@apple.com> + + DFG CFG simplification should correct the variables at the head of the predecessor block + https://bugs.webkit.org/show_bug.cgi?id=88284 + + Reviewed by Geoffrey Garen. + + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::mergeBlocks): + +2012-06-04 Geoffrey Garen <ggaren@apple.com> + + Unreviewed. + + Rolled out r119364 because it's still causing crashes (when running + v8-earley in release builds of DRT) + + This time for sure! + + * heap/Heap.cpp: + (JSC::Heap::collect): + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::sweep): + * heap/MarkedBlock.h: + (JSC::MarkedBlock::resetAllocator): + (JSC): + * heap/MarkedSpace.cpp: + (JSC::ResetAllocator::operator()): + (JSC): + (JSC::MarkedSpace::resetAllocators): + (JSC::MarkedSpace::sweepWeakSets): + * heap/MarkedSpace.h: + (MarkedSpace): + * heap/WeakBlock.cpp: + (JSC::WeakBlock::sweep): + * heap/WeakSet.cpp: + (JSC::WeakSet::sweep): + (JSC::WeakSet::tryFindAllocator): + * heap/WeakSet.h: + (JSC::WeakSet::shrink): + +2012-06-04 Filip Pizlo <fpizlo@apple.com> + + DFG arguments simplification should have rationalized handling of TearOffArguments + https://bugs.webkit.org/show_bug.cgi?id=88206 + + Reviewed by Geoffrey Garen. + + - Accesses to the unmodified arguments register ought to have the same effect on + alias/escape analysis of arguments as accesses to the mutable arguments register. + + - The existence of TearOffArguments should not get in the way of arguments aliasing. + + - TearOffArguments should be eliminated if CreateArguments is eliminated. + + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): + +2012-06-04 Gavin Barraclough <barraclough@apple.com> + + Remove enabledProfilerReference + https://bugs.webkit.org/show_bug.cgi?id=88258 + + Reviewed by Michael Saboff. + + Make the enabled profiler a member of JSGlobalData, and switch code that accesses it to do so directly + via the JSGlobalData, rather than holding a Profiler** reference to it. Do not pass the Profiler** + reference to JIT code. This patch does not change the stack layout on entry into JIT code (passing an + unused void* instead), since this is an intrusive change better handled in a separate patch. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::throwException): + (JSC::Interpreter::execute): + (JSC::Interpreter::executeCall): + (JSC::Interpreter::executeConstruct): + (JSC::Interpreter::privateExecute): + * jit/JITCode.h: + (JSC::JITCode::execute): + - Don't pass Profiler** to JIT code. + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_profile_will_call): + (JSC::JIT::emit_op_profile_did_call): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_profile_will_call): + (JSC::JIT::emit_op_profile_did_call): + * jit/JITStubs.cpp: + (JSC): + (JSC::ctiTrampoline): + (JSC::ctiVMThrowTrampoline): + (JSC::ctiOpThrowNotCaught): + (JSC::JITThunks::JITThunks): + (JSC::DEFINE_STUB_FUNCTION): + - For ARM_THUMB2, rename ENABLE_PROFILER_REFERENCE_OFFSET to FIRST_STACK_ARGUMENT (which is how it is being used). + - For MIPS, remove ENABLE_PROFILER_REFERENCE_OFFSET. + * jit/JITStubs.h: + (JITStackFrame): + (JSC): + - Renamed enabledProfilerReference to unusedX. + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter.asm: + * profiler/Profiler.cpp: + (JSC): + (JSC::Profiler::startProfiling): + (JSC::Profiler::stopProfiling): + * profiler/Profiler.h: + (Profiler): + - Removed s_sharedEnabledProfilerReference, enabledProfilerReference(). + * runtime/JSGlobalData.cpp: + (JSC::JSGlobalData::JSGlobalData): + * runtime/JSGlobalData.h: + (JSC): + (JSC::JSGlobalData::enabledProfiler): + (JSGlobalData): + - Added m_enabledProfiler, enabledProfiler(). + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::~JSGlobalObject): + +2012-06-04 Filip Pizlo <fpizlo@apple.com> + + get_argument_by_val should be profiled everywhere + https://bugs.webkit.org/show_bug.cgi?id=88205 + + Reviewed by Geoffrey Garen. + + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emitSlow_op_get_argument_by_val): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + +2012-06-04 Filip Pizlo <fpizlo@apple.com> + + DFG arguments simplification takes unkindly to direct accesses to the arguments register + https://bugs.webkit.org/show_bug.cgi?id=88261 + + Reviewed by Geoffrey Garen. + + Fixed arguments simplification for direct accesses to the arguments register, which may + arise if CSE had not run. Fixed CSE so that it does run prior to arguments simplification, + by making it a full-fledged member of the fixpoint. Fixed other issues in arguments + simplification, like realizing that it needs to bail if there is a direct assignment to + the arguments register, and failing to turn CreateArguments into PhantomArguments. Also + fixed CSE's handling of store elimination of captured locals in the presence of a + GetMyArgumentByVal (or one of its friends), and fixed CSE to correctly fixup variables at + tail if the Flush it removes is the last operation on a local in a basic block. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::run): + (JSC::DFG::CSEPhase::setLocalStoreElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + (CSEPhase): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + +2012-06-04 Anders Carlsson <andersca@apple.com> + + Fix a struct/class mismatch. + + * heap/Handle.h: + (Handle): + +2012-06-04 David Kilzer <ddkilzer@apple.com> + + BUILD FIX: FeatureDefines.xcconfig should match across projects + + * Configurations/FeatureDefines.xcconfig: + - Add missing ENABLE_LEGACY_CSS_VENDOR_PREFIXES. + +2012-06-02 Geoffrey Garen <ggaren@apple.com> + + Weak pointer finalization should be lazy + https://bugs.webkit.org/show_bug.cgi?id=87599 + + Reviewed by Sam Weinig. + + This time for sure! + + * heap/Heap.cpp: + (JSC::Heap::collect): Don't sweep eagerly -- we'll sweep lazily instead. + + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::sweep): Sweep our weak set before we sweep our other + destructors -- this is our last chance to run weak set finalizers before + we recycle our memory. + + * heap/MarkedBlock.h: + (JSC::MarkedBlock::resetAllocator): + * heap/MarkedSpace.cpp: + (JSC::MarkedSpace::resetAllocators): + * heap/MarkedSpace.h: + (JSC::MarkedSpace::resetAllocators): Don't force allocator reset anymore. + It will happen automatically when a weak set is swept. It's simpler to + have only one canonical way for this to happen, and it wasn't buying + us anything to do it eagerly. + + * heap/WeakBlock.cpp: + (JSC::WeakBlock::sweep): Don't short-circuit a sweep unless we know + the sweep would be a no-op. If even one finalizer is pending, we need to + run it, since we won't get another chance. + + * heap/WeakSet.cpp: + (JSC::WeakSet::sweep): This loop can be simpler now that + WeakBlock::sweep() does what we mean. + + Reset our allocator after a sweep because this is the optimal time to + start trying to recycle old weak pointers. + + (JSC::WeakSet::tryFindAllocator): Don't sweep when searching for an + allocator because we've swept already, and forcing a new sweep would be + wasteful. + + * heap/WeakSet.h: + (JSC::WeakSet::shrink): Be sure to reset our allocator after a shrink + because the shrink may have removed the block the allocator was going to + allocate out of. + +2012-06-02 Filip Pizlo <fpizlo@apple.com> + + If the DFG bytecode parser detects that op_method_check has gone polymorphic, it + shouldn't revert all the way to GetById/GetByIdFlush + https://bugs.webkit.org/show_bug.cgi?id=88176 + + Reviewed by Geoffrey Garen. + + Refactored the code so that the op_method_check case of the parser gracefully falls + through to all of the goodness of the normal op_get_by_id case. + + * dfg/DFGByteCodeParser.cpp: + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::handleGetById): + (DFG): + (JSC::DFG::ByteCodeParser::parseBlock): + +2012-06-02 Filip Pizlo <fpizlo@apple.com> + + DFG CSE should be able to eliminate unnecessary flushes of arguments and captured variables + https://bugs.webkit.org/show_bug.cgi?id=87929 + + Reviewed by Geoffrey Garen. + + Slight speed-up on V8. Big win (up to 50%) on programs that inline very small functions. + + This required a bunch of changes: + + - The obvious change is making CSE essentially ignore whether or not the set of + operations between the Flush and the SetLocal can exit, and instead focus on whether or + not that set of operations can clobber the world or access local variables. This code + is now refactored to return a set of flags indicating any of these events, and the CSE + decides what to do based on those flags. If the set of operations is non-clobbering + and non-accessing, then the Flush is turned into a Phantom on the child of the + SetLocal. This expands the liveness of the relevant variable but virtually guarantees + that it will be register allocated and not flushed to the stack. So, yeah, this patch + is a lot of work to save a few stores to the stack. + + - Previously, CheckArgumentsNotCreated was optimized "lazily" in that you only knew if + it was a no-op if you were holding onto a CFA abstract state. But this would make the + CSE act pessimistically, since it doesn't use the CFA. Hence, this patch changes the + constant folding phase into something more broad; it now fixes up + CheckArgumentsNotCreated nodes by turning them into phantoms if it knows that they are + no-ops. + + - Arguments simplification was previously relying on this very strange PhantomArguments + node, which had two different meanings: for normal execution it meant the empty value + but for OSR exit it meant that the arguments should be reified. This produces problems + when set SetLocals to the captured arguments registers are CSE'd away, since we'd be + triggering reification of arguments without having initialized the arguments registers + to empty. The cleanest solution was to fix PhantomArguments to have one meaning: + namely, arguments reification on OSR exit. Hence, this patch changes arguments + simplification to change SetLocal of CreateArguments on the arguments registers to be + a SetLocal of Empty. + + - Argument value recoveries were previously derived from the value source of the + arguments at the InlineStart. But that relies on all SetLocals to arguments having + been flushed. It's possible that we could have elided the SetLocal to the arguments + at the callsite because there were subsequent SetLocals to the arguments inside of the + callee, in which case the InlineStart would get the wrong information. Hence, this + patch changes argument value recovery computation to operate over the ArgumentPositions + directly. + + - But that doesn't actually work, because previously, there was no way to link an + InlineStart back to the corresponding ArgumentPositions, at least not without some + ugliness. So this patch instates the rule that the m_argumentPositions vector consists + of disjoint subsequences such that each subsequence corresponds to an inline callsite + and can be identified by its first index, and within each subsequence are the + ArgumentPositions of all of the arguments ordered by argument index. This required + flipping the order in which ArgumentPositions are added to the vector, and giving + InlineStart an operand that indicates the start of that inline callsite's + ArgumentPosition subsequence. + + - This patch also revealed a nasty bug in the reification of arguments in inline call + frames on OSR exit. Since the reification was happening after the values of virtual + registers were recovered, the value recoveries of the inline arguments were wrong. + Hence using operationCreateInlinedArguments is wrong. For example a value recovery + might say that you have to box a double, but if we had already boxed it then boxing + it a second time will result in garbage. The specific case of this bug was this patch + uncovered was that now it is possible for an inline call frame to not have any valid + value recoveries for any inline arguments, if the optimization elides all argument + flushes, while at the same time optimizing away arguments creation. Then OSR exit + would try to recover the arguments using the inline call frame, which had bogus + information, and humorous crashes would ensue. This patch fixes this issue by moving + arguments reification to after call frame reification, so that arguments reification + can always use operationCreateArguments instead of operationCreateInlinedArguments. + + - This patch may turn a Flush into a Phantom. That's kind of the whole point. But that + broke forward speculation checks, which knew to look for a Flush prior to a SetLocal + but didn't know that there could alternatively be a Phantom in place of the Flush. + This patch fixes that by augmenting the forward speculation check logic. + + - Finally, in the process of having fun with all of the above, I realized that my DFG + validation was not actually running on every phase like I had originally designed it + to. In fact it was only running just after bytecode parsing. I initially tried to + make it run in every phase but found that this causes some tests to timeout + (specifically the evil fuzzing ones), so I decided on a compromise where: (i) in + release mode validation never runs, (ii) in debug mode validation will run just + after parsing and just before the backend, and (iii) it's possible with a simple + switch to enable validation to run on every phase. + + Luckily all of the above issues were already covered by the 77 or so DFG-specific + layout tests. Hence, this patch does not introduce any new tests despite being so + meaty. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGArgumentPosition.h: + (JSC::DFG::ArgumentPosition::prediction): + (JSC::DFG::ArgumentPosition::doubleFormatState): + (JSC::DFG::ArgumentPosition::shouldUseDoubleFormat): + (ArgumentPosition): + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleInlining): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::SetLocalStoreEliminationResult::SetLocalStoreEliminationResult): + (SetLocalStoreEliminationResult): + (JSC::DFG::CSEPhase::setLocalStoreElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGCommon.h: + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::run): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGNode.h: + (Node): + (JSC::DFG::Node::hasArgumentPositionStart): + (JSC::DFG::Node::argumentPositionStart): + * dfg/DFGOSRExitCompiler32_64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGOSRExitCompiler64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGPhase.cpp: + (DFG): + * dfg/DFGPhase.h: + (Phase): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-06-02 Geoffrey Garen <ggaren@apple.com> + + DOM string cache should hash pointers, not characters + https://bugs.webkit.org/show_bug.cgi?id=88175 + + Reviewed by Phil Pizlo and Sam Weinig. + + * heap/Weak.h: + (JSC::weakAdd): + (JSC::weakRemove): Made these function templates slightly more generic + to accommodate new client types. + +2012-06-01 Filip Pizlo <fpizlo@apple.com> + + DFG CFA should know that PutByVal can clobber the world + https://bugs.webkit.org/show_bug.cgi?id=88155 + + Reviewed by Gavin Barraclough. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + +2012-06-01 Filip Pizlo <fpizlo@apple.com> + + DFG CFA should mark basic blocks as having constants if local accesses yield constants + https://bugs.webkit.org/show_bug.cgi?id=88153 + + Reviewed by Gavin Barraclough. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + +2012-06-01 Filip Pizlo <fpizlo@apple.com> + + DFG arguments simplification phase uses a node.codeOrigin after appending a node + https://bugs.webkit.org/show_bug.cgi?id=88151 + + Reviewed by Geoffrey Garen. + + The right thing to do is to save the CodeOrigin before appending to the graph. + + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + +2012-06-01 Filip Pizlo <fpizlo@apple.com> + + DFG should not emit unnecessary speculation checks when performing an int32 to double conversion on + a value that is proved to be a number, predicted to be an int32, but not proved to be an int32 + https://bugs.webkit.org/show_bug.cgi?id=88146 + + Reviewed by Gavin Barraclough. + + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compileInt32ToDouble): + +2012-06-01 Filip Pizlo <fpizlo@apple.com> + + DFG constant folding search for the last local access skips the immediately previous local access + https://bugs.webkit.org/show_bug.cgi?id=88141 + + Reviewed by Michael Saboff. + + If you use a loop in the style of: + + for (i = start; i--;) + + then you need to remember that the first value of 'i' that the loop body will see is 'start - 1'. + Hence the following is probably wrong: + + for (i = start - 1; i--;) + + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::run): + +2012-06-01 Filip Pizlo <fpizlo@apple.com> + + DFG constant folding should be OK with GetLocal of captured variables having a constant + https://bugs.webkit.org/show_bug.cgi?id=88137 + + Reviewed by Gavin Barraclough. + + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::run): + +2012-05-31 Mark Hahnenberg <mhahnenberg@apple.com> + + JSGlobalObject does not mark m_privateNameStructure + https://bugs.webkit.org/show_bug.cgi?id=88023 + + Rubber stamped by Gavin Barraclough. + + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::visitChildren): We need to mark this so it doesn't get + inadvertently garbage collected. + +2012-05-31 Erik Arvidsson <arv@chromium.org> + + Make DOM Exceptions Errors + https://bugs.webkit.org/show_bug.cgi?id=85078 + + Reviewed by Oliver Hunt. + + WebIDL mandates that exceptions should have Error.prototype on its prototype chain. + + For JSC we have access to the Error.prototype from the binding code. + + For V8 we set a field in the WrapperTypeInfo and when the constructor function is created we + set the prototype as needed. + + Updated test: fast/dom/DOMException/prototype-object.html + + * JavaScriptCore.xcodeproj/project.pbxproj: + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::reset): + * runtime/JSGlobalObject.h: + (JSC): + (JSGlobalObject): + (JSC::JSGlobalObject::errorPrototype): + +2012-05-31 Andy Wingo <wingo@igalia.com> + + Fix reference to unset variable in debug mode + https://bugs.webkit.org/show_bug.cgi?id=87981 + + Reviewed by Geoffrey Garen. + + * runtime/JSONObject.cpp (Stringifier::Holder::Holder): + Initialize m_size in debug mode, as we check it later in an assert. + +2012-05-30 Mark Hahnenberg <mhahnenberg@apple.com> + + Heap should sweep incrementally + https://bugs.webkit.org/show_bug.cgi?id=85429 + + We shouldn't have to wait for the opportunistic GC timer to fire in order + to call object destructors. Instead, we should incrementally sweep some + subset of the blocks requiring sweeping periodically. We tie this sweeping + to a timer rather than to collections because we want to reclaim this memory + even if we stop allocating. This way, our memory usage scales smoothly with + actual use, regardless of whether we've recently done an opportunistic GC or not. + + Reviewed by Geoffrey Garen. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.gypi: + * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * heap/Heap.cpp: + (JSC::Heap::Heap): + (JSC::Heap::collect): We no longer sweep during a full sweep. We only shrink now, + which we will switch over to being done during incremental sweeping too as soon as + all finalizers can be run lazily (and, by extension, incrementally). + (JSC::Heap::sweeper): + (JSC): + * heap/Heap.h: + (JSC): + (Heap): + * heap/IncrementalSweeper.cpp: Added. + (JSC): + (JSC::IncrementalSweeper::timerDidFire): The IncrementalSweeper works very similarly to + GCActivityCallback. It is tied to a run-loop based timer that fires periodically based + on how long the previous sweep increment took to run. The IncrementalSweeper doesn't do + anything if the platform doesn't support CoreFoundation. + (JSC::IncrementalSweeper::IncrementalSweeper): + (JSC::IncrementalSweeper::~IncrementalSweeper): + (JSC::IncrementalSweeper::create): + (JSC::IncrementalSweeper::scheduleTimer): + (JSC::IncrementalSweeper::cancelTimer): + (JSC::IncrementalSweeper::doSweep): Iterates over the snapshot of the MarkedSpace taken + during the last collection, checking to see which blocks need sweeping. If it successfully + gets to the end of the blocks that need sweeping then it cancels the timer. + (JSC::IncrementalSweeper::startSweeping): We take a snapshot of the Heap and store it in + a Vector that the incremental sweep will iterate over. We also reset our index into this Vector. + * heap/IncrementalSweeper.h: Added. + (JSC): + (IncrementalSweeper): + * heap/MarkedBlock.h: + (JSC::MarkedBlock::needsSweeping): If a block is in the Marked state it needs sweeping + to be usable and to run any destructors that need to be run. + +2012-05-30 Patrick Gansterer <paroga@webkit.org> + + [WINCE] Fix JSString after r115516. + https://bugs.webkit.org/show_bug.cgi?id=87892 + + Reviewed by Geoffrey Garen. + + r115516 splitted JSString into two classes, with addition nested classes. + Add a workaround for the WinCE compiler since it can't resolve the friend class + declerations corretly and denies the access to protected members of JSString. + + * runtime/JSString.h: + (JSC::JSRopeString::RopeBuilder::append): + (JSC::JSRopeString::append): + (JSRopeString): + +2012-05-30 Oliver Hunt <oliver@apple.com> + + Really provide error information with the inspector disabled + https://bugs.webkit.org/show_bug.cgi?id=87910 + + Reviewed by Filip Pizlo. + + Don't bother checking for anything other than pre-existing error info. + In the absence of complete line number information you'll only get the + line a function starts on, but at least it's something. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::throwException): + +2012-05-30 Filip Pizlo <fpizlo@apple.com> + + LLInt broken on x86-32 with JIT turned off + https://bugs.webkit.org/show_bug.cgi?id=87906 + + Reviewed by Geoffrey Garen. + + Fixed the code to not clobber registers that contain important things, like the call frame. + + * llint/LowLevelInterpreter32_64.asm: + +2012-05-30 Filip Pizlo <fpizlo@apple.com> + + ScriptDebugServer wants sourceIDs that are non-zero because that's what HashMaps want, so JSC should placate it + https://bugs.webkit.org/show_bug.cgi?id=87887 + + Reviewed by Darin Adler. + + Better fix - we now never call SourceProvider::asID() if SourceProvider* is 0. + + * parser/Nodes.h: + (JSC::ScopeNode::sourceID): + * parser/SourceCode.h: + (JSC::SourceCode::providerID): + (SourceCode): + * parser/SourceProvider.h: + (SourceProvider): + (JSC::SourceProvider::asID): + * runtime/Executable.h: + (JSC::ScriptExecutable::sourceID): + +2012-05-30 Filip Pizlo <fpizlo@apple.com> + + ScriptDebugServer wants sourceIDs that are non-zero because that's what HashMaps want, so JSC should placate it + https://bugs.webkit.org/show_bug.cgi?id=87887 + + Reviewed by Geoffrey Garen. + + * parser/SourceProvider.h: + (JSC::SourceProvider::asID): + +2012-05-30 Oliver Hunt <oliver@apple.com> + + DFG does not correctly handle exceptions caught in the LLInt + https://bugs.webkit.org/show_bug.cgi?id=87885 + + Reviewed by Filip Pizlo. + + Make the DFG use genericThrow, rather than reimplementing a small portion of it. + Also make the LLInt slow paths validate that their PC is correct. + + * dfg/DFGOperations.cpp: + * llint/LLIntSlowPaths.cpp: + (LLInt): + +2012-05-29 Filip Pizlo <fpizlo@apple.com> + + DFG CFA should infer types and values of captured variables + https://bugs.webkit.org/show_bug.cgi?id=87813 + + Reviewed by Gavin Barraclough. + + Slight speed-up in V8/earley-boyer (~1%). + + * bytecode/CodeBlock.h: + (JSC::CodeBlock::argumentsAreCaptured): + (JSC::CodeBlock::argumentIsCaptured): + (CodeBlock): + * dfg/DFGAbstractState.cpp: + (DFG): + (JSC::DFG::AbstractState::beginBasicBlock): + (JSC::DFG::AbstractState::initialize): + (JSC::DFG::AbstractState::endBasicBlock): + (JSC::DFG::AbstractState::execute): + (JSC::DFG::AbstractState::clobberWorld): + (JSC::DFG::AbstractState::clobberStructures): + (JSC::DFG::AbstractState::mergeStateAtTail): + (JSC::DFG::AbstractState::merge): + (JSC::DFG::AbstractState::mergeToSuccessors): + * dfg/DFGAbstractState.h: + (JSC::DFG::AbstractState::variables): + (AbstractState): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-05-30 Patrick Gansterer <paroga@webkit.org> + + Unreviewed. Build fix for !ENABLE(JIT) after r117823. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + +2012-05-30 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r118868. + http://trac.webkit.org/changeset/118868 + https://bugs.webkit.org/show_bug.cgi?id=87828 + + introduced ~20 crashes on Mac and Qt bots (Requested by pizlo_ + on #webkit). + + * heap/Heap.cpp: + (JSC::Heap::collect): + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::sweep): + * heap/MarkedBlock.h: + (JSC::MarkedBlock::sweepWeakSet): + (JSC): + * heap/MarkedSpace.cpp: + (JSC::SweepWeakSet::operator()): + (JSC): + (JSC::MarkedSpace::sweepWeakSets): + * heap/MarkedSpace.h: + (MarkedSpace): + +2012-05-29 Geoffrey Garen <ggaren@apple.com> + + Rolled back in r118646, now that + https://bugs.webkit.org/show_bug.cgi?id=87784 is fixed. + + http://trac.webkit.org/changeset/118646 + https://bugs.webkit.org/show_bug.cgi?id=87599 + + * heap/Heap.cpp: + (JSC::Heap::collect): + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::sweep): + * heap/MarkedBlock.h: + (JSC): + * heap/MarkedSpace.cpp: + (JSC): + * heap/MarkedSpace.h: + (MarkedSpace): + +2012-05-29 Filip Pizlo <fpizlo@apple.com> + + DFG should keep captured variables alive until the (inline) return. + https://bugs.webkit.org/show_bug.cgi?id=87205 + + Reviewed by Gavin Barraclough. + + Changes the way we do flushing for captured variables and arguments. Instead of flushing + each SetLocal immediately, we flush at kill points. So a SetLocal will cause a Flush of + whatever was live in the variable previously, and a return will cause a Flush of all + captured variables and all arguments. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::setDirect): + (JSC::DFG::ByteCodeParser::set): + (JSC::DFG::ByteCodeParser::setLocal): + (JSC::DFG::ByteCodeParser::getArgument): + (JSC::DFG::ByteCodeParser::setArgument): + (JSC::DFG::ByteCodeParser::findArgumentPositionForArgument): + (ByteCodeParser): + (JSC::DFG::ByteCodeParser::findArgumentPositionForLocal): + (JSC::DFG::ByteCodeParser::findArgumentPosition): + (JSC::DFG::ByteCodeParser::flush): + (JSC::DFG::ByteCodeParser::flushDirect): + (JSC::DFG::ByteCodeParser::flushArgumentsAndCapturedVariables): + (JSC::DFG::ByteCodeParser::handleInlining): + (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::setLocalStoreElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): + +2012-05-29 Geoffrey Garen <ggaren@apple.com> + + WeakGCMap should be lazy-finalization-safe + https://bugs.webkit.org/show_bug.cgi?id=87784 + + Reviewed by Darin Adler. + + * runtime/WeakGCMap.h: + (JSC::WeakGCMap::get): Since this is a map of raw WeakImpl pointers, and + not Weak<T>, we need to verify manually that the WeakImpl is live before + we return its payload. + +2012-05-29 Mark Hahnenberg <mhahnenberg@apple.com> + + CopiedSpace::doneCopying could start another collection + https://bugs.webkit.org/show_bug.cgi?id=86538 + + Reviewed by Geoffrey Garen. + + It's possible that if we don't have anything at the head of to-space + after a collection and the BlockAllocator doesn't have any fresh blocks + to give us right now we could start another collection while still in + the middle of the first collection when we call CopiedSpace::addNewBlock(). + + One way to resolve this would be to have Heap::shouldCollect() check that + m_operationInProgress is NoOperation. This would prevent the path in + getFreshBlock() that starts the collection if we're already in the middle of one. + + I could not come up with a test case to reproduce this crash on ToT. + + * heap/Heap.h: + (JSC::Heap::shouldCollect): We shouldn't collect if we're already in the middle + of a collection, i.e. the current operation should be NoOperation. + +2012-05-29 David Barr <davidbarr@chromium.org> + + Introduce ENABLE_CSS_IMAGE_RESOLUTION compile flag + https://bugs.webkit.org/show_bug.cgi?id=87685 + + Reviewed by Eric Seidel. + + Add a configuration option for CSS image-resolution support, disabling it by default. + + * Configurations/FeatureDefines.xcconfig: + +2012-05-28 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r118646. + http://trac.webkit.org/changeset/118646 + https://bugs.webkit.org/show_bug.cgi?id=87691 + + broke V8 raytrace benchmark (Requested by pizlo_ on #webkit). + + * heap/Heap.cpp: + (JSC::Heap::collect): + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::sweep): + * heap/MarkedBlock.h: + (JSC::MarkedBlock::sweepWeakSet): + (JSC): + * heap/MarkedSpace.cpp: + (JSC::SweepWeakSet::operator()): + (JSC): + (JSC::MarkedSpace::sweepWeakSets): + * heap/MarkedSpace.h: + (MarkedSpace): + +2012-05-28 Filip Pizlo <fpizlo@apple.com> + + DFG should not generate code for code that the CFA proves to be unreachable + https://bugs.webkit.org/show_bug.cgi?id=87682 + + Reviewed by Sam Weinig. + + This also fixes a small performance bug where CFA was not marking blocks + as having constants (and hence not triggering constant folding) if the only + constants were on GetLocals. + + And fixing that bug revealed another bug: constant folding was assuming that + a GetLocal must be the first access to a local in a basic block. This isn't + true. The first access may be a Flush. This patch fixes that issue using the + safest approach possible, since we don't need to be clever for something that + only happens in one of our benchmarks. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGConstantFoldingPhase.cpp: + (JSC::DFG::ConstantFoldingPhase::run): + * dfg/DFGJITCompiler.h: + (JSC::DFG::JITCompiler::noticeOSREntry): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-05-28 Carlos Garcia Campos <cgarcia@igalia.com> + + Unreviewed. Fix make distcheck. + + * GNUmakefile.list.am: Add missing header file. + +2012-05-27 Geoffrey Garen <ggaren@apple.com> + + Weak pointer finalization should be lazy + https://bugs.webkit.org/show_bug.cgi?id=87599 + + Reviewed by Darin Adler. + + * heap/Heap.cpp: + (JSC::Heap::collect): Don't force immediate finalization -- it will + happen lazily. + + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::sweep): Sweep a block's weak set when sweeping the + block. The weak set may not have been swept yet, and this is our last + chance to run weak finalizers before we recycle the memory they reference. + + * heap/MarkedBlock.h: + * heap/MarkedSpace.cpp: + (JSC::MarkedBlock::sweepWeakSets): + * heap/MarkedSpace.h: + (JSC::MarkedSpace::sweepWeakSets): Nixed sweepWeakSets because it's unused + now. + +2012-05-26 Geoffrey Garen <ggaren@apple.com> + + WebKit should be lazy-finalization-safe (esp. the DOM) v2 + https://bugs.webkit.org/show_bug.cgi?id=87581 + + Reviewed by Oliver Hunt. + + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::callDestructor): + * heap/WeakBlock.h: + * heap/WeakSetInlines.h: + (JSC::WeakBlock::finalize): Since we don't guarantee destruction order, + it's not valid to access GC pointers like the Structure pointer during + finalization. We NULL out the structure pointer in debug builds to try + to make this programming mistake more obvious. + + * API/JSCallbackConstructor.cpp: + (JSC::JSCallbackConstructor::destroy): + * API/JSCallbackObject.cpp: + (JSC::::destroy): + (JSC::JSCallbackObjectData::finalize): + * runtime/Arguments.cpp: + (JSC::Arguments::destroy): + * runtime/DateInstance.cpp: + (JSC::DateInstance::destroy): + * runtime/Error.cpp: + (JSC::StrictModeTypeErrorFunction::destroy): + * runtime/Executable.cpp: + (JSC::ExecutableBase::destroy): + (JSC::NativeExecutable::destroy): + (JSC::ScriptExecutable::destroy): + (JSC::EvalExecutable::destroy): + (JSC::ProgramExecutable::destroy): + (JSC::FunctionExecutable::destroy): + * runtime/JSGlobalObject.cpp: + (JSC::JSGlobalObject::destroy): + * runtime/JSPropertyNameIterator.cpp: + (JSC::JSPropertyNameIterator::destroy): + * runtime/JSStaticScopeObject.cpp: + (JSC::JSStaticScopeObject::destroy): + * runtime/JSString.cpp: + (JSC::JSString::destroy): + * runtime/JSVariableObject.cpp: + (JSC::JSVariableObject::destroy): + * runtime/NameInstance.cpp: + (JSC::NameInstance::destroy): + * runtime/RegExp.cpp: + (JSC::RegExp::destroy): + * runtime/RegExpConstructor.cpp: + (JSC::RegExpConstructor::destroy): + * runtime/Structure.cpp: + (JSC::Structure::destroy): + * runtime/StructureChain.cpp: + (JSC::StructureChain::destroy): Use static_cast instead of jsCast because + jsCast does Structure-based validation, and our Structure is not guaranteed + to be alive when we get finalized. + +2012-05-22 Filip Pizlo <fpizlo@apple.com> + + DFG CSE should eliminate redundant WeakJSConstants + https://bugs.webkit.org/show_bug.cgi?id=87179 + + Reviewed by Gavin Barraclough. + + Merged r118141 from dfgopt. + + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::weakConstantCSE): + (CSEPhase): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGNode.h: + (JSC::DFG::Node::weakConstant): + +2012-05-22 Filip Pizlo <fpizlo@apple.com> + + DFG CSE should do redundant store elimination + https://bugs.webkit.org/show_bug.cgi?id=87161 + + Reviewed by Oliver Hunt. + + Merge r118138 from dfgopt. + + This patch adds redundant store elimination. For example, consider this + code: + + o.x = 42; + o.x = 84; + + If o.x is speculated to be a well-behaved field, the first assignment is + unnecessary, since the second just overwrites it. We would like to + eliminate the first assignment in these cases. The need for this + optimization arises mostly from stores that our runtime requires. For + example: + + o = {f:1, g:2, h:3}; + + This will have four assignments to the structure for the newly created + object - one assignment for the empty structure, one for {f}, one for + {f, g}, and one for {f, g, h}. We would like to only have the last of + those assigments in this case. + + Intriguingly, doing so for captured variables breaks the way arguments + simplification used to work. Consider that prior to either arguments + simplification or store elimination we will have IR that looks like: + + a: SetLocal(r0, Empty) + b: SetLocal(r1, Empty) + c: GetLocal(r0) + d: CreateArguments(@c) + e: SetLocal(r0, @d) + f: SetLocal(r1, @d) + + Then redundant store elimination will eliminate the stores that + initialize the arguments registers to Empty, but then arguments + simplification eliminates the stores that initialize the arguments to + the newly created arguments - and at this point we no longer have any + stores to the arguments register, leading to hilarious crashes. This + patch therefore changes arguments simplification to replace + CreateArguments with JSConstant(Empty) rather than eliminating the + SetLocals. But this revealed bugs where arguments simplification was + being overzealous, so I fixed those bugs. + + This is a minor speed-up on V8/early and a handful of other tests. + + * bytecode/CodeBlock.h: + (JSC::CodeBlock::uncheckedActivationRegister): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUses): + (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::globalVarStoreElimination): + (CSEPhase): + (JSC::DFG::CSEPhase::putStructureStoreElimination): + (JSC::DFG::CSEPhase::putByOffsetStoreElimination): + (JSC::DFG::CSEPhase::setLocalStoreElimination): + (JSC::DFG::CSEPhase::setReplacement): + (JSC::DFG::CSEPhase::eliminate): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::uncheckedActivationRegisterFor): + (Graph): + * dfg/DFGNode.h: + (JSC::DFG::Node::isPhantomArguments): + (Node): + (JSC::DFG::Node::hasConstant): + (JSC::DFG::Node::valueOfJSConstant): + (JSC::DFG::Node::hasStructureTransitionData): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-05-21 Filip Pizlo <fpizlo@apple.com> + + DFG ConvertThis should just be a CheckStructure if the structure is known + https://bugs.webkit.org/show_bug.cgi?id=87057 + + Reviewed by Gavin Barraclough. + + Merged r118021 from dfgopt. + + This gives ValueProfile the ability to track singleton values - i.e. profiling + sites that always see the same value. + + That is then used to profile the structure in op_convert_this. + + This is then used to optimize op_convert_this into a CheckStructure if the + structure is always the same. + + That then results in better CSE in inlined code that uses 'this', since + previously we couldn't CSE accesses on 'this' from different inline call frames. + + Also fixed a bug where we were unnecessarily flushing 'this'. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::dump): + (JSC::CodeBlock::stronglyVisitStrongReferences): + * bytecode/LazyOperandValueProfile.cpp: + (JSC::CompressedLazyOperandValueProfileHolder::computeUpdatedPredictions): + * bytecode/LazyOperandValueProfile.h: + (CompressedLazyOperandValueProfileHolder): + * bytecode/Opcode.h: + (JSC): + (JSC::padOpcodeName): + * bytecode/ValueProfile.h: + (JSC::ValueProfileBase::ValueProfileBase): + (JSC::ValueProfileBase::dump): + (JSC::ValueProfileBase::computeUpdatedPrediction): + (ValueProfileBase): + * bytecompiler/BytecodeGenerator.cpp: + (JSC::BytecodeGenerator::BytecodeGenerator): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::setArgument): + (JSC::DFG::ByteCodeParser::parseBlock): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_convert_this): + (JSC::JIT::emitSlow_op_convert_this): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_convert_this): + (JSC::JIT::emitSlow_op_convert_this): + * llint/LLIntSlowPaths.cpp: + (JSC::LLInt::LLINT_SLOW_PATH_DECL): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + * runtime/JSValue.h: + (JSValue): + * runtime/Structure.h: + (JSC::JSValue::structureOrUndefined): + (JSC): + +2012-05-24 Tim Horton <timothy_horton@apple.com> + + Add feature defines for web-facing parts of CSS Regions and Exclusions + https://bugs.webkit.org/show_bug.cgi?id=87442 + <rdar://problem/10887709> + + Reviewed by Dan Bernstein. + + * Configurations/FeatureDefines.xcconfig: + +2012-05-24 Geoffrey Garen <ggaren@apple.com> + + WebKit should be lazy-finalization-safe (esp. the DOM) + https://bugs.webkit.org/show_bug.cgi?id=87456 + + Reviewed by Filip Pizlo. + + Lazy finalization adds one twist to weak pointer use: + + A HashMap of weak pointers may contain logically null entries. + (Weak pointers behave as-if null once their payloads die.) + Insertion must not assume that a pre-existing entry is + necessarily valid, and iteration must not assume that all + entries can be dereferenced. + + (Previously, I thought that it also added a second twist: + + A demand-allocated weak pointer may replace a dead payload + before the payload's finalizer runs. In that case, when the + payload's finalizer runs, the payload has already been + overwritten, and the finalizer should not clear the payload, + which now points to something new. + + But that's not the case here, since we cancel the old payload's + finalizer when we over-write it. I've added ASSERTs to verify this + assumption, in case it ever changes.) + + * API/JSClassRef.cpp: + (OpaqueJSClass::prototype): No need to specify null; that's the default. + + * API/JSWeakObjectMapRefPrivate.cpp: Use remove, since take() is gone. + + * heap/PassWeak.h: + (WeakImplAccessor::was): This is no longer a debug-only function, since + it's required to reason about lazily finalized pointers. + + * heap/Weak.h: + (JSC::weakAdd): + (JSC::weakRemove): + (JSC::weakClear): Added these helper functions for the common idioms of + what clients want to do in their weak pointer finalizers. + + * jit/JITStubs.cpp: + (JSC::JITThunks::hostFunctionStub): Use the new idioms. Otherwise, we + would return NULL for a "zombie" executable weak pointer that was waiting + for finalization (item (2)), and finalizing a dead executable weak pointer + would potentially destroy a new, live one (item (1)). + + * runtime/RegExpCache.cpp: + (JSC::RegExpCache::lookupOrCreate): + (JSC::RegExpCache::finalize): Ditto. + + (JSC::RegExpCache::invalidateCode): Check for null while iterating. (See + item (2).) + + * runtime/Structure.cpp: + (JSC::StructureTransitionTable::contains): + (JSC::StructureTransitionTable::add): Use get and set instead of add and + contains, since add and contains are not compatible with lazy finalization. + + * runtime/WeakGCMap.h: + (WeakGCMap): + (JSC::WeakGCMap::clear): + (JSC::WeakGCMap::remove): Removed a bunch of code that was incompatible with + lazy finalization because I didn't feel like making it compatible, and I had + no way to test it. + +2012-05-24 Filip Pizlo <fpizlo@apple.com> + + REGRESSION (r118013-r118031): Loops/Reloads under www.yahoo.com, quits after three tries with error + https://bugs.webkit.org/show_bug.cgi?id=87327 + + Reviewed by Geoffrey Garen. + + If you use AbstractValue::filter(StructureSet) to test subset relationships between TOP and a + set containing >=2 elements, you're going to have a bad time. + + That's because AbstractValue considers a set with >=2 elements to be equivalent to TOP, in order + to save space and speed up convergence. So filtering has no effect in this case, which made + the code think that the abstract value was proving that the structure check was unnecessary. + The correct thing to do is to use isSubsetOf() on the StructureAbstractValue, which does the + right thingies for TOP and >=2 elements. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-05-24 Filip Pizlo <fpizlo@apple.com> + + new test fast/js/dfg-arguments-mixed-alias.html fails on JSVALUE32_64 + https://bugs.webkit.org/show_bug.cgi?id=87378 + + Reviewed by Gavin Barraclough. + + - Captured variable tracking forgot did not consistently handle arguments, leading to OSR + badness. + + - Nodes capable of exiting were tracked in a non-monotonic way, leading to compiler errors. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::CSEPhase): + (CSEPhase): + (JSC::DFG::performCSE): + * dfg/DFGCSEPhase.h: + (DFG): + * dfg/DFGCommon.h: + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::resetExitStates): + (DFG): + * dfg/DFGGraph.h: + (Graph): + * dfg/DFGPhase.h: + (DFG): + (JSC::DFG::runPhase): + +2012-05-24 Geoffrey Garen <ggaren@apple.com> + + Made WeakSet per-block instead of per-heap + https://bugs.webkit.org/show_bug.cgi?id=87401 + + Reviewed by Oliver Hunt. + + This allows us fast access to the set of all weak pointers for a block, + which is a step toward lazy finalization. + + No performance change. + + * heap/Heap.cpp: + (JSC::Heap::Heap): + (JSC::Heap::lastChanceToFinalize): Removed the per-heap weak set, since + it's per-block now. + + (JSC::Heap::markRoots): Delegate weak set visiting to the marked space, + since it knows how to iterate all blocks. + + (JSC::Heap::collect): Moved the reaping outside of markRoots, since it + doesn't mark anything. + + Make sure to reset allocators after shrinking, since shrinking may + deallocate the current allocator. + + * heap/Heap.h: + (Heap): No more per-heap weak set, since it's per-block now. + + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::MarkedBlock): + * heap/MarkedBlock.h: + (MarkedBlock): + (JSC::MarkedBlock::lastChanceToFinalize): Migrated finalization logic + here from the heap, so the heap doesn't need to know about our internal + data structures like our weak set. + + (JSC::MarkedBlock::heap): + (JSC::MarkedBlock::weakSet): + (JSC::MarkedBlock::shrink): + (JSC::MarkedBlock::resetAllocator): + (JSC::MarkedBlock::visitWeakSet): + (JSC::MarkedBlock::reapWeakSet): + (JSC::MarkedBlock::sweepWeakSet): + * heap/MarkedSpace.cpp: + (JSC::VisitWeakSet::VisitWeakSet): + (JSC::VisitWeakSet::operator()): + (VisitWeakSet): + (JSC): + (JSC::ReapWeakSet::operator()): + (JSC::SweepWeakSet::operator()): + (JSC::LastChanceToFinalize::operator()): + (JSC::MarkedSpace::lastChanceToFinalize): + (JSC::ResetAllocator::operator()): + (JSC::MarkedSpace::resetAllocators): + (JSC::MarkedSpace::visitWeakSets): + (JSC::MarkedSpace::reapWeakSets): + (JSC::MarkedSpace::sweepWeakSets): + (JSC::Shrink::operator()): + (JSC::MarkedSpace::shrink): + * heap/MarkedSpace.h: + (MarkedSpace): Make sure to account for our weak sets when sweeping, + shrinking, etc. + + * heap/WeakSet.cpp: + (JSC): + * heap/WeakSet.h: + (WeakSet): + (JSC::WeakSet::heap): + (JSC): + (JSC::WeakSet::lastChanceToFinalize): + (JSC::WeakSet::visit): + (JSC::WeakSet::reap): + (JSC::WeakSet::shrink): + (JSC::WeakSet::resetAllocator): Inlined some things since they're called + once per block now instead of once per heap. + + * heap/WeakSetInlines.h: + (JSC::WeakSet::allocate): Use the per-block weak set since there is no + per-heap weak set anymore. + +2012-05-24 Gavin Barraclough <barraclough@apple.com> + + Fix arm build + + Rubber stamped by Geoff Garen + + * dfg/DFGGPRInfo.h: + (GPRInfo): + +2012-05-24 Gavin Barraclough <barraclough@apple.com> + + Move cacheFlush from ExecutableAllocator to Assembler classes + https://bugs.webkit.org/show_bug.cgi?id=87420 + + Reviewed by Oliver Hunt. + + Makes more sense there, & remove a pile of #ifdefs. + + * assembler/ARMAssembler.cpp: + (JSC): + (JSC::ARMAssembler::cacheFlush): + * assembler/ARMAssembler.h: + (ARMAssembler): + (JSC::ARMAssembler::cacheFlush): + * assembler/ARMv7Assembler.h: + (JSC::ARMv7Assembler::relinkJump): + (JSC::ARMv7Assembler::cacheFlush): + (ARMv7Assembler): + (JSC::ARMv7Assembler::setInt32): + (JSC::ARMv7Assembler::setUInt7ForLoad): + * assembler/AbstractMacroAssembler.h: + (JSC::AbstractMacroAssembler::cacheFlush): + * assembler/LinkBuffer.h: + (JSC::LinkBuffer::performFinalization): + * assembler/MIPSAssembler.h: + (JSC::MIPSAssembler::relinkJump): + (JSC::MIPSAssembler::relinkCall): + (JSC::MIPSAssembler::repatchInt32): + (JSC::MIPSAssembler::cacheFlush): + (MIPSAssembler): + * assembler/SH4Assembler.h: + (JSC::SH4Assembler::repatchCompact): + (JSC::SH4Assembler::cacheFlush): + (SH4Assembler): + * assembler/X86Assembler.h: + (X86Assembler): + (JSC::X86Assembler::cacheFlush): + * jit/ExecutableAllocator.cpp: + (JSC): + * jit/ExecutableAllocator.h: + (ExecutableAllocator): + +2012-05-24 John Mellor <johnme@chromium.org> + + Font Boosting: Add compile flag and runtime setting + https://bugs.webkit.org/show_bug.cgi?id=87394 + + Reviewed by Adam Barth. + + Add ENABLE_FONT_BOOSTING. + + * Configurations/FeatureDefines.xcconfig: + +2012-05-24 Allan Sandfeld Jensen <allan.jensen@nokia.com> + + cti_vm_throw gets kicked out by gcc 4.6 -flto + https://bugs.webkit.org/show_bug.cgi?id=56088 + + Reviewed by Darin Adler. + + Add REFERENCED_FROM_ASM to functions only referenced from assembler. + + * dfg/DFGOperations.cpp: + * jit/HostCallReturnValue.h: + * jit/JITStubs.h: + * jit/ThunkGenerators.cpp: + +2012-05-24 Filip Pizlo <fpizlo@apple.com> + + Incorrect merge of r117542 from dfg opt branch in r118323 is leading to fast/js/dfg-arguments-osr-exit.html failing + https://bugs.webkit.org/show_bug.cgi?id=87350 + + Reviewed by Maciej Stachowiak. + + The dfgopt branch introduced the notion of a local variable being killed because it was aliased + to the Arguments object as in cases like: + + var a = arguments; + return a.length; + + This required changes to OSR exit handling - if the variable is dead but aliased to arguments, then + OSR exit should reify the arguments. But meanwhile, in tip of tree we introduced special handling for + dead variables on OSR exit. When the two were merged in r118323, the structure of the if/else branches + ended up being such that we would treat dead arguments variables as totally dead as opposed to treating + them as variables that need arguments reification. + + This fixes the structure of the relevant if/else block so that variables that are dead-but-arguments + end up being treated as reified arguments objects, while variables that are dead but not aliased to + arguments are treated as tip of tree would have treated them (initialize to Undefined). + + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-05-24 Csaba Osztrogonác <ossy@webkit.org> + + Unreviewed 32 bit buildfix after r118325. + + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): Use ASSERT_UNUSED instead ASSERT. + +2012-05-23 Filip Pizlo <fpizlo@apple.com> + + DFG operationTearOffActivation should return after handling the null activation case + https://bugs.webkit.org/show_bug.cgi?id=87348 + <rdar://problem/11522295> + + Reviewed by Oliver Hunt. + + * dfg/DFGOperations.cpp: + +2012-05-23 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, merge the arguments fix in r118138 to get bots green. + + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): + +2012-05-20 Filip Pizlo <fpizlo@apple.com> + + DFG CFA should record if a node can OSR exit + https://bugs.webkit.org/show_bug.cgi?id=86905 + + Reviewed by Oliver Hunt. + + Merged r117931 from dfgopt. + + Adds a NodeFlag that denotes nodes that are known to not have OSR exits. + This ought to aid any backwards analyses that need to know when a + backward flow merge might happen due to a side exit. + + Also added assertions into speculationCheck() that ensure that we did not + mark a node as non-exiting and then promptly compile in an exit. This + helped catch some minor bugs where we were doing unnecessary speculation + checks. + + This is a perf-neutral change. The speculation checks that this removes + were not on hot paths of major benchmarks. + + * bytecode/PredictedType.h: + (JSC): + (JSC::isAnyPrediction): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGAbstractState.h: + (JSC::DFG::AbstractState::speculateInt32Unary): + (AbstractState): + (JSC::DFG::AbstractState::speculateNumberUnary): + (JSC::DFG::AbstractState::speculateBooleanUnary): + (JSC::DFG::AbstractState::speculateInt32Binary): + (JSC::DFG::AbstractState::speculateNumberBinary): + * dfg/DFGNode.h: + (JSC::DFG::Node::mergeFlags): + (JSC::DFG::Node::filterFlags): + (Node): + (JSC::DFG::Node::setCanExit): + (JSC::DFG::Node::canExit): + * dfg/DFGNodeFlags.cpp: + (JSC::DFG::nodeFlagsAsString): + * dfg/DFGNodeFlags.h: + (DFG): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::checkArgumentTypes): + (JSC::DFG::SpeculativeJIT::compileValueToInt32): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::speculationCheck): + (JSC::DFG::SpeculativeJIT::forwardSpeculationCheck): + (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution): + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): + (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): + (JSC::DFG::SpeculativeJIT::fillSpeculateCell): + (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): + (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): + (JSC::DFG::SpeculativeJIT::fillSpeculateCell): + (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean): + (JSC::DFG::SpeculativeJIT::compile): + +2012-05-20 Filip Pizlo <fpizlo@apple.com> + + DFG should not do unnecessary indirections when storing to objects + https://bugs.webkit.org/show_bug.cgi?id=86959 + + Reviewed by Oliver Hunt. + + Merged r117819 from dfgopt. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getByOffsetLoadElimination): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-05-17 Filip Pizlo <fpizlo@apple.com> + + DFG should optimize aliased uses of the Arguments object of the current call frame + https://bugs.webkit.org/show_bug.cgi?id=86552 + + Reviewed by Geoff Garen. + + Merged r117542 and r117543 from dfgopt. + + Performs must-alias and escape analysis on uses of CreateArguments, and if + a variable is must-aliased to CreateArguments and does not escape, then we + turn all uses of that variable into direct arguments accesses. + + 36% speed-up on V8/earley leading to a 2.3% speed-up overall in V8. + + * bytecode/CodeBlock.h: + (JSC::CodeBlock::uncheckedArgumentsRegister): + * bytecode/ValueRecovery.h: + (JSC::ValueRecovery::argumentsThatWereNotCreated): + (ValueRecovery): + (JSC::ValueRecovery::dump): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGAdjacencyList.h: + (AdjacencyList): + (JSC::DFG::AdjacencyList::removeEdgeFromBag): + * dfg/DFGArgumentsSimplificationPhase.cpp: + (JSC::DFG::ArgumentsSimplificationPhase::run): + (ArgumentsSimplificationPhase): + (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::observeBadArgumentsUses): + (JSC::DFG::ArgumentsSimplificationPhase::observeProperArgumentsUse): + (JSC::DFG::ArgumentsSimplificationPhase::isOKToOptimize): + (JSC::DFG::ArgumentsSimplificationPhase::removeArgumentsReferencingPhantomChild): + * dfg/DFGAssemblyHelpers.h: + (JSC::DFG::AssemblyHelpers::argumentsRegisterFor): + (AssemblyHelpers): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::removePotentiallyDeadPhiReference): + * dfg/DFGGPRInfo.h: + (GPRInfo): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::collectGarbage): + (DFG): + * dfg/DFGGraph.h: + (Graph): + (JSC::DFG::Graph::executableFor): + (JSC::DFG::Graph::argumentsRegisterFor): + (JSC::DFG::Graph::uncheckedArgumentsRegisterFor): + (JSC::DFG::Graph::clobbersWorld): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasHeapPrediction): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOSRExitCompiler.cpp: + * dfg/DFGOSRExitCompiler.h: + (JSC::DFG::OSRExitCompiler::OSRExitCompiler): + (OSRExitCompiler): + * dfg/DFGOSRExitCompiler32_64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGOSRExitCompiler64.cpp: + (JSC::DFG::OSRExitCompiler::compileExit): + * dfg/DFGOperations.cpp: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::ValueSource::dump): + (JSC::DFG::SpeculativeJIT::compile): + (JSC::DFG::SpeculativeJIT::computeValueRecoveryFor): + * dfg/DFGSpeculativeJIT.h: + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGVariableAccessData.h: + (JSC::DFG::VariableAccessData::VariableAccessData): + (JSC::DFG::VariableAccessData::mergeIsArgumentsAlias): + (VariableAccessData): + (JSC::DFG::VariableAccessData::isArgumentsAlias): + * jit/JITOpcodes.cpp: + (JSC::JIT::emitSlow_op_get_argument_by_val): + +2012-05-23 Filip Pizlo <fpizlo@apple.com> + + DFGCapabilities should not try to get an arguments register from code blocks that don't have one + https://bugs.webkit.org/show_bug.cgi?id=87332 + + Reviewed by Andy Estes. + + * dfg/DFGCapabilities.h: + (JSC::DFG::canInlineOpcode): + +2012-05-23 Filip Pizlo <fpizlo@apple.com> + + DFG should have sparse conditional constant propagation + https://bugs.webkit.org/show_bug.cgi?id=86580 + + Reviewed by Oliver Hunt. + + Merged r117370 from dfgopt. + + This enhances CFA so that if it suspects at any point during the fixpoint that a + branch will only go one way, then it only propagates in that one way. + + This vastly increases the opportunities for CFG simplification. For example, it + enables us to evaporate this loop: + + for (var i = 0; i < 1; ++i) doThings(i); + + As a result, it uncovered loads of bugs in the CFG simplifier. In particular: + + - Phi fixup was assuming that all Phis worth fixing up are shouldGenerate(). + That's not true; we also fixup Phis that are dead. + + - GetLocal fixup was assuming that it's only necessary to rewire links to a + GetLocal, and that the GetLocal's own links don't need to be rewired. Untrue, + because the GetLocal may not be rewirable (first block has no GetLocal for r42 + but second block does have a GetLocal), in which case it will refer to a Phi + in the second block. We need it to refer to a Phi from the first block to + ensure that subsequent transformations work. + + - Tail operand fixup was ignoring the fact that Phis in successors may contain + references to the children of our tail variables. Hence, successor Phi child + substitution needs to use the original second block variable table as its + prior, rather than trying to reconstruct the prior later (since by that point + the children of the second block's tail variables will have been fixed up, so + we will not know what the prior would have been). + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::beginBasicBlock): + (JSC::DFG::AbstractState::endBasicBlock): + (JSC::DFG::AbstractState::reset): + (JSC::DFG::AbstractState::execute): + (JSC::DFG::AbstractState::mergeToSuccessors): + * dfg/DFGAbstractState.h: + (JSC::DFG::AbstractState::branchDirectionToString): + (AbstractState): + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::run): + (JSC::DFG::CFGSimplificationPhase::removePotentiallyDeadPhiReference): + (JSC::DFG::CFGSimplificationPhase::OperandSubstitution::OperandSubstitution): + (OperandSubstitution): + (JSC::DFG::CFGSimplificationPhase::skipGetLocal): + (JSC::DFG::CFGSimplificationPhase::recordPossibleIncomingReference): + (CFGSimplificationPhase): + (JSC::DFG::CFGSimplificationPhase::fixTailOperand): + (JSC::DFG::CFGSimplificationPhase::mergeBlocks): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::changeEdge): + +2012-05-23 Ojan Vafai <ojan@chromium.org> + + add back the ability to disable flexbox + https://bugs.webkit.org/show_bug.cgi?id=87147 + + Reviewed by Tony Chang. + + * Configurations/FeatureDefines.xcconfig: + +2012-05-23 Filip Pizlo <fpizlo@apple.com> + + Unreviewed, fix Windows build. + + * bytecode/CodeBlock.h: + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + (JSC::DFG::canCompileOpcodes): + * dfg/DFGCommon.h: + (DFG): + +2012-05-23 Filip Pizlo <fpizlo@apple.com> + + DFG should optimize inlined uses of arguments.length and arguments[i] + https://bugs.webkit.org/show_bug.cgi?id=86327 + + Reviewed by Gavin Barraclough. + + Merged r117017 from dfgopt. + + Turns inlined uses of arguments.length into a constant. + + Turns inlined uses of arguments[constant] into a direct reference to the + argument. + + Big win on micro-benchmarks. Not yet a win on V8 because the hot uses of + arguments.length and arguments[i] are aliased. I'll leave the aliasing + optimizations to a later patch. + + * CMakeLists.txt: + * GNUmakefile.list.am: + * JavaScriptCore.xcodeproj/project.pbxproj: + * Target.pri: + * bytecode/DFGExitProfile.h: + (FrequentExitSite): + (JSC::DFG::FrequentExitSite::FrequentExitSite): + (JSC::DFG::QueryableExitProfile::hasExitSite): + (QueryableExitProfile): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGArgumentsSimplificationPhase.cpp: Added. + (DFG): + (ArgumentsSimplificationPhase): + (JSC::DFG::ArgumentsSimplificationPhase::ArgumentsSimplificationPhase): + (JSC::DFG::ArgumentsSimplificationPhase::run): + (JSC::DFG::performArgumentsSimplification): + * dfg/DFGArgumentsSimplificationPhase.h: Added. + (DFG): + * dfg/DFGAssemblyHelpers.cpp: + (JSC::DFG::AssemblyHelpers::executableFor): + (DFG): + * dfg/DFGAssemblyHelpers.h: + (AssemblyHelpers): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getLocalLoadElimination): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::Graph): + (JSC::DFG::Graph::executableFor): + (Graph): + (JSC::DFG::Graph::clobbersWorld): + * dfg/DFGNode.h: + (JSC::DFG::Node::convertToConstant): + (JSC::DFG::Node::convertToGetLocalUnlinked): + (Node): + (JSC::DFG::Node::unlinkedLocal): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOSRExit.cpp: + (JSC::DFG::OSRExit::considerAddingAsFrequentExitSiteSlow): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-05-13 Filip Pizlo <fpizlo@apple.com> + + DFG should be able to optimize foo.apply(bar, arguments) + https://bugs.webkit.org/show_bug.cgi?id=86306 + + Reviewed by Gavin Barraclough. + + Merge r116912 from dfgopt. + + Enables compilation of op_jneq_ptr and some forms of op_call_varargs. + + Also includes a bunch of bug fixes that were made necessary by the increased + pressure on the CFG simplifier. + + This is a 1-2% win on V8. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::printCallOp): + (JSC::CodeBlock::CodeBlock): + (JSC::ProgramCodeBlock::canCompileWithDFGInternal): + (JSC::EvalCodeBlock::canCompileWithDFGInternal): + (JSC::FunctionCodeBlock::canCompileWithDFGInternal): + * bytecode/CodeBlock.h: + (CodeBlock): + (JSC::CodeBlock::canCompileWithDFG): + (JSC::CodeBlock::canCompileWithDFGState): + (ProgramCodeBlock): + (EvalCodeBlock): + (FunctionCodeBlock): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::processPhiStack): + (JSC::DFG::ByteCodeParser::parse): + * dfg/DFGCFGSimplificationPhase.cpp: + (JSC::DFG::CFGSimplificationPhase::run): + (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal): + (JSC::DFG::CFGSimplificationPhase::fixTailOperand): + (JSC::DFG::CFGSimplificationPhase::mergeBlocks): + * dfg/DFGCSEPhase.cpp: + (JSC::DFG::CSEPhase::getLocalLoadElimination): + (CSEPhase): + (JSC::DFG::CSEPhase::setReplacement): + (JSC::DFG::CSEPhase::performNodeCSE): + * dfg/DFGCapabilities.cpp: + (JSC::DFG::debugFail): + (DFG): + (JSC::DFG::canHandleOpcodes): + (JSC::DFG::canCompileOpcodes): + (JSC::DFG::canInlineOpcodes): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + (JSC::DFG::canInlineOpcode): + (DFG): + (JSC::DFG::canCompileOpcodes): + (JSC::DFG::canCompileEval): + (JSC::DFG::canCompileProgram): + (JSC::DFG::canCompileFunctionForCall): + (JSC::DFG::canCompileFunctionForConstruct): + * dfg/DFGCommon.h: + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::dump): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::emitCall): + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGValidate.cpp: + (Validate): + (JSC::DFG::Validate::validate): + (JSC::DFG::Validate::checkOperand): + (JSC::DFG::Validate::reportValidationContext): + * jit/JIT.cpp: + (JSC::JIT::emitOptimizationCheck): + (JSC::JIT::privateCompileSlowCases): + (JSC::JIT::privateCompile): + * jit/JIT.h: + * jit/JITArithmetic.cpp: + (JSC::JIT::compileBinaryArithOp): + * jit/JITPropertyAccess.cpp: + (JSC::JIT::privateCompilePutByIdTransition): + * jit/JITPropertyAccess32_64.cpp: + (JSC::JIT::privateCompilePutByIdTransition): + * tools/CodeProfile.cpp: + (JSC::CodeProfile::sample): + +2012-05-23 Geoffrey Garen <ggaren@apple.com> + + Refactored WeakBlock to use malloc, clarify behavior + https://bugs.webkit.org/show_bug.cgi?id=87318 + + Reviewed by Filip Pizlo. + + We want to use malloc so we can make these smaller than 4KB, + since an individual MarkedBlock will usually have fewer than + 4KB worth of weak pointers. + + * heap/Heap.cpp: + (JSC::Heap::markRoots): Renamed visitLiveWeakImpls to visit, since + we no longer need to distinguish from "visitDeadWeakImpls". + + Renamed "visitDeadWeakImpls" to "reap" because we're not actually + doing any visiting -- we're just tagging things as dead. + + * heap/WeakBlock.cpp: + (JSC::WeakBlock::create): + (JSC::WeakBlock::destroy): + (JSC::WeakBlock::WeakBlock): Malloc! + + (JSC::WeakBlock::visit): + (JSC::WeakBlock::reap): Renamed as above. + + * heap/WeakBlock.h: + (WeakBlock): Reduced to 3KB, as explained above. + + * heap/WeakSet.cpp: + (JSC::WeakSet::visit): + (JSC::WeakSet::reap): + * heap/WeakSet.h: + (WeakSet): Updated for renames, and to match WebKit style. + +2012-05-23 Filip Pizlo <fpizlo@apple.com> + + Use after free in JSC::DFG::ByteCodeParser::processPhiStack + https://bugs.webkit.org/show_bug.cgi?id=87312 + <rdar://problem/11518848> + + Reviewed by Oliver Hunt. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::processPhiStack): + (JSC::DFG::ByteCodeParser::parse): + +2012-05-23 Filip Pizlo <fpizlo@apple.com> + + It should be possible to make C function calls from DFG code on ARM in debug mode + https://bugs.webkit.org/show_bug.cgi?id=87313 + + Reviewed by Gavin Barraclough. + + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + +2012-05-11 Filip Pizlo <fpizlo@apple.com> + + DFG should be able to inline functions that use arguments reflectively + https://bugs.webkit.org/show_bug.cgi?id=86132 + + Reviewed by Oliver Hunt. + + Merged r116838 from dfgopt. + + This turns on inlining of functions that use arguments reflectively, but it + does not do any of the obvious optimizations that this exposes. I'll save that + for another patch - the important thing for now is that this contains all of + the plumbing necessary to make this kind of inlining sound even in bizarro + cases like an inline callee escaping the arguments object to parts of the + inline caller where the arguments are otherwise dead. Or even more fun cases + like where you've inlined to an inline stack that is three-deep, and the + function on top of the inline stack reflectively accesses the arguments of a + function that is in the middle of the inline stack. Any subsequent + optimizations that we do for the obvious cases of arguments usage in inline + functions will have to take care not to break the baseline functionality that + this patch plumbs together. + + * bytecode/CodeBlock.cpp: + (JSC::CodeBlock::printCallOp): + (JSC::CodeBlock::dump): + * bytecode/CodeBlock.h: + * dfg/DFGAssemblyHelpers.h: + (JSC::DFG::AssemblyHelpers::argumentsRegisterFor): + (AssemblyHelpers): + * dfg/DFGByteCodeParser.cpp: + (InlineStackEntry): + (JSC::DFG::ByteCodeParser::handleCall): + (JSC::DFG::ByteCodeParser::handleInlining): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + (JSC::DFG::ByteCodeParser::parse): + * dfg/DFGCCallHelpers.h: + (JSC::DFG::CCallHelpers::setupArgumentsWithExecState): + (CCallHelpers): + * dfg/DFGCapabilities.h: + (JSC::DFG::canInlineOpcode): + * dfg/DFGDriver.cpp: + (JSC::DFG::compile): + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * interpreter/CallFrame.cpp: + (JSC): + (JSC::CallFrame::someCodeBlockForPossiblyInlinedCode): + * interpreter/CallFrame.h: + (ExecState): + (JSC::ExecState::someCodeBlockForPossiblyInlinedCode): + * interpreter/Interpreter.cpp: + (JSC::Interpreter::retrieveArgumentsFromVMCode): + * runtime/Arguments.cpp: + (JSC::Arguments::tearOff): + (JSC): + (JSC::Arguments::tearOffForInlineCallFrame): + * runtime/Arguments.h: + (Arguments): + (JSC::Arguments::create): + (JSC::Arguments::finishCreation): + (JSC): + +2012-05-23 Filip Pizlo <fpizlo@apple.com> + + Every OSR exit on ARM results in a crash + https://bugs.webkit.org/show_bug.cgi?id=87307 + + Reviewed by Geoffrey Garen. + + * dfg/DFGThunks.cpp: + (JSC::DFG::osrExitGenerationThunkGenerator): + +2012-05-23 Geoffrey Garen <ggaren@apple.com> + + Refactored heap tear-down to use normal value semantics (i.e., destructors) + https://bugs.webkit.org/show_bug.cgi?id=87302 + + Reviewed by Oliver Hunt. + + This is a step toward incremental DOM finalization. + + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::~CopiedSpace): + * heap/CopiedSpace.h: + (CopiedSpace): Just use our destructor, instead of relying on the heap + to send us a special message at a special time. + + * heap/Heap.cpp: + (JSC::Heap::Heap): Use OwnPtr for m_markListSet because this is not Sparta. + + (JSC::Heap::~Heap): No need for delete or freeAllBlocks because normal + destructors do this work automatically now. + + (JSC::Heap::lastChanceToFinalize): Just call lastChanceToFinalize on our + sub-objects, and assume it does the right thing. This improves encapsulation, + so we can add items requiring finalization to our sub-objects. + + * heap/Heap.h: Moved m_blockAllocator to get the right destruction order. + + * heap/MarkedSpace.cpp: + (Take): + (JSC): + (JSC::Take::Take): + (JSC::Take::operator()): + (JSC::Take::returnValue): Moved to the top of the file so it can be used + in another function. + + (JSC::MarkedSpace::~MarkedSpace): Delete all outstanding memory, like a good + destructor should. + + (JSC::MarkedSpace::lastChanceToFinalize): Moved some code here from the heap, + since it pertains to our internal implementation details. + + * heap/MarkedSpace.h: + (MarkedSpace): + * heap/WeakBlock.cpp: + (JSC::WeakBlock::lastChanceToFinalize): + * heap/WeakBlock.h: + (WeakBlock): + * heap/WeakSet.cpp: + (JSC::WeakSet::lastChanceToFinalize): + * heap/WeakSet.h: + (WeakSet): Stop using a special freeAllBlocks() callback and just implement + lastChanceToFinalize. + +2011-05-22 Geoffrey Garen <ggaren@apple.com> + + Encapsulated some calculations for whether portions of the heap are empty + https://bugs.webkit.org/show_bug.cgi?id=87210 + + Reviewed by Gavin Barraclough. + + This is a step toward incremental DOM finalization. + + * heap/Heap.cpp: + (JSC::Heap::~Heap): Explicitly call freeAllBlocks() instead of relying + implicitly on all blocks thinking they're empty. In future, we may + choose to tear down the heap without first setting all data structures + to "empty". + + * heap/MarkedBlock.h: + (JSC::MarkedBlock::isEmpty): + (JSC::MarkedBlock::gatherDirtyCells): Renamed markCountIsZero to isEmpty, + in preparation for making it check for outstanding finalizers in addition + to marked cells. + + * heap/MarkedSpace.cpp: + (Take): + (JSC::Take::Take): + (JSC::Take::operator()): + (JSC::Take::returnValue): + (JSC::MarkedSpace::shrink): + (JSC::MarkedSpace::freeAllBlocks): Refactored the "Take" functor to support + a conditional isEmpty check, so it dould be shared by shrink() and freeAllBlocks(). + + * heap/WeakBlock.cpp: + (JSC::WeakBlock::WeakBlock): + (JSC::WeakBlock::visitLiveWeakImpls): + (JSC::WeakBlock::visitDeadWeakImpls): + * heap/WeakBlock.h: + (WeakBlock): + (JSC::WeakBlock::isEmpty): + * heap/WeakSet.cpp: + (JSC::WeakSet::sweep): + (JSC::WeakSet::shrink): Use isEmpty(), in preparation for changes in + its implementation. + +2012-05-23 Oswald Buddenhagen <oswald.buddenhagen@nokia.com> + + [Qt] Remove references to $$QT_SOURCE_TREE + + With a modularized Qt, it's ambigious. What we really want is qtbase, + which qtcore is a proxy for (we assume it will always live in qtbase). + + Reviewed by Tor Arne Vestbø. + + * JavaScriptCore.pri: + * Target.pri: + +2012-05-09 Filip Pizlo <fpizlo@apple.com> + + DFG should allow inlining in case of certain arity mismatches + https://bugs.webkit.org/show_bug.cgi?id=86059 + + Reviewed by Geoff Garen. + + Merge r116620 from dfgopt. + + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::handleInlining): + +2012-05-08 Filip Pizlo <fpizlo@apple.com> + + DFG variable capture analysis should work even if the variables arose through inlining + https://bugs.webkit.org/show_bug.cgi?id=85945 + + Reviewed by Oliver Hunt. + + Merged r116555 from dfgopt. + + This just changes how the DFG queries whether a variable is captured. It does not + change any user-visible behavior. + + As part of this change, I further solidified the policy that the CFA behaves in an + undefined way for captured locals and queries about their values will not yield + reliable results. This will likely be changed in the future, but for now it makes + sense. + + One fun part about this change is that it recognizes that the same variable may + be both captured and not, at the same time, because their live interval spans + inlining boundaries. This only happens in the case of arguments to functions that + capture their arguments, and this change treats them with just the right touch of + conservatism: they will be treated as if captured by the caller as well as the + callee. + + Finally, this also adds captured variable reasoning to the InlineCallFrame, which + I thought might be useful for later tooling. + + This is perf-neutral, since it does it does not make the DFG take advantage of this + new functionality in any way. In particular, it is still the case that the DFG will + not inline functions that use arguments reflectively or that create activations. + + * bytecode/CodeBlock.h: + (CodeBlock): + (JSC::CodeBlock::needsActivation): + (JSC::CodeBlock::argumentIsCaptured): + (JSC::CodeBlock::localIsCaptured): + (JSC::CodeBlock::isCaptured): + * bytecode/CodeOrigin.h: + (InlineCallFrame): + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::initialize): + (JSC::DFG::AbstractState::endBasicBlock): + (JSC::DFG::AbstractState::execute): + (JSC::DFG::AbstractState::merge): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::newVariableAccessData): + (JSC::DFG::ByteCodeParser::getLocal): + (JSC::DFG::ByteCodeParser::setLocal): + (JSC::DFG::ByteCodeParser::getArgument): + (JSC::DFG::ByteCodeParser::setArgument): + (JSC::DFG::ByteCodeParser::flushArgument): + (JSC::DFG::ByteCodeParser::parseBlock): + (JSC::DFG::ByteCodeParser::processPhiStack): + (JSC::DFG::ByteCodeParser::fixVariableAccessPredictions): + (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): + * dfg/DFGCFGSimplificationPhase.cpp: + (CFGSimplificationPhase): + (JSC::DFG::CFGSimplificationPhase::keepOperandAlive): + (JSC::DFG::CFGSimplificationPhase::fixPossibleGetLocal): + (JSC::DFG::CFGSimplificationPhase::fixTailOperand): + * dfg/DFGCommon.h: + * dfg/DFGFixupPhase.cpp: + (JSC::DFG::FixupPhase::fixupNode): + * dfg/DFGGraph.cpp: + (JSC::DFG::Graph::nameOfVariableAccessData): + * dfg/DFGGraph.h: + (JSC::DFG::Graph::needsActivation): + (JSC::DFG::Graph::usesArguments): + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::doRoundOfDoubleVoting): + * dfg/DFGSpeculativeJIT.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGVariableAccessData.h: + (JSC::DFG::VariableAccessData::VariableAccessData): + (JSC::DFG::VariableAccessData::mergeIsCaptured): + (VariableAccessData): + (JSC::DFG::VariableAccessData::isCaptured): + +2012-05-08 Filip Pizlo <fpizlo@apple.com> + + DFG should support op_get_argument_by_val and op_get_arguments_length + https://bugs.webkit.org/show_bug.cgi?id=85911 + + Reviewed by Oliver Hunt. + + Merged r116467 from dfgopt. + + This adds a simple and relatively conservative implementation of op_get_argument_by_val + and op_get_arguments_length. We can optimize these later. For now it's great to have + the additional coverage. + + This patch appears to be perf-neutral. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGAssemblyHelpers.h: + (JSC::DFG::AssemblyHelpers::addressFor): + (JSC::DFG::AssemblyHelpers::tagFor): + (JSC::DFG::AssemblyHelpers::payloadFor): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + (JSC::DFG::canInlineOpcode): + * dfg/DFGNode.h: + (JSC::DFG::Node::hasHeapPrediction): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.h: + (JSC::DFG::SpeculativeJIT::callOperation): + (SpeculativeJIT): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * jit/JITOpcodes.cpp: + (JSC::JIT::emit_op_get_argument_by_val): + * jit/JITOpcodes32_64.cpp: + (JSC::JIT::emit_op_get_argument_by_val): + * llint/LowLevelInterpreter32_64.asm: + * llint/LowLevelInterpreter64.asm: + +2012-05-07 Filip Pizlo <fpizlo@apple.com> + + DFG should support op_tear_off_arguments + https://bugs.webkit.org/show_bug.cgi?id=85847 + + Reviewed by Michael Saboff. + + Merged r116378 from dfgopt. + + * dfg/DFGAbstractState.cpp: + (JSC::DFG::AbstractState::execute): + * dfg/DFGByteCodeParser.cpp: + (JSC::DFG::ByteCodeParser::parseBlock): + * dfg/DFGCapabilities.h: + (JSC::DFG::canCompileOpcode): + (JSC::DFG::canInlineOpcode): + * dfg/DFGNodeType.h: + (DFG): + * dfg/DFGOperations.cpp: + * dfg/DFGOperations.h: + * dfg/DFGPredictionPropagationPhase.cpp: + (JSC::DFG::PredictionPropagationPhase::propagate): + * dfg/DFGSpeculativeJIT.h: + (SpeculativeJIT): + (JSC::DFG::SpeculativeJIT::callOperation): + * dfg/DFGSpeculativeJIT32_64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + * dfg/DFGSpeculativeJIT64.cpp: + (JSC::DFG::SpeculativeJIT::compile): + +2012-05-22 Mark Hahnenberg <mhahnenberg@apple.com> + + CopiedSpace::contains doesn't check for oversize blocks + https://bugs.webkit.org/show_bug.cgi?id=87180 + + Reviewed by Geoffrey Garen. + + When doing a conservative scan we use CopiedSpace::contains to determine if a particular + address points into the CopiedSpace. Currently contains() only checks if the address + points to a block in to-space, which means that pointers to oversize blocks may not get scanned. + + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::tryAllocateOversize): + (JSC::CopiedSpace::tryReallocateOversize): + (JSC::CopiedSpace::doneFillingBlock): + (JSC::CopiedSpace::doneCopying): + * heap/CopiedSpace.h: Refactored CopiedSpace so that all blocks (oversize and to-space) are + in a single hash set and bloom filter for membership testing. + (CopiedSpace): + * heap/CopiedSpaceInlineMethods.h: + (JSC::CopiedSpace::contains): We check for the normal block first. Since the oversize blocks are + only page aligned, rather than block aligned, we have to re-mask the ptr to check if it's in + CopiedSpace. Also added a helper function of the same name that takes a CopiedBlock* and checks + if it's in CopiedSpace so that check isn't typed out twice. + (JSC): + (JSC::CopiedSpace::startedCopying): + (JSC::CopiedSpace::addNewBlock): + +2012-05-22 Geoffrey Garen <ggaren@apple.com> + + CopiedBlock and MarkedBlock should have proper value semantics (i.e., destructors) + https://bugs.webkit.org/show_bug.cgi?id=87172 + + Reviewed by Oliver Hunt and Phil Pizlo. + + This enables MarkedBlock to own non-trivial sub-objects that require + destruction. It also fixes a FIXME about casting a CopiedBlock to a + MarkedBlock at destroy time. + + CopiedBlock and MarkedBlock now accept an allocation chunk at create + time and return it at destroy time. Their client is expected to + allocate, recycle, and destroy these chunks. + + * heap/BlockAllocator.cpp: + (JSC::BlockAllocator::releaseFreeBlocks): + (JSC::BlockAllocator::blockFreeingThreadMain): Don't call MarkedBlock::destroy + because we expect that to be called before a block is put on our free + list now. Do manually deallocate our allocation chunk because that's + our job now. + + * heap/BlockAllocator.h: + (BlockAllocator): + (JSC::BlockAllocator::allocate): Allocate never fails now. This is a + cleaner abstraction because only one object does all the VM allocation + and deallocation. Caching is an implementation detail. + + (JSC::BlockAllocator::deallocate): We take an allocation chunk argument + instead of a block because we now expect the block to have been destroyed + before we recycle its memory. For convenience, we still use the HeapBlock + class as our linked list node. This is OK because HeapBlock is a POD type. + + * heap/CopiedBlock.h: + (CopiedBlock): + (JSC::CopiedBlock::create): + (JSC::CopiedBlock::destroy): + (JSC::CopiedBlock::CopiedBlock): Added proper create and destroy functions, + to match MarkedBlock. + + * heap/CopiedSpace.cpp: + (JSC::CopiedSpace::tryAllocateOversize): + (JSC::CopiedSpace::tryReallocateOversize): + (JSC::CopiedSpace::doneCopying): + (JSC::CopiedSpace::getFreshBlock): + (JSC::CopiedSpace::freeAllBlocks): + * heap/CopiedSpaceInlineMethods.h: + (JSC::CopiedSpace::recycleBlock): Make sure to call destroy before + returning a block to the BlockAllocator. Otherwise, our destructors + won't run. (If we get this wrong now, we'll get a compile error.) + + * heap/HeapBlock.h: + (JSC::HeapBlock::HeapBlock): const! + + * heap/MarkedAllocator.cpp: + (JSC::MarkedAllocator::allocateBlock): No need to distinguish between + create and recycle -- MarkedBlock always accepts memory allocated by + its client now. + + * heap/MarkedBlock.cpp: + (JSC::MarkedBlock::create): Don't allocate memory -- we assume that we're + passed already-allocated memory, to clarify the responsibility for VM + recycling. + + (JSC::MarkedBlock::destroy): Do run our destructor before giving back + our VM -- that is the whole point of this patch. + + (JSC::MarkedBlock::MarkedBlock): + * heap/MarkedBlock.h: + (MarkedBlock): + * heap/MarkedSpace.cpp: const! + + (JSC::MarkedSpace::freeBlocks): Make sure to call destroy before + returning a block to the BlockAllocator. Otherwise, our destructors + won't run. (If we get this wrong now, we'll get a compile error.) + +== Rolled over to ChangeLog-2012-05-22 == diff --git a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig index 1b4a75243..19d4b4037 100644 --- a/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig +++ b/Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig @@ -44,7 +44,7 @@ ENABLE_CSS_IMAGE_ORIENTATION = ; ENABLE_CSS_IMAGE_RESOLUTION = ; ENABLE_CSS_REGIONS = ENABLE_CSS_REGIONS; ENABLE_CSS_SHADERS = ENABLE_CSS_SHADERS; -ENABLE_CSS_COMPOSITING = ; +ENABLE_CSS_COMPOSITING = ENABLE_CSS_COMPOSITING; ENABLE_CSS_STICKY_POSITION = ENABLE_CSS_STICKY_POSITION; ENABLE_CSS_VARIABLES = ; ENABLE_CSS3_TEXT_DECORATION = ; @@ -57,12 +57,20 @@ ENABLE_DETAILS_ELEMENT = ENABLE_DETAILS_ELEMENT; ENABLE_DEVICE_ORIENTATION = ; ENABLE_DIALOG_ELEMENT = ; ENABLE_DIRECTORY_UPLOAD = ; +ENABLE_DRAGGABLE_REGION = ; +ENABLE_ENCRYPTED_MEDIA = $(ENABLE_ENCRYPTED_MEDIA_$(REAL_PLATFORM_NAME)); +ENABLE_ENCRYPTED_MEDIA_macosx = $(ENABLE_ENCRYPTED_MEDIA_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR)); +ENABLE_ENCRYPTED_MEDIA_macosx_1070 = ; +ENABLE_ENCRYPTED_MEDIA_macosx_1080 = ; +ENABLE_ENCRYPTED_MEDIA_macosx_1090 = ENABLE_ENCRYPTED_MEDIA; ENABLE_FILE_SYSTEM = ; ENABLE_FILTERS = $(ENABLE_FILTERS_$(REAL_PLATFORM_NAME)); ENABLE_FILTERS_macosx = ENABLE_FILTERS; ENABLE_FULLSCREEN_API = ENABLE_FULLSCREEN_API; ENABLE_GAMEPAD = ; ENABLE_GEOLOCATION = ENABLE_GEOLOCATION; +ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING = $(HIDDEN_PAGE_DOM_TIMER_THROTTLING_$(REAL_PLATFORM_NAME)); +ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING_macosx = HIDDEN_PAGE_DOM_TIMER_THROTTLING; ENABLE_HIGH_DPI_CANVAS = ENABLE_HIGH_DPI_CANVAS; ENABLE_ICONDATABASE = $(ENABLE_ICONDATABASE_$(REAL_PLATFORM_NAME)); ENABLE_ICONDATABASE_macosx = ENABLE_ICONDATABASE; @@ -136,9 +144,7 @@ ENABLE_WEBGL = ENABLE_WEBGL; ENABLE_WEB_AUDIO = ENABLE_WEB_AUDIO; ENABLE_WEB_SOCKETS = ENABLE_WEB_SOCKETS; ENABLE_WEB_TIMING = ; -ENABLE_WIDGET_REGION = $(ENABLE_WIDGET_REGION_$(REAL_PLATFORM_NAME)); -ENABLE_WIDGET_REGION_macosx = ENABLE_WIDGET_REGION; ENABLE_WORKERS = ENABLE_WORKERS; ENABLE_XSLT = ENABLE_XSLT; -FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_HIERARCHIES) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_TEXT_DECORATION) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WIDGET_REGION) $(ENABLE_WORKERS) $(ENABLE_XSLT); +FEATURE_DEFINES = $(ENABLE_3D_RENDERING) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_EXCLUSIONS) $(ENABLE_CSS_FILTERS) $(ENABLE_CSS_HIERARCHIES) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SHADERS) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_STICKY_POSITION) $(ENABLE_CSS_VARIABLES) $(ENABLE_CSS3_TEXT_DECORATION) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIALOG_ELEMENT) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DRAGGABLE_REGION) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_FILE_SYSTEM) $(ENABLE_FILTERS) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_HIDDEN_PAGE_DOM_TIMER_THROTTLING) $(ENABLE_HIGH_DPI_CANVAS) $(ENABLE_ICONDATABASE) $(ENABLE_IFRAME_SEAMLESS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LEGACY_WEB_AUDIO) $(ENABLE_LINK_PREFETCH) $(ENABLE_LINK_PRERENDER) $(ENABLE_MATHML) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MICRODATA) $(ENABLE_MUTATION_OBSERVERS) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NOTIFICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_ELEMENT) $(ENABLE_QUOTA) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_SCRIPTED_SPEECH) $(ENABLE_SHADOW_DOM) $(ENABLE_SHARED_WORKERS) $(ENABLE_SQL_DATABASE) $(ENABLE_STYLE_SCOPED) $(ENABLE_SVG) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_TEXT_AUTOSIZING) $(ENABLE_TEXT_NOTIFICATIONS_ONLY) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_UNDO_MANAGER) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_WEBGL) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XSLT); diff --git a/Source/JavaScriptCore/Configurations/Version.xcconfig b/Source/JavaScriptCore/Configurations/Version.xcconfig index ffba40115..f0f18d9e1 100644 --- a/Source/JavaScriptCore/Configurations/Version.xcconfig +++ b/Source/JavaScriptCore/Configurations/Version.xcconfig @@ -22,7 +22,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MAJOR_VERSION = 537; -MINOR_VERSION = 12; +MINOR_VERSION = 16; TINY_VERSION = 0; FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION); diff --git a/Source/JavaScriptCore/DerivedSources.pri b/Source/JavaScriptCore/DerivedSources.pri index 8d0f0537e..75fd5acc0 100644 --- a/Source/JavaScriptCore/DerivedSources.pri +++ b/Source/JavaScriptCore/DerivedSources.pri @@ -33,6 +33,13 @@ KEYWORDLUT_FILES += \ JIT_STUB_FILES += \ jit/JITStubs.cpp +LLINT_FILES = \ + llint/LowLevelInterpreter.asm + +LLINT_DEPENDENCY = \ + $$PWD/llint/LowLevelInterpreter32_64.asm \ + $$PWD/llint/LowLevelInterpreter64.asm + # GENERATOR 1-A: LUT creator lut.output = ${QMAKE_FILE_BASE}.lut.h lut.input = LUT_FILES @@ -80,3 +87,13 @@ klgen.script = $$PWD/KeywordLookupGenerator.py klgen.input = KEYWORDLUT_FILES klgen.commands = python $$klgen.script ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT} GENERATORS += klgen + +linux-*:!equals(QT_ARCH, "arm") { + #GENERATOR: LLInt + llint.output = LLIntAssembly.h + llint.script = $$PWD/offlineasm/asm.rb + llint.input = LLINT_FILES + llint.depends = LLIntOffsetsExtractor $$LLINT_DEPENDENCY + llint.commands = ruby $$llint.script ${QMAKE_FILE_NAME} LLIntOffsetsExtractor ${QMAKE_FILE_OUT} + GENERATORS += llint +} diff --git a/Source/JavaScriptCore/GNUmakefile.list.am b/Source/JavaScriptCore/GNUmakefile.list.am index e79542f9e..ae5854b91 100644 --- a/Source/JavaScriptCore/GNUmakefile.list.am +++ b/Source/JavaScriptCore/GNUmakefile.list.am @@ -67,6 +67,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/assembler/CodeLocation.h \ Source/JavaScriptCore/assembler/LinkBuffer.cpp \ Source/JavaScriptCore/assembler/LinkBuffer.h \ + Source/JavaScriptCore/assembler/MacroAssembler.cpp \ Source/JavaScriptCore/assembler/MacroAssembler.h \ Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp \ Source/JavaScriptCore/assembler/MacroAssemblerARM.h \ @@ -84,6 +85,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/assembler/X86Assembler.h \ Source/JavaScriptCore/bytecode/ArrayProfile.cpp \ Source/JavaScriptCore/bytecode/ArrayProfile.h \ + Source/JavaScriptCore/bytecode/ByValInfo.h \ Source/JavaScriptCore/bytecode/BytecodeConventions.h \ Source/JavaScriptCore/bytecode/CallLinkInfo.cpp \ Source/JavaScriptCore/bytecode/CallLinkInfo.h \ @@ -133,6 +135,8 @@ javascriptcore_sources += \ Source/JavaScriptCore/bytecode/ResolveGlobalStatus.h \ Source/JavaScriptCore/bytecode/SamplingTool.cpp \ Source/JavaScriptCore/bytecode/SamplingTool.h \ + Source/JavaScriptCore/bytecode/SpecialPointer.cpp \ + Source/JavaScriptCore/bytecode/SpecialPointer.h \ Source/JavaScriptCore/bytecode/StructureSet.h \ Source/JavaScriptCore/bytecode/StructureStubInfo.cpp \ Source/JavaScriptCore/bytecode/StructureStubInfo.h \ @@ -166,6 +170,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/dfg/DFGCCallHelpers.h \ Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp \ Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.h \ + Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h \ Source/JavaScriptCore/dfg/DFGCapabilities.cpp \ Source/JavaScriptCore/dfg/DFGCapabilities.h \ Source/JavaScriptCore/dfg/DFGCFAPhase.cpp \ @@ -252,6 +257,9 @@ javascriptcore_sources += \ Source/JavaScriptCore/heap/CopiedSpace.cpp \ Source/JavaScriptCore/heap/CopiedSpace.h \ Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h \ + Source/JavaScriptCore/heap/CopyVisitor.h \ + Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h \ + Source/JavaScriptCore/heap/CopyVisitor.cpp \ Source/JavaScriptCore/heap/CardSet.h \ Source/JavaScriptCore/heap/ConservativeRoots.cpp \ Source/JavaScriptCore/heap/ConservativeRoots.h \ @@ -276,8 +284,12 @@ javascriptcore_sources += \ Source/JavaScriptCore/heap/BlockAllocator.h \ Source/JavaScriptCore/heap/GCThreadSharedData.cpp \ Source/JavaScriptCore/heap/GCThreadSharedData.h \ + Source/JavaScriptCore/heap/GCThread.cpp \ + Source/JavaScriptCore/heap/GCThread.h \ Source/JavaScriptCore/heap/Heap.cpp \ Source/JavaScriptCore/heap/Heap.h \ + Source/JavaScriptCore/heap/HeapStatistics.cpp \ + Source/JavaScriptCore/heap/HeapStatistics.h \ Source/JavaScriptCore/heap/JITStubRoutineSet.cpp \ Source/JavaScriptCore/heap/JITStubRoutineSet.h \ Source/JavaScriptCore/heap/ListableHandler.h \ @@ -363,8 +375,8 @@ javascriptcore_sources += \ Source/JavaScriptCore/interpreter/CallFrame.h \ Source/JavaScriptCore/interpreter/Interpreter.cpp \ Source/JavaScriptCore/interpreter/Interpreter.h \ - Source/JavaScriptCore/interpreter/RegisterFile.cpp \ - Source/JavaScriptCore/interpreter/RegisterFile.h \ + Source/JavaScriptCore/interpreter/JSStack.cpp \ + Source/JavaScriptCore/interpreter/JSStack.h \ Source/JavaScriptCore/interpreter/Register.h \ Source/JavaScriptCore/interpreter/VMInspector.cpp \ Source/JavaScriptCore/interpreter/VMInspector.h \ @@ -517,6 +529,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/Identifier.h \ Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h \ Source/JavaScriptCore/runtime/IndexingHeader.h \ + Source/JavaScriptCore/runtime/IndexingType.cpp \ Source/JavaScriptCore/runtime/IndexingType.h \ Source/JavaScriptCore/runtime/InitializeThreading.cpp \ Source/JavaScriptCore/runtime/InitializeThreading.h \ @@ -533,6 +546,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/JSCell.h \ Source/JavaScriptCore/runtime/JSDateMath.cpp \ Source/JavaScriptCore/runtime/JSDateMath.h \ + Source/JavaScriptCore/runtime/JSDestructibleObject.h \ Source/JavaScriptCore/runtime/JSFunction.cpp \ Source/JavaScriptCore/runtime/JSFunction.h \ Source/JavaScriptCore/runtime/JSBoundFunction.cpp \ @@ -544,8 +558,8 @@ javascriptcore_sources += \ 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/JSProxy.cpp \ + Source/JavaScriptCore/runtime/JSProxy.h \ Source/JavaScriptCore/runtime/JSLock.cpp \ Source/JavaScriptCore/runtime/JSLock.h \ Source/JavaScriptCore/runtime/JSNotAnObject.cpp \ @@ -670,6 +684,7 @@ javascriptcore_sources += \ Source/JavaScriptCore/runtime/TimeoutChecker.cpp \ Source/JavaScriptCore/runtime/TimeoutChecker.h \ Source/JavaScriptCore/runtime/Tracing.h \ + Source/JavaScriptCore/runtime/TypedArrayDescriptor.h \ Source/JavaScriptCore/runtime/Uint16WithFraction.h \ Source/JavaScriptCore/runtime/WeakGCMap.h \ Source/JavaScriptCore/runtime/WeakRandom.h \ diff --git a/Source/JavaScriptCore/JSCTypedArrayStubs.h b/Source/JavaScriptCore/JSCTypedArrayStubs.h index e3926338c..2e273f66f 100644 --- a/Source/JavaScriptCore/JSCTypedArrayStubs.h +++ b/Source/JavaScriptCore/JSCTypedArrayStubs.h @@ -26,7 +26,7 @@ #ifndef JSCTypedArrayStubs_h #define JSCTypedArrayStubs_h -#include "JSObject.h" +#include "JSDestructibleObject.h" #include "ObjectPrototype.h" #include <wtf/Float32Array.h> #include <wtf/Float64Array.h> @@ -42,9 +42,9 @@ namespace JSC { #define TYPED_ARRAY(name, type) \ -class JS##name##Array : public JSNonFinalObject { \ +class JS##name##Array : public JSDestructibleObject { \ public: \ - typedef JSNonFinalObject Base; \ + typedef JSDestructibleObject Base; \ static JS##name##Array* create(JSC::Structure* structure, JSGlobalObject* globalObject, PassRefPtr<name##Array> impl) \ { \ JS##name##Array* ptr = new (NotNull, JSC::allocateCell<JS##name##Array>(globalObject->globalData().heap)) JS##name##Array(structure, globalObject, impl); \ diff --git a/Source/JavaScriptCore/JavaScriptCore.order b/Source/JavaScriptCore/JavaScriptCore.order index 0742a0a0e..aa3d0ef32 100644 --- a/Source/JavaScriptCore/JavaScriptCore.order +++ b/Source/JavaScriptCore/JavaScriptCore.order @@ -29,7 +29,7 @@ __ZN3JSC10JSFunctionC1ENS_6JSCell20VPtrStealingHackTypeE __ZN3WTF15initializeDatesEv __ZN3WTF11currentTimeEv __ZN3WTF8msToYearEd -__ZN3JSC12RegisterFile19initializeThreadingEv +__ZN3JSC12JSStack19initializeThreadingEv __ZN3WTF39initializeMainThreadToProcessMainThreadEv __ZN3WTF36lockAtomicallyInitializedStaticMutexEv __ZN3WTF38unlockAtomicallyInitializedStaticMutexEv @@ -158,7 +158,7 @@ __ZN3JSC25DefaultGCActivityCallbackclEv __ZN3JSC11RegExpCacheC1EPNS_12JSGlobalDataE __ZN3JSC11InterpreterC1ERNS_12JSGlobalDataE __ZN3JSC10HandleHeap12writeBarrierEPNS_7JSValueERKS1_ -__ZN3JSC12RegisterFile23addToCommittedByteCountEl +__ZN3JSC12JSStack23addToCommittedByteCountEl __ZN3JSC11MarkedSpace21allocateFromSizeClassERNS0_9SizeClassE __ZN3JSC11MarkedSpace13allocateBlockERNS0_9SizeClassE __ZN3JSC11MarkedBlock6createEPNS_12JSGlobalDataEm @@ -370,7 +370,7 @@ __ZN3JSC4Heap9markRootsEv __ZN3JSC14MachineThreads23gatherConservativeRootsERNS_17ConservativeRootsEPv __ZN3JSC14MachineThreads23gatherFromCurrentThreadERNS_17ConservativeRootsEPv __ZN3JSC17ConservativeRoots3addEPvS1_ -__ZN3JSC12RegisterFile23gatherConservativeRootsERNS_17ConservativeRootsE +__ZN3JSC12JSStack23gatherConservativeRootsERNS_17ConservativeRootsE __ZN3JSC11MarkedSpace10clearMarksEv __ZN3JSC9MarkStack6appendERNS_17ConservativeRootsE __ZN3JSC9MarkStack5drainEv @@ -511,9 +511,9 @@ __ZN3JSC4Heap29reportExtraMemoryCostSlowCaseEm __ZN3JSC17BytecodeGeneratorD2Ev __ZThn16_N3JSC11ProgramNodeD0Ev __ZN3JSC11ProgramNodeD0Ev -__ZN3JSC12RegisterFile12globalObjectEv -__ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12RegisterFileE -__ZN3JSC12RegisterFile15setGlobalObjectEPNS_14JSGlobalObjectE +__ZN3JSC12JSStack12globalObjectEv +__ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12JSStackE +__ZN3JSC12JSStack15setGlobalObjectEPNS_14JSGlobalObjectE _ctiTrampoline __ZN3WTF15SegmentedVectorIN3JSC10IdentifierELm64EE6appendIS2_EEvRKT_ __ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE @@ -682,7 +682,7 @@ __ZN3JSC18FunctionExecutable11discardCodeEv __ZN3JSC17FunctionCodeBlockD0Ev __ZN3JSC9CodeBlockD2Ev __ZN3JSC15WeakHandleOwner26isReachableFromOpaqueRootsENS_6HandleINS_7UnknownEEEPvRNS_9MarkStackE -__ZN3JSC12RegisterFile17GlobalObjectOwner8finalizeENS_6HandleINS_7UnknownEEEPv +__ZN3JSC12JSStack17GlobalObjectOwner8finalizeENS_6HandleINS_7UnknownEEEPv __ZN3JSC13ErrorInstanceD1Ev __ZN3JSC12StringObjectD1Ev __ZN3JSC12NumberObjectD1Ev @@ -784,7 +784,7 @@ __ZN3WTF9HashTableIPNS_10StringImplES2_NS_17IdentityExtractorIS2_EEN3JSC17Identi __ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE __ZN3JSC18FunctionExecutableC1EPNS_9ExecStateERKNS_10IdentifierERKNS_10SourceCodeEbPNS_18FunctionParametersEbii __ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE -__ZN3JSC14JSGlobalObject15copyGlobalsFromERNS_12RegisterFileE +__ZN3JSC14JSGlobalObject15copyGlobalsFromERNS_12JSStackE __ZNK3WTF12AtomicString5lowerEv __ZN3JSC41constructFunctionSkippingEvalEnabledCheckEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi __ZN3WTF13StringBuilder6appendEPKcj @@ -810,7 +810,7 @@ __ZNK3JSC14JSGlobalObject14isDynamicScopeERb __ZN3JSC16VarStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17AssignResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE __ZN3JSC17BytecodeGenerator15isLocalConstantERKNS_10IdentifierE -_cti_register_file_check +_cti_stack_check __ZN3JSC16JSCallbackObjectINS_24JSObjectWithGlobalObjectEE17staticValueGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE __ZN3WTF9HashTableISt4pairINS_6RefPtrINS_10StringImplEEEjES1_IS5_PN3JSC7JSValueEENS_18PairFirstExtractorIS9_EENS6_24StructureTransitionTable4HashENS_14PairHashTraitsINSC_10HashTraitsENS_10HashTraitsIS8_EEEESF_E6rehashEi _JSValueMakeString @@ -979,7 +979,7 @@ _cti_op_eq _cti_op_resolve_with_base __ZN3JSC12JSActivation18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE _cti_op_call_eval -__ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12RegisterFileEPNS_8RegisterEii +__ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12JSStackEPNS_8RegisterEii __ZN3JSC14EvalExecutableC1EPNS_9ExecStateERKNS_10SourceCodeEb __ZN3JSC14EvalExecutable15compileInternalEPNS_9ExecStateEPNS_14ScopeChainNodeE __ZN3JSC6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_14JSGlobalObjectEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPNS_18FunctionParametersENS_18JSParserStrictnessEPPNS_8JSObjectE @@ -1155,6 +1155,7 @@ ___initializeScavenger_block_invoke_1 __ZN3WTF23waitForThreadCompletionEj __ZN3WTF23waitForThreadCompletionEjPPv _JSObjectCopyPropertyNames +__ZN3JSC8JSObject16copyBackingStoreEPNS_6JSCellERNS_11CopyVisitorE __ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE __ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE __ZN3JSC9Structure16getPropertyNamesERNS_12JSGlobalDataERNS_17PropertyNameArrayENS_15EnumerationModeE @@ -1713,8 +1714,8 @@ __ZN3JSC9JITThunks22clearHostFunctionStubsEv __ZN3JSC11MarkedSpace7destroyEv __ZN3JSC12JSGlobalDataD1Ev __ZN3JSC12JSGlobalDataD2Ev -__ZN3JSC12RegisterFileD1Ev -__ZN3JSC12RegisterFileD2Ev +__ZN3JSC12JSStackD1Ev +__ZN3JSC12JSStackD2Ev __ZNK3JSC9HashTable11deleteTableEv __ZN3JSC5LexerD1Ev __ZN3WTF20deleteAllPairSecondsIP24OpaqueJSClassContextDataKNS_7HashMapIP13OpaqueJSClassS2_NS_7PtrHashIS5_EENS_10HashTraitsIS5_EENS8_IS2_EEEEEEvRT0_ @@ -1835,7 +1836,7 @@ __ZN3JSCL19constructJSCallbackEPNS_9ExecStateE __ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE __ZN3JSC16createRangeErrorEPNS_9ExecStateERKNS_7UStringE _cti_op_mul -__ZN3JSC12RegisterFile21releaseExcessCapacityEv +__ZN3JSC12JSStack21releaseExcessCapacityEv __ZN3JSC16JSCallbackObjectINS_14JSGlobalObjectEED1Ev _JSObjectHasProperty _JSObjectGetPrototype @@ -2482,7 +2483,7 @@ __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 +__ZN3JSC12JSStack18committedByteCountEv __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_ diff --git a/Source/JavaScriptCore/JavaScriptCore.pro b/Source/JavaScriptCore/JavaScriptCore.pro index 393728f99..082244f8d 100644 --- a/Source/JavaScriptCore/JavaScriptCore.pro +++ b/Source/JavaScriptCore/JavaScriptCore.pro @@ -7,11 +7,18 @@ TEMPLATE = subdirs CONFIG += ordered +linux-*:!equals(QT_ARCH, "arm") { + LLIntOffsetsExtractor.file = LLIntOffsetsExtractor.pro + LLIntOffsetsExtractor.makefile = Makefile.LLIntOffsetsExtractor + SUBDIRS += LLIntOffsetsExtractor +} + derived_sources.file = DerivedSources.pri target.file = Target.pri SUBDIRS += derived_sources target +linux-*:!equals(QT_ARCH, "arm"):addStrictSubdirOrderBetween(LLIntOffsetsExtractor, derived_sources) addStrictSubdirOrderBetween(derived_sources, target) jsc.file = jsc.pro diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def index eda306f3c..0724ca1ca 100755 --- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def +++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def @@ -2,9 +2,9 @@ EXPORTS ??0ArrayBufferView@WTF@@IAE@V?$PassRefPtr@VArrayBuffer@WTF@@@1@I@Z ??0BooleanObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@@Z + ??0Collator@WTF@@QAE@PBD@Z ??0CString@WTF@@QAE@PBD@Z ??0CString@WTF@@QAE@PBDI@Z - ??0Collator@WTF@@QAE@PBD@Z ??0DateInstance@JSC@@IAE@PAVExecState@1@PAVStructure@1@@Z ??0DefaultGCActivityCallback@JSC@@QAE@PAVHeap@1@@Z ??0DropAllLocks@JSLock@JSC@@QAE@PAVExecState@2@@Z @@ -16,13 +16,14 @@ EXPORTS ??0JSLockHolder@JSC@@QAE@PAVExecState@1@@Z ??0JSLockHolder@JSC@@QAE@PAVJSGlobalData@1@@Z ??0MD5@WTF@@QAE@XZ + ??0MediaTime@WTF@@QAE@_JHI@Z ??0Mutex@WTF@@QAE@XZ ??0ParallelEnvironment@WTF@@QAE@P6AXPAX@ZIH@Z ??0RefCountedLeakCounter@WTF@@QAE@PBD@Z ??0RegExpObject@JSC@@IAE@PAVJSGlobalObject@1@PAVStructure@1@PAVRegExp@1@@Z ??0SHA1@WTF@@QAE@XZ ??0StringObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@@Z - ??0Structure@JSC@@AAE@AAVJSGlobalData@1@PAVJSGlobalObject@1@VJSValue@1@ABVTypeInfo@1@PBUClassInfo@1@E@Z + ??0Structure@JSC@@AAE@AAVJSGlobalData@1@PAVJSGlobalObject@1@VJSValue@1@ABVTypeInfo@1@PBUClassInfo@1@EH@Z ??0ThreadCondition@WTF@@QAE@XZ ??0WTFThreadData@WTF@@QAE@XZ ??0YarrPattern@Yarr@JSC@@QAE@ABVString@WTF@@_N1PAPBD@Z @@ -34,19 +35,20 @@ EXPORTS ??1JSGlobalData@JSC@@QAE@XZ ??1JSGlobalObject@JSC@@QAE@XZ ??1JSLockHolder@JSC@@QAE@XZ + ??1MediaTime@WTF@@QAE@XZ ??1Mutex@WTF@@QAE@XZ ??1RefCountedLeakCounter@WTF@@QAE@XZ ??1SourceProviderCache@JSC@@QAE@XZ ??1ThreadCondition@WTF@@QAE@XZ - ??1WTFThreadData@WTF@@QAE@XZ ??1WeakHandleOwner@JSC@@UAE@XZ + ??1WTFThreadData@WTF@@QAE@XZ + ??8MediaTime@WTF@@QBE_NABV01@@Z ??8WTF@@YA_NABVCString@0@0@Z - ?EcmaScriptConverter@DoubleToStringConverter@double_conversion@WTF@@SAABV123@XZ - ?StringToDouble@StringToDoubleConverter@double_conversion@WTF@@SANPBDIPAI@Z - ?ToExponential@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z - ?ToFixed@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z - ?ToPrecision@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z - ?ToShortest@DoubleToStringConverter@double_conversion@WTF@@QBE_NNPAVStringBuilder@23@@Z + ??GMediaTime@WTF@@QBE?AV01@ABV01@@Z + ??HMediaTime@WTF@@QBE?AV01@ABV01@@Z + ??MMediaTime@WTF@@QBE_NABV01@@Z + ??OMediaTime@WTF@@QBE_NABV01@@Z + ?abs@WTF@@YA?AVMediaTime@1@ABV21@@Z ?absoluteTimeToWaitTimeoutInterval@WTF@@YAKN@Z ?activityCallback@Heap@JSC@@QAEPAVGCActivityCallback@2@XZ ?add@AtomicString@WTF@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@2@PBD@Z @@ -64,14 +66,14 @@ EXPORTS ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVJSGlobalData@2@PAVStringImpl@4@@Z ?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z ?allocateSlowCase@MarkedAllocator@JSC@@AAEPAXI@Z - ?append@StringBuilder@WTF@@QAEXPBEI@Z ?append@StringBuilder@WTF@@QAEXPB_WI@Z + ?append@StringBuilder@WTF@@QAEXPBEI@Z + ?appendNumber@StringBuilder@WTF@@QAEX_J@Z + ?appendNumber@StringBuilder@WTF@@QAEX_K@Z ?appendNumber@StringBuilder@WTF@@QAEXH@Z ?appendNumber@StringBuilder@WTF@@QAEXI@Z ?appendNumber@StringBuilder@WTF@@QAEXJ@Z ?appendNumber@StringBuilder@WTF@@QAEXK@Z - ?appendNumber@StringBuilder@WTF@@QAEX_J@Z - ?appendNumber@StringBuilder@WTF@@QAEX_K@Z ?attach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z ?base64Decode@WTF@@YA_NABVString@1@AAV?$Vector@D$0A@@1@W4Base64DecodePolicy@1@@Z ?base64Encode@WTF@@YA?AVString@1@PBDIW4Base64EncodePolicy@1@@Z @@ -81,23 +83,24 @@ EXPORTS ?bufferLengthForStringExponential@DecimalNumber@WTF@@QBEIXZ ?byteCompile@Yarr@JSC@@YA?AV?$PassOwnPtr@UBytecodePattern@Yarr@JSC@@@WTF@@AAUYarrPattern@12@PAVBumpPointerAllocator@4@@Z ?byteSize@SourceProviderCache@JSC@@QBEIXZ + ?calculatedFunctionName@DebuggerCallFrame@JSC@@QBE?AVString@WTF@@XZ ?calculateDSTOffset@WTF@@YANNN@Z ?calculateStringHashAndLengthFromUTF8MaskingTop8Bits@Unicode@WTF@@YAIPBD0AAI1@Z ?calculateUTCOffset@WTF@@YAHXZ - ?calculatedFunctionName@DebuggerCallFrame@JSC@@QBE?AVString@WTF@@XZ ?call@JSC@@YA?AVJSValue@1@PAVExecState@1@V21@W4CallType@1@ABTCallData@1@1ABVArgList@1@@Z ?callHostFunctionAsConstructor@JSC@@YI_JPAVExecState@1@@Z ?callOnMainThread@WTF@@YAXP6AXPAX@Z0@Z ?callOnMainThreadAndWait@WTF@@YAXP6AXPAX@Z0@Z - ?canShrink@StringBuilder@WTF@@QBE_NXZ ?cancelCallOnMainThread@WTF@@YAXP6AXPAX@Z0@Z + ?canShrink@StringBuilder@WTF@@QBE_NXZ ?capacity@Heap@JSC@@QAEIXZ ?changePrototypeTransition@Structure@JSC@@SAPAV12@AAVJSGlobalData@2@PAV12@VJSValue@2@@Z ?checkCurrentIdentifierTable@Identifier@JSC@@CAXPAVExecState@2@@Z ?checkCurrentIdentifierTable@Identifier@JSC@@CAXPAVJSGlobalData@2@@Z - ?checkSyntax@JSC@@YA_NPAVExecState@1@ABVSourceCode@1@PAVJSValue@1@@Z ?checksum@MD5@WTF@@QAEXAAV?$Vector@E$0BA@@2@@Z + ?checkSyntax@JSC@@YA_NPAVExecState@1@ABVSourceCode@1@PAVJSValue@1@@Z ?className@JSObject@JSC@@SA?AVString@WTF@@PBV12@@Z + ?className@JSProxy@JSC@@KA?AVString@WTF@@PBVJSObject@2@@Z ?clear@SourceProviderCache@JSC@@QAEXXZ ?clearRareData@JSGlobalObject@JSC@@CAXPAVJSCell@2@@Z ?collate@Collator@WTF@@QBE?AW4Result@12@PB_WI0I@Z @@ -113,6 +116,7 @@ EXPORTS ?convertLatin1ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPBEPBEPAPADPAD@Z ?convertUTF16ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPB_WPB_WPAPADPAD_N@Z ?convertUTF8ToUTF16@Unicode@WTF@@YA?AW4ConversionResult@12@PAPBDPBDPAPA_WPA_W_N@Z + ?copyBackingStore@JSObject@JSC@@SAXPAVJSCell@2@AAVCopyVisitor@2@@Z ?create@JSFunction@JSC@@SAPAV12@PAVExecState@2@PAVJSGlobalObject@2@HABVString@WTF@@P6I_J0@ZW4Intrinsic@2@3@Z ?create@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@W4ThreadStackType@2@W4HeapType@2@@Z ?create@RegExp@JSC@@SAPAV12@AAVJSGlobalData@2@ABVString@WTF@@W4RegExpFlags@2@@Z @@ -131,6 +135,8 @@ EXPORTS ?createThread@WTF@@YAIP6APAXPAX@Z0PBD@Z ?createThread@WTF@@YAIP6AXPAX@Z0PBD@Z ?createTypeError@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVString@WTF@@@Z + ?createWithDouble@MediaTime@WTF@@SA?AV12@NH@Z + ?createWithFloat@MediaTime@WTF@@SA?AV12@MH@Z ?cryptographicallyRandomNumber@WTF@@YAIXZ ?cryptographicallyRandomValues@WTF@@YAXPAXI@Z ?currentThread@WTF@@YAIXZ @@ -145,14 +151,18 @@ EXPORTS ?defaultValue@JSObject@JSC@@SA?AVJSValue@2@PBV12@PAVExecState@2@W4PreferredPrimitiveType@2@@Z ?defineOwnProperty@JSGlobalObject@JSC@@SA_NPAVJSObject@2@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@_N@Z ?defineOwnProperty@JSObject@JSC@@SA_NPAV12@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@_N@Z + ?defineOwnProperty@JSProxy@JSC@@KA_NPAVJSObject@2@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@_N@Z + ?deleteAllCompiledCode@Heap@JSC@@QAEXXZ ?deleteOwnedPtr@WTF@@YAXPAUHBITMAP__@@@Z ?deleteOwnedPtr@WTF@@YAXPAUHBRUSH__@@@Z ?deleteOwnedPtr@WTF@@YAXPAUHDC__@@@Z ?deleteOwnedPtr@WTF@@YAXPAUHFONT__@@@Z ?deleteOwnedPtr@WTF@@YAXPAUHRGN__@@@Z ?deleteProperty@JSObject@JSC@@SA_NPAVJSCell@2@PAVExecState@2@VPropertyName@2@@Z + ?deleteProperty@JSProxy@JSC@@KA_NPAVJSCell@2@PAVExecState@2@VPropertyName@2@@Z ?deleteProperty@JSSymbolTableObject@JSC@@SA_NPAVJSCell@2@PAVExecState@2@VPropertyName@2@@Z ?deletePropertyByIndex@JSObject@JSC@@SA_NPAVJSCell@2@PAVExecState@2@I@Z + ?deletePropertyByIndex@JSProxy@JSC@@KA_NPAVJSCell@2@PAVExecState@2@I@Z ?deleteTable@HashTable@JSC@@QBEXXZ ?description@JSValue@JSC@@QBEPADXZ ?despecifyDictionaryFunction@Structure@JSC@@QAEXAAVJSGlobalData@2@VPropertyName@2@@Z @@ -164,11 +174,11 @@ EXPORTS ?detachThread@WTF@@YAXI@Z ?didTimeOut@TimeoutChecker@JSC@@QAE_NPAVExecState@2@@Z ?displayName@JSFunction@JSC@@QAE?AVString@WTF@@PAVExecState@2@@Z - ?deleteAllCompiledCode@Heap@JSC@@QAEXXZ ?dtoa@WTF@@YAXQADNAA_NAAHAAI@Z ?dumpAllOptions@Options@JSC@@SAXPAU_iobuf@@@Z ?dumpCallFrame@Interpreter@JSC@@QAEXPAVExecState@2@@Z ?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z + ?EcmaScriptConverter@DoubleToStringConverter@double_conversion@WTF@@SAABV123@XZ ?empty@StringImpl@WTF@@SAPAV12@XZ ?enumerable@PropertyDescriptor@JSC@@QBE_NXZ ?equalUTF16WithUTF8@Unicode@WTF@@YA_NPB_W0PBD1@Z @@ -199,35 +209,41 @@ EXPORTS ?from@Identifier@JSC@@SA?AV12@PAVExecState@2@H@Z ?from@Identifier@JSC@@SA?AV12@PAVExecState@2@I@Z ?functionGetter@PropertySlot@JSC@@ABE?AVJSValue@2@PAVExecState@2@@Z + ?get@Structure@JSC@@QAEHAAVJSGlobalData@2@VPropertyName@2@AAIAAPAVJSCell@2@@Z ?getCalculatedDisplayName@JSC@@YA?AVString@WTF@@PAVExecState@1@PAVJSObject@1@@Z - ?getCallData@JSCell@JSC@@SA?AW4CallType@2@PAV12@AATCallData@2@@Z ?getCallableObjectSlow@JSC@@YAPAVJSCell@1@PAV21@@Z + ?getCallData@JSCell@JSC@@SA?AW4CallType@2@PAV12@AATCallData@2@@Z ?getConstructData@JSCell@JSC@@SA?AW4ConstructType@2@PAV12@AATConstructData@2@@Z ?getObject@JSCell@JSC@@QAEPAVJSObject@2@XZ ?getOwnNonIndexPropertyNames@JSObject@JSC@@SAXPAV12@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z ?getOwnNonIndexPropertyNames@JSSymbolTableObject@JSC@@SAXPAVJSObject@2@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z ?getOwnPropertyDescriptor@JSGlobalObject@JSC@@SA_NPAVJSObject@2@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@@Z ?getOwnPropertyDescriptor@JSObject@JSC@@SA_NPAV12@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@@Z + ?getOwnPropertyDescriptor@JSProxy@JSC@@KA_NPAVJSObject@2@PAVExecState@2@VPropertyName@2@AAVPropertyDescriptor@2@@Z ?getOwnPropertyNames@JSObject@JSC@@SAXPAV12@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z + ?getOwnPropertyNames@JSProxy@JSC@@KAXPAVJSObject@2@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z ?getOwnPropertySlot@JSGlobalObject@JSC@@SA_NPAVJSCell@2@PAVExecState@2@VPropertyName@2@AAVPropertySlot@2@@Z + ?getOwnPropertySlot@JSProxy@JSC@@KA_NPAVJSCell@2@PAVExecState@2@VPropertyName@2@AAVPropertySlot@2@@Z ?getOwnPropertySlotByIndex@JSObject@JSC@@SA_NPAVJSCell@2@PAVExecState@2@IAAVPropertySlot@2@@Z + ?getOwnPropertySlotByIndex@JSProxy@JSC@@KA_NPAVJSCell@2@PAVExecState@2@IAAVPropertySlot@2@@Z ?getOwnPropertySlotSlow@JSObject@JSC@@AAE_NPAVExecState@2@VPropertyName@2@AAVPropertySlot@2@@Z ?getPropertyNames@JSObject@JSC@@SAXPAV12@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z + ?getPropertyNames@JSProxy@JSC@@KAXPAVJSObject@2@PAVExecState@2@AAVPropertyNameArray@2@W4EnumerationMode@2@@Z ?getSlice@ArgList@JSC@@QBEXHAAV12@@Z ?getStackTrace@Interpreter@JSC@@SAXPAVJSGlobalData@2@AAV?$Vector@UStackFrame@JSC@@$0A@@WTF@@@Z ?getString@JSCell@JSC@@QBE?AVString@WTF@@PAVExecState@2@@Z ?getString@JSCell@JSC@@QBE_NPAVExecState@2@AAVString@WTF@@@Z - ?get@Structure@JSC@@QAEHAAVJSGlobalData@2@VPropertyName@2@AAIAAPAVJSCell@2@@Z ?getter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ ?globalExec@JSGlobalObject@JSC@@QAEPAVExecState@2@XZ ?globalObjectCount@Heap@JSC@@QAEIXZ ?grow@HandleSet@JSC@@AAEXXZ ?growOutOfLineStorage@JSObject@JSC@@QAEPAVButterfly@2@AAVJSGlobalData@2@II@Z + ?hashSlowCase@StringImpl@WTF@@ABEIXZ ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@I@Z ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@VPropertyName@2@@Z - ?hashSlowCase@StringImpl@WTF@@ABEIXZ ?heap@Heap@JSC@@SAPAV12@VJSValue@2@@Z ?increment@RefCountedLeakCounter@WTF@@QAEXXZ + ?indefiniteTime@MediaTime@WTF@@SAABV12@XZ ?init@AtomicString@WTF@@SAXXZ ?init@JSGlobalObject@JSC@@AAEXPAVJSObject@2@@Z ?initialize@double_conversion@WTF@@YAXXZ @@ -235,6 +251,7 @@ EXPORTS ?initializeThreading@JSC@@YAXXZ ?initializeThreading@WTF@@YAXXZ ?interpret@Yarr@JSC@@YAIPAUBytecodePattern@12@ABVString@WTF@@IPAI@Z + ?invalidTime@MediaTime@WTF@@SAABV12@XZ ?isAccessorDescriptor@PropertyDescriptor@JSC@@QBE_NXZ ?isBusy@Heap@JSC@@QAE_NXZ ?isDataDescriptor@PropertyDescriptor@JSC@@QBE_NXZ @@ -254,6 +271,7 @@ EXPORTS ?monthFromDayInYear@WTF@@YAHH_N@Z ?msToYear@WTF@@YAHN@Z ?name@JSFunction@JSC@@QAE?AVString@WTF@@PAVExecState@2@@Z + ?negativeInfiniteTime@MediaTime@WTF@@SAABV12@XZ ?neuter@ArrayBufferView@WTF@@MAEXXZ ?newUninitialized@CString@WTF@@SA?AV12@IAAPAD@Z ?notifyWriteSlow@SymbolTableEntry@JSC@@AAEXXZ @@ -268,6 +286,7 @@ EXPORTS ?objectTypeCounts@Heap@JSC@@QAE?AV?$PassOwnPtr@V?$HashCountedSet@PBDU?$PtrHash@PBD@WTF@@U?$HashTraits@PBD@2@@WTF@@@WTF@@XZ ?parseDateFromNullTerminatedCharacters@WTF@@YANPBD@Z ?parseDoubleFromLongString@Internal@WTF@@YANPB_WIAAI@Z + ?positiveInfiniteTime@MediaTime@WTF@@SAABV12@XZ ?profiler@Profiler@JSC@@SAPAV12@XZ ?protect@Heap@JSC@@QAEXVJSValue@2@@Z ?protectedGlobalObjectCount@Heap@JSC@@QAEIXZ @@ -275,11 +294,14 @@ EXPORTS ?protectedObjectTypeCounts@Heap@JSC@@QAE?AV?$PassOwnPtr@V?$HashCountedSet@PBDU?$PtrHash@PBD@WTF@@U?$HashTraits@PBD@2@@WTF@@@WTF@@XZ ?put@JSGlobalObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@VPropertyName@2@VJSValue@2@AAVPutPropertySlot@2@@Z ?put@JSObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@VPropertyName@2@VJSValue@2@AAVPutPropertySlot@2@@Z + ?put@JSProxy@JSC@@KAXPAVJSCell@2@PAVExecState@2@VPropertyName@2@VJSValue@2@AAVPutPropertySlot@2@@Z ?putByIndex@JSObject@JSC@@SAXPAVJSCell@2@PAVExecState@2@IVJSValue@2@_N@Z + ?putByIndex@JSProxy@JSC@@KAXPAVJSCell@2@PAVExecState@2@IVJSValue@2@_N@Z ?putDirectIndexBeyondVectorLength@JSObject@JSC@@AAE_NPAVExecState@2@IVJSValue@2@IW4PutDirectIndexMode@2@@Z ?putDirectMayBeIndex@JSObject@JSC@@QAEXPAVExecState@2@VPropertyName@2@VJSValue@2@@Z ?putDirectVirtual@JSGlobalObject@JSC@@SAXPAVJSObject@2@PAVExecState@2@VPropertyName@2@VJSValue@2@I@Z ?putDirectVirtual@JSObject@JSC@@SAXPAV12@PAVExecState@2@VPropertyName@2@VJSValue@2@I@Z + ?putDirectVirtual@JSProxy@JSC@@KAXPAVJSObject@2@PAVExecState@2@VPropertyName@2@VJSValue@2@I@Z ?randomNumber@WTF@@YANXZ ?recompileAllJSFunctions@Debugger@JSC@@QAEXPAVJSGlobalData@2@@Z ?regExpFlags@JSC@@YA?AW4RegExpFlags@1@ABVString@WTF@@@Z @@ -289,6 +311,7 @@ EXPORTS ?removeBlock@MarkedAllocator@JSC@@QAEXPAVMarkedBlock@2@@Z ?reportAbandonedObjectGraph@Heap@JSC@@QAEXXZ ?reportExtraMemoryCostSlowCase@Heap@JSC@@AAEXI@Z + ?reportSuccess@HeapStatistics@JSC@@SAXXZ ?reserveAndCommit@OSAllocator@WTF@@SAPAXIW4Usage@12@_N11@Z ?reserveCapacity@StringBuilder@WTF@@QAEXI@Z ?reset@ParserArena@JSC@@QAEXXZ @@ -306,18 +329,19 @@ EXPORTS ?setEnumerable@PropertyDescriptor@JSC@@QAEX_N@Z ?setGarbageCollectionTimerEnabled@Heap@JSC@@QAEX_N@Z ?setGetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z + ?setGlobalThis@JSGlobalObject@JSC@@IAEXAAVJSGlobalData@2@PAVJSObject@2@@Z ?setLoc@StatementNode@JSC@@QAEXHH@Z ?setMainThreadCallbacksPaused@WTF@@YAX_N@Z ?setOption@Options@JSC@@SA_NPBD@Z ?setOrderLowerFirst@Collator@WTF@@QAEX_N@Z ?setPrototype@JSObject@JSC@@QAEXAAVJSGlobalData@2@VJSValue@2@@Z ?setSetter@PropertyDescriptor@JSC@@QAEXVJSValue@2@@Z + ?setTarget@JSProxy@JSC@@IAEXAAVJSGlobalData@2@PAVJSGlobalObject@2@@Z + ?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ ?setToCurrentLocalTime@GregorianDateTime@WTF@@QAEXXZ ?setUndefined@PropertyDescriptor@JSC@@QAEXXZ - ?setUnwrappedObject@JSGlobalThis@JSC@@IAEXAAVJSGlobalData@2@PAVJSGlobalObject@2@@Z ?setUpStaticFunctionSlot@JSC@@YA_NPAVExecState@1@PBVHashEntry@1@PAVJSObject@1@VPropertyName@1@AAVPropertySlot@1@@Z ?setWritable@PropertyDescriptor@JSC@@QAEX_N@Z - ?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ ?shrinkToFit@StringBuilder@WTF@@QAEXXZ ?signal@ThreadCondition@WTF@@QAEXXZ ?singleCharacterStringRep@SmallStrings@JSC@@QAEPAVStringImpl@WTF@@E@Z @@ -330,6 +354,7 @@ EXPORTS ?startSampling@JSGlobalData@JSC@@QAEXXZ ?stopProfiling@Profiler@JSC@@QAE?AV?$PassRefPtr@VProfile@JSC@@@WTF@@PAVExecState@2@ABVString@4@@Z ?stopSampling@JSGlobalData@JSC@@QAEXXZ + ?StringToDouble@StringToDoubleConverter@double_conversion@WTF@@SANPBDIPAI@Z ?suggestedNewOutOfLineStorageCapacity@Structure@JSC@@QAEIXZ ?sweeper@Heap@JSC@@QAEPAVIncrementalSweeper@2@XZ ?synthesizePrototype@JSValue@JSC@@QBEPAVJSObject@2@PAVExecState@2@@Z @@ -343,15 +368,22 @@ EXPORTS ?tlsKeyCount@WTF@@YAAAJXZ ?tlsKeys@WTF@@YAPAKXZ ?toBoolean@JSString@JSC@@QBE_NXZ + ?toDouble@MediaTime@WTF@@QBENXZ + ?ToExponential@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z + ?ToFixed@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z + ?toFloat@MediaTime@WTF@@QBEMXZ ?toInt32@JSC@@YAHN@Z ?toInteger@JSValue@JSC@@QBENPAVExecState@2@@Z ?toNumberSlowCase@JSValue@JSC@@ABENPAVExecState@2@@Z ?toObject@JSCell@JSC@@QBEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z ?toObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@PAVJSGlobalObject@2@@Z + ?ToPrecision@DoubleToStringConverter@double_conversion@WTF@@QBE_NNHPAVStringBuilder@23@@Z + ?ToShortest@DoubleToStringConverter@double_conversion@WTF@@QBE_NNPAVStringBuilder@23@@Z ?toString@JSObject@JSC@@QBEPAVJSString@2@PAVExecState@2@@Z ?toStringDecimal@DecimalNumber@WTF@@QBEIPAEI@Z ?toStringExponential@DecimalNumber@WTF@@QBEIPAEI@Z ?toStringSlowCase@JSValue@JSC@@ABEPAVJSString@2@PAVExecState@2@@Z + ?toThisObject@JSGlobalObject@JSC@@KAPAVJSObject@2@PAVJSCell@2@PAVExecState@2@@Z ?toThisObject@JSObject@JSC@@SAPAV12@PAVJSCell@2@PAVExecState@2@@Z ?toThisObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z ?toWTFStringSlowCase@JSValue@JSC@@ABE?AVString@WTF@@PAVExecState@2@@Z @@ -368,31 +400,15 @@ EXPORTS ?unprotect@Heap@JSC@@QAE_NVJSValue@2@@Z ?validate@SlotVisitor@JSC@@CAXPAVJSCell@2@@Z ?visitChildren@JSGlobalObject@JSC@@SAXPAVJSCell@2@AAVSlotVisitor@2@@Z - ?visitChildren@JSGlobalThis@JSC@@KAXPAVJSCell@2@AAVSlotVisitor@2@@Z ?visitChildren@JSObject@JSC@@SAXPAVJSCell@2@AAVSlotVisitor@2@@Z + ?visitChildren@JSProxy@JSC@@KAXPAVJSCell@2@AAVSlotVisitor@2@@Z ?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z ?waitForThreadCompletion@WTF@@YAHI@Z ?waitForThreadCompletion@WTF@@YAHIPAPAX@Z ?writable@PropertyDescriptor@JSC@@QBE_NXZ ?writeBarrier@HandleSet@JSC@@QAEXPAVJSValue@2@ABV32@@Z ?yield@WTF@@YAXXZ - ?toDouble@MediaTime@WTF@@QBENXZ - ?toFloat@MediaTime@WTF@@QBEMXZ - ?createWithDouble@MediaTime@WTF@@SA?AV12@NH@Z - ?createWithFloat@MediaTime@WTF@@SA?AV12@MH@Z - ?abs@WTF@@YA?AVMediaTime@1@ABV21@@Z ?zeroTime@MediaTime@WTF@@SAABV12@XZ - ??GMediaTime@WTF@@QBE?AV01@ABV01@@Z - ??HMediaTime@WTF@@QBE?AV01@ABV01@@Z - ??1MediaTime@WTF@@QAE@XZ - ??0MediaTime@WTF@@QAE@_JHI@Z - ?indefiniteTime@MediaTime@WTF@@SAABV12@XZ - ?invalidTime@MediaTime@WTF@@SAABV12@XZ - ??8MediaTime@WTF@@QBE_NABV01@@Z - ??MMediaTime@WTF@@QBE_NABV01@@Z - ??OMediaTime@WTF@@QBE_NABV01@@Z - ?positiveInfiniteTime@MediaTime@WTF@@SAABV12@XZ - ?negativeInfiniteTime@MediaTime@WTF@@SAABV12@XZ WTFGetBacktrace WTFInvokeCrashHook WTFLog diff --git a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj index f5cbbb150..a21dcf1e8 100644 --- a/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj +++ b/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj @@ -522,6 +522,10 @@ >
</File>
<File
+ RelativePath="..\..\runtime\IndexingType.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\IndexingType.h"
>
</File>
@@ -842,6 +846,10 @@ >
</File>
<File
+ RelativePath="..\..\runtime\JSDestructibleObject.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\JSFunction.cpp"
>
</File>
@@ -874,11 +882,11 @@ >
</File>
<File
- RelativePath="..\..\runtime\JSGlobalThis.cpp"
+ RelativePath="..\..\runtime\JSProxy.cpp"
>
</File>
<File
- RelativePath="..\..\runtime\JSGlobalThis.h"
+ RelativePath="..\..\runtime\JSProxy.h"
>
</File>
<File
@@ -1330,6 +1338,10 @@ >
</File>
<File
+ RelativePath="..\..\runtime\TypedArrayDescriptor.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\WeakGCMap.h"
>
</File>
@@ -1570,6 +1582,10 @@ >
</File>
<File
+ RelativePath="..\..\bytecode\ByValInfo.h"
+ >
+ </File>
+ <File
RelativePath="..\..\bytecode\CallLinkInfo.cpp"
>
</File>
@@ -1698,6 +1714,14 @@ >
</File>
<File
+ RelativePath="..\..\bytecode\SpecialPointer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\bytecode\SpecialPointer.h"
+ >
+ </File>
+ <File
RelativePath="..\..\bytecode\SpeculatedType.cpp"
>
</File>
@@ -1802,6 +1826,10 @@ >
</File>
<File
+ RelativePath="..\..\assembler\MacroAssembler.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\assembler\MacroAssembler.h"
>
</File>
@@ -2130,15 +2158,15 @@ >
</File>
<File
- RelativePath="..\..\interpreter\Register.h"
+ RelativePath="..\..\interpreter\JSStack.cpp"
>
</File>
<File
- RelativePath="..\..\interpreter\RegisterFile.cpp"
+ RelativePath="..\..\interpreter\JSStack.h"
>
</File>
<File
- RelativePath="..\..\interpreter\RegisterFile.h"
+ RelativePath="..\..\interpreter\Register.h"
>
</File>
<File
@@ -2326,6 +2354,18 @@ >
</File>
<File
+ RelativePath="..\..\heap\CopyVisitor.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\heap\CopyVisitor.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\heap\CopyVisitorInlineMethods.h"
+ >
+ </File>
+ <File
RelativePath="..\..\heap\DFGCodeBlocks.cpp"
>
</File>
@@ -2422,6 +2462,14 @@ >
</File>
<File
+ RelativePath="..\..\heap\GCThread.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\heap\GCThread.h"
+ >
+ </File>
+ <File
RelativePath="..\..\heap\GCThreadSharedData.cpp"
>
</File>
@@ -2445,6 +2493,14 @@ RelativePath="..\..\heap\HeapRootVisitor.h"
>
</File>
+ <File
+ RelativePath="..\..\heap\HeapStatistics.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\heap\HeapStatistics.h"
+ >
+ </File>
<File
RelativePath="..\..\heap\Local.h"
>
diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj index 7c5ebaded..28c2746dd 100644 --- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj +++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj @@ -76,6 +76,7 @@ 0F0CD4C215F1A6070032F1C0 /* PutDirectIndexMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F0CD4C415F6B6BB0032F1C0 /* SparseArrayValueMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F0CD4C315F6B6B50032F1C0 /* SparseArrayValueMap.cpp */; }; 0F0FC45A14BD15F500B81154 /* LLIntCallLinkInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */; }; 0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F16015D156198C900C2587C /* DFGArgumentsSimplificationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */; }; 0F16015E156198C900C2587C /* DFGArgumentsSimplificationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -87,6 +88,7 @@ 0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27914BE727300ADC64B /* CodeSpecializationKind.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F2BDC15151C5D4D00CD8910 /* DFGFixupPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */; }; 0F2BDC16151C5D4F00CD8910 /* DFGFixupPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F2BDC21151E803B00CD8910 /* DFGInsertionSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -127,6 +129,8 @@ 0F4680D314BBD16700BFE272 /* LLIntData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680CF14BBB3D100BFE272 /* LLIntData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F4680D414BBD24900BFE272 /* HostCallReturnValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */; }; 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */; }; + 0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F55F0F114D1063600AC7649 /* AbstractPC.cpp */; }; 0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F55F0F214D1063600AC7649 /* AbstractPC.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F56A1D315000F35002992B1 /* ExecutionCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F56A1D115000F31002992B1 /* ExecutionCounter.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -163,6 +167,7 @@ 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F7B294C14C3CD43007C3DB1 /* DFGByteCodeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC0977E1469EBC400CF2442 /* DFGCommon.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F8023E91613832300A0BA45 /* ByValInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F919D0C157EE09F004A4E7D /* JSSymbolTableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */; }; 0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */; }; @@ -231,6 +236,8 @@ 0FD82E86141F3FF100179C94 /* SpeculatedType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */; }; 0FE228ED1436AB2700196C48 /* Options.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE228EB1436AB2300196C48 /* Options.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0FE228EE1436AB2C00196C48 /* Options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Options.cpp */; }; + 0FEB3ECD16237F4D00AB67AD /* TypedArrayDescriptor.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */; }; 0FF42731158EBD54004CB9FF /* Disassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF4272F158EBD44004CB9FF /* Disassembler.h */; settings = {ATTRIBUTES = (Private, ); }; }; 0FF42732158EBD58004CB9FF /* UDis86Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FF42730158EBD44004CB9FF /* UDis86Disassembler.cpp */; }; 0FF42740158EBE8B004CB9FF /* udis86_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = 0FF42734158EBD94004CB9FF /* udis86_decode.c */; }; @@ -277,7 +284,7 @@ 14280823107EC02C0013E7B2 /* Debugger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A8580255597D01FF60F7 /* Debugger.cpp */; }; 1428082D107EC0570013E7B2 /* CallData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA62DFE0E2826230004F30D /* CallData.cpp */; }; 1428082E107EC0570013E7B2 /* ConstructData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCA62DFF0E2826310004F30D /* ConstructData.cpp */; }; - 1428083A107EC0750013E7B2 /* RegisterFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D85B0ED218E900B89619 /* RegisterFile.cpp */; }; + 1428083A107EC0750013E7B2 /* JSStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D85B0ED218E900B89619 /* JSStack.cpp */; }; 14280841107EC0930013E7B2 /* RegExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A87D0255597D01FF60F7 /* RegExp.cpp */; }; 14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD202BD0E1706A7002C7E82 /* RegExpConstructor.cpp */; }; 14280843107EC0930013E7B2 /* RegExpObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A87B0255597D01FF60F7 /* RegExpObject.cpp */; }; @@ -439,10 +446,11 @@ 860161E40F3A83C100F84710 /* MacroAssemblerX86.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E00F3A83C100F84710 /* MacroAssemblerX86.h */; settings = {ATTRIBUTES = (Private, ); }; }; 860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */; settings = {ATTRIBUTES = (Private, ); }; }; 860161E60F3A83C100F84710 /* MacroAssemblerX86Common.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 8604F505143CE1C200B295F5 /* JSGlobalThis.h in Headers */ = {isa = PBXBuildFile; fileRef = 8604F503143CE1C100B295F5 /* JSGlobalThis.h */; settings = {ATTRIBUTES = (Private, ); }; }; 860BD801148EA6F200112B2F /* Intrinsic.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BF642A148DB2B5004DE36A /* Intrinsic.h */; settings = {ATTRIBUTES = (Private, ); }; }; 8612E4CD152389EC00C836BE /* MatchResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 8612E4CB1522918400C836BE /* MatchResult.h */; settings = {ATTRIBUTES = (Private, ); }; }; 86158AB3155C8B4000B45C9C /* PropertyName.h in Headers */ = {isa = PBXBuildFile; fileRef = 86158AB2155C8B3F00B45C9C /* PropertyName.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 862553D116136DA9009F17D0 /* JSProxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 862553CE16136AA5009F17D0 /* JSProxy.cpp */; }; + 862553D216136E1A009F17D0 /* JSProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 862553CF16136AA5009F17D0 /* JSProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; 863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; }; 863C6D9C1521111A00585E4E /* YarrCanonicalizeUCS2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */; }; 8642C510151C06A90046D4EF /* RegExpCachedResult.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86F75EFB151C062F007C9BA3 /* RegExpCachedResult.cpp */; }; @@ -663,7 +671,7 @@ BC18C45A0E16F5CD00B34460 /* RegExp.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87E0255597D01FF60F7 /* RegExp.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */ = {isa = PBXBuildFile; fileRef = F692A87C0255597D01FF60F7 /* RegExpObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC18C45D0E16F5CD00B34460 /* Register.h in Headers */ = {isa = PBXBuildFile; fileRef = 149B24FF0D8AF6D1009CB8C7 /* Register.h */; settings = {ATTRIBUTES = (Private, ); }; }; - BC18C45E0E16F5CD00B34460 /* RegisterFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D792640DAA03FB001A9F05 /* RegisterFile.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BC18C45E0E16F5CD00B34460 /* JSStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D792640DAA03FB001A9F05 /* JSStack.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC18C4630E16F5CD00B34460 /* SourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E866ED0DD59AFA00A2B2A1 /* SourceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC18C4640E16F5CD00B34460 /* SourceCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 65E866EE0DD59AFA00A2B2A1 /* SourceCode.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC18C4660E16F5CD00B34460 /* StringConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = BC18C3C10E16EE3300B34460 /* StringConstructor.h */; }; @@ -680,7 +688,6 @@ BC3046070E1F497F003232CF /* Error.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3046060E1F497F003232CF /* Error.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC3135640F302FA3003DFD3A /* DebuggerActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = BC3135620F302FA3003DFD3A /* DebuggerActivation.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC3135650F302FA3003DFD3A /* DebuggerActivation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3135630F302FA3003DFD3A /* DebuggerActivation.cpp */; }; - BC3C4CA01458F5450025FB62 /* JSGlobalThis.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC3C4C9F1458F5450025FB62 /* JSGlobalThis.cpp */; }; BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */; }; BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = BC87CDB810712ACA000614CF /* JSONObject.lut.h */; }; @@ -705,11 +712,19 @@ C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; C21122E315DD9AB300790E3A /* MarkStackInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = C21122E015DD9AB300790E3A /* MarkStackInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; C2160FE715F7E95E00942DFC /* SlotVisitorInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FCB408515C0A3C30048932B /* SlotVisitorInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2239D1216262BDD005AC5FD /* CopyVisitor.cpp */; }; + C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */ = {isa = PBXBuildFile; fileRef = C2239D1316262BDD005AC5FD /* CopyVisitor.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C2239D1916262BDD005AC5FD /* CopyVisitorInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = C2239D1416262BDD005AC5FD /* CopyVisitorInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2239D1516262BDD005AC5FD /* GCThread.cpp */; }; + C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */ = {isa = PBXBuildFile; fileRef = C2239D1616262BDD005AC5FD /* GCThread.h */; }; C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C225494215F7DBAA0065E898 /* SlotVisitor.cpp */; }; C22B31B9140577D700DB475A /* SamplingCounter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F77008E1402FDD60078EB39 /* SamplingCounter.h */; settings = {ATTRIBUTES = (Private, ); }; }; C240305514B404E60079EB64 /* CopiedSpace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C240305314B404C90079EB64 /* CopiedSpace.cpp */; }; + C24D31E2161CD695002AA4DB /* HeapStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */; }; + C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = C24D31E1161CD695002AA4DB /* HeapStatistics.h */; settings = {ATTRIBUTES = (Private, ); }; }; C25F8BCD157544A900245B71 /* IncrementalSweeper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */; }; C25F8BCE157544A900245B71 /* IncrementalSweeper.h in Headers */ = {isa = PBXBuildFile; fileRef = C25F8BCC157544A900245B71 /* IncrementalSweeper.h */; settings = {ATTRIBUTES = (Private, ); }; }; + C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */ = {isa = PBXBuildFile; fileRef = C2A7F687160432D400F76B98 /* JSDestructibleObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */; }; C2C8D02D14A3C6E000578E65 /* CopiedSpaceInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlineMethods.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -845,6 +860,7 @@ 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutDirectIndexMode.h; sourceTree = "<group>"; }; 0F0CD4C315F6B6B50032F1C0 /* SparseArrayValueMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SparseArrayValueMap.cpp; sourceTree = "<group>"; }; 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntCallLinkInfo.h; sourceTree = "<group>"; }; + 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IndexingType.cpp; sourceTree = "<group>"; }; 0F15F15D14B7A73A005DE37D /* CommonSlowPaths.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonSlowPaths.h; sourceTree = "<group>"; }; 0F16015A156198BF00C2587C /* DFGArgumentsSimplificationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArgumentsSimplificationPhase.cpp; path = dfg/DFGArgumentsSimplificationPhase.cpp; sourceTree = "<group>"; }; 0F16015B156198BF00C2587C /* DFGArgumentsSimplificationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArgumentsSimplificationPhase.h; path = dfg/DFGArgumentsSimplificationPhase.h; sourceTree = "<group>"; }; @@ -857,6 +873,7 @@ 0F21C27A14BE727300ADC64B /* ExecutionHarness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionHarness.h; sourceTree = "<group>"; }; 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BytecodeConventions.h; sourceTree = "<group>"; }; 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; }; + 0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCallArrayAllocatorSlowPathGenerator.h; path = dfg/DFGCallArrayAllocatorSlowPathGenerator.h; sourceTree = "<group>"; }; 0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGFixupPhase.cpp; path = dfg/DFGFixupPhase.cpp; sourceTree = "<group>"; }; 0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGFixupPhase.h; path = dfg/DFGFixupPhase.h; sourceTree = "<group>"; }; 0F2BDC1F151E803800CD8910 /* DFGInsertionSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGInsertionSet.h; path = dfg/DFGInsertionSet.h; sourceTree = "<group>"; }; @@ -898,6 +915,8 @@ 0F4680CF14BBB3D100BFE272 /* LLIntData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntData.h; path = llint/LLIntData.h; sourceTree = "<group>"; }; 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HostCallReturnValue.cpp; sourceTree = "<group>"; }; 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HostCallReturnValue.h; sourceTree = "<group>"; }; + 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialPointer.cpp; sourceTree = "<group>"; }; + 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpecialPointer.h; sourceTree = "<group>"; }; 0F55F0F114D1063600AC7649 /* AbstractPC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AbstractPC.cpp; sourceTree = "<group>"; }; 0F55F0F214D1063600AC7649 /* AbstractPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AbstractPC.h; sourceTree = "<group>"; }; 0F56A1D115000F31002992B1 /* ExecutionCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutionCounter.h; sourceTree = "<group>"; }; @@ -933,6 +952,7 @@ 0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = "<group>"; }; 0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; }; 0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCCallHelpers.h; path = dfg/DFGCCallHelpers.h; sourceTree = "<group>"; }; + 0F8023E91613832300A0BA45 /* ByValInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByValInfo.h; sourceTree = "<group>"; }; 0F919D09157EE09D004A4E7D /* JSSymbolTableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSymbolTableObject.cpp; sourceTree = "<group>"; }; 0F919D0A157EE09D004A4E7D /* JSSymbolTableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSymbolTableObject.h; sourceTree = "<group>"; }; 0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSegmentedVariableObject.cpp; sourceTree = "<group>"; }; @@ -1004,6 +1024,8 @@ 0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpeculatedType.cpp; sourceTree = "<group>"; }; 0FE228EA1436AB2300196C48 /* Options.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Options.cpp; sourceTree = "<group>"; }; 0FE228EB1436AB2300196C48 /* Options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Options.h; sourceTree = "<group>"; }; + 0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayDescriptor.h; sourceTree = "<group>"; }; + 0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssembler.cpp; sourceTree = "<group>"; }; 0FF4272F158EBD44004CB9FF /* Disassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Disassembler.h; path = disassembler/Disassembler.h; sourceTree = "<group>"; }; 0FF42730158EBD44004CB9FF /* UDis86Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UDis86Disassembler.cpp; path = disassembler/UDis86Disassembler.cpp; sourceTree = "<group>"; }; 0FF42734158EBD94004CB9FF /* udis86_decode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = udis86_decode.c; path = disassembler/udis86/udis86_decode.c; sourceTree = "<group>"; }; @@ -1048,7 +1070,7 @@ 142711380A460BBB0080EEEA /* JSBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSBase.h; sourceTree = "<group>"; }; 1429D77B0ED20D7300B89619 /* Interpreter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Interpreter.h; sourceTree = "<group>"; }; 1429D7D30ED2128200B89619 /* Interpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Interpreter.cpp; sourceTree = "<group>"; }; - 1429D85B0ED218E900B89619 /* RegisterFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterFile.cpp; sourceTree = "<group>"; }; + 1429D85B0ED218E900B89619 /* JSStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStack.cpp; sourceTree = "<group>"; }; 1429D8770ED21ACD00B89619 /* ExceptionHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExceptionHelpers.cpp; sourceTree = "<group>"; }; 1429D8830ED21C3D00B89619 /* SamplingTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingTool.cpp; sourceTree = "<group>"; }; 1429D8840ED21C3D00B89619 /* SamplingTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingTool.h; sourceTree = "<group>"; }; @@ -1136,7 +1158,7 @@ 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMap.h; sourceTree = "<group>"; }; 14D2F3D8139F4BE200491031 /* MarkedSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedSpace.cpp; sourceTree = "<group>"; }; 14D2F3D9139F4BE200491031 /* MarkedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpace.h; sourceTree = "<group>"; }; - 14D792640DAA03FB001A9F05 /* RegisterFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterFile.h; sourceTree = "<group>"; }; + 14D792640DAA03FB001A9F05 /* JSStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStack.h; sourceTree = "<group>"; }; 14D857740A4696C80032146C /* testapi.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = testapi.js; path = API/tests/testapi.js; sourceTree = "<group>"; }; 14DA818E0D99FD2000B0A4FB /* JSActivation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSActivation.h; sourceTree = "<group>"; }; 14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSActivation.cpp; sourceTree = "<group>"; }; @@ -1200,9 +1222,10 @@ 8603CEF214C7546400AE59E3 /* CodeProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeProfiling.cpp; sourceTree = "<group>"; }; 8603CEF314C7546400AE59E3 /* CodeProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeProfiling.h; sourceTree = "<group>"; }; 8604F4F2143A6C4400B295F5 /* ChangeLog */ = {isa = PBXFileReference; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; }; - 8604F503143CE1C100B295F5 /* JSGlobalThis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalThis.h; sourceTree = "<group>"; }; 8612E4CB1522918400C836BE /* MatchResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MatchResult.h; sourceTree = "<group>"; }; 86158AB2155C8B3F00B45C9C /* PropertyName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PropertyName.h; sourceTree = "<group>"; }; + 862553CE16136AA5009F17D0 /* JSProxy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSProxy.cpp; sourceTree = "<group>"; }; + 862553CF16136AA5009F17D0 /* JSProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSProxy.h; sourceTree = "<group>"; }; 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerCodeRef.h; sourceTree = "<group>"; }; 863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrCanonicalizeUCS2.cpp; path = yarr/YarrCanonicalizeUCS2.cpp; sourceTree = "<group>"; }; 863C6D991521111200585E4E /* YarrCanonicalizeUCS2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrCanonicalizeUCS2.h; path = yarr/YarrCanonicalizeUCS2.h; sourceTree = "<group>"; }; @@ -1437,7 +1460,6 @@ BC3135630F302FA3003DFD3A /* DebuggerActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DebuggerActivation.cpp; sourceTree = "<group>"; }; BC337BDE0E1AF0B80076918A /* GetterSetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetterSetter.h; sourceTree = "<group>"; }; BC337BEA0E1B00CB0076918A /* Error.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Error.cpp; sourceTree = "<group>"; }; - BC3C4C9F1458F5450025FB62 /* JSGlobalThis.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalThis.cpp; sourceTree = "<group>"; }; BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClassInfo.h; sourceTree = "<group>"; }; BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObjectFunctions.cpp; sourceTree = "<group>"; }; BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObjectFunctions.h; sourceTree = "<group>"; }; @@ -1479,10 +1501,18 @@ C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThreadSharedData.cpp; sourceTree = "<group>"; }; C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThreadSharedData.h; sourceTree = "<group>"; }; C21122E015DD9AB300790E3A /* MarkStackInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStackInlineMethods.h; sourceTree = "<group>"; }; + C2239D1216262BDD005AC5FD /* CopyVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CopyVisitor.cpp; sourceTree = "<group>"; }; + C2239D1316262BDD005AC5FD /* CopyVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyVisitor.h; sourceTree = "<group>"; }; + C2239D1416262BDD005AC5FD /* CopyVisitorInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyVisitorInlineMethods.h; sourceTree = "<group>"; }; + C2239D1516262BDD005AC5FD /* GCThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCThread.cpp; sourceTree = "<group>"; }; + C2239D1616262BDD005AC5FD /* GCThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCThread.h; sourceTree = "<group>"; }; C225494215F7DBAA0065E898 /* SlotVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SlotVisitor.cpp; sourceTree = "<group>"; }; C240305314B404C90079EB64 /* CopiedSpace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CopiedSpace.cpp; sourceTree = "<group>"; }; + C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapStatistics.cpp; sourceTree = "<group>"; }; + C24D31E1161CD695002AA4DB /* HeapStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapStatistics.h; sourceTree = "<group>"; }; C25F8BCB157544A900245B71 /* IncrementalSweeper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IncrementalSweeper.cpp; sourceTree = "<group>"; }; C25F8BCC157544A900245B71 /* IncrementalSweeper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IncrementalSweeper.h; sourceTree = "<group>"; }; + C2A7F687160432D400F76B98 /* JSDestructibleObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDestructibleObject.h; sourceTree = "<group>"; }; C2B916C114DA014E00CBAC86 /* MarkedAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedAllocator.h; sourceTree = "<group>"; }; C2B916C414DA040C00CBAC86 /* MarkedAllocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkedAllocator.cpp; sourceTree = "<group>"; }; C2C8D02B14A3C6B200578E65 /* CopiedSpaceInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopiedSpaceInlineMethods.h; sourceTree = "<group>"; }; @@ -1757,8 +1787,8 @@ 1429D7D30ED2128200B89619 /* Interpreter.cpp */, 1429D77B0ED20D7300B89619 /* Interpreter.h */, 149B24FF0D8AF6D1009CB8C7 /* Register.h */, - 1429D85B0ED218E900B89619 /* RegisterFile.cpp */, - 14D792640DAA03FB001A9F05 /* RegisterFile.h */, + 1429D85B0ED218E900B89619 /* JSStack.cpp */, + 14D792640DAA03FB001A9F05 /* JSStack.h */, ); path = interpreter; sourceTree = "<group>"; @@ -1809,6 +1839,13 @@ 142E312A134FF0A600AFADB5 /* heap */ = { isa = PBXGroup; children = ( + C2239D1216262BDD005AC5FD /* CopyVisitor.cpp */, + C2239D1316262BDD005AC5FD /* CopyVisitor.h */, + C2239D1416262BDD005AC5FD /* CopyVisitorInlineMethods.h */, + C2239D1516262BDD005AC5FD /* GCThread.cpp */, + C2239D1616262BDD005AC5FD /* GCThread.h */, + C24D31E0161CD695002AA4DB /* HeapStatistics.cpp */, + C24D31E1161CD695002AA4DB /* HeapStatistics.h */, C225494215F7DBAA0065E898 /* SlotVisitor.cpp */, C21122DE15DD9AB300790E3A /* GCThreadSharedData.cpp */, C21122DF15DD9AB300790E3A /* GCThreadSharedData.h */, @@ -2043,27 +2080,16 @@ 7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = { isa = PBXGroup; children = ( - 0F0CD4C315F6B6B50032F1C0 /* SparseArrayValueMap.cpp */, - 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */, - 0FB7F38915ED8E3800F167B2 /* ArrayConventions.h */, - 0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */, - 0FB7F38B15ED8E3800F167B2 /* Butterfly.h */, - 0FB7F38C15ED8E3800F167B2 /* ButterflyInlineMethods.h */, - 0FB7F38D15ED8E3800F167B2 /* IndexingHeader.h */, - 0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlineMethods.h */, - 0FB7F38F15ED8E3800F167B2 /* IndexingType.h */, - 0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */, - 0FB7F39115ED8E3800F167B2 /* Reject.h */, - 0FB7F39215ED8E3800F167B2 /* SparseArrayValueMap.h */, - C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */, BCF605110E203EF800B9A64D /* ArgList.cpp */, BCF605120E203EF800B9A64D /* ArgList.h */, BC257DE50E1F51C50016B6C9 /* Arguments.cpp */, BC257DE60E1F51C50016B6C9 /* Arguments.h */, BC7952060E15E8A800A898AB /* ArrayConstructor.cpp */, BC7952070E15E8A800A898AB /* ArrayConstructor.h */, + 0FB7F38915ED8E3800F167B2 /* ArrayConventions.h */, F692A84D0255597D01FF60F7 /* ArrayPrototype.cpp */, F692A84E0255597D01FF60F7 /* ArrayPrototype.h */, + 0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */, 147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */, 866739D013BFDE710023D87C /* BigInteger.h */, BC7952320E15EB5600A898AB /* BooleanConstructor.cpp */, @@ -2072,6 +2098,8 @@ 704FD35305697E6D003DBED9 /* BooleanObject.h */, BC7952340E15EB5600A898AB /* BooleanPrototype.cpp */, BC7952350E15EB5600A898AB /* BooleanPrototype.h */, + 0FB7F38B15ED8E3800F167B2 /* Butterfly.h */, + 0FB7F38C15ED8E3800F167B2 /* ButterflyInlineMethods.h */, 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */, BCA62DFE0E2826230004F30D /* CallData.cpp */, 145C507F0D9DF63B0088F6B9 /* CallData.h */, @@ -2116,6 +2144,10 @@ BC337BDE0E1AF0B80076918A /* GetterSetter.h */, 933A349D038AE80F008635CE /* Identifier.cpp */, 933A349A038AE7C6008635CE /* Identifier.h */, + 0FB7F38D15ED8E3800F167B2 /* IndexingHeader.h */, + 0FB7F38E15ED8E3800F167B2 /* IndexingHeaderInlineMethods.h */, + 0F13E04C16164A1B00DC8DE7 /* IndexingType.cpp */, + 0FB7F38F15ED8E3800F167B2 /* IndexingType.h */, E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */, E178633F0D9BEC0000D74E75 /* InitializeThreading.h */, BC9BB95B0E19680600DF8855 /* InternalFunction.cpp */, @@ -2131,6 +2163,7 @@ BC1167D80E19BCC9008066DD /* JSCell.h */, 9788FC221471AD0C0068CE2D /* JSDateMath.cpp */, 9788FC231471AD0C0068CE2D /* JSDateMath.h */, + C2A7F687160432D400F76B98 /* JSDestructibleObject.h */, A7B4ACAE1484C9CE00B38A36 /* JSExportMacros.h */, F692A85E0255597D01FF60F7 /* JSFunction.cpp */, F692A85F0255597D01FF60F7 /* JSFunction.h */, @@ -2140,8 +2173,6 @@ A8E894330CD0603F00367179 /* JSGlobalObject.h */, BC756FC60E2031B200DE7D12 /* JSGlobalObjectFunctions.cpp */, BC756FC70E2031B200DE7D12 /* JSGlobalObjectFunctions.h */, - BC3C4C9F1458F5450025FB62 /* JSGlobalThis.cpp */, - 8604F503143CE1C100B295F5 /* JSGlobalThis.h */, 65EA4C99092AF9E20093D800 /* JSLock.cpp */, 65EA4C9A092AF9E20093D800 /* JSLock.h */, 14874ADF15EBDE4A002E3587 /* JSNameScope.cpp */, @@ -2154,6 +2185,8 @@ A7F9935D0FD7325100A0B2D0 /* JSONObject.h */, A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */, A727FF650DA3053B00E548D7 /* JSPropertyNameIterator.h */, + 862553CE16136AA5009F17D0 /* JSProxy.cpp */, + 862553CF16136AA5009F17D0 /* JSProxy.h */, 14874AE115EBDE4A002E3587 /* JSScope.cpp */, 14874AE215EBDE4A002E3587 /* JSScope.h */, 0F919D0E157F3327004A4E7D /* JSSegmentedVariableObject.cpp */, @@ -2220,7 +2253,9 @@ 0FF7168A15A3B231008F5DAA /* PropertyOffset.h */, 65621E6B089E859700760F35 /* PropertySlot.cpp */, 65621E6C089E859700760F35 /* PropertySlot.h */, + 0FB7F39015ED8E3800F167B2 /* PropertyStorage.h */, 65C02FBB0637462A003E7EE6 /* Protect.h */, + 0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */, 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */, F692A87D0255597D01FF60F7 /* RegExp.cpp */, F692A87E0255597D01FF60F7 /* RegExp.h */, @@ -2237,10 +2272,13 @@ F692A87C0255597D01FF60F7 /* RegExpObject.h */, BCD202BF0E1706A7002C7E82 /* RegExpPrototype.cpp */, BCD202C00E1706A7002C7E82 /* RegExpPrototype.h */, + 0FB7F39115ED8E3800F167B2 /* Reject.h */, 0F7700911402FF280078EB39 /* SamplingCounter.cpp */, 0F77008E1402FDD60078EB39 /* SamplingCounter.h */, 93303FE80E6A72B500786E6A /* SmallStrings.cpp */, 93303FEA0E6A72C000786E6A /* SmallStrings.h */, + 0F0CD4C315F6B6B50032F1C0 /* SparseArrayValueMap.cpp */, + 0FB7F39215ED8E3800F167B2 /* SparseArrayValueMap.h */, A730B6111250068F009D25B1 /* StrictEvalActivation.cpp */, A730B6101250068F009D25B1 /* StrictEvalActivation.h */, BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */, @@ -2263,10 +2301,12 @@ 14A42E3E0F4F60EE00599099 /* TimeoutChecker.h */, 5D53726D0E1C546B0021E549 /* Tracing.d */, 5D53726E0E1C54880021E549 /* Tracing.h */, + 0FEB3ECB16237F4700AB67AD /* TypedArrayDescriptor.h */, 866739D113BFDE710023D87C /* Uint16WithFraction.h */, 14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */, 1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */, A7DCB77912E3D90500911940 /* WriteBarrier.h */, + C2D58C3315912FEE0021A844 /* GCActivityCallback.cpp */, ); path = runtime; sourceTree = "<group>"; @@ -2322,20 +2362,21 @@ 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */, 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */, 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */, + 0F256C341627B0AA007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h */, + 0FD82E1E14172C2F00179C94 /* DFGCapabilities.cpp */, + 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */, 0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */, 0FFFC94B14EF909500C72532 /* DFGCFAPhase.cpp */, 0FFFC94C14EF909500C72532 /* DFGCFAPhase.h */, 0F3B3A241544C991003ED0FF /* DFGCFGSimplificationPhase.cpp */, 0F3B3A251544C991003ED0FF /* DFGCFGSimplificationPhase.h */, - 0FFFC94D14EF909500C72532 /* DFGCSEPhase.cpp */, - 0FFFC94E14EF909500C72532 /* DFGCSEPhase.h */, - 0FD82E1E14172C2F00179C94 /* DFGCapabilities.cpp */, - 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */, 0FC0977E1469EBC400CF2442 /* DFGCommon.h */, 0F3B3A17153E68EF003ED0FF /* DFGConstantFoldingPhase.cpp */, 0F3B3A18153E68EF003ED0FF /* DFGConstantFoldingPhase.h */, 0FC0979D146B271E00CF2442 /* DFGCorrectableJumpPoint.cpp */, 0FC0979A146A772000CF2442 /* DFGCorrectableJumpPoint.h */, + 0FFFC94D14EF909500C72532 /* DFGCSEPhase.cpp */, + 0FFFC94E14EF909500C72532 /* DFGCSEPhase.h */, 0FF427611591A1C9004CB9FF /* DFGDisassembler.cpp */, 0FF427621591A1C9004CB9FF /* DFGDisassembler.h */, 0FD81ACF154FB4EB00983E72 /* DFGDominators.cpp */, @@ -2343,9 +2384,10 @@ 0F1E3A441534CBAD000F9456 /* DFGDoubleFormatState.h */, 0FD3C82014115CF800FD81CB /* DFGDriver.cpp */, 0FD3C82214115D0E00FD81CB /* DFGDriver.h */, - 86AE6C4B136A11E400963012 /* DFGFPRInfo.h */, + 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */, 0F2BDC12151C5D4A00CD8910 /* DFGFixupPhase.cpp */, 0F2BDC13151C5D4A00CD8910 /* DFGFixupPhase.h */, + 86AE6C4B136A11E400963012 /* DFGFPRInfo.h */, 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */, 86AE6C4C136A11E400963012 /* DFGGPRInfo.h */, 86EC9DB71328DF82002B2AD7 /* DFGGraph.cpp */, @@ -2360,7 +2402,6 @@ 0FA581B7150E952A00B9A2D9 /* DFGNodeFlags.cpp */, 0FA581B8150E952A00B9A2D9 /* DFGNodeFlags.h */, 0FA581B9150E952A00B9A2D9 /* DFGNodeType.h */, - 0F66E16914DF3F1300B7B2E4 /* DFGEdge.h */, 86EC9DBF1328DF82002B2AD7 /* DFGOperations.cpp */, 86EC9DC01328DF82002B2AD7 /* DFGOperations.h */, 0FD82E52141DAEDE00179C94 /* DFGOSREntry.cpp */, @@ -2392,11 +2433,11 @@ 0F63943D15C75F14006A597C /* DFGStructureCheckHoistingPhase.h */, 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */, 0FC097A0146B28C700CF2442 /* DFGThunks.h */, + 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */, + 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */, 0F2BDC3F1522801700CD8910 /* DFGValueRecoveryOverride.h */, 0F2BDC4E15228BE700CD8910 /* DFGValueSource.cpp */, 0F2BDC401522801700CD8910 /* DFGValueSource.h */, - 0F3B3A2915474FF4003ED0FF /* DFGValidate.cpp */, - 0F3B3A2A15474FF4003ED0FF /* DFGValidate.h */, 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */, 0F2BDC5015228FFA00CD8910 /* DFGVariableEvent.cpp */, 0F2BDC411522801700CD8910 /* DFGVariableEvent.h */, @@ -2448,6 +2489,7 @@ 86E116B00FE75AC800B512BC /* CodeLocation.h */, 0FF4275615914A20004CB9FF /* LinkBuffer.cpp */, 86D3B3C110159D7F002865E7 /* LinkBuffer.h */, + 0FEB3ECE16237F6700AB67AD /* MacroAssembler.cpp */, 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */, 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */, 86D3B2C210156BDE002865E7 /* MacroAssemblerARM.h */, @@ -2472,56 +2514,59 @@ children = ( 0F63945115D07051006A597C /* ArrayProfile.cpp */, 0F63945215D07051006A597C /* ArrayProfile.h */, - 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */, - 0F56A1D115000F31002992B1 /* ExecutionCounter.h */, - 0FB5467C14F5CFD3002C2989 /* MethodOfGettingAValueProfile.cpp */, - 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */, - 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */, - 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */, 0F21C27E14BEAA8000ADC64B /* BytecodeConventions.h */, - 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */, - 0F2BDC2B151FDE8B00CD8910 /* Operands.h */, - 0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */, - 0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */, - 0F9FC8C114E1B5FB00D52AE0 /* PutKind.h */, + 0F8023E91613832300A0BA45 /* ByValInfo.h */, + 0F0B83AE14BCF71400885B4F /* CallLinkInfo.cpp */, + 0F0B83AF14BCF71400885B4F /* CallLinkInfo.h */, 0F93329314CA7DC10085F3C6 /* CallLinkStatus.cpp */, 0F93329414CA7DC10085F3C6 /* CallLinkStatus.h */, - 0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */, - 0F93329614CA7DC10085F3C6 /* GetByIdStatus.h */, - 0F93329714CA7DC10085F3C6 /* MethodCallLinkStatus.cpp */, - 0F93329814CA7DC10085F3C6 /* MethodCallLinkStatus.h */, - 0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */, - 0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */, - 0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */, - 0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */, - 0F93329B14CA7DC10085F3C6 /* StructureSet.h */, 0F0B83B814BCF95B00885B4F /* CallReturnOffsetToBytecodeOffset.h */, - 0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */, - 0F0B83B214BCF85E00885B4F /* MethodCallLinkInfo.cpp */, - 0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */, - 0F0B83AE14BCF71400885B4F /* CallLinkInfo.cpp */, - 0F0B83AF14BCF71400885B4F /* CallLinkInfo.h */, - FEB63AA2159B9DA3008932A6 /* Comment.h */, - 0F0B83AC14BCF60200885B4F /* LineInfo.h */, - 0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */, - 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */, - 0F0B83A514BCF50400885B4F /* CodeType.h */, 969A07900ED1D3AE00F1F681 /* CodeBlock.cpp */, 969A07910ED1D3AE00F1F681 /* CodeBlock.h */, 0FBD7E671447998F00481315 /* CodeOrigin.h */, + 0F0B83A514BCF50400885B4F /* CodeType.h */, + FEB63AA2159B9DA3008932A6 /* Comment.h */, 0F426A4A1460CD6B00131F8F /* DataFormat.h */, 0FBC0AE41496C7C100D4FBDD /* DFGExitProfile.cpp */, 0FBC0AE51496C7C100D4FBDD /* DFGExitProfile.h */, 969A07920ED1D3AE00F1F681 /* EvalCodeCache.h */, + 0F56A1D415001CF2002992B1 /* ExecutionCounter.cpp */, + 0F56A1D115000F31002992B1 /* ExecutionCounter.h */, + 0F0B83AA14BCF5B900885B4F /* ExpressionRangeInfo.h */, + 0F93329514CA7DC10085F3C6 /* GetByIdStatus.cpp */, + 0F93329614CA7DC10085F3C6 /* GetByIdStatus.h */, + 0F0B83B614BCF8DF00885B4F /* GlobalResolveInfo.h */, + 0F0B83A814BCF55E00885B4F /* HandlerInfo.h */, 969A07930ED1D3AE00F1F681 /* Instruction.h */, BCFD8C900EEB2EE700283848 /* JumpTable.cpp */, BCFD8C910EEB2EE700283848 /* JumpTable.h */, + 0FB5467814F5C468002C2989 /* LazyOperandValueProfile.cpp */, + 0FB5467614F59AD1002C2989 /* LazyOperandValueProfile.h */, + 0F0B83AC14BCF60200885B4F /* LineInfo.h */, + 0F0FC45814BD15F100B81154 /* LLIntCallLinkInfo.h */, + 0F0B83B214BCF85E00885B4F /* MethodCallLinkInfo.cpp */, + 0F0B83B314BCF85E00885B4F /* MethodCallLinkInfo.h */, + 0F93329714CA7DC10085F3C6 /* MethodCallLinkStatus.cpp */, + 0F93329814CA7DC10085F3C6 /* MethodCallLinkStatus.h */, + 0FB5467C14F5CFD3002C2989 /* MethodOfGettingAValueProfile.cpp */, + 0FB5467A14F5C7D4002C2989 /* MethodOfGettingAValueProfile.h */, 969A07940ED1D3AE00F1F681 /* Opcode.cpp */, 969A07950ED1D3AE00F1F681 /* Opcode.h */, - 0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */, - 0FD82E4F141DAEA100179C94 /* SpeculatedType.h */, + 0F2BDC2B151FDE8B00CD8910 /* Operands.h */, + 0F9FC8BF14E1B5FB00D52AE0 /* PolymorphicPutByIdList.cpp */, + 0F9FC8C014E1B5FB00D52AE0 /* PolymorphicPutByIdList.h */, + 0F93329914CA7DC10085F3C6 /* PutByIdStatus.cpp */, + 0F93329A14CA7DC10085F3C6 /* PutByIdStatus.h */, + 0F9FC8C114E1B5FB00D52AE0 /* PutKind.h */, + 0FF4276E159275D2004CB9FF /* ResolveGlobalStatus.cpp */, + 0FF4276F159275D2004CB9FF /* ResolveGlobalStatus.h */, 1429D8830ED21C3D00B89619 /* SamplingTool.cpp */, 1429D8840ED21C3D00B89619 /* SamplingTool.h */, + 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */, + 0F5541B01613C1FB00CE3E25 /* SpecialPointer.h */, + 0FD82E84141F3FDA00179C94 /* SpeculatedType.cpp */, + 0FD82E4F141DAEA100179C94 /* SpeculatedType.h */, + 0F93329B14CA7DC10085F3C6 /* StructureSet.h */, 0F766D3615AE4A1A008F363E /* StructureStubClearingWatchpoint.cpp */, 0F766D3715AE4A1A008F363E /* StructureStubClearingWatchpoint.h */, BCCF0D0B0EF0B8A500413C8F /* StructureStubInfo.cpp */, @@ -2563,6 +2608,10 @@ 86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */, C2EAD2FC14F0249800A4B159 /* CopiedAllocator.h in Headers */, C2B916C214DA014E00CBAC86 /* MarkedAllocator.h in Headers */, + C2239D1816262BDD005AC5FD /* CopyVisitor.h in Headers */, + C2239D1916262BDD005AC5FD /* CopyVisitorInlineMethods.h in Headers */, + C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */, + C2A7F688160432D400F76B98 /* JSDestructibleObject.h in Headers */, FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */, C21122E215DD9AB300790E3A /* GCThreadSharedData.h in Headers */, C2160FE715F7E95E00942DFC /* SlotVisitorInlineMethods.h in Headers */, @@ -2686,7 +2735,6 @@ BC18C4200E16F5CD00B34460 /* JSGlobalData.h in Headers */, BC18C4210E16F5CD00B34460 /* JSGlobalObject.h in Headers */, BC756FC90E2031B200DE7D12 /* JSGlobalObjectFunctions.h in Headers */, - 8604F505143CE1C200B295F5 /* JSGlobalThis.h in Headers */, A76C51761182748D00715B05 /* JSInterfaceJIT.h in Headers */, BC18C4230E16F5CD00B34460 /* JSLock.h in Headers */, BC18C4240E16F5CD00B34460 /* JSObject.h in Headers */, @@ -2696,6 +2744,7 @@ BC87CDB910712AD4000614CF /* JSONObject.lut.h in Headers */, 9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */, BC18C4260E16F5CD00B34460 /* JSRetainPtr.h in Headers */, + BC18C45E0E16F5CD00B34460 /* JSStack.h in Headers */, BC18C4270E16F5CD00B34460 /* JSString.h in Headers */, 86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */, 2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */, @@ -2777,7 +2826,6 @@ BC18C52C0E16FCD200B34460 /* RegExpObject.lut.h in Headers */, BCD202C40E1706A7002C7E82 /* RegExpPrototype.h in Headers */, BC18C45D0E16F5CD00B34460 /* Register.h in Headers */, - BC18C45E0E16F5CD00B34460 /* RegisterFile.h in Headers */, 969A072B0ED1CE6900F1F681 /* RegisterID.h in Headers */, 86D3B3C410159D7F002865E7 /* RepatchBuffer.h in Headers */, 869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */, @@ -2950,6 +2998,12 @@ 0FB7F39D15ED8E4600F167B2 /* Reject.h in Headers */, 0FB7F39E15ED8E4600F167B2 /* SparseArrayValueMap.h in Headers */, 0F0CD4C215F1A6070032F1C0 /* PutDirectIndexMode.h in Headers */, + 0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */, + 862553D216136E1A009F17D0 /* JSProxy.h in Headers */, + 0F5541B21613C1FB00CE3E25 /* SpecialPointer.h in Headers */, + 0FEB3ECD16237F4D00AB67AD /* TypedArrayDescriptor.h in Headers */, + 0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */, + C2239D1B16262BDD005AC5FD /* GCThread.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3394,7 +3448,6 @@ E18E3A590DF9278C00D90B34 /* JSGlobalData.cpp in Sources */, 147F39D2107EC37600427A48 /* JSGlobalObject.cpp in Sources */, 14E9D17B107EC469004DDA21 /* JSGlobalObjectFunctions.cpp in Sources */, - BC3C4CA01458F5450025FB62 /* JSGlobalThis.cpp in Sources */, 14280875107EC13E0013E7B2 /* JSLock.cpp in Sources */, A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */, 147F39D4107EC37600427A48 /* JSObject.cpp in Sources */, @@ -3402,6 +3455,7 @@ A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */, 95F6E6950E5B5F970091E860 /* JSProfilerPrivate.cpp in Sources */, A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */, + 1428083A107EC0750013E7B2 /* JSStack.cpp in Sources */, 147F39D5107EC37600427A48 /* JSString.cpp in Sources */, 2600B5A6152BAAA70091EE5F /* JSStringJoiner.cpp in Sources */, 1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */, @@ -3451,7 +3505,6 @@ 14280842107EC0930013E7B2 /* RegExpConstructor.cpp in Sources */, 14280843107EC0930013E7B2 /* RegExpObject.cpp in Sources */, 14280844107EC0930013E7B2 /* RegExpPrototype.cpp in Sources */, - 1428083A107EC0750013E7B2 /* RegisterFile.cpp in Sources */, 0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */, 1429D8850ED21C3D00B89619 /* SamplingTool.cpp in Sources */, 9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */, @@ -3554,6 +3607,13 @@ 0F0CD4C415F6B6BB0032F1C0 /* SparseArrayValueMap.cpp in Sources */, FE20CE9D15F04A9500DF3430 /* LLIntCLoop.cpp in Sources */, C225494315F7DBAA0065E898 /* SlotVisitor.cpp in Sources */, + 862553D116136DA9009F17D0 /* JSProxy.cpp in Sources */, + 0F13E04E16164A1F00DC8DE7 /* IndexingType.cpp in Sources */, + 0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */, + 0FEB3ECF16237F6C00AB67AD /* MacroAssembler.cpp in Sources */, + C24D31E2161CD695002AA4DB /* HeapStatistics.cpp in Sources */, + C2239D1716262BDD005AC5FD /* CopyVisitor.cpp in Sources */, + C2239D1A16262BDD005AC5FD /* GCThread.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Source/JavaScriptCore/LLIntOffsetsExtractor.pro b/Source/JavaScriptCore/LLIntOffsetsExtractor.pro new file mode 100644 index 000000000..4a6f69a89 --- /dev/null +++ b/Source/JavaScriptCore/LLIntOffsetsExtractor.pro @@ -0,0 +1,55 @@ +# ------------------------------------------------------------------- +# Project file for the LLIntOffsetsExtractor binary, used to generate +# derived sources for JavaScriptCore. +# +# See 'Tools/qmake/README' for an overview of the build system +# ------------------------------------------------------------------- + +TEMPLATE = app +TARGET = LLIntOffsetsExtractor +DESTDIR = $$OUT_PWD + +QT = core # Needed for qglobal.h + +defineTest(addIncludePaths) { + # Just needed for include paths + include(../WTF/WTF.pri) + include(JavaScriptCore.pri) + + export(INCLUDEPATH) +} + +addIncludePaths() + +LLINT_DEPENDENCY = \ + $$PWD/llint/LowLevelInterpreter.asm \ + $$PWD/llint/LowLevelInterpreter32_64.asm \ + $$PWD/llint/LowLevelInterpreter64.asm \ + $$PWD/offlineasm/armv7.rb \ + $$PWD/offlineasm/ast.rb \ + $$PWD/offlineasm/backends.rb \ + $$PWD/offlineasm/generate_offset_extractor.rb \ + $$PWD/offlineasm/instructions.rb \ + $$PWD/offlineasm/offsets.rb \ + $$PWD/offlineasm/opt.rb \ + $$PWD/offlineasm/parser.rb \ + $$PWD/offlineasm/registers.rb \ + $$PWD/offlineasm/self_hash.rb \ + $$PWD/offlineasm/settings.rb \ + $$PWD/offlineasm/transform.rb \ + $$PWD/offlineasm/x86.rb + +INPUT_FILES = $$PWD/llint/LowLevelInterpreter.asm +llint.output = LLIntDesiredOffsets.h +llint.script = $$PWD/offlineasm/generate_offset_extractor.rb +llint.input = INPUT_FILES +llint.depends = $$LLINT_DEPENDENCY +llint.commands = ruby $$llint.script ${QMAKE_FILE_NAME} ${QMAKE_FILE_OUT} +llint.CONFIG += no_link +QMAKE_EXTRA_COMPILERS += llint + +# Compilation of this file will automatically depend on LLIntDesiredOffsets.h +# due to qmake scanning the source file for header dependencies. +SOURCES = llint/LLIntOffsetsExtractor.cpp + +mac: LIBS_PRIVATE += -framework AppKit diff --git a/Source/JavaScriptCore/Target.pri b/Source/JavaScriptCore/Target.pri index 6f063fafb..861dbc740 100644 --- a/Source/JavaScriptCore/Target.pri +++ b/Source/JavaScriptCore/Target.pri @@ -45,6 +45,7 @@ SOURCES += \ assembler/ARMAssembler.cpp \ assembler/ARMv7Assembler.cpp \ assembler/LinkBuffer.cpp \ + assembler/MacroAssembler.cpp \ assembler/MacroAssemblerARM.cpp \ assembler/MacroAssemblerSH4.cpp \ bytecode/ArrayProfile.cpp \ @@ -64,6 +65,7 @@ SOURCES += \ bytecode/PutByIdStatus.cpp \ bytecode/ResolveGlobalStatus.cpp \ bytecode/SamplingTool.cpp \ + bytecode/SpecialPointer.cpp \ bytecode/SpeculatedType.cpp \ bytecode/StructureStubClearingWatchpoint.cpp \ bytecode/StructureStubInfo.cpp \ @@ -71,6 +73,7 @@ SOURCES += \ bytecompiler/BytecodeGenerator.cpp \ bytecompiler/NodesCodegen.cpp \ heap/CopiedSpace.cpp \ + heap/CopyVisitor.cpp \ heap/ConservativeRoots.cpp \ heap/DFGCodeBlocks.cpp \ heap/WeakSet.cpp \ @@ -80,7 +83,9 @@ SOURCES += \ heap/HandleStack.cpp \ heap/BlockAllocator.cpp \ heap/GCThreadSharedData.cpp \ + heap/GCThread.cpp \ heap/Heap.cpp \ + heap/HeapStatistics.cpp \ heap/HeapTimer.cpp \ heap/IncrementalSweeper.cpp \ heap/JITStubRoutineSet.cpp \ @@ -136,7 +141,7 @@ SOURCES += \ interpreter/AbstractPC.cpp \ interpreter/CallFrame.cpp \ interpreter/Interpreter.cpp \ - interpreter/RegisterFile.cpp \ + interpreter/JSStack.cpp \ jit/ExecutableAllocatorFixedVMPool.cpp \ jit/ExecutableAllocator.cpp \ jit/HostCallReturnValue.cpp \ @@ -155,6 +160,13 @@ SOURCES += \ jit/JITStubs.cpp \ jit/JumpReplacementWatchpoint.cpp \ jit/ThunkGenerators.cpp \ + llint/LLIntCLoop.cpp \ + llint/LLIntData.cpp \ + llint/LLIntEntrypoints.cpp \ + llint/LLIntExceptions.cpp \ + llint/LLIntSlowPaths.cpp \ + llint/LLIntThunks.cpp \ + llint/LowLevelInterpreter.cpp \ parser/Lexer.cpp \ parser/Nodes.cpp \ parser/ParserArena.cpp \ @@ -191,6 +203,7 @@ SOURCES += \ runtime/GetterSetter.cpp \ runtime/Options.cpp \ runtime/Identifier.cpp \ + runtime/IndexingType.cpp \ runtime/InitializeThreading.cpp \ runtime/InternalFunction.cpp \ runtime/JSActivation.cpp \ @@ -203,7 +216,7 @@ SOURCES += \ runtime/JSGlobalData.cpp \ runtime/JSGlobalObject.cpp \ runtime/JSGlobalObjectFunctions.cpp \ - runtime/JSGlobalThis.cpp \ + runtime/JSProxy.cpp \ runtime/JSLock.cpp \ runtime/JSNotAnObject.cpp \ runtime/JSObject.cpp \ diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h index e6a9df994..c75adb7e9 100644 --- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h +++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h @@ -261,6 +261,50 @@ public: }; + // TrustedImm64: + // + // A 64bit immediate operand to an instruction - this is wrapped in a + // class requiring explicit construction in order to prevent RegisterIDs + // (which are implemented as an enum) from accidentally being passed as + // immediate values. + struct TrustedImm64 { + TrustedImm64() { } + + explicit TrustedImm64(int64_t value) + : m_value(value) + { + } + +#if CPU(X86_64) + explicit TrustedImm64(TrustedImmPtr ptr) + : m_value(ptr.asIntptr()) + { + } +#endif + + int64_t m_value; + }; + + struct Imm64 : +#if ENABLE(JIT_CONSTANT_BLINDING) + private TrustedImm64 +#else + public TrustedImm64 +#endif + { + explicit Imm64(int64_t value) + : TrustedImm64(value) + { + } +#if CPU(X86_64) + explicit Imm64(TrustedImmPtr ptr) + : TrustedImm64(ptr) + { + } +#endif + const TrustedImm64& asTrustedImm64() const { return *this; } + }; + // Section 2: MacroAssembler code buffer handles // // The following types are used to reference items in the code buffer @@ -564,7 +608,7 @@ public: m_jumps.append(jump); } - void append(JumpList& other) + void append(const JumpList& other) { m_jumps.append(other.m_jumps.begin(), other.m_jumps.size()); } @@ -579,7 +623,7 @@ public: m_jumps.clear(); } - const JumpVector& jumps() { return m_jumps; } + const JumpVector& jumps() const { return m_jumps; } private: JumpVector m_jumps; diff --git a/Source/JavaScriptCore/assembler/MIPSAssembler.h b/Source/JavaScriptCore/assembler/MIPSAssembler.h index d3f8af996..30f172fb8 100644 --- a/Source/JavaScriptCore/assembler/MIPSAssembler.h +++ b/Source/JavaScriptCore/assembler/MIPSAssembler.h @@ -227,20 +227,17 @@ public: void addiu(RegisterID rt, RegisterID rs, int imm) { - emitInst(0x24000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (imm & 0xffff)); + emitInst(0x24000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff)); } void addu(RegisterID rd, RegisterID rs, RegisterID rt) { - emitInst(0x00000021 | (rd << OP_SH_RD) | (rs << OP_SH_RS) - | (rt << OP_SH_RT)); + emitInst(0x00000021 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT)); } void subu(RegisterID rd, RegisterID rs, RegisterID rt) { - emitInst(0x00000023 | (rd << OP_SH_RD) | (rs << OP_SH_RS) - | (rt << OP_SH_RT)); + emitInst(0x00000023 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT)); } void mult(RegisterID rs, RegisterID rt) @@ -266,8 +263,7 @@ public: void mul(RegisterID rd, RegisterID rs, RegisterID rt) { #if WTF_MIPS_ISA_AT_LEAST(32) - emitInst(0x70000002 | (rd << OP_SH_RD) | (rs << OP_SH_RS) - | (rt << OP_SH_RT)); + emitInst(0x70000002 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT)); #else mult(rs, rt); mflo(rd); @@ -276,151 +272,139 @@ public: void andInsn(RegisterID rd, RegisterID rs, RegisterID rt) { - emitInst(0x00000024 | (rd << OP_SH_RD) | (rs << OP_SH_RS) - | (rt << OP_SH_RT)); + emitInst(0x00000024 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT)); } void andi(RegisterID rt, RegisterID rs, int imm) { - emitInst(0x30000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (imm & 0xffff)); + emitInst(0x30000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff)); } void nor(RegisterID rd, RegisterID rs, RegisterID rt) { - emitInst(0x00000027 | (rd << OP_SH_RD) | (rs << OP_SH_RS) - | (rt << OP_SH_RT)); + emitInst(0x00000027 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT)); } void orInsn(RegisterID rd, RegisterID rs, RegisterID rt) { - emitInst(0x00000025 | (rd << OP_SH_RD) | (rs << OP_SH_RS) - | (rt << OP_SH_RT)); + emitInst(0x00000025 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT)); } void ori(RegisterID rt, RegisterID rs, int imm) { - emitInst(0x34000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (imm & 0xffff)); + emitInst(0x34000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff)); } void xorInsn(RegisterID rd, RegisterID rs, RegisterID rt) { - emitInst(0x00000026 | (rd << OP_SH_RD) | (rs << OP_SH_RS) - | (rt << OP_SH_RT)); + emitInst(0x00000026 | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT)); } void xori(RegisterID rt, RegisterID rs, int imm) { - emitInst(0x38000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (imm & 0xffff)); + emitInst(0x38000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff)); } void slt(RegisterID rd, RegisterID rs, RegisterID rt) { - emitInst(0x0000002a | (rd << OP_SH_RD) | (rs << OP_SH_RS) - | (rt << OP_SH_RT)); + emitInst(0x0000002a | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT)); } void sltu(RegisterID rd, RegisterID rs, RegisterID rt) { - emitInst(0x0000002b | (rd << OP_SH_RD) | (rs << OP_SH_RS) - | (rt << OP_SH_RT)); + emitInst(0x0000002b | (rd << OP_SH_RD) | (rs << OP_SH_RS) | (rt << OP_SH_RT)); } void sltiu(RegisterID rt, RegisterID rs, int imm) { - emitInst(0x2c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (imm & 0xffff)); + emitInst(0x2c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (imm & 0xffff)); } void sll(RegisterID rd, RegisterID rt, int shamt) { - emitInst(0x00000000 | (rd << OP_SH_RD) | (rt << OP_SH_RT) - | ((shamt & 0x1f) << OP_SH_SHAMT)); + emitInst(0x00000000 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | ((shamt & 0x1f) << OP_SH_SHAMT)); } void sllv(RegisterID rd, RegisterID rt, int rs) { - emitInst(0x00000004 | (rd << OP_SH_RD) | (rt << OP_SH_RT) - | (rs << OP_SH_RS)); + emitInst(0x00000004 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | (rs << OP_SH_RS)); } void sra(RegisterID rd, RegisterID rt, int shamt) { - emitInst(0x00000003 | (rd << OP_SH_RD) | (rt << OP_SH_RT) - | ((shamt & 0x1f) << OP_SH_SHAMT)); + emitInst(0x00000003 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | ((shamt & 0x1f) << OP_SH_SHAMT)); } void srav(RegisterID rd, RegisterID rt, RegisterID rs) { - emitInst(0x00000007 | (rd << OP_SH_RD) | (rt << OP_SH_RT) - | (rs << OP_SH_RS)); + emitInst(0x00000007 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | (rs << OP_SH_RS)); } void srl(RegisterID rd, RegisterID rt, int shamt) { - emitInst(0x00000002 | (rd << OP_SH_RD) | (rt << OP_SH_RT) - | ((shamt & 0x1f) << OP_SH_SHAMT)); + emitInst(0x00000002 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | ((shamt & 0x1f) << OP_SH_SHAMT)); } void srlv(RegisterID rd, RegisterID rt, RegisterID rs) { - emitInst(0x00000006 | (rd << OP_SH_RD) | (rt << OP_SH_RT) - | (rs << OP_SH_RS)); + emitInst(0x00000006 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | (rs << OP_SH_RS)); + } + + void lb(RegisterID rt, RegisterID rs, int offset) + { + emitInst(0x80000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff)); + loadDelayNop(); } void lbu(RegisterID rt, RegisterID rs, int offset) { - emitInst(0x90000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0x90000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff)); loadDelayNop(); } void lw(RegisterID rt, RegisterID rs, int offset) { - emitInst(0x8c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0x8c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff)); loadDelayNop(); } void lwl(RegisterID rt, RegisterID rs, int offset) { - emitInst(0x88000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0x88000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff)); loadDelayNop(); } void lwr(RegisterID rt, RegisterID rs, int offset) { - emitInst(0x98000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0x98000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff)); + loadDelayNop(); + } + + void lh(RegisterID rt, RegisterID rs, int offset) + { + emitInst(0x84000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff)); loadDelayNop(); } void lhu(RegisterID rt, RegisterID rs, int offset) { - emitInst(0x94000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0x94000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff)); loadDelayNop(); } void sb(RegisterID rt, RegisterID rs, int offset) { - emitInst(0xa0000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0xa0000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff)); } void sh(RegisterID rt, RegisterID rs, int offset) { - emitInst(0xa4000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0xa4000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff)); } void sw(RegisterID rt, RegisterID rs, int offset) { - emitInst(0xac000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0xac000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS) | (offset & 0xffff)); } void jr(RegisterID rs) @@ -481,51 +465,43 @@ public: void addd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft) { - emitInst(0x46200000 | (fd << OP_SH_FD) | (fs << OP_SH_FS) - | (ft << OP_SH_FT)); + emitInst(0x46200000 | (fd << OP_SH_FD) | (fs << OP_SH_FS) | (ft << OP_SH_FT)); } void subd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft) { - emitInst(0x46200001 | (fd << OP_SH_FD) | (fs << OP_SH_FS) - | (ft << OP_SH_FT)); + emitInst(0x46200001 | (fd << OP_SH_FD) | (fs << OP_SH_FS) | (ft << OP_SH_FT)); } void muld(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft) { - emitInst(0x46200002 | (fd << OP_SH_FD) | (fs << OP_SH_FS) - | (ft << OP_SH_FT)); + emitInst(0x46200002 | (fd << OP_SH_FD) | (fs << OP_SH_FS) | (ft << OP_SH_FT)); } void divd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft) { - emitInst(0x46200003 | (fd << OP_SH_FD) | (fs << OP_SH_FS) - | (ft << OP_SH_FT)); + emitInst(0x46200003 | (fd << OP_SH_FD) | (fs << OP_SH_FS) | (ft << OP_SH_FT)); } void lwc1(FPRegisterID ft, RegisterID rs, int offset) { - emitInst(0xc4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0xc4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) | (offset & 0xffff)); copDelayNop(); } void ldc1(FPRegisterID ft, RegisterID rs, int offset) { - emitInst(0xd4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0xd4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) | (offset & 0xffff)); } void swc1(FPRegisterID ft, RegisterID rs, int offset) { - emitInst(0xe4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0xe4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) | (offset & 0xffff)); } void sdc1(FPRegisterID ft, RegisterID rs, int offset) { - emitInst(0xf4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) - | (offset & 0xffff)); + emitInst(0xf4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS) | (offset & 0xffff)); } void mtc1(RegisterID rt, FPRegisterID fs) @@ -561,11 +537,21 @@ public: emitInst(0x46800021 | (fd << OP_SH_FD) | (fs << OP_SH_FS)); } + void cvtds(FPRegisterID fd, FPRegisterID fs) + { + emitInst(0x46000021 | (fd << OP_SH_FD) | (fs << OP_SH_FS)); + } + void cvtwd(FPRegisterID fd, FPRegisterID fs) { emitInst(0x46200024 | (fd << OP_SH_FD) | (fs << OP_SH_FS)); } + void cvtsd(FPRegisterID fd, FPRegisterID fs) + { + emitInst(0x46200020 | (fd << OP_SH_FD) | (fs << OP_SH_FS)); + } + void ceqd(FPRegisterID fs, FPRegisterID ft) { emitInst(0x46200032 | (fs << OP_SH_FS) | (ft << OP_SH_FT)); @@ -675,6 +661,19 @@ public: unsigned debugOffset() { return m_buffer.debugOffset(); } + // Assembly helpers for moving data between fp and registers. + void vmov(RegisterID rd1, RegisterID rd2, FPRegisterID rn) + { + mfc1(rd1, rn); + mfc1(rd2, FPRegisterID(rn + 1)); + } + + void vmov(FPRegisterID rd, RegisterID rn1, RegisterID rn2) + { + mtc1(rn1, rd); + mtc1(rn2, FPRegisterID(rd + 1)); + } + static unsigned getCallReturnOffset(AssemblerLabel call) { // The return address is after a call and a delay slot instruction @@ -684,7 +683,7 @@ public: // Linking & patching: // // 'link' and 'patch' methods are for use on unprotected code - such as the code - // within the AssemblerBuffer, and code being patched by the patch buffer. Once + // within the AssemblerBuffer, and code being patched by the patch buffer. Once // code has been finalized it is (platform support permitting) within a non- // writable region of memory; to modify the code in an execute-only execuable // pool the 'repatch' and 'relink' methods should be used. @@ -858,7 +857,7 @@ private: MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(newBase) + pos); insn = insn + 2; // Need to make sure we have 5 valid instructions after pos - if ((unsigned int)pos >= m_buffer.codeSize() - 5 * sizeof(MIPSWord)) + if ((unsigned)pos >= m_buffer.codeSize() - 5 * sizeof(MIPSWord)) continue; if ((*insn & 0xfc000000) == 0x08000000) { // j @@ -894,11 +893,10 @@ private: static int linkWithOffset(MIPSWord* insn, void* to) { ASSERT((*insn & 0xfc000000) == 0x10000000 // beq - || (*insn & 0xfc000000) == 0x14000000 // bne - || (*insn & 0xffff0000) == 0x45010000 // bc1t - || (*insn & 0xffff0000) == 0x45000000); // bc1f - intptr_t diff = (reinterpret_cast<intptr_t>(to) - - reinterpret_cast<intptr_t>(insn) - 4) >> 2; + || (*insn & 0xfc000000) == 0x14000000 // bne + || (*insn & 0xffff0000) == 0x45010000 // bc1t + || (*insn & 0xffff0000) == 0x45000000); // bc1f + intptr_t diff = (reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(insn) - 4) >> 2; if (diff < -32768 || diff > 32767 || *(insn + 2) != 0x10000003) { /* diff --git a/Source/JavaScriptCore/assembler/MacroAssembler.cpp b/Source/JavaScriptCore/assembler/MacroAssembler.cpp new file mode 100644 index 000000000..2cff056d2 --- /dev/null +++ b/Source/JavaScriptCore/assembler/MacroAssembler.cpp @@ -0,0 +1,38 @@ +/* + * 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 "MacroAssembler.h" + +#if ENABLE(ASSEMBLER) + +namespace JSC { + +const double MacroAssembler::twoToThe32 = (double)0x100000000ull; + +} // namespace JSC + +#endif // ENABLE(ASSEMBLER) + diff --git a/Source/JavaScriptCore/assembler/MacroAssembler.h b/Source/JavaScriptCore/assembler/MacroAssembler.h index 1a9af2989..4d4a960d3 100644 --- a/Source/JavaScriptCore/assembler/MacroAssembler.h +++ b/Source/JavaScriptCore/assembler/MacroAssembler.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -26,6 +26,8 @@ #ifndef MacroAssembler_h #define MacroAssembler_h +#include <wtf/Platform.h> + #if ENABLE(ASSEMBLER) #if CPU(ARM_THUMB2) @@ -68,10 +70,6 @@ public: using MacroAssemblerBase::pop; using MacroAssemblerBase::jump; using MacroAssemblerBase::branch32; -#if CPU(X86_64) - using MacroAssemblerBase::branchPtr; - using MacroAssemblerBase::branchTestPtr; -#endif using MacroAssemblerBase::move; #if ENABLE(JIT_CONSTANT_BLINDING) @@ -89,6 +87,8 @@ public: using MacroAssemblerBase::xor32; #endif + static const double twoToThe32; // This is super useful for some double code. + // Utilities used by the DFG JIT. #if ENABLE(DFG_JIT) using MacroAssemblerBase::invert; @@ -183,6 +183,23 @@ public: storePtr(imm, addressForPoke(index)); } +#if CPU(X86_64) + void peek64(RegisterID dest, int index = 0) + { + load64(Address(stackPointerRegister, (index * sizeof(void*))), dest); + } + + void poke(TrustedImm64 value, int index = 0) + { + store64(value, addressForPoke(index)); + } + + void poke64(RegisterID src, int index = 0) + { + store64(src, addressForPoke(index)); + } +#endif + // Backwards banches, these are currently all implemented using existing forwards branch mechanisms. void branchPtr(RelationalCondition cond, RegisterID op1, TrustedImmPtr imm, Label target) @@ -230,6 +247,11 @@ public: } #if !CPU(ARM_THUMB2) + PatchableJump patchableBranchPtr(RelationalCondition cond, Address left, TrustedImmPtr right = TrustedImmPtr(0)) + { + return PatchableJump(branchPtr(cond, left, right)); + } + PatchableJump patchableBranchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) { return PatchableJump(branchPtrWithPatch(cond, left, dataLabel, initialRightValue)); @@ -239,6 +261,16 @@ public: { return PatchableJump(jump()); } + + PatchableJump patchableBranchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) + { + return PatchableJump(branchTest32(cond, reg, mask)); + } + + PatchableJump patchableBranch32(RelationalCondition cond, RegisterID reg, TrustedImm32 imm) + { + return PatchableJump(branch32(cond, reg, imm)); + } #endif void jump(Label target) @@ -486,6 +518,11 @@ public: return branch32(cond, left, TrustedImm32(right)); } + Jump branchSubPtr(ResultCondition cond, RegisterID src, RegisterID dest) + { + return branchSub32(cond, src, dest); + } + Jump branchTestPtr(ResultCondition cond, RegisterID reg, RegisterID mask) { return branchTest32(cond, reg, mask); @@ -521,15 +558,295 @@ public: return MacroAssemblerBase::branchTest8(cond, Address(address.base, address.offset), mask); } #else + void addPtr(RegisterID src, RegisterID dest) + { + add64(src, dest); + } + void addPtr(Address src, RegisterID dest) + { + add64(src, dest); + } + + void addPtr(TrustedImm32 imm, RegisterID srcDest) + { + add64(imm, srcDest); + } + + void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + add64(imm, src, dest); + } + + void addPtr(TrustedImm32 imm, Address address) + { + add64(imm, address); + } + + void addPtr(AbsoluteAddress src, RegisterID dest) + { + add64(src, dest); + } + + void addPtr(TrustedImmPtr imm, RegisterID dest) + { + add64(TrustedImm64(imm), dest); + } + + void addPtr(TrustedImm32 imm, AbsoluteAddress address) + { + add64(imm, address); + } + + void andPtr(RegisterID src, RegisterID dest) + { + and64(src, dest); + } + + void andPtr(TrustedImm32 imm, RegisterID srcDest) + { + and64(imm, srcDest); + } + + void negPtr(RegisterID dest) + { + neg64(dest); + } + + void orPtr(RegisterID src, RegisterID dest) + { + or64(src, dest); + } + + void orPtr(TrustedImm32 imm, RegisterID dest) + { + or64(imm, dest); + } + + void orPtr(TrustedImmPtr imm, RegisterID dest) + { + or64(TrustedImm64(imm), dest); + } + + void orPtr(RegisterID op1, RegisterID op2, RegisterID dest) + { + or64(op1, op2, dest); + } + + void orPtr(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + or64(imm, src, dest); + } + + void rotateRightPtr(TrustedImm32 imm, RegisterID srcDst) + { + rotateRight64(imm, srcDst); + } + + void subPtr(RegisterID src, RegisterID dest) + { + sub64(src, dest); + } + + void subPtr(TrustedImm32 imm, RegisterID dest) + { + sub64(imm, dest); + } + + void subPtr(TrustedImmPtr imm, RegisterID dest) + { + sub64(TrustedImm64(imm), dest); + } + + void xorPtr(RegisterID src, RegisterID dest) + { + xor64(src, dest); + } + + void xorPtr(RegisterID src, Address dest) + { + xor64(src, dest); + } + + void xorPtr(TrustedImm32 imm, RegisterID srcDest) + { + xor64(imm, srcDest); + } + + void loadPtr(ImplicitAddress address, RegisterID dest) + { + load64(address, dest); + } + + void loadPtr(BaseIndex address, RegisterID dest) + { + load64(address, dest); + } + + void loadPtr(const void* address, RegisterID dest) + { + load64(address, dest); + } + + DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest) + { + return load64WithAddressOffsetPatch(address, dest); + } + + DataLabelCompact loadPtrWithCompactAddressOffsetPatch(Address address, RegisterID dest) + { + return load64WithCompactAddressOffsetPatch(address, dest); + } + + void storePtr(RegisterID src, ImplicitAddress address) + { + store64(src, address); + } + + void storePtr(RegisterID src, BaseIndex address) + { + store64(src, address); + } + + void storePtr(RegisterID src, void* address) + { + store64(src, address); + } + + void storePtr(TrustedImmPtr imm, ImplicitAddress address) + { + store64(TrustedImm64(imm), address); + } + + void storePtr(TrustedImmPtr imm, BaseIndex address) + { + store64(TrustedImm64(imm), address); + } + + DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address) + { + return store64WithAddressOffsetPatch(src, address); + } + + void movePtrToDouble(RegisterID src, FPRegisterID dest) + { + move64ToDouble(src, dest); + } + + void moveDoubleToPtr(FPRegisterID src, RegisterID dest) + { + moveDoubleTo64(src, dest); + } + + void comparePtr(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest) + { + compare64(cond, left, right, dest); + } + + void comparePtr(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest) + { + compare64(cond, left, right, dest); + } + + void testPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest) + { + test64(cond, reg, mask, dest); + } + + void testPtr(ResultCondition cond, RegisterID reg, RegisterID mask, RegisterID dest) + { + test64(cond, reg, mask, dest); + } + + Jump branchPtr(RelationalCondition cond, RegisterID left, RegisterID right) + { + return branch64(cond, left, right); + } + + Jump branchPtr(RelationalCondition cond, RegisterID left, TrustedImmPtr right) + { + return branch64(cond, left, TrustedImm64(right)); + } + + Jump branchPtr(RelationalCondition cond, RegisterID left, Address right) + { + return branch64(cond, left, right); + } + + Jump branchPtr(RelationalCondition cond, Address left, RegisterID right) + { + return branch64(cond, left, right); + } + + Jump branchPtr(RelationalCondition cond, AbsoluteAddress left, RegisterID right) + { + return branch64(cond, left, right); + } + + Jump branchPtr(RelationalCondition cond, Address left, TrustedImmPtr right) + { + return branch64(cond, left, TrustedImm64(right)); + } + + Jump branchTestPtr(ResultCondition cond, RegisterID reg, RegisterID mask) + { + return branchTest64(cond, reg, mask); + } + + Jump branchTestPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) + { + return branchTest64(cond, reg, mask); + } + + Jump branchTestPtr(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) + { + return branchTest64(cond, address, mask); + } + + Jump branchTestPtr(ResultCondition cond, Address address, RegisterID reg) + { + return branchTest64(cond, address, reg); + } + + Jump branchTestPtr(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1)) + { + return branchTest64(cond, address, mask); + } + + Jump branchTestPtr(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1)) + { + return branchTest64(cond, address, mask); + } + + Jump branchAddPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest) + { + return branchAdd64(cond, imm, dest); + } + + Jump branchAddPtr(ResultCondition cond, RegisterID src, RegisterID dest) + { + return branchAdd64(cond, src, dest); + } + + Jump branchSubPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest) + { + return branchSub64(cond, imm, dest); + } + + Jump branchSubPtr(ResultCondition cond, RegisterID src, RegisterID dest) + { + return branchSub64(cond, src, dest); + } + + Jump branchSubPtr(ResultCondition cond, RegisterID src1, TrustedImm32 src2, RegisterID dest) + { + return branchSub64(cond, src1, src2, dest); + } + #if ENABLE(JIT_CONSTANT_BLINDING) - using MacroAssemblerBase::addPtr; - using MacroAssemblerBase::andPtr; - using MacroAssemblerBase::branchSubPtr; + using MacroAssemblerBase::and64; using MacroAssemblerBase::convertInt32ToDouble; - using MacroAssemblerBase::storePtr; - using MacroAssemblerBase::subPtr; - using MacroAssemblerBase::xorPtr; + using MacroAssemblerBase::store64; bool shouldBlindDouble(double value) { @@ -539,7 +856,7 @@ public: // Try to force normalisation, and check that there's no change // in the bit pattern - if (bitwise_cast<uintptr_t>(value * 1.0) != bitwise_cast<uintptr_t>(value)) + if (bitwise_cast<uint64_t>(value * 1.0) != bitwise_cast<uint64_t>(value)) return true; value = abs(value); @@ -578,7 +895,6 @@ public: default: { if (value <= 0xff) return false; -#if CPU(X86_64) JSValue jsValue = JSValue::decode(reinterpret_cast<void*>(value)); if (jsValue.isInt32()) return shouldBlind(Imm32(jsValue.asInt32())); @@ -587,7 +903,6 @@ public: if (!shouldBlindDouble(bitwise_cast<double>(value))) return false; -#endif } } return shouldBlindForSpecificArch(value); @@ -617,6 +932,59 @@ public: rotateRightPtr(constant.rotation, dest); } + bool shouldBlind(Imm64 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 + uint64_t value = imm.asTrustedImm64().m_value; + switch (value) { + case 0xffff: + case 0xffffff: + case 0xffffffffL: + case 0xffffffffffL: + case 0xffffffffffffL: + case 0xffffffffffffffL: + case 0xffffffffffffffffL: + return false; + default: { + if (value <= 0xff) + return false; + } + } + return shouldBlindForSpecificArch(value); + } + + struct RotatedImm64 { + RotatedImm64(uint64_t v1, uint8_t v2) + : value(v1) + , rotation(v2) + { + } + TrustedImm64 value; + TrustedImm32 rotation; + }; + + RotatedImm64 rotationBlindConstant(Imm64 imm) + { + uint8_t rotation = random() % (sizeof(int64_t) * 8); + uint64_t value = imm.asTrustedImm64().m_value; + value = (value << rotation) | (value >> (sizeof(int64_t) * 8 - rotation)); + return RotatedImm64(value, rotation); + } + + void loadRotationBlindedConstant(RotatedImm64 constant, RegisterID dest) + { + move(constant.value, dest); + rotateRight64(constant.rotation, dest); + } + void convertInt32ToDouble(Imm32 imm, FPRegisterID dest) { if (shouldBlind(imm)) { @@ -635,6 +1003,24 @@ public: move(imm.asTrustedImmPtr(), dest); } + void move(Imm64 imm, RegisterID dest) + { + if (shouldBlind(imm)) + loadRotationBlindedConstant(rotationBlindConstant(imm), dest); + else + move(imm.asTrustedImm64(), dest); + } + + void and64(Imm32 imm, RegisterID dest) + { + if (shouldBlind(imm)) { + BlindedImm32 key = andBlindedConstant(imm); + and64(key.value1, dest); + and64(key.value2, dest); + } else + and64(imm.asTrustedImm32(), dest); + } + Jump branchPtr(RelationalCondition cond, RegisterID left, ImmPtr right) { if (shouldBlind(right)) { @@ -655,6 +1041,16 @@ public: storePtr(imm.asTrustedImmPtr(), dest); } + void store64(Imm64 imm, Address dest) + { + if (shouldBlind(imm)) { + RegisterID scratchRegister = scratchRegisterForBlinding(); + loadRotationBlindedConstant(rotationBlindConstant(imm), scratchRegister); + store64(scratchRegister, dest); + } else + store64(imm.asTrustedImm64(), dest); + } + #endif #endif // !CPU(X86_64) @@ -848,6 +1244,13 @@ public: storePtr(value, addressForPoke(index)); } +#if CPU(X86_64) + void poke(Imm64 value, int index = 0) + { + store64(value, addressForPoke(index)); + } +#endif + void store32(Imm32 imm, Address dest) { if (shouldBlind(imm)) { diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h index 298de9793..39d94adea 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h @@ -672,6 +672,17 @@ public: load32(Address(ARMRegisters::S0, 0), ARMRegisters::pc); } + void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2) + { + m_assembler.vmov(dest1, dest2, src); + } + + void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID scratch) + { + UNUSED_PARAM(scratch); + m_assembler.vmov(dest, src1, src2); + } + Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 46d7225d0..1301038e5 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -754,6 +754,18 @@ public: store16(src, setupArmAddress(address)); } + // Possibly clobbers src, but not on this architecture. + void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2) + { + m_assembler.vmov(dest1, dest2, src); + } + + void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID scratch) + { + UNUSED_PARAM(scratch); + m_assembler.vmov(dest, src1, src2); + } + #if ENABLE(JIT_CONSTANT_BLINDING) static bool shouldBlindForSpecificArch(uint32_t value) { @@ -1672,6 +1684,30 @@ public: dataLabel = moveWithPatch(initialRightValue, dataTempRegister); return branch32(cond, addressTempRegister, dataTempRegister); } + + PatchableJump patchableBranchPtr(RelationalCondition cond, Address left, TrustedImmPtr right = TrustedImmPtr(0)) + { + m_makeJumpPatchable = true; + Jump result = branch32(cond, left, TrustedImm32(right)); + m_makeJumpPatchable = false; + return PatchableJump(result); + } + + PatchableJump patchableBranchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) + { + m_makeJumpPatchable = true; + Jump result = branchTest32(cond, reg, mask); + m_makeJumpPatchable = false; + return PatchableJump(result); + } + + PatchableJump patchableBranch32(RelationalCondition cond, RegisterID reg, TrustedImm32 imm) + { + m_makeJumpPatchable = true; + Jump result = branch32(cond, reg, imm); + m_makeJumpPatchable = false; + return PatchableJump(result); + } PatchableJump patchableBranchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) { diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h index 22830a621..fc6f9f40d 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h @@ -29,8 +29,8 @@ #if ENABLE(ASSEMBLER) && CPU(MIPS) -#include "MIPSAssembler.h" #include "AbstractMacroAssembler.h" +#include "MIPSAssembler.h" namespace JSC { @@ -155,12 +155,10 @@ public: m_assembler.lw(dataTempRegister, address.base, address.offset); if (imm.m_value >= -32768 && imm.m_value <= 32767 && !m_fixedWidth) - m_assembler.addiu(dataTempRegister, dataTempRegister, - imm.m_value); + m_assembler.addiu(dataTempRegister, dataTempRegister, imm.m_value); else { move(imm, immTempRegister); - m_assembler.addu(dataTempRegister, dataTempRegister, - immTempRegister); + m_assembler.addu(dataTempRegister, dataTempRegister, immTempRegister); } m_assembler.sw(dataTempRegister, address.base, address.offset); } else { @@ -177,12 +175,10 @@ public: m_assembler.lw(dataTempRegister, addrTempRegister, address.offset); if (imm.m_value >= -32768 && imm.m_value <= 32767 && !m_fixedWidth) - m_assembler.addiu(dataTempRegister, dataTempRegister, - imm.m_value); + m_assembler.addiu(dataTempRegister, dataTempRegister, imm.m_value); else { move(imm, immTempRegister); - m_assembler.addu(dataTempRegister, dataTempRegister, - immTempRegister); + m_assembler.addu(dataTempRegister, dataTempRegister, immTempRegister); } m_assembler.sw(dataTempRegister, addrTempRegister, address.offset); } @@ -257,8 +253,7 @@ public: { if (!imm.m_value && !m_fixedWidth) move(MIPSRegisters::zero, dest); - else if (imm.m_value > 0 && imm.m_value < 65535 - && !m_fixedWidth) + else if (imm.m_value > 0 && imm.m_value < 65535 && !m_fixedWidth) m_assembler.andi(dest, dest, imm.m_value); else { /* @@ -419,14 +414,11 @@ public: sw dataTemp, offset(base) */ m_assembler.lw(dataTempRegister, address.base, address.offset); - if (imm.m_value >= -32767 && imm.m_value <= 32768 - && !m_fixedWidth) - m_assembler.addiu(dataTempRegister, dataTempRegister, - -imm.m_value); + if (imm.m_value >= -32767 && imm.m_value <= 32768 && !m_fixedWidth) + m_assembler.addiu(dataTempRegister, dataTempRegister, -imm.m_value); else { move(imm, immTempRegister); - m_assembler.subu(dataTempRegister, dataTempRegister, - immTempRegister); + m_assembler.subu(dataTempRegister, dataTempRegister, immTempRegister); } m_assembler.sw(dataTempRegister, address.base, address.offset); } else { @@ -444,12 +436,10 @@ public: if (imm.m_value >= -32767 && imm.m_value <= 32768 && !m_fixedWidth) - m_assembler.addiu(dataTempRegister, dataTempRegister, - -imm.m_value); + m_assembler.addiu(dataTempRegister, dataTempRegister, -imm.m_value); else { move(imm, immTempRegister); - m_assembler.subu(dataTempRegister, dataTempRegister, - immTempRegister); + m_assembler.subu(dataTempRegister, dataTempRegister, immTempRegister); } m_assembler.sw(dataTempRegister, addrTempRegister, address.offset); } @@ -473,11 +463,9 @@ public: move(TrustedImmPtr(address.m_ptr), addrTempRegister); m_assembler.lw(dataTempRegister, addrTempRegister, 0); - if (imm.m_value >= -32767 && imm.m_value <= 32768 - && !m_fixedWidth) { - m_assembler.addiu(dataTempRegister, dataTempRegister, - -imm.m_value); - } else { + if (imm.m_value >= -32767 && imm.m_value <= 32768 && !m_fixedWidth) + m_assembler.addiu(dataTempRegister, dataTempRegister, -imm.m_value); + else { move(imm, immTempRegister); m_assembler.subu(dataTempRegister, dataTempRegister, immTempRegister); } @@ -531,7 +519,7 @@ public: // Memory access operations: // // Loads are of the form load(address, destination) and stores of the form - // store(source, address). The source for a store may be an TrustedImm32. Address + // store(source, address). The source for a store may be an TrustedImm32. Address // operand objects to loads and store will be implicitly constructed if a // register is passed. @@ -576,12 +564,39 @@ public: 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.addu(addrTempRegister, addrTempRegister, immTempRegister); m_assembler.lbu(dest, addrTempRegister, address.offset); } } + void load8Signed(BaseIndex address, RegisterID dest) + { + if (address.offset >= -32768 && address.offset <= 32767 + && !m_fixedWidth) { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + lb dest, address.offset(addrTemp) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.lb(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 + lb 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.lb(dest, addrTempRegister, address.offset); + } + } + void load32(ImplicitAddress address, RegisterID dest) { if (address.offset >= -32768 && address.offset <= 32767 @@ -622,8 +637,7 @@ public: 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.addu(addrTempRegister, addrTempRegister, immTempRegister); m_assembler.lw(dest, addrTempRegister, address.offset); } } @@ -675,8 +689,7 @@ public: m_assembler.addu(addrTempRegister, addrTempRegister, address.base); m_assembler.lui(immTempRegister, address.offset >> 16); m_assembler.ori(immTempRegister, immTempRegister, address.offset); - m_assembler.addu(addrTempRegister, addrTempRegister, - immTempRegister); + m_assembler.addu(addrTempRegister, addrTempRegister, immTempRegister); #if CPU(BIG_ENDIAN) m_assembler.lwl(dest, addrTempRegister, 0); m_assembler.lwr(dest, addrTempRegister, 3); @@ -763,12 +776,39 @@ public: 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.addu(addrTempRegister, addrTempRegister, immTempRegister); m_assembler.lhu(dest, addrTempRegister, address.offset); } } + void load16Signed(BaseIndex address, RegisterID dest) + { + if (address.offset >= -32768 && address.offset <= 32767 + && !m_fixedWidth) { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + lh dest, address.offset(addrTemp) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.lh(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 + lh dest, (address.offset & 0xffff)(addrTemp) + */ + 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.lh(dest, addrTempRegister, address.offset); + } + } + DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address) { m_fixedWidth = true; @@ -809,8 +849,7 @@ public: 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.addu(addrTempRegister, addrTempRegister, immTempRegister); m_assembler.sb(src, addrTempRegister, address.offset); } } @@ -855,8 +894,7 @@ public: 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.addu(addrTempRegister, addrTempRegister, immTempRegister); m_assembler.sh(src, addrTempRegister, address.offset); } } @@ -901,8 +939,7 @@ public: 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.addu(addrTempRegister, addrTempRegister, immTempRegister); m_assembler.sw(src, addrTempRegister, address.offset); } } @@ -912,8 +949,7 @@ public: if (address.offset >= -32768 && address.offset <= 32767 && !m_fixedWidth) { if (!imm.m_value) - m_assembler.sw(MIPSRegisters::zero, address.base, - address.offset); + m_assembler.sw(MIPSRegisters::zero, address.base, address.offset); else { move(imm, immTempRegister); m_assembler.sw(immTempRegister, address.base, address.offset); @@ -927,12 +963,10 @@ public: m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16); m_assembler.addu(addrTempRegister, addrTempRegister, address.base); if (!imm.m_value && !m_fixedWidth) - m_assembler.sw(MIPSRegisters::zero, addrTempRegister, - address.offset); + m_assembler.sw(MIPSRegisters::zero, addrTempRegister, address.offset); else { move(imm, immTempRegister); - m_assembler.sw(immTempRegister, addrTempRegister, - address.offset); + m_assembler.sw(immTempRegister, addrTempRegister, address.offset); } } } @@ -997,9 +1031,9 @@ public: // Stack manipulation operations: // // The ABI is assumed to provide a stack abstraction to memory, - // containing machine word sized units of data. Push and pop + // containing machine word sized units of data. Push and pop // operations add and remove a single register sized unit of data - // to or from the stack. Peek and poke operations read or write + // to or from the stack. Peek and poke operations read or write // values on the stack, without moving the current stack position. void pop(RegisterID dest) @@ -1283,10 +1317,21 @@ public: m_fixedWidth = false; } + void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2) + { + m_assembler.vmov(dest1, dest2, src); + } + + void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID scratch) + { + UNUSED_PARAM(scratch); + m_assembler.vmov(dest, src1, src2); + } + // Arithmetic control flow operations: // // This set of conditional branch operations branch based - // on the result of an arithmetic operation. The operation + // on the result of an arithmetic operation. The operation // is performed as normal, storing the result. // // * jz operations branch if the result is zero. @@ -1495,7 +1540,7 @@ public: Call nearCall() { - /* We need two words for relaxation. */ + /* We need two words for relaxation. */ m_assembler.nop(); m_assembler.nop(); m_assembler.jal(); @@ -1583,8 +1628,7 @@ public: m_assembler.sltu(dest, MIPSRegisters::zero, dataTempRegister); } else { move(mask, immTempRegister); - m_assembler.andInsn(cmpTempRegister, dataTempRegister, - immTempRegister); + m_assembler.andInsn(cmpTempRegister, dataTempRegister, immTempRegister); if (cond == Zero) m_assembler.sltiu(dest, cmpTempRegister, 1); else @@ -1603,8 +1647,7 @@ public: m_assembler.sltu(dest, MIPSRegisters::zero, dataTempRegister); } else { move(mask, immTempRegister); - m_assembler.andInsn(cmpTempRegister, dataTempRegister, - immTempRegister); + m_assembler.andInsn(cmpTempRegister, dataTempRegister, immTempRegister); if (cond == Zero) m_assembler.sltiu(dest, cmpTempRegister, 1); else @@ -1680,6 +1723,34 @@ public: return tailRecursiveCall(); } + void loadFloat(BaseIndex address, FPRegisterID dest) + { + if (address.offset >= -32768 && address.offset <= 32767 + && !m_fixedWidth) { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + lwc1 dest, address.offset(addrTemp) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.lwc1(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 + lwc1 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.lwc1(dest, addrTempRegister, address.offset); + } + } + void loadDouble(ImplicitAddress address, FPRegisterID dest) { #if WTF_MIPS_ISA(1) @@ -1710,6 +1781,65 @@ public: #endif } + void loadDouble(BaseIndex address, FPRegisterID dest) + { +#if WTF_MIPS_ISA(1) + if (address.offset >= -32768 && address.offset <= 32767 + && !m_fixedWidth) { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + lwc1 dest, address.offset(addrTemp) + lwc1 dest+1, (address.offset+4)(addrTemp) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.lwc1(dest, addrTempRegister, address.offset); + m_assembler.lwc1(FPRegisterID(dest + 1), addrTempRegister, address.offset + 4); + } else { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + lui immTemp, (address.offset + 0x8000) >> 16 + addu addrTemp, addrTemp, immTemp + lwc1 dest, (address.offset & 0xffff)(at) + lwc1 dest+4, (address.offset & 0xffff + 4)(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.lwc1(dest, addrTempRegister, address.offset); + m_assembler.lwc1(FPRegisterID(dest + 1), addrTempRegister, address.offset + 4); + } +#else + if (address.offset >= -32768 && address.offset <= 32767 + && !m_fixedWidth) { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + ldc1 dest, address.offset(addrTemp) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.ldc1(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 + ldc1 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.ldc1(dest, addrTempRegister, address.offset); + } +#endif + } + void loadDouble(const void* address, FPRegisterID dest) { #if WTF_MIPS_ISA(1) @@ -1731,6 +1861,33 @@ public: #endif } + void storeFloat(FPRegisterID src, BaseIndex address) + { + if (address.offset >= -32768 && address.offset <= 32767 + && !m_fixedWidth) { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + swc1 src, address.offset(addrTemp) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.swc1(src, 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 + swc1 src, (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.swc1(src, addrTempRegister, address.offset); + } + } void storeDouble(FPRegisterID src, ImplicitAddress address) { @@ -1762,17 +1919,99 @@ public: #endif } + void storeDouble(FPRegisterID src, BaseIndex address) + { +#if WTF_MIPS_ISA(1) + if (address.offset >= -32768 && address.offset <= 32767 + && !m_fixedWidth) { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + swc1 src, address.offset(addrTemp) + swc1 src+1, (address.offset + 4)(addrTemp) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.swc1(src, addrTempRegister, address.offset); + m_assembler.swc1(FPRegisterID(src + 1), addrTempRegister, address.offset + 4); + } else { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + lui immTemp, (address.offset + 0x8000) >> 16 + addu addrTemp, addrTemp, immTemp + swc1 src, (address.offset & 0xffff)(at) + swc1 src+1, (address.offset & 0xffff + 4)(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.swc1(src, addrTempRegister, address.offset); + m_assembler.swc1(FPRegisterID(src + 1), addrTempRegister, address.offset + 4); + } +#else + if (address.offset >= -32768 && address.offset <= 32767 + && !m_fixedWidth) { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + sdc1 src, address.offset(addrTemp) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.sdc1(src, 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 + sdc1 src, (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.sdc1(src, addrTempRegister, address.offset); + } +#endif + } + + void storeDouble(FPRegisterID src, const void* address) + { +#if WTF_MIPS_ISA(1) + move(TrustedImmPtr(address), addrTempRegister); + m_assembler.swc1(src, addrTempRegister, 0); + m_assembler.swc1(FPRegisterID(src + 1), addrTempRegister, 4); +#else + move(TrustedImmPtr(address), addrTempRegister); + m_assembler.sdc1(src, addrTempRegister, 0); +#endif + } + void addDouble(FPRegisterID src, FPRegisterID dest) { m_assembler.addd(dest, dest, src); } + void addDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + m_assembler.addd(dest, op1, op2); + } + void addDouble(Address src, FPRegisterID dest) { loadDouble(src, fpTempRegister); m_assembler.addd(dest, dest, fpTempRegister); } + void addDouble(AbsoluteAddress address, FPRegisterID dest) + { + loadDouble(address.m_ptr, fpTempRegister); + m_assembler.addd(dest, dest, fpTempRegister); + } + void subDouble(FPRegisterID src, FPRegisterID dest) { m_assembler.subd(dest, dest, src); @@ -1820,6 +2059,16 @@ public: m_assembler.cvtdw(dest, fpTempRegister); } + void convertFloatToDouble(FPRegisterID src, FPRegisterID dst) + { + m_assembler.cvtds(dst, src); + } + + void convertDoubleToFloat(FPRegisterID src, FPRegisterID dst) + { + m_assembler.cvtsd(dst, src); + } + void insertRelaxationWords() { /* We need four words for relaxation. */ diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h index f6e373d3e..8fd31466d 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h @@ -138,6 +138,22 @@ public: ASSERT(-128 <= imm.m_value && imm.m_value < 128); m_assembler.movb_i8m(imm.m_value, address); } + + // Possibly clobbers src. + void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2) + { + movePackedToInt32(src, dest1); + rshiftPacked(TrustedImm32(32), src); + movePackedToInt32(src, dest2); + } + + void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID scratch) + { + moveInt32ToPacked(src1, dest); + moveInt32ToPacked(src2, scratch); + lshiftPacked(TrustedImm32(32), scratch); + orPacked(scratch, dest); + } Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest) { diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h index 905c09426..66db26acb 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h @@ -97,9 +97,12 @@ public: #if ENABLE(JIT_CONSTANT_BLINDING) static bool shouldBlindForSpecificArch(uint32_t value) { return value >= 0x00ffffff; } #if CPU(X86_64) + static bool shouldBlindForSpecificArch(uint64_t value) { return value >= 0x00ffffff; } +#if OS(DARWIN) // On 64-bit systems other than DARWIN uint64_t and uintptr_t are the same type so overload is prohibited. static bool shouldBlindForSpecificArch(uintptr_t value) { return value >= 0x00ffffff; } #endif #endif +#endif // Integer arithmetic operations: // @@ -993,6 +996,11 @@ public: m_assembler.movq_i64r(imm.asIntptr(), dest); } + void move(TrustedImm64 imm, RegisterID dest) + { + m_assembler.movq_i64r(imm.m_value, dest); + } + void swap(RegisterID reg1, RegisterID reg2) { if (reg1 != reg2) diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h index 6493b0c34..ceacf6aa8 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h @@ -154,231 +154,225 @@ public: return Call::fromTailJump(newJump); } + 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))); + } - void addPtr(RegisterID src, RegisterID dest) + void add64(RegisterID src, RegisterID dest) { m_assembler.addq_rr(src, dest); } - void addPtr(Address src, RegisterID dest) + void add64(Address src, RegisterID dest) { m_assembler.addq_mr(src.offset, src.base, dest); } - void addPtr(AbsoluteAddress src, RegisterID dest) + void add64(AbsoluteAddress src, RegisterID dest) { move(TrustedImmPtr(src.m_ptr), scratchRegister); - addPtr(Address(scratchRegister), dest); + add64(Address(scratchRegister), dest); } - void addPtr(TrustedImm32 imm, RegisterID srcDest) + void add64(TrustedImm32 imm, RegisterID srcDest) { m_assembler.addq_ir(imm.m_value, srcDest); } - void addPtr(TrustedImmPtr imm, RegisterID dest) + void add64(TrustedImm64 imm, RegisterID dest) { move(imm, scratchRegister); - m_assembler.addq_rr(scratchRegister, dest); + add64(scratchRegister, dest); } - void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest) + void add64(TrustedImm32 imm, RegisterID src, RegisterID dest) { m_assembler.leaq_mr(imm.m_value, src, dest); } - void addPtr(TrustedImm32 imm, Address address) + void add64(TrustedImm32 imm, Address address) { m_assembler.addq_im(imm.m_value, address.offset, address.base); } - void addPtr(TrustedImm32 imm, AbsoluteAddress address) - { - move(TrustedImmPtr(address.m_ptr), scratchRegister); - addPtr(imm, Address(scratchRegister)); - } - void add64(TrustedImm32 imm, AbsoluteAddress address) { - addPtr(imm, address); + move(TrustedImmPtr(address.m_ptr), scratchRegister); + add64(imm, Address(scratchRegister)); } - void andPtr(RegisterID src, RegisterID dest) + void and64(RegisterID src, RegisterID dest) { m_assembler.andq_rr(src, dest); } - void andPtr(TrustedImm32 imm, RegisterID srcDest) + void and64(TrustedImm32 imm, RegisterID srcDest) { m_assembler.andq_ir(imm.m_value, srcDest); } - void negPtr(RegisterID dest) + void neg64(RegisterID dest) { m_assembler.negq_r(dest); } - void orPtr(RegisterID src, RegisterID dest) + void or64(RegisterID src, RegisterID dest) { m_assembler.orq_rr(src, dest); } - void orPtr(TrustedImmPtr imm, RegisterID dest) + void or64(TrustedImm64 imm, RegisterID dest) { move(imm, scratchRegister); - m_assembler.orq_rr(scratchRegister, dest); + or64(scratchRegister, dest); } - void orPtr(TrustedImm32 imm, RegisterID dest) + void or64(TrustedImm32 imm, RegisterID dest) { m_assembler.orq_ir(imm.m_value, dest); } - void orPtr(RegisterID op1, RegisterID op2, RegisterID dest) + void or64(RegisterID op1, RegisterID op2, RegisterID dest) { if (op1 == op2) move(op1, dest); else if (op1 == dest) - orPtr(op2, dest); + or64(op2, dest); else { move(op2, dest); - orPtr(op1, dest); + or64(op1, dest); } } - void orPtr(TrustedImm32 imm, RegisterID src, RegisterID dest) + void or64(TrustedImm32 imm, RegisterID src, RegisterID dest) { move(src, dest); - orPtr(imm, dest); + or64(imm, dest); } - void rotateRightPtr(TrustedImm32 imm, RegisterID srcDst) + void rotateRight64(TrustedImm32 imm, RegisterID srcDst) { m_assembler.rorq_i8r(imm.m_value, srcDst); } - void subPtr(RegisterID src, RegisterID dest) + void sub64(RegisterID src, RegisterID dest) { m_assembler.subq_rr(src, dest); } - void subPtr(TrustedImm32 imm, RegisterID dest) + void sub64(TrustedImm32 imm, RegisterID dest) { m_assembler.subq_ir(imm.m_value, dest); } - void subPtr(TrustedImmPtr imm, RegisterID dest) + void sub64(TrustedImm64 imm, RegisterID dest) { move(imm, scratchRegister); - m_assembler.subq_rr(scratchRegister, dest); + sub64(scratchRegister, dest); } - void xorPtr(RegisterID src, RegisterID dest) + void xor64(RegisterID src, RegisterID dest) { m_assembler.xorq_rr(src, dest); } - void xorPtr(RegisterID src, Address dest) + void xor64(RegisterID src, Address dest) { m_assembler.xorq_rm(src, dest.offset, dest.base); } - void xorPtr(TrustedImm32 imm, RegisterID srcDest) + void xor64(TrustedImm32 imm, RegisterID srcDest) { m_assembler.xorq_ir(imm.m_value, srcDest); } - void loadPtr(ImplicitAddress address, RegisterID dest) + void load64(ImplicitAddress address, RegisterID dest) { m_assembler.movq_mr(address.offset, address.base, dest); } - ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest) - { - ConvertibleLoadLabel result = ConvertibleLoadLabel(this); - m_assembler.movq_mr(address.offset, address.base, dest); - return result; - } - - void loadPtr(BaseIndex address, RegisterID dest) + void load64(BaseIndex address, RegisterID dest) { m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest); } - void loadPtr(const void* address, RegisterID dest) + void load64(const void* address, RegisterID dest) { if (dest == X86Registers::eax) m_assembler.movq_mEAX(address); else { move(TrustedImmPtr(address), dest); - loadPtr(dest, dest); + load64(dest, dest); } } - DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest) + DataLabel32 load64WithAddressOffsetPatch(Address address, RegisterID dest) { padBeforePatch(); m_assembler.movq_mr_disp32(address.offset, address.base, dest); return DataLabel32(this); } - DataLabelCompact loadPtrWithCompactAddressOffsetPatch(Address address, RegisterID dest) + DataLabelCompact load64WithCompactAddressOffsetPatch(Address address, RegisterID dest) { padBeforePatch(); m_assembler.movq_mr_disp8(address.offset, address.base, dest); return DataLabelCompact(this); } - void storePtr(RegisterID src, ImplicitAddress address) + void store64(RegisterID src, ImplicitAddress address) { m_assembler.movq_rm(src, address.offset, address.base); } - void storePtr(RegisterID src, BaseIndex address) + void store64(RegisterID src, BaseIndex address) { m_assembler.movq_rm(src, address.offset, address.base, address.index, address.scale); } - void storePtr(RegisterID src, void* address) + void store64(RegisterID src, void* address) { if (src == X86Registers::eax) m_assembler.movq_EAXm(address); else { move(TrustedImmPtr(address), scratchRegister); - storePtr(src, scratchRegister); + store64(src, scratchRegister); } } - void storePtr(TrustedImmPtr imm, ImplicitAddress address) + void store64(TrustedImm64 imm, ImplicitAddress address) { move(imm, scratchRegister); - storePtr(scratchRegister, address); + store64(scratchRegister, address); } - void storePtr(TrustedImmPtr imm, BaseIndex address) + void store64(TrustedImm64 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) + DataLabel32 store64WithAddressOffsetPatch(RegisterID src, Address address) { padBeforePatch(); m_assembler.movq_rm_disp32(src, address.offset, address.base); return DataLabel32(this); } - void movePtrToDouble(RegisterID src, FPRegisterID dest) + void move64ToDouble(RegisterID src, FPRegisterID dest) { m_assembler.movq_rr(src, dest); } - void moveDoubleToPtr(FPRegisterID src, RegisterID dest) + void moveDoubleTo64(FPRegisterID src, RegisterID dest) { m_assembler.movq_rr(src, dest); } - void comparePtr(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest) + void compare64(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest) { if (((cond == Equal) || (cond == NotEqual)) && !right.m_value) m_assembler.testq_rr(left, left); @@ -388,67 +382,60 @@ public: m_assembler.movzbl_rr(dest, dest); } - void comparePtr(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest) + void compare64(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) + Jump branch64(RelationalCondition cond, RegisterID left, RegisterID right) { m_assembler.cmpq_rr(right, left); return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchPtr(RelationalCondition cond, RegisterID left, TrustedImmPtr right) + Jump branch64(RelationalCondition cond, RegisterID left, TrustedImm64 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); + return branch64(cond, left, scratchRegister); } - Jump branchPtr(RelationalCondition cond, RegisterID left, Address right) + Jump branch64(RelationalCondition cond, RegisterID left, Address right) { m_assembler.cmpq_mr(right.offset, right.base, left); return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchPtr(RelationalCondition cond, AbsoluteAddress left, RegisterID right) + Jump branch64(RelationalCondition cond, AbsoluteAddress left, RegisterID right) { move(TrustedImmPtr(left.m_ptr), scratchRegister); - return branchPtr(cond, Address(scratchRegister), right); + return branch64(cond, Address(scratchRegister), right); } - Jump branchPtr(RelationalCondition cond, Address left, RegisterID right) + Jump branch64(RelationalCondition cond, Address left, RegisterID right) { m_assembler.cmpq_rm(right, left.offset, left.base); return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchPtr(RelationalCondition cond, Address left, TrustedImmPtr right) + Jump branch64(RelationalCondition cond, Address left, TrustedImm64 right) { move(right, scratchRegister); - return branchPtr(cond, left, scratchRegister); + return branch64(cond, left, scratchRegister); } - Jump branchTestPtr(ResultCondition cond, RegisterID reg, RegisterID mask) + Jump branchTest64(ResultCondition cond, RegisterID reg, RegisterID mask) { m_assembler.testq_rr(reg, mask); return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchTestPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) + Jump branchTest64(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 if (mask.m_value == -1) @@ -460,7 +447,7 @@ public: return Jump(m_assembler.jCC(x86Condition(cond))); } - void testPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest) + void test64(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest) { if (mask.m_value == -1) m_assembler.testq_rr(reg, reg); @@ -471,19 +458,19 @@ public: set32(x86Condition(cond), dest); } - void testPtr(ResultCondition cond, RegisterID reg, RegisterID mask, RegisterID dest) + void test64(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)) + Jump branchTest64(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1)) { - loadPtr(address.m_ptr, scratchRegister); - return branchTestPtr(cond, scratchRegister, mask); + load64(address.m_ptr, scratchRegister); + return branchTest64(cond, scratchRegister, mask); } - Jump branchTestPtr(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) + Jump branchTest64(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) { if (mask.m_value == -1) m_assembler.cmpq_im(0, address.offset, address.base); @@ -492,13 +479,13 @@ public: return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchTestPtr(ResultCondition cond, Address address, RegisterID reg) + Jump branchTest64(ResultCondition cond, Address address, RegisterID reg) { m_assembler.testq_rm(reg, address.offset, address.base); return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchTestPtr(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1)) + Jump branchTest64(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1)) { if (mask.m_value == -1) m_assembler.cmpq_im(0, address.offset, address.base, address.index, address.scale); @@ -508,28 +495,41 @@ public: } - Jump branchAddPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest) + Jump branchAdd64(ResultCondition cond, TrustedImm32 imm, RegisterID dest) + { + add64(imm, dest); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + + Jump branchAdd64(ResultCondition cond, RegisterID src, RegisterID dest) { - addPtr(imm, dest); + add64(src, dest); return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchAddPtr(ResultCondition cond, RegisterID src, RegisterID dest) + Jump branchSub64(ResultCondition cond, TrustedImm32 imm, RegisterID dest) { - addPtr(src, dest); + sub64(imm, dest); return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchSubPtr(ResultCondition cond, TrustedImm32 imm, RegisterID dest) + Jump branchSub64(ResultCondition cond, RegisterID src, RegisterID dest) { - subPtr(imm, dest); + sub64(src, dest); return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchSubPtr(ResultCondition cond, RegisterID src1, TrustedImm32 src2, RegisterID dest) + Jump branchSub64(ResultCondition cond, RegisterID src1, TrustedImm32 src2, RegisterID dest) { move(src1, dest); - return branchSubPtr(cond, src2, dest); + return branchSub64(cond, src2, dest); + } + + ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest) + { + ConvertibleLoadLabel result = ConvertibleLoadLabel(this); + m_assembler.movq_mr(address.offset, address.base, dest); + return result; } DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest) @@ -542,22 +542,22 @@ public: Jump branchPtrWithPatch(RelationalCondition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) { dataLabel = moveWithPatch(initialRightValue, scratchRegister); - return branchPtr(cond, left, scratchRegister); + return branch64(cond, left, scratchRegister); } Jump branchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) { dataLabel = moveWithPatch(initialRightValue, scratchRegister); - return branchPtr(cond, left, scratchRegister); + return branch64(cond, left, scratchRegister); } DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address) { DataLabelPtr label = moveWithPatch(initialValue, scratchRegister); - storePtr(scratchRegister, address); + store64(scratchRegister, address); return label; } - + using MacroAssemblerX86Common::branchTest8; Jump branchTest8(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1)) { diff --git a/Source/JavaScriptCore/bytecode/ByValInfo.h b/Source/JavaScriptCore/bytecode/ByValInfo.h new file mode 100644 index 000000000..8cba4463d --- /dev/null +++ b/Source/JavaScriptCore/bytecode/ByValInfo.h @@ -0,0 +1,158 @@ +/* + * 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 ByValInfo_h +#define ByValInfo_h + +#include <wtf/Platform.h> + +#if ENABLE(JIT) + +#include "ClassInfo.h" +#include "CodeLocation.h" +#include "IndexingType.h" +#include "JITStubRoutine.h" +#include "Structure.h" + +namespace JSC { + +enum JITArrayMode { + JITContiguous, + JITArrayStorage, + JITInt8Array, + JITInt16Array, + JITInt32Array, + JITUint8Array, + JITUint8ClampedArray, + JITUint16Array, + JITUint32Array, + JITFloat32Array, + JITFloat64Array +}; + +inline bool isOptimizableIndexingType(IndexingType indexingType) +{ + switch (indexingType) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: + return true; + default: + return false; + } +} + +inline bool hasOptimizableIndexingForClassInfo(const ClassInfo* classInfo) +{ + return classInfo->typedArrayStorageType != TypedArrayNone; +} + +inline bool hasOptimizableIndexing(Structure* structure) +{ + return isOptimizableIndexingType(structure->indexingType()) + || hasOptimizableIndexingForClassInfo(structure->classInfo()); +} + +inline JITArrayMode jitArrayModeForIndexingType(IndexingType indexingType) +{ + switch (indexingType) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + return JITContiguous; + case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: + return JITArrayStorage; + default: + CRASH(); + return JITContiguous; + } +} + +inline JITArrayMode jitArrayModeForClassInfo(const ClassInfo* classInfo) +{ + switch (classInfo->typedArrayStorageType) { + case TypedArrayInt8: + return JITInt8Array; + case TypedArrayInt16: + return JITInt16Array; + case TypedArrayInt32: + return JITInt32Array; + case TypedArrayUint8: + return JITUint8Array; + case TypedArrayUint8Clamped: + return JITUint8ClampedArray; + case TypedArrayUint16: + return JITUint16Array; + case TypedArrayUint32: + return JITUint32Array; + case TypedArrayFloat32: + return JITFloat32Array; + case TypedArrayFloat64: + return JITFloat64Array; + default: + CRASH(); + return JITContiguous; + } +} + +inline JITArrayMode jitArrayModeForStructure(Structure* structure) +{ + if (isOptimizableIndexingType(structure->indexingType())) + return jitArrayModeForIndexingType(structure->indexingType()); + + ASSERT(hasOptimizableIndexingForClassInfo(structure->classInfo())); + return jitArrayModeForClassInfo(structure->classInfo()); +} + +struct ByValInfo { + ByValInfo() { } + + ByValInfo(unsigned bytecodeIndex, CodeLocationJump badTypeJump, JITArrayMode arrayMode, int16_t badTypeJumpToDone, int16_t returnAddressToSlowPath) + : bytecodeIndex(bytecodeIndex) + , badTypeJump(badTypeJump) + , arrayMode(arrayMode) + , badTypeJumpToDone(badTypeJumpToDone) + , returnAddressToSlowPath(returnAddressToSlowPath) + , slowPathCount(0) + { + } + + unsigned bytecodeIndex; + CodeLocationJump badTypeJump; + JITArrayMode arrayMode; // The array mode that was baked into the inline JIT code. + int16_t badTypeJumpToDone; + int16_t returnAddressToSlowPath; + unsigned slowPathCount; + RefPtr<JITStubRoutine> stubRoutine; +}; + +inline unsigned getByValInfoBytecodeIndex(ByValInfo* info) +{ + return info->bytecodeIndex; +} + +} // namespace JSC + +#endif // ENABLE(JIT) + +#endif // ByValInfo_h + diff --git a/Source/JavaScriptCore/bytecode/BytecodeConventions.h b/Source/JavaScriptCore/bytecode/BytecodeConventions.h index f33b060f8..e375f263c 100644 --- a/Source/JavaScriptCore/bytecode/BytecodeConventions.h +++ b/Source/JavaScriptCore/bytecode/BytecodeConventions.h @@ -27,7 +27,7 @@ #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. +// 0x80000000-0xFFFFFFFF Negative indices from the CallFrame pointer are entries in the call frame, see JSStack.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; diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index bd8bfec0d..9b8260a79 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -641,7 +641,7 @@ void CodeBlock::dump(ExecState* exec) 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) - dataLog("\t\t\"%s\" => %04d\n", String(iter->first).utf8().data(), iter->second.branchOffset); + dataLog("\t\t\"%s\" => %04d\n", String(iter->key).utf8().data(), iter->value.branchOffset); dataLog(" }\n"); ++i; } while (i < m_rareData->m_stringSwitchJumpTables.size()); @@ -1899,7 +1899,7 @@ void EvalCodeCache::visitAggregate(SlotVisitor& visitor) { EvalCacheMap::iterator end = m_cacheMap.end(); for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr) - visitor.append(&ptr->second); + visitor.append(&ptr->value); } void CodeBlock::visitAggregate(SlotVisitor& visitor) @@ -3002,8 +3002,8 @@ String CodeBlock::nameForRegister(int registerNumber) { SymbolTable::iterator end = m_symbolTable->end(); for (SymbolTable::iterator ptr = m_symbolTable->begin(); ptr != end; ++ptr) { - if (ptr->second.getIndex() == registerNumber) - return String(ptr->first); + if (ptr->value.getIndex() == registerNumber) + return String(ptr->key); } if (needsActivation() && registerNumber == activationRegister()) return ASCIILiteral("activation"); @@ -3017,7 +3017,7 @@ String CodeBlock::nameForRegister(int registerNumber) } if (registerNumber < 0) { int argumentPosition = -registerNumber; - argumentPosition -= RegisterFile::CallFrameHeaderSize + 1; + argumentPosition -= JSStack::CallFrameHeaderSize + 1; return String::format("arguments[%3d]", argumentPosition - 1).impl(); } return ""; diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h index 22c48311c..01a8ef4a1 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.h +++ b/Source/JavaScriptCore/bytecode/CodeBlock.h @@ -31,6 +31,7 @@ #define CodeBlock_h #include "ArrayProfile.h" +#include "ByValInfo.h" #include "BytecodeConventions.h" #include "CallLinkInfo.h" #include "CallReturnOffsetToBytecodeOffset.h" @@ -159,7 +160,7 @@ namespace JSC { return result; } #endif - + void visitAggregate(SlotVisitor&); static void dumpStatistics(); @@ -209,6 +210,11 @@ namespace JSC { } void resetStub(StructureStubInfo&); + + ByValInfo& getByValInfo(unsigned bytecodeIndex) + { + return *(binarySearch<ByValInfo, unsigned, getByValInfoBytecodeIndex>(m_byValInfos.begin(), m_byValInfos.size(), bytecodeIndex)); + } CallLinkInfo& getCallLinkInfo(ReturnAddressPtr returnAddress) { @@ -610,6 +616,10 @@ namespace JSC { void setNumberOfStructureStubInfos(size_t size) { m_structureStubInfos.grow(size); } size_t numberOfStructureStubInfos() const { return m_structureStubInfos.size(); } StructureStubInfo& structureStubInfo(int index) { return m_structureStubInfos[index]; } + + void setNumberOfByValInfos(size_t size) { m_byValInfos.grow(size); } + size_t numberOfByValInfos() const { return m_byValInfos.size(); } + ByValInfo& byValInfo(size_t index) { return m_byValInfos[index]; } void addGlobalResolveInfo(unsigned globalResolveInstruction) { @@ -915,18 +925,32 @@ namespace JSC { } RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); } - unsigned addConstantBuffer(unsigned length) + unsigned numberOfConstantBuffers() const + { + if (!m_rareData) + return 0; + return m_rareData->m_constantBuffers.size(); + } + unsigned addConstantBuffer(const Vector<JSValue>& buffer) { createRareDataIfNecessary(); unsigned size = m_rareData->m_constantBuffers.size(); - m_rareData->m_constantBuffers.append(Vector<JSValue>(length)); + m_rareData->m_constantBuffers.append(buffer); return size; } + unsigned addConstantBuffer(unsigned length) + { + return addConstantBuffer(Vector<JSValue>(length)); + } - JSValue* constantBuffer(unsigned index) + Vector<JSValue>& constantBufferAsVector(unsigned index) { ASSERT(m_rareData); - return m_rareData->m_constantBuffers[index].data(); + return m_rareData->m_constantBuffers[index]; + } + JSValue* constantBuffer(unsigned index) + { + return constantBufferAsVector(index).data(); } JSGlobalObject* globalObject() { return m_globalObject.get(); } @@ -1289,6 +1313,7 @@ namespace JSC { #endif #if ENABLE(JIT) Vector<StructureStubInfo> m_structureStubInfos; + Vector<ByValInfo> m_byValInfos; Vector<GlobalResolveInfo> m_globalResolveInfos; Vector<CallLinkInfo> m_callLinkInfos; Vector<MethodCallLinkInfo> m_methodCallLinkInfos; diff --git a/Source/JavaScriptCore/bytecode/Instruction.h b/Source/JavaScriptCore/bytecode/Instruction.h index b276fd957..9fcf509f6 100644 --- a/Source/JavaScriptCore/bytecode/Instruction.h +++ b/Source/JavaScriptCore/bytecode/Instruction.h @@ -33,6 +33,7 @@ #include "MacroAssembler.h" #include "Opcode.h" #include "PropertySlot.h" +#include "SpecialPointer.h" #include "Structure.h" #include "StructureChain.h" #include <wtf/VectorTraits.h> @@ -195,6 +196,8 @@ namespace JSC { Instruction(WriteBarrier<Unknown>* registerPointer) { u.registerPointer = registerPointer; } + Instruction(Special::Pointer pointer) { u.specialPointer = pointer; } + Instruction(bool* predicatePointer) { u.predicatePointer = predicatePointer; } union { @@ -204,6 +207,7 @@ namespace JSC { WriteBarrierBase<StructureChain> structureChain; WriteBarrierBase<JSCell> jsCell; WriteBarrier<Unknown>* registerPointer; + Special::Pointer specialPointer; PropertySlot::GetValueFunc getterFunc; LLIntCallLinkInfo* callLinkInfo; ValueProfile* profile; diff --git a/Source/JavaScriptCore/bytecode/JumpTable.h b/Source/JavaScriptCore/bytecode/JumpTable.h index a01f90cb0..f54a3718f 100644 --- a/Source/JavaScriptCore/bytecode/JumpTable.h +++ b/Source/JavaScriptCore/bytecode/JumpTable.h @@ -57,7 +57,7 @@ namespace JSC { StringOffsetTable::const_iterator loc = offsetTable.find(value); if (loc == end) return defaultOffset; - return loc->second.branchOffset; + return loc->value.branchOffset; } #if ENABLE(JIT) @@ -67,7 +67,7 @@ namespace JSC { StringOffsetTable::const_iterator loc = offsetTable.find(value); if (loc == end) return ctiDefault; - return loc->second.ctiOffset; + return loc->value.ctiOffset; } #endif }; diff --git a/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp b/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp index 59f0d0234..f923e4a28 100644 --- a/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp +++ b/Source/JavaScriptCore/bytecode/LazyOperandValueProfile.cpp @@ -81,7 +81,7 @@ LazyOperandValueProfile* LazyOperandValueProfileParser::getIfPresent( if (iter == m_map.end()) return 0; - return iter->second; + return iter->value; } SpeculatedType LazyOperandValueProfileParser::prediction( diff --git a/Source/JavaScriptCore/bytecode/SamplingTool.cpp b/Source/JavaScriptCore/bytecode/SamplingTool.cpp index f07dc79fb..f9b8245e5 100644 --- a/Source/JavaScriptCore/bytecode/SamplingTool.cpp +++ b/Source/JavaScriptCore/bytecode/SamplingTool.cpp @@ -410,7 +410,7 @@ void SamplingTool::dump(ExecState* exec) Vector<ScriptSampleRecord*> codeBlockSamples(scopeCount); ScriptSampleRecordMap::iterator iter = m_scopeSampleMap->begin(); for (int i = 0; i < scopeCount; ++i, ++iter) - codeBlockSamples[i] = iter->second.get(); + codeBlockSamples[i] = iter->value.get(); qsort(codeBlockSamples.begin(), scopeCount, sizeof(ScriptSampleRecord*), compareScriptSampleRecords); @@ -446,8 +446,8 @@ void SamplingTool::dump(ExecState* exec) Vector<LineCountInfo> lineCountInfo(linesCount); int lineno = 0; for (HashMap<unsigned,unsigned>::iterator iter = lineCounts.begin(); iter != lineCounts.end(); ++iter, ++lineno) { - lineCountInfo[lineno].line = iter->first; - lineCountInfo[lineno].count = iter->second; + lineCountInfo[lineno].line = iter->key; + lineCountInfo[lineno].count = iter->value; } qsort(lineCountInfo.begin(), linesCount, sizeof(LineCountInfo), compareLineCountInfoSampling); diff --git a/Source/JavaScriptCore/bytecode/SamplingTool.h b/Source/JavaScriptCore/bytecode/SamplingTool.h index 52a6e35ad..8f90c3e17 100644 --- a/Source/JavaScriptCore/bytecode/SamplingTool.h +++ b/Source/JavaScriptCore/bytecode/SamplingTool.h @@ -37,6 +37,7 @@ #include <wtf/Atomics.h> #include <wtf/HashMap.h> #include <wtf/MainThread.h> +#include <wtf/Spectrum.h> #include <wtf/Threading.h> namespace JSC { diff --git a/Source/JavaScriptCore/bytecode/SpecialPointer.cpp b/Source/JavaScriptCore/bytecode/SpecialPointer.cpp new file mode 100644 index 000000000..7789653f0 --- /dev/null +++ b/Source/JavaScriptCore/bytecode/SpecialPointer.cpp @@ -0,0 +1,45 @@ +/* + * 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 "SpecialPointer.h" + +#include "CodeBlock.h" +#include "JSGlobalObject.h" + +namespace JSC { + +void* actualPointerFor(JSGlobalObject* globalObject, Special::Pointer pointer) +{ + return globalObject->actualPointerFor(pointer); +} + +void* actualPointerFor(CodeBlock* codeBlock, Special::Pointer pointer) +{ + return actualPointerFor(codeBlock->globalObject(), pointer); +} + +} // namespace JSC + diff --git a/Source/JavaScriptCore/bytecode/SpecialPointer.h b/Source/JavaScriptCore/bytecode/SpecialPointer.h new file mode 100644 index 000000000..2c624784b --- /dev/null +++ b/Source/JavaScriptCore/bytecode/SpecialPointer.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 SpecialPointer_h +#define SpecialPointer_h + +namespace JSC { + +class CodeBlock; +class JSGlobalObject; + +namespace Special { +enum Pointer { + CallFunction, + ApplyFunction, + TableSize // Not a real special pointer. Use this to determine the number of pointers. +}; +} // namespace Special + +inline bool pointerIsFunction(Special::Pointer pointer) +{ + ASSERT_UNUSED(pointer, pointer < Special::TableSize); + return true; +} + +inline bool pointerIsCell(Special::Pointer pointer) +{ + ASSERT_UNUSED(pointer, pointer < Special::TableSize); + return true; +} + +void* actualPointerFor(JSGlobalObject*, Special::Pointer); +void* actualPointerFor(CodeBlock*, Special::Pointer); + +} // namespace JSC + +#endif // SpecialPointer_h + diff --git a/Source/JavaScriptCore/bytecode/ValueRecovery.h b/Source/JavaScriptCore/bytecode/ValueRecovery.h index 1be5201ea..93ad221d8 100644 --- a/Source/JavaScriptCore/bytecode/ValueRecovery.h +++ b/Source/JavaScriptCore/bytecode/ValueRecovery.h @@ -38,13 +38,13 @@ 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 already in the stack at the right location. + AlreadyInJSStack, + // It's already in the stack but unboxed. + AlreadyInJSStackAsUnboxedInt32, + AlreadyInJSStackAsUnboxedCell, + AlreadyInJSStackAsUnboxedBoolean, + AlreadyInJSStackAsUnboxedDouble, // It's in a register. InGPR, UnboxedInt32InGPR, @@ -54,13 +54,13 @@ enum ValueRecoveryTechnique { #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 in the stack, but at a different location. + DisplacedInJSStack, + // It's in the stack, at a different location, and it's unboxed. + Int32DisplacedInJSStack, + DoubleDisplacedInJSStack, + CellDisplacedInJSStack, + BooleanDisplacedInJSStack, // It's an Arguments object. ArgumentsThatWereNotCreated, // It's a constant. @@ -79,38 +79,38 @@ public: bool isSet() const { return m_technique != DontKnow; } bool operator!() const { return !isSet(); } - static ValueRecovery alreadyInRegisterFile() + static ValueRecovery alreadyInJSStack() { ValueRecovery result; - result.m_technique = AlreadyInRegisterFile; + result.m_technique = AlreadyInJSStack; return result; } - static ValueRecovery alreadyInRegisterFileAsUnboxedInt32() + static ValueRecovery alreadyInJSStackAsUnboxedInt32() { ValueRecovery result; - result.m_technique = AlreadyInRegisterFileAsUnboxedInt32; + result.m_technique = AlreadyInJSStackAsUnboxedInt32; return result; } - static ValueRecovery alreadyInRegisterFileAsUnboxedCell() + static ValueRecovery alreadyInJSStackAsUnboxedCell() { ValueRecovery result; - result.m_technique = AlreadyInRegisterFileAsUnboxedCell; + result.m_technique = AlreadyInJSStackAsUnboxedCell; return result; } - static ValueRecovery alreadyInRegisterFileAsUnboxedBoolean() + static ValueRecovery alreadyInJSStackAsUnboxedBoolean() { ValueRecovery result; - result.m_technique = AlreadyInRegisterFileAsUnboxedBoolean; + result.m_technique = AlreadyInJSStackAsUnboxedBoolean; return result; } - static ValueRecovery alreadyInRegisterFileAsUnboxedDouble() + static ValueRecovery alreadyInJSStackAsUnboxedDouble() { ValueRecovery result; - result.m_technique = AlreadyInRegisterFileAsUnboxedDouble; + result.m_technique = AlreadyInJSStackAsUnboxedDouble; return result; } @@ -158,29 +158,29 @@ public: return result; } - static ValueRecovery displacedInRegisterFile(VirtualRegister virtualReg, DataFormat dataFormat) + static ValueRecovery displacedInJSStack(VirtualRegister virtualReg, DataFormat dataFormat) { ValueRecovery result; switch (dataFormat) { case DataFormatInteger: - result.m_technique = Int32DisplacedInRegisterFile; + result.m_technique = Int32DisplacedInJSStack; break; case DataFormatDouble: - result.m_technique = DoubleDisplacedInRegisterFile; + result.m_technique = DoubleDisplacedInJSStack; break; case DataFormatCell: - result.m_technique = CellDisplacedInRegisterFile; + result.m_technique = CellDisplacedInJSStack; break; case DataFormatBoolean: - result.m_technique = BooleanDisplacedInRegisterFile; + result.m_technique = BooleanDisplacedInJSStack; break; default: ASSERT(dataFormat != DataFormatNone && dataFormat != DataFormatStorage); - result.m_technique = DisplacedInRegisterFile; + result.m_technique = DisplacedInJSStack; break; } result.m_source.virtualReg = virtualReg; @@ -222,14 +222,14 @@ public: } } - bool isAlreadyInRegisterFile() const + bool isAlreadyInJSStack() const { switch (technique()) { - case AlreadyInRegisterFile: - case AlreadyInRegisterFileAsUnboxedInt32: - case AlreadyInRegisterFileAsUnboxedCell: - case AlreadyInRegisterFileAsUnboxedBoolean: - case AlreadyInRegisterFileAsUnboxedDouble: + case AlreadyInJSStack: + case AlreadyInJSStackAsUnboxedInt32: + case AlreadyInJSStackAsUnboxedCell: + case AlreadyInJSStackAsUnboxedBoolean: + case AlreadyInJSStackAsUnboxedDouble: return true; default: return false; @@ -264,7 +264,7 @@ public: VirtualRegister virtualRegister() const { - ASSERT(m_technique == DisplacedInRegisterFile || m_technique == Int32DisplacedInRegisterFile || m_technique == DoubleDisplacedInRegisterFile || m_technique == CellDisplacedInRegisterFile || m_technique == BooleanDisplacedInRegisterFile); + ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack); return m_source.virtualReg; } @@ -277,19 +277,19 @@ public: void dump(FILE* out) const { switch (technique()) { - case AlreadyInRegisterFile: + case AlreadyInJSStack: fprintf(out, "-"); break; - case AlreadyInRegisterFileAsUnboxedInt32: + case AlreadyInJSStackAsUnboxedInt32: fprintf(out, "(int32)"); break; - case AlreadyInRegisterFileAsUnboxedCell: + case AlreadyInJSStackAsUnboxedCell: fprintf(out, "(cell)"); break; - case AlreadyInRegisterFileAsUnboxedBoolean: + case AlreadyInJSStackAsUnboxedBoolean: fprintf(out, "(bool)"); break; - case AlreadyInRegisterFileAsUnboxedDouble: + case AlreadyInJSStackAsUnboxedDouble: fprintf(out, "(double)"); break; case InGPR: @@ -312,19 +312,19 @@ public: fprintf(out, "pair(%%r%d, %%r%d)", tagGPR(), payloadGPR()); break; #endif - case DisplacedInRegisterFile: + case DisplacedInJSStack: fprintf(out, "*%d", virtualRegister()); break; - case Int32DisplacedInRegisterFile: + case Int32DisplacedInJSStack: fprintf(out, "*int32(%d)", virtualRegister()); break; - case DoubleDisplacedInRegisterFile: + case DoubleDisplacedInJSStack: fprintf(out, "*double(%d)", virtualRegister()); break; - case CellDisplacedInRegisterFile: + case CellDisplacedInJSStack: fprintf(out, "*cell(%d)", virtualRegister()); break; - case BooleanDisplacedInRegisterFile: + case BooleanDisplacedInJSStack: fprintf(out, "*bool(%d)", virtualRegister()); break; case ArgumentsThatWereNotCreated: diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp index 9e993ec65..4308148b3 100644 --- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp +++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp @@ -230,7 +230,7 @@ bool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, Registe SymbolTable::AddResult result = symbolTable().add(ident.impl(), newEntry); if (!result.isNewEntry) { - r0 = ®isterFor(result.iterator->second.getIndex()); + r0 = ®isterFor(result.iterator->value.getIndex()); return false; } @@ -248,8 +248,8 @@ int BytecodeGenerator::addGlobalVar( newEntry.attemptToWatch(); SymbolTable::AddResult result = symbolTable().add(ident.impl(), newEntry); if (!result.isNewEntry) { - result.iterator->second.notifyWrite(); - index = result.iterator->second.getIndex(); + result.iterator->value.notifyWrite(); + index = result.iterator->value.getIndex(); } return index; } @@ -629,7 +629,7 @@ RegisterID* BytecodeGenerator::resolveCallee(FunctionBodyNode* functionBodyNode) if (functionBodyNode->ident().isNull() || !functionBodyNode->functionNameIsInScope()) return 0; - m_calleeRegister.setIndex(RegisterFile::Callee); + m_calleeRegister.setIndex(JSStack::Callee); // If non-strict eval is in play, we use a separate object in the scope chain for the callee's name. if ((m_codeBlock->usesEval() && !m_codeBlock->isStrictMode()) || m_shouldEmitDebugHooks) { @@ -1129,7 +1129,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, emitOpcode(op_jneq_ptr); instructions().append(cond->index()); - instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scope->globalObject()->callFunction())); + instructions().append(Special::CallFunction); instructions().append(target->bind(begin, instructions().size())); return target; } @@ -1140,7 +1140,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond emitOpcode(op_jneq_ptr); instructions().append(cond->index()); - instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scope->globalObject()->applyFunction())); + instructions().append(Special::ApplyFunction); instructions().append(target->bind(begin, instructions().size())); return target; } @@ -1152,7 +1152,7 @@ unsigned BytecodeGenerator::addConstant(const Identifier& ident) if (result.isNewEntry) m_codeBlock->addIdentifier(Identifier(m_globalData, rep)); - return result.iterator->second; + return result.iterator->value; } // We can't hash JSValue(), so we use a dedicated data member to cache it. @@ -1181,7 +1181,7 @@ RegisterID* BytecodeGenerator::addConstantValue(JSValue v) ++m_nextConstantOffset; m_codeBlock->addConstant(v); } else - index = result.iterator->second; + index = result.iterator->value; return &m_constantPoolRegisters[index]; } @@ -1327,7 +1327,7 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number) // work correctly with NaN as a key. if (isnan(number) || number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number)) return emitLoad(dst, jsNumber(number)); - JSValue& valueInMap = m_numberMap.add(number, JSValue()).iterator->second; + JSValue& valueInMap = m_numberMap.add(number, JSValue()).iterator->value; if (!valueInMap) valueInMap = jsNumber(number); return emitLoad(dst, valueInMap); @@ -1335,7 +1335,7 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number) RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier) { - JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).iterator->second; + JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).iterator->value; if (!stringInMap) stringInMap = jsOwnedString(globalData(), identifier.string()); return emitLoad(dst, JSValue(stringInMap)); @@ -1907,7 +1907,7 @@ unsigned BytecodeGenerator::addConstantBuffer(unsigned length) JSString* BytecodeGenerator::addStringConstant(const Identifier& identifier) { - JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).iterator->second; + JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).iterator->value; if (!stringInMap) { stringInMap = jsString(globalData(), identifier.string()); addConstantValue(stringInMap); @@ -1979,8 +1979,8 @@ RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBody { FunctionOffsetMap::AddResult ptr = m_functionOffsets.add(function, 0); if (ptr.isNewEntry) - ptr.iterator->second = m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, function)); - return emitNewFunctionInternal(dst, ptr.iterator->second, true); + ptr.iterator->value = m_codeBlock->addFunctionDecl(FunctionExecutable::create(*m_globalData, function)); + return emitNewFunctionInternal(dst, ptr.iterator->value, true); } RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck) @@ -2065,8 +2065,8 @@ RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Regi emitNode(callArguments.argumentRegister(argument++), n); // Reserve space for call frame. - Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame; - for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i) + Vector<RefPtr<RegisterID>, JSStack::CallFrameHeaderSize> callFrame; + for (int i = 0; i < JSStack::CallFrameHeaderSize; ++i) callFrame.append(newTemporary()); if (m_shouldEmitProfileHooks) { @@ -2182,8 +2182,8 @@ RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, } // Reserve space for call frame. - Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame; - for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i) + Vector<RefPtr<RegisterID>, JSStack::CallFrameHeaderSize> callFrame; + for (int i = 0; i < JSStack::CallFrameHeaderSize; ++i) callFrame.append(newTemporary()); emitExpressionInfo(divot, startOffset, endOffset); diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h index 1bf1d8f26..a429c710e 100644 --- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h +++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h @@ -629,11 +629,11 @@ namespace JSC { if (index >= 0) return m_calleeRegisters[index]; - if (index == RegisterFile::Callee) + if (index == JSStack::Callee) return m_calleeRegister; ASSERT(m_parameters.size()); - return m_parameters[index + m_parameters.size() + RegisterFile::CallFrameHeaderSize]; + return m_parameters[index + m_parameters.size() + JSStack::CallFrameHeaderSize]; } unsigned addConstant(const Identifier&); diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp index 823dadf14..0ac4149b6 100644 --- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp +++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp @@ -260,7 +260,7 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe GetterSetterPair pair(node, static_cast<PropertyNode*>(0)); GetterSetterMap::AddResult result = map.add(node->name().impl(), pair); if (!result.isNewEntry) - result.iterator->second.second = node; + result.iterator->value.second = node; } // Iterate over the remaining properties in the list. @@ -278,7 +278,7 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe ASSERT(node->m_type == PropertyNode::Getter || node->m_type == PropertyNode::Setter); GetterSetterMap::iterator it = map.find(node->name().impl()); ASSERT(it != map.end()); - GetterSetterPair& pair = it->second; + GetterSetterPair& pair = it->value; // Was this already generated as a part of its partner? if (pair.second == node) diff --git a/Source/JavaScriptCore/debugger/Debugger.cpp b/Source/JavaScriptCore/debugger/Debugger.cpp index 8d360efc2..3731b0473 100644 --- a/Source/JavaScriptCore/debugger/Debugger.cpp +++ b/Source/JavaScriptCore/debugger/Debugger.cpp @@ -59,7 +59,7 @@ inline Recompiler::~Recompiler() // JavaScript in the inspector. SourceProviderMap::const_iterator end = m_sourceProviders.end(); for (SourceProviderMap::const_iterator iter = m_sourceProviders.begin(); iter != end; ++iter) - m_debugger->sourceParsed(iter->second, iter->first, -1, String()); + m_debugger->sourceParsed(iter->value, iter->key, -1, String()); } inline void Recompiler::operator()(JSCell* cell) diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp index db0861c7d..da5682f55 100644 --- a/Source/JavaScriptCore/dfg/DFGAbstractState.cpp +++ b/Source/JavaScriptCore/dfg/DFGAbstractState.cpp @@ -859,12 +859,16 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(node.child2()).filter(SpecInt32); forNode(nodeIndex).makeTop(); break; + case IN_BOUNDS_CONTIGUOUS_MODES: case IN_BOUNDS_ARRAY_STORAGE_MODES: forNode(node.child2()).filter(SpecInt32); forNode(nodeIndex).makeTop(); break; + case OUT_OF_BOUNDS_CONTIGUOUS_MODES: case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES: - case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: + case SLOW_PUT_ARRAY_STORAGE_MODES: + case ALL_EFFECTFUL_MODES: + forNode(node.child1()).filter(SpecCell); forNode(node.child2()).filter(SpecInt32); clobberWorld(node.codeOrigin, indexInBlock); forNode(nodeIndex).makeTop(); @@ -908,6 +912,9 @@ bool AbstractState::execute(unsigned indexInBlock) forNode(node.child2()).filter(SpecInt32); forNode(nodeIndex).set(SpecDouble); break; + default: + ASSERT_NOT_REACHED(); + break; } break; } @@ -915,6 +922,7 @@ bool AbstractState::execute(unsigned indexInBlock) case PutByVal: case PutByValAlias: { node.setCanExit(true); + Edge child1 = m_graph.varArgChild(node, 0); Edge child2 = m_graph.varArgChild(node, 1); Edge child3 = m_graph.varArgChild(node, 2); switch (modeForPut(node.arrayMode())) { @@ -924,11 +932,17 @@ bool AbstractState::execute(unsigned indexInBlock) case Array::Generic: clobberWorld(node.codeOrigin, indexInBlock); break; + case IN_BOUNDS_CONTIGUOUS_MODES: + case CONTIGUOUS_TO_TAIL_MODES: case IN_BOUNDS_ARRAY_STORAGE_MODES: forNode(child2).filter(SpecInt32); break; + case OUT_OF_BOUNDS_CONTIGUOUS_MODES: + case ARRAY_STORAGE_TO_HOLE_MODES: case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES: - case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: + case SLOW_PUT_ARRAY_STORAGE_MODES: + case ALL_EFFECTFUL_MODES: + forNode(child1).filter(SpecCell); forNode(child2).filter(SpecInt32); clobberWorld(node.codeOrigin, indexInBlock); break; @@ -1110,16 +1124,15 @@ bool AbstractState::execute(unsigned indexInBlock) break; case NewArrayBuffer: - // Unless we're having a bad time, this node can change its mind about what structure - // it uses. - node.setCanExit(false); - forNode(nodeIndex).set(SpecArray); + node.setCanExit(true); + forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructure()); + m_haveStructures = true; break; case NewArrayWithSize: node.setCanExit(true); forNode(node.child1()).filter(SpecInt32); - forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructure()); + forNode(nodeIndex).set(SpecArray); m_haveStructures = true; break; @@ -1367,6 +1380,7 @@ bool AbstractState::execute(unsigned indexInBlock) case Array::String: forNode(node.child1()).filter(SpecString); break; + case ALL_CONTIGUOUS_MODES: case ALL_ARRAY_STORAGE_MODES: // This doesn't filter anything meaningful right now. We may want to add // CFA tracking of array mode speculations, but we don't have that, yet. @@ -1410,9 +1424,11 @@ bool AbstractState::execute(unsigned indexInBlock) } case Arrayify: { switch (node.arrayMode()) { - case EFFECTFUL_NON_ARRAY_ARRAY_STORAGE_MODES: + case ALL_EFFECTFUL_MODES: node.setCanExit(true); forNode(node.child1()).filter(SpecCell); + if (node.child2()) + forNode(node.child2()).filter(SpecInt32); forNode(nodeIndex).clear(); clobberStructures(indexInBlock); break; diff --git a/Source/JavaScriptCore/dfg/DFGAbstractState.h b/Source/JavaScriptCore/dfg/DFGAbstractState.h index d2bc1a551..ec1a06231 100644 --- a/Source/JavaScriptCore/dfg/DFGAbstractState.h +++ b/Source/JavaScriptCore/dfg/DFGAbstractState.h @@ -185,7 +185,7 @@ public: void reset(); // Abstractly executes the given node. The new abstract state is stored into an - // abstract register file stored in *this. Loads of local variables (that span + // abstract stack stored in *this. Loads of local variables (that span // basic blocks) interrogate the basic block's notion of the state at the head. // Stores to local variables are handled in endBasicBlock(). This returns true // if execution should continue past this node. Notably, it will return true diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp index 513357424..bb61a59e6 100644 --- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp @@ -210,7 +210,7 @@ public: // Make sure that if it's a variable that we think is aliased to // the arguments, that we know that it might actually not be. ArgumentsAliasingData& data = - m_argumentsAliasing.find(variableAccessData)->second; + m_argumentsAliasing.find(variableAccessData)->value; data.mergeNonArgumentsAssignment(); data.mergeCallContext(node.codeOrigin.inlineCallFrame); break; @@ -228,7 +228,7 @@ public: break; } ArgumentsAliasingData& data = - m_argumentsAliasing.find(variableAccessData)->second; + m_argumentsAliasing.find(variableAccessData)->value; data.mergeArgumentsAssignment(); // This ensures that the variable's uses are in the same context as // the arguments it is aliasing. @@ -243,7 +243,7 @@ public: if (variableAccessData->isCaptured()) break; ArgumentsAliasingData& data = - m_argumentsAliasing.find(variableAccessData)->second; + m_argumentsAliasing.find(variableAccessData)->value; data.mergeCallContext(node.codeOrigin.inlineCallFrame); break; } @@ -253,7 +253,7 @@ public: if (variableAccessData->isCaptured()) break; ArgumentsAliasingData& data = - m_argumentsAliasing.find(variableAccessData)->second; + m_argumentsAliasing.find(variableAccessData)->value; data.mergeCallContext(node.codeOrigin.inlineCallFrame); // If a variable is used in a flush then by definition it escapes. @@ -266,7 +266,7 @@ public: if (variableAccessData->isCaptured()) break; ArgumentsAliasingData& data = - m_argumentsAliasing.find(variableAccessData)->second; + m_argumentsAliasing.find(variableAccessData)->value; data.mergeNonArgumentsAssignment(); data.mergeCallContext(node.codeOrigin.inlineCallFrame); break; @@ -350,7 +350,7 @@ public: } ArgumentsAliasingData& data = - m_argumentsAliasing.find(variableAccessData)->second; + m_argumentsAliasing.find(variableAccessData)->value; if (data.isValid()) continue; @@ -369,7 +369,7 @@ public: dataLog("Captured"); else { ArgumentsAliasingData& data = - m_argumentsAliasing.find(variableAccessData)->second; + m_argumentsAliasing.find(variableAccessData)->value; bool first = true; if (data.callContextIsValid()) { if (!first) @@ -441,7 +441,7 @@ public: // things. Note also that the SetLocal should become dead as soon as // we replace all uses of this variable with GetMyArgumentsLength and // GetMyArgumentByVal. - ASSERT(m_argumentsAliasing.find(variableAccessData)->second.isValid()); + ASSERT(m_argumentsAliasing.find(variableAccessData)->value.isValid()); changed |= variableAccessData->mergeIsArgumentsAlias(true); break; } @@ -685,7 +685,7 @@ private: if (variableAccessData->isCaptured()) break; - ArgumentsAliasingData& data = m_argumentsAliasing.find(variableAccessData)->second; + ArgumentsAliasingData& data = m_argumentsAliasing.find(variableAccessData)->value; data.escapes = true; break; } @@ -734,7 +734,7 @@ private: if (variableAccessData->isCaptured()) return; - ArgumentsAliasingData& data = m_argumentsAliasing.find(variableAccessData)->second; + ArgumentsAliasingData& data = m_argumentsAliasing.find(variableAccessData)->value; data.mergeCallContext(node.codeOrigin.inlineCallFrame); } @@ -756,7 +756,7 @@ private: if (variableAccessData->isCaptured()) break; ArgumentsAliasingData& data = - m_argumentsAliasing.find(variableAccessData)->second; + m_argumentsAliasing.find(variableAccessData)->value; if (!data.isValid()) break; @@ -792,7 +792,7 @@ private: && !m_createsArguments.contains(child.codeOrigin.inlineCallFrame); bool isAliasedArgumentsRegister = !variableAccessData->isCaptured() - && m_argumentsAliasing.find(variableAccessData)->second.isValid() + && m_argumentsAliasing.find(variableAccessData)->value.isValid() && !m_createsArguments.contains(child.codeOrigin.inlineCallFrame); if (!isDeadArgumentsRegister && !isAliasedArgumentsRegister) break; diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp index 12c9640c8..3985d769c 100644 --- a/Source/JavaScriptCore/dfg/DFGArrayMode.cpp +++ b/Source/JavaScriptCore/dfg/DFGArrayMode.cpp @@ -39,8 +39,14 @@ Array::Mode fromObserved(ArrayProfile* profile, Array::Action action, bool makeS return Array::Unprofiled; case asArrayModes(NonArray): if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) - return Array::BlankToArrayStorage; // FIXME: we don't know whether to go to slow put mode, or not. This is a decent guess. + return Array::ToContiguous; // FIXME: we don't know whether to go to contiguous or array storage. We're making a static guess here. In future we should use exit profiling for this. return Array::Undecided; + case asArrayModes(NonArrayWithContiguous): + return makeSafe ? Array::ContiguousOutOfBounds : (profile->mayStoreToHole() ? Array::ContiguousToTail : Array::Contiguous); + case asArrayModes(ArrayWithContiguous): + return makeSafe ? Array::ArrayWithContiguousOutOfBounds : (profile->mayStoreToHole() ? Array::ArrayWithContiguousToTail : Array::ArrayWithContiguous); + case asArrayModes(NonArrayWithContiguous) | asArrayModes(ArrayWithContiguous): + return makeSafe ? Array::PossiblyArrayWithContiguousOutOfBounds : (profile->mayStoreToHole() ? Array::PossiblyArrayWithContiguousToTail : Array::PossiblyArrayWithContiguous); case asArrayModes(NonArrayWithArrayStorage): return makeSafe ? Array::ArrayStorageOutOfBounds : (profile->mayStoreToHole() ? Array::ArrayStorageToHole : Array::ArrayStorage); case asArrayModes(NonArrayWithSlowPutArrayStorage): @@ -56,14 +62,25 @@ Array::Mode fromObserved(ArrayProfile* profile, Array::Action action, bool makeS case asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage): case asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage): return Array::PossiblyArrayWithSlowPutArrayStorage; + case asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage): + return Array::ToArrayStorage; + case asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage): + return Array::ArrayToArrayStorage; + case asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage): + return Array::PossiblyArrayToArrayStorage; + case asArrayModes(NonArray) | asArrayModes(NonArrayWithContiguous): + if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) + return Array::ToContiguous; + return Array::Undecided; + case asArrayModes(NonArray) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage): case asArrayModes(NonArray) | asArrayModes(NonArrayWithArrayStorage): if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) - return Array::BlankToArrayStorage; + return Array::ToArrayStorage; return Array::Undecided; case asArrayModes(NonArray) | asArrayModes(NonArrayWithSlowPutArrayStorage): case asArrayModes(NonArray) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage): if (action == Array::Write && !profile->mayInterceptIndexedAccesses()) - return Array::BlankToSlowPutArrayStorage; + return Array::ToSlowPutArrayStorage; return Array::Undecided; default: // We know that this is possibly a kind of array for which, though there is no @@ -144,6 +161,22 @@ bool modeAlreadyChecked(AbstractValue& value, Array::Mode arrayMode) case Array::String: return isStringSpeculation(value.m_type); + case Array::Contiguous: + case Array::ContiguousToTail: + case Array::ContiguousOutOfBounds: + case Array::PossiblyArrayWithContiguous: + case Array::PossiblyArrayWithContiguousToTail: + case Array::PossiblyArrayWithContiguousOutOfBounds: + return value.m_currentKnownStructure.hasSingleton() + && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType()); + + case Array::ArrayWithContiguous: + case Array::ArrayWithContiguousToTail: + case Array::ArrayWithContiguousOutOfBounds: + return value.m_currentKnownStructure.hasSingleton() + && hasContiguous(value.m_currentKnownStructure.singleton()->indexingType()) + && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray); + case Array::ArrayStorage: case Array::ArrayStorageToHole: case Array::ArrayStorageOutOfBounds: @@ -151,26 +184,26 @@ bool modeAlreadyChecked(AbstractValue& value, Array::Mode arrayMode) case Array::PossiblyArrayWithArrayStorageToHole: case Array::PossiblyArrayWithArrayStorageOutOfBounds: return value.m_currentKnownStructure.hasSingleton() - && (value.m_currentKnownStructure.singleton()->indexingType() & HasArrayStorage); + && hasFastArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()); case Array::SlowPutArrayStorage: case Array::PossiblyArrayWithSlowPutArrayStorage: return value.m_currentKnownStructure.hasSingleton() - && (value.m_currentKnownStructure.singleton()->indexingType() & (HasArrayStorage | HasSlowPutArrayStorage)); + && hasArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()); case Array::ArrayWithArrayStorage: case Array::ArrayWithArrayStorageToHole: case Array::ArrayWithArrayStorageOutOfBounds: return value.m_currentKnownStructure.hasSingleton() - && (value.m_currentKnownStructure.singleton()->indexingType() & HasArrayStorage) + && hasFastArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()) && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray); case Array::ArrayWithSlowPutArrayStorage: return value.m_currentKnownStructure.hasSingleton() - && (value.m_currentKnownStructure.singleton()->indexingType() & (HasArrayStorage | HasSlowPutArrayStorage)) + && hasArrayStorage(value.m_currentKnownStructure.singleton()->indexingType()) && (value.m_currentKnownStructure.singleton()->indexingType() & IsArray); - case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: + case ALL_EFFECTFUL_MODES: return false; case Array::Arguments: @@ -225,6 +258,24 @@ const char* modeToString(Array::Mode mode) return "ForceExit"; case Array::String: return "String"; + case Array::Contiguous: + return "Contiguous"; + case Array::ContiguousToTail: + return "ContiguousToTail"; + case Array::ContiguousOutOfBounds: + return "ContiguousOutOfBounds"; + case Array::ArrayWithContiguous: + return "ArrayWithContiguous"; + case Array::ArrayWithContiguousToTail: + return "ArrayWithContiguousToTail"; + case Array::ArrayWithContiguousOutOfBounds: + return "ArrayWithContiguousOutOfBounds"; + case Array::PossiblyArrayWithContiguous: + return "PossiblyArrayWithContiguous"; + case Array::PossiblyArrayWithContiguousToTail: + return "PossiblyArrayWithContiguousToTail"; + case Array::PossiblyArrayWithContiguousOutOfBounds: + return "PossiblyArrayWithContiguousOutOfBounds"; case Array::ArrayStorage: return "ArrayStorage"; case Array::ArrayStorageToHole: @@ -249,10 +300,16 @@ const char* modeToString(Array::Mode mode) return "PossiblyArrayWithSlowPutArrayStorage"; case Array::PossiblyArrayWithArrayStorageOutOfBounds: return "PossiblyArrayWithArrayStorageOutOfBounds"; - case Array::BlankToArrayStorage: - return "BlankToArrayStorage"; - case Array::BlankToSlowPutArrayStorage: - return "BlankToSlowPutArrayStorage"; + case Array::ToContiguous: + return "ToContiguous"; + case Array::ToArrayStorage: + return "ToArrayStorage"; + case Array::ToSlowPutArrayStorage: + return "ToSlowPutArrayStorage"; + case Array::ArrayToArrayStorage: + return "ArrayToArrayStorage"; + case Array::PossiblyArrayToArrayStorage: + return "PossiblyArrayToArrayStorage"; case Array::Arguments: return "Arguments"; case Array::Int8Array: diff --git a/Source/JavaScriptCore/dfg/DFGArrayMode.h b/Source/JavaScriptCore/dfg/DFGArrayMode.h index d4be9c0eb..a666bb83f 100644 --- a/Source/JavaScriptCore/dfg/DFGArrayMode.h +++ b/Source/JavaScriptCore/dfg/DFGArrayMode.h @@ -54,6 +54,15 @@ enum Mode { String, // Modes of conventional indexed storage where the check is non side-effecting. + Contiguous, + ContiguousToTail, + ContiguousOutOfBounds, + ArrayWithContiguous, + ArrayWithContiguousToTail, + ArrayWithContiguousOutOfBounds, + PossiblyArrayWithContiguous, + PossiblyArrayWithContiguousToTail, + PossiblyArrayWithContiguousOutOfBounds, ArrayStorage, ArrayStorageToHole, SlowPutArrayStorage, @@ -68,8 +77,11 @@ enum Mode { PossiblyArrayWithArrayStorageOutOfBounds, // Modes of conventional indexed storage where the check is side-effecting. - BlankToArrayStorage, - BlankToSlowPutArrayStorage, + ToContiguous, + ToArrayStorage, + ArrayToArrayStorage, + PossiblyArrayToArrayStorage, + ToSlowPutArrayStorage, Arguments, Int8Array, @@ -89,6 +101,32 @@ enum Mode { // have the word "ArrayStorage" in them. // First: helpers for non-side-effecting checks. +#define NON_ARRAY_CONTIGUOUS_MODES \ + Array::Contiguous: \ + case Array::ContiguousToTail: \ + case Array::ContiguousOutOfBounds: \ + case Array::PossiblyArrayWithContiguous: \ + case Array::PossiblyArrayWithContiguousToTail: \ + case Array::PossiblyArrayWithContiguousOutOfBounds +#define ARRAY_WITH_CONTIGUOUS_MODES \ + Array::ArrayWithContiguous: \ + case Array::ArrayWithContiguousToTail: \ + case Array::ArrayWithContiguousOutOfBounds +#define ALL_CONTIGUOUS_MODES \ + NON_ARRAY_CONTIGUOUS_MODES: \ + case ARRAY_WITH_CONTIGUOUS_MODES +#define IN_BOUNDS_CONTIGUOUS_MODES \ + Array::Contiguous: \ + case Array::ArrayWithContiguous: \ + case Array::PossiblyArrayWithContiguous +#define CONTIGUOUS_TO_TAIL_MODES \ + Array::ContiguousToTail: \ + case Array::ArrayWithContiguousToTail: \ + case Array::PossiblyArrayWithContiguousToTail +#define OUT_OF_BOUNDS_CONTIGUOUS_MODES \ + Array::ContiguousOutOfBounds: \ + case Array::ArrayWithContiguousOutOfBounds: \ + case Array::PossiblyArrayWithContiguousOutOfBounds #define NON_ARRAY_ARRAY_STORAGE_MODES \ Array::ArrayStorage: \ case Array::ArrayStorageToHole: \ @@ -106,33 +144,43 @@ enum Mode { #define ALL_ARRAY_STORAGE_MODES \ NON_ARRAY_ARRAY_STORAGE_MODES: \ case ARRAY_WITH_ARRAY_STORAGE_MODES +#define IN_BOUNDS_ARRAY_STORAGE_MODES \ + Array::ArrayStorage: \ + case Array::ArrayWithArrayStorage: \ + case Array::PossiblyArrayWithArrayStorage #define ARRAY_STORAGE_TO_HOLE_MODES \ Array::ArrayStorageToHole: \ case Array::ArrayWithArrayStorageToHole: \ case Array::PossiblyArrayWithArrayStorageToHole -#define IN_BOUNDS_ARRAY_STORAGE_MODES \ - ARRAY_STORAGE_TO_HOLE_MODES: \ - case Array::ArrayStorage: \ - case Array::ArrayWithArrayStorage: \ - case Array::PossiblyArrayWithArrayStorage #define SLOW_PUT_ARRAY_STORAGE_MODES \ Array::SlowPutArrayStorage: \ case Array::ArrayWithSlowPutArrayStorage: \ case Array::PossiblyArrayWithSlowPutArrayStorage #define OUT_OF_BOUNDS_ARRAY_STORAGE_MODES \ - SLOW_PUT_ARRAY_STORAGE_MODES: \ - case Array::ArrayStorageOutOfBounds: \ + Array::ArrayStorageOutOfBounds: \ case Array::ArrayWithArrayStorageOutOfBounds: \ case Array::PossiblyArrayWithArrayStorageOutOfBounds // Next: helpers for side-effecting checks. -#define EFFECTFUL_NON_ARRAY_ARRAY_STORAGE_MODES \ - Array::BlankToArrayStorage: \ - case Array::BlankToSlowPutArrayStorage -#define ALL_EFFECTFUL_ARRAY_STORAGE_MODES \ - EFFECTFUL_NON_ARRAY_ARRAY_STORAGE_MODES -#define SLOW_PUT_EFFECTFUL_ARRAY_STORAGE_MODES \ - Array::BlankToSlowPutArrayStorage +#define NON_ARRAY_EFFECTFUL_MODES \ + Array::ToContiguous: \ + case Array::ToArrayStorage: \ + case Array::ToSlowPutArrayStorage: \ + case Array::PossiblyArrayToArrayStorage +#define ARRAY_EFFECTFUL_MODES \ + Array::ArrayToArrayStorage +#define ALL_EFFECTFUL_CONTIGUOUS_MODES \ + Array::ToContiguous +#define ALL_EFFECTFUL_ARRAY_STORAGE_MODES \ + Array::ToArrayStorage: \ + case Array::ToSlowPutArrayStorage: \ + case Array::ArrayToArrayStorage: \ + case Array::PossiblyArrayToArrayStorage +#define SLOW_PUT_EFFECTFUL_ARRAY_STORAGE_MODES \ + Array::ToSlowPutArrayStorage +#define ALL_EFFECTFUL_MODES \ + ALL_EFFECTFUL_CONTIGUOUS_MODES: \ + case ALL_EFFECTFUL_ARRAY_STORAGE_MODES Array::Mode fromObserved(ArrayProfile*, Array::Action, bool makeSafe); @@ -145,8 +193,9 @@ const char* modeToString(Array::Mode); inline bool modeUsesButterfly(Array::Mode arrayMode) { switch (arrayMode) { + case ALL_CONTIGUOUS_MODES: case ALL_ARRAY_STORAGE_MODES: - case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: + case ALL_EFFECTFUL_MODES: return true; default: return false; @@ -156,7 +205,9 @@ inline bool modeUsesButterfly(Array::Mode arrayMode) inline bool modeIsJSArray(Array::Mode arrayMode) { switch (arrayMode) { + case ARRAY_WITH_CONTIGUOUS_MODES: case ARRAY_WITH_ARRAY_STORAGE_MODES: + case ARRAY_EFFECTFUL_MODES: return true; default: return false; @@ -166,6 +217,9 @@ inline bool modeIsJSArray(Array::Mode arrayMode) inline bool isInBoundsAccess(Array::Mode arrayMode) { switch (arrayMode) { + case IN_BOUNDS_CONTIGUOUS_MODES: + case CONTIGUOUS_TO_TAIL_MODES: + case ARRAY_STORAGE_TO_HOLE_MODES: case IN_BOUNDS_ARRAY_STORAGE_MODES: return true; default: @@ -184,11 +238,24 @@ inline bool isSlowPutAccess(Array::Mode arrayMode) } } +inline bool mayStoreToTail(Array::Mode arrayMode) +{ + switch (arrayMode) { + case CONTIGUOUS_TO_TAIL_MODES: + case OUT_OF_BOUNDS_CONTIGUOUS_MODES: + case ALL_EFFECTFUL_CONTIGUOUS_MODES: + return true; + default: + return false; + } +} + inline bool mayStoreToHole(Array::Mode arrayMode) { switch (arrayMode) { case ARRAY_STORAGE_TO_HOLE_MODES: case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES: + case SLOW_PUT_ARRAY_STORAGE_MODES: case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: return true; default: @@ -249,7 +316,9 @@ inline bool modeSupportsLength(Array::Mode mode) case Array::Unprofiled: case Array::ForceExit: case Array::Generic: + case NON_ARRAY_CONTIGUOUS_MODES: case NON_ARRAY_ARRAY_STORAGE_MODES: + case NON_ARRAY_EFFECTFUL_MODES: return false; default: return true; @@ -259,7 +328,7 @@ inline bool modeSupportsLength(Array::Mode mode) inline bool benefitsFromStructureCheck(Array::Mode mode) { switch (mode) { - case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: + case ALL_EFFECTFUL_MODES: case Array::Undecided: case Array::Unprofiled: case Array::ForceExit: @@ -273,7 +342,7 @@ inline bool benefitsFromStructureCheck(Array::Mode mode) inline bool isEffectful(Array::Mode mode) { switch (mode) { - case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: + case ALL_EFFECTFUL_MODES: return true; default: return false; diff --git a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.cpp b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.cpp index 7799ee505..a19b723d8 100644 --- a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.cpp +++ b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.cpp @@ -30,8 +30,6 @@ namespace JSC { namespace DFG { -const double AssemblyHelpers::twoToThe32 = (double)0x100000000ull; - ExecutableBase* AssemblyHelpers::executableFor(const CodeOrigin& codeOrigin) { if (!codeOrigin.inlineCallFrame) @@ -49,9 +47,9 @@ Vector<BytecodeAndMachineOffset>& AssemblyHelpers::decodedCodeMapFor(CodeBlock* HashMap<CodeBlock*, Vector<BytecodeAndMachineOffset> >::AddResult result = m_decodedCodeMaps.add(codeBlock, Vector<BytecodeAndMachineOffset>()); if (result.isNewEntry) - codeBlock->jitCodeMap()->decode(result.iterator->second); + codeBlock->jitCodeMap()->decode(result.iterator->value); - return result.iterator->second; + return result.iterator->value; } #if ENABLE(SAMPLING_FLAGS) diff --git a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h index a2003c5bf..5d338fa57 100644 --- a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h +++ b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h @@ -93,16 +93,16 @@ public: } #endif - void emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, GPRReg to) + void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, GPRReg to) { loadPtr(Address(GPRInfo::callFrameRegister, entry * sizeof(Register)), to); } - void emitPutToCallFrameHeader(GPRReg from, RegisterFile::CallFrameHeaderEntry entry) + void emitPutToCallFrameHeader(GPRReg from, JSStack::CallFrameHeaderEntry entry) { storePtr(from, Address(GPRInfo::callFrameRegister, entry * sizeof(Register))); } - void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry) + void emitPutImmediateToCallFrameHeader(void* value, JSStack::CallFrameHeaderEntry entry) { storePtr(TrustedImmPtr(value), Address(GPRInfo::callFrameRegister, entry * sizeof(Register))); } @@ -243,33 +243,14 @@ public: } #endif -#if USE(JSVALUE32_64) && CPU(X86) +#if USE(JSVALUE32_64) void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR) { - movePackedToInt32(fpr, payloadGPR); - rshiftPacked(TrustedImm32(32), fpr); - movePackedToInt32(fpr, tagGPR); + moveDoubleToInts(fpr, payloadGPR, tagGPR); } void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR) { - jitAssertIsJSDouble(tagGPR); - moveInt32ToPacked(payloadGPR, fpr); - moveInt32ToPacked(tagGPR, scratchFPR); - lshiftPacked(TrustedImm32(32), scratchFPR); - orPacked(scratchFPR, fpr); - } -#endif - -#if USE(JSVALUE32_64) && CPU(ARM) - void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR) - { - m_assembler.vmov(payloadGPR, tagGPR, fpr); - } - void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR) - { - jitAssertIsJSDouble(tagGPR); - UNUSED_PARAM(scratchFPR); - m_assembler.vmov(fpr, payloadGPR, tagGPR); + moveIntsToDouble(payloadGPR, tagGPR, fpr, scratchFPR); } #endif @@ -364,8 +345,6 @@ public: Vector<BytecodeAndMachineOffset>& decodedCodeMapFor(CodeBlock*); - static const double twoToThe32; - protected: JSGlobalData* m_globalData; CodeBlock* m_codeBlock; diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeCache.h b/Source/JavaScriptCore/dfg/DFGByteCodeCache.h index ab88e99e5..6b9056e54 100644 --- a/Source/JavaScriptCore/dfg/DFGByteCodeCache.h +++ b/Source/JavaScriptCore/dfg/DFGByteCodeCache.h @@ -132,10 +132,10 @@ public: Map::iterator begin = m_map.begin(); Map::iterator end = m_map.end(); for (Map::iterator iter = begin; iter != end; ++iter) { - if (!iter->second.codeBlock) + if (!iter->value.codeBlock) continue; - if (iter->second.owned) { - delete iter->second.codeBlock; + if (iter->value.owned) { + delete iter->value.codeBlock; continue; } } @@ -145,7 +145,7 @@ public: { Map::iterator iter = m_map.find(key); if (iter != m_map.end()) - return iter->second.codeBlock; + return iter->value.codeBlock; ByteCodeCacheValue value; diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp index 6d5f68200..dc668d93e 100644 --- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp +++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp @@ -43,6 +43,76 @@ namespace JSC { namespace DFG { +class ConstantBufferKey { +public: + ConstantBufferKey() + : m_codeBlock(0) + , m_index(0) + { + } + + ConstantBufferKey(WTF::HashTableDeletedValueType) + : m_codeBlock(0) + , m_index(1) + { + } + + ConstantBufferKey(CodeBlock* codeBlock, unsigned index) + : m_codeBlock(codeBlock) + , m_index(index) + { + } + + bool operator==(const ConstantBufferKey& other) const + { + return m_codeBlock == other.m_codeBlock + && m_index == other.m_index; + } + + unsigned hash() const + { + return WTF::PtrHash<CodeBlock*>::hash(m_codeBlock) ^ m_index; + } + + bool isHashTableDeletedValue() const + { + return !m_codeBlock && m_index; + } + + CodeBlock* codeBlock() const { return m_codeBlock; } + unsigned index() const { return m_index; } + +private: + CodeBlock* m_codeBlock; + unsigned m_index; +}; + +struct ConstantBufferKeyHash { + static unsigned hash(const ConstantBufferKey& key) { return key.hash(); } + static bool equal(const ConstantBufferKey& a, const ConstantBufferKey& b) + { + return a == b; + } + + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +} } // namespace JSC::DFG + +namespace WTF { + +template<typename T> struct DefaultHash; +template<> struct DefaultHash<JSC::DFG::ConstantBufferKey> { + typedef JSC::DFG::ConstantBufferKeyHash Hash; +}; + +template<typename T> struct HashTraits; +template<> struct HashTraits<JSC::DFG::ConstantBufferKey> : SimpleClassHashTraits<JSC::DFG::ConstantBufferKey> { }; + +} // namespace WTF + +namespace JSC { namespace DFG { + // === ByteCodeParser === // // This class is used to compile the dataflow graph from a CodeBlock. @@ -142,7 +212,7 @@ private: return getJSConstant(constant); } - if (operand == RegisterFile::Callee) + if (operand == JSStack::Callee) return getCallee(); // Is this an argument? @@ -227,7 +297,10 @@ private: if (nodePtr->op() == GetLocal) nodeIndex = nodePtr->child1().index(); - return injectLazyOperandSpeculation(addToGraph(GetLocal, OpInfo(nodePtr->variableAccessData()), nodeIndex)); + NodeIndex newGetLocal = injectLazyOperandSpeculation( + addToGraph(GetLocal, OpInfo(nodePtr->variableAccessData()), nodeIndex)); + m_currentBlock->variablesAtTail.local(operand) = newGetLocal; + return newGetLocal; } if (nodePtr->op() == GetLocal) @@ -366,11 +439,11 @@ private: InlineCallFrame* inlineCallFrame = stack->m_inlineCallFrame; if (!inlineCallFrame) break; - if (operand >= static_cast<int>(inlineCallFrame->stackOffset - RegisterFile::CallFrameHeaderSize)) + if (operand >= static_cast<int>(inlineCallFrame->stackOffset - JSStack::CallFrameHeaderSize)) continue; if (operand == inlineCallFrame->stackOffset + CallFrame::thisArgumentOffset()) continue; - if (operand < static_cast<int>(inlineCallFrame->stackOffset - RegisterFile::CallFrameHeaderSize - inlineCallFrame->arguments.size())) + if (operand < static_cast<int>(inlineCallFrame->stackOffset - JSStack::CallFrameHeaderSize - inlineCallFrame->arguments.size())) continue; int argument = operandToArgument(operand - inlineCallFrame->stackOffset); return stack->m_argumentPositions[argument]; @@ -669,9 +742,9 @@ private: { HashMap<JSCell*, NodeIndex>::AddResult result = m_cellConstantNodes.add(cell, NoNode); if (result.isNewEntry) - result.iterator->second = addToGraph(WeakJSConstant, OpInfo(cell)); + result.iterator->value = addToGraph(WeakJSConstant, OpInfo(cell)); - return result.iterator->second; + return result.iterator->value; } CodeOrigin currentCodeOrigin() @@ -758,8 +831,8 @@ private: addVarArgChild(get(currentInstruction[1].u.operand)); int argCount = currentInstruction[2].u.operand; - if (RegisterFile::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots) - m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount; + if (JSStack::CallFrameHeaderSize + (unsigned)argCount > m_parameterSlots) + m_parameterSlots = JSStack::CallFrameHeaderSize + argCount; int registerOffset = currentInstruction[3].u.operand; int dummyThisArgument = op == Call ? 0 : 1; @@ -1049,6 +1122,8 @@ private: Vector<PhiStackEntry, 16> m_argumentPhiStack; Vector<PhiStackEntry, 16> m_localPhiStack; + HashMap<ConstantBufferKey, unsigned> m_constantBufferCache; + struct InlineStackEntry { ByteCodeParser* m_byteCodeParser; @@ -1067,6 +1142,7 @@ private: // direct, caller). Vector<unsigned> m_identifierRemap; Vector<unsigned> m_constantRemap; + Vector<unsigned> m_constantBufferRemap; // Blocks introduced by this code block, which need successor linking. // May include up to one basic block that includes the continuation after @@ -1139,7 +1215,7 @@ private: return result; } - if (operand == RegisterFile::Callee) + if (operand == JSStack::Callee) return m_calleeVR; return operand + m_inlineCallFrame->stackOffset; @@ -1361,14 +1437,14 @@ bool ByteCodeParser::handleInlining(bool usesResult, int callTarget, NodeIndex c // FIXME: Don't flush constants! - int inlineCallFrameStart = m_inlineStackTop->remapOperand(registerOffset) - RegisterFile::CallFrameHeaderSize; + int inlineCallFrameStart = m_inlineStackTop->remapOperand(registerOffset) - JSStack::CallFrameHeaderSize; // Make sure that the area used by the call frame is reserved. - for (int arg = inlineCallFrameStart + RegisterFile::CallFrameHeaderSize + codeBlock->m_numVars; arg-- > inlineCallFrameStart;) + for (int arg = inlineCallFrameStart + JSStack::CallFrameHeaderSize + codeBlock->m_numVars; arg-- > inlineCallFrameStart;) m_preservedVars.set(arg); // Make sure that we have enough locals. - unsigned newNumLocals = inlineCallFrameStart + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters; + unsigned newNumLocals = inlineCallFrameStart + JSStack::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters; if (newNumLocals > m_numLocals) { m_numLocals = newNumLocals; for (size_t i = 0; i < m_graph.m_blocks.size(); ++i) @@ -1571,6 +1647,8 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins case Array::ArrayWithArrayStorageToHole: ASSERT_NOT_REACHED(); + case Array::ArrayWithContiguous: + case Array::ArrayWithContiguousOutOfBounds: case Array::ArrayWithArrayStorage: case Array::ArrayWithArrayStorageOutOfBounds: { NodeIndex arrayPush = addToGraph(ArrayPush, OpInfo(arrayMode), OpInfo(prediction), get(registerOffset + argumentToOperand(0)), get(registerOffset + argumentToOperand(1))); @@ -1594,6 +1672,8 @@ bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrins case Array::ArrayWithArrayStorageToHole: ASSERT_NOT_REACHED(); + case Array::ArrayWithContiguous: + case Array::ArrayWithContiguousOutOfBounds: case Array::ArrayWithArrayStorage: case Array::ArrayWithArrayStorageOutOfBounds: { NodeIndex arrayPop = addToGraph(ArrayPop, OpInfo(arrayMode), OpInfo(prediction), get(registerOffset + argumentToOperand(0))); @@ -1868,7 +1948,7 @@ bool ByteCodeParser::parseBlock(unsigned limit) } case op_create_this: { - set(currentInstruction[1].u.operand, addToGraph(CreateThis, get(RegisterFile::Callee))); + set(currentInstruction[1].u.operand, addToGraph(CreateThis, get(JSStack::Callee))); NEXT_OPCODE(op_create_this); } @@ -1889,7 +1969,7 @@ bool ByteCodeParser::parseBlock(unsigned limit) case op_new_array_buffer: { int startConstant = currentInstruction[2].u.operand; int numConstants = currentInstruction[3].u.operand; - set(currentInstruction[1].u.operand, addToGraph(NewArrayBuffer, OpInfo(startConstant), OpInfo(numConstants))); + set(currentInstruction[1].u.operand, addToGraph(NewArrayBuffer, OpInfo(m_inlineStackTop->m_constantBufferRemap[startConstant]), OpInfo(numConstants))); NEXT_OPCODE(op_new_array_buffer); } @@ -2753,8 +2833,8 @@ bool ByteCodeParser::parseBlock(unsigned limit) addToGraph(CheckArgumentsNotCreated); unsigned argCount = m_inlineStackTop->m_inlineCallFrame->arguments.size(); - if (RegisterFile::CallFrameHeaderSize + argCount > m_parameterSlots) - m_parameterSlots = RegisterFile::CallFrameHeaderSize + argCount; + if (JSStack::CallFrameHeaderSize + argCount > m_parameterSlots) + m_parameterSlots = JSStack::CallFrameHeaderSize + argCount; addVarArgChild(get(currentInstruction[1].u.operand)); // callee addVarArgChild(get(currentInstruction[2].u.operand)); // this @@ -2775,8 +2855,10 @@ bool ByteCodeParser::parseBlock(unsigned limit) // Statically speculate for now. It makes sense to let speculate-only jneq_ptr // support simmer for a while before making it more general, since it's // already gnarly enough as it is. + ASSERT(pointerIsFunction(currentInstruction[2].u.specialPointer)); addToGraph( - CheckFunction, OpInfo(currentInstruction[2].u.jsCell.get()), + CheckFunction, + OpInfo(actualPointerFor(m_inlineStackTop->m_codeBlock, currentInstruction[2].u.specialPointer)), get(currentInstruction[1].u.operand)); addToGraph(Jump, OpInfo(m_currentIndex + OPCODE_LENGTH(op_jneq_ptr))); LAST_OPCODE(op_jneq_ptr); @@ -3205,7 +3287,7 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry( InlineCallFrame inlineCallFrame; inlineCallFrame.executable.set(*byteCodeParser->m_globalData, byteCodeParser->m_codeBlock->ownerExecutable(), codeBlock->ownerExecutable()); - inlineCallFrame.stackOffset = inlineCallFrameStart + RegisterFile::CallFrameHeaderSize; + inlineCallFrame.stackOffset = inlineCallFrameStart + JSStack::CallFrameHeaderSize; inlineCallFrame.callee.set(*byteCodeParser->m_globalData, byteCodeParser->m_codeBlock->ownerExecutable(), callee); inlineCallFrame.caller = byteCodeParser->currentCodeOrigin(); inlineCallFrame.arguments.resize(argumentCountIncludingThis); // Set the number of arguments including this, but don't configure the value recoveries, yet. @@ -3242,13 +3324,14 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry( m_identifierRemap.resize(codeBlock->numberOfIdentifiers()); m_constantRemap.resize(codeBlock->numberOfConstantRegisters()); + m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers()); for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i) { StringImpl* rep = codeBlock->identifier(i).impl(); IdentifierMap::AddResult result = byteCodeParser->m_identifierMap.add(rep, byteCodeParser->m_codeBlock->numberOfIdentifiers()); if (result.isNewEntry) byteCodeParser->m_codeBlock->addIdentifier(Identifier(byteCodeParser->m_globalData, rep)); - m_identifierRemap[i] = result.iterator->second; + m_identifierRemap[i] = result.iterator->value; } for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i) { JSValue value = codeBlock->getConstant(i + FirstConstantRegisterIndex); @@ -3266,10 +3349,24 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry( byteCodeParser->m_codeBlock->addConstant(value); byteCodeParser->m_constants.append(ConstantRecord()); } - m_constantRemap[i] = result.iterator->second; + m_constantRemap[i] = result.iterator->value; } for (unsigned i = 0; i < codeBlock->numberOfGlobalResolveInfos(); ++i) byteCodeParser->m_codeBlock->addGlobalResolveInfo(std::numeric_limits<unsigned>::max()); + for (unsigned i = 0; i < codeBlock->numberOfConstantBuffers(); ++i) { + // If we inline the same code block multiple times, we don't want to needlessly + // duplicate its constant buffers. + HashMap<ConstantBufferKey, unsigned>::iterator iter = + byteCodeParser->m_constantBufferCache.find(ConstantBufferKey(codeBlock, i)); + if (iter != byteCodeParser->m_constantBufferCache.end()) { + m_constantBufferRemap[i] = iter->value; + continue; + } + Vector<JSValue>& buffer = codeBlock->constantBufferAsVector(i); + unsigned newIndex = byteCodeParser->m_codeBlock->addConstantBuffer(buffer); + m_constantBufferRemap[i] = newIndex; + byteCodeParser->m_constantBufferCache.add(ConstantBufferKey(codeBlock, i), newIndex); + } m_callsiteBlockHeadNeedsLinking = true; } else { @@ -3285,11 +3382,14 @@ ByteCodeParser::InlineStackEntry::InlineStackEntry( m_identifierRemap.resize(codeBlock->numberOfIdentifiers()); m_constantRemap.resize(codeBlock->numberOfConstantRegisters()); + m_constantBufferRemap.resize(codeBlock->numberOfConstantBuffers()); for (size_t i = 0; i < codeBlock->numberOfIdentifiers(); ++i) m_identifierRemap[i] = i; for (size_t i = 0; i < codeBlock->numberOfConstantRegisters(); ++i) m_constantRemap[i] = i + FirstConstantRegisterIndex; + for (size_t i = 0; i < codeBlock->numberOfConstantBuffers(); ++i) + m_constantBufferRemap[i] = i; m_callsiteBlockHeadNeedsLinking = false; } diff --git a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h index 5cd0baab2..4a6024305 100644 --- a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h +++ b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h @@ -184,6 +184,14 @@ public: addCallArgument(arg2); } + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2) + { + resetCallArguments(); + addCallArgument(GPRInfo::callFrameRegister); + addCallArgument(arg1); + addCallArgument(arg2); + } + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3) { resetCallArguments(); @@ -593,6 +601,13 @@ public: move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); } + ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImmPtr arg1, TrustedImm32 arg2) + { + move(arg1, GPRInfo::argumentGPR1); + move(arg2, GPRInfo::argumentGPR2); + move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); + } + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3) { setupStubArguments(arg1, arg2, arg3); diff --git a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp index cea2f3c48..185332921 100644 --- a/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGCSEPhase.cpp @@ -177,6 +177,7 @@ private: if (!m_graph.byValIsPure(node)) return NoNode; switch (node.arrayMode()) { + case CONTIGUOUS_TO_TAIL_MODES: case ARRAY_STORAGE_TO_HOLE_MODES: return NoNode; default: @@ -197,6 +198,8 @@ private: for (unsigned i = m_indexInBlock; i--;) { NodeIndex index = m_currentBlock->at(i); Node& node = m_graph[index]; + if (!node.shouldGenerate()) + continue; switch (node.op()) { case GetGlobalVar: if (node.registerPointer() == registerPointer) @@ -220,6 +223,8 @@ private: for (unsigned i = m_indexInBlock; i--;) { NodeIndex index = m_currentBlock->at(i); Node& node = m_graph[index]; + if (!node.shouldGenerate()) + continue; switch (node.op()) { case GetScopedVar: { Node& getScopeRegisters = m_graph[node.child1()]; @@ -248,6 +253,8 @@ private: for (unsigned i = m_indexInBlock; i--;) { NodeIndex index = m_currentBlock->at(i); Node& node = m_graph[index]; + if (!node.shouldGenerate()) + continue; switch (node.op()) { case GlobalVarWatchpoint: if (node.registerPointer() == registerPointer) @@ -334,6 +341,8 @@ private: break; Node& node = m_graph[index]; + if (!node.shouldGenerate()) + continue; switch (node.op()) { case GetByVal: if (!m_graph.byValIsPure(node)) @@ -359,9 +368,6 @@ private: // for a structure change or a put to property storage to affect // the GetByVal. break; - case ArrayPush: - // A push cannot affect previously existing elements in the array. - break; default: if (m_graph.clobbersWorld(index)) return NoNode; @@ -393,6 +399,8 @@ private: break; Node& node = m_graph[index]; + if (!node.shouldGenerate()) + continue; switch (node.op()) { case CheckStructure: case ForwardCheckStructure: @@ -447,6 +455,8 @@ private: break; Node& node = m_graph[index]; + if (!node.shouldGenerate()) + continue; switch (node.op()) { case CheckStructure: case ForwardCheckStructure: @@ -549,6 +559,8 @@ private: break; Node& node = m_graph[index]; + if (!node.shouldGenerate()) + continue; switch (node.op()) { case GetByOffset: if (node.child1() == child1 @@ -1222,9 +1234,7 @@ private: case PutByVal: { Edge child1 = m_graph.varArgChild(node, 0); Edge child2 = m_graph.varArgChild(node, 1); - if (isActionableMutableArraySpeculation(m_graph[child1].prediction()) - && m_graph[child2].shouldSpeculateInteger() - && !m_graph[child1].shouldSpeculateArguments()) { + if (canCSEStorage(node.arrayMode())) { NodeIndex nodeIndex = getByValLoadElimination(child1.index(), child2.index()); if (nodeIndex == NoNode) break; diff --git a/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h b/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h new file mode 100644 index 000000000..46d5f44cb --- /dev/null +++ b/Source/JavaScriptCore/dfg/DFGCallArrayAllocatorSlowPathGenerator.h @@ -0,0 +1,128 @@ +/* + * 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 DFGCallArrayAllocatorSlowPathGenerator_h +#define DFGCallArrayAllocatorSlowPathGenerator_h + +#include <wtf/Platform.h> + +#if ENABLE(DFG_JIT) + +#include "DFGCommon.h" +#include "DFGSlowPathGenerator.h" +#include "DFGSpeculativeJIT.h" +#include <wtf/Vector.h> + +namespace JSC { namespace DFG { + +class CallArrayAllocatorSlowPathGenerator : public JumpingSlowPathGenerator<MacroAssembler::JumpList> { +public: + CallArrayAllocatorSlowPathGenerator( + MacroAssembler::JumpList from, SpeculativeJIT* jit, P_DFGOperation_EStZ function, + GPRReg resultGPR, GPRReg storageGPR, Structure* structure, size_t size) + : JumpingSlowPathGenerator<MacroAssembler::JumpList>(from, jit) + , m_function(function) + , m_resultGPR(resultGPR) + , m_storageGPR(storageGPR) + , m_structure(structure) + , m_size(size) + { + ASSERT(size < static_cast<size_t>(std::numeric_limits<int32_t>::max())); + jit->silentSpillAllRegistersImpl(false, m_plans, resultGPR); + } + +protected: + void generateInternal(SpeculativeJIT* jit) + { + linkFrom(jit); + for (unsigned i = 0; i < m_plans.size(); ++i) + jit->silentSpill(m_plans[i]); + jit->callOperation(m_function, m_resultGPR, m_structure, m_size); + GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR); + for (unsigned i = 0; i < m_plans.size(); ++i) + jit->silentFill(m_plans[i], canTrample); + jit->m_jit.loadPtr(MacroAssembler::Address(m_resultGPR, JSObject::butterflyOffset()), m_storageGPR); + jumpTo(jit); + } + +private: + P_DFGOperation_EStZ m_function; + GPRReg m_resultGPR; + GPRReg m_storageGPR; + Structure* m_structure; + size_t m_size; + Vector<SilentRegisterSavePlan, 2> m_plans; +}; + +class CallArrayAllocatorWithVariableSizeSlowPathGenerator : public JumpingSlowPathGenerator<MacroAssembler::JumpList> { +public: + CallArrayAllocatorWithVariableSizeSlowPathGenerator( + MacroAssembler::JumpList from, SpeculativeJIT* jit, P_DFGOperation_EStZ function, + GPRReg resultGPR, Structure* contiguousStructure, Structure* arrayStorageStructure, GPRReg sizeGPR) + : JumpingSlowPathGenerator<MacroAssembler::JumpList>(from, jit) + , m_function(function) + , m_resultGPR(resultGPR) + , m_contiguousStructure(contiguousStructure) + , m_arrayStorageStructure(arrayStorageStructure) + , m_sizeGPR(sizeGPR) + { + jit->silentSpillAllRegistersImpl(false, m_plans, resultGPR); + } + +protected: + void generateInternal(SpeculativeJIT* jit) + { + linkFrom(jit); + for (unsigned i = 0; i < m_plans.size(); ++i) + jit->silentSpill(m_plans[i]); + GPRReg scratchGPR = AssemblyHelpers::selectScratchGPR(m_sizeGPR); + MacroAssembler::Jump bigLength = jit->m_jit.branch32(MacroAssembler::AboveOrEqual, m_sizeGPR, MacroAssembler::TrustedImm32(MIN_SPARSE_ARRAY_INDEX)); + jit->m_jit.move(MacroAssembler::TrustedImmPtr(m_contiguousStructure), scratchGPR); + MacroAssembler::Jump done = jit->m_jit.jump(); + bigLength.link(&jit->m_jit); + jit->m_jit.move(MacroAssembler::TrustedImmPtr(m_arrayStorageStructure), scratchGPR); + done.link(&jit->m_jit); + jit->callOperation(m_function, m_resultGPR, scratchGPR, m_sizeGPR); + GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR); + for (unsigned i = 0; i < m_plans.size(); ++i) + jit->silentFill(m_plans[i], canTrample); + jumpTo(jit); + } + +private: + P_DFGOperation_EStZ m_function; + GPRReg m_resultGPR; + Structure* m_contiguousStructure; + Structure* m_arrayStorageStructure; + GPRReg m_sizeGPR; + Vector<SilentRegisterSavePlan, 2> m_plans; +}; + +} } // namespace JSC::DFG + +#endif // ENABLE(DFG_JIT) + +#endif // DFGCallArrayAllocatorSlowPathGenerator_h + diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.h b/Source/JavaScriptCore/dfg/DFGCapabilities.h index bccde7ca7..e1760699a 100644 --- a/Source/JavaScriptCore/dfg/DFGCapabilities.h +++ b/Source/JavaScriptCore/dfg/DFGCapabilities.h @@ -201,10 +201,6 @@ inline bool canInlineOpcode(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction case op_resolve: case op_resolve_base: - // Constant buffers aren't copied correctly. This is easy to fix, but for - // now we just disable inlining for functions that use them. - case op_new_array_buffer: - // Inlining doesn't correctly remap regular expression operands. case op_new_regexp: diff --git a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp index dfb62cbc4..8a261ad2b 100644 --- a/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp @@ -179,7 +179,8 @@ private: block->variablesAtTail.operand(node.local()) = previousLocalAccess; else { ASSERT(m_graph[tailNodeIndex].op() == Flush - || m_graph[tailNodeIndex].op() == SetLocal); + || m_graph[tailNodeIndex].op() == SetLocal + || node.variableAccessData()->isCaptured()); } } diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp index aa2d5dff4..49212730c 100644 --- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp @@ -116,7 +116,7 @@ private: m_graph.deref(m_compileIndex); nodePtr->setArrayMode(arrayMode); - NodeIndex storage = checkArray(arrayMode, nodePtr->codeOrigin, nodePtr->child1().index(), lengthNeedsStorage, nodePtr->shouldGenerate()); + NodeIndex storage = checkArray(arrayMode, nodePtr->codeOrigin, nodePtr->child1().index(), NoNode, lengthNeedsStorage, nodePtr->shouldGenerate()); if (storage == NoNode) break; @@ -137,17 +137,18 @@ private: m_graph[node.child1()].prediction(), m_graph[node.child2()].prediction())); - blessArrayOperation(node.child1(), 2); + blessArrayOperation(node.child1(), node.child2(), 2); break; } case ArrayPush: { - blessArrayOperation(node.child1(), 2); + blessArrayOperation(node.child1(), node.child2(), 2); break; } case ArrayPop: { - blessArrayOperation(node.child1(), 1); + blessArrayOperation(node.child1(), node.child2(), 1); + break; } case ValueToInt32: { @@ -327,7 +328,7 @@ private: m_graph[child1].prediction(), m_graph[child2].prediction())); - blessArrayOperation(child1, 3); + blessArrayOperation(child1, child2, 3); Node* nodePtr = &m_graph[m_compileIndex]; @@ -375,25 +376,28 @@ private: return nodeIndex; } - NodeIndex checkArray(Array::Mode arrayMode, CodeOrigin codeOrigin, NodeIndex array, bool (*storageCheck)(Array::Mode) = canCSEStorage, bool shouldGenerate = true) + NodeIndex checkArray(Array::Mode arrayMode, CodeOrigin codeOrigin, NodeIndex array, NodeIndex index, bool (*storageCheck)(Array::Mode) = canCSEStorage, bool shouldGenerate = true) { ASSERT(modeIsSpecific(arrayMode)); m_graph.ref(array); if (isEffectful(arrayMode)) { - Node arrayify(Arrayify, codeOrigin, OpInfo(arrayMode), array); + if (index != NoNode) + m_graph.ref(index); + Node arrayify(Arrayify, codeOrigin, OpInfo(arrayMode), array, index); arrayify.ref(); // Once because it's used as a butterfly. arrayify.ref(); // And twice because it's must-generate. NodeIndex arrayifyIndex = m_graph.size(); m_graph.append(arrayify); m_insertionSet.append(m_indexInBlock, arrayifyIndex); - ASSERT(storageCheck == canCSEStorage); ASSERT(shouldGenerate); ASSERT(canCSEStorage(arrayMode)); ASSERT(modeUsesButterfly(arrayMode)); - + + if (!storageCheck(arrayMode)) + return NoNode; return arrayifyIndex; } @@ -415,14 +419,15 @@ private: return addNode(Node(GetIndexedPropertyStorage, codeOrigin, OpInfo(arrayMode), array), shouldGenerate); } - void blessArrayOperation(Edge base, unsigned storageChildIdx) + void blessArrayOperation(Edge base, Edge index, unsigned storageChildIdx) { if (m_graph.m_fixpointState > BeforeFixpoint) return; Node* nodePtr = &m_graph[m_compileIndex]; - if (nodePtr->arrayMode() == Array::ForceExit) { + switch (nodePtr->arrayMode()) { + case Array::ForceExit: { Node forceExit(ForceOSRExit, nodePtr->codeOrigin); forceExit.ref(); NodeIndex forceExitIndex = m_graph.size(); @@ -430,15 +435,23 @@ private: m_insertionSet.append(m_indexInBlock, forceExitIndex); return; } - - if (!modeIsSpecific(nodePtr->arrayMode())) + + case Array::Undecided: + case Array::Unprofiled: + ASSERT_NOT_REACHED(); return; - NodeIndex storage = checkArray(nodePtr->arrayMode(), nodePtr->codeOrigin, base.index()); - if (storage == NoNode) + case Array::Generic: return; - m_graph.child(m_graph[m_compileIndex], storageChildIdx) = Edge(storage); + default: { + NodeIndex storage = checkArray(nodePtr->arrayMode(), nodePtr->codeOrigin, base.index(), index.indexUnchecked()); + if (storage == NoNode) + return; + + m_graph.child(m_graph[m_compileIndex], storageChildIdx) = Edge(storage); + return; + } } } void fixIntEdge(Edge& edge) diff --git a/Source/JavaScriptCore/dfg/DFGGenerationInfo.h b/Source/JavaScriptCore/dfg/DFGGenerationInfo.h index 905c5c5fb..227433e0e 100644 --- a/Source/JavaScriptCore/dfg/DFGGenerationInfo.h +++ b/Source/JavaScriptCore/dfg/DFGGenerationInfo.h @@ -201,7 +201,7 @@ public: // Get the format of the value in machine registers (or 'none'). DataFormat registerFormat() { return m_registerFormat; } - // Get the format of the value as it is spilled in the RegisterFile (or 'none'). + // Get the format of the value as it is spilled in the JSStack (or 'none'). DataFormat spillFormat() { return m_spillFormat; } bool isJSFormat(DataFormat expectedFormat) @@ -255,11 +255,11 @@ public: // This should only be called on values that are currently in a register. ASSERT(m_registerFormat != DataFormatNone); // Constants do not need spilling, nor do values that have already been - // spilled to the RegisterFile. + // spilled to the JSStack. return !m_canFill; } - // Called when a VirtualRegister is being spilled to the RegisterFile for the first time. + // Called when a VirtualRegister is being spilled to the JSStack for the first time. void spill(VariableEventStream& stream, VirtualRegister virtualRegister, DataFormat spillFormat) { // We shouldn't be spill values that don't need spilling. diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h index b02c9991c..212c8bbd2 100644 --- a/Source/JavaScriptCore/dfg/DFGGraph.h +++ b/Source/JavaScriptCore/dfg/DFGGraph.h @@ -36,8 +36,8 @@ #include "DFGBasicBlock.h" #include "DFGDominators.h" #include "DFGNode.h" +#include "JSStack.h" #include "MethodOfGettingAValueProfile.h" -#include "RegisterFile.h" #include <wtf/BitVector.h> #include <wtf/HashMap.h> #include <wtf/Vector.h> @@ -479,8 +479,11 @@ public: { switch (node.arrayMode()) { case Array::Generic: + case OUT_OF_BOUNDS_CONTIGUOUS_MODES: + case ARRAY_STORAGE_TO_HOLE_MODES: case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES: - case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: + case SLOW_PUT_ARRAY_STORAGE_MODES: + case ALL_EFFECTFUL_MODES: return false; case Array::String: return node.op() == GetByVal; diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp index ae28fad3f..c7f941a7a 100644 --- a/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp +++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp @@ -68,14 +68,14 @@ void JITCompiler::compileEntry() { // This code currently matches the old JIT. In the function header we need to // pop the return address (since we do not allow any recursion on the machine - // stack), and perform a fast register file check. + // stack), and perform a fast stack check. // FIXME: https://bugs.webkit.org/show_bug.cgi?id=56292 - // We'll need to convert the remaining cti_ style calls (specifically the register file + // We'll need to convert the remaining cti_ style calls (specifically the stack // check) which will be dependent on stack layout. (We'd need to account for this in // both normal return code and when jumping to an exception handler). preserveReturnAddressAfterCall(GPRInfo::regT2); - emitPutToCallFrameHeader(GPRInfo::regT2, RegisterFile::ReturnPC); - emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock); + emitPutToCallFrameHeader(GPRInfo::regT2, JSStack::ReturnPC); + emitPutImmediateToCallFrameHeader(m_codeBlock, JSStack::CodeBlock); } void JITCompiler::compileBody(SpeculativeJIT& speculative) @@ -256,12 +256,12 @@ bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi // If we needed to perform an arity check we will already have moved the return address, // so enter after this. Label fromArityCheck(this); - // Plant a check that sufficient space is available in the RegisterFile. + // Plant a check that sufficient space is available in the JSStack. // FIXME: https://bugs.webkit.org/show_bug.cgi?id=56291 addPtr(TrustedImm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::regT1); - Jump registerFileCheck = branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), GPRInfo::regT1); - // Return here after register file check. - Label fromRegisterFileCheck = label(); + Jump stackCheck = branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->stack().addressOfEnd()), GPRInfo::regT1); + // Return here after stack check. + Label fromStackCheck = label(); // === Function body code generation === @@ -271,21 +271,21 @@ bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi // === Function footer code generation === // - // Generate code to perform the slow register file check (if the fast one in + // Generate code to perform the slow stack check (if the fast one in // the function header fails), and generate the entry point with arity check. // - // Generate the register file check; if the fast check in the function head fails, + // Generate the stack check; if the fast check in the function head fails, // we need to call out to a helper function to check whether more space is available. // FIXME: change this from a cti call to a DFG style operation (normal C calling conventions). - registerFileCheck.link(this); + stackCheck.link(this); move(stackPointerRegister, GPRInfo::argumentGPR0); poke(GPRInfo::callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); CallBeginToken token; beginCall(CodeOrigin(0), token); - Call callRegisterFileCheck = call(); - notifyCall(callRegisterFileCheck, CodeOrigin(0), token); - jump(fromRegisterFileCheck); + Call callStackCheck = call(); + notifyCall(callStackCheck, CodeOrigin(0), token); + jump(fromStackCheck); // The fast entry point into a function does not check the correct number of arguments // have been passed to the call (we only use the fast entry point where we can statically @@ -295,7 +295,7 @@ bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi Label arityCheck = label(); compileEntry(); - load32(AssemblyHelpers::payloadFor((VirtualRegister)RegisterFile::ArgumentCount), GPRInfo::regT1); + load32(AssemblyHelpers::payloadFor((VirtualRegister)JSStack::ArgumentCount), GPRInfo::regT1); branch32(AboveOrEqual, GPRInfo::regT1, TrustedImm32(m_codeBlock->numParameters())).linkTo(fromArityCheck, this); move(stackPointerRegister, GPRInfo::argumentGPR0); poke(GPRInfo::callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*)); @@ -322,8 +322,8 @@ bool JITCompiler::compileFunction(JITCode& entry, MacroAssemblerCodePtr& entryWi link(linkBuffer); speculative.linkOSREntries(linkBuffer); - // FIXME: switch the register file check & arity check over to DFGOpertaion style calls, not JIT stubs. - linkBuffer.link(callRegisterFileCheck, cti_register_file_check); + // FIXME: switch the stack check & arity check over to DFGOpertaion style calls, not JIT stubs. + linkBuffer.link(callStackCheck, cti_stack_check); linkBuffer.link(callArityCheck, m_codeBlock->m_isConstructor ? cti_op_construct_arityCheck : cti_op_call_arityCheck); if (m_disassembler) diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h index 7ff399f78..c73934832 100644 --- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h +++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h @@ -297,7 +297,7 @@ public: void beginCall(CodeOrigin codeOrigin, CallBeginToken& token) { unsigned index = m_exceptionChecks.size(); - store32(TrustedImm32(index), tagFor(static_cast<VirtualRegister>(RegisterFile::ArgumentCount))); + store32(TrustedImm32(index), tagFor(static_cast<VirtualRegister>(JSStack::ArgumentCount))); token.set(codeOrigin, index); } diff --git a/Source/JavaScriptCore/dfg/DFGOSREntry.cpp b/Source/JavaScriptCore/dfg/DFGOSREntry.cpp index 9a7bc96cc..b838c4fb4 100644 --- a/Source/JavaScriptCore/dfg/DFGOSREntry.cpp +++ b/Source/JavaScriptCore/dfg/DFGOSREntry.cpp @@ -136,7 +136,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn // it seems silly: you'd be diverting the program to error handling when it // would have otherwise just kept running albeit less quickly. - if (!globalData->interpreter->registerFile().grow(&exec->registers()[codeBlock->m_numCalleeRegisters])) { + if (!globalData->interpreter->stack().grow(&exec->registers()[codeBlock->m_numCalleeRegisters])) { #if ENABLE(JIT_VERBOSE_OSR) dataLog(" OSR failed because stack growth failed.\n"); #endif diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp index 8c8e2f949..cb13dcc50 100644 --- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp +++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp @@ -125,9 +125,9 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov // Int32s, have no FPRs, and have no constants. If there are constants, we // expect most of them to be jsUndefined(); if that's true then we handle that // specially to minimize code size and execution time. - bool haveUnboxedInt32InRegisterFile = false; - bool haveUnboxedCellInRegisterFile = false; - bool haveUnboxedBooleanInRegisterFile = false; + bool haveUnboxedInt32InJSStack = false; + bool haveUnboxedCellInJSStack = false; + bool haveUnboxedBooleanInJSStack = false; bool haveUInt32s = false; bool haveFPRs = false; bool haveConstants = false; @@ -137,10 +137,10 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case DisplacedInRegisterFile: - case Int32DisplacedInRegisterFile: - case CellDisplacedInRegisterFile: - case BooleanDisplacedInRegisterFile: + case DisplacedInJSStack: + case Int32DisplacedInJSStack: + case CellDisplacedInJSStack: + case BooleanDisplacedInJSStack: numberOfDisplacedVirtualRegisters++; ASSERT((int)recovery.virtualRegister() >= 0); @@ -174,16 +174,16 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov haveUInt32s = true; break; - case AlreadyInRegisterFileAsUnboxedInt32: - haveUnboxedInt32InRegisterFile = true; + case AlreadyInJSStackAsUnboxedInt32: + haveUnboxedInt32InJSStack = true; break; - case AlreadyInRegisterFileAsUnboxedCell: - haveUnboxedCellInRegisterFile = true; + case AlreadyInJSStackAsUnboxedCell: + haveUnboxedCellInJSStack = true; break; - case AlreadyInRegisterFileAsUnboxedBoolean: - haveUnboxedBooleanInRegisterFile = true; + case AlreadyInJSStackAsUnboxedBoolean: + haveUnboxedBooleanInJSStack = true; break; case InFPR: @@ -214,19 +214,19 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov // 5) Perform all reboxing of integers and cells, except for those in registers. - if (haveUnboxedInt32InRegisterFile || haveUnboxedCellInRegisterFile || haveUnboxedBooleanInRegisterFile) { + if (haveUnboxedInt32InJSStack || haveUnboxedCellInJSStack || haveUnboxedBooleanInJSStack) { for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case AlreadyInRegisterFileAsUnboxedInt32: + case AlreadyInJSStackAsUnboxedInt32: m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::Int32Tag), AssemblyHelpers::tagFor(static_cast<VirtualRegister>(operands.operandForIndex(index)))); break; - case AlreadyInRegisterFileAsUnboxedCell: + case AlreadyInJSStackAsUnboxedCell: m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor(static_cast<VirtualRegister>(operands.operandForIndex(index)))); break; - case AlreadyInRegisterFileAsUnboxedBoolean: + case AlreadyInJSStackAsUnboxedBoolean: m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::BooleanTag), AssemblyHelpers::tagFor(static_cast<VirtualRegister>(operands.operandForIndex(index)))); break; @@ -327,7 +327,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov } } - // 7) Dump all doubles into the register file, or to the scratch storage if the + // 7) Dump all doubles into the stack, or to the scratch storage if the // destination virtual register is poisoned. if (haveFPRs) { for (size_t index = 0; index < operands.size(); ++index) { @@ -360,19 +360,19 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case DisplacedInRegisterFile: + case DisplacedInJSStack: m_jit.load32(AssemblyHelpers::payloadFor(recovery.virtualRegister()), GPRInfo::toRegister(displacementIndex++)); m_jit.load32(AssemblyHelpers::tagFor(recovery.virtualRegister()), GPRInfo::toRegister(displacementIndex++)); break; - case Int32DisplacedInRegisterFile: + case Int32DisplacedInJSStack: m_jit.load32(AssemblyHelpers::payloadFor(recovery.virtualRegister()), GPRInfo::toRegister(displacementIndex++)); m_jit.move(AssemblyHelpers::TrustedImm32(JSValue::Int32Tag), GPRInfo::toRegister(displacementIndex++)); break; - case CellDisplacedInRegisterFile: + case CellDisplacedInJSStack: m_jit.load32(AssemblyHelpers::payloadFor(recovery.virtualRegister()), GPRInfo::toRegister(displacementIndex++)); m_jit.move(AssemblyHelpers::TrustedImm32(JSValue::CellTag), GPRInfo::toRegister(displacementIndex++)); break; - case BooleanDisplacedInRegisterFile: + case BooleanDisplacedInJSStack: m_jit.load32(AssemblyHelpers::payloadFor(recovery.virtualRegister()), GPRInfo::toRegister(displacementIndex++)); m_jit.move(AssemblyHelpers::TrustedImm32(JSValue::BooleanTag), GPRInfo::toRegister(displacementIndex++)); break; @@ -385,10 +385,10 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case DisplacedInRegisterFile: - case Int32DisplacedInRegisterFile: - case CellDisplacedInRegisterFile: - case BooleanDisplacedInRegisterFile: + case DisplacedInJSStack: + case Int32DisplacedInJSStack: + case CellDisplacedInJSStack: + case BooleanDisplacedInJSStack: m_jit.store32(GPRInfo::toRegister(displacementIndex++), AssemblyHelpers::payloadFor((VirtualRegister)operands.operandForIndex(index))); m_jit.store32(GPRInfo::toRegister(displacementIndex++), AssemblyHelpers::tagFor((VirtualRegister)operands.operandForIndex(index))); break; @@ -418,16 +418,16 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case DisplacedInRegisterFile: + case DisplacedInJSStack: m_jit.load32(AssemblyHelpers::payloadFor(recovery.virtualRegister()), GPRInfo::regT0); m_jit.load32(AssemblyHelpers::tagFor(recovery.virtualRegister()), GPRInfo::regT1); m_jit.store32(GPRInfo::regT0, reinterpret_cast<char*>(scratchDataBuffer + scratchIndex) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)); m_jit.store32(GPRInfo::regT1, reinterpret_cast<char*>(scratchDataBuffer + scratchIndex) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)); scratchIndex++; break; - case Int32DisplacedInRegisterFile: - case CellDisplacedInRegisterFile: - case BooleanDisplacedInRegisterFile: + case Int32DisplacedInJSStack: + case CellDisplacedInJSStack: + case BooleanDisplacedInJSStack: m_jit.load32(AssemblyHelpers::payloadFor(recovery.virtualRegister()), GPRInfo::regT0); m_jit.store32(GPRInfo::regT0, reinterpret_cast<char*>(scratchDataBuffer + scratchIndex++) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)); break; @@ -440,24 +440,24 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case DisplacedInRegisterFile: + case DisplacedInJSStack: m_jit.load32(reinterpret_cast<char*>(scratchDataBuffer + scratchIndex) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload), GPRInfo::regT0); m_jit.load32(reinterpret_cast<char*>(scratchDataBuffer + scratchIndex) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag), GPRInfo::regT1); m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor((VirtualRegister)operands.operandForIndex(index))); m_jit.store32(GPRInfo::regT1, AssemblyHelpers::tagFor((VirtualRegister)operands.operandForIndex(index))); scratchIndex++; break; - case Int32DisplacedInRegisterFile: + case Int32DisplacedInJSStack: m_jit.load32(reinterpret_cast<char*>(scratchDataBuffer + scratchIndex++) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload), GPRInfo::regT0); m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::Int32Tag), AssemblyHelpers::tagFor((VirtualRegister)operands.operandForIndex(index))); m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor((VirtualRegister)operands.operandForIndex(index))); break; - case CellDisplacedInRegisterFile: + case CellDisplacedInJSStack: m_jit.load32(reinterpret_cast<char*>(scratchDataBuffer + scratchIndex++) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload), GPRInfo::regT0); m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)operands.operandForIndex(index))); m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor((VirtualRegister)operands.operandForIndex(index))); break; - case BooleanDisplacedInRegisterFile: + case BooleanDisplacedInJSStack: m_jit.load32(reinterpret_cast<char*>(scratchDataBuffer + scratchIndex++) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload), GPRInfo::regT0); m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::BooleanTag), AssemblyHelpers::tagFor((VirtualRegister)operands.operandForIndex(index))); m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor((VirtualRegister)operands.operandForIndex(index))); @@ -575,7 +575,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov // 13) Reify inlined call frames. ASSERT(m_jit.baselineCodeBlock()->getJITType() == JITCode::BaselineJIT); - m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), AssemblyHelpers::addressFor((VirtualRegister)RegisterFile::CodeBlock)); + m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), AssemblyHelpers::addressFor((VirtualRegister)JSStack::CodeBlock)); for (CodeOrigin codeOrigin = exit.m_codeOrigin; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) { InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; @@ -597,15 +597,15 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov } else callerFrameGPR = GPRInfo::callFrameRegister; - m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CodeBlock))); - m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ScopeChain))); - m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee->scope()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ScopeChain))); - m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CallerFrame))); - m_jit.storePtr(callerFrameGPR, AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CallerFrame))); - m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ReturnPC))); - m_jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ArgumentCount))); - m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::Callee))); - m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee.get()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::Callee))); + m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CodeBlock))); + m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain))); + m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee->scope()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain))); + m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CallerFrame))); + m_jit.storePtr(callerFrameGPR, AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CallerFrame))); + m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ReturnPC))); + m_jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount))); + m_jit.store32(AssemblyHelpers::TrustedImm32(JSValue::CellTag), AssemblyHelpers::tagFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee))); + m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee.get()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee))); } // 14) Create arguments if necessary and place them into the appropriate aliased diff --git a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp index fcaf0a4bc..968e56f1a 100644 --- a/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp +++ b/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp @@ -133,9 +133,9 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case Int32DisplacedInRegisterFile: - case DoubleDisplacedInRegisterFile: - case DisplacedInRegisterFile: + case Int32DisplacedInJSStack: + case DoubleDisplacedInJSStack: + case DisplacedInJSStack: numberOfDisplacedVirtualRegisters++; ASSERT((int)recovery.virtualRegister() >= 0); @@ -164,11 +164,11 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov break; case UnboxedInt32InGPR: - case AlreadyInRegisterFileAsUnboxedInt32: + case AlreadyInJSStackAsUnboxedInt32: haveUnboxedInt32s = true; break; - case AlreadyInRegisterFileAsUnboxedDouble: + case AlreadyInJSStackAsUnboxedDouble: haveUnboxedDoubles = true; break; @@ -233,7 +233,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov m_jit.orPtr(GPRInfo::tagTypeNumberRegister, recovery.gpr()); break; - case AlreadyInRegisterFileAsUnboxedInt32: + case AlreadyInJSStackAsUnboxedInt32: m_jit.store32(AssemblyHelpers::TrustedImm32(static_cast<uint32_t>(TagTypeNumber >> 32)), AssemblyHelpers::tagFor(static_cast<VirtualRegister>(operands.operandForIndex(index)))); break; @@ -321,7 +321,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov m_jit.boxDouble(fpr, gpr); } - // 8) Dump all doubles into the register file, or to the scratch storage if + // 8) Dump all doubles into the stack, or to the scratch storage if // the destination virtual register is poisoned. for (size_t index = 0; index < operands.size(); ++index) { @@ -340,11 +340,11 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov // At this point all GPRs and FPRs are available for scratch use. - // 9) Box all unboxed doubles in the register file. + // 9) Box all unboxed doubles in the stack. if (haveUnboxedDoubles) { for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; - if (recovery.technique() != AlreadyInRegisterFileAsUnboxedDouble) + if (recovery.technique() != AlreadyInJSStackAsUnboxedDouble) continue; m_jit.loadDouble(AssemblyHelpers::addressFor((VirtualRegister)operands.operandForIndex(index)), FPRInfo::fpRegT0); m_jit.boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0); @@ -367,18 +367,18 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case DisplacedInRegisterFile: + case DisplacedInJSStack: m_jit.loadPtr(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::toRegister(displacementIndex++)); break; - case Int32DisplacedInRegisterFile: { + case Int32DisplacedInJSStack: { GPRReg gpr = GPRInfo::toRegister(displacementIndex++); m_jit.load32(AssemblyHelpers::addressFor(recovery.virtualRegister()), gpr); m_jit.orPtr(GPRInfo::tagTypeNumberRegister, gpr); break; } - case DoubleDisplacedInRegisterFile: { + case DoubleDisplacedInJSStack: { GPRReg gpr = GPRInfo::toRegister(displacementIndex++); m_jit.loadPtr(AssemblyHelpers::addressFor(recovery.virtualRegister()), gpr); m_jit.subPtr(GPRInfo::tagTypeNumberRegister, gpr); @@ -394,9 +394,9 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case DisplacedInRegisterFile: - case Int32DisplacedInRegisterFile: - case DoubleDisplacedInRegisterFile: + case DisplacedInJSStack: + case Int32DisplacedInJSStack: + case DoubleDisplacedInJSStack: m_jit.storePtr(GPRInfo::toRegister(displacementIndex++), AssemblyHelpers::addressFor((VirtualRegister)operands.operandForIndex(index))); break; @@ -427,19 +427,19 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case DisplacedInRegisterFile: + case DisplacedInJSStack: m_jit.loadPtr(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::regT0); m_jit.storePtr(GPRInfo::regT0, scratchDataBuffer + scratchIndex++); break; - case Int32DisplacedInRegisterFile: { + case Int32DisplacedInJSStack: { m_jit.load32(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::regT0); m_jit.orPtr(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0); m_jit.storePtr(GPRInfo::regT0, scratchDataBuffer + scratchIndex++); break; } - case DoubleDisplacedInRegisterFile: { + case DoubleDisplacedInJSStack: { m_jit.loadPtr(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::regT0); m_jit.subPtr(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0); m_jit.storePtr(GPRInfo::regT0, scratchDataBuffer + scratchIndex++); @@ -455,9 +455,9 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov for (size_t index = 0; index < operands.size(); ++index) { const ValueRecovery& recovery = operands[index]; switch (recovery.technique()) { - case DisplacedInRegisterFile: - case Int32DisplacedInRegisterFile: - case DoubleDisplacedInRegisterFile: + case DisplacedInJSStack: + case Int32DisplacedInJSStack: + case DoubleDisplacedInJSStack: m_jit.loadPtr(scratchDataBuffer + scratchIndex++, GPRInfo::regT0); m_jit.storePtr(GPRInfo::regT0, AssemblyHelpers::addressFor((VirtualRegister)operands.operandForIndex(index))); break; @@ -553,7 +553,7 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov // 14) Reify inlined call frames. ASSERT(m_jit.baselineCodeBlock()->getJITType() == JITCode::BaselineJIT); - m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), AssemblyHelpers::addressFor((VirtualRegister)RegisterFile::CodeBlock)); + m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(m_jit.baselineCodeBlock()), AssemblyHelpers::addressFor((VirtualRegister)JSStack::CodeBlock)); for (CodeOrigin codeOrigin = exit.m_codeOrigin; codeOrigin.inlineCallFrame; codeOrigin = codeOrigin.inlineCallFrame->caller) { InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; @@ -575,12 +575,12 @@ void OSRExitCompiler::compileExit(const OSRExit& exit, const Operands<ValueRecov } else callerFrameGPR = GPRInfo::callFrameRegister; - m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CodeBlock))); - m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee->scope()), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ScopeChain))); - m_jit.storePtr(callerFrameGPR, AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CallerFrame))); - m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ReturnPC))); - m_jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ArgumentCount))); - m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee.get()), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::Callee))); + m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(baselineCodeBlock), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CodeBlock))); + m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee->scope()), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ScopeChain))); + m_jit.storePtr(callerFrameGPR, AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::CallerFrame))); + m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(jumpTarget), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ReturnPC))); + m_jit.store32(AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), AssemblyHelpers::payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::ArgumentCount))); + m_jit.storePtr(AssemblyHelpers::TrustedImmPtr(inlineCallFrame->callee.get()), AssemblyHelpers::addressFor((VirtualRegister)(inlineCallFrame->stackOffset + JSStack::Callee))); } // 15) Create arguments if necessary and place them into the appropriate aliased diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp index eaa0f47f7..db736feeb 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.cpp +++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp @@ -49,7 +49,7 @@ #if ENABLE(DFG_JIT) -#if CPU(X86_64) +#if COMPILER(GCC) && CPU(X86_64) #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \ asm( \ @@ -64,7 +64,7 @@ #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx) #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8) -#elif CPU(X86) +#elif COMPILER(GCC) && CPU(X86) #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset) \ asm( \ @@ -556,9 +556,7 @@ void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSO NativeCallFrameTracer tracer(globalData, exec); if (index >= 0) { - // We should only get here if index is outside the existing vector. - ASSERT(!array->canSetIndexQuickly(index)); - array->methodTable()->putByIndex(array, exec, index, JSValue::decode(encodedValue), true); + array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true); return; } @@ -573,9 +571,7 @@ void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, NativeCallFrameTracer tracer(globalData, exec); if (index >= 0) { - // We should only get here if index is outside the existing vector. - ASSERT(!array->canSetIndexQuickly(index)); - array->methodTable()->putByIndex(array, exec, index, JSValue::decode(encodedValue), false); + array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false); return; } @@ -601,6 +597,16 @@ EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array) return JSValue::encode(array->pop(exec)); } +EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array) +{ + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + + array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1); + + return JSValue::encode(array->pop(exec)); +} + EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument) { JSGlobalData& globalData = exec->globalData(); @@ -1100,29 +1106,35 @@ EncodedJSValue DFG_OPERATION operationStrCat(ExecState* exec, void* buffer, size return JSValue::encode(jsString(exec, static_cast<Register*>(buffer), size)); } -EncodedJSValue DFG_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size) +char* DFG_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size) { JSGlobalData* globalData = &exec->globalData(); NativeCallFrameTracer tracer(globalData, exec); - - return JSValue::encode(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size)); + + return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size)); } -EncodedJSValue DFG_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure) +char* DFG_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure) { - return JSValue::encode(JSArray::create(exec->globalData(), arrayStructure)); + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + + return bitwise_cast<char*>(JSArray::create(*globalData, arrayStructure)); } -EncodedJSValue DFG_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size) +char* DFG_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size) { - return JSValue::encode(JSArray::create(exec->globalData(), arrayStructure, size)); + JSGlobalData* globalData = &exec->globalData(); + NativeCallFrameTracer tracer(globalData, exec); + + return bitwise_cast<char*>(JSArray::create(*globalData, arrayStructure, size)); } -EncodedJSValue DFG_OPERATION operationNewArrayBuffer(ExecState* exec, size_t start, size_t size) +char* DFG_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size) { JSGlobalData& globalData = exec->globalData(); NativeCallFrameTracer tracer(&globalData, exec); - return JSValue::encode(constructArray(exec, exec->codeBlock()->constantBuffer(start), size)); + return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size)); } EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr) @@ -1309,6 +1321,14 @@ char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* return reinterpret_cast<char*>(result); } +char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSObject* object) +{ + JSGlobalData& globalData = exec->globalData(); + NativeCallFrameTracer tracer(&globalData, exec); + + return reinterpret_cast<char*>(object->ensureContiguous(globalData)); +} + char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSObject* object) { JSGlobalData& globalData = exec->globalData(); @@ -1317,6 +1337,16 @@ char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSObject* objec return reinterpret_cast<char*>(object->ensureArrayStorage(globalData)); } +char* DFG_OPERATION operationEnsureContiguousOrArrayStorage(ExecState* exec, JSObject* object, int32_t index) +{ + JSGlobalData& globalData = exec->globalData(); + NativeCallFrameTracer tracer(&globalData, exec); + + if (static_cast<unsigned>(index) >= MIN_SPARSE_ARRAY_INDEX) + return reinterpret_cast<char*>(object->ensureArrayStorage(globalData)); + return reinterpret_cast<char*>(object->ensureIndexedStorage(globalData)); +} + double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b) { return fmod(a, b); @@ -1425,11 +1455,9 @@ extern "C" void DFG_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock) #endif // ENABLE(DFG_JIT) -#if COMPILER(GCC) - namespace JSC { -#if CPU(X86_64) +#if COMPILER(GCC) && CPU(X86_64) asm ( ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n" HIDE_SYMBOL(getHostCallReturnValue) "\n" @@ -1438,7 +1466,7 @@ SYMBOL_STRING(getHostCallReturnValue) ":" "\n" "mov %r13, %rdi\n" "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n" ); -#elif CPU(X86) +#elif COMPILER(GCC) && CPU(X86) asm ( ".text" "\n" \ ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n" @@ -1448,7 +1476,7 @@ SYMBOL_STRING(getHostCallReturnValue) ":" "\n" "mov %edi, 4(%esp)\n" "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n" ); -#elif CPU(ARM_THUMB2) +#elif COMPILER(GCC) && CPU(ARM_THUMB2) asm ( ".text" "\n" ".align 2" "\n" @@ -1461,7 +1489,7 @@ SYMBOL_STRING(getHostCallReturnValue) ":" "\n" "mov r0, r5" "\n" "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n" ); -#elif CPU(ARM_TRADITIONAL) +#elif COMPILER(GCC) && CPU(ARM_TRADITIONAL) asm ( ".text" "\n" ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n" @@ -1483,6 +1511,4 @@ extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWi } // namespace JSC -#endif // COMPILER(GCC) - #endif // ENABLE(JIT) diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h index 3b947ecbf..b6530b755 100644 --- a/Source/JavaScriptCore/dfg/DFGOperations.h +++ b/Source/JavaScriptCore/dfg/DFGOperations.h @@ -77,9 +77,6 @@ typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EP)(ExecState*, void*); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EPP)(ExecState*, void*, void*); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EPS)(ExecState*, void*, size_t); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ESS)(ExecState*, size_t, size_t); -typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ESt)(ExecState*, Structure*); -typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EStI)(ExecState*, Structure*, int32_t); -typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EStPS)(ExecState*, Structure*, void*, size_t); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EZ)(ExecState*, int32_t); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EZIcfZ)(ExecState*, int32_t, InlineCallFrame*, int32_t); typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EZZ)(ExecState*, int32_t, int32_t); @@ -110,8 +107,13 @@ typedef void DFG_OPERATION (*V_DFGOperation_W)(WatchpointSet*); typedef char* DFG_OPERATION (*P_DFGOperation_E)(ExecState*); typedef char* DFG_OPERATION (*P_DFGOperation_EO)(ExecState*, JSObject*); typedef char* DFG_OPERATION (*P_DFGOperation_EOS)(ExecState*, JSObject*, size_t); +typedef char* DFG_OPERATION (*P_DFGOperation_EOZ)(ExecState*, JSObject*, int32_t); typedef char* DFG_OPERATION (*P_DFGOperation_EPS)(ExecState*, void*, size_t); typedef char* DFG_OPERATION (*P_DFGOperation_ES)(ExecState*, size_t); +typedef char* DFG_OPERATION (*P_DFGOperation_ESt)(ExecState*, Structure*); +typedef char* DFG_OPERATION (*P_DFGOperation_EStPS)(ExecState*, Structure*, void*, size_t); +typedef char* DFG_OPERATION (*P_DFGOperation_EStSS)(ExecState*, Structure*, size_t, size_t); +typedef char* DFG_OPERATION (*P_DFGOperation_EStZ)(ExecState*, Structure*, int32_t); // These routines are provide callbacks out to C++ implementations of operations too complex to JIT. JSCell* DFG_OPERATION operationNewObject(ExecState*) WTF_INTERNAL; @@ -135,10 +137,10 @@ EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState*, Identifie EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState*, GlobalResolveInfo*, JSGlobalObject*, Identifier*) WTF_INTERNAL; EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState*, EncodedJSValue) WTF_INTERNAL; EncodedJSValue DFG_OPERATION operationStrCat(ExecState*, void*, size_t) WTF_INTERNAL; -EncodedJSValue DFG_OPERATION operationNewArray(ExecState*, Structure*, void*, size_t) WTF_INTERNAL; -EncodedJSValue DFG_OPERATION operationNewArrayBuffer(ExecState*, size_t, size_t) WTF_INTERNAL; -EncodedJSValue DFG_OPERATION operationNewEmptyArray(ExecState*, Structure*) WTF_INTERNAL; -EncodedJSValue DFG_OPERATION operationNewArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL; +char* DFG_OPERATION operationNewArray(ExecState*, Structure*, void*, size_t) WTF_INTERNAL; +char* DFG_OPERATION operationNewArrayBuffer(ExecState*, Structure*, size_t, size_t) WTF_INTERNAL; +char* DFG_OPERATION operationNewEmptyArray(ExecState*, Structure*) WTF_INTERNAL; +char* DFG_OPERATION operationNewArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL; EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState*, void*) WTF_INTERNAL; void DFG_OPERATION operationPutByValStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL; void DFG_OPERATION operationPutByValNonStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL; @@ -148,6 +150,7 @@ void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState*, JSObject void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState*, JSObject*, int32_t index, EncodedJSValue encodedValue) WTF_INTERNAL; EncodedJSValue DFG_OPERATION operationArrayPush(ExecState*, EncodedJSValue encodedValue, JSArray*) WTF_INTERNAL; EncodedJSValue DFG_OPERATION operationArrayPop(ExecState*, JSArray*) WTF_INTERNAL; +EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState*, JSArray*) WTF_INTERNAL; EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState*, JSCell*, JSCell*) WTF_INTERNAL; void DFG_OPERATION operationPutByIdStrict(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*) WTF_INTERNAL; void DFG_OPERATION operationPutByIdNonStrict(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*) WTF_INTERNAL; @@ -192,7 +195,9 @@ char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecStat char* DFG_OPERATION operationAllocatePropertyStorage(ExecState*, size_t newSize) WTF_INTERNAL; char* DFG_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState*, JSObject*) WTF_INTERNAL; char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState*, JSObject*, size_t newSize) WTF_INTERNAL; +char* DFG_OPERATION operationEnsureContiguous(ExecState*, JSObject*); char* DFG_OPERATION operationEnsureArrayStorage(ExecState*, JSObject*); +char* DFG_OPERATION operationEnsureContiguousOrArrayStorage(ExecState*, JSObject*, int32_t); // This method is used to lookup an exception hander, keyed by faultLocation, which is // the return location from one of the calls out to one of the helper operations above. diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp index b05537fdf..6fb185c12 100644 --- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp +++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp @@ -256,7 +256,7 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSCell::structureOffset()), scratchGPR); stubJit.load8(MacroAssembler::Address(scratchGPR, Structure::indexingTypeOffset()), scratchGPR); failureCases.append(stubJit.branchTest32(MacroAssembler::Zero, scratchGPR, MacroAssembler::TrustedImm32(IsArray))); - failureCases.append(stubJit.branchTest32(MacroAssembler::Zero, scratchGPR, MacroAssembler::TrustedImm32(HasArrayStorage))); + failureCases.append(stubJit.branchTest32(MacroAssembler::Zero, scratchGPR, MacroAssembler::TrustedImm32(IndexingShapeMask))); stubJit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR); stubJit.load32(MacroAssembler::Address(scratchGPR, ArrayStorage::lengthOffset()), scratchGPR); @@ -448,7 +448,7 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi // right now! stubJit.store32( MacroAssembler::TrustedImm32(exec->codeOriginIndexForDFG()), - CCallHelpers::tagFor(static_cast<VirtualRegister>(RegisterFile::ArgumentCount))); + CCallHelpers::tagFor(static_cast<VirtualRegister>(JSStack::ArgumentCount))); operationCall = stubJit.call(); #if USE(JSVALUE64) diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp index 05b1e741e..850d5aa74 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp @@ -29,6 +29,7 @@ #if ENABLE(DFG_JIT) #include "Arguments.h" +#include "DFGCallArrayAllocatorSlowPathGenerator.h" #include "DFGSlowPathGenerator.h" #include "LinkBuffer.h" @@ -56,6 +57,37 @@ SpeculativeJIT::~SpeculativeJIT() WTF::deleteAllValues(m_slowPathGenerators); } +void SpeculativeJIT::emitAllocateJSArray(Structure* structure, GPRReg resultGPR, GPRReg storageGPR, unsigned numElements) +{ + ASSERT(hasContiguous(structure->indexingType())); + + GPRTemporary scratch(this); + GPRReg scratchGPR = scratch.gpr(); + + unsigned vectorLength = std::max(BASE_VECTOR_LEN, numElements); + + JITCompiler::JumpList slowCases; + slowCases.append( + emitAllocateBasicStorage(TrustedImm32(vectorLength * sizeof(JSValue) + sizeof(IndexingHeader)), storageGPR)); + m_jit.subPtr(TrustedImm32(vectorLength * sizeof(JSValue)), storageGPR); + emitAllocateBasicJSObject<JSArray, MarkedBlock::None>( + TrustedImmPtr(structure), resultGPR, scratchGPR, + storageGPR, sizeof(JSArray), slowCases); + + // I'm assuming that two 32-bit stores are better than a 64-bit store. + // I have no idea if that's true. And it probably doesn't matter anyway. + m_jit.store32(TrustedImm32(numElements), MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); + m_jit.store32(TrustedImm32(vectorLength), MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); + + // I want a slow path that also loads out the storage pointer, and that's + // what this custom CallArrayAllocatorSlowPathGenerator gives me. It's a lot + // of work for a very small piece of functionality. :-/ + addSlowPathGenerator(adoptPtr( + new CallArrayAllocatorSlowPathGenerator( + slowCases, this, operationNewArrayWithSize, resultGPR, storageGPR, + structure, numElements))); +} + void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::Jump jumpToFail) { if (!m_compileOkay) @@ -70,7 +102,7 @@ void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource speculationCheck(kind, jsValueSource, nodeUse.index(), jumpToFail); } -void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::JumpList& jumpsToFail) +void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, const MacroAssembler::JumpList& jumpsToFail) { ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes); Vector<MacroAssembler::Jump, 16> jumpVector = jumpsToFail.jumps(); @@ -78,7 +110,7 @@ void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource speculationCheck(kind, jsValueSource, nodeIndex, jumpVector[i]); } -void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, MacroAssembler::JumpList& jumpsToFail) +void SpeculativeJIT::speculationCheck(ExitKind kind, JSValueSource jsValueSource, Edge nodeUse, const MacroAssembler::JumpList& jumpsToFail) { ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes); speculationCheck(kind, jsValueSource, nodeUse.index(), jumpsToFail); @@ -190,7 +222,7 @@ void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValu convertLastOSRExitToForward(valueRecovery); } -void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& valueRecovery) +void SpeculativeJIT::forwardSpeculationCheck(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& valueRecovery) { ASSERT(at(m_compileIndex).canExit() || m_isCheckingArgumentTypes); Vector<MacroAssembler::Jump, 16> jumpVector = jumpsToFail.jumps(); @@ -295,6 +327,66 @@ const TypedArrayDescriptor* SpeculativeJIT::typedArrayDescriptor(Array::Mode arr } } +JITCompiler::JumpList SpeculativeJIT::jumpSlowForUnwantedArrayMode(GPRReg tempGPR, Array::Mode arrayMode) +{ + JITCompiler::JumpList result; + + switch (arrayMode) { + case NON_ARRAY_CONTIGUOUS_MODES: { + m_jit.and32(TrustedImm32(IndexingShapeMask), tempGPR); + result.append( + m_jit.branch32(MacroAssembler::NotEqual, tempGPR, TrustedImm32(ContiguousShape))); + break; + } + case ARRAY_WITH_CONTIGUOUS_MODES: { + m_jit.and32(TrustedImm32(IsArray | IndexingShapeMask), tempGPR); + result.append( + m_jit.branch32( + MacroAssembler::NotEqual, tempGPR, TrustedImm32(IsArray | ContiguousShape))); + break; + } + case NON_ARRAY_ARRAY_STORAGE_MODES: { + m_jit.and32(TrustedImm32(IndexingShapeMask), tempGPR); + if (isSlowPutAccess(arrayMode)) { + m_jit.sub32(TrustedImm32(ArrayStorageShape), tempGPR); + result.append( + m_jit.branch32( + MacroAssembler::Above, tempGPR, + TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape))); + } else { + result.append( + m_jit.branch32(MacroAssembler::NotEqual, tempGPR, TrustedImm32(ArrayStorageShape))); + } + break; + } + case Array::ArrayWithArrayStorage: + case Array::ArrayWithArrayStorageToHole: + case Array::ArrayWithArrayStorageOutOfBounds: { + m_jit.and32(TrustedImm32(IsArray | IndexingShapeMask), tempGPR); + result.append( + m_jit.branch32(MacroAssembler::NotEqual, tempGPR, TrustedImm32(ArrayStorageShape))); + break; + } + case Array::ArrayWithSlowPutArrayStorage: { + result.append( + m_jit.branchTest32( + MacroAssembler::Zero, tempGPR, MacroAssembler::TrustedImm32(IsArray))); + m_jit.and32(TrustedImm32(IndexingShapeMask), tempGPR); + m_jit.sub32(TrustedImm32(ArrayStorageShape), tempGPR); + result.append( + m_jit.branch32( + MacroAssembler::Above, tempGPR, + TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape))); + break; + } + default: + CRASH(); + break; + } + + return result; +} + void SpeculativeJIT::checkArray(Node& node) { ASSERT(modeIsSpecific(node.arrayMode())); @@ -315,39 +407,18 @@ void SpeculativeJIT::checkArray(Node& node) case Array::String: expectedClassInfo = &JSString::s_info; break; - case NON_ARRAY_ARRAY_STORAGE_MODES: { - GPRTemporary temp(this); - m_jit.loadPtr( - MacroAssembler::Address(baseReg, JSCell::structureOffset()), temp.gpr()); - speculationCheck( - Uncountable, JSValueRegs(), NoNode, - m_jit.branchTest8( - MacroAssembler::Zero, - MacroAssembler::Address(temp.gpr(), Structure::indexingTypeOffset()), - MacroAssembler::TrustedImm32( - isSlowPutAccess(node.arrayMode()) ? (HasArrayStorage | HasSlowPutArrayStorage) : HasArrayStorage))); - - noResult(m_compileIndex); - return; - } + case NON_ARRAY_CONTIGUOUS_MODES: + case ARRAY_WITH_CONTIGUOUS_MODES: + case NON_ARRAY_ARRAY_STORAGE_MODES: case ARRAY_WITH_ARRAY_STORAGE_MODES: { GPRTemporary temp(this); GPRReg tempGPR = temp.gpr(); m_jit.loadPtr( MacroAssembler::Address(baseReg, JSCell::structureOffset()), tempGPR); m_jit.load8(MacroAssembler::Address(tempGPR, Structure::indexingTypeOffset()), tempGPR); - // FIXME: This can be turned into a single branch. But we currently have no evidence - // that doing so would be profitable, nor do I feel comfortable with the present test - // coverage for this code path. speculationCheck( Uncountable, JSValueRegs(), NoNode, - m_jit.branchTest32( - MacroAssembler::Zero, tempGPR, MacroAssembler::TrustedImm32(IsArray))); - speculationCheck( - Uncountable, JSValueRegs(), NoNode, - m_jit.branchTest32( - MacroAssembler::Zero, tempGPR, MacroAssembler::TrustedImm32( - isSlowPutAccess(node.arrayMode()) ? (HasArrayStorage | HasSlowPutArrayStorage) : HasArrayStorage))); + jumpSlowForUnwantedArrayMode(tempGPR, node.arrayMode())); noResult(m_compileIndex); return; @@ -384,78 +455,122 @@ void SpeculativeJIT::checkArray(Node& node) noResult(m_compileIndex); } -void SpeculativeJIT::arrayify(Node& node) +void SpeculativeJIT::arrayify(Node& node, GPRReg baseReg, GPRReg propertyReg) { - ASSERT(modeIsSpecific(node.arrayMode())); - ASSERT(!modeAlreadyChecked(m_state.forNode(node.child1()), node.arrayMode())); - - SpeculateCellOperand base(this, node.child1()); - GPRReg baseReg = base.gpr(); + Array::Mode desiredArrayMode; switch (node.arrayMode()) { - case EFFECTFUL_NON_ARRAY_ARRAY_STORAGE_MODES: { - GPRTemporary structure(this); - GPRTemporary temp(this); - GPRReg structureGPR = structure.gpr(); - GPRReg tempGPR = temp.gpr(); - - m_jit.loadPtr( - MacroAssembler::Address(baseReg, JSCell::structureOffset()), structureGPR); + case Array::ToContiguous: + desiredArrayMode = Array::Contiguous; + break; + case Array::ToArrayStorage: + desiredArrayMode = Array::ArrayStorage; + break; + case Array::ToSlowPutArrayStorage: + desiredArrayMode = Array::SlowPutArrayStorage; + break; + case Array::ArrayToArrayStorage: + desiredArrayMode = Array::ArrayWithArrayStorage; + break; + case Array::PossiblyArrayToArrayStorage: + desiredArrayMode = Array::PossiblyArrayWithArrayStorage; + break; + default: + CRASH(); + desiredArrayMode = Array::Undecided; + break; + } + + GPRTemporary structure(this); + GPRTemporary temp(this); + GPRReg structureGPR = structure.gpr(); + GPRReg tempGPR = temp.gpr(); - // We can skip all that comes next if we already have array storage. - IndexingType desiredIndexingTypeMask = - isSlowPutAccess(node.arrayMode()) ? (HasArrayStorage | HasSlowPutArrayStorage) : HasArrayStorage; - MacroAssembler::Jump slowCase = m_jit.branchTest8( - MacroAssembler::Zero, - MacroAssembler::Address(structureGPR, Structure::indexingTypeOffset()), - MacroAssembler::TrustedImm32(desiredIndexingTypeMask)); + m_jit.loadPtr( + MacroAssembler::Address(baseReg, JSCell::structureOffset()), structureGPR); + + m_jit.load8( + MacroAssembler::Address(structureGPR, Structure::indexingTypeOffset()), tempGPR); - m_jit.loadPtr( - MacroAssembler::Address(baseReg, JSObject::butterflyOffset()), tempGPR); + // We can skip all that comes next if we already have array storage. + MacroAssembler::JumpList slowCases = + jumpSlowForUnwantedArrayMode(tempGPR, desiredArrayMode); - MacroAssembler::Jump done = m_jit.jump(); + m_jit.loadPtr( + MacroAssembler::Address(baseReg, JSObject::butterflyOffset()), tempGPR); - slowCase.link(&m_jit); + MacroAssembler::Jump done = m_jit.jump(); - // Next check that the object does not intercept indexed accesses. If it does, - // then this mode won't work. + slowCases.link(&m_jit); + + // If we're allegedly creating contiguous storage and the index is bogus, then + // just don't. + if (node.arrayMode() == Array::ToContiguous && propertyReg != InvalidGPRReg) { speculationCheck( Uncountable, JSValueRegs(), NoNode, - m_jit.branchTest8( - MacroAssembler::NonZero, - MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()), - MacroAssembler::TrustedImm32(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero))); + m_jit.branch32( + MacroAssembler::AboveOrEqual, propertyReg, TrustedImm32(MIN_SPARSE_ARRAY_INDEX))); + } + + // Next check that the object does not intercept indexed accesses. If it does, + // then this mode won't work. + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + m_jit.branchTest8( + MacroAssembler::NonZero, + MacroAssembler::Address(structureGPR, Structure::typeInfoFlagsOffset()), + MacroAssembler::TrustedImm32(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero))); - // Now call out to create the array storage. - silentSpillAllRegisters(tempGPR); + // Now call out to create the array storage. + silentSpillAllRegisters(tempGPR); + switch (node.arrayMode()) { + case ALL_EFFECTFUL_CONTIGUOUS_MODES: + callOperation(operationEnsureContiguous, tempGPR, baseReg); + break; + case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: callOperation(operationEnsureArrayStorage, tempGPR, baseReg); - silentFillAllRegisters(tempGPR); - - // Alas, we need to reload the structure because silent spilling does not save - // temporaries. Nor would it be useful for it to do so. Either way we're talking - // about a load. - m_jit.loadPtr( - MacroAssembler::Address(baseReg, JSCell::structureOffset()), structureGPR); - - // Finally, check that we have the kind of array storage that we wanted to get. - // Note that this is a backwards speculation check, which will result in the - // bytecode operation corresponding to this arrayification being reexecuted. - // That's fine, since arrayification is not user-visible. - speculationCheck( - Uncountable, JSValueRegs(), NoNode, - m_jit.branchTest8( - MacroAssembler::Zero, - MacroAssembler::Address(structureGPR, Structure::indexingTypeOffset()), - MacroAssembler::TrustedImm32(desiredIndexingTypeMask))); - - done.link(&m_jit); - storageResult(tempGPR, m_compileIndex); break; - } default: - ASSERT_NOT_REACHED(); + CRASH(); break; } + silentFillAllRegisters(tempGPR); + + // Alas, we need to reload the structure because silent spilling does not save + // temporaries. Nor would it be useful for it to do so. Either way we're talking + // about a load. + m_jit.loadPtr( + MacroAssembler::Address(baseReg, JSCell::structureOffset()), structureGPR); + + // Finally, check that we have the kind of array storage that we wanted to get. + // Note that this is a backwards speculation check, which will result in the + // bytecode operation corresponding to this arrayification being reexecuted. + // That's fine, since arrayification is not user-visible. + m_jit.load8( + MacroAssembler::Address(structureGPR, Structure::indexingTypeOffset()), structureGPR); + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + jumpSlowForUnwantedArrayMode(structureGPR, desiredArrayMode)); + + done.link(&m_jit); + storageResult(tempGPR, m_compileIndex); +} + +void SpeculativeJIT::arrayify(Node& node) +{ + ASSERT(modeIsSpecific(node.arrayMode())); + ASSERT(!modeAlreadyChecked(m_state.forNode(node.child1()), node.arrayMode())); + + SpeculateCellOperand base(this, node.child1()); + + if (!node.child2()) { + arrayify(node, base.gpr(), InvalidGPRReg); + return; + } + + SpeculateIntegerOperand property(this, node.child2()); + + arrayify(node, base.gpr(), property.gpr()); } GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex) @@ -1367,7 +1482,7 @@ void SpeculativeJIT::compile(BasicBlock& block) ASSERT(m_arguments.size() == block.variablesAtHead.numberOfArguments()); for (size_t i = 0; i < m_arguments.size(); ++i) { - ValueSource valueSource = ValueSource(ValueInRegisterFile); + ValueSource valueSource = ValueSource(ValueInJSStack); m_arguments[i] = valueSource; m_stream->appendAndLog(VariableEvent::setLocal(argumentToOperand(i), valueSource.dataFormat())); } @@ -1384,11 +1499,11 @@ void SpeculativeJIT::compile(BasicBlock& block) else if (at(nodeIndex).variableAccessData()->isArgumentsAlias()) valueSource = ValueSource(ArgumentsSource); else if (at(nodeIndex).variableAccessData()->isCaptured()) - valueSource = ValueSource(ValueInRegisterFile); + valueSource = ValueSource(ValueInJSStack); else if (!at(nodeIndex).refCount()) valueSource = ValueSource(SourceIsDead); else if (at(nodeIndex).variableAccessData()->shouldUseDoubleFormat()) - valueSource = ValueSource(DoubleInRegisterFile); + valueSource = ValueSource(DoubleInJSStack); else valueSource = ValueSource::forSpeculation(at(nodeIndex).variableAccessData()->argumentAwarePrediction()); m_variables[i] = valueSource; @@ -1440,25 +1555,25 @@ void SpeculativeJIT::compile(BasicBlock& block) for (int i = 0; i < argumentCountIncludingThis; ++i) { ValueRecovery recovery; if (codeBlock->isCaptured(argumentToOperand(i))) - recovery = ValueRecovery::alreadyInRegisterFile(); + recovery = ValueRecovery::alreadyInJSStack(); else { ArgumentPosition& argumentPosition = m_jit.graph().m_argumentPositions[argumentPositionStart + i]; ValueSource valueSource; if (argumentPosition.shouldUseDoubleFormat()) - valueSource = ValueSource(DoubleInRegisterFile); + valueSource = ValueSource(DoubleInJSStack); else if (isInt32Speculation(argumentPosition.prediction())) - valueSource = ValueSource(Int32InRegisterFile); + valueSource = ValueSource(Int32InJSStack); else if (isCellSpeculation(argumentPosition.prediction())) - valueSource = ValueSource(CellInRegisterFile); + valueSource = ValueSource(CellInJSStack); else if (isBooleanSpeculation(argumentPosition.prediction())) - valueSource = ValueSource(BooleanInRegisterFile); + valueSource = ValueSource(BooleanInJSStack); else - valueSource = ValueSource(ValueInRegisterFile); + valueSource = ValueSource(ValueInJSStack); recovery = computeValueRecoveryFor(valueSource); } // The recovery should refer either to something that has already been - // stored into the register file at the right place, or to a constant, + // stored into the stack at the right place, or to a constant, // since the Arguments code isn't smart enough to handle anything else. // The exception is the this argument, which we don't really need to be // able to recover. @@ -1550,9 +1665,9 @@ void SpeculativeJIT::checkArgumentTypes() m_codeOriginForOSR = CodeOrigin(0); for (size_t i = 0; i < m_arguments.size(); ++i) - m_arguments[i] = ValueSource(ValueInRegisterFile); + m_arguments[i] = ValueSource(ValueInJSStack); for (size_t i = 0; i < m_variables.size(); ++i) - m_variables[i] = ValueSource(ValueInRegisterFile); + m_variables[i] = ValueSource(ValueInJSStack); for (int i = 0; i < m_jit.codeBlock()->numParameters(); ++i) { NodeIndex nodeIndex = m_jit.graph().m_arguments[i]; @@ -1649,7 +1764,7 @@ void SpeculativeJIT::linkOSREntries(LinkBuffer& linkBuffer) ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSource) { - if (valueSource.isInRegisterFile()) + if (valueSource.isInJSStack()) return valueSource.valueRecovery(); ASSERT(valueSource.kind() == HaveNode); @@ -1942,16 +2057,17 @@ void SpeculativeJIT::compileUInt32ToNumber(Node& node) } IntegerOperand op1(this, node.child1()); - GPRTemporary result(this, op1); + GPRTemporary result(this); // For the benefit of OSR exit, force these to be in different registers. In reality the OSR exit compiler could find cases where you have uint32(%r1) followed by int32(%r1) and then use different registers, but that seems like too much effort. + + m_jit.move(op1.gpr(), result.gpr()); // Test the operand is positive. This is a very special speculation check - we actually // use roll-forward speculation here, where if this fails, we jump to the baseline // instruction that follows us, rather than the one we're executing right now. We have // to do this because by this point, the original values necessary to compile whatever // operation the UInt32ToNumber originated from might be dead. - forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)), ValueRecovery::uint32InGPR(op1.gpr())); + forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, result.gpr(), TrustedImm32(0)), ValueRecovery::uint32InGPR(result.gpr())); - m_jit.move(op1.gpr(), result.gpr()); integerResult(result.gpr(), m_compileIndex, op1.format()); } @@ -2140,7 +2256,7 @@ void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor& m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesFour), resultReg); break; default: - ASSERT_NOT_REACHED(); + CRASH(); } if (elementSize < 4 || signedness == SignedTypedArray) { integerResult(resultReg, m_compileIndex); @@ -2250,7 +2366,7 @@ void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& m_jit.store32(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesFour)); break; default: - ASSERT_NOT_REACHED(); + CRASH(); } if (node.op() == PutByVal) outOfBounds.link(&m_jit); @@ -3205,12 +3321,23 @@ void SpeculativeJIT::compileGetArrayLength(Node& node) const TypedArrayDescriptor* descriptor = typedArrayDescriptor(node.arrayMode()); switch (node.arrayMode()) { - case ARRAY_WITH_ARRAY_STORAGE_MODES: { + case ARRAY_WITH_CONTIGUOUS_MODES: { + StorageOperand storage(this, node.child2()); + GPRTemporary result(this, storage); + GPRReg storageReg = storage.gpr(); + GPRReg resultReg = result.gpr(); + m_jit.load32(MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()), resultReg); + + integerResult(resultReg, m_compileIndex); + break; + } + case ARRAY_WITH_ARRAY_STORAGE_MODES: + case ARRAY_EFFECTFUL_MODES: { StorageOperand storage(this, node.child2()); GPRTemporary result(this, storage); GPRReg storageReg = storage.gpr(); GPRReg resultReg = result.gpr(); - m_jit.load32(MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()), resultReg); + m_jit.load32(MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()), resultReg); speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultReg, MacroAssembler::TrustedImm32(0))); @@ -3328,14 +3455,11 @@ void SpeculativeJIT::compileAllocatePropertyStorage(Node& node) ASSERT(!node.structureTransitionData().previousStructure->outOfLineCapacity()); ASSERT(initialOutOfLineCapacity == node.structureTransitionData().newStructure->outOfLineCapacity()); - size_t newSize = initialOutOfLineCapacity * sizeof(JSValue); - CopiedAllocator* copiedAllocator = &m_jit.globalData()->heap.storageAllocator(); - - m_jit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR); - JITCompiler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, JITCompiler::TrustedImm32(newSize), scratchGPR); - m_jit.storePtr(scratchGPR, &copiedAllocator->m_currentRemaining); - m_jit.negPtr(scratchGPR); - m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR); + + JITCompiler::Jump slowPath = + emitAllocateBasicStorage( + TrustedImm32(initialOutOfLineCapacity * sizeof(JSValue)), scratchGPR); + m_jit.addPtr(JITCompiler::TrustedImm32(sizeof(JSValue)), scratchGPR); addSlowPathGenerator( @@ -3376,15 +3500,9 @@ void SpeculativeJIT::compileReallocatePropertyStorage(Node& node) GPRReg scratchGPR1 = scratch1.gpr(); GPRReg scratchGPR2 = scratch2.gpr(); - JITCompiler::Jump slowPath; - - CopiedAllocator* copiedAllocator = &m_jit.globalData()->heap.storageAllocator(); - - m_jit.loadPtr(&copiedAllocator->m_currentRemaining, scratchGPR2); - slowPath = m_jit.branchSubPtr(JITCompiler::Signed, JITCompiler::TrustedImm32(newSize), scratchGPR2); - m_jit.storePtr(scratchGPR2, &copiedAllocator->m_currentRemaining); - m_jit.negPtr(scratchGPR2); - m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), scratchGPR2); + JITCompiler::Jump slowPath = + emitAllocateBasicStorage(TrustedImm32(newSize), scratchGPR2); + m_jit.addPtr(JITCompiler::TrustedImm32(sizeof(JSValue)), scratchGPR2); addSlowPathGenerator( @@ -3399,6 +3517,16 @@ void SpeculativeJIT::compileReallocatePropertyStorage(Node& node) storageResult(scratchGPR2, m_compileIndex); } +GPRReg SpeculativeJIT::temporaryRegisterForPutByVal(GPRTemporary& temporary, Array::Mode arrayMode) +{ + if (!putByValWillNeedExtraRegister(arrayMode)) + return InvalidGPRReg; + + GPRTemporary realTemporary(this); + temporary.adopt(realTemporary); + return temporary.gpr(); +} + } } // namespace JSC::DFG #endif diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h index 15314b2f2..90b6d483a 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h @@ -42,6 +42,7 @@ namespace JSC { namespace DFG { +class GPRTemporary; class JSValueOperand; class SlowPathGenerator; class SpeculativeJIT; @@ -325,7 +326,7 @@ public: // These methods are used when generating 'unexpected' // calls out from JIT code to C++ helper routines - // they spill all live values to the appropriate - // slots in the RegisterFile without changing any state + // slots in the JSStack without changing any state // in the GenerationInfo. SilentRegisterSavePlan silentSavePlanForGPR(VirtualRegister spillMe, GPRReg source) { @@ -704,7 +705,7 @@ public: } #endif - // Spill a VirtualRegister to the RegisterFile. + // Spill a VirtualRegister to the JSStack. void spill(VirtualRegister spillMe) { GenerationInfo& info = m_generationInfo[spillMe]; @@ -714,7 +715,7 @@ public: return; #endif // Check the GenerationInfo to see if this value need writing - // to the RegisterFile - if not, mark it as spilled & return. + // to the JSStack - if not, mark it as spilled & return. if (!info.needsSpill()) { info.setSpilled(*m_stream, spillMe); return; @@ -829,7 +830,7 @@ public: return &m_jit.codeBlock()->identifier(index); } - // Spill all VirtualRegisters back to the RegisterFile. + // Spill all VirtualRegisters back to the JSStack. void flushRegisters() { for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) { @@ -1166,6 +1167,11 @@ public: m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size)); return appendCallWithExceptionCheckSetResult(operation, result); } + JITCompiler::Call callOperation(P_DFGOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size) + { + m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size)); + return appendCallWithExceptionCheckSetResult(operation, result); + } JITCompiler::Call callOperation(P_DFGOperation_EPS operation, GPRReg result, GPRReg old, size_t size) { m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size)); @@ -1213,21 +1219,36 @@ public: m_jit.setupArgumentsWithExecState(arg1, arg2); return appendCallWithExceptionCheckSetResult(operation, result); } - JITCompiler::Call callOperation(J_DFGOperation_ESt operation, GPRReg result, Structure* structure) + JITCompiler::Call callOperation(P_DFGOperation_ESt operation, GPRReg result, Structure* structure) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure)); return appendCallWithExceptionCheckSetResult(operation, result); } - JITCompiler::Call callOperation(J_DFGOperation_EStI operation, GPRReg result, Structure* structure, GPRReg arg2) + JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2); return appendCallWithExceptionCheckSetResult(operation, result); } - JITCompiler::Call callOperation(J_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size) + JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2)); + return appendCallWithExceptionCheckSetResult(operation, result); + } + JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallWithExceptionCheckSetResult(operation, result); + } + JITCompiler::Call callOperation(P_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size)); return appendCallWithExceptionCheckSetResult(operation, result); } + JITCompiler::Call callOperation(P_DFGOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size)); + return appendCallWithExceptionCheckSetResult(operation, result); + } JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg result, void* pointer, size_t size) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size)); @@ -1468,6 +1489,11 @@ public: m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2)); return appendCallWithExceptionCheckSetResult(operation, result); } + JITCompiler::Call callOperation(P_DFGOperation_EOZ operation, GPRReg result, GPRReg arg1, int32_t arg2) + { + m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2)); + return appendCallWithExceptionCheckSetResult(operation, result); + } JITCompiler::Call callOperation(P_DFGOperation_EPS operation, GPRReg result, GPRReg old, size_t size) { m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size)); @@ -1526,20 +1552,35 @@ public: m_jit.setupArgumentsWithExecState(arg1, arg2); return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); } - JITCompiler::Call callOperation(J_DFGOperation_ESt operation, GPRReg resultTag, GPRReg resultPayload, Structure* structure) + JITCompiler::Call callOperation(P_DFGOperation_ESt operation, GPRReg result, Structure* structure) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallWithExceptionCheckSetResult(operation, result); } - JITCompiler::Call callOperation(J_DFGOperation_EStI operation, GPRReg resultTag, GPRReg resultPayload, Structure* structure, GPRReg arg2) + JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallWithExceptionCheckSetResult(operation, result); + } + JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2)); + return appendCallWithExceptionCheckSetResult(operation, result); + } + JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2) + { + m_jit.setupArgumentsWithExecState(arg1, arg2); + return appendCallWithExceptionCheckSetResult(operation, result); } - JITCompiler::Call callOperation(J_DFGOperation_EStPS operation, GPRReg resultTag, GPRReg resultPayload, Structure* structure, void* pointer, size_t size) + JITCompiler::Call callOperation(P_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size) { m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size)); - return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag); + return appendCallWithExceptionCheckSetResult(operation, result); + } + JITCompiler::Call callOperation(P_DFGOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size) + { + m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size)); + return appendCallWithExceptionCheckSetResult(operation, result); } JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size) { @@ -2149,6 +2190,48 @@ public: void compileAllocatePropertyStorage(Node&); void compileReallocatePropertyStorage(Node&); +#if USE(JSVALUE64) + MacroAssembler::JumpList compileContiguousGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultReg); + MacroAssembler::JumpList compileArrayStorageGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultReg); +#else + MacroAssembler::JumpList compileContiguousGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultTagReg, GPRReg resultPayloadReg); + MacroAssembler::JumpList compileArrayStorageGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultTagReg, GPRReg resultPayloadReg); +#endif + + bool putByValWillNeedExtraRegister(Array::Mode arrayMode) + { + switch (arrayMode) { + // For ArrayStorage, we need an extra reg for stores to holes except if + // we're in SlowPut mode. + case ARRAY_STORAGE_TO_HOLE_MODES: + case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES: + case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: + return true; + + // For Contiguous, we need an extra reg for any access that may store + // to the tail. + case CONTIGUOUS_TO_TAIL_MODES: + case OUT_OF_BOUNDS_CONTIGUOUS_MODES: + case ALL_EFFECTFUL_CONTIGUOUS_MODES: + return true; + + default: + return false; + } + } + GPRReg temporaryRegisterForPutByVal(GPRTemporary&, Array::Mode); + GPRReg temporaryRegisterForPutByVal(GPRTemporary& temporary, Node& node) + { + return temporaryRegisterForPutByVal(temporary, node.arrayMode()); + } +#if USE(JSVALUE64) + MacroAssembler::JumpList compileContiguousPutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueReg, GPRReg tempReg); + MacroAssembler::JumpList compileArrayStoragePutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueReg, GPRReg tempReg); +#else + MacroAssembler::JumpList compileContiguousPutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueTagReg, GPRReg valuePayloadReg); + MacroAssembler::JumpList compileArrayStoragePutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueTagReg, GPRReg valuePayloadReg); +#endif + void compileGetCharCodeAt(Node&); void compileGetByValOnString(Node&); @@ -2170,14 +2253,6 @@ public: #endif void compileArithMod(Node&); void compileSoftModulo(Node&); - enum TypedArraySignedness { - SignedTypedArray, - UnsignedTypedArray - }; - enum TypedArrayRounding { - TruncateRounding, - ClampRounding - }; void compileGetIndexedPropertyStorage(Node&); void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySignedness); void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySignedness, TypedArrayRounding = TruncateRounding); @@ -2186,17 +2261,43 @@ public: void compileNewFunctionNoCheck(Node&); void compileNewFunctionExpression(Node&); bool compileRegExpExec(Node&); - + + // size can be an immediate or a register, and must be in bytes. If size is a register, + // it must be a different register than resultGPR. Emits code that place a pointer to + // the end of the allocation. The returned jump is the jump to the slow path. + template<typename SizeType> + MacroAssembler::Jump emitAllocateBasicStorage(SizeType size, GPRReg resultGPR) + { + CopiedAllocator* copiedAllocator = &m_jit.globalData()->heap.storageAllocator(); + + m_jit.loadPtr(&copiedAllocator->m_currentRemaining, resultGPR); + MacroAssembler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, size, resultGPR); +#if 0 + MacroAssembler::Jump done = m_jit.jump(); + slowPath1.link(&m_jit); + m_jit.breakpoint(); + MacroAssembler::Jump slowPath = m_jit.jump(); + done.link(&m_jit); +#endif + m_jit.storePtr(resultGPR, &copiedAllocator->m_currentRemaining); + m_jit.negPtr(resultGPR); + m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), resultGPR); + + return slowPath; + } + // It is NOT okay for the structure and the scratch register to be the same thing because if they are then the Structure will // get clobbered. - template <typename ClassType, bool destructor, typename StructureType> - void emitAllocateBasicJSObject(StructureType structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath) + template <typename ClassType, MarkedBlock::DestructorType destructorType, typename StructureType, typename StorageType> + void emitAllocateBasicJSObject(StructureType structure, GPRReg resultGPR, GPRReg scratchGPR, StorageType storage, size_t size, MacroAssembler::JumpList& slowPath) { MarkedAllocator* allocator = 0; - if (destructor) - allocator = &m_jit.globalData()->heap.allocatorForObjectWithDestructor(sizeof(ClassType)); + if (destructorType == MarkedBlock::Normal) + allocator = &m_jit.globalData()->heap.allocatorForObjectWithNormalDestructor(size); + else if (destructorType == MarkedBlock::ImmortalStructure) + allocator = &m_jit.globalData()->heap.allocatorForObjectWithImmortalStructureDestructor(size); else - allocator = &m_jit.globalData()->heap.allocatorForObjectWithoutDestructor(sizeof(ClassType)); + allocator = &m_jit.globalData()->heap.allocatorForObjectWithoutDestructor(size); m_jit.loadPtr(&allocator->m_freeList.head, resultGPR); slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR)); @@ -2210,14 +2311,16 @@ public: m_jit.storePtr(structure, MacroAssembler::Address(resultGPR, JSCell::structureOffset())); // Initialize the object's property storage pointer. - m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::Address(resultGPR, JSObject::butterflyOffset())); + m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset())); } template<typename T> void emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath) { - return emitAllocateBasicJSObject<JSFinalObject, false>(structure, resultGPR, scratchGPR, slowPath); + return emitAllocateBasicJSObject<JSFinalObject, MarkedBlock::None>(structure, resultGPR, scratchGPR, TrustedImmPtr(0), JSFinalObject::allocationSize(INLINE_STORAGE_CAPACITY), slowPath); } + + void emitAllocateJSArray(Structure*, GPRReg resultGPR, GPRReg storageGPR, unsigned numElements); #if USE(JSVALUE64) JITCompiler::Jump convertToDouble(GPRReg value, FPRReg result, GPRReg tmp); @@ -2229,8 +2332,8 @@ public: void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail); void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail); // Add a set of speculation checks without additional recovery. - void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::JumpList& jumpsToFail); - void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::JumpList& jumpsToFail); + void speculationCheck(ExitKind, JSValueSource, NodeIndex, const MacroAssembler::JumpList& jumpsToFail); + void speculationCheck(ExitKind, JSValueSource, Edge, const MacroAssembler::JumpList& jumpsToFail); // Add a speculation check with additional recovery. void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&); void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&); @@ -2251,7 +2354,7 @@ public: // Note: not specifying the valueRecovery argument (leaving it as ValueRecovery()) implies // that you've ensured that there exists a MovHint prior to your use of forwardSpeculationCheck(). void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& = ValueRecovery()); - void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& = ValueRecovery()); + void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& = ValueRecovery()); void speculationCheckWithConditionalDirection(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, bool isForward); // Called when we statically determine that a speculation will fail. void terminateSpeculativeExecution(ExitKind, JSValueRegs, NodeIndex); @@ -2264,7 +2367,9 @@ public: const TypedArrayDescriptor* typedArrayDescriptor(Array::Mode); + JITCompiler::JumpList jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, Array::Mode arrayMode); void checkArray(Node&); + void arrayify(Node&, GPRReg baseReg, GPRReg propertyReg); void arrayify(Node&); template<bool strict> diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp index 70709b52f..0396f8696 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. * Copyright (C) 2011 Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,6 +29,7 @@ #if ENABLE(DFG_JIT) +#include "DFGCallArrayAllocatorSlowPathGenerator.h" #include "DFGSlowPathGenerator.h" #include "JSActivation.h" @@ -1015,10 +1016,10 @@ void SpeculativeJIT::emitCall(Node& node) // receiver (method call). subsequent children are the arguments. int numPassedArgs = node.numChildren() - 1; - m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs + dummyThisArgument), callFramePayloadSlot(RegisterFile::ArgumentCount)); - m_jit.storePtr(GPRInfo::callFrameRegister, callFramePayloadSlot(RegisterFile::CallerFrame)); - m_jit.store32(calleePayloadGPR, callFramePayloadSlot(RegisterFile::Callee)); - m_jit.store32(calleeTagGPR, callFrameTagSlot(RegisterFile::Callee)); + m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs + dummyThisArgument), callFramePayloadSlot(JSStack::ArgumentCount)); + m_jit.storePtr(GPRInfo::callFrameRegister, callFramePayloadSlot(JSStack::CallerFrame)); + m_jit.store32(calleePayloadGPR, callFramePayloadSlot(JSStack::Callee)); + m_jit.store32(calleeTagGPR, callFrameTagSlot(JSStack::Callee)); for (int i = 0; i < numPassedArgs; i++) { Edge argEdge = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + i]; @@ -1049,8 +1050,8 @@ void SpeculativeJIT::emitCall(Node& node) slowPath.append(m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleePayloadGPR, targetToCheck)); slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, calleeTagGPR, TrustedImm32(JSValue::CellTag))); m_jit.loadPtr(MacroAssembler::Address(calleePayloadGPR, OBJECT_OFFSETOF(JSFunction, m_scope)), resultPayloadGPR); - m_jit.storePtr(resultPayloadGPR, MacroAssembler::Address(GPRInfo::callFrameRegister, static_cast<ptrdiff_t>(sizeof(Register)) * RegisterFile::ScopeChain + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); - m_jit.store32(MacroAssembler::TrustedImm32(JSValue::CellTag), MacroAssembler::Address(GPRInfo::callFrameRegister, static_cast<ptrdiff_t>(sizeof(Register)) * RegisterFile::ScopeChain + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); + m_jit.storePtr(resultPayloadGPR, MacroAssembler::Address(GPRInfo::callFrameRegister, static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ScopeChain + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); + m_jit.store32(MacroAssembler::TrustedImm32(JSValue::CellTag), MacroAssembler::Address(GPRInfo::callFrameRegister, static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ScopeChain + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); CodeOrigin codeOrigin = at(m_compileIndex).codeOrigin; JITCompiler::Call fastCall = m_jit.nearCall(); @@ -2045,6 +2046,113 @@ void SpeculativeJIT::emitBranch(Node& node) } } +MacroAssembler::JumpList SpeculativeJIT::compileContiguousGetByVal(Node&, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultTagReg, GPRReg resultPayloadReg) +{ + MacroAssembler::JumpList slowCases; + slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); + + m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagReg); + m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadReg); + slowCases.append(m_jit.branch32(MacroAssembler::Equal, resultTagReg, TrustedImm32(JSValue::EmptyValueTag))); + + return slowCases; +} + +MacroAssembler::JumpList SpeculativeJIT::compileArrayStorageGetByVal(Node&, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultTagReg, GPRReg resultPayloadReg) +{ + MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())); + + m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagReg); + m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadReg); + MacroAssembler::Jump hole = m_jit.branch32(MacroAssembler::Equal, resultTagReg, TrustedImm32(JSValue::EmptyValueTag)); + + MacroAssembler::JumpList slowCases; + slowCases.append(outOfBounds); + slowCases.append(hole); + return slowCases; +} + +MacroAssembler::JumpList SpeculativeJIT::compileContiguousPutByVal(Node& node, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueTagReg, GPRReg valuePayloadReg) +{ + Array::Mode arrayMode = node.arrayMode(); + + MacroAssembler::JumpList slowCases; + + if (!mayStoreToTail(arrayMode)) { + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); + } else { + MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())); + + slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()))); + + if (isInBoundsAccess(arrayMode)) + speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases); + + m_jit.add32(TrustedImm32(1), propertyReg); + m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())); + m_jit.sub32(TrustedImm32(1), propertyReg); + + inBounds.link(&m_jit); + } + + m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + + if (isInBoundsAccess(arrayMode)) + return MacroAssembler::JumpList(); + return slowCases; +} + +MacroAssembler::JumpList SpeculativeJIT::compileArrayStoragePutByVal(Node& node, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueTagReg, GPRReg valuePayloadReg) +{ + Array::Mode arrayMode = node.arrayMode(); + + MacroAssembler::JumpList slowCases; + + MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())); + if (isInBoundsAccess(arrayMode)) + speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds); + else + slowCases.append(beyondArrayBounds); + + // Check if we're writing to a hole; if so increment m_numValuesInVector. + if (!mayStoreToHole(arrayMode)) { + // This is uncountable because if we take this exit, then the baseline JIT + // will immediately count the hole store. So there is no need for exit + // profiling. + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + m_jit.branch32(MacroAssembler::Equal, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag))); + } else { + MacroAssembler::Jump notHoleValue = m_jit.branch32(MacroAssembler::NotEqual, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag)); + if (isSlowPutAccess(arrayMode)) { + // This is sort of strange. If we wanted to optimize this code path, we would invert + // the above branch. But it's simply not worth it since this only happens if we're + // already having a bad time. + slowCases.append(m_jit.jump()); + } else { + m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, ArrayStorage::numValuesInVectorOffset())); + + // If we're writing to a hole we might be growing the array; + MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset())); + m_jit.add32(TrustedImm32(1), propertyReg); + m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset())); + m_jit.sub32(TrustedImm32(1), propertyReg); + + lengthDoesNotNeedUpdate.link(&m_jit); + } + notHoleValue.link(&m_jit); + } + + // Store the value to the array. + m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + + return slowCases; +} + void SpeculativeJIT::compile(Node& node) { NodeType op = node.op(); @@ -2161,7 +2269,7 @@ void SpeculativeJIT::compile(Node& node) // SetLocal doubles as a hint as to where a node will be stored and // as a speculation point. So before we speculate make sure that we // know where the child of this node needs to go in the virtual - // register file. + // stack. compileMovHint(node); // As far as OSR is concerned, we're on the bytecode index corresponding @@ -2190,7 +2298,7 @@ void SpeculativeJIT::compile(Node& node) // this SetLocal should not have executed. But for op_post_inc, it's just // fine, because this SetLocal's local (i.e. the LHS in a x = y++ // statement) would be dead anyway - so the fact that DFG would have - // already made the assignment, and baked it into the register file during + // already made the assignment, and baked it into the stack during // OSR exit, would not be visible to the old JIT in any way. m_codeOriginForOSR = nextNode->codeOrigin; @@ -2200,9 +2308,9 @@ void SpeculativeJIT::compile(Node& node) m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local())); noResult(m_compileIndex); // Indicate that it's no longer necessary to retrieve the value of - // this bytecode variable from registers or other locations in the register file, + // this bytecode variable from registers or other locations in the stack, // but that it is stored as a double. - recordSetLocal(node.local(), ValueSource(DoubleInRegisterFile)); + recordSetLocal(node.local(), ValueSource(DoubleInJSStack)); break; } SpeculatedType predictedType = node.variableAccessData()->argumentAwarePrediction(); @@ -2210,14 +2318,14 @@ void SpeculativeJIT::compile(Node& node) DoubleOperand value(this, node.child1()); m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local())); noResult(m_compileIndex); - recordSetLocal(node.local(), ValueSource(DoubleInRegisterFile)); + recordSetLocal(node.local(), ValueSource(DoubleInJSStack)); break; } if (isInt32Speculation(predictedType)) { SpeculateIntegerOperand value(this, node.child1()); m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local())); noResult(m_compileIndex); - recordSetLocal(node.local(), ValueSource(Int32InRegisterFile)); + recordSetLocal(node.local(), ValueSource(Int32InJSStack)); break; } if (isCellSpeculation(predictedType)) { @@ -2225,14 +2333,14 @@ void SpeculativeJIT::compile(Node& node) GPRReg cellGPR = cell.gpr(); m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local())); noResult(m_compileIndex); - recordSetLocal(node.local(), ValueSource(CellInRegisterFile)); + recordSetLocal(node.local(), ValueSource(CellInJSStack)); break; } if (isBooleanSpeculation(predictedType)) { SpeculateBooleanOperand value(this, node.child1()); m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local())); noResult(m_compileIndex); - recordSetLocal(node.local(), ValueSource(BooleanInRegisterFile)); + recordSetLocal(node.local(), ValueSource(BooleanInJSStack)); break; } } @@ -2240,7 +2348,7 @@ void SpeculativeJIT::compile(Node& node) m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node.local())); m_jit.store32(value.tagGPR(), JITCompiler::tagFor(node.local())); noResult(m_compileIndex); - recordSetLocal(node.local(), ValueSource(ValueInRegisterFile)); + recordSetLocal(node.local(), ValueSource(ValueInJSStack)); // If we're storing an arguments object that has been optimized away, // our variable event stream for OSR exit now reflects the optimized @@ -2565,6 +2673,55 @@ void SpeculativeJIT::compile(Node& node) jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex); break; } + case IN_BOUNDS_CONTIGUOUS_MODES: { + SpeculateStrictInt32Operand property(this, node.child2()); + StorageOperand storage(this, node.child3()); + + GPRReg propertyReg = property.gpr(); + GPRReg storageReg = storage.gpr(); + + if (!m_compileOkay) + return; + + speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); + + GPRTemporary resultTag(this); + GPRTemporary resultPayload(this); + m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr()); + speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag))); + m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr()); + jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex); + break; + } + case CONTIGUOUS_TO_TAIL_MODES: + case OUT_OF_BOUNDS_CONTIGUOUS_MODES: + case ALL_EFFECTFUL_CONTIGUOUS_MODES: { + SpeculateCellOperand base(this, node.child1()); + SpeculateStrictInt32Operand property(this, node.child2()); + StorageOperand storage(this, node.child3()); + + GPRReg baseReg = base.gpr(); + GPRReg propertyReg = property.gpr(); + GPRReg storageReg = storage.gpr(); + + if (!m_compileOkay) + return; + + GPRTemporary resultTag(this); + GPRTemporary resultPayload(this); + GPRReg resultTagReg = resultTag.gpr(); + GPRReg resultPayloadReg = resultPayload.gpr(); + + MacroAssembler::JumpList slowCases = + compileContiguousGetByVal(node, baseReg, propertyReg, storageReg, resultTagReg, resultPayloadReg); + addSlowPathGenerator( + slowPathCall( + slowCases, this, operationGetByValArrayInt, + JSValueRegs(resultTagReg, resultPayloadReg), baseReg, propertyReg)); + + jsValueResult(resultTagReg, resultPayloadReg, m_compileIndex); + break; + } case IN_BOUNDS_ARRAY_STORAGE_MODES: { SpeculateStrictInt32Operand property(this, node.child2()); StorageOperand storage(this, node.child3()); @@ -2587,6 +2744,7 @@ void SpeculativeJIT::compile(Node& node) break; } case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES: + case SLOW_PUT_ARRAY_STORAGE_MODES: case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: { SpeculateCellOperand base(this, node.child1()); SpeculateStrictInt32Operand property(this, node.child2()); @@ -2714,6 +2872,55 @@ void SpeculativeJIT::compile(Node& node) GPRReg propertyReg = property.gpr(); switch (arrayMode) { + case ALL_CONTIGUOUS_MODES: + case ALL_EFFECTFUL_CONTIGUOUS_MODES: { + JSValueOperand value(this, child3); + + GPRReg valueTagReg = value.tagGPR(); + GPRReg valuePayloadReg = value.payloadGPR(); + + if (!m_compileOkay) + return; + + if (Heap::isWriteBarrierEnabled()) { + GPRTemporary scratch(this); + writeBarrier(baseReg, valueTagReg, child3, WriteBarrierForPropertyAccess, scratch.gpr()); + } + + StorageOperand storage(this, child4); + GPRReg storageReg = storage.gpr(); + + if (node.op() == PutByValAlias) { + // Store the value to the array. + GPRReg propertyReg = property.gpr(); + m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + + noResult(m_compileIndex); + break; + } + + MacroAssembler::JumpList slowCases = + compileContiguousPutByVal( + node, baseReg, propertyReg, storageReg, valueTagReg, valuePayloadReg); + + base.use(); + property.use(); + value.use(); + storage.use(); + + if (!slowCases.empty()) { + addSlowPathGenerator( + slowPathCall( + slowCases, this, + m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict, + NoResult, baseReg, propertyReg, valueTagReg, valuePayloadReg)); + } + + noResult(m_compileIndex, UseChildrenCalledExplicitly); + break; + } + case ALL_ARRAY_STORAGE_MODES: case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: { JSValueOperand value(this, child3); @@ -2743,61 +2950,23 @@ void SpeculativeJIT::compile(Node& node) break; } - MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())); - if (isInBoundsAccess(node.arrayMode())) - speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds); - - // Check if we're writing to a hole; if so increment m_numValuesInVector. - MacroAssembler::Jump isHoleValue; - if (!mayStoreToHole(arrayMode)) { - // This is uncountable because if we take this exit, then the baseline JIT - // will immediately count the hole store. So there is no need for exit - // profiling. - speculationCheck( - Uncountable, JSValueRegs(), NoNode, - m_jit.branch32(MacroAssembler::Equal, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag))); - } else { - MacroAssembler::Jump notHoleValue = m_jit.branch32(MacroAssembler::NotEqual, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag)); - if (isSlowPutAccess(arrayMode)) { - // This is sort of strange. If we wanted to optimize this code path, we would invert - // the above branch. But it's simply not worth it since this only happens if we're - // already having a bad time. - isHoleValue = m_jit.jump(); - } else { - m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); - - // If we're writing to a hole we might be growing the array; - MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset())); - m_jit.add32(TrustedImm32(1), propertyReg); - m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset())); - m_jit.sub32(TrustedImm32(1), propertyReg); - - lengthDoesNotNeedUpdate.link(&m_jit); - } - notHoleValue.link(&m_jit); - } + MacroAssembler::JumpList slowCases = + compileArrayStoragePutByVal( + node, baseReg, propertyReg, storageReg, valueTagReg, valuePayloadReg); base.use(); property.use(); value.use(); storage.use(); - - // Store the value to the array. - m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - - if (!isInBoundsAccess(arrayMode)) { - MacroAssembler::JumpList slowCases; - slowCases.append(beyondArrayBounds); - if (isSlowPutAccess(arrayMode)) - slowCases.append(isHoleValue); + + if (!slowCases.empty()) { addSlowPathGenerator( slowPathCall( slowCases, this, m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict, NoResult, baseReg, propertyReg, valueTagReg, valuePayloadReg)); } - + noResult(m_compileIndex, UseChildrenCalledExplicitly); break; } @@ -2919,25 +3088,55 @@ void SpeculativeJIT::compile(Node& node) StorageOperand storage(this, node.child3()); GPRReg storageGPR = storage.gpr(); - - m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR); - // Refuse to handle bizarre lengths. - speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe))); + switch (node.arrayMode()) { + case Array::ArrayWithContiguous: + case Array::ArrayWithContiguousOutOfBounds: { + m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR); + MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); + m_jit.store32(valueTagGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + m_jit.add32(TrustedImm32(1), storageLengthGPR); + m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); + m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR); + + addSlowPathGenerator( + slowPathCall( + slowPath, this, operationArrayPush, + JSValueRegs(storageGPR, storageLengthGPR), + valueTagGPR, valuePayloadGPR, baseGPR)); + + jsValueResult(storageGPR, storageLengthGPR, m_compileIndex); + break; + } + + case Array::ArrayWithArrayStorage: + case Array::ArrayWithArrayStorageOutOfBounds: { + m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR); - MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())); + // Refuse to handle bizarre lengths. + speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe))); - m_jit.store32(valueTagGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())); - m_jit.add32(TrustedImm32(1), storageLengthGPR); - m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset())); - m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); - m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR); + m_jit.store32(valueTagGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); - addSlowPathGenerator(slowPathCall(slowPath, this, operationArrayPush, JSValueRegs(storageGPR, storageLengthGPR), valueTagGPR, valuePayloadGPR, baseGPR)); + m_jit.add32(TrustedImm32(1), storageLengthGPR); + m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset())); + m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR); - jsValueResult(storageGPR, storageLengthGPR, m_compileIndex); + addSlowPathGenerator(slowPathCall(slowPath, this, operationArrayPush, JSValueRegs(storageGPR, storageLengthGPR), valueTagGPR, valuePayloadGPR, baseGPR)); + + jsValueResult(storageGPR, storageLengthGPR, m_compileIndex); + break; + } + + default: + CRASH(); + break; + } break; } @@ -2948,46 +3147,88 @@ void SpeculativeJIT::compile(Node& node) StorageOperand storage(this, node.child2()); GPRTemporary valueTag(this); GPRTemporary valuePayload(this); - GPRTemporary storageLength(this); GPRReg baseGPR = base.gpr(); GPRReg valueTagGPR = valueTag.gpr(); GPRReg valuePayloadGPR = valuePayload.gpr(); GPRReg storageGPR = storage.gpr(); - GPRReg storageLengthGPR = storageLength.gpr(); - m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR); + switch (node.arrayMode()) { + case Array::ArrayWithContiguous: + case Array::ArrayWithContiguousOutOfBounds: { + m_jit.load32( + MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), valueTagGPR); + MacroAssembler::Jump undefinedCase = + m_jit.branchTest32(MacroAssembler::Zero, valueTagGPR); + m_jit.sub32(TrustedImm32(1), valueTagGPR); + m_jit.store32( + valueTagGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); + m_jit.load32( + MacroAssembler::BaseIndex(storageGPR, valueTagGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), + valuePayloadGPR); + m_jit.load32( + MacroAssembler::BaseIndex(storageGPR, valueTagGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), + valueTagGPR); + MacroAssembler::Jump slowCase = m_jit.branch32(MacroAssembler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag)); + + addSlowPathGenerator( + slowPathMove( + undefinedCase, this, + MacroAssembler::TrustedImm32(jsUndefined().tag()), valueTagGPR, + MacroAssembler::TrustedImm32(jsUndefined().payload()), valuePayloadGPR)); + addSlowPathGenerator( + slowPathCall( + slowCase, this, operationArrayPopAndRecoverLength, + JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR)); + + jsValueResult(valueTagGPR, valuePayloadGPR, m_compileIndex); + break; + } + + case Array::ArrayWithArrayStorage: + case Array::ArrayWithArrayStorageOutOfBounds: { + GPRTemporary storageLength(this); + GPRReg storageLengthGPR = storageLength.gpr(); + + m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR); - JITCompiler::JumpList setUndefinedCases; - setUndefinedCases.append(m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR)); + JITCompiler::JumpList setUndefinedCases; + setUndefinedCases.append(m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR)); - m_jit.sub32(TrustedImm32(1), storageLengthGPR); + m_jit.sub32(TrustedImm32(1), storageLengthGPR); - MacroAssembler::Jump slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())); + MacroAssembler::Jump slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())); - m_jit.load32(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), valueTagGPR); - m_jit.load32(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), valuePayloadGPR); + m_jit.load32(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), valueTagGPR); + m_jit.load32(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), valuePayloadGPR); - m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset())); + m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset())); - setUndefinedCases.append(m_jit.branch32(MacroAssembler::Equal, TrustedImm32(JSValue::EmptyValueTag), valueTagGPR)); + setUndefinedCases.append(m_jit.branch32(MacroAssembler::Equal, TrustedImm32(JSValue::EmptyValueTag), valueTagGPR)); - m_jit.store32(TrustedImm32(JSValue::EmptyValueTag), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + m_jit.store32(TrustedImm32(JSValue::EmptyValueTag), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); - m_jit.sub32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + m_jit.sub32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); - addSlowPathGenerator( - slowPathMove( - setUndefinedCases, this, - MacroAssembler::TrustedImm32(jsUndefined().tag()), valueTagGPR, - MacroAssembler::TrustedImm32(jsUndefined().payload()), valuePayloadGPR)); + addSlowPathGenerator( + slowPathMove( + setUndefinedCases, this, + MacroAssembler::TrustedImm32(jsUndefined().tag()), valueTagGPR, + MacroAssembler::TrustedImm32(jsUndefined().payload()), valuePayloadGPR)); - addSlowPathGenerator( - slowPathCall( - slowCase, this, operationArrayPop, - JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR)); + addSlowPathGenerator( + slowPathCall( + slowCase, this, operationArrayPop, + JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR)); - jsValueResult(valueTagGPR, valuePayloadGPR, m_compileIndex); + jsValueResult(valueTagGPR, valuePayloadGPR, m_compileIndex); + break; + } + + default: + CRASH(); + break; + } break; } @@ -3051,9 +3292,9 @@ void SpeculativeJIT::compile(Node& node) } // Grab the return address. - m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, GPRInfo::regT2); + m_jit.emitGetFromCallFrameHeaderPtr(JSStack::ReturnPC, GPRInfo::regT2); // Restore our caller's "r". - m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, GPRInfo::callFrameRegister); + m_jit.emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, GPRInfo::callFrameRegister); // Return. m_jit.restoreReturnAddressBeforeReturn(GPRInfo::regT2); m_jit.ret(); @@ -3163,16 +3404,48 @@ void SpeculativeJIT::compile(Node& node) case NewArray: { JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); - if (!globalObject->isHavingABadTime()) + if (!globalObject->isHavingABadTime()) { globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); + + ASSERT(hasContiguous(globalObject->arrayStructure()->indexingType())); + + unsigned numElements = node.numChildren(); + + GPRTemporary result(this); + GPRTemporary storage(this); + + GPRReg resultGPR = result.gpr(); + GPRReg storageGPR = storage.gpr(); + + emitAllocateJSArray(globalObject->arrayStructure(), resultGPR, storageGPR, numElements); + + // At this point, one way or another, resultGPR and storageGPR have pointers to + // the JSArray and the Butterfly, respectively. + + for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) { + JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]); + GPRReg opTagGPR = operand.tagGPR(); + GPRReg opPayloadGPR = operand.payloadGPR(); + m_jit.store32(opTagGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx + OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + m_jit.store32(opPayloadGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx + OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + } + + // Yuck, we should *really* have a way of also returning the storageGPR. But + // that's the least of what's wrong with this code. We really shouldn't be + // allocating the array after having computed - and probably spilled to the + // stack - all of the things that will go into the array. The solution to that + // bigger problem will also likely fix the redundancy in reloading the storage + // pointer that we currently have. + + cellResult(resultGPR, m_compileIndex); + break; + } if (!node.numChildren()) { flushRegisters(); GPRResult result(this); - GPRResult2 resultTagIgnored(this); callOperation( - operationNewEmptyArray, resultTagIgnored.gpr(), result.gpr(), - globalObject->arrayStructure()); + operationNewEmptyArray, result.gpr(), globalObject->arrayStructure()); cellResult(result.gpr(), m_compileIndex); break; } @@ -3201,11 +3474,10 @@ void SpeculativeJIT::compile(Node& node) m_jit.storePtr(TrustedImmPtr(scratchSize), scratch.gpr()); } - GPRResult resultPayload(this); - GPRResult2 resultTag(this); + GPRResult result(this); callOperation( - operationNewArray, resultTag.gpr(), resultPayload.gpr(), globalObject->arrayStructure(), + operationNewArray, result.gpr(), globalObject->arrayStructure(), static_cast<void *>(buffer), node.numChildren()); if (scratchSize) { @@ -3215,37 +3487,94 @@ void SpeculativeJIT::compile(Node& node) m_jit.storePtr(TrustedImmPtr(0), scratch.gpr()); } - // FIXME: make the callOperation above explicitly return a cell result, or jitAssert the tag is a cell tag. - cellResult(resultPayload.gpr(), m_compileIndex, UseChildrenCalledExplicitly); + cellResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly); break; } case NewArrayWithSize: { JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); - if (!globalObject->isHavingABadTime()) + if (!globalObject->isHavingABadTime()) { globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); + + SpeculateStrictInt32Operand size(this, node.child1()); + GPRTemporary result(this); + GPRTemporary storage(this); + GPRTemporary scratch(this); + + GPRReg sizeGPR = size.gpr(); + GPRReg resultGPR = result.gpr(); + GPRReg storageGPR = storage.gpr(); + GPRReg scratchGPR = scratch.gpr(); + + MacroAssembler::JumpList slowCases; + slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX))); + + ASSERT((1 << 3) == sizeof(JSValue)); + m_jit.move(sizeGPR, scratchGPR); + m_jit.lshift32(TrustedImm32(3), scratchGPR); + m_jit.add32(TrustedImm32(sizeof(IndexingHeader)), scratchGPR, resultGPR); + slowCases.append( + emitAllocateBasicStorage(resultGPR, storageGPR)); + m_jit.subPtr(scratchGPR, storageGPR); + emitAllocateBasicJSObject<JSArray, MarkedBlock::None>( + TrustedImmPtr(globalObject->arrayStructure()), resultGPR, scratchGPR, + storageGPR, sizeof(JSArray), slowCases); + + m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); + m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); + + addSlowPathGenerator(adoptPtr( + new CallArrayAllocatorWithVariableSizeSlowPathGenerator( + slowCases, this, operationNewArrayWithSize, resultGPR, + globalObject->arrayStructure(), + globalObject->arrayStructureWithArrayStorage(), + sizeGPR))); + + cellResult(resultGPR, m_compileIndex); + break; + } SpeculateStrictInt32Operand size(this, node.child1()); GPRReg sizeGPR = size.gpr(); flushRegisters(); GPRResult result(this); - GPRResult2 resultTagIgnored(this); callOperation( - operationNewArrayWithSize, resultTagIgnored.gpr(), result.gpr(), - globalObject->arrayStructure(), sizeGPR); + operationNewArrayWithSize, result.gpr(), globalObject->arrayStructure(), sizeGPR); cellResult(result.gpr(), m_compileIndex); break; } case NewArrayBuffer: { + JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); + if (!globalObject->isHavingABadTime()) { + globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); + + unsigned numElements = node.numConstants(); + + GPRTemporary result(this); + GPRTemporary storage(this); + + GPRReg resultGPR = result.gpr(); + GPRReg storageGPR = storage.gpr(); + + emitAllocateJSArray(globalObject->arrayStructure(), resultGPR, storageGPR, numElements); + + int32_t* data = bitwise_cast<int32_t*>(m_jit.codeBlock()->constantBuffer(node.startConstant())); + for (unsigned index = 0; index < node.numConstants() * 2; ++index) { + m_jit.store32( + Imm32(data[index]), MacroAssembler::Address(storageGPR, sizeof(int32_t) * index)); + } + + cellResult(resultGPR, m_compileIndex); + break; + } + flushRegisters(); - GPRResult resultPayload(this); - GPRResult2 resultTag(this); + GPRResult result(this); - callOperation(operationNewArrayBuffer, resultTag.gpr(), resultPayload.gpr(), node.startConstant(), node.numConstants()); + callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructure(), node.startConstant(), node.numConstants()); - // FIXME: make the callOperation above explicitly return a cell result, or jitAssert the tag is a cell tag. - cellResult(resultPayload.gpr(), m_compileIndex); + cellResult(result.gpr(), m_compileIndex); break; } @@ -3366,7 +3695,7 @@ void SpeculativeJIT::compile(Node& node) case GetCallee: { GPRTemporary result(this); - m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::Callee)), result.gpr()); + m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(JSStack::Callee)), result.gpr()); cellResult(result.gpr(), m_compileIndex); break; } @@ -3375,7 +3704,7 @@ void SpeculativeJIT::compile(Node& node) GPRTemporary result(this); GPRReg resultGPR = result.gpr(); - m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::ScopeChain)), resultGPR); + m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(JSStack::ScopeChain)), resultGPR); bool checkTopLevel = m_jit.codeBlock()->codeType() == FunctionCode && m_jit.codeBlock()->needsFullScopeChain(); int skip = node.scopeChainDepth(); ASSERT(skip || !checkTopLevel); @@ -4004,14 +4333,14 @@ void SpeculativeJIT::compile(Node& node) m_jit.loadPtr(JITCompiler::Address(globalObjectGPR, JSObject::butterflyOffset()), resultPayloadGPR); m_jit.load32(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), resolveInfoGPR); #if DFG_ENABLE(JIT_ASSERT) - JITCompiler::Jump isOutOfLine = m_jit.branch32(JITCompiler::GreaterThanOrEqual, resolveInfoGPR, TrustedImm32(inlineStorageCapacity)); + JITCompiler::Jump isOutOfLine = m_jit.branch32(JITCompiler::GreaterThanOrEqual, resolveInfoGPR, TrustedImm32(firstOutOfLineOffset)); m_jit.breakpoint(); isOutOfLine.link(&m_jit); #endif m_jit.neg32(resolveInfoGPR); m_jit.signExtend32ToPtr(resolveInfoGPR, resolveInfoGPR); - m_jit.load32(JITCompiler::BaseIndex(resultPayloadGPR, resolveInfoGPR, JITCompiler::TimesEight, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) + (inlineStorageCapacity - 2) * static_cast<ptrdiff_t>(sizeof(JSValue))), resultTagGPR); - m_jit.load32(JITCompiler::BaseIndex(resultPayloadGPR, resolveInfoGPR, JITCompiler::TimesEight, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) + (inlineStorageCapacity - 2) * static_cast<ptrdiff_t>(sizeof(JSValue))), resultPayloadGPR); + m_jit.load32(JITCompiler::BaseIndex(resultPayloadGPR, resolveInfoGPR, JITCompiler::TimesEight, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) + (firstOutOfLineOffset - 2) * static_cast<ptrdiff_t>(sizeof(JSValue))), resultTagGPR); + m_jit.load32(JITCompiler::BaseIndex(resultPayloadGPR, resolveInfoGPR, JITCompiler::TimesEight, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) + (firstOutOfLineOffset - 2) * static_cast<ptrdiff_t>(sizeof(JSValue))), resultPayloadGPR); addSlowPathGenerator( slowPathCall( @@ -4161,7 +4490,7 @@ void SpeculativeJIT::compile(Node& node) } ASSERT(!node.codeOrigin.inlineCallFrame); - m_jit.load32(JITCompiler::payloadFor(RegisterFile::ArgumentCount), resultGPR); + m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR); m_jit.sub32(TrustedImm32(1), resultGPR); integerResult(resultGPR, m_compileIndex); break; @@ -4183,7 +4512,7 @@ void SpeculativeJIT::compile(Node& node) Imm32(node.codeOrigin.inlineCallFrame->arguments.size() - 1), resultPayloadGPR); } else { - m_jit.load32(JITCompiler::payloadFor(RegisterFile::ArgumentCount), resultPayloadGPR); + m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultPayloadGPR); m_jit.sub32(TrustedImm32(1), resultPayloadGPR); } m_jit.move(TrustedImm32(JSValue::Int32Tag), resultTagGPR); @@ -4236,7 +4565,7 @@ void SpeculativeJIT::compile(Node& node) m_jit.branch32( JITCompiler::AboveOrEqual, resultPayloadGPR, - JITCompiler::payloadFor(RegisterFile::ArgumentCount))); + JITCompiler::payloadFor(JSStack::ArgumentCount))); } JITCompiler::JumpList slowArgument; @@ -4313,7 +4642,7 @@ void SpeculativeJIT::compile(Node& node) m_jit.branch32( JITCompiler::AboveOrEqual, resultPayloadGPR, - JITCompiler::payloadFor(RegisterFile::ArgumentCount))); + JITCompiler::payloadFor(JSStack::ArgumentCount))); } JITCompiler::JumpList slowArgument; diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp index d7cec27c1..0928dfa58 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp @@ -29,6 +29,7 @@ #if ENABLE(DFG_JIT) #include "Arguments.h" +#include "DFGCallArrayAllocatorSlowPathGenerator.h" #include "DFGSlowPathGenerator.h" namespace JSC { namespace DFG { @@ -72,7 +73,7 @@ GPRReg SpeculativeJIT::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat } // Since we statically know that we're filling an integer, and values - // in the RegisterFile are boxed, this must be DataFormatJSInteger. + // in the JSStack are boxed, this must be DataFormatJSInteger. // We will check this with a jitAssert below. info.fillJSValue(*m_stream, gpr, DataFormatJSInteger); unlock(gpr); @@ -1005,9 +1006,9 @@ void SpeculativeJIT::emitCall(Node& node) // arguments. int numPassedArgs = node.numChildren() - 1; - m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs + dummyThisArgument), callFramePayloadSlot(RegisterFile::ArgumentCount)); - m_jit.storePtr(GPRInfo::callFrameRegister, callFrameSlot(RegisterFile::CallerFrame)); - m_jit.storePtr(calleeGPR, callFrameSlot(RegisterFile::Callee)); + m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs + dummyThisArgument), callFramePayloadSlot(JSStack::ArgumentCount)); + m_jit.storePtr(GPRInfo::callFrameRegister, callFrameSlot(JSStack::CallerFrame)); + m_jit.storePtr(calleeGPR, callFrameSlot(JSStack::Callee)); for (int i = 0; i < numPassedArgs; i++) { Edge argEdge = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + i]; @@ -1033,7 +1034,7 @@ void SpeculativeJIT::emitCall(Node& node) slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue()))); m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scope)), resultGPR); - m_jit.storePtr(resultGPR, MacroAssembler::Address(GPRInfo::callFrameRegister, static_cast<ptrdiff_t>(sizeof(Register)) * RegisterFile::ScopeChain)); + m_jit.storePtr(resultGPR, MacroAssembler::Address(GPRInfo::callFrameRegister, static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ScopeChain)); CodeOrigin codeOrigin = at(m_compileIndex).codeOrigin; JITCompiler::Call fastCall = m_jit.nearCall(); @@ -2109,10 +2110,111 @@ void SpeculativeJIT::emitBranch(Node& node) } } +MacroAssembler::JumpList SpeculativeJIT::compileContiguousGetByVal(Node&, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultReg) +{ + MacroAssembler::JumpList slowCases; + slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); + + m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr), resultReg); + slowCases.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultReg)); + + return slowCases; +} + +MacroAssembler::JumpList SpeculativeJIT::compileArrayStorageGetByVal(Node&, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultReg) +{ + MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())); + + m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), resultReg); + MacroAssembler::Jump hole = m_jit.branchTestPtr(MacroAssembler::Zero, resultReg); + + MacroAssembler::JumpList slowCases; + slowCases.append(outOfBounds); + slowCases.append(hole); + return slowCases; +} + +MacroAssembler::JumpList SpeculativeJIT::compileContiguousPutByVal(Node& node, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueReg, GPRReg tempReg) +{ + Array::Mode arrayMode = node.arrayMode(); + + MacroAssembler::JumpList slowCases; + + if (!mayStoreToTail(arrayMode)) { + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); + } else { + MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())); + + slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()))); + + if (isInBoundsAccess(arrayMode)) + speculationCheck(Uncountable, JSValueRegs(), NoNode, slowCases); + + m_jit.add32(TrustedImm32(1), propertyReg, tempReg); + m_jit.store32(tempReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())); + + inBounds.link(&m_jit); + } + + m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr)); + + if (isInBoundsAccess(arrayMode)) + return MacroAssembler::JumpList(); + return slowCases; +} + +MacroAssembler::JumpList SpeculativeJIT::compileArrayStoragePutByVal(Node& node, GPRReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueReg, GPRReg tempReg) +{ + Array::Mode arrayMode = node.arrayMode(); + + MacroAssembler::JumpList slowCases; + + MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())); + if (isInBoundsAccess(arrayMode)) + speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds); + else + slowCases.append(beyondArrayBounds); + + // Check if we're writing to a hole; if so increment m_numValuesInVector. + if (!mayStoreToHole(arrayMode)) { + // This is uncountable because if we take this exit, then the baseline JIT + // will immediately count the hole store. So there is no need for exit + // profiling. + speculationCheck( + Uncountable, JSValueRegs(), NoNode, + m_jit.branchTestPtr(MacroAssembler::Zero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])))); + } else { + MacroAssembler::Jump notHoleValue = m_jit.branchTestPtr(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); + if (isSlowPutAccess(arrayMode)) { + // This is sort of strange. If we wanted to optimize this code path, we would invert + // the above branch. But it's simply not worth it since this only happens if we're + // already having a bad time. + slowCases.append(m_jit.jump()); + } else { + m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, ArrayStorage::numValuesInVectorOffset())); + + // If we're writing to a hole we might be growing the array; + MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset())); + m_jit.add32(TrustedImm32(1), propertyReg, tempReg); + m_jit.store32(tempReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset())); + + lengthDoesNotNeedUpdate.link(&m_jit); + } + notHoleValue.link(&m_jit); + } + + // Store the value to the array. + m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); + + return slowCases; +} + void SpeculativeJIT::compile(Node& node) { NodeType op = node.op(); - + switch (op) { case JSConstant: initConstantInfo(m_compileIndex); @@ -2202,7 +2304,7 @@ void SpeculativeJIT::compile(Node& node) // SetLocal doubles as a hint as to where a node will be stored and // as a speculation point. So before we speculate make sure that we // know where the child of this node needs to go in the virtual - // register file. + // stack. compileMovHint(node); // As far as OSR is concerned, we're on the bytecode index corresponding @@ -2231,7 +2333,7 @@ void SpeculativeJIT::compile(Node& node) // this SetLocal should not have executed. But for op_post_inc, it's just // fine, because this SetLocal's local (i.e. the LHS in a x = y++ // statement) would be dead anyway - so the fact that DFG would have - // already made the assignment, and baked it into the register file during + // already made the assignment, and baked it into the stack during // OSR exit, would not be visible to the old JIT in any way. m_codeOriginForOSR = nextNode->codeOrigin; @@ -2241,9 +2343,9 @@ void SpeculativeJIT::compile(Node& node) m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node.local())); noResult(m_compileIndex); // Indicate that it's no longer necessary to retrieve the value of - // this bytecode variable from registers or other locations in the register file, + // this bytecode variable from registers or other locations in the stack, // but that it is stored as a double. - recordSetLocal(node.local(), ValueSource(DoubleInRegisterFile)); + recordSetLocal(node.local(), ValueSource(DoubleInJSStack)); break; } @@ -2252,7 +2354,7 @@ void SpeculativeJIT::compile(Node& node) SpeculateIntegerOperand value(this, node.child1()); m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local())); noResult(m_compileIndex); - recordSetLocal(node.local(), ValueSource(Int32InRegisterFile)); + recordSetLocal(node.local(), ValueSource(Int32InJSStack)); break; } if (isCellSpeculation(predictedType)) { @@ -2260,14 +2362,14 @@ void SpeculativeJIT::compile(Node& node) GPRReg cellGPR = cell.gpr(); m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local())); noResult(m_compileIndex); - recordSetLocal(node.local(), ValueSource(CellInRegisterFile)); + recordSetLocal(node.local(), ValueSource(CellInJSStack)); break; } if (isBooleanSpeculation(predictedType)) { SpeculateBooleanOperand boolean(this, node.child1()); m_jit.storePtr(boolean.gpr(), JITCompiler::addressFor(node.local())); noResult(m_compileIndex); - recordSetLocal(node.local(), ValueSource(BooleanInRegisterFile)); + recordSetLocal(node.local(), ValueSource(BooleanInJSStack)); break; } } @@ -2276,7 +2378,7 @@ void SpeculativeJIT::compile(Node& node) m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local())); noResult(m_compileIndex); - recordSetLocal(node.local(), ValueSource(ValueInRegisterFile)); + recordSetLocal(node.local(), ValueSource(ValueInJSStack)); // If we're storing an arguments object that has been optimized away, // our variable event stream for OSR exit now reflects the optimized @@ -2595,6 +2697,51 @@ void SpeculativeJIT::compile(Node& node) jsValueResult(result.gpr(), m_compileIndex); break; } + case IN_BOUNDS_CONTIGUOUS_MODES: { + SpeculateStrictInt32Operand property(this, node.child2()); + StorageOperand storage(this, node.child3()); + + GPRReg propertyReg = property.gpr(); + GPRReg storageReg = storage.gpr(); + + if (!m_compileOkay) + return; + + speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()))); + + GPRTemporary result(this); + m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr), result.gpr()); + speculationCheck(OutOfBounds, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr())); + jsValueResult(result.gpr(), m_compileIndex); + break; + } + case CONTIGUOUS_TO_TAIL_MODES: + case OUT_OF_BOUNDS_CONTIGUOUS_MODES: + case ALL_EFFECTFUL_CONTIGUOUS_MODES: { + SpeculateCellOperand base(this, node.child1()); + SpeculateStrictInt32Operand property(this, node.child2()); + StorageOperand storage(this, node.child3()); + + GPRReg baseReg = base.gpr(); + GPRReg propertyReg = property.gpr(); + GPRReg storageReg = storage.gpr(); + + if (!m_compileOkay) + return; + + GPRTemporary result(this); + GPRReg resultReg = result.gpr(); + + MacroAssembler::JumpList slowCases = + compileContiguousGetByVal(node, baseReg, propertyReg, storageReg, resultReg); + addSlowPathGenerator( + slowPathCall( + slowCases, this, operationGetByValArrayInt, + result.gpr(), baseReg, propertyReg)); + + jsValueResult(resultReg, m_compileIndex); + break; + } case IN_BOUNDS_ARRAY_STORAGE_MODES: { SpeculateStrictInt32Operand property(this, node.child2()); StorageOperand storage(this, node.child3()); @@ -2615,6 +2762,7 @@ void SpeculativeJIT::compile(Node& node) break; } case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES: + case SLOW_PUT_ARRAY_STORAGE_MODES: case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: { SpeculateCellOperand base(this, node.child1()); SpeculateStrictInt32Operand property(this, node.child2()); @@ -2627,21 +2775,17 @@ void SpeculativeJIT::compile(Node& node) if (!m_compileOkay) return; - MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())); - GPRTemporary result(this); - m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.gpr()); - MacroAssembler::Jump hole = m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr()); - - MacroAssembler::JumpList slowCases; - slowCases.append(outOfBounds); - slowCases.append(hole); + GPRReg resultReg = result.gpr(); + + MacroAssembler::JumpList slowCases = + compileArrayStorageGetByVal(node, baseReg, propertyReg, storageReg, resultReg); addSlowPathGenerator( slowPathCall( slowCases, this, operationGetByValArrayInt, result.gpr(), baseReg, propertyReg)); - jsValueResult(result.gpr(), m_compileIndex); + jsValueResult(resultReg, m_compileIndex); break; } case Array::String: @@ -2735,8 +2879,8 @@ void SpeculativeJIT::compile(Node& node) GPRReg propertyReg = property.gpr(); switch (arrayMode) { - case ALL_ARRAY_STORAGE_MODES: - case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: { + case ALL_CONTIGUOUS_MODES: + case ALL_EFFECTFUL_CONTIGUOUS_MODES: { JSValueOperand value(this, child3); GPRReg valueReg = value.gpr(); @@ -2756,59 +2900,76 @@ void SpeculativeJIT::compile(Node& node) // Store the value to the array. GPRReg propertyReg = property.gpr(); GPRReg valueReg = value.gpr(); - m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); + m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr)); noResult(m_compileIndex); break; } - MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())); - if (isInBoundsAccess(arrayMode)) - speculationCheck(OutOfBounds, JSValueRegs(), NoNode, beyondArrayBounds); - - // Check if we're writing to a hole; if so increment m_numValuesInVector. - MacroAssembler::Jump isHoleValue; - if (!mayStoreToHole(arrayMode)) { - // This is uncountable because if we take this exit, then the baseline JIT - // will immediately count the hole store. So there is no need for exit - // profiling. - speculationCheck( - Uncountable, JSValueRegs(), NoNode, - m_jit.branchTestPtr(MacroAssembler::Zero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])))); - } else { - MacroAssembler::Jump notHoleValue = m_jit.branchTestPtr(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); - if (isSlowPutAccess(arrayMode)) { - // This is sort of strange. If we wanted to optimize this code path, we would invert - // the above branch. But it's simply not worth it since this only happens if we're - // already having a bad time. - isHoleValue = m_jit.jump(); - } else { - m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); - - // If we're writing to a hole we might be growing the array; - MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset())); - m_jit.add32(TrustedImm32(1), propertyReg); - m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset())); - m_jit.sub32(TrustedImm32(1), propertyReg); + GPRTemporary temporary; + GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node); + + MacroAssembler::JumpList slowCases = + compileContiguousPutByVal( + node, baseReg, propertyReg, storageReg, valueReg, temporaryReg); + + base.use(); + property.use(); + value.use(); + storage.use(); + + if (!slowCases.empty()) { + addSlowPathGenerator( + slowPathCall( + slowCases, this, + m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict, + NoResult, baseReg, propertyReg, valueReg)); + } + + noResult(m_compileIndex, UseChildrenCalledExplicitly); + break; + } + + case ALL_ARRAY_STORAGE_MODES: + case ALL_EFFECTFUL_ARRAY_STORAGE_MODES: { + JSValueOperand value(this, child3); + + GPRReg valueReg = value.gpr(); + + if (!m_compileOkay) + return; + + if (Heap::isWriteBarrierEnabled()) { + GPRTemporary scratch(this); + writeBarrier(baseReg, value.gpr(), child3, WriteBarrierForPropertyAccess, scratch.gpr()); + } + + StorageOperand storage(this, child4); + GPRReg storageReg = storage.gpr(); + + if (node.op() == PutByValAlias) { + // Store the value to the array. + GPRReg propertyReg = property.gpr(); + GPRReg valueReg = value.gpr(); + m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); - lengthDoesNotNeedUpdate.link(&m_jit); - } - notHoleValue.link(&m_jit); + noResult(m_compileIndex); + break; } + GPRTemporary temporary; + GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node); + + MacroAssembler::JumpList slowCases = + compileArrayStoragePutByVal( + node, baseReg, propertyReg, storageReg, valueReg, temporaryReg); + base.use(); property.use(); value.use(); storage.use(); - - // Store the value to the array. - m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); - - if (!isInBoundsAccess(arrayMode)) { - MacroAssembler::JumpList slowCases; - slowCases.append(beyondArrayBounds); - if (isSlowPutAccess(arrayMode)) - slowCases.append(isHoleValue); + + if (!slowCases.empty()) { addSlowPathGenerator( slowPathCall( slowCases, this, @@ -2973,26 +3134,54 @@ void SpeculativeJIT::compile(Node& node) StorageOperand storage(this, node.child3()); GPRReg storageGPR = storage.gpr(); - m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR); + switch (node.arrayMode()) { + case Array::ArrayWithContiguous: + case Array::ArrayWithContiguousOutOfBounds: { + m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR); + MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); + m_jit.storePtr(valueGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr)); + m_jit.add32(TrustedImm32(1), storageLengthGPR); + m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); + m_jit.orPtr(GPRInfo::tagTypeNumberRegister, storageLengthGPR); + + addSlowPathGenerator( + slowPathCall( + slowPath, this, operationArrayPush, NoResult, storageLengthGPR, + valueGPR, baseGPR)); - // Refuse to handle bizarre lengths. - speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe))); + jsValueResult(storageLengthGPR, m_compileIndex); + break; + } + + case Array::ArrayWithArrayStorage: + case Array::ArrayWithArrayStorageOutOfBounds: { + m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR); - MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())); + // Refuse to handle bizarre lengths. + speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe))); - m_jit.storePtr(valueGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); + MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())); - m_jit.add32(TrustedImm32(1), storageLengthGPR); - m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset())); - m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); - m_jit.orPtr(GPRInfo::tagTypeNumberRegister, storageLengthGPR); + m_jit.storePtr(valueGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); - addSlowPathGenerator( - slowPathCall( - slowPath, this, operationArrayPush, NoResult, storageLengthGPR, - valueGPR, baseGPR)); + m_jit.add32(TrustedImm32(1), storageLengthGPR); + m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset())); + m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + m_jit.orPtr(GPRInfo::tagTypeNumberRegister, storageLengthGPR); + + addSlowPathGenerator( + slowPathCall( + slowPath, this, operationArrayPush, NoResult, storageLengthGPR, + valueGPR, baseGPR)); - jsValueResult(storageLengthGPR, m_compileIndex); + jsValueResult(storageLengthGPR, m_compileIndex); + break; + } + + default: + CRASH(); + break; + } break; } @@ -3002,41 +3191,77 @@ void SpeculativeJIT::compile(Node& node) SpeculateCellOperand base(this, node.child1()); StorageOperand storage(this, node.child2()); GPRTemporary value(this); - GPRTemporary storageLength(this); GPRReg baseGPR = base.gpr(); GPRReg storageGPR = storage.gpr(); GPRReg valueGPR = value.gpr(); - GPRReg storageLengthGPR = storageLength.gpr(); - m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR); + switch (node.arrayMode()) { + case Array::ArrayWithContiguous: + case Array::ArrayWithContiguousOutOfBounds: { + m_jit.load32( + MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), valueGPR); + MacroAssembler::Jump undefinedCase = + m_jit.branchTest32(MacroAssembler::Zero, valueGPR); + m_jit.sub32(TrustedImm32(1), valueGPR); + m_jit.store32( + valueGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); + m_jit.loadPtr( + MacroAssembler::BaseIndex(storageGPR, valueGPR, MacroAssembler::ScalePtr), + valueGPR); + MacroAssembler::Jump slowCase = m_jit.branchTestPtr(MacroAssembler::Zero, valueGPR); + + addSlowPathGenerator( + slowPathMove( + undefinedCase, this, + MacroAssembler::TrustedImmPtr(JSValue::encode(jsUndefined())), valueGPR)); + addSlowPathGenerator( + slowPathCall( + slowCase, this, operationArrayPopAndRecoverLength, valueGPR, baseGPR)); + + jsValueResult(valueGPR, m_compileIndex); + break; + } + + case Array::ArrayWithArrayStorage: + case Array::ArrayWithArrayStorageOutOfBounds: { + GPRTemporary storageLength(this); + GPRReg storageLengthGPR = storageLength.gpr(); + m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR); - JITCompiler::JumpList setUndefinedCases; - setUndefinedCases.append(m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR)); + JITCompiler::Jump undefinedCase = + m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR); - m_jit.sub32(TrustedImm32(1), storageLengthGPR); + m_jit.sub32(TrustedImm32(1), storageLengthGPR); - MacroAssembler::Jump slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())); + JITCompiler::JumpList slowCases; + slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()))); - m_jit.loadPtr(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), valueGPR); + m_jit.loadPtr(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), valueGPR); + slowCases.append(m_jit.branchTestPtr(MacroAssembler::Zero, valueGPR)); - m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset())); - - setUndefinedCases.append(m_jit.branchTestPtr(MacroAssembler::Zero, valueGPR)); + m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset())); - m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); - m_jit.sub32(MacroAssembler::TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); + m_jit.sub32(MacroAssembler::TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); - addSlowPathGenerator( - slowPathMove( - setUndefinedCases, this, - MacroAssembler::TrustedImmPtr(JSValue::encode(jsUndefined())), valueGPR)); + addSlowPathGenerator( + slowPathMove( + undefinedCase, this, + MacroAssembler::TrustedImmPtr(JSValue::encode(jsUndefined())), valueGPR)); - addSlowPathGenerator( - slowPathCall( - slowCase, this, operationArrayPop, valueGPR, baseGPR)); + addSlowPathGenerator( + slowPathCall( + slowCases, this, operationArrayPop, valueGPR, baseGPR)); - jsValueResult(valueGPR, m_compileIndex); + jsValueResult(valueGPR, m_compileIndex); + break; + } + + default: + CRASH(); + break; + } break; } @@ -3087,9 +3312,9 @@ void SpeculativeJIT::compile(Node& node) m_jit.move(op1.gpr(), GPRInfo::returnValueGPR); // Grab the return address. - m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, GPRInfo::regT1); + m_jit.emitGetFromCallFrameHeaderPtr(JSStack::ReturnPC, GPRInfo::regT1); // Restore our caller's "r". - m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, GPRInfo::callFrameRegister); + m_jit.emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, GPRInfo::callFrameRegister); // Return. m_jit.restoreReturnAddressBeforeReturn(GPRInfo::regT1); m_jit.ret(); @@ -3151,8 +3376,40 @@ void SpeculativeJIT::compile(Node& node) case NewArray: { JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); - if (!globalObject->isHavingABadTime()) + if (!globalObject->isHavingABadTime()) { globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); + + ASSERT(hasContiguous(globalObject->arrayStructure()->indexingType())); + + unsigned numElements = node.numChildren(); + + GPRTemporary result(this); + GPRTemporary storage(this); + + GPRReg resultGPR = result.gpr(); + GPRReg storageGPR = storage.gpr(); + + emitAllocateJSArray(globalObject->arrayStructure(), resultGPR, storageGPR, numElements); + + // At this point, one way or another, resultGPR and storageGPR have pointers to + // the JSArray and the Butterfly, respectively. + + for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) { + JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]); + GPRReg opGPR = operand.gpr(); + m_jit.storePtr(opGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx)); + } + + // Yuck, we should *really* have a way of also returning the storageGPR. But + // that's the least of what's wrong with this code. We really shouldn't be + // allocating the array after having computed - and probably spilled to the + // stack - all of the things that will go into the array. The solution to that + // bigger problem will also likely fix the redundancy in reloading the storage + // pointer that we currently have. + + cellResult(resultGPR, m_compileIndex); + break; + } if (!node.numChildren()) { flushRegisters(); @@ -3203,15 +3460,61 @@ void SpeculativeJIT::compile(Node& node) case NewArrayWithSize: { JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); - if (!globalObject->isHavingABadTime()) + if (!globalObject->isHavingABadTime()) { globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); + + SpeculateStrictInt32Operand size(this, node.child1()); + GPRTemporary result(this); + GPRTemporary storage(this); + GPRTemporary scratch(this); + + GPRReg sizeGPR = size.gpr(); + GPRReg resultGPR = result.gpr(); + GPRReg storageGPR = storage.gpr(); + GPRReg scratchGPR = scratch.gpr(); + + MacroAssembler::JumpList slowCases; + slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX))); + + ASSERT((1 << 3) == sizeof(JSValue)); + m_jit.move(sizeGPR, scratchGPR); + m_jit.lshift32(TrustedImm32(3), scratchGPR); + m_jit.add32(TrustedImm32(sizeof(IndexingHeader)), scratchGPR, resultGPR); + slowCases.append( + emitAllocateBasicStorage(resultGPR, storageGPR)); + m_jit.subPtr(scratchGPR, storageGPR); + emitAllocateBasicJSObject<JSArray, MarkedBlock::None>( + TrustedImmPtr(globalObject->arrayStructure()), resultGPR, scratchGPR, + storageGPR, sizeof(JSArray), slowCases); + + m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength())); + m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength())); + + addSlowPathGenerator(adoptPtr( + new CallArrayAllocatorWithVariableSizeSlowPathGenerator( + slowCases, this, operationNewArrayWithSize, resultGPR, + globalObject->arrayStructure(), + globalObject->arrayStructureWithArrayStorage(), + sizeGPR))); + + cellResult(resultGPR, m_compileIndex); + break; + } SpeculateStrictInt32Operand size(this, node.child1()); GPRReg sizeGPR = size.gpr(); flushRegisters(); GPRResult result(this); - callOperation(operationNewArrayWithSize, result.gpr(), globalObject->arrayStructure(), sizeGPR); - cellResult(result.gpr(), m_compileIndex); + GPRReg resultGPR = result.gpr(); + GPRReg structureGPR = selectScratchGPR(sizeGPR); + MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_SPARSE_ARRAY_INDEX)); + m_jit.move(TrustedImmPtr(globalObject->arrayStructure()), structureGPR); + MacroAssembler::Jump done = m_jit.jump(); + bigLength.link(&m_jit); + m_jit.move(TrustedImmPtr(globalObject->arrayStructureWithArrayStorage()), structureGPR); + done.link(&m_jit); + callOperation(operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR); + cellResult(resultGPR, m_compileIndex); break; } @@ -3254,10 +3557,35 @@ void SpeculativeJIT::compile(Node& node) } case NewArrayBuffer: { + JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node.codeOrigin); + if (!globalObject->isHavingABadTime()) { + globalObject->havingABadTimeWatchpoint()->add(speculationWatchpoint()); + + unsigned numElements = node.numConstants(); + + GPRTemporary result(this); + GPRTemporary storage(this); + + GPRReg resultGPR = result.gpr(); + GPRReg storageGPR = storage.gpr(); + + emitAllocateJSArray(globalObject->arrayStructure(), resultGPR, storageGPR, numElements); + + JSValue* data = m_jit.codeBlock()->constantBuffer(node.startConstant()); + for (unsigned index = 0; index < node.numConstants(); ++index) { + m_jit.storePtr( + ImmPtr(bitwise_cast<void*>(JSValue::encode(data[index]))), + MacroAssembler::Address(storageGPR, sizeof(JSValue) * index)); + } + + cellResult(resultGPR, m_compileIndex); + break; + } + flushRegisters(); GPRResult result(this); - callOperation(operationNewArrayBuffer, result.gpr(), node.startConstant(), node.numConstants()); + callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructure(), node.startConstant(), node.numConstants()); cellResult(result.gpr(), m_compileIndex); break; @@ -3375,7 +3703,7 @@ void SpeculativeJIT::compile(Node& node) case GetCallee: { GPRTemporary result(this); - m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::Callee)), result.gpr()); + m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(JSStack::Callee)), result.gpr()); cellResult(result.gpr(), m_compileIndex); break; } @@ -3384,7 +3712,7 @@ void SpeculativeJIT::compile(Node& node) GPRTemporary result(this); GPRReg resultGPR = result.gpr(); - m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::ScopeChain)), resultGPR); + m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(JSStack::ScopeChain)), resultGPR); bool checkTopLevel = m_jit.codeBlock()->codeType() == FunctionCode && m_jit.codeBlock()->needsFullScopeChain(); int skip = node.scopeChainDepth(); ASSERT(skip || !checkTopLevel); @@ -3973,14 +4301,14 @@ void SpeculativeJIT::compile(Node& node) // Fast case m_jit.load32(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), resolveInfoGPR); #if DFG_ENABLE(JIT_ASSERT) - JITCompiler::Jump isOutOfLine = m_jit.branch32(JITCompiler::GreaterThanOrEqual, resolveInfoGPR, TrustedImm32(inlineStorageCapacity)); + JITCompiler::Jump isOutOfLine = m_jit.branch32(JITCompiler::GreaterThanOrEqual, resolveInfoGPR, TrustedImm32(firstOutOfLineOffset)); m_jit.breakpoint(); isOutOfLine.link(&m_jit); #endif m_jit.neg32(resolveInfoGPR); m_jit.signExtend32ToPtr(resolveInfoGPR, resolveInfoGPR); m_jit.loadPtr(JITCompiler::Address(globalObjectGPR, JSObject::butterflyOffset()), resultGPR); - m_jit.loadPtr(JITCompiler::BaseIndex(resultGPR, resolveInfoGPR, JITCompiler::ScalePtr, (inlineStorageCapacity - 2) * static_cast<ptrdiff_t>(sizeof(JSValue))), resultGPR); + m_jit.loadPtr(JITCompiler::BaseIndex(resultGPR, resolveInfoGPR, JITCompiler::ScalePtr, (firstOutOfLineOffset - 2) * static_cast<ptrdiff_t>(sizeof(JSValue))), resultGPR); addSlowPathGenerator( slowPathCall( @@ -4106,7 +4434,7 @@ void SpeculativeJIT::compile(Node& node) } ASSERT(!node.codeOrigin.inlineCallFrame); - m_jit.load32(JITCompiler::payloadFor(RegisterFile::ArgumentCount), resultGPR); + m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR); m_jit.sub32(TrustedImm32(1), resultGPR); integerResult(resultGPR, m_compileIndex); break; @@ -4129,7 +4457,7 @@ void SpeculativeJIT::compile(Node& node) jsNumber(node.codeOrigin.inlineCallFrame->arguments.size() - 1)))), resultGPR); } else { - m_jit.load32(JITCompiler::payloadFor(RegisterFile::ArgumentCount), resultGPR); + m_jit.load32(JITCompiler::payloadFor(JSStack::ArgumentCount), resultGPR); m_jit.sub32(TrustedImm32(1), resultGPR); m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR); } @@ -4178,7 +4506,7 @@ void SpeculativeJIT::compile(Node& node) m_jit.branch32( JITCompiler::AboveOrEqual, resultGPR, - JITCompiler::payloadFor(RegisterFile::ArgumentCount))); + JITCompiler::payloadFor(JSStack::ArgumentCount))); } JITCompiler::JumpList slowArgument; @@ -4243,7 +4571,7 @@ void SpeculativeJIT::compile(Node& node) m_jit.branch32( JITCompiler::AboveOrEqual, resultGPR, - JITCompiler::payloadFor(RegisterFile::ArgumentCount))); + JITCompiler::payloadFor(JSStack::ArgumentCount))); } JITCompiler::JumpList slowArgument; diff --git a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp index 5b0b22963..2e44af2d7 100644 --- a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp @@ -122,14 +122,20 @@ public: if (!subNode.shouldGenerate()) continue; switch (subNode.op()) { - case CheckStructure: - case StructureTransitionWatchpoint: { + case CheckStructure: { if (subNode.child1().index() != source) break; noticeStructureCheck(variable, subNode.structureSet()); break; } + case StructureTransitionWatchpoint: { + if (subNode.child1().index() != source) + break; + + noticeStructureCheck(variable, subNode.structure()); + break; + } default: break; } @@ -162,7 +168,7 @@ public: dataLog("Zeroing the structure to hoist for %s because the ratio is %lf.\n", m_graph.nameOfVariableAccessData(variable), variable->voteRatio()); #endif - iter->second.m_structure = 0; + iter->value.m_structure = 0; } // Disable structure check hoisting for variables that cross the OSR entry that @@ -187,7 +193,7 @@ public: HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable); if (iter == m_map.end()) continue; - if (!iter->second.m_structure) + if (!iter->value.m_structure) continue; JSValue value = m_graph.m_mustHandleValues[i]; if (!value || !value.isCell()) { @@ -195,162 +201,34 @@ public: dataLog("Zeroing the structure to hoist for %s because the OSR entry value is not a cell: %s.\n", m_graph.nameOfVariableAccessData(variable), value.description()); #endif - iter->second.m_structure = 0; + iter->value.m_structure = 0; continue; } - if (value.asCell()->structure() != iter->second.m_structure) { + if (value.asCell()->structure() != iter->value.m_structure) { #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) dataLog("Zeroing the structure to hoist for %s because the OSR entry value has structure %p and we wanted %p.\n", - m_graph.nameOfVariableAccessData(variable), value.asCell()->structure(), iter->second.m_structure); + m_graph.nameOfVariableAccessData(variable), value.asCell()->structure(), iter->value.m_structure); #endif - iter->second.m_structure = 0; + iter->value.m_structure = 0; continue; } } } - // Identify the set of variables that are live across a structure clobber. - - Operands<VariableAccessData*> live( - m_graph.m_blocks[0]->variablesAtTail.numberOfArguments(), - m_graph.m_blocks[0]->variablesAtTail.numberOfLocals()); - for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) { - BasicBlock* block = m_graph.m_blocks[blockIndex].get(); - if (!block) - continue; - ASSERT(live.numberOfArguments() == block->variablesAtTail.numberOfArguments()); - ASSERT(live.numberOfLocals() == block->variablesAtTail.numberOfLocals()); - for (unsigned i = live.size(); i--;) { - NodeIndex indexAtTail = block->variablesAtTail[i]; - VariableAccessData* variable; - if (indexAtTail == NoNode) - variable = 0; - else - variable = m_graph[indexAtTail].variableAccessData(); - live[i] = variable; - } - for (unsigned indexInBlock = block->size(); indexInBlock--;) { - NodeIndex nodeIndex = block->at(indexInBlock); - Node& node = m_graph[nodeIndex]; - if (!node.shouldGenerate()) - continue; - switch (node.op()) { - case GetLocal: - case Flush: - // This is a birth. - live.operand(node.local()) = node.variableAccessData(); - break; - - case SetLocal: - case SetArgument: - ASSERT(live.operand(node.local())); // Must be live. - ASSERT(live.operand(node.local()) == node.variableAccessData()); // Must have the variable we expected. - // This is a death. - live.operand(node.local()) = 0; - break; - - // Use the CFA's notion of what clobbers the world. - case ValueAdd: - if (m_graph.addShouldSpeculateInteger(node)) - break; - if (Node::shouldSpeculateNumber(m_graph[node.child1()], m_graph[node.child2()])) - break; - clobber(live); - break; - - case CompareLess: - case CompareLessEq: - case CompareGreater: - case CompareGreaterEq: - case CompareEq: { - Node& left = m_graph[node.child1()]; - Node& right = m_graph[node.child2()]; - if (Node::shouldSpeculateInteger(left, right)) - break; - if (Node::shouldSpeculateNumber(left, right)) - break; - if (node.op() == CompareEq) { - if ((m_graph.isConstant(node.child1().index()) - && m_graph.valueOfJSConstant(node.child1().index()).isNull()) - || (m_graph.isConstant(node.child2().index()) - && m_graph.valueOfJSConstant(node.child2().index()).isNull())) - break; - - if (Node::shouldSpeculateFinalObject(left, right)) - break; - if (Node::shouldSpeculateArray(left, right)) - break; - if (left.shouldSpeculateFinalObject() && right.shouldSpeculateFinalObjectOrOther()) - break; - if (right.shouldSpeculateFinalObject() && left.shouldSpeculateFinalObjectOrOther()) - break; - if (left.shouldSpeculateArray() && right.shouldSpeculateArrayOrOther()) - break; - if (right.shouldSpeculateArray() && left.shouldSpeculateArrayOrOther()) - break; - } - clobber(live); - break; - } - - case GetByVal: - case PutByVal: - case PutByValAlias: - if (m_graph.byValIsPure(node)) - break; - clobber(live); - break; - - case GetMyArgumentsLengthSafe: - case GetMyArgumentByValSafe: - case GetById: - case GetByIdFlush: - case PutStructure: - case PhantomPutStructure: - case PutById: - case PutByIdDirect: - case Call: - case Construct: - case Resolve: - case ResolveBase: - case ResolveBaseStrictPut: - case ResolveGlobal: - case ArrayPush: - case ArrayPop: - case Arrayify: - clobber(live); - break; - - default: - ASSERT(node.op() != Phi); - break; - } - } - } - bool changed = false; #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) for (HashMap<VariableAccessData*, CheckData>::iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (!it->second.m_structure) { - dataLog("Not hoisting checks for %s because of heuristics.\n", m_graph.nameOfVariableAccessData(it->first)); - continue; - } - if (it->second.m_isClobbered && !it->second.m_structure->transitionWatchpointSetIsStillValid()) { - dataLog("Not hoisting checks for %s because the structure is clobbered and has an invalid watchpoint set.\n", m_graph.nameOfVariableAccessData(it->first)); + if (!it->value.m_structure) { + dataLog("Not hoisting checks for %s because of heuristics.\n", m_graph.nameOfVariableAccessData(it->key)); continue; } - dataLog("Hoisting checks for %s\n", m_graph.nameOfVariableAccessData(it->first)); + dataLog("Hoisting checks for %s\n", m_graph.nameOfVariableAccessData(it->key)); } #endif // DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) - // Make changes: - // 1) If a variable's live range does not span a clobber, then inject structure - // checks before the SetLocal. - // 2) If a variable's live range spans a clobber but is watchpointable, then - // inject structure checks before the SetLocal and replace all other structure - // checks on that variable with structure transition watchpoints. + // Place CheckStructure's at SetLocal sites. InsertionSet<NodeIndex> insertionSet; for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) { @@ -376,9 +254,7 @@ public: HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable); if (iter == m_map.end()) break; - if (!iter->second.m_structure) - break; - if (iter->second.m_isClobbered && !iter->second.m_structure->transitionWatchpointSetIsStillValid()) + if (!iter->value.m_structure) break; node.ref(); @@ -392,7 +268,7 @@ public: m_graph.append(getLocal); insertionSet.append(indexInBlock + 1, getLocalIndex); - Node checkStructure(CheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(iter->second.m_structure)), getLocalIndex); + Node checkStructure(CheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(iter->value.m_structure)), getLocalIndex); checkStructure.ref(); NodeIndex checkStructureIndex = m_graph.size(); m_graph.append(checkStructure); @@ -412,9 +288,7 @@ public: HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(variable); if (iter == m_map.end()) break; - if (!iter->second.m_structure) - break; - if (iter->second.m_isClobbered && !iter->second.m_structure->transitionWatchpointSetIsStillValid()) + if (!iter->value.m_structure) break; // First insert a dead SetLocal to tell OSR that the child's value should @@ -431,7 +305,7 @@ public: m_graph[child1].ref(); // Use a ForwardCheckStructure to indicate that we should exit to the // next bytecode instruction rather than reexecuting the current one. - Node checkStructure(ForwardCheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(iter->second.m_structure)), child1); + Node checkStructure(ForwardCheckStructure, codeOrigin, OpInfo(m_graph.addStructureSet(iter->value.m_structure)), child1); checkStructure.ref(); NodeIndex checkStructureIndex = m_graph.size(); m_graph.append(checkStructure); @@ -440,28 +314,6 @@ public: break; } - case CheckStructure: { - Node& child = m_graph[node.child1()]; - if (child.op() != GetLocal) - break; - HashMap<VariableAccessData*, CheckData>::iterator iter = m_map.find(child.variableAccessData()); - if (iter == m_map.end()) - break; - if (!iter->second.m_structure) - break; - if (!iter->second.m_isClobbered) { - node.setOpAndDefaultFlags(Phantom); - ASSERT(node.refCount() == 1); - break; - } - if (!iter->second.m_structure->transitionWatchpointSetIsStillValid()) - break; - ASSERT(iter->second.m_structure == node.structureSet().singletonStructure()); - node.convertToStructureTransitionWatchpoint(); - changed = true; - break; - } - default: break; } @@ -476,12 +328,12 @@ private: void noticeStructureCheck(VariableAccessData* variable, Structure* structure) { HashMap<VariableAccessData*, CheckData>::AddResult result = - m_map.add(variable, CheckData(structure, false)); + m_map.add(variable, CheckData(structure)); if (result.isNewEntry) return; - if (result.iterator->second.m_structure == structure) + if (result.iterator->value.m_structure == structure) return; - result.iterator->second.m_structure = 0; + result.iterator->value.m_structure = 0; } void noticeStructureCheck(VariableAccessData* variable, const StructureSet& set) @@ -493,38 +345,16 @@ private: noticeStructureCheck(variable, set.singletonStructure()); } - void noticeClobber(VariableAccessData* variable) - { - HashMap<VariableAccessData*, CheckData>::iterator iter = - m_map.find(variable); - if (iter == m_map.end()) - return; - iter->second.m_isClobbered = true; - } - - void clobber(const Operands<VariableAccessData*>& live) - { - for (size_t i = live.size(); i--;) { - VariableAccessData* variable = live[i]; - if (!variable) - continue; - noticeClobber(variable); - } - } - struct CheckData { Structure* m_structure; - bool m_isClobbered; CheckData() : m_structure(0) - , m_isClobbered(false) { } - CheckData(Structure* structure, bool isClobbered) + CheckData(Structure* structure) : m_structure(structure) - , m_isClobbered(isClobbered) { } }; diff --git a/Source/JavaScriptCore/dfg/DFGThunks.cpp b/Source/JavaScriptCore/dfg/DFGThunks.cpp index 546aec256..25fcad10a 100644 --- a/Source/JavaScriptCore/dfg/DFGThunks.cpp +++ b/Source/JavaScriptCore/dfg/DFGThunks.cpp @@ -113,7 +113,7 @@ MacroAssemblerCodeRef throwExceptionFromCallSlowPathGenerator(JSGlobalData* glob jit.loadPtr( CCallHelpers::Address( GPRInfo::callFrameRegister, - static_cast<ptrdiff_t>(sizeof(Register)) * RegisterFile::CallerFrame), + static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::CallerFrame), GPRInfo::callFrameRegister); jit.peek(GPRInfo::nonPreservedNonReturnGPR, JITSTACKFRAME_ARGS_INDEX); jit.setupArgumentsWithExecState(GPRInfo::nonPreservedNonReturnGPR); @@ -136,7 +136,7 @@ static void slowPathFor( GPRInfo::nonArgGPR2, CCallHelpers::Address( GPRInfo::callFrameRegister, - static_cast<ptrdiff_t>(sizeof(Register)) * RegisterFile::ReturnPC)); + static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ReturnPC)); jit.storePtr(GPRInfo::callFrameRegister, &globalData->topCallFrame); jit.poke(GPRInfo::nonPreservedNonReturnGPR, JITSTACKFRAME_ARGS_INDEX); jit.setupArgumentsExecState(); @@ -151,13 +151,13 @@ static void slowPathFor( jit.loadPtr( CCallHelpers::Address( GPRInfo::callFrameRegister, - static_cast<ptrdiff_t>(sizeof(Register)) * RegisterFile::ReturnPC), + static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ReturnPC), GPRInfo::nonPreservedNonReturnGPR); jit.storePtr( CCallHelpers::TrustedImmPtr(0), CCallHelpers::Address( GPRInfo::callFrameRegister, - static_cast<ptrdiff_t>(sizeof(Register)) * RegisterFile::ReturnPC)); + static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ReturnPC)); emitPointerValidation(jit, GPRInfo::nonPreservedNonReturnGPR); jit.restoreReturnAddressBeforeReturn(GPRInfo::nonPreservedNonReturnGPR); emitPointerValidation(jit, GPRInfo::returnValueGPR); @@ -249,19 +249,19 @@ static MacroAssemblerCodeRef virtualForThunkGenerator( GPRInfo::nonArgGPR1, CCallHelpers::Address( GPRInfo::callFrameRegister, - static_cast<ptrdiff_t>(sizeof(Register)) * RegisterFile::ScopeChain)); + static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ScopeChain)); #else jit.storePtr( GPRInfo::nonArgGPR1, CCallHelpers::Address( GPRInfo::callFrameRegister, - static_cast<ptrdiff_t>(sizeof(Register)) * RegisterFile::ScopeChain + + static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ScopeChain + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); jit.store32( CCallHelpers::TrustedImm32(JSValue::CellTag), CCallHelpers::Address( GPRInfo::callFrameRegister, - static_cast<ptrdiff_t>(sizeof(Register)) * RegisterFile::ScopeChain + + static_cast<ptrdiff_t>(sizeof(Register)) * JSStack::ScopeChain + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); #endif diff --git a/Source/JavaScriptCore/dfg/DFGValueSource.cpp b/Source/JavaScriptCore/dfg/DFGValueSource.cpp index 25d43ee6b..d59e4842f 100644 --- a/Source/JavaScriptCore/dfg/DFGValueSource.cpp +++ b/Source/JavaScriptCore/dfg/DFGValueSource.cpp @@ -39,19 +39,19 @@ void ValueSource::dump(FILE* out) const case SourceIsDead: fprintf(out, "IsDead"); break; - case ValueInRegisterFile: - fprintf(out, "InRegFile"); + case ValueInJSStack: + fprintf(out, "InStack"); break; - case Int32InRegisterFile: + case Int32InJSStack: fprintf(out, "Int32"); break; - case CellInRegisterFile: + case CellInJSStack: fprintf(out, "Cell"); break; - case BooleanInRegisterFile: + case BooleanInJSStack: fprintf(out, "Bool"); break; - case DoubleInRegisterFile: + case DoubleInJSStack: fprintf(out, "Double"); break; case ArgumentsSource: diff --git a/Source/JavaScriptCore/dfg/DFGValueSource.h b/Source/JavaScriptCore/dfg/DFGValueSource.h index f776137d0..8a4c66b37 100644 --- a/Source/JavaScriptCore/dfg/DFGValueSource.h +++ b/Source/JavaScriptCore/dfg/DFGValueSource.h @@ -39,11 +39,11 @@ namespace JSC { namespace DFG { enum ValueSourceKind { SourceNotSet, - ValueInRegisterFile, - Int32InRegisterFile, - CellInRegisterFile, - BooleanInRegisterFile, - DoubleInRegisterFile, + ValueInJSStack, + Int32InJSStack, + CellInJSStack, + BooleanInJSStack, + DoubleInJSStack, ArgumentsSource, SourceIsDead, HaveNode @@ -53,35 +53,35 @@ static inline ValueSourceKind dataFormatToValueSourceKind(DataFormat dataFormat) { switch (dataFormat) { case DataFormatInteger: - return Int32InRegisterFile; + return Int32InJSStack; case DataFormatDouble: - return DoubleInRegisterFile; + return DoubleInJSStack; case DataFormatBoolean: - return BooleanInRegisterFile; + return BooleanInJSStack; case DataFormatCell: - return CellInRegisterFile; + return CellInJSStack; case DataFormatDead: return SourceIsDead; case DataFormatArguments: return ArgumentsSource; default: ASSERT(dataFormat & DataFormatJS); - return ValueInRegisterFile; + return ValueInJSStack; } } static inline DataFormat valueSourceKindToDataFormat(ValueSourceKind kind) { switch (kind) { - case ValueInRegisterFile: + case ValueInJSStack: return DataFormatJS; - case Int32InRegisterFile: + case Int32InJSStack: return DataFormatInteger; - case CellInRegisterFile: + case CellInJSStack: return DataFormatCell; - case BooleanInRegisterFile: + case BooleanInJSStack: return DataFormatBoolean; - case DoubleInRegisterFile: + case DoubleInJSStack: return DataFormatDouble; case ArgumentsSource: return DataFormatArguments; @@ -92,7 +92,7 @@ static inline DataFormat valueSourceKindToDataFormat(ValueSourceKind kind) } } -static inline bool isInRegisterFile(ValueSourceKind kind) +static inline bool isInJSStack(ValueSourceKind kind) { DataFormat format = valueSourceKindToDataFormat(kind); return format != DataFormatNone && format < DataFormatOSRMarker; @@ -129,12 +129,12 @@ public: static ValueSource forSpeculation(SpeculatedType prediction) { if (isInt32Speculation(prediction)) - return ValueSource(Int32InRegisterFile); + return ValueSource(Int32InJSStack); if (isArraySpeculation(prediction) || isCellSpeculation(prediction)) - return ValueSource(CellInRegisterFile); + return ValueSource(CellInJSStack); if (isBooleanSpeculation(prediction)) - return ValueSource(BooleanInRegisterFile); - return ValueSource(ValueInRegisterFile); + return ValueSource(BooleanInJSStack); + return ValueSource(ValueInJSStack); } static ValueSource forDataFormat(DataFormat dataFormat) @@ -152,7 +152,7 @@ public: return kindFromNodeIndex(m_nodeIndex); } - bool isInRegisterFile() const { return JSC::DFG::isInRegisterFile(kind()); } + bool isInJSStack() const { return JSC::DFG::isInJSStack(kind()); } bool isTriviallyRecoverable() const { return JSC::DFG::isTriviallyRecoverable(kind()); } DataFormat dataFormat() const @@ -164,20 +164,20 @@ public: { ASSERT(isTriviallyRecoverable()); switch (kind()) { - case ValueInRegisterFile: - return ValueRecovery::alreadyInRegisterFile(); + case ValueInJSStack: + return ValueRecovery::alreadyInJSStack(); - case Int32InRegisterFile: - return ValueRecovery::alreadyInRegisterFileAsUnboxedInt32(); + case Int32InJSStack: + return ValueRecovery::alreadyInJSStackAsUnboxedInt32(); - case CellInRegisterFile: - return ValueRecovery::alreadyInRegisterFileAsUnboxedCell(); + case CellInJSStack: + return ValueRecovery::alreadyInJSStackAsUnboxedCell(); - case BooleanInRegisterFile: - return ValueRecovery::alreadyInRegisterFileAsUnboxedBoolean(); + case BooleanInJSStack: + return ValueRecovery::alreadyInJSStackAsUnboxedBoolean(); - case DoubleInRegisterFile: - return ValueRecovery::alreadyInRegisterFileAsUnboxedDouble(); + case DoubleInJSStack: + return ValueRecovery::alreadyInJSStackAsUnboxedDouble(); case SourceIsDead: return ValueRecovery::constant(jsUndefined()); diff --git a/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp b/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp index a1152bc2b..fa36ccdb5 100644 --- a/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp +++ b/Source/JavaScriptCore/dfg/DFGVariableEventStream.cpp @@ -93,7 +93,7 @@ void VariableEventStream::reconstruct( if (!index) { valueRecoveries = Operands<ValueRecovery>(codeBlock->numParameters(), numVariables); for (size_t i = 0; i < valueRecoveries.size(); ++i) - valueRecoveries[i] = ValueRecovery::alreadyInRegisterFile(); + valueRecoveries[i] = ValueRecovery::alreadyInJSStack(); return; } @@ -280,7 +280,7 @@ void VariableEventStream::reconstruct( } valueRecoveries[i] = - ValueRecovery::displacedInRegisterFile(static_cast<VirtualRegister>(info->u.virtualReg), info->format); + ValueRecovery::displacedInJSStack(static_cast<VirtualRegister>(info->u.virtualReg), info->format); } } diff --git a/Source/JavaScriptCore/heap/BlockAllocator.cpp b/Source/JavaScriptCore/heap/BlockAllocator.cpp index 690fd83c4..9a2e0bf60 100644 --- a/Source/JavaScriptCore/heap/BlockAllocator.cpp +++ b/Source/JavaScriptCore/heap/BlockAllocator.cpp @@ -26,51 +26,54 @@ #include "config.h" #include "BlockAllocator.h" +#include "CopiedBlock.h" +#include "MarkedBlock.h" #include <wtf/CurrentTime.h> namespace JSC { BlockAllocator::BlockAllocator() - : m_numberOfFreeBlocks(0) + : m_copiedRegionSet(CopiedBlock::blockSize) + , m_markedRegionSet(MarkedBlock::blockSize) + , m_numberOfEmptyRegions(0) , m_isCurrentlyAllocating(false) , m_blockFreeingThreadShouldQuit(false) , m_blockFreeingThread(createThread(blockFreeingThreadStartFunc, this, "JavaScriptCore::BlockFree")) { ASSERT(m_blockFreeingThread); - m_freeBlockLock.Init(); + m_regionLock.Init(); } BlockAllocator::~BlockAllocator() { - releaseFreeBlocks(); + releaseFreeRegions(); { - MutexLocker locker(m_freeBlockConditionLock); - + MutexLocker locker(m_emptyRegionConditionLock); m_blockFreeingThreadShouldQuit = true; - m_freeBlockCondition.broadcast(); + m_emptyRegionCondition.broadcast(); } waitForThreadCompletion(m_blockFreeingThread); } -void BlockAllocator::releaseFreeBlocks() +void BlockAllocator::releaseFreeRegions() { while (true) { - DeadBlock* block; + Region* region; { - SpinLockHolder locker(&m_freeBlockLock); - if (!m_numberOfFreeBlocks) - block = 0; + SpinLockHolder locker(&m_regionLock); + if (!m_numberOfEmptyRegions) + region = 0; else { - block = m_freeBlocks.removeHead(); - ASSERT(block); - m_numberOfFreeBlocks--; + region = m_emptyRegions.removeHead(); + ASSERT(region); + m_numberOfEmptyRegions--; } } - if (!block) + if (!region) break; - DeadBlock::destroy(block).deallocate(); + delete region; } } @@ -79,7 +82,7 @@ void BlockAllocator::waitForRelativeTimeWhileHoldingLock(double relative) if (m_blockFreeingThreadShouldQuit) return; - m_freeBlockCondition.timedWait(m_freeBlockConditionLock, currentTime() + relative); + m_emptyRegionCondition.timedWait(m_emptyRegionConditionLock, currentTime() + relative); } void BlockAllocator::waitForRelativeTime(double relative) @@ -88,7 +91,7 @@ void BlockAllocator::waitForRelativeTime(double relative) // frequently. It would only be a bug if this function failed to return // when it was asked to do so. - MutexLocker locker(m_freeBlockConditionLock); + MutexLocker locker(m_emptyRegionConditionLock); waitForRelativeTimeWhileHoldingLock(relative); } @@ -114,30 +117,40 @@ void BlockAllocator::blockFreeingThreadMain() // Now process the list of free blocks. Keep freeing until half of the // blocks that are currently on the list are gone. Assume that a size_t // field can be accessed atomically. - size_t currentNumberOfFreeBlocks = m_numberOfFreeBlocks; - if (!currentNumberOfFreeBlocks) + size_t currentNumberOfEmptyRegions = m_numberOfEmptyRegions; + if (!currentNumberOfEmptyRegions) continue; - size_t desiredNumberOfFreeBlocks = currentNumberOfFreeBlocks / 2; + size_t desiredNumberOfEmptyRegions = currentNumberOfEmptyRegions / 2; while (!m_blockFreeingThreadShouldQuit) { - DeadBlock* block; + Region* region; { - SpinLockHolder locker(&m_freeBlockLock); - if (m_numberOfFreeBlocks <= desiredNumberOfFreeBlocks) - block = 0; + SpinLockHolder locker(&m_regionLock); + if (m_numberOfEmptyRegions <= desiredNumberOfEmptyRegions) + region = 0; else { - block = m_freeBlocks.removeHead(); - ASSERT(block); - m_numberOfFreeBlocks--; + region = m_emptyRegions.removeHead(); + ASSERT(region); + m_numberOfEmptyRegions--; } } - if (!block) + if (!region) break; - DeadBlock::destroy(block).deallocate(); + delete region; + } + + // Sleep until there is actually work to do rather than waking up every second to check. + MutexLocker locker(m_emptyRegionConditionLock); + m_regionLock.Lock(); + while (!m_numberOfEmptyRegions && !m_blockFreeingThreadShouldQuit) { + m_regionLock.Unlock(); + m_emptyRegionCondition.wait(m_emptyRegionConditionLock); + m_regionLock.Lock(); } + m_regionLock.Unlock(); } } diff --git a/Source/JavaScriptCore/heap/BlockAllocator.h b/Source/JavaScriptCore/heap/BlockAllocator.h index 042e65d92..a41df1aab 100644 --- a/Source/JavaScriptCore/heap/BlockAllocator.h +++ b/Source/JavaScriptCore/heap/BlockAllocator.h @@ -35,25 +35,116 @@ namespace JSC { +class BlockAllocator; +class CopiedBlock; +class MarkedBlock; +class Region; + // Simple allocator to reduce VM cost by holding onto blocks of memory for // short periods of time and then freeing them on a secondary thread. class DeadBlock : public HeapBlock<DeadBlock> { public: - static DeadBlock* create(const PageAllocationAligned&); + DeadBlock(Region*); +}; + +inline DeadBlock::DeadBlock(Region* region) + : HeapBlock<DeadBlock>(region) +{ +} + +class Region : public DoublyLinkedListNode<Region> { + friend CLASS_IF_GCC DoublyLinkedListNode<Region>; + friend class BlockAllocator; +public: + ~Region(); + static Region* create(size_t blockSize); + static Region* createCustomSize(size_t blockSize, size_t blockAlignment); + Region* reset(size_t blockSize); + + size_t blockSize() const { return m_blockSize; } + bool isFull() const { return m_blocksInUse == m_totalBlocks; } + bool isEmpty() const { return !m_blocksInUse; } + + DeadBlock* allocate(); + void deallocate(void*); + + static const size_t s_regionSize = 64 * KB; private: - DeadBlock(const PageAllocationAligned&); + Region(PageAllocationAligned&, size_t blockSize, size_t totalBlocks); + + PageAllocationAligned m_allocation; + size_t m_totalBlocks; + size_t m_blocksInUse; + size_t m_blockSize; + Region* m_prev; + Region* m_next; + DoublyLinkedList<DeadBlock> m_deadBlocks; }; -inline DeadBlock::DeadBlock(const PageAllocationAligned& allocation) - : HeapBlock<DeadBlock>(allocation) +inline Region* Region::create(size_t blockSize) +{ + ASSERT(blockSize <= s_regionSize); + ASSERT(!(s_regionSize % blockSize)); + PageAllocationAligned allocation = PageAllocationAligned::allocate(s_regionSize, s_regionSize, OSAllocator::JSGCHeapPages); + if (!static_cast<bool>(allocation)) + CRASH(); + return new Region(allocation, blockSize, s_regionSize / blockSize); +} + +inline Region* Region::createCustomSize(size_t blockSize, size_t blockAlignment) { + PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockAlignment, OSAllocator::JSGCHeapPages); + if (!static_cast<bool>(allocation)) + CRASH(); + return new Region(allocation, blockSize, 1); } -inline DeadBlock* DeadBlock::create(const PageAllocationAligned& allocation) +inline Region::Region(PageAllocationAligned& allocation, size_t blockSize, size_t totalBlocks) + : DoublyLinkedListNode<Region>() + , m_allocation(allocation) + , m_totalBlocks(totalBlocks) + , m_blocksInUse(0) + , m_blockSize(blockSize) + , m_prev(0) + , m_next(0) { - return new(NotNull, allocation.base()) DeadBlock(allocation); + ASSERT(allocation); + char* start = static_cast<char*>(m_allocation.base()); + char* end = start + m_allocation.size(); + for (char* current = start; current < end; current += blockSize) + m_deadBlocks.append(new (NotNull, current) DeadBlock(this)); +} + +inline Region::~Region() +{ + ASSERT(isEmpty()); + m_allocation.deallocate(); +} + +inline Region* Region::reset(size_t blockSize) +{ + ASSERT(isEmpty()); + PageAllocationAligned allocation = m_allocation; + return new (NotNull, this) Region(allocation, blockSize, s_regionSize / blockSize); +} + +inline DeadBlock* Region::allocate() +{ + ASSERT(!isFull()); + m_blocksInUse++; + return m_deadBlocks.removeHead(); +} + +inline void Region::deallocate(void* base) +{ + ASSERT(base); + ASSERT(m_blocksInUse); + ASSERT(base >= m_allocation.base() && base < static_cast<char*>(m_allocation.base()) + m_allocation.size()); + DeadBlock* block = new (NotNull, base) DeadBlock(this); + m_deadBlocks.push(block); + m_blocksInUse--; } class BlockAllocator { @@ -61,8 +152,10 @@ public: BlockAllocator(); ~BlockAllocator(); - PageAllocationAligned allocate(); - void deallocate(PageAllocationAligned); + template <typename T> DeadBlock* allocate(); + DeadBlock* allocateCustomSize(size_t blockSize, size_t blockAlignment); + template <typename T> void deallocate(T*); + template <typename T> void deallocateCustomSize(T*); private: void waitForRelativeTimeWhileHoldingLock(double relative); @@ -71,42 +164,169 @@ private: void blockFreeingThreadMain(); static void blockFreeingThreadStartFunc(void* heap); - void releaseFreeBlocks(); + struct RegionSet { + RegionSet(size_t blockSize) + : m_numberOfPartialRegions(0) + , m_blockSize(blockSize) + { + } + DoublyLinkedList<Region> m_fullRegions; + DoublyLinkedList<Region> m_partialRegions; + size_t m_numberOfPartialRegions; + size_t m_blockSize; + }; + + DeadBlock* tryAllocateFromRegion(RegionSet&, DoublyLinkedList<Region>&, size_t&); + + void releaseFreeRegions(); + + template <typename T> RegionSet& regionSetFor(); + + RegionSet m_copiedRegionSet; + RegionSet m_markedRegionSet; + + DoublyLinkedList<Region> m_emptyRegions; + size_t m_numberOfEmptyRegions; - DoublyLinkedList<DeadBlock> m_freeBlocks; - size_t m_numberOfFreeBlocks; bool m_isCurrentlyAllocating; bool m_blockFreeingThreadShouldQuit; - SpinLock m_freeBlockLock; - Mutex m_freeBlockConditionLock; - ThreadCondition m_freeBlockCondition; + SpinLock m_regionLock; + Mutex m_emptyRegionConditionLock; + ThreadCondition m_emptyRegionCondition; ThreadIdentifier m_blockFreeingThread; }; -inline PageAllocationAligned BlockAllocator::allocate() +inline DeadBlock* BlockAllocator::tryAllocateFromRegion(RegionSet& set, DoublyLinkedList<Region>& regions, size_t& numberOfRegions) { + if (numberOfRegions) { + ASSERT(!regions.isEmpty()); + Region* region = regions.head(); + ASSERT(!region->isFull()); + + if (region->isEmpty()) { + ASSERT(region == m_emptyRegions.head()); + m_numberOfEmptyRegions--; + set.m_numberOfPartialRegions++; + region = m_emptyRegions.removeHead()->reset(set.m_blockSize); + set.m_partialRegions.push(region); + } + + DeadBlock* block = region->allocate(); + + if (region->isFull()) { + set.m_numberOfPartialRegions--; + set.m_fullRegions.push(set.m_partialRegions.removeHead()); + } + + return block; + } + return 0; +} + +template<typename T> +inline DeadBlock* BlockAllocator::allocate() +{ + RegionSet& set = regionSetFor<T>(); + DeadBlock* block; + m_isCurrentlyAllocating = true; { - SpinLockHolder locker(&m_freeBlockLock); - m_isCurrentlyAllocating = true; - if (m_numberOfFreeBlocks) { - ASSERT(!m_freeBlocks.isEmpty()); - m_numberOfFreeBlocks--; - return DeadBlock::destroy(m_freeBlocks.removeHead()); + SpinLockHolder locker(&m_regionLock); + if ((block = tryAllocateFromRegion(set, set.m_partialRegions, set.m_numberOfPartialRegions))) + return block; + if ((block = tryAllocateFromRegion(set, m_emptyRegions, m_numberOfEmptyRegions))) + return block; + } + + Region* newRegion = Region::create(T::blockSize); + + SpinLockHolder locker(&m_regionLock); + m_emptyRegions.push(newRegion); + m_numberOfEmptyRegions++; + block = tryAllocateFromRegion(set, m_emptyRegions, m_numberOfEmptyRegions); + ASSERT(block); + return block; +} + +inline DeadBlock* BlockAllocator::allocateCustomSize(size_t blockSize, size_t blockAlignment) +{ + size_t realSize = WTF::roundUpToMultipleOf(blockAlignment, blockSize); + Region* newRegion = Region::createCustomSize(realSize, blockAlignment); + DeadBlock* block = newRegion->allocate(); + ASSERT(block); + return block; +} + +template<typename T> +inline void BlockAllocator::deallocate(T* block) +{ + RegionSet& set = regionSetFor<T>(); + bool shouldWakeBlockFreeingThread = false; + { + SpinLockHolder locker(&m_regionLock); + Region* region = block->region(); + ASSERT(!region->isEmpty()); + if (region->isFull()) + set.m_fullRegions.remove(region); + else { + set.m_partialRegions.remove(region); + set.m_numberOfPartialRegions--; + } + + region->deallocate(block); + + if (region->isEmpty()) { + m_emptyRegions.push(region); + shouldWakeBlockFreeingThread = !m_numberOfEmptyRegions; + m_numberOfEmptyRegions++; + } else { + set.m_partialRegions.push(region); + set.m_numberOfPartialRegions++; } } - ASSERT(m_freeBlocks.isEmpty()); - PageAllocationAligned allocation = PageAllocationAligned::allocate(DeadBlock::s_blockSize, DeadBlock::s_blockSize, OSAllocator::JSGCHeapPages); - if (!static_cast<bool>(allocation)) - CRASH(); - return allocation; + if (shouldWakeBlockFreeingThread) { + MutexLocker mutexLocker(m_emptyRegionConditionLock); + m_emptyRegionCondition.signal(); + } +} + +template<typename T> +inline void BlockAllocator::deallocateCustomSize(T* block) +{ + Region* region = block->region(); + region->deallocate(block); + delete region; +} + +template <> +inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<CopiedBlock>() +{ + return m_copiedRegionSet; +} + +template <> +inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<MarkedBlock>() +{ + return m_markedRegionSet; +} + +template <> +inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<CopiedBlock> >() +{ + return m_copiedRegionSet; +} + +template <> +inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor<HeapBlock<MarkedBlock> >() +{ + return m_markedRegionSet; } -inline void BlockAllocator::deallocate(PageAllocationAligned allocation) +template <typename T> +inline BlockAllocator::RegionSet& BlockAllocator::regionSetFor() { - SpinLockHolder locker(&m_freeBlockLock); - m_freeBlocks.push(DeadBlock::create(allocation)); - m_numberOfFreeBlocks++; + ASSERT_NOT_REACHED(); + return *(RegionSet*)0; } } // namespace JSC diff --git a/Source/JavaScriptCore/heap/CopiedBlock.h b/Source/JavaScriptCore/heap/CopiedBlock.h index ad5dbb46b..af36f55df 100644 --- a/Source/JavaScriptCore/heap/CopiedBlock.h +++ b/Source/JavaScriptCore/heap/CopiedBlock.h @@ -26,9 +26,12 @@ #ifndef CopiedBlock_h #define CopiedBlock_h +#include "BlockAllocator.h" #include "HeapBlock.h" #include "JSValue.h" #include "JSValueInlineMethods.h" +#include "Options.h" +#include <wtf/Atomics.h> namespace JSC { @@ -38,8 +41,17 @@ class CopiedBlock : public HeapBlock<CopiedBlock> { friend class CopiedSpace; friend class CopiedAllocator; public: - static CopiedBlock* create(const PageAllocationAligned&); - static CopiedBlock* createNoZeroFill(const PageAllocationAligned&); + static CopiedBlock* create(DeadBlock*); + static CopiedBlock* createNoZeroFill(DeadBlock*); + + bool isPinned(); + + unsigned liveBytes(); + void reportLiveBytes(unsigned); + void didSurviveGC(); + bool didEvacuateBytes(unsigned); + bool shouldEvacuate(); + bool canBeRecycled(); // The payload is the region of the block that is usable for allocations. char* payload(); @@ -60,24 +72,28 @@ public: size_t size(); size_t capacity(); + static const size_t blockSize = 32 * KB; + private: - CopiedBlock(const PageAllocationAligned&); + CopiedBlock(Region*); void zeroFillWilderness(); // Can be called at any time to zero-fill to the end of the block. size_t m_remaining; uintptr_t m_isPinned; + unsigned m_liveBytes; }; -inline CopiedBlock* CopiedBlock::createNoZeroFill(const PageAllocationAligned& allocation) +inline CopiedBlock* CopiedBlock::createNoZeroFill(DeadBlock* block) { - return new(NotNull, allocation.base()) CopiedBlock(allocation); + Region* region = block->region(); + return new(NotNull, block) CopiedBlock(region); } -inline CopiedBlock* CopiedBlock::create(const PageAllocationAligned& allocation) +inline CopiedBlock* CopiedBlock::create(DeadBlock* block) { - CopiedBlock* block = createNoZeroFill(allocation); - block->zeroFillWilderness(); - return block; + CopiedBlock* newBlock = createNoZeroFill(block); + newBlock->zeroFillWilderness(); + return newBlock; } inline void CopiedBlock::zeroFillWilderness() @@ -92,14 +108,73 @@ inline void CopiedBlock::zeroFillWilderness() #endif } -inline CopiedBlock::CopiedBlock(const PageAllocationAligned& allocation) - : HeapBlock<CopiedBlock>(allocation) +inline CopiedBlock::CopiedBlock(Region* region) + : HeapBlock<CopiedBlock>(region) , m_remaining(payloadCapacity()) , m_isPinned(false) + , m_liveBytes(0) { ASSERT(is8ByteAligned(reinterpret_cast<void*>(m_remaining))); } +inline void CopiedBlock::reportLiveBytes(unsigned bytes) +{ +#if ENABLE(PARALLEL_GC) + unsigned oldValue = 0; + unsigned newValue = 0; + do { + oldValue = m_liveBytes; + newValue = oldValue + bytes; + } while (!WTF::weakCompareAndSwap(&m_liveBytes, oldValue, newValue)); +#else + m_liveBytes += bytes; +#endif +} + +inline void CopiedBlock::didSurviveGC() +{ + m_liveBytes = 0; + m_isPinned = false; +} + +inline bool CopiedBlock::didEvacuateBytes(unsigned bytes) +{ + ASSERT(m_liveBytes >= bytes); +#if ENABLE(PARALLEL_GC) + unsigned oldValue = 0; + unsigned newValue = 0; + do { + oldValue = m_liveBytes; + newValue = oldValue - bytes; + } while (!WTF::weakCompareAndSwap(&m_liveBytes, oldValue, newValue)); + ASSERT(m_liveBytes < oldValue); + return !newValue; +#else + m_liveBytes -= bytes; + return !m_liveBytes; +#endif +} + +inline bool CopiedBlock::canBeRecycled() +{ + return !m_liveBytes; +} + +inline bool CopiedBlock::shouldEvacuate() +{ + return static_cast<double>(m_liveBytes) / static_cast<double>(payloadCapacity()) <= Options::minCopiedBlockUtilization(); +} + +inline bool CopiedBlock::isPinned() +{ + return m_isPinned; +} + +inline unsigned CopiedBlock::liveBytes() +{ + return m_liveBytes; +} + inline char* CopiedBlock::payload() { return reinterpret_cast<char*>(this) + ((sizeof(CopiedBlock) + 7) & ~7); @@ -107,7 +182,7 @@ inline char* CopiedBlock::payload() inline char* CopiedBlock::payloadEnd() { - return reinterpret_cast<char*>(this) + allocation().size(); + return reinterpret_cast<char*>(this) + region()->blockSize(); } inline size_t CopiedBlock::payloadCapacity() @@ -152,7 +227,7 @@ inline size_t CopiedBlock::size() inline size_t CopiedBlock::capacity() { - return allocation().size(); + return region()->blockSize(); } } // namespace JSC diff --git a/Source/JavaScriptCore/heap/CopiedSpace.cpp b/Source/JavaScriptCore/heap/CopiedSpace.cpp index bf87a305c..cedafee3a 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.cpp +++ b/Source/JavaScriptCore/heap/CopiedSpace.cpp @@ -28,6 +28,7 @@ #include "CopiedSpaceInlineMethods.h" #include "GCActivityCallback.h" +#include "Options.h" namespace JSC { @@ -36,6 +37,7 @@ CopiedSpace::CopiedSpace(Heap* heap) , m_toSpace(0) , m_fromSpace(0) , m_inCopyingPhase(false) + , m_shouldDoCopyPhase(false) , m_numberOfLoanedBlocks(0) { m_toSpaceLock.Init(); @@ -50,7 +52,7 @@ CopiedSpace::~CopiedSpace() m_heap->blockAllocator().deallocate(CopiedBlock::destroy(m_fromSpace->removeHead())); while (!m_oversizeBlocks.isEmpty()) - CopiedBlock::destroy(m_oversizeBlocks.removeHead()).deallocate(); + m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(m_oversizeBlocks.removeHead())); } void CopiedSpace::init() @@ -79,15 +81,7 @@ CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr) { ASSERT(isOversize(bytes)); - size_t blockSize = WTF::roundUpToMultipleOf(WTF::pageSize(), sizeof(CopiedBlock) + bytes); - - PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, WTF::pageSize(), OSAllocator::JSGCHeapPages); - if (!static_cast<bool>(allocation)) { - *outPtr = 0; - return false; - } - - CopiedBlock* block = CopiedBlock::create(allocation); + CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocateCustomSize(sizeof(CopiedBlock) + bytes, WTF::pageSize())); m_oversizeBlocks.push(block); m_blockFilter.add(reinterpret_cast<Bits>(block)); m_blockSet.add(block); @@ -97,7 +91,7 @@ CheckedBoolean CopiedSpace::tryAllocateOversize(size_t bytes, void** outPtr) *outPtr = allocator.forceAllocate(bytes); allocator.resetCurrentBlock(); - m_heap->didAllocate(blockSize); + m_heap->didAllocate(block->region()->blockSize()); return true; } @@ -145,22 +139,25 @@ CheckedBoolean CopiedSpace::tryReallocateOversize(void** ptr, size_t oldSize, si CopiedBlock* oldBlock = oversizeBlockFor(oldPtr); m_oversizeBlocks.remove(oldBlock); m_blockSet.remove(oldBlock); - CopiedBlock::destroy(oldBlock).deallocate(); + m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(oldBlock)); } *ptr = newPtr; return true; } -void CopiedSpace::doneFillingBlock(CopiedBlock* block) +void CopiedSpace::doneFillingBlock(CopiedBlock* block, CopiedBlock** exchange) { ASSERT(m_inCopyingPhase); + if (exchange) + *exchange = allocateBlockForCopyingPhase(); + if (!block) return; if (!block->dataSize()) { - recycleBlock(block); + recycleBorrowedBlock(block); return; } @@ -182,6 +179,38 @@ void CopiedSpace::doneFillingBlock(CopiedBlock* block) } } +void CopiedSpace::startedCopying() +{ + std::swap(m_fromSpace, m_toSpace); + + m_blockFilter.reset(); + m_allocator.resetCurrentBlock(); + + CopiedBlock* next = 0; + size_t totalLiveBytes = 0; + size_t totalUsableBytes = 0; + for (CopiedBlock* block = m_fromSpace->head(); block; block = next) { + next = block->next(); + if (!block->isPinned() && block->canBeRecycled()) { + recycleEvacuatedBlock(block); + continue; + } + totalLiveBytes += block->liveBytes(); + totalUsableBytes += block->payloadCapacity(); + } + + double markedSpaceBytes = m_heap->objectSpace().capacity(); + double totalFragmentation = ((double)totalLiveBytes + markedSpaceBytes) / ((double)totalUsableBytes + markedSpaceBytes); + m_shouldDoCopyPhase = totalFragmentation <= Options::minHeapUtilization(); + if (!m_shouldDoCopyPhase) + return; + + ASSERT(m_shouldDoCopyPhase); + ASSERT(!m_inCopyingPhase); + ASSERT(!m_numberOfLoanedBlocks); + m_inCopyingPhase = true; +} + void CopiedSpace::doneCopying() { { @@ -190,12 +219,13 @@ void CopiedSpace::doneCopying() m_loanedBlocksCondition.wait(m_loanedBlocksLock); } - ASSERT(m_inCopyingPhase); + ASSERT(m_inCopyingPhase == m_shouldDoCopyPhase); m_inCopyingPhase = false; + while (!m_fromSpace->isEmpty()) { CopiedBlock* block = m_fromSpace->removeHead(); - if (block->m_isPinned) { - block->m_isPinned = false; + if (block->isPinned() || !m_shouldDoCopyPhase) { + block->didSurviveGC(); // We don't add the block to the blockSet because it was never removed. ASSERT(m_blockSet.contains(block)); m_blockFilter.add(reinterpret_cast<Bits>(block)); @@ -210,13 +240,13 @@ void CopiedSpace::doneCopying() CopiedBlock* curr = m_oversizeBlocks.head(); while (curr) { CopiedBlock* next = curr->next(); - if (!curr->m_isPinned) { + if (!curr->isPinned()) { m_oversizeBlocks.remove(curr); m_blockSet.remove(curr); - CopiedBlock::destroy(curr).deallocate(); + m_heap->blockAllocator().deallocateCustomSize(CopiedBlock::destroy(curr)); } else { m_blockFilter.add(reinterpret_cast<Bits>(curr)); - curr->m_isPinned = false; + curr->didSurviveGC(); } curr = next; } @@ -225,6 +255,8 @@ void CopiedSpace::doneCopying() allocateBlock(); else m_allocator.setCurrentBlock(m_toSpace->head()); + + m_shouldDoCopyPhase = false; } size_t CopiedSpace::size() diff --git a/Source/JavaScriptCore/heap/CopiedSpace.h b/Source/JavaScriptCore/heap/CopiedSpace.h index e8a4f8724..3a698e8dc 100644 --- a/Source/JavaScriptCore/heap/CopiedSpace.h +++ b/Source/JavaScriptCore/heap/CopiedSpace.h @@ -46,6 +46,7 @@ class Heap; class CopiedBlock; class CopiedSpace { + friend class CopyVisitor; friend class SlotVisitor; friend class JIT; public: @@ -74,6 +75,7 @@ public: size_t capacity(); bool isPagedOut(double deadline); + bool shouldDoCopyPhase() { return m_shouldDoCopyPhase; } static CopiedBlock* blockFor(void*); @@ -88,8 +90,9 @@ private: void allocateBlock(); CopiedBlock* allocateBlockForCopyingPhase(); - void doneFillingBlock(CopiedBlock*); - void recycleBlock(CopiedBlock*); + void doneFillingBlock(CopiedBlock*, CopiedBlock**); + void recycleEvacuatedBlock(CopiedBlock*); + void recycleBorrowedBlock(CopiedBlock*); Heap* m_heap; @@ -108,14 +111,15 @@ private: DoublyLinkedList<CopiedBlock> m_oversizeBlocks; bool m_inCopyingPhase; + bool m_shouldDoCopyPhase; Mutex m_loanedBlocksLock; ThreadCondition m_loanedBlocksCondition; size_t m_numberOfLoanedBlocks; - static const size_t s_maxAllocationSize = 32 * KB; + static const size_t s_maxAllocationSize = CopiedBlock::blockSize / 2; static const size_t s_initialBlockNum = 16; - static const size_t s_blockMask = ~(CopiedBlock::s_blockSize - 1); + static const size_t s_blockMask = ~(CopiedBlock::blockSize - 1); }; } // namespace JSC diff --git a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h index 790a302de..01e816793 100644 --- a/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h +++ b/Source/JavaScriptCore/heap/CopiedSpaceInlineMethods.h @@ -93,19 +93,20 @@ inline void CopiedSpace::pinIfNecessary(void* opaquePointer) pin(block); } -inline void CopiedSpace::startedCopying() +inline void CopiedSpace::recycleEvacuatedBlock(CopiedBlock* block) { - std::swap(m_fromSpace, m_toSpace); - - m_blockFilter.reset(); - m_allocator.resetCurrentBlock(); - - ASSERT(!m_inCopyingPhase); - ASSERT(!m_numberOfLoanedBlocks); - m_inCopyingPhase = true; + ASSERT(block); + ASSERT(block->canBeRecycled()); + ASSERT(!block->m_isPinned); + { + SpinLockHolder locker(&m_toSpaceLock); + m_blockSet.remove(block); + m_fromSpace->remove(block); + } + m_heap->blockAllocator().deallocate(CopiedBlock::destroy(block)); } -inline void CopiedSpace::recycleBlock(CopiedBlock* block) +inline void CopiedSpace::recycleBorrowedBlock(CopiedBlock* block) { m_heap->blockAllocator().deallocate(CopiedBlock::destroy(block)); @@ -121,7 +122,7 @@ inline void CopiedSpace::recycleBlock(CopiedBlock* block) inline CopiedBlock* CopiedSpace::allocateBlockForCopyingPhase() { ASSERT(m_inCopyingPhase); - CopiedBlock* block = CopiedBlock::createNoZeroFill(m_heap->blockAllocator().allocate()); + CopiedBlock* block = CopiedBlock::createNoZeroFill(m_heap->blockAllocator().allocate<CopiedBlock>()); { MutexLocker locker(m_loanedBlocksLock); @@ -139,7 +140,7 @@ inline void CopiedSpace::allocateBlock() m_allocator.resetCurrentBlock(); - CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocate()); + CopiedBlock* block = CopiedBlock::create(m_heap->blockAllocator().allocate<CopiedBlock>()); m_toSpace->push(block); m_blockFilter.add(reinterpret_cast<Bits>(block)); diff --git a/Source/JavaScriptCore/runtime/JSGlobalThis.cpp b/Source/JavaScriptCore/heap/CopyVisitor.cpp index a3f2e7785..ae826f0d2 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalThis.cpp +++ b/Source/JavaScriptCore/heap/CopyVisitor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Apple Inc. All rights reserved. + * 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 @@ -24,35 +24,34 @@ */ #include "config.h" -#include "JSGlobalThis.h" +#include "CopyVisitor.h" -#include "JSGlobalObject.h" +#include "CopyVisitorInlineMethods.h" +#include "GCThreadSharedData.h" +#include "JSCell.h" +#include "JSObject.h" +#include <wtf/Threading.h> namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSGlobalThis); -ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSGlobalThis); - -const ClassInfo JSGlobalThis::s_info = { "JSGlobalThis", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSGlobalThis) }; - -void JSGlobalThis::visitChildren(JSCell* cell, SlotVisitor& visitor) +CopyVisitor::CopyVisitor(GCThreadSharedData& shared) + : m_shared(shared) { - JSGlobalThis* thisObject = jsCast<JSGlobalThis*>(cell); - ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); - - COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); - ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); - - Base::visitChildren(thisObject, visitor); - visitor.append(&thisObject->m_unwrappedObject); } -void JSGlobalThis::setUnwrappedObject(JSGlobalData& globalData, JSGlobalObject* globalObject) +void CopyVisitor::copyFromShared() { - ASSERT_ARG(globalObject, globalObject); - m_unwrappedObject.set(globalData, this, globalObject); - setPrototype(globalData, globalObject->prototype()); - resetInheritorID(globalData); + GCCopyPhaseFunctor functor(*this); + Vector<MarkedBlock*>& blocksToCopy = m_shared.m_blocksToCopy; + size_t startIndex, endIndex; + + m_shared.getNextBlocksToCopy(startIndex, endIndex); + while (startIndex < endIndex) { + for (size_t i = startIndex; i < endIndex; i++) + blocksToCopy[i]->forEachLiveCell(functor); + m_shared.getNextBlocksToCopy(startIndex, endIndex); + } + ASSERT(startIndex == endIndex); } } // namespace JSC diff --git a/Source/JavaScriptCore/heap/CopyVisitor.h b/Source/JavaScriptCore/heap/CopyVisitor.h new file mode 100644 index 000000000..45a2e0ad9 --- /dev/null +++ b/Source/JavaScriptCore/heap/CopyVisitor.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. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CopyVisitor_h +#define CopyVisitor_h + +#include "CopiedSpace.h" + +namespace JSC { + +class GCThreadSharedData; + +class CopyVisitor { +public: + CopyVisitor(GCThreadSharedData&); + + void copyFromShared(); + + void startCopying(); + void doneCopying(); + + // Low-level API for copying, appropriate for cases where the object's heap references + // are discontiguous or if the object occurs frequently enough that you need to focus on + // performance. Use this with care as it is easy to shoot yourself in the foot. + bool checkIfShouldCopy(void*, size_t); + void* allocateNewSpace(size_t); + void didCopy(void*, size_t); + +private: + void* allocateNewSpaceSlow(size_t); + + GCThreadSharedData& m_shared; + CopiedAllocator m_copiedAllocator; +}; + +} // namespace JSC + +#endif diff --git a/Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h b/Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h new file mode 100644 index 000000000..73400750f --- /dev/null +++ b/Source/JavaScriptCore/heap/CopyVisitorInlineMethods.h @@ -0,0 +1,121 @@ +/* + * 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. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CopyVisitorInlineMethods_h +#define CopyVisitorInlineMethods_h + +#include "ClassInfo.h" +#include "CopyVisitor.h" +#include "GCThreadSharedData.h" +#include "JSCell.h" +#include "JSDestructibleObject.h" + +namespace JSC { + +class GCCopyPhaseFunctor : public MarkedBlock::VoidFunctor { +public: + GCCopyPhaseFunctor(CopyVisitor& visitor) + : m_visitor(visitor) + { + } + + void operator()(JSCell* cell) + { + Structure* structure = cell->structure(); + if (!structure->outOfLineCapacity() && !hasIndexedProperties(structure->indexingType())) + return; + ASSERT(structure->classInfo()->methodTable.copyBackingStore == JSObject::copyBackingStore); + JSObject::copyBackingStore(cell, m_visitor); + } + +private: + CopyVisitor& m_visitor; +}; + +inline bool CopyVisitor::checkIfShouldCopy(void* oldPtr, size_t bytes) +{ + if (CopiedSpace::isOversize(bytes)) { + ASSERT(CopiedSpace::oversizeBlockFor(oldPtr)->isPinned()); + return false; + } + + if (CopiedSpace::blockFor(oldPtr)->isPinned()) + return false; + + return true; +} + +inline void* CopyVisitor::allocateNewSpace(size_t bytes) +{ + void* result = 0; // Compilers don't realize that this will be assigned. + if (LIKELY(m_copiedAllocator.tryAllocate(bytes, &result))) + return result; + + result = allocateNewSpaceSlow(bytes); + ASSERT(result); + return result; +} + +inline void* CopyVisitor::allocateNewSpaceSlow(size_t bytes) +{ + CopiedBlock* newBlock = 0; + m_shared.m_copiedSpace->doneFillingBlock(m_copiedAllocator.resetCurrentBlock(), &newBlock); + m_copiedAllocator.setCurrentBlock(newBlock); + + void* result = 0; + CheckedBoolean didSucceed = m_copiedAllocator.tryAllocate(bytes, &result); + ASSERT(didSucceed); + return result; +} + +inline void CopyVisitor::startCopying() +{ + ASSERT(!m_copiedAllocator.isValid()); + CopiedBlock* block = 0; + m_shared.m_copiedSpace->doneFillingBlock(m_copiedAllocator.resetCurrentBlock(), &block); + m_copiedAllocator.setCurrentBlock(block); +} + +inline void CopyVisitor::doneCopying() +{ + if (!m_copiedAllocator.isValid()) + return; + + m_shared.m_copiedSpace->doneFillingBlock(m_copiedAllocator.resetCurrentBlock(), 0); +} + +inline void CopyVisitor::didCopy(void* ptr, size_t bytes) +{ + ASSERT(!CopiedSpace::isOversize(bytes)); + CopiedBlock* block = CopiedSpace::blockFor(ptr); + ASSERT(!block->isPinned()); + + if (block->didEvacuateBytes(bytes)) + m_shared.m_copiedSpace->recycleEvacuatedBlock(block); +} + +} // namespace JSC + +#endif diff --git a/Source/JavaScriptCore/heap/GCThread.cpp b/Source/JavaScriptCore/heap/GCThread.cpp new file mode 100644 index 000000000..ea43456bd --- /dev/null +++ b/Source/JavaScriptCore/heap/GCThread.cpp @@ -0,0 +1,130 @@ +/* + * 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. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "GCThread.h" + +#include "CopyVisitor.h" +#include "CopyVisitorInlineMethods.h" +#include "GCThreadSharedData.h" +#include "SlotVisitor.h" +#include <wtf/MainThread.h> +#include <wtf/PassOwnPtr.h> + +namespace JSC { + +GCThread::GCThread(GCThreadSharedData& shared, SlotVisitor* slotVisitor, CopyVisitor* copyVisitor) + : m_threadID(0) + , m_shared(shared) + , m_slotVisitor(WTF::adoptPtr(slotVisitor)) + , m_copyVisitor(WTF::adoptPtr(copyVisitor)) +{ +} + +ThreadIdentifier GCThread::threadID() +{ + ASSERT(m_threadID); + return m_threadID; +} + +void GCThread::initializeThreadID(ThreadIdentifier threadID) +{ + ASSERT(!m_threadID); + m_threadID = threadID; +} + +SlotVisitor* GCThread::slotVisitor() +{ + ASSERT(m_slotVisitor); + return m_slotVisitor.get(); +} + +CopyVisitor* GCThread::copyVisitor() +{ + ASSERT(m_copyVisitor); + return m_copyVisitor.get(); +} + +GCPhase GCThread::waitForNextPhase() +{ + MutexLocker locker(m_shared.m_phaseLock); + while (m_shared.m_currentPhase == NoPhase) + m_shared.m_phaseCondition.wait(m_shared.m_phaseLock); + return m_shared.m_currentPhase; +} + +void GCThread::gcThreadMain() +{ + GCPhase currentPhase; +#if ENABLE(PARALLEL_GC) + WTF::registerGCThread(); +#endif + // Wait for the main thread to finish creating and initializing us. The main thread grabs this lock before + // creating this thread. We aren't guaranteed to have a valid threadID until the main thread releases this lock. + { + MutexLocker locker(m_shared.m_markingLock); + } + { + ParallelModeEnabler enabler(*m_slotVisitor); + while ((currentPhase = waitForNextPhase()) != Exit) { + // Note: Each phase is responsible for its own termination conditions. The comments below describe + // how each phase reaches termination. + switch (currentPhase) { + case Mark: + m_slotVisitor->drainFromShared(SlotVisitor::SlaveDrain); + // GCThreads only return from drainFromShared() if the main thread sets the m_parallelMarkersShouldExit + // flag in the GCThreadSharedData. The only way the main thread sets that flag is if it realizes + // that all of the various subphases in Heap::markRoots() have been fully finished and there is + // no more marking work to do and all of the GCThreads are idle, meaning no more work can be generated. + break; + case Copy: + // We don't have to call startCopying() because it's called for us on the main thread to avoid a + // race condition. + m_copyVisitor->copyFromShared(); + // We know we're done copying when we return from copyFromShared() because we would + // only do so if there were no more chunks of copying work left to do. When there is no + // more copying work to do, the main thread will wait in CopiedSpace::doneCopying() until + // all of the blocks that the GCThreads borrowed have been returned. doneCopying() + // returns our borrowed CopiedBlock, allowing the copying phase to finish. + m_copyVisitor->doneCopying(); + break; + case NoPhase: + ASSERT_NOT_REACHED(); + break; + case Exit: + ASSERT_NOT_REACHED(); + break; + } + } + } +} + +void GCThread::gcThreadStartFunc(void* data) +{ + GCThread* thread = static_cast<GCThread*>(data); + thread->gcThreadMain(); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/heap/GCThread.h b/Source/JavaScriptCore/heap/GCThread.h new file mode 100644 index 000000000..0d218f975 --- /dev/null +++ b/Source/JavaScriptCore/heap/GCThread.h @@ -0,0 +1,63 @@ +/* + * 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. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GCThread_h +#define GCThread_h + +#include <GCThreadSharedData.h> +#include <wtf/Deque.h> +#include <wtf/OwnPtr.h> +#include <wtf/Threading.h> + +namespace JSC { + +class CopyVisitor; +class GCThreadSharedData; +class SlotVisitor; + +class GCThread { +public: + GCThread(GCThreadSharedData&, SlotVisitor*, CopyVisitor*); + + SlotVisitor* slotVisitor(); + CopyVisitor* copyVisitor(); + ThreadIdentifier threadID(); + void initializeThreadID(ThreadIdentifier); + + static void gcThreadStartFunc(void*); + +private: + void gcThreadMain(); + GCPhase waitForNextPhase(); + + ThreadIdentifier m_threadID; + GCThreadSharedData& m_shared; + OwnPtr<SlotVisitor> m_slotVisitor; + OwnPtr<CopyVisitor> m_copyVisitor; +}; + +} // namespace JSC + +#endif diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp index 23a6b97a1..d9946d589 100644 --- a/Source/JavaScriptCore/heap/GCThreadSharedData.cpp +++ b/Source/JavaScriptCore/heap/GCThreadSharedData.cpp @@ -26,45 +26,30 @@ #include "config.h" #include "GCThreadSharedData.h" +#include "CopyVisitor.h" +#include "CopyVisitorInlineMethods.h" +#include "GCThread.h" #include "JSGlobalData.h" #include "MarkStack.h" #include "SlotVisitor.h" #include "SlotVisitorInlineMethods.h" -#include <wtf/MainThread.h> namespace JSC { #if ENABLE(PARALLEL_GC) void GCThreadSharedData::resetChildren() { - for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i) - m_markingThreadsMarkStack[i]->reset(); + for (size_t i = 0; i < m_gcThreads.size(); ++i) + m_gcThreads[i]->slotVisitor()->reset(); } size_t GCThreadSharedData::childVisitCount() { unsigned long result = 0; - for (unsigned i = 0; i < m_markingThreadsMarkStack.size(); ++i) - result += m_markingThreadsMarkStack[i]->visitCount(); + for (unsigned i = 0; i < m_gcThreads.size(); ++i) + result += m_gcThreads[i]->slotVisitor()->visitCount(); return result; } - -void GCThreadSharedData::markingThreadMain(SlotVisitor* slotVisitor) -{ - WTF::registerGCThread(); - { - ParallelModeEnabler enabler(*slotVisitor); - slotVisitor->drainFromShared(SlotVisitor::SlaveDrain); - } - delete slotVisitor; -} - -void GCThreadSharedData::markingThreadStartFunc(void* myVisitor) -{ - SlotVisitor* slotVisitor = static_cast<SlotVisitor*>(myVisitor); - - slotVisitor->sharedData().markingThreadMain(slotVisitor); -} #endif GCThreadSharedData::GCThreadSharedData(JSGlobalData* globalData) @@ -74,13 +59,21 @@ GCThreadSharedData::GCThreadSharedData(JSGlobalData* globalData) , m_sharedMarkStack(m_segmentAllocator) , m_numberOfActiveParallelMarkers(0) , m_parallelMarkersShouldExit(false) + , m_blocksToCopy(globalData->heap.m_blockSnapshot) + , m_copyIndex(0) + , m_currentPhase(NoPhase) { + m_copyLock.Init(); #if ENABLE(PARALLEL_GC) + // Grab the lock so the new GC threads can be properly initialized before they start running. + MutexLocker locker(m_markingLock); for (unsigned i = 1; i < Options::numberOfGCMarkers(); ++i) { SlotVisitor* slotVisitor = new SlotVisitor(*this); - m_markingThreadsMarkStack.append(slotVisitor); - m_markingThreads.append(createThread(markingThreadStartFunc, slotVisitor, "JavaScriptCore::Marking")); - ASSERT(m_markingThreads.last()); + CopyVisitor* copyVisitor = new CopyVisitor(*this); + GCThread* newThread = new GCThread(*this, slotVisitor, copyVisitor); + ThreadIdentifier threadID = createThread(GCThread::gcThreadStartFunc, newThread, "JavaScriptCore::Marking"); + newThread->initializeThreadID(threadID); + m_gcThreads.append(newThread); } #endif } @@ -90,19 +83,22 @@ GCThreadSharedData::~GCThreadSharedData() #if ENABLE(PARALLEL_GC) // Destroy our marking threads. { - MutexLocker locker(m_markingLock); + MutexLocker markingLocker(m_markingLock); + MutexLocker phaseLocker(m_phaseLock); + ASSERT(m_currentPhase == NoPhase); m_parallelMarkersShouldExit = true; - m_markingCondition.broadcast(); + m_currentPhase = Exit; + m_phaseCondition.broadcast(); + } + for (unsigned i = 0; i < m_gcThreads.size(); ++i) { + waitForThreadCompletion(m_gcThreads[i]->threadID()); + delete m_gcThreads[i]; } - for (unsigned i = 0; i < m_markingThreads.size(); ++i) - waitForThreadCompletion(m_markingThreads[i]); #endif } void GCThreadSharedData::reset() { - ASSERT(!m_numberOfActiveParallelMarkers); - ASSERT(!m_parallelMarkersShouldExit); ASSERT(m_sharedMarkStack.isEmpty()); #if ENABLE(PARALLEL_GC) @@ -119,4 +115,53 @@ void GCThreadSharedData::reset() } } +void GCThreadSharedData::didStartMarking() +{ + MutexLocker markingLocker(m_markingLock); + MutexLocker phaseLocker(m_phaseLock); + ASSERT(m_currentPhase == NoPhase); + m_currentPhase = Mark; + m_parallelMarkersShouldExit = false; + m_phaseCondition.broadcast(); +} + +void GCThreadSharedData::didFinishMarking() +{ + MutexLocker markingLocker(m_markingLock); + MutexLocker phaseLocker(m_phaseLock); + ASSERT(m_currentPhase == Mark); + m_currentPhase = NoPhase; + m_parallelMarkersShouldExit = true; + m_markingCondition.broadcast(); +} + +void GCThreadSharedData::didStartCopying() +{ + { + SpinLockHolder locker(&m_copyLock); + m_blocksToCopy = m_globalData->heap.m_blockSnapshot; + m_copyIndex = 0; + } + + // We do this here so that we avoid a race condition where the main thread can + // blow through all of the copying work before the GCThreads fully wake up. + // The GCThreads then request a block from the CopiedSpace when the copying phase + // has completed, which isn't allowed. + for (size_t i = 0; i < m_gcThreads.size(); i++) + m_gcThreads[i]->copyVisitor()->startCopying(); + + MutexLocker locker(m_phaseLock); + ASSERT(m_currentPhase == NoPhase); + m_currentPhase = Copy; + m_phaseCondition.broadcast(); +} + +void GCThreadSharedData::didFinishCopying() +{ + MutexLocker locker(m_phaseLock); + ASSERT(m_currentPhase == Copy); + m_currentPhase = NoPhase; + m_phaseCondition.broadcast(); +} + } // namespace JSC diff --git a/Source/JavaScriptCore/heap/GCThreadSharedData.h b/Source/JavaScriptCore/heap/GCThreadSharedData.h index 3f09a2820..bd48d9263 100644 --- a/Source/JavaScriptCore/heap/GCThreadSharedData.h +++ b/Source/JavaScriptCore/heap/GCThreadSharedData.h @@ -28,16 +28,27 @@ #include "ListableHandler.h" #include "MarkStack.h" +#include "MarkedBlock.h" #include "UnconditionalFinalizer.h" #include "WeakReferenceHarvester.h" #include <wtf/HashSet.h> +#include <wtf/TCSpinLock.h> #include <wtf/Threading.h> #include <wtf/Vector.h> namespace JSC { +class GCThread; class JSGlobalData; class CopiedSpace; +class CopyVisitor; + +enum GCPhase { + NoPhase, + Mark, + Copy, + Exit +}; class GCThreadSharedData { public: @@ -46,6 +57,11 @@ public: void reset(); + void didStartMarking(); + void didFinishMarking(); + void didStartCopying(); + void didFinishCopying(); + #if ENABLE(PARALLEL_GC) void resetChildren(); size_t childVisitCount(); @@ -53,12 +69,11 @@ public: #endif private: + friend class GCThread; friend class SlotVisitor; + friend class CopyVisitor; -#if ENABLE(PARALLEL_GC) - void markingThreadMain(SlotVisitor*); - static void markingThreadStartFunc(void* heap); -#endif + void getNextBlocksToCopy(size_t&, size_t&); JSGlobalData* m_globalData; CopiedSpace* m_copiedSpace; @@ -67,9 +82,8 @@ private: bool m_shouldHashConst; - Vector<ThreadIdentifier> m_markingThreads; - Vector<SlotVisitor*> m_markingThreadsMarkStack; - + Vector<GCThread*> m_gcThreads; + Mutex m_markingLock; ThreadCondition m_markingCondition; MarkStackArray m_sharedMarkStack; @@ -79,10 +93,27 @@ private: Mutex m_opaqueRootsLock; HashSet<void*> m_opaqueRoots; + SpinLock m_copyLock; + Vector<MarkedBlock*>& m_blocksToCopy; + size_t m_copyIndex; + static const size_t s_blockFragmentLength = 32; + + Mutex m_phaseLock; + ThreadCondition m_phaseCondition; + GCPhase m_currentPhase; + ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters; ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers; }; +inline void GCThreadSharedData::getNextBlocksToCopy(size_t& start, size_t& end) +{ + SpinLockHolder locker(&m_copyLock); + start = m_copyIndex; + end = std::min(m_blocksToCopy.size(), m_copyIndex + s_blockFragmentLength); + m_copyIndex = end; +} + } // namespace JSC #endif diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp index ca936ebfc..772d85144 100644 --- a/Source/JavaScriptCore/heap/Heap.cpp +++ b/Source/JavaScriptCore/heap/Heap.cpp @@ -21,12 +21,14 @@ #include "config.h" #include "Heap.h" -#include "CopiedSpace.h" -#include "CopiedSpaceInlineMethods.h" #include "CodeBlock.h" #include "ConservativeRoots.h" +#include "CopiedSpace.h" +#include "CopiedSpaceInlineMethods.h" +#include "CopyVisitorInlineMethods.h" #include "GCActivityCallback.h" #include "HeapRootVisitor.h" +#include "HeapStatistics.h" #include "IncrementalSweeper.h" #include "Interpreter.h" #include "JSGlobalData.h" @@ -235,74 +237,6 @@ inline PassOwnPtr<TypeCountSet> RecordType::returnValue() return m_typeCountSet.release(); } -class StorageStatistics : public MarkedBlock::VoidFunctor { -public: - StorageStatistics(); - - void operator()(JSCell*); - - size_t objectWithOutOfLineStorageCount(); - size_t objectCount(); - - size_t storageSize(); - size_t storageCapacity(); - -private: - size_t m_objectWithOutOfLineStorageCount; - size_t m_objectCount; - size_t m_storageSize; - size_t m_storageCapacity; -}; - -inline StorageStatistics::StorageStatistics() - : m_objectWithOutOfLineStorageCount(0) - , m_objectCount(0) - , m_storageSize(0) - , m_storageCapacity(0) -{ -} - -inline void StorageStatistics::operator()(JSCell* cell) -{ - if (!cell->isObject()) - return; - - JSObject* object = jsCast<JSObject*>(cell); - if (hasIndexedProperties(object->structure()->indexingType())) - return; - - if (object->structure()->isUncacheableDictionary()) - return; - - ++m_objectCount; - if (!object->hasInlineStorage()) - ++m_objectWithOutOfLineStorageCount; - m_storageSize += object->structure()->totalStorageSize() * sizeof(WriteBarrierBase<Unknown>); - m_storageCapacity += object->structure()->totalStorageCapacity() * sizeof(WriteBarrierBase<Unknown>); -} - -inline size_t StorageStatistics::objectWithOutOfLineStorageCount() -{ - return m_objectWithOutOfLineStorageCount; -} - -inline size_t StorageStatistics::objectCount() -{ - return m_objectCount; -} - - -inline size_t StorageStatistics::storageSize() -{ - return m_storageSize; -} - - -inline size_t StorageStatistics::storageCapacity() -{ - return m_storageCapacity; -} - } // anonymous namespace Heap::Heap(JSGlobalData* globalData, HeapType heapType) @@ -319,6 +253,7 @@ Heap::Heap(JSGlobalData* globalData, HeapType heapType) , m_machineThreads(this) , m_sharedData(globalData) , m_slotVisitor(m_sharedData) + , m_copyVisitor(m_sharedData) , m_handleSet(globalData) , m_isSafeToCollect(false) , m_globalData(globalData) @@ -422,7 +357,7 @@ void Heap::markProtectedObjects(HeapRootVisitor& heapRootVisitor) { ProtectCountSet::iterator end = m_protectedValues.end(); for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) - heapRootVisitor.visit(&it->first); + heapRootVisitor.visit(&it->key); } void Heap::pushTempSortVector(Vector<ValueStringPair>* tempVector) @@ -462,19 +397,19 @@ void Heap::finalizeUnconditionalFinalizers() m_slotVisitor.finalizeUnconditionalFinalizers(); } -inline RegisterFile& Heap::registerFile() +inline JSStack& Heap::stack() { - return m_globalData->interpreter->registerFile(); + return m_globalData->interpreter->stack(); } void Heap::getConservativeRegisterRoots(HashSet<JSCell*>& roots) { ASSERT(isValidThreadState(m_globalData)); - ConservativeRoots registerFileRoots(&m_objectSpace.blocks(), &m_storageSpace); - registerFile().gatherConservativeRoots(registerFileRoots); - size_t registerFileRootCount = registerFileRoots.size(); - JSCell** registerRoots = registerFileRoots.roots(); - for (size_t i = 0; i < registerFileRootCount; i++) { + ConservativeRoots stackRoots(&m_objectSpace.blocks(), &m_storageSpace); + stack().gatherConservativeRoots(stackRoots); + size_t stackRootCount = stackRoots.size(); + JSCell** registerRoots = stackRoots.roots(); + for (size_t i = 0; i < stackRootCount; i++) { setMarked(registerRoots[i]); roots.add(registerRoots[i]); } @@ -503,12 +438,12 @@ void Heap::markRoots(bool fullGC) m_machineThreads.gatherConservativeRoots(machineThreadRoots, &dummy); } - ConservativeRoots registerFileRoots(&m_objectSpace.blocks(), &m_storageSpace); + ConservativeRoots stackRoots(&m_objectSpace.blocks(), &m_storageSpace); m_dfgCodeBlocks.clearMarks(); { - GCPHASE(GatherRegisterFileRoots); - registerFile().gatherConservativeRoots( - registerFileRoots, m_jitStubRoutines, m_dfgCodeBlocks); + GCPHASE(GatherStackRoots); + stack().gatherConservativeRoots( + stackRoots, m_jitStubRoutines, m_dfgCodeBlocks); } #if ENABLE(DFG_JIT) @@ -531,7 +466,7 @@ void Heap::markRoots(bool fullGC) m_objectSpace.clearMarks(); } - m_storageSpace.startedCopying(); + m_sharedData.didStartMarking(); SlotVisitor& visitor = m_slotVisitor; visitor.setup(); HeapRootVisitor heapRootVisitor(visitor); @@ -563,9 +498,9 @@ void Heap::markRoots(bool fullGC) visitor.donateAndDrain(); } { - GCPHASE(VisitRegisterFileRoots); - MARK_LOG_ROOT(visitor, "Register File"); - visitor.append(registerFileRoots); + GCPHASE(VisitStackRoots); + MARK_LOG_ROOT(visitor, "Stack"); + visitor.append(stackRoots); visitor.donateAndDrain(); } #if ENABLE(DFG_JIT) @@ -656,7 +591,7 @@ void Heap::markRoots(bool fullGC) GCCOUNTER(VisitedValueCount, visitor.visitCount()); - visitor.doneCopying(); + m_sharedData.didFinishMarking(); #if ENABLE(OBJECT_MARK_LOGGING) size_t visitCount = visitor.visitCount(); #if ENABLE(PARALLEL_GC) @@ -670,7 +605,23 @@ void Heap::markRoots(bool fullGC) m_sharedData.resetChildren(); #endif m_sharedData.reset(); - m_storageSpace.doneCopying(); +} + +void Heap::copyBackingStores() +{ + m_storageSpace.startedCopying(); + if (m_storageSpace.shouldDoCopyPhase()) { + m_sharedData.didStartCopying(); + CopyVisitor& visitor = m_copyVisitor; + visitor.startCopying(); + visitor.copyFromShared(); + visitor.doneCopying(); + // We need to wait for everybody to finish and return their CopiedBlocks + // before signaling that the phase is complete. + m_storageSpace.doneCopying(); + m_sharedData.didFinishCopying(); + } else + m_storageSpace.doneCopying(); } size_t Heap::objectCount() @@ -801,6 +752,14 @@ void Heap::collect(SweepToggle sweepToggle) JAVASCRIPTCORE_GC_MARKED(); { + m_blockSnapshot.resize(m_objectSpace.blocks().set().size()); + MarkedBlockSnapshotFunctor functor(m_blockSnapshot); + m_objectSpace.forEachBlock(functor); + } + + copyBackingStores(); + + { GCPHASE(FinalizeUnconditionalFinalizers); finalizeUnconditionalFinalizers(); } @@ -822,7 +781,7 @@ void Heap::collect(SweepToggle sweepToggle) m_objectSpace.shrink(); } - m_sweeper->startSweeping(m_objectSpace.blocks().set()); + m_sweeper->startSweeping(m_blockSnapshot); m_bytesAbandoned = 0; { @@ -831,6 +790,9 @@ void Heap::collect(SweepToggle sweepToggle) } size_t currentHeapSize = size(); + if (Options::gcMaxHeapSize() && currentHeapSize > Options::gcMaxHeapSize()) + HeapStatistics::exitWithFailure(); + if (fullGC) { m_sizeAfterLastCollect = currentHeapSize; @@ -844,6 +806,8 @@ void Heap::collect(SweepToggle sweepToggle) double lastGCEndTime = WTF::currentTime(); m_lastGCLength = lastGCEndTime - lastGCStartTime; + if (Options::recordGCPauseTimes()) + HeapStatistics::recordGCPauseTime(lastGCStartTime, lastGCEndTime); if (m_operationInProgress != Collection) CRASH(); m_operationInProgress = NoOperation; @@ -855,31 +819,8 @@ void Heap::collect(SweepToggle sweepToggle) if (Options::objectsAreImmortal()) markDeadObjects(); - if (Options::showHeapStatistics()) - showStatistics(); -} - -void Heap::showStatistics() -{ - dataLog("\n=== Heap Statistics: ===\n"); - dataLog("size: %ldkB\n", static_cast<long>(m_sizeAfterLastCollect / KB)); - dataLog("capacity: %ldkB\n", static_cast<long>(capacity() / KB)); - dataLog("pause time: %lfms\n\n", m_lastGCLength); - - StorageStatistics storageStatistics; - m_objectSpace.forEachLiveCell(storageStatistics); - dataLog("wasted .property storage: %ldkB (%ld%%)\n", - static_cast<long>( - (storageStatistics.storageCapacity() - storageStatistics.storageSize()) / KB), - static_cast<long>( - (storageStatistics.storageCapacity() - storageStatistics.storageSize()) * 100 - / storageStatistics.storageCapacity())); - dataLog("objects with out-of-line .property storage: %ld (%ld%%)\n", - static_cast<long>( - storageStatistics.objectWithOutOfLineStorageCount()), - static_cast<long>( - storageStatistics.objectWithOutOfLineStorageCount() * 100 - / storageStatistics.objectCount())); + if (Options::showObjectStatistics()) + HeapStatistics::showObjectStatistics(this); } void Heap::markDeadObjects() @@ -942,11 +883,6 @@ void Heap::addCompiledCode(ExecutableBase* executable) m_compiledCode.append(executable); } -bool Heap::isSafeToSweepStructures() -{ - return !m_sweeper || m_sweeper->structuresCanBeSwept(); -} - void Heap::didStartVMShutdown() { m_activityCallback->didStartVMShutdown(); diff --git a/Source/JavaScriptCore/heap/Heap.h b/Source/JavaScriptCore/heap/Heap.h index 92efff7c5..88dc201a4 100644 --- a/Source/JavaScriptCore/heap/Heap.h +++ b/Source/JavaScriptCore/heap/Heap.h @@ -23,6 +23,7 @@ #define Heap_h #include "BlockAllocator.h" +#include "CopyVisitor.h" #include "DFGCodeBlocks.h" #include "GCThreadSharedData.h" #include "HandleSet.h" @@ -32,6 +33,7 @@ #include "MarkedBlock.h" #include "MarkedBlockSet.h" #include "MarkedSpace.h" +#include "Options.h" #include "SlotVisitor.h" #include "WeakHandleOwner.h" #include "WriteBarrierSupport.h" @@ -54,11 +56,11 @@ namespace JSC { class JITStubRoutine; class JSCell; class JSGlobalData; + class JSStack; class JSValue; class LiveObjectIterator; class LLIntOffsetsExtractor; class MarkedArgumentBuffer; - class RegisterFile; class WeakGCHandlePool; class SlotVisitor; @@ -112,7 +114,8 @@ namespace JSC { MarkedAllocator& firstAllocatorWithoutDestructors() { return m_objectSpace.firstAllocator(); } MarkedAllocator& allocatorForObjectWithoutDestructor(size_t bytes) { return m_objectSpace.allocatorFor(bytes); } - MarkedAllocator& allocatorForObjectWithDestructor(size_t bytes) { return m_objectSpace.destructorAllocatorFor(bytes); } + MarkedAllocator& allocatorForObjectWithNormalDestructor(size_t bytes) { return m_objectSpace.normalDestructorAllocatorFor(bytes); } + MarkedAllocator& allocatorForObjectWithImmortalStructureDestructor(size_t bytes) { return m_objectSpace.immortalStructureDestructorAllocatorFor(bytes); } CopiedAllocator& storageAllocator() { return m_storageSpace.allocator(); } CheckedBoolean tryAllocateStorage(size_t, void**); CheckedBoolean tryReallocateStorage(void**, size_t, size_t); @@ -169,7 +172,6 @@ namespace JSC { void didAbandon(size_t); bool isPagedOut(double deadline); - bool isSafeToSweepStructures(); void didStartVMShutdown(); private: @@ -181,13 +183,16 @@ namespace JSC { friend class MarkedAllocator; friend class MarkedBlock; friend class CopiedSpace; + friend class CopyVisitor; friend class SlotVisitor; + friend class IncrementalSweeper; + friend class HeapStatistics; template<typename T> friend void* allocateCell(Heap&); template<typename T> friend void* allocateCell(Heap&, size_t); - void* allocateWithDestructor(size_t); - void* allocateWithoutDestructor(size_t); - void* allocateStructure(size_t); + void* allocateWithImmortalStructureDestructor(size_t); // For use with special objects whose Structures never die. + void* allocateWithNormalDestructor(size_t); // For use with objects that inherit directly or indirectly from JSDestructibleObject. + void* allocateWithoutDestructor(size_t); // For use with objects without destructors. static const size_t minExtraCost = 256; static const size_t maxExtraCost = 1024 * 1024; @@ -202,13 +207,14 @@ namespace JSC { void markRoots(bool fullGC); void markProtectedObjects(HeapRootVisitor&); void markTempSortVectors(HeapRootVisitor&); + void copyBackingStores(); void harvestWeakReferences(); void finalizeUnconditionalFinalizers(); void deleteUnmarkedCompiledCode(); void zombifyDeadObjects(); void markDeadObjects(); - RegisterFile& registerFile(); + JSStack& stack(); BlockAllocator& blockAllocator(); const HeapType m_heapType; @@ -237,6 +243,7 @@ namespace JSC { GCThreadSharedData m_sharedData; SlotVisitor m_slotVisitor; + CopyVisitor m_copyVisitor; HandleSet m_handleSet; HandleStack m_handleStack; @@ -254,10 +261,26 @@ namespace JSC { GCActivityCallback* m_activityCallback; IncrementalSweeper* m_sweeper; + Vector<MarkedBlock*> m_blockSnapshot; + }; + + struct MarkedBlockSnapshotFunctor : public MarkedBlock::VoidFunctor { + MarkedBlockSnapshotFunctor(Vector<MarkedBlock*>& blocks) + : m_index(0) + , m_blocks(blocks) + { + } + + void operator()(MarkedBlock* block) { m_blocks[m_index++] = block; } + + size_t m_index; + Vector<MarkedBlock*>& m_blocks; }; inline bool Heap::shouldCollect() { + if (Options::gcMaxHeapSize()) + return m_bytesAllocated > Options::gcMaxHeapSize() && m_isSafeToCollect && m_operationInProgress == NoOperation; #if ENABLE(GGC) return m_objectSpace.nurseryWaterMark() >= m_minBytesPerCycle && m_isSafeToCollect && m_operationInProgress == NoOperation; #else @@ -351,7 +374,7 @@ namespace JSC { { ProtectCountSet::iterator end = m_protectedValues.end(); for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it) - functor(it->first); + functor(it->key); m_handleSet.forEachStrongHandle(functor, m_protectedValues); return functor.returnValue(); @@ -363,10 +386,16 @@ namespace JSC { return forEachProtectedCell(functor); } - inline void* Heap::allocateWithDestructor(size_t bytes) + inline void* Heap::allocateWithNormalDestructor(size_t bytes) + { + ASSERT(isValidAllocation(bytes)); + return m_objectSpace.allocateWithNormalDestructor(bytes); + } + + inline void* Heap::allocateWithImmortalStructureDestructor(size_t bytes) { ASSERT(isValidAllocation(bytes)); - return m_objectSpace.allocateWithDestructor(bytes); + return m_objectSpace.allocateWithImmortalStructureDestructor(bytes); } inline void* Heap::allocateWithoutDestructor(size_t bytes) @@ -375,11 +404,6 @@ namespace JSC { return m_objectSpace.allocateWithoutDestructor(bytes); } - inline void* Heap::allocateStructure(size_t bytes) - { - return m_objectSpace.allocateStructure(bytes); - } - inline CheckedBoolean Heap::tryAllocateStorage(size_t bytes, void** outPtr) { return m_storageSpace.tryAllocate(bytes, outPtr); diff --git a/Source/JavaScriptCore/heap/HeapBlock.h b/Source/JavaScriptCore/heap/HeapBlock.h index a63b7ebe1..677eaacd4 100644 --- a/Source/JavaScriptCore/heap/HeapBlock.h +++ b/Source/JavaScriptCore/heap/HeapBlock.h @@ -27,13 +27,14 @@ #define HeapBlock_h #include <wtf/DoublyLinkedList.h> -#include <wtf/PageAllocationAligned.h> #include <wtf/StdLibExtras.h> namespace JSC { enum AllocationEffort { AllocationCanFail, AllocationMustSucceed }; +class Region; + #if COMPILER(GCC) #define CLASS_IF_GCC class #else @@ -44,30 +45,25 @@ template<typename T> class HeapBlock : public DoublyLinkedListNode<T> { friend CLASS_IF_GCC DoublyLinkedListNode<T>; public: - static const size_t s_blockSize = 64 * KB; - - static PageAllocationAligned destroy(HeapBlock* block) + static HeapBlock* destroy(HeapBlock* block) { static_cast<T*>(block)->~T(); - - PageAllocationAligned allocation; - std::swap(allocation, block->m_allocation); - return allocation; + return block; } - HeapBlock(const PageAllocationAligned& allocation) + HeapBlock(Region* region) : DoublyLinkedListNode<T>() - , m_allocation(allocation) + , m_region(region) , m_prev(0) , m_next(0) { - ASSERT(m_allocation); + ASSERT(m_region); } - const PageAllocationAligned allocation() const { return m_allocation; } + Region* region() const { return m_region; } private: - PageAllocationAligned m_allocation; + Region* m_region; T* m_prev; T* m_next; }; diff --git a/Source/JavaScriptCore/heap/HeapStatistics.cpp b/Source/JavaScriptCore/heap/HeapStatistics.cpp new file mode 100644 index 000000000..68044e0b3 --- /dev/null +++ b/Source/JavaScriptCore/heap/HeapStatistics.cpp @@ -0,0 +1,258 @@ +/* + * 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. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "HeapStatistics.h" + +#include "Heap.h" +#include "JSObject.h" +#include "Options.h" +#include <stdlib.h> +#if OS(UNIX) +#include <sys/resource.h> +#endif +#include <wtf/CurrentTime.h> +#include <wtf/DataLog.h> +#include <wtf/Deque.h> + +namespace JSC { + +double HeapStatistics::s_startTime = 0.0; +double HeapStatistics::s_endTime = 0.0; +Deque<double>* HeapStatistics::s_pauseTimeStarts = 0; +Deque<double>* HeapStatistics::s_pauseTimeEnds = 0; + +#if OS(UNIX) + +void HeapStatistics::initialize() +{ + ASSERT(Options::recordGCPauseTimes()); + s_startTime = WTF::monotonicallyIncreasingTime(); + s_pauseTimeStarts = new Deque<double>(); + s_pauseTimeEnds = new Deque<double>(); +} + +void HeapStatistics::recordGCPauseTime(double start, double end) +{ + ASSERT(Options::recordGCPauseTimes()); + ASSERT(s_pauseTimeStarts); + ASSERT(s_pauseTimeEnds); + s_pauseTimeStarts->append(start); + s_pauseTimeEnds->append(end); +} + +void HeapStatistics::logStatistics() +{ + struct rusage usage; + getrusage(RUSAGE_SELF, &usage); +#if USE(CF) || OS(UNIX) + char* vmName = getenv("JSVMName"); + char* suiteName = getenv("JSSuiteName"); + char* benchmarkName = getenv("JSBenchmarkName"); +#else +#error "The HeapStatistics module is not supported on this platform." +#endif + if (!vmName || !suiteName || !benchmarkName) + dataLog("HeapStatistics: {\"max_rss\": %ld", usage.ru_maxrss); + else + dataLog("HeapStatistics: {\"max_rss\": %ld, \"vm_name\": \"%s\", \"suite_name\": \"%s\", \"benchmark_name\": \"%s\"", + usage.ru_maxrss, vmName, suiteName, benchmarkName); + + if (Options::recordGCPauseTimes()) { + dataLog(", \"pause_times\": ["); + Deque<double>::iterator startIt = s_pauseTimeStarts->begin(); + Deque<double>::iterator endIt = s_pauseTimeEnds->begin(); + if (startIt != s_pauseTimeStarts->end() && endIt != s_pauseTimeEnds->end()) { + dataLog("[%f, %f]", *startIt, *endIt); + ++startIt; + ++endIt; + } + while (startIt != s_pauseTimeStarts->end() && endIt != s_pauseTimeEnds->end()) { + dataLog(", [%f, %f]", *startIt, *endIt); + ++startIt; + ++endIt; + } + dataLog("], \"start_time\": %f, \"end_time\": %f", s_startTime, s_endTime); + } + dataLog("}\n"); +} + +void HeapStatistics::exitWithFailure() +{ + ASSERT(Options::logHeapStatisticsAtExit()); + s_endTime = WTF::monotonicallyIncreasingTime(); + logStatistics(); + exit(-1); +} + +void HeapStatistics::reportSuccess() +{ + ASSERT(Options::logHeapStatisticsAtExit()); + s_endTime = WTF::monotonicallyIncreasingTime(); + logStatistics(); +} + +#else + +void HeapStatistics::initialize() +{ +} + +void HeapStatistics::recordGCPauseTime(double, double) +{ +} + +void HeapStatistics::logStatistics() +{ +} + +void HeapStatistics::exitWithFailure() +{ +} + +void HeapStatistics::reportSuccess() +{ +} + +#endif // OS(UNIX) + +size_t HeapStatistics::usedJSHeap() +{ + JSGlobalData* globalData = &JSGlobalData::sharedInstance(); + return globalData->heap.size(); +} + +size_t HeapStatistics::parseMemoryAmount(char* s) +{ + size_t multiplier = 1; + char* afterS; + size_t value = strtol(s, &afterS, 10); + char next = afterS[0]; + switch (next) { + case 'K': + multiplier = KB; + break; + case 'M': + multiplier = MB; + break; + case 'G': + multiplier = GB; + break; + default: + break; + } + return value * multiplier; +} + +class StorageStatistics : public MarkedBlock::VoidFunctor { +public: + StorageStatistics(); + + void operator()(JSCell*); + + size_t objectWithOutOfLineStorageCount(); + size_t objectCount(); + + size_t storageSize(); + size_t storageCapacity(); + +private: + size_t m_objectWithOutOfLineStorageCount; + size_t m_objectCount; + size_t m_storageSize; + size_t m_storageCapacity; +}; + +inline StorageStatistics::StorageStatistics() + : m_objectWithOutOfLineStorageCount(0) + , m_objectCount(0) + , m_storageSize(0) + , m_storageCapacity(0) +{ +} + +inline void StorageStatistics::operator()(JSCell* cell) +{ + if (!cell->isObject()) + return; + + JSObject* object = jsCast<JSObject*>(cell); + if (hasIndexedProperties(object->structure()->indexingType())) + return; + + if (object->structure()->isUncacheableDictionary()) + return; + + ++m_objectCount; + if (!object->hasInlineStorage()) + ++m_objectWithOutOfLineStorageCount; + m_storageSize += object->structure()->totalStorageSize() * sizeof(WriteBarrierBase<Unknown>); + m_storageCapacity += object->structure()->totalStorageCapacity() * sizeof(WriteBarrierBase<Unknown>); +} + +inline size_t StorageStatistics::objectWithOutOfLineStorageCount() +{ + return m_objectWithOutOfLineStorageCount; +} + +inline size_t StorageStatistics::objectCount() +{ + return m_objectCount; +} + +inline size_t StorageStatistics::storageSize() +{ + return m_storageSize; +} + +inline size_t StorageStatistics::storageCapacity() +{ + return m_storageCapacity; +} + +void HeapStatistics::showObjectStatistics(Heap* heap) +{ + dataLog("\n=== Heap Statistics: ===\n"); + dataLog("size: %ldkB\n", static_cast<long>(heap->m_sizeAfterLastCollect / KB)); + dataLog("capacity: %ldkB\n", static_cast<long>(heap->capacity() / KB)); + dataLog("pause time: %lfms\n\n", heap->m_lastGCLength); + + StorageStatistics storageStatistics; + heap->m_objectSpace.forEachLiveCell(storageStatistics); + dataLog("wasted .property storage: %ldkB (%ld%%)\n", + static_cast<long>( + (storageStatistics.storageCapacity() - storageStatistics.storageSize()) / KB), + static_cast<long>( + (storageStatistics.storageCapacity() - storageStatistics.storageSize()) * 100 + / storageStatistics.storageCapacity())); + dataLog("objects with out-of-line .property storage: %ld (%ld%%)\n", + static_cast<long>( + storageStatistics.objectWithOutOfLineStorageCount()), + static_cast<long>( + storageStatistics.objectWithOutOfLineStorageCount() * 100 + / storageStatistics.objectCount())); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/heap/HeapStatistics.h b/Source/JavaScriptCore/heap/HeapStatistics.h new file mode 100644 index 000000000..34d05af7c --- /dev/null +++ b/Source/JavaScriptCore/heap/HeapStatistics.h @@ -0,0 +1,61 @@ +/* + * 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. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HeapStatistics_h +#define HeapStatistics_h + +#include <wtf/Deque.h> + +namespace JSC { + +class Heap; + +class HeapStatistics { +public: + NO_RETURN static void exitWithFailure(); + JS_EXPORT_PRIVATE static void reportSuccess(); + JS_EXPORT_PRIVATE static size_t usedJSHeap(); + + static void initialize(); + static void recordGCPauseTime(double start, double end); + static size_t parseMemoryAmount(char*); + + static void showObjectStatistics(Heap*); + + static const size_t KB = 1024; + static const size_t MB = 1024 * KB; + static const size_t GB = 1024 * MB; + +private: + static void logStatistics(); + static Deque<double>* s_pauseTimeStarts; + static Deque<double>* s_pauseTimeEnds; + static double s_startTime; + static double s_endTime; +}; + +} // namespace JSC + +#endif diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp index bd1342f2a..4aec4dd51 100644 --- a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp +++ b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp @@ -48,7 +48,7 @@ static const double sweepTimeMultiplier = 1.0 / sweepTimeTotal; IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop) : HeapTimer(heap->globalData(), runLoop) , m_currentBlockToSweepIndex(0) - , m_structuresCanBeSwept(false) + , m_blocksToSweep(heap->m_blockSnapshot) { } @@ -72,7 +72,6 @@ void IncrementalSweeper::cancelTimer() IncrementalSweeper::IncrementalSweeper(Heap* heap) : HeapTimer(heap->globalData()) , m_currentBlockToSweepIndex(0) - , m_structuresCanBeSwept(false) { } @@ -119,10 +118,6 @@ void IncrementalSweeper::sweepNextBlock() { while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) { MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++]; - if (block->onlyContainsStructures()) - m_structuresCanBeSwept = true; - else - ASSERT(!m_structuresCanBeSwept); if (!block->needsSweeping()) continue; @@ -133,20 +128,16 @@ void IncrementalSweeper::sweepNextBlock() } } -void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>& blockSnapshot) +void IncrementalSweeper::startSweeping(Vector<MarkedBlock*>& blockSnapshot) { - m_blocksToSweep.resize(blockSnapshot.size()); - CopyFunctor functor(m_blocksToSweep); - m_globalData->heap.objectSpace().forEachBlock(functor); + m_blocksToSweep = blockSnapshot; m_currentBlockToSweepIndex = 0; - m_structuresCanBeSwept = false; scheduleTimer(); } void IncrementalSweeper::willFinishSweeping() { m_currentBlockToSweepIndex = 0; - m_structuresCanBeSwept = true; m_blocksToSweep.clear(); if (m_globalData) cancelTimer(); @@ -156,7 +147,6 @@ void IncrementalSweeper::willFinishSweeping() IncrementalSweeper::IncrementalSweeper(JSGlobalData* globalData) : HeapTimer(globalData) - , m_structuresCanBeSwept(false) { } @@ -169,14 +159,12 @@ IncrementalSweeper* IncrementalSweeper::create(Heap* heap) return new IncrementalSweeper(heap->globalData()); } -void IncrementalSweeper::startSweeping(const HashSet<MarkedBlock*>&) +void IncrementalSweeper::startSweeping(Vector<MarkedBlock*>&) { - m_structuresCanBeSwept = false; } void IncrementalSweeper::willFinishSweeping() { - m_structuresCanBeSwept = true; } void IncrementalSweeper::sweepNextBlock() @@ -185,9 +173,4 @@ void IncrementalSweeper::sweepNextBlock() #endif -bool IncrementalSweeper::structuresCanBeSwept() -{ - return m_structuresCanBeSwept; -} - } // namespace JSC diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.h b/Source/JavaScriptCore/heap/IncrementalSweeper.h index 03c620f9c..5b9267bc7 100644 --- a/Source/JavaScriptCore/heap/IncrementalSweeper.h +++ b/Source/JavaScriptCore/heap/IncrementalSweeper.h @@ -37,26 +37,12 @@ namespace JSC { class Heap; -struct CopyFunctor : public MarkedBlock::VoidFunctor { - CopyFunctor(Vector<MarkedBlock*>& blocks) - : m_index(0) - , m_blocks(blocks) - { - } - - void operator()(MarkedBlock* block) { m_blocks[m_index++] = block; } - - size_t m_index; - Vector<MarkedBlock*>& m_blocks; -}; - class IncrementalSweeper : public HeapTimer { public: static IncrementalSweeper* create(Heap*); - void startSweeping(const HashSet<MarkedBlock*>& blockSnapshot); + void startSweeping(Vector<MarkedBlock*>&); virtual void doWork(); void sweepNextBlock(); - bool structuresCanBeSwept(); void willFinishSweeping(); private: @@ -72,13 +58,12 @@ private: void cancelTimer(); unsigned m_currentBlockToSweepIndex; - Vector<MarkedBlock*> m_blocksToSweep; + Vector<MarkedBlock*>& m_blocksToSweep; #else IncrementalSweeper(JSGlobalData*); #endif - bool m_structuresCanBeSwept; }; } // namespace JSC diff --git a/Source/JavaScriptCore/heap/JITStubRoutineSet.cpp b/Source/JavaScriptCore/heap/JITStubRoutineSet.cpp index 5e4ca36e0..a37dc6f5c 100644 --- a/Source/JavaScriptCore/heap/JITStubRoutineSet.cpp +++ b/Source/JavaScriptCore/heap/JITStubRoutineSet.cpp @@ -82,7 +82,7 @@ void JITStubRoutineSet::markSlow(uintptr_t address) if (iter == m_addressToRoutineMap.end()) return; - iter->second->m_mayBeExecuting = true; + iter->value->m_mayBeExecuting = true; } void JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines() @@ -97,7 +97,7 @@ void JITStubRoutineSet::deleteUnmarkedJettisonedStubRoutines() uintptr_t step = JITStubRoutine::addressStep(); for (uintptr_t iter = start; iter < end; iter += step) { ASSERT(m_addressToRoutineMap.find(iter) != m_addressToRoutineMap.end()); - ASSERT(m_addressToRoutineMap.find(iter)->second == routine); + ASSERT(m_addressToRoutineMap.find(iter)->value == routine); m_addressToRoutineMap.remove(iter); } diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.cpp b/Source/JavaScriptCore/heap/MarkedAllocator.cpp index 8a7d02e21..466c9fffe 100644 --- a/Source/JavaScriptCore/heap/MarkedAllocator.cpp +++ b/Source/JavaScriptCore/heap/MarkedAllocator.cpp @@ -30,17 +30,6 @@ bool MarkedAllocator::isPagedOut(double deadline) inline void* MarkedAllocator::tryAllocateHelper(size_t bytes) { if (!m_freeList.head) { - if (m_onlyContainsStructures && !m_heap->isSafeToSweepStructures()) { - if (m_currentBlock) { - m_currentBlock->didConsumeFreeList(); - m_currentBlock = 0; - } - // We sweep another random block here so that we can make progress - // toward being able to sweep Structures. - m_heap->sweeper()->sweepNextBlock(); - return 0; - } - for (MarkedBlock*& block = m_blocksToSweep; block; block = block->next()) { MarkedBlock::FreeList freeList = block->sweep(MarkedBlock::SweepToFreeList); if (!freeList.head) { @@ -122,15 +111,9 @@ MarkedBlock* MarkedAllocator::allocateBlock(size_t bytes) size_t cellSize = m_cellSize ? m_cellSize : WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes); - if (blockSize == MarkedBlock::blockSize) { - PageAllocationAligned allocation = m_heap->blockAllocator().allocate(); - return MarkedBlock::create(allocation, m_heap, cellSize, m_cellsNeedDestruction, m_onlyContainsStructures); - } - - PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, MarkedBlock::blockSize, OSAllocator::JSGCHeapPages); - if (!static_cast<bool>(allocation)) - CRASH(); - return MarkedBlock::create(allocation, m_heap, cellSize, m_cellsNeedDestruction, m_onlyContainsStructures); + if (blockSize == MarkedBlock::blockSize) + return MarkedBlock::create(m_heap->blockAllocator().allocate<MarkedBlock>(), this, cellSize, m_destructorType); + return MarkedBlock::create(m_heap->blockAllocator().allocateCustomSize(blockSize, MarkedBlock::blockSize), this, cellSize, m_destructorType); } void MarkedAllocator::addBlock(MarkedBlock* block) diff --git a/Source/JavaScriptCore/heap/MarkedAllocator.h b/Source/JavaScriptCore/heap/MarkedAllocator.h index f9cb6ae52..13bd8e493 100644 --- a/Source/JavaScriptCore/heap/MarkedAllocator.h +++ b/Source/JavaScriptCore/heap/MarkedAllocator.h @@ -23,8 +23,7 @@ public: void reset(); void canonicalizeCellLivenessData(); size_t cellSize() { return m_cellSize; } - bool cellsNeedDestruction() { return m_cellsNeedDestruction; } - bool onlyContainsStructures() { return m_onlyContainsStructures; } + MarkedBlock::DestructorType destructorType() { return m_destructorType; } void* allocate(size_t); Heap* heap() { return m_heap; } @@ -32,7 +31,7 @@ public: void addBlock(MarkedBlock*); void removeBlock(MarkedBlock*); - void init(Heap*, MarkedSpace*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures); + void init(Heap*, MarkedSpace*, size_t cellSize, MarkedBlock::DestructorType); bool isPagedOut(double deadline); @@ -49,8 +48,7 @@ private: MarkedBlock* m_blocksToSweep; DoublyLinkedList<MarkedBlock> m_blockList; size_t m_cellSize; - bool m_cellsNeedDestruction; - bool m_onlyContainsStructures; + MarkedBlock::DestructorType m_destructorType; Heap* m_heap; MarkedSpace* m_markedSpace; }; @@ -59,20 +57,18 @@ inline MarkedAllocator::MarkedAllocator() : m_currentBlock(0) , m_blocksToSweep(0) , m_cellSize(0) - , m_cellsNeedDestruction(true) - , m_onlyContainsStructures(false) + , m_destructorType(MarkedBlock::None) , m_heap(0) , m_markedSpace(0) { } -inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures) +inline void MarkedAllocator::init(Heap* heap, MarkedSpace* markedSpace, size_t cellSize, MarkedBlock::DestructorType destructorType) { m_heap = heap; m_markedSpace = markedSpace; m_cellSize = cellSize; - m_cellsNeedDestruction = cellsNeedDestruction; - m_onlyContainsStructures = onlyContainsStructures; + m_destructorType = destructorType; } inline void* MarkedAllocator::allocate(size_t bytes) diff --git a/Source/JavaScriptCore/heap/MarkedBlock.cpp b/Source/JavaScriptCore/heap/MarkedBlock.cpp index c345080fe..70a24b6ae 100644 --- a/Source/JavaScriptCore/heap/MarkedBlock.cpp +++ b/Source/JavaScriptCore/heap/MarkedBlock.cpp @@ -28,26 +28,27 @@ #include "IncrementalSweeper.h" #include "JSCell.h" -#include "JSObject.h" +#include "JSDestructibleObject.h" namespace JSC { -MarkedBlock* MarkedBlock::create(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures) +MarkedBlock* MarkedBlock::create(DeadBlock* block, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType) { - return new (NotNull, allocation.base()) MarkedBlock(allocation, heap, cellSize, cellsNeedDestruction, onlyContainsStructures); + Region* region = block->region(); + return new (NotNull, block) MarkedBlock(region, allocator, cellSize, destructorType); } -MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures) - : HeapBlock<MarkedBlock>(allocation) +MarkedBlock::MarkedBlock(Region* region, MarkedAllocator* allocator, size_t cellSize, DestructorType destructorType) + : HeapBlock<MarkedBlock>(region) , m_atomsPerCell((cellSize + atomSize - 1) / atomSize) - , m_endAtom(atomsPerBlock - m_atomsPerCell + 1) - , m_cellsNeedDestruction(cellsNeedDestruction) - , m_onlyContainsStructures(onlyContainsStructures) + , m_endAtom((allocator->cellSize() ? atomsPerBlock : region->blockSize() / atomSize) - m_atomsPerCell + 1) + , m_destructorType(destructorType) + , m_allocator(allocator) , m_state(New) // All cells start out unmarked. - , m_weakSet(heap->globalData()) + , m_weakSet(allocator->heap()->globalData()) { - ASSERT(heap); + ASSERT(allocator); HEAP_LOG_BLOCK_STATE_TRANSITION(this); } @@ -65,11 +66,11 @@ inline void MarkedBlock::callDestructor(JSCell* cell) cell->zap(); } -template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, bool destructorCallNeeded> +template<MarkedBlock::BlockState blockState, MarkedBlock::SweepMode sweepMode, MarkedBlock::DestructorType dtorType> MarkedBlock::FreeList MarkedBlock::specializedSweep() { ASSERT(blockState != Allocated && blockState != FreeListed); - ASSERT(destructorCallNeeded || sweepMode != SweepOnly); + ASSERT(!(dtorType == MarkedBlock::None && sweepMode == SweepOnly)); // This produces a free list that is ordered in reverse through the block. // This is fine, since the allocation code makes no assumptions about the @@ -82,7 +83,7 @@ MarkedBlock::FreeList MarkedBlock::specializedSweep() JSCell* cell = reinterpret_cast_ptr<JSCell*>(&atoms()[i]); - if (destructorCallNeeded && blockState != New) + if (dtorType != MarkedBlock::None && blockState != New) callDestructor(cell); if (sweepMode == SweepToFreeList) { @@ -103,21 +104,23 @@ MarkedBlock::FreeList MarkedBlock::sweep(SweepMode sweepMode) m_weakSet.sweep(); - if (sweepMode == SweepOnly && !m_cellsNeedDestruction) + if (sweepMode == SweepOnly && m_destructorType == MarkedBlock::None) return FreeList(); - if (m_cellsNeedDestruction) - return sweepHelper<true>(sweepMode); - return sweepHelper<false>(sweepMode); + if (m_destructorType == MarkedBlock::ImmortalStructure) + return sweepHelper<MarkedBlock::ImmortalStructure>(sweepMode); + if (m_destructorType == MarkedBlock::Normal) + return sweepHelper<MarkedBlock::Normal>(sweepMode); + return sweepHelper<MarkedBlock::None>(sweepMode); } -template<bool destructorCallNeeded> +template<MarkedBlock::DestructorType dtorType> MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode) { switch (m_state) { case New: ASSERT(sweepMode == SweepToFreeList); - return specializedSweep<New, SweepToFreeList, destructorCallNeeded>(); + return specializedSweep<New, SweepToFreeList, dtorType>(); case FreeListed: // Happens when a block transitions to fully allocated. ASSERT(sweepMode == SweepToFreeList); @@ -126,10 +129,9 @@ MarkedBlock::FreeList MarkedBlock::sweepHelper(SweepMode sweepMode) ASSERT_NOT_REACHED(); return FreeList(); case Marked: - ASSERT(!m_onlyContainsStructures || heap()->isSafeToSweepStructures()); return sweepMode == SweepToFreeList - ? specializedSweep<Marked, SweepToFreeList, destructorCallNeeded>() - : specializedSweep<Marked, SweepOnly, destructorCallNeeded>(); + ? specializedSweep<Marked, SweepToFreeList, dtorType>() + : specializedSweep<Marked, SweepOnly, dtorType>(); } ASSERT_NOT_REACHED(); diff --git a/Source/JavaScriptCore/heap/MarkedBlock.h b/Source/JavaScriptCore/heap/MarkedBlock.h index 4b2a5fd53..31bf60b9f 100644 --- a/Source/JavaScriptCore/heap/MarkedBlock.h +++ b/Source/JavaScriptCore/heap/MarkedBlock.h @@ -22,6 +22,7 @@ #ifndef MarkedBlock_h #define MarkedBlock_h +#include "BlockAllocator.h" #include "CardSet.h" #include "HeapBlock.h" @@ -52,6 +53,7 @@ namespace JSC { class Heap; class JSCell; + class MarkedAllocator; typedef uintptr_t Bits; @@ -112,7 +114,8 @@ namespace JSC { ReturnType m_count; }; - static MarkedBlock* create(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures); + enum DestructorType { None, ImmortalStructure, Normal }; + static MarkedBlock* create(DeadBlock*, MarkedAllocator*, size_t cellSize, DestructorType); static bool isAtomAligned(const void*); static MarkedBlock* blockFor(const void*); @@ -120,6 +123,7 @@ namespace JSC { void lastChanceToFinalize(); + MarkedAllocator* allocator() const; Heap* heap() const; JSGlobalData* globalData() const; WeakSet& weakSet(); @@ -143,8 +147,7 @@ namespace JSC { bool isEmpty(); size_t cellSize(); - bool cellsNeedDestruction(); - bool onlyContainsStructures(); + DestructorType destructorType(); size_t size(); size_t capacity(); @@ -194,15 +197,15 @@ namespace JSC { static const size_t atomAlignmentMask = atomSize - 1; // atomSize must be a power of two. enum BlockState { New, FreeListed, Allocated, Marked }; - template<bool destructorCallNeeded> FreeList sweepHelper(SweepMode = SweepOnly); + template<DestructorType> FreeList sweepHelper(SweepMode = SweepOnly); typedef char Atom[atomSize]; - MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize, bool cellsNeedDestruction, bool onlyContainsStructures); + MarkedBlock(Region*, MarkedAllocator*, size_t cellSize, DestructorType); Atom* atoms(); size_t atomNumber(const void*); void callDestructor(JSCell*); - template<BlockState, SweepMode, bool destructorCallNeeded> FreeList specializedSweep(); + template<BlockState, SweepMode, DestructorType> FreeList specializedSweep(); #if ENABLE(GGC) CardSet<bytesPerCard, blockSize> m_cards; @@ -215,8 +218,8 @@ namespace JSC { #else WTF::Bitmap<atomsPerBlock, WTF::BitmapNotAtomic> m_marks; #endif - bool m_cellsNeedDestruction; - bool m_onlyContainsStructures; + DestructorType m_destructorType; + MarkedAllocator* m_allocator; BlockState m_state; WeakSet m_weakSet; }; @@ -261,6 +264,11 @@ namespace JSC { sweep(); } + inline MarkedAllocator* MarkedBlock::allocator() const + { + return m_allocator; + } + inline Heap* MarkedBlock::heap() const { return m_weakSet.heap(); @@ -326,14 +334,9 @@ namespace JSC { return m_atomsPerCell * atomSize; } - inline bool MarkedBlock::cellsNeedDestruction() - { - return m_cellsNeedDestruction; - } - - inline bool MarkedBlock::onlyContainsStructures() + inline MarkedBlock::DestructorType MarkedBlock::destructorType() { - return m_onlyContainsStructures; + return m_destructorType; } inline size_t MarkedBlock::size() @@ -343,7 +346,7 @@ namespace JSC { inline size_t MarkedBlock::capacity() { - return allocation().size(); + return region()->blockSize(); } inline size_t MarkedBlock::atomNumber(const void* p) diff --git a/Source/JavaScriptCore/heap/MarkedSpace.cpp b/Source/JavaScriptCore/heap/MarkedSpace.cpp index 9a823c50b..50634dd23 100644 --- a/Source/JavaScriptCore/heap/MarkedSpace.cpp +++ b/Source/JavaScriptCore/heap/MarkedSpace.cpp @@ -81,17 +81,20 @@ MarkedSpace::MarkedSpace(Heap* heap) : m_heap(heap) { for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { - allocatorFor(cellSize).init(heap, this, cellSize, false, false); - destructorAllocatorFor(cellSize).init(heap, this, cellSize, true, false); + allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None); + normalDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::Normal); + immortalStructureDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::ImmortalStructure); } for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { - allocatorFor(cellSize).init(heap, this, cellSize, false, false); - destructorAllocatorFor(cellSize).init(heap, this, cellSize, true, false); + allocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::None); + normalDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::Normal); + immortalStructureDestructorAllocatorFor(cellSize).init(heap, this, cellSize, MarkedBlock::ImmortalStructure); } - m_largeAllocator.init(heap, this, 0, true, false); - m_structureAllocator.init(heap, this, WTF::roundUpToMultipleOf(32, sizeof(Structure)), true, true); + m_normalSpace.largeAllocator.init(heap, this, 0, MarkedBlock::None); + m_normalDestructorSpace.largeAllocator.init(heap, this, 0, MarkedBlock::Normal); + m_immortalStructureDestructorSpace.largeAllocator.init(heap, this, 0, MarkedBlock::ImmortalStructure); } MarkedSpace::~MarkedSpace() @@ -120,16 +123,19 @@ void MarkedSpace::resetAllocators() { for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { allocatorFor(cellSize).reset(); - destructorAllocatorFor(cellSize).reset(); + normalDestructorAllocatorFor(cellSize).reset(); + immortalStructureDestructorAllocatorFor(cellSize).reset(); } for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { allocatorFor(cellSize).reset(); - destructorAllocatorFor(cellSize).reset(); + normalDestructorAllocatorFor(cellSize).reset(); + immortalStructureDestructorAllocatorFor(cellSize).reset(); } - m_largeAllocator.reset(); - m_structureAllocator.reset(); + m_normalSpace.largeAllocator.reset(); + m_normalDestructorSpace.largeAllocator.reset(); + m_immortalStructureDestructorSpace.largeAllocator.reset(); } void MarkedSpace::visitWeakSets(HeapRootVisitor& heapRootVisitor) @@ -147,34 +153,40 @@ void MarkedSpace::canonicalizeCellLivenessData() { for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { allocatorFor(cellSize).canonicalizeCellLivenessData(); - destructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); + normalDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); + immortalStructureDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); } for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { allocatorFor(cellSize).canonicalizeCellLivenessData(); - destructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); + normalDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); + immortalStructureDestructorAllocatorFor(cellSize).canonicalizeCellLivenessData(); } - m_largeAllocator.canonicalizeCellLivenessData(); - m_structureAllocator.canonicalizeCellLivenessData(); + m_normalSpace.largeAllocator.canonicalizeCellLivenessData(); + m_normalDestructorSpace.largeAllocator.canonicalizeCellLivenessData(); + m_immortalStructureDestructorSpace.largeAllocator.canonicalizeCellLivenessData(); } bool MarkedSpace::isPagedOut(double deadline) { for (size_t cellSize = preciseStep; cellSize <= preciseCutoff; cellSize += preciseStep) { - if (allocatorFor(cellSize).isPagedOut(deadline) || destructorAllocatorFor(cellSize).isPagedOut(deadline)) + if (allocatorFor(cellSize).isPagedOut(deadline) + || normalDestructorAllocatorFor(cellSize).isPagedOut(deadline) + || immortalStructureDestructorAllocatorFor(cellSize).isPagedOut(deadline)) return true; } for (size_t cellSize = impreciseStep; cellSize <= impreciseCutoff; cellSize += impreciseStep) { - if (allocatorFor(cellSize).isPagedOut(deadline) || destructorAllocatorFor(cellSize).isPagedOut(deadline)) + if (allocatorFor(cellSize).isPagedOut(deadline) + || normalDestructorAllocatorFor(cellSize).isPagedOut(deadline) + || immortalStructureDestructorAllocatorFor(cellSize).isPagedOut(deadline)) return true; } - if (m_largeAllocator.isPagedOut(deadline)) - return true; - - if (m_structureAllocator.isPagedOut(deadline)) + if (m_normalSpace.largeAllocator.isPagedOut(deadline) + || m_normalDestructorSpace.largeAllocator.isPagedOut(deadline) + || m_immortalStructureDestructorSpace.largeAllocator.isPagedOut(deadline)) return true; return false; @@ -182,14 +194,13 @@ bool MarkedSpace::isPagedOut(double deadline) void MarkedSpace::freeBlock(MarkedBlock* block) { - allocatorFor(block).removeBlock(block); + block->allocator()->removeBlock(block); m_blocks.remove(block); if (block->capacity() == MarkedBlock::blockSize) { m_heap->blockAllocator().deallocate(MarkedBlock::destroy(block)); return; } - - MarkedBlock::destroy(block).deallocate(); + m_heap->blockAllocator().deallocateCustomSize(MarkedBlock::destroy(block)); } void MarkedSpace::freeOrShrinkBlock(MarkedBlock* block) diff --git a/Source/JavaScriptCore/heap/MarkedSpace.h b/Source/JavaScriptCore/heap/MarkedSpace.h index 151099b60..214536ad7 100644 --- a/Source/JavaScriptCore/heap/MarkedSpace.h +++ b/Source/JavaScriptCore/heap/MarkedSpace.h @@ -34,8 +34,6 @@ #include <wtf/Noncopyable.h> #include <wtf/Vector.h> -#define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= MarkedSpace::maxCellSize, class_fits_in_cell) - namespace JSC { class Heap; @@ -68,19 +66,17 @@ struct Capacity : MarkedBlock::CountFunctor { class MarkedSpace { WTF_MAKE_NONCOPYABLE(MarkedSpace); public: - static const size_t maxCellSize = 2048; - MarkedSpace(Heap*); ~MarkedSpace(); void lastChanceToFinalize(); MarkedAllocator& firstAllocator(); MarkedAllocator& allocatorFor(size_t); - MarkedAllocator& allocatorFor(MarkedBlock*); - MarkedAllocator& destructorAllocatorFor(size_t); - void* allocateWithDestructor(size_t); + MarkedAllocator& immortalStructureDestructorAllocatorFor(size_t); + MarkedAllocator& normalDestructorAllocatorFor(size_t); + void* allocateWithNormalDestructor(size_t); + void* allocateWithImmortalStructureDestructor(size_t); void* allocateWithoutDestructor(size_t); - void* allocateStructure(size_t); void resetAllocators(); @@ -131,12 +127,12 @@ private: struct Subspace { FixedArray<MarkedAllocator, preciseCount> preciseAllocators; FixedArray<MarkedAllocator, impreciseCount> impreciseAllocators; + MarkedAllocator largeAllocator; }; - Subspace m_destructorSpace; + Subspace m_normalDestructorSpace; + Subspace m_immortalStructureDestructorSpace; Subspace m_normalSpace; - MarkedAllocator m_largeAllocator; - MarkedAllocator m_structureAllocator; Heap* m_heap; MarkedBlockSet m_blocks; @@ -186,28 +182,27 @@ inline MarkedAllocator& MarkedSpace::allocatorFor(size_t bytes) return m_normalSpace.preciseAllocators[(bytes - 1) / preciseStep]; if (bytes <= impreciseCutoff) return m_normalSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; - return m_largeAllocator; + return m_normalSpace.largeAllocator; } -inline MarkedAllocator& MarkedSpace::allocatorFor(MarkedBlock* block) +inline MarkedAllocator& MarkedSpace::immortalStructureDestructorAllocatorFor(size_t bytes) { - if (block->onlyContainsStructures()) - return m_structureAllocator; - - if (block->cellsNeedDestruction()) - return destructorAllocatorFor(block->cellSize()); - - return allocatorFor(block->cellSize()); + ASSERT(bytes); + if (bytes <= preciseCutoff) + return m_immortalStructureDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep]; + if (bytes <= impreciseCutoff) + return m_immortalStructureDestructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; + return m_immortalStructureDestructorSpace.largeAllocator; } -inline MarkedAllocator& MarkedSpace::destructorAllocatorFor(size_t bytes) +inline MarkedAllocator& MarkedSpace::normalDestructorAllocatorFor(size_t bytes) { ASSERT(bytes); if (bytes <= preciseCutoff) - return m_destructorSpace.preciseAllocators[(bytes - 1) / preciseStep]; + return m_normalDestructorSpace.preciseAllocators[(bytes - 1) / preciseStep]; if (bytes <= impreciseCutoff) - return m_normalSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; - return m_largeAllocator; + return m_normalDestructorSpace.impreciseAllocators[(bytes - 1) / impreciseStep]; + return m_normalDestructorSpace.largeAllocator; } inline void* MarkedSpace::allocateWithoutDestructor(size_t bytes) @@ -215,30 +210,33 @@ inline void* MarkedSpace::allocateWithoutDestructor(size_t bytes) return allocatorFor(bytes).allocate(bytes); } -inline void* MarkedSpace::allocateWithDestructor(size_t bytes) +inline void* MarkedSpace::allocateWithImmortalStructureDestructor(size_t bytes) { - return destructorAllocatorFor(bytes).allocate(bytes); + return immortalStructureDestructorAllocatorFor(bytes).allocate(bytes); } -inline void* MarkedSpace::allocateStructure(size_t bytes) +inline void* MarkedSpace::allocateWithNormalDestructor(size_t bytes) { - return m_structureAllocator.allocate(bytes); + return normalDestructorAllocatorFor(bytes).allocate(bytes); } template <typename Functor> inline typename Functor::ReturnType MarkedSpace::forEachBlock(Functor& functor) { for (size_t i = 0; i < preciseCount; ++i) { m_normalSpace.preciseAllocators[i].forEachBlock(functor); - m_destructorSpace.preciseAllocators[i].forEachBlock(functor); + m_normalDestructorSpace.preciseAllocators[i].forEachBlock(functor); + m_immortalStructureDestructorSpace.preciseAllocators[i].forEachBlock(functor); } for (size_t i = 0; i < impreciseCount; ++i) { m_normalSpace.impreciseAllocators[i].forEachBlock(functor); - m_destructorSpace.impreciseAllocators[i].forEachBlock(functor); + m_normalDestructorSpace.impreciseAllocators[i].forEachBlock(functor); + m_immortalStructureDestructorSpace.impreciseAllocators[i].forEachBlock(functor); } - m_largeAllocator.forEachBlock(functor); - m_structureAllocator.forEachBlock(functor); + m_normalSpace.largeAllocator.forEachBlock(functor); + m_normalDestructorSpace.largeAllocator.forEachBlock(functor); + m_immortalStructureDestructorSpace.largeAllocator.forEachBlock(functor); return functor.returnValue(); } diff --git a/Source/JavaScriptCore/heap/SlotVisitor.cpp b/Source/JavaScriptCore/heap/SlotVisitor.cpp index 0f003e79d..26d056feb 100644 --- a/Source/JavaScriptCore/heap/SlotVisitor.cpp +++ b/Source/JavaScriptCore/heap/SlotVisitor.cpp @@ -4,7 +4,9 @@ #include "ConservativeRoots.h" #include "CopiedSpace.h" #include "CopiedSpaceInlineMethods.h" +#include "GCThread.h" #include "JSArray.h" +#include "JSDestructibleObject.h" #include "JSGlobalData.h" #include "JSObject.h" #include "JSString.h" @@ -34,8 +36,8 @@ void SlotVisitor::setup() m_shared.m_shouldHashConst = m_shared.m_globalData->haveEnoughNewStringsToHashConst(); m_shouldHashConst = m_shared.m_shouldHashConst; #if ENABLE(PARALLEL_GC) - for (unsigned i = 0; i < m_shared.m_markingThreadsMarkStack.size(); ++i) - m_shared.m_markingThreadsMarkStack[i]->m_shouldHashConst = m_shared.m_shouldHashConst; + for (unsigned i = 0; i < m_shared.m_gcThreads.size(); ++i) + m_shared.m_gcThreads[i]->slotVisitor()->m_shouldHashConst = m_shared.m_shouldHashConst; #endif } @@ -180,7 +182,7 @@ void SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode) while (true) { // Did we reach termination? if (!m_shared.m_numberOfActiveParallelMarkers && m_shared.m_sharedMarkStack.isEmpty()) { - // Let any sleeping slaves know it's time for them to give their private CopiedBlocks back + // Let any sleeping slaves know it's time for them to return; m_shared.m_markingCondition.broadcast(); return; } @@ -199,17 +201,12 @@ void SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode) if (!m_shared.m_numberOfActiveParallelMarkers && m_shared.m_sharedMarkStack.isEmpty()) m_shared.m_markingCondition.broadcast(); - while (m_shared.m_sharedMarkStack.isEmpty() && !m_shared.m_parallelMarkersShouldExit) { - if (!m_shared.m_numberOfActiveParallelMarkers && m_shared.m_sharedMarkStack.isEmpty()) - doneCopying(); + while (m_shared.m_sharedMarkStack.isEmpty() && !m_shared.m_parallelMarkersShouldExit) m_shared.m_markingCondition.wait(m_shared.m_markingLock); - } - // Is the VM exiting? If so, exit this thread. - if (m_shared.m_parallelMarkersShouldExit) { - doneCopying(); + // Is the current phase done? If so, return from this function. + if (m_shared.m_parallelMarkersShouldExit) return; - } } size_t idleThreadCount = Options::numberOfGCMarkers() - m_shared.m_numberOfActiveParallelMarkers; @@ -235,30 +232,6 @@ void SlotVisitor::mergeOpaqueRoots() m_opaqueRoots.clear(); } -void SlotVisitor::startCopying() -{ - ASSERT(!m_copiedAllocator.isValid()); -} - -void* SlotVisitor::allocateNewSpaceSlow(size_t bytes) -{ - m_shared.m_copiedSpace->doneFillingBlock(m_copiedAllocator.resetCurrentBlock()); - m_copiedAllocator.setCurrentBlock(m_shared.m_copiedSpace->allocateBlockForCopyingPhase()); - - void* result = 0; - CheckedBoolean didSucceed = m_copiedAllocator.tryAllocate(bytes, &result); - ASSERT(didSucceed); - return result; -} - -void* SlotVisitor::allocateNewSpaceOrPin(void* ptr, size_t bytes) -{ - if (!checkIfShouldCopyAndPinOtherwise(ptr, bytes)) - return 0; - - return allocateNewSpace(bytes); -} - ALWAYS_INLINE bool JSString::tryHashConstLock() { #if ENABLE(PARALLEL_GC) @@ -320,7 +293,7 @@ ALWAYS_INLINE void SlotVisitor::internalAppend(JSValue* slot) if (addResult.isNewEntry) string->setHashConstSingleton(); else { - JSValue existingJSValue = addResult.iterator->second; + JSValue existingJSValue = addResult.iterator->value; if (value != existingJSValue) jsCast<JSString*>(existingJSValue.asCell())->clearHashConstSingleton(); *slot = existingJSValue; @@ -334,36 +307,6 @@ ALWAYS_INLINE void SlotVisitor::internalAppend(JSValue* slot) internalAppend(cell); } -void SlotVisitor::copyAndAppend(void** ptr, size_t bytes, JSValue* values, unsigned length) -{ - void* oldPtr = *ptr; - void* newPtr = allocateNewSpaceOrPin(oldPtr, bytes); - if (newPtr) { - size_t jsValuesOffset = static_cast<size_t>(reinterpret_cast<char*>(values) - static_cast<char*>(oldPtr)); - - JSValue* newValues = reinterpret_cast_ptr<JSValue*>(static_cast<char*>(newPtr) + jsValuesOffset); - for (unsigned i = 0; i < length; i++) { - JSValue& value = values[i]; - newValues[i] = value; - if (!value) - continue; - internalAppend(&newValues[i]); - } - - memcpy(newPtr, oldPtr, jsValuesOffset); - *ptr = newPtr; - } else - append(values, length); -} - -void SlotVisitor::doneCopying() -{ - if (!m_copiedAllocator.isValid()) - return; - - m_shared.m_copiedSpace->doneFillingBlock(m_copiedAllocator.resetCurrentBlock()); -} - void SlotVisitor::harvestWeakReferences() { for (WeakReferenceHarvester* current = m_shared.m_weakReferenceHarvesters.head(); current; current = current->next()) diff --git a/Source/JavaScriptCore/heap/SlotVisitor.h b/Source/JavaScriptCore/heap/SlotVisitor.h index 230ed3334..dcd4b75ef 100644 --- a/Source/JavaScriptCore/heap/SlotVisitor.h +++ b/Source/JavaScriptCore/heap/SlotVisitor.h @@ -26,7 +26,6 @@ #ifndef SlotVisitor_h #define SlotVisitor_h -#include "CopiedSpace.h" #include "HandleTypes.h" #include "MarkStackInlineMethods.h" @@ -80,21 +79,8 @@ public: void harvestWeakReferences(); void finalizeUnconditionalFinalizers(); - void startCopying(); + void copyLater(void*, size_t); - // High-level API for copying, appropriate for cases where the object's heap references - // fall into a contiguous region of the storage chunk and if the object for which you're - // doing copying does not occur frequently. - void copyAndAppend(void**, size_t, JSValue*, unsigned); - - // Low-level API for copying, appropriate for cases where the object's heap references - // are discontiguous or if the object occurs frequently enough that you need to focus on - // performance. Use this with care as it is easy to shoot yourself in the foot. - bool checkIfShouldCopyAndPinOtherwise(void* oldPtr, size_t); - void* allocateNewSpace(size_t); - - void doneCopying(); - #if ENABLE(SIMPLE_HEAP_PROFILING) VTableSpectrum m_visitedTypeCounts; #endif @@ -125,9 +111,6 @@ private: void mergeOpaqueRootsIfNecessary(); void mergeOpaqueRootsIfProfitable(); - void* allocateNewSpaceOrPin(void*, size_t); - void* allocateNewSpaceSlow(size_t); - void donateKnownParallel(); MarkStackArray m_stack; @@ -146,8 +129,6 @@ private: unsigned m_logChildCount; #endif - CopiedAllocator m_copiedAllocator; - public: #if !ASSERT_DISABLED bool m_isCheckingForDefaultMarkViolation; diff --git a/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h b/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h index 540da3bc4..e5908bf36 100644 --- a/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h +++ b/Source/JavaScriptCore/heap/SlotVisitorInlineMethods.h @@ -136,30 +136,6 @@ inline void SlotVisitor::mergeOpaqueRootsIfProfitable() mergeOpaqueRoots(); } -ALWAYS_INLINE bool SlotVisitor::checkIfShouldCopyAndPinOtherwise(void* oldPtr, size_t bytes) -{ - if (CopiedSpace::isOversize(bytes)) { - m_shared.m_copiedSpace->pin(CopiedSpace::oversizeBlockFor(oldPtr)); - return false; - } - - if (m_shared.m_copiedSpace->isPinned(oldPtr)) - return false; - - return true; -} - -ALWAYS_INLINE void* SlotVisitor::allocateNewSpace(size_t bytes) -{ - void* result = 0; // Compilers don't realize that this will be assigned. - if (LIKELY(m_copiedAllocator.tryAllocate(bytes, &result))) - return result; - - result = allocateNewSpaceSlow(bytes); - ASSERT(result); - return result; -} - inline void SlotVisitor::donate() { ASSERT(m_isInParallelMode); @@ -175,6 +151,23 @@ inline void SlotVisitor::donateAndDrain() drain(); } +inline void SlotVisitor::copyLater(void* ptr, size_t bytes) +{ + if (CopiedSpace::isOversize(bytes)) { + m_shared.m_copiedSpace->pin(CopiedSpace::oversizeBlockFor(ptr)); + return; + } + + CopiedBlock* block = CopiedSpace::blockFor(ptr); + if (block->isPinned()) + return; + + block->reportLiveBytes(bytes); + + if (!block->shouldEvacuate()) + m_shared.m_copiedSpace->pin(block); +} + } // namespace JSC #endif // SlotVisitorInlineMethods_h diff --git a/Source/JavaScriptCore/heap/Weak.h b/Source/JavaScriptCore/heap/Weak.h index 07698fd06..3c3d1d0ce 100644 --- a/Source/JavaScriptCore/heap/Weak.h +++ b/Source/JavaScriptCore/heap/Weak.h @@ -164,8 +164,8 @@ template<typename Map, typename Key, typename Value> inline void weakRemove(Map& typename Map::iterator it = map.find(key); ASSERT_UNUSED(value, value); ASSERT(it != map.end()); - ASSERT(it->second.was(value)); - ASSERT(!it->second); + ASSERT(it->value.was(value)); + ASSERT(!it->value); map.remove(it); } diff --git a/Source/JavaScriptCore/interpreter/CallFrame.cpp b/Source/JavaScriptCore/interpreter/CallFrame.cpp index 63bc93aeb..6dcf354b3 100644 --- a/Source/JavaScriptCore/interpreter/CallFrame.cpp +++ b/Source/JavaScriptCore/interpreter/CallFrame.cpp @@ -43,9 +43,9 @@ void CallFrame::dumpCaller() dataLog("Callpoint => %s:%d\n", urlString.utf8().data(), signedLineNumber); } -RegisterFile* CallFrame::registerFile() +JSStack* CallFrame::stack() { - return &interpreter()->registerFile(); + return &interpreter()->stack(); } #endif diff --git a/Source/JavaScriptCore/interpreter/CallFrame.h b/Source/JavaScriptCore/interpreter/CallFrame.h index 4758e5bd0..7aa49a9b0 100644 --- a/Source/JavaScriptCore/interpreter/CallFrame.h +++ b/Source/JavaScriptCore/interpreter/CallFrame.h @@ -25,8 +25,8 @@ #include "AbstractPC.h" #include "JSGlobalData.h" +#include "JSStack.h" #include "MacroAssemblerCodeRef.h" -#include "RegisterFile.h" namespace JSC { @@ -39,13 +39,13 @@ namespace JSC { // Passed as the first argument to most functions. class ExecState : private Register { public: - JSValue calleeAsValue() const { return this[RegisterFile::Callee].jsValue(); } - JSObject* callee() const { return this[RegisterFile::Callee].function(); } - CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); } + JSValue calleeAsValue() const { return this[JSStack::Callee].jsValue(); } + JSObject* callee() const { return this[JSStack::Callee].function(); } + CodeBlock* codeBlock() const { return this[JSStack::CodeBlock].Register::codeBlock(); } JSScope* scope() const { - ASSERT(this[RegisterFile::ScopeChain].Register::scope()); - return this[RegisterFile::ScopeChain].Register::scope(); + ASSERT(this[JSStack::ScopeChain].Register::scope()); + return this[JSStack::ScopeChain].Register::scope(); } // Global object in which execution began. @@ -102,11 +102,11 @@ namespace JSC { CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; } - CallFrame* callerFrame() const { return this[RegisterFile::CallerFrame].callFrame(); } + CallFrame* callerFrame() const { return this[JSStack::CallerFrame].callFrame(); } #if ENABLE(JIT) || ENABLE(LLINT) - ReturnAddressPtr returnPC() const { return ReturnAddressPtr(this[RegisterFile::ReturnPC].vPC()); } - bool hasReturnPC() const { return !!this[RegisterFile::ReturnPC].vPC(); } - void clearReturnPC() { registers()[RegisterFile::ReturnPC] = static_cast<Instruction*>(0); } + ReturnAddressPtr returnPC() const { return ReturnAddressPtr(this[JSStack::ReturnPC].vPC()); } + bool hasReturnPC() const { return !!this[JSStack::ReturnPC].vPC(); } + void clearReturnPC() { registers()[JSStack::ReturnPC] = static_cast<Instruction*>(0); } #endif AbstractPC abstractReturnPC(JSGlobalData& globalData) { return AbstractPC(globalData, this); } #if USE(JSVALUE32_64) @@ -116,13 +116,13 @@ namespace JSC { unsigned bytecodeOffsetForNonDFGCode() const { ASSERT(codeBlock()); - return this[RegisterFile::ArgumentCount].tag(); + return this[JSStack::ArgumentCount].tag(); } void setBytecodeOffsetForNonDFGCode(unsigned offset) { ASSERT(codeBlock()); - this[RegisterFile::ArgumentCount].tag() = static_cast<int32_t>(offset); + this[JSStack::ArgumentCount].tag() = static_cast<int32_t>(offset); } #endif @@ -136,8 +136,8 @@ namespace JSC { Register* frameExtentInternal(); #if ENABLE(DFG_JIT) - InlineCallFrame* inlineCallFrame() const { return this[RegisterFile::ReturnPC].asInlineCallFrame(); } - unsigned codeOriginIndexForDFG() const { return this[RegisterFile::ArgumentCount].tag(); } + InlineCallFrame* inlineCallFrame() const { return this[JSStack::ReturnPC].asInlineCallFrame(); } + unsigned codeOriginIndexForDFG() const { return this[JSStack::ArgumentCount].tag(); } #else // This will never be called if !ENABLE(DFG_JIT) since all calls should be guarded by // isInlineCallFrame(). But to make it easier to write code without having a bunch of @@ -151,25 +151,25 @@ namespace JSC { #if USE(JSVALUE32_64) Instruction* currentVPC() const { - return bitwise_cast<Instruction*>(this[RegisterFile::ArgumentCount].tag()); + return bitwise_cast<Instruction*>(this[JSStack::ArgumentCount].tag()); } void setCurrentVPC(Instruction* vpc) { - this[RegisterFile::ArgumentCount].tag() = bitwise_cast<int32_t>(vpc); + this[JSStack::ArgumentCount].tag() = bitwise_cast<int32_t>(vpc); } #else Instruction* currentVPC() const; void setCurrentVPC(Instruction* vpc); #endif - void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; } - void setScope(JSScope* scope) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scope; } + void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[JSStack::CallerFrame] = callerFrame; } + void setScope(JSScope* scope) { static_cast<Register*>(this)[JSStack::ScopeChain] = scope; } ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, JSScope* scope, CallFrame* callerFrame, int argc, JSObject* callee) { ASSERT(callerFrame); // Use noCaller() rather than 0 for the outer host call frame caller. - ASSERT(callerFrame == noCaller() || callerFrame->removeHostCallFrameFlag()->registerFile()->end() >= this); + ASSERT(callerFrame == noCaller() || callerFrame->removeHostCallFrameFlag()->stack()->end() >= this); setCodeBlock(codeBlock); setScope(scope); @@ -186,10 +186,19 @@ namespace JSC { // Access to arguments as passed. (After capture, arguments may move to a different location.) size_t argumentCount() const { return argumentCountIncludingThis() - 1; } - size_t argumentCountIncludingThis() const { return this[RegisterFile::ArgumentCount].payload(); } + size_t argumentCountIncludingThis() const { return this[JSStack::ArgumentCount].payload(); } static int argumentOffset(int argument) { return s_firstArgumentOffset - argument; } static int argumentOffsetIncludingThis(int argument) { return s_thisArgumentOffset - argument; } + // In the following (argument() and setArgument()), the 'argument' + // parameter is the index of the arguments of the target function of + // this frame. The index starts at 0 for the first arg, 1 for the + // second, etc. + // + // The arguments (in this case) do not include the 'this' value. + // arguments(0) will not fetch the 'this' value. To get/set 'this', + // use thisValue() and setThisValue() below. + JSValue argument(size_t argument) { if (argument >= argumentCount()) @@ -207,7 +216,7 @@ namespace JSC { JSValue argumentAfterCapture(size_t argument); - static int offsetFor(size_t argumentCountIncludingThis) { return argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize; } + static int offsetFor(size_t argumentCountIncludingThis) { return argumentCountIncludingThis + JSStack::CallFrameHeaderSize; } // FIXME: Remove these. int hostThisRegister() { return thisArgumentOffset(); } @@ -219,15 +228,15 @@ namespace JSC { CallFrame* addHostCallFrameFlag() const { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) | HostCallFrameFlag); } CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); } - void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[RegisterFile::ArgumentCount].payload() = count; } - void setCallee(JSObject* callee) { static_cast<Register*>(this)[RegisterFile::Callee] = Register::withCallee(callee); } - void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[RegisterFile::CodeBlock] = codeBlock; } - void setReturnPC(void* value) { static_cast<Register*>(this)[RegisterFile::ReturnPC] = (Instruction*)value; } + void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[JSStack::ArgumentCount].payload() = count; } + void setCallee(JSObject* callee) { static_cast<Register*>(this)[JSStack::Callee] = Register::withCallee(callee); } + void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[JSStack::CodeBlock] = codeBlock; } + void setReturnPC(void* value) { static_cast<Register*>(this)[JSStack::ReturnPC] = (Instruction*)value; } #if ENABLE(DFG_JIT) bool isInlineCallFrame(); - void setInlineCallFrame(InlineCallFrame* inlineCallFrame) { static_cast<Register*>(this)[RegisterFile::ReturnPC] = inlineCallFrame; } + void setInlineCallFrame(InlineCallFrame* inlineCallFrame) { static_cast<Register*>(this)[JSStack::ReturnPC] = inlineCallFrame; } // Call this to get the semantically correct JS CallFrame* for the // currently executing function. @@ -260,11 +269,11 @@ namespace JSC { private: static const intptr_t HostCallFrameFlag = 1; - static const int s_thisArgumentOffset = -1 - RegisterFile::CallFrameHeaderSize; + static const int s_thisArgumentOffset = -1 - JSStack::CallFrameHeaderSize; static const int s_firstArgumentOffset = s_thisArgumentOffset - 1; #ifndef NDEBUG - RegisterFile* registerFile(); + JSStack* stack(); #endif #if ENABLE(DFG_JIT) bool isInlineCallFrameSlow(); diff --git a/Source/JavaScriptCore/interpreter/CallFrameClosure.h b/Source/JavaScriptCore/interpreter/CallFrameClosure.h index 125193258..157d1b3b9 100644 --- a/Source/JavaScriptCore/interpreter/CallFrameClosure.h +++ b/Source/JavaScriptCore/interpreter/CallFrameClosure.h @@ -52,7 +52,11 @@ struct CallFrameClosure { void resetCallFrame() { newCallFrame->setScope(scope); - for (int i = argumentCountIncludingThis; i < parameterCountIncludingThis; ++i) + // setArgument() takes an arg index that starts from 0 for the first + // argument after the 'this' value. Since both argumentCountIncludingThis + // and parameterCountIncludingThis includes the 'this' value, we need to + // subtract 1 from them to make i a valid argument index for setArgument(). + for (int i = argumentCountIncludingThis-1; i < parameterCountIncludingThis-1; ++i) newCallFrame->setArgument(i, jsUndefined()); } }; diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp index 3107a5dab..00b283393 100644 --- a/Source/JavaScriptCore/interpreter/Interpreter.cpp +++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp @@ -88,10 +88,10 @@ static int depth(CodeBlock* codeBlock, JSScope* sc) return sc->localDepth(); } -ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argumentCountIncludingThis) +ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, JSStack* stack, CallFrame* callFrame, size_t registerOffset, int argumentCountIncludingThis) { // This ensures enough space for the worst case scenario of zero arguments passed by the caller. - if (!registerFile->grow(callFrame->registers() + registerOffset + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters)) + if (!stack->grow(callFrame->registers() + registerOffset + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters)) return 0; if (argumentCountIncludingThis >= newCodeBlock->numParameters()) { @@ -163,15 +163,15 @@ JSValue eval(CallFrame* callFrame) JSValue thisValue = callerFrame->thisValue(); ASSERT(isValidThisObject(thisValue, callFrame)); Interpreter* interpreter = callFrame->globalData().interpreter; - return interpreter->execute(eval, callFrame, thisValue, callerScopeChain, callFrame->registers() - interpreter->registerFile().begin() + 1 + RegisterFile::CallFrameHeaderSize); + return interpreter->execute(eval, callFrame, thisValue, callerScopeChain, callFrame->registers() - interpreter->stack().begin() + 1 + JSStack::CallFrameHeaderSize); } -CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue thisValue, JSValue arguments, int firstFreeRegister) +CallFrame* loadVarargs(CallFrame* callFrame, JSStack* stack, JSValue thisValue, JSValue arguments, int firstFreeRegister) { if (!arguments) { // f.apply(x, arguments), with arguments unmodified. unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis(); - CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize); - if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !registerFile->grow(newCallFrame->registers())) { + CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize); + if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->grow(newCallFrame->registers())) { callFrame->globalData().exception = createStackOverflowError(callFrame); return 0; } @@ -184,8 +184,8 @@ CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue } if (arguments.isUndefinedOrNull()) { - CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + 1 + RegisterFile::CallFrameHeaderSize); - if (!registerFile->grow(newCallFrame->registers())) { + CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + 1 + JSStack::CallFrameHeaderSize); + if (!stack->grow(newCallFrame->registers())) { callFrame->globalData().exception = createStackOverflowError(callFrame); return 0; } @@ -203,7 +203,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue Arguments* argsObject = asArguments(arguments); unsigned argCount = argsObject->length(callFrame); CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1)); - if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) { + if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) { callFrame->globalData().exception = createStackOverflowError(callFrame); return 0; } @@ -217,7 +217,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue JSArray* array = asArray(arguments); unsigned argCount = array->length(); CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1)); - if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) { + if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) { callFrame->globalData().exception = createStackOverflowError(callFrame); return 0; } @@ -230,7 +230,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue JSObject* argObject = asObject(arguments); unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1)); - if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) { + if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) { callFrame->globalData().exception = createStackOverflowError(callFrame); return 0; } @@ -301,8 +301,8 @@ void Interpreter::dumpRegisters(CallFrame* callFrame) const Register* it; const Register* end; - it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - callFrame->argumentCountIncludingThis(); - end = callFrame->registers() - RegisterFile::CallFrameHeaderSize; + it = callFrame->registers() - JSStack::CallFrameHeaderSize - callFrame->argumentCountIncludingThis(); + end = callFrame->registers() - JSStack::CallFrameHeaderSize; while (it < end) { JSValue v = it->jsValue(); int registerNumber = it - callFrame->registers(); @@ -710,7 +710,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV Register* callerHighWaterMark = callerFrame->registers() + codeBlock->m_numCalleeRegisters; highWaterMark = max(highWaterMark, callerHighWaterMark); } - m_registerFile.shrink(highWaterMark); + m_stack.shrink(highWaterMark); // Unwind the scope chain within the exception handler's call frame. JSScope* scope = callFrame->scope(); @@ -738,8 +738,25 @@ static inline JSObject* checkedReturn(JSObject* returnValue) return returnValue; } +class SamplingScope { +public: + SamplingScope(Interpreter* interpreter) + : m_interpreter(interpreter) + { + interpreter->startSampling(); + } + ~SamplingScope() + { + m_interpreter->stopSampling(); + } +private: + Interpreter* m_interpreter; +}; + JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, JSObject* thisObj) { + SamplingScope samplingScope(this); + JSScope* scope = callFrame->scope(); ASSERT(isValidThisObject(thisObj, callFrame)); ASSERT(!scope->globalData()->exception); @@ -863,13 +880,13 @@ failedJSONP: CodeBlock* codeBlock = &program->generatedBytecode(); // Reserve stack space for this invocation: - Register* oldEnd = m_registerFile.end(); - Register* newEnd = oldEnd + codeBlock->numParameters() + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters; - if (!m_registerFile.grow(newEnd)) + Register* oldEnd = m_stack.end(); + Register* newEnd = oldEnd + codeBlock->numParameters() + JSStack::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters; + if (!m_stack.grow(newEnd)) return checkedReturn(throwStackOverflowError(callFrame)); // Push the call frame for this invocation: - CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->numParameters() + RegisterFile::CallFrameHeaderSize); + CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->numParameters() + JSStack::CallFrameHeaderSize); ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'. newCallFrame->init(codeBlock, 0, scope, CallFrame::noCaller(), codeBlock->numParameters(), 0); newCallFrame->setThisValue(thisObj); @@ -883,11 +900,11 @@ failedJSONP: { SamplingTool::CallRecord callRecord(m_sampler.get()); - m_reentryDepth++; + m_reentryDepth++; #if ENABLE(LLINT_C_LOOP) result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue); #elif ENABLE(JIT) - result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData()); + result = program->generatedJITCode().execute(&m_stack, newCallFrame, scope->globalData()); #endif // ENABLE(JIT) m_reentryDepth--; @@ -896,7 +913,7 @@ failedJSONP: if (Profiler* profiler = callFrame->globalData().enabledProfiler()) profiler->didExecute(callFrame, program->sourceURL(), program->lineNo()); - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); return checkedReturn(result); } @@ -912,13 +929,13 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) return checkedReturn(throwStackOverflowError(callFrame)); - Register* oldEnd = m_registerFile.end(); + Register* oldEnd = m_stack.end(); ASSERT(callFrame->frameExtent() <= oldEnd || callFrame == callFrame->scope()->globalObject()->globalExec()); int argCount = 1 + args.size(); // implicit "this" parameter - size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize; + size_t registerOffset = argCount + JSStack::CallFrameHeaderSize; CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset); - if (!m_registerFile.grow(newCallFrame->registers())) + if (!m_stack.grow(newCallFrame->registers())) return checkedReturn(throwStackOverflowError(callFrame)); newCallFrame->setThisValue(thisValue); @@ -932,14 +949,14 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, callDataScope); if (UNLIKELY(!!compileError)) { - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); return checkedReturn(throwError(callFrame, compileError)); } CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall(); - newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, 0, argCount); + newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_stack, newCallFrame, 0, argCount); if (UNLIKELY(!newCallFrame)) { - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); return checkedReturn(throwStackOverflowError(callFrame)); } @@ -958,7 +975,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT #if ENABLE(LLINT_C_LOOP) result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue); #elif ENABLE(JIT) - result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScope->globalData()); + result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_stack, newCallFrame, callDataScope->globalData()); #endif // ENABLE(JIT) m_reentryDepth--; @@ -967,7 +984,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT if (Profiler* profiler = callFrame->globalData().enabledProfiler()) profiler->didExecute(callFrame, function); - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); return checkedReturn(result); } @@ -991,7 +1008,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT if (Profiler* profiler = callFrame->globalData().enabledProfiler()) profiler->didExecute(callFrame, function); - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); return checkedReturn(result); } @@ -1007,11 +1024,11 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth) return checkedReturn(throwStackOverflowError(callFrame)); - Register* oldEnd = m_registerFile.end(); + Register* oldEnd = m_stack.end(); int argCount = 1 + args.size(); // implicit "this" parameter - size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize; + size_t registerOffset = argCount + JSStack::CallFrameHeaderSize; - if (!m_registerFile.grow(oldEnd + registerOffset)) + if (!m_stack.grow(oldEnd + registerOffset)) return checkedReturn(throwStackOverflowError(callFrame)); CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset); @@ -1026,14 +1043,14 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, constructDataScope); if (UNLIKELY(!!compileError)) { - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); return checkedReturn(throwError(callFrame, compileError)); } CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct(); - newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, 0, argCount); + newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_stack, newCallFrame, 0, argCount); if (UNLIKELY(!newCallFrame)) { - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); return checkedReturn(throwStackOverflowError(callFrame)); } @@ -1052,7 +1069,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc #if ENABLE(LLINT_C_LOOP) result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue); #elif ENABLE(JIT) - result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScope->globalData()); + result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_stack, newCallFrame, constructDataScope->globalData()); #endif // ENABLE(JIT) m_reentryDepth--; } @@ -1060,7 +1077,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc if (Profiler* profiler = callFrame->globalData().enabledProfiler()) profiler->didExecute(callFrame, constructor); - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); if (callFrame->hadException()) return 0; ASSERT(result.isObject()); @@ -1087,7 +1104,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc if (Profiler* profiler = callFrame->globalData().enabledProfiler()) profiler->didExecute(callFrame, constructor); - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); if (callFrame->hadException()) return 0; ASSERT(result.isObject()); @@ -1106,11 +1123,11 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE return CallFrameClosure(); } - Register* oldEnd = m_registerFile.end(); - size_t registerOffset = argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize; + Register* oldEnd = m_stack.end(); + size_t registerOffset = argumentCountIncludingThis + JSStack::CallFrameHeaderSize; CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset); - if (!m_registerFile.grow(newCallFrame->registers())) { + if (!m_stack.grow(newCallFrame->registers())) { throwStackOverflowError(callFrame); return CallFrameClosure(); } @@ -1118,15 +1135,15 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE JSObject* error = functionExecutable->compileForCall(callFrame, scope); if (error) { throwError(callFrame, error); - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); return CallFrameClosure(); } CodeBlock* codeBlock = &functionExecutable->generatedBytecodeForCall(); - newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, 0, argumentCountIncludingThis); + newCallFrame = slideRegisterWindowForCall(codeBlock, &m_stack, newCallFrame, 0, argumentCountIncludingThis); if (UNLIKELY(!newCallFrame)) { throwStackOverflowError(callFrame); - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); return CallFrameClosure(); } newCallFrame->init(codeBlock, 0, scope, callFrame->addHostCallFrameFlag(), argumentCountIncludingThis, function); @@ -1137,6 +1154,8 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE JSValue Interpreter::execute(CallFrameClosure& closure) { + SamplingScope samplingScope(this); + ASSERT(!closure.oldCallFrame->globalData().isCollectorBusy()); if (closure.oldCallFrame->globalData().isCollectorBusy()) return jsNull(); @@ -1154,7 +1173,7 @@ JSValue Interpreter::execute(CallFrameClosure& closure) #if ENABLE(LLINT_C_LOOP) result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue); #elif ENABLE(JIT) - result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData); + result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_stack, closure.newCallFrame, closure.globalData); #endif // ENABLE(JIT) m_reentryDepth--; } @@ -1167,11 +1186,13 @@ JSValue Interpreter::execute(CallFrameClosure& closure) void Interpreter::endRepeatCall(CallFrameClosure& closure) { closure.globalData->topCallFrame = closure.oldCallFrame; - m_registerFile.shrink(closure.oldEnd); + m_stack.shrink(closure.oldEnd); } JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope, int globalRegisterOffset) { + SamplingScope samplingScope(this); + ASSERT(isValidThisObject(thisValue, callFrame)); ASSERT(!scope->globalData()->exception); ASSERT(!callFrame->globalData().isCollectorBusy()); @@ -1222,12 +1243,12 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue } } - Register* oldEnd = m_registerFile.end(); - Register* newEnd = m_registerFile.begin() + globalRegisterOffset + codeBlock->m_numCalleeRegisters; - if (!m_registerFile.grow(newEnd)) + Register* oldEnd = m_stack.end(); + Register* newEnd = m_stack.begin() + globalRegisterOffset + codeBlock->m_numCalleeRegisters; + if (!m_stack.grow(newEnd)) return checkedReturn(throwStackOverflowError(callFrame)); - CallFrame* newCallFrame = CallFrame::create(m_registerFile.begin() + globalRegisterOffset); + CallFrame* newCallFrame = CallFrame::create(m_stack.begin() + globalRegisterOffset); ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'. newCallFrame->init(codeBlock, 0, scope, callFrame->addHostCallFrameFlag(), codeBlock->numParameters(), 0); @@ -1247,7 +1268,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue #if ENABLE(LLINT_C_LOOP) result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue); #elif ENABLE(JIT) - result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData()); + result = eval->generatedJITCode().execute(&m_stack, newCallFrame, scope->globalData()); #endif // ENABLE(JIT) m_reentryDepth--; } @@ -1255,7 +1276,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue if (Profiler* profiler = callFrame->globalData().enabledProfiler()) profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo()); - m_registerFile.shrink(oldEnd); + m_stack.shrink(oldEnd); return checkedReturn(result); } diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h index f27ae8206..11c6f078a 100644 --- a/Source/JavaScriptCore/interpreter/Interpreter.h +++ b/Source/JavaScriptCore/interpreter/Interpreter.h @@ -35,9 +35,9 @@ #include "JSFunction.h" #include "JSValue.h" #include "JSObject.h" +#include "JSStack.h" #include "LLIntData.h" #include "Opcode.h" -#include "RegisterFile.h" #include <wtf/HashMap.h> #include <wtf/text/StringBuilder.h> @@ -189,7 +189,7 @@ namespace JSC { void initialize(bool canUseJIT); - RegisterFile& registerFile() { return m_registerFile; } + JSStack& stack() { return m_stack; } Opcode getOpcode(OpcodeID id) { @@ -249,14 +249,10 @@ namespace JSC { NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&); - static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc); + static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, JSStack*, CallFrame*, size_t registerOffset, int argc); static CallFrame* findFunctionCallFrameFromVMCode(CallFrame*, JSFunction*); -#if !ENABLE(LLINT_C_LOOP) - JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*); -#endif - void dumpRegisters(CallFrame*); bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); } @@ -267,7 +263,7 @@ namespace JSC { int m_reentryDepth; - RegisterFile m_registerFile; + JSStack m_stack; #if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT) Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling @@ -287,11 +283,11 @@ namespace JSC { inline JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope) { - return execute(eval, callFrame, thisValue, scope, m_registerFile.size() + 1 + RegisterFile::CallFrameHeaderSize); + return execute(eval, callFrame, thisValue, scope, m_stack.size() + 1 + JSStack::CallFrameHeaderSize); } JSValue eval(CallFrame*); - CallFrame* loadVarargs(CallFrame*, RegisterFile*, JSValue thisValue, JSValue arguments, int firstFreeRegister); + CallFrame* loadVarargs(CallFrame*, JSStack*, JSValue thisValue, JSValue arguments, int firstFreeRegister); } // namespace JSC diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.cpp b/Source/JavaScriptCore/interpreter/JSStack.cpp index dacb53872..5dd708a48 100644 --- a/Source/JavaScriptCore/interpreter/RegisterFile.cpp +++ b/Source/JavaScriptCore/interpreter/JSStack.cpp @@ -27,7 +27,7 @@ */ #include "config.h" -#include "RegisterFile.h" +#include "JSStack.h" #include "ConservativeRoots.h" #include "Interpreter.h" @@ -36,13 +36,13 @@ namespace JSC { static size_t committedBytesCount = 0; -static Mutex& registerFileStatisticsMutex() +static Mutex& stackStatisticsMutex() { DEFINE_STATIC_LOCAL(Mutex, staticMutex, ()); return staticMutex; } -RegisterFile::~RegisterFile() +JSStack::~JSStack() { void* base = m_reservation.base(); m_reservation.decommit(base, reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(base)); @@ -50,7 +50,7 @@ RegisterFile::~RegisterFile() m_reservation.deallocate(); } -bool RegisterFile::growSlowCase(Register* newEnd) +bool JSStack::growSlowCase(Register* newEnd) { if (newEnd <= m_commitEnd) { m_end = newEnd; @@ -68,17 +68,17 @@ bool RegisterFile::growSlowCase(Register* newEnd) return true; } -void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots) +void JSStack::gatherConservativeRoots(ConservativeRoots& conservativeRoots) { conservativeRoots.add(begin(), end()); } -void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, DFGCodeBlocks& dfgCodeBlocks) +void JSStack::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, DFGCodeBlocks& dfgCodeBlocks) { conservativeRoots.add(begin(), end(), jitStubRoutines, dfgCodeBlocks); } -void RegisterFile::releaseExcessCapacity() +void JSStack::releaseExcessCapacity() { ptrdiff_t delta = reinterpret_cast<uintptr_t>(m_commitEnd) - reinterpret_cast<uintptr_t>(m_reservation.base()); m_reservation.decommit(m_reservation.base(), delta); @@ -86,20 +86,20 @@ void RegisterFile::releaseExcessCapacity() m_commitEnd = static_cast<Register*>(m_reservation.base()); } -void RegisterFile::initializeThreading() +void JSStack::initializeThreading() { - registerFileStatisticsMutex(); + stackStatisticsMutex(); } -size_t RegisterFile::committedByteCount() +size_t JSStack::committedByteCount() { - MutexLocker locker(registerFileStatisticsMutex()); + MutexLocker locker(stackStatisticsMutex()); return committedBytesCount; } -void RegisterFile::addToCommittedByteCount(long byteCount) +void JSStack::addToCommittedByteCount(long byteCount) { - MutexLocker locker(registerFileStatisticsMutex()); + MutexLocker locker(stackStatisticsMutex()); ASSERT(static_cast<long>(committedBytesCount) + byteCount > -1); committedBytesCount += byteCount; } diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.h b/Source/JavaScriptCore/interpreter/JSStack.h index 8fff8208c..86fa40be7 100644 --- a/Source/JavaScriptCore/interpreter/RegisterFile.h +++ b/Source/JavaScriptCore/interpreter/JSStack.h @@ -26,8 +26,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef RegisterFile_h -#define RegisterFile_h +#ifndef JSStack_h +#define JSStack_h #include "ExecutableAllocator.h" #include "Register.h" @@ -42,8 +42,8 @@ namespace JSC { class JITStubRoutineSet; class LLIntOffsetsExtractor; - class RegisterFile { - WTF_MAKE_NONCOPYABLE(RegisterFile); + class JSStack { + WTF_MAKE_NONCOPYABLE(JSStack); public: enum CallFrameHeaderEntry { CallFrameHeaderSize = 6, @@ -58,11 +58,11 @@ namespace JSC { static const size_t defaultCapacity = 512 * 1024; static const size_t commitSize = 16 * 1024; - // Allow 8k of excess registers before we start trying to reap the registerfile + // Allow 8k of excess registers before we start trying to reap the stack static const ptrdiff_t maxExcessCapacity = 8 * 1024; - RegisterFile(size_t capacity = defaultCapacity); - ~RegisterFile(); + JSStack(size_t capacity = defaultCapacity); + ~JSStack(); void gatherConservativeRoots(ConservativeRoots&); void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, DFGCodeBlocks&); @@ -84,7 +84,7 @@ namespace JSC { private: friend class LLIntOffsetsExtractor; - + bool growSlowCase(Register*); void releaseExcessCapacity(); void addToCommittedByteCount(long); @@ -93,7 +93,7 @@ namespace JSC { PageReservation m_reservation; }; - inline RegisterFile::RegisterFile(size_t capacity) + inline JSStack::JSStack(size_t capacity) : m_end(0) { ASSERT(capacity && isPageAligned(capacity)); @@ -103,7 +103,7 @@ namespace JSC { m_commitEnd = static_cast<Register*>(m_reservation.base()); } - inline void RegisterFile::shrink(Register* newEnd) + inline void JSStack::shrink(Register* newEnd) { if (newEnd >= m_end) return; @@ -112,7 +112,7 @@ namespace JSC { releaseExcessCapacity(); } - inline bool RegisterFile::grow(Register* newEnd) + inline bool JSStack::grow(Register* newEnd) { if (newEnd <= m_end) return true; @@ -121,4 +121,4 @@ namespace JSC { } // namespace JSC -#endif // RegisterFile_h +#endif // JSStack_h diff --git a/Source/JavaScriptCore/interpreter/VMInspector.cpp b/Source/JavaScriptCore/interpreter/VMInspector.cpp index 34bf61535..566d4e8e0 100644 --- a/Source/JavaScriptCore/interpreter/VMInspector.cpp +++ b/Source/JavaScriptCore/interpreter/VMInspector.cpp @@ -69,25 +69,19 @@ void VMInspector::dumpFrame(CallFrame* frame, const char* prefix, printf("%s ", prefix); printf("frame [%d] %p { cb %p:%s, retPC %p:%s, scope %p:%s, callee %p:%s, callerFrame %p:%s, argc %d, vPC %p }", - frameCount, frame, - - CAST<void*>(frame[RegisterFile::CodeBlock].payload()), - getTypeName(frame[RegisterFile::CodeBlock].jsValue()), - - CAST<void*>(frame[RegisterFile::ReturnPC].payload()), - getTypeName(frame[RegisterFile::ReturnPC].jsValue()), - - CAST<void*>(frame[RegisterFile::ScopeChain].payload()), - getTypeName(frame[RegisterFile::ScopeChain].jsValue()), - - CAST<void*>(frame[RegisterFile::Callee].payload()), - getTypeName(frame[RegisterFile::Callee].jsValue()), - - CAST<void*>(frame[RegisterFile::CallerFrame].payload()), - getTypeName(frame[RegisterFile::CallerFrame].jsValue()), - - frame[RegisterFile::ArgumentCount].payload(), - vPC); + frameCount, frame, + CAST<void*>(frame[JSStack::CodeBlock].payload()), + getTypeName(frame[JSStack::CodeBlock].jsValue()), + CAST<void*>(frame[JSStack::ReturnPC].payload()), + getTypeName(frame[JSStack::ReturnPC].jsValue()), + CAST<void*>(frame[JSStack::ScopeChain].payload()), + getTypeName(frame[JSStack::ScopeChain].jsValue()), + CAST<void*>(frame[JSStack::Callee].payload()), + getTypeName(frame[JSStack::Callee].jsValue()), + CAST<void*>(frame[JSStack::CallerFrame].callFrame()), + getTypeName(frame[JSStack::CallerFrame].jsValue()), + frame[JSStack::ArgumentCount].payload(), + vPC); if (funcName || file || (line >= 0)) { printf(" @"); diff --git a/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp index 2123f5a67..7ee3e0497 100644 --- a/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp +++ b/Source/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp @@ -31,7 +31,6 @@ #include "CodeProfiling.h" #include <errno.h> -#include <sys/mman.h> #include <unistd.h> #include <wtf/MetaAllocator.h> #include <wtf/PageReservation.h> diff --git a/Source/JavaScriptCore/jit/HostCallReturnValue.h b/Source/JavaScriptCore/jit/HostCallReturnValue.h index 0e17ca035..3f61179a3 100644 --- a/Source/JavaScriptCore/jit/HostCallReturnValue.h +++ b/Source/JavaScriptCore/jit/HostCallReturnValue.h @@ -30,10 +30,7 @@ #include "MacroAssemblerCodeRef.h" #include <wtf/Platform.h> -// Unfortunately this only works on GCC-like compilers. And it's currently only used -// by LLInt and DFG, which also are restricted to GCC-like compilers. We should -// probably fix that at some point. -#if COMPILER(GCC) && ENABLE(JIT) +#if ENABLE(JIT) #if CALLING_CONVENTION_IS_STDCALL #define HOST_CALL_RETURN_VALUE_OPTION CDECL @@ -45,6 +42,8 @@ namespace JSC { extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValue() REFERENCED_FROM_ASM WTF_INTERNAL; +#if COMPILER(GCC) + // This is a public declaration only to convince CLANG not to elide it. extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState*) REFERENCED_FROM_ASM WTF_INTERNAL; @@ -53,15 +52,14 @@ inline void initializeHostCallReturnValue() getHostCallReturnValueWithExecState(0); } -} - #else // COMPILER(GCC) -namespace JSC { inline void initializeHostCallReturnValue() { } -} #endif // COMPILER(GCC) -#endif // HostCallReturnValue_h +} // namespace JSC +#endif // ENABLE(JIT) + +#endif // HostCallReturnValue_h diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp index bf5ac88dd..49f9ec3b5 100644 --- a/Source/JavaScriptCore/jit/JIT.cpp +++ b/Source/JavaScriptCore/jit/JIT.cpp @@ -75,10 +75,14 @@ JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock) , m_codeBlock(codeBlock) , m_labels(codeBlock ? codeBlock->numberOfInstructions() : 0) , m_bytecodeOffset((unsigned)-1) + , m_propertyAccessInstructionIndex(UINT_MAX) + , m_byValInstructionIndex(UINT_MAX) + , m_globalResolveInfoIndex(UINT_MAX) + , m_callLinkInfoIndex(UINT_MAX) #if USE(JSVALUE32_64) , m_jumpTargetIndex(0) , m_mappedBytecodeOffset((unsigned)-1) - , m_mappedVirtualRegisterIndex(RegisterFile::ReturnPC) + , m_mappedVirtualRegisterIndex(JSStack::ReturnPC) , m_mappedTag((RegisterID)-1) , m_mappedPayload((RegisterID)-1) #else @@ -90,6 +94,10 @@ JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock) #else , m_randomGenerator(static_cast<unsigned>(randomNumber() * 0xFFFFFFF)) #endif +#if ENABLE(VALUE_PROFILER) + , m_canBeOptimized(false) + , m_shouldEmitProfiling(false) +#endif { } @@ -400,6 +408,7 @@ void JIT::privateCompileSlowCases() Instruction* instructionsBegin = m_codeBlock->instructions().begin(); m_propertyAccessInstructionIndex = 0; + m_byValInstructionIndex = 0; m_globalResolveInfoIndex = 0; m_callLinkInfoIndex = 0; @@ -606,8 +615,8 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo nop(); preserveReturnAddressAfterCall(regT2); - emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC); - emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock); + emitPutToCallFrameHeader(regT2, JSStack::ReturnPC); + emitPutImmediateToCallFrameHeader(m_codeBlock, JSStack::CodeBlock); Label beginLabel(this); @@ -616,7 +625,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo sampleInstruction(m_codeBlock->instructions().begin()); #endif - Jump registerFileCheck; + Jump stackCheck; if (m_codeBlock->codeType() == FunctionCode) { #if ENABLE(DFG_JIT) #if DFG_ENABLE(SUCCESS_STATS) @@ -646,7 +655,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo #endif addPtr(TrustedImm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, regT1); - registerFileCheck = branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT1); + stackCheck = branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->stack().addressOfEnd()), regT1); } Label functionBody = label(); @@ -662,9 +671,9 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo Label arityCheck; if (m_codeBlock->codeType() == FunctionCode) { - registerFileCheck.link(this); + stackCheck.link(this); m_bytecodeOffset = 0; - JITStubCall(this, cti_register_file_check).call(); + JITStubCall(this, cti_stack_check).call(); #ifndef NDEBUG m_bytecodeOffset = (unsigned)-1; // Reset this, in order to guard its use with ASSERTs. #endif @@ -672,10 +681,10 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo arityCheck = label(); preserveReturnAddressAfterCall(regT2); - emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC); - emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock); + emitPutToCallFrameHeader(regT2, JSStack::ReturnPC); + emitPutImmediateToCallFrameHeader(m_codeBlock, JSStack::CodeBlock); - load32(payloadFor(RegisterFile::ArgumentCount), regT1); + load32(payloadFor(JSStack::ArgumentCount), regT1); branch32(AboveOrEqual, regT1, TrustedImm32(m_codeBlock->m_numParameters)).linkTo(beginLabel, this); m_bytecodeOffset = 0; @@ -715,8 +724,8 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo StringJumpTable::StringOffsetTable::iterator end = record.jumpTable.stringJumpTable->offsetTable.end(); for (StringJumpTable::StringOffsetTable::iterator it = record.jumpTable.stringJumpTable->offsetTable.begin(); it != end; ++it) { - unsigned offset = it->second.branchOffset; - it->second.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeOffset + offset]) : record.jumpTable.stringJumpTable->ctiDefault; + unsigned offset = it->value.branchOffset; + it->value.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeOffset + offset]) : record.jumpTable.stringJumpTable->ctiDefault; } } } @@ -738,6 +747,20 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck, JITCompilationEffo m_codeBlock->setNumberOfStructureStubInfos(m_propertyAccessCompilationInfo.size()); for (unsigned i = 0; i < m_propertyAccessCompilationInfo.size(); ++i) m_propertyAccessCompilationInfo[i].copyToStubInfo(m_codeBlock->structureStubInfo(i), patchBuffer); + m_codeBlock->setNumberOfByValInfos(m_byValCompilationInfo.size()); + for (unsigned i = 0; i < m_byValCompilationInfo.size(); ++i) { + CodeLocationJump badTypeJump = CodeLocationJump(patchBuffer.locationOf(m_byValCompilationInfo[i].badTypeJump)); + CodeLocationLabel doneTarget = patchBuffer.locationOf(m_byValCompilationInfo[i].doneTarget); + CodeLocationLabel slowPathTarget = patchBuffer.locationOf(m_byValCompilationInfo[i].slowPathTarget); + CodeLocationCall returnAddress = patchBuffer.locationOf(m_byValCompilationInfo[i].returnAddress); + + m_codeBlock->byValInfo(i) = ByValInfo( + m_byValCompilationInfo[i].bytecodeIndex, + badTypeJump, + m_byValCompilationInfo[i].arrayMode, + differenceBetweenCodePtr(badTypeJump, doneTarget), + differenceBetweenCodePtr(returnAddress, slowPathTarget)); + } m_codeBlock->setNumberOfCallLinkInfos(m_callStructureStubCompilationInfo.size()); for (unsigned i = 0; i < m_codeBlock->numberOfCallLinkInfos(); ++i) { CallLinkInfo& info = m_codeBlock->callLinkInfo(i); diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h index 150aae9ea..3e16972e2 100644 --- a/Source/JavaScriptCore/jit/JIT.h +++ b/Source/JavaScriptCore/jit/JIT.h @@ -58,9 +58,9 @@ namespace JSC { class JIT; class JSPropertyNameIterator; class Interpreter; - class Register; - class RegisterFile; class JSScope; + class JSStack; + class Register; class StructureChain; struct CallLinkInfo; @@ -264,6 +264,25 @@ namespace JSC { void copyToStubInfo(StructureStubInfo& info, LinkBuffer &patchBuffer); }; + struct ByValCompilationInfo { + ByValCompilationInfo() { } + + ByValCompilationInfo(unsigned bytecodeIndex, MacroAssembler::PatchableJump badTypeJump, JITArrayMode arrayMode, MacroAssembler::Label doneTarget) + : bytecodeIndex(bytecodeIndex) + , badTypeJump(badTypeJump) + , arrayMode(arrayMode) + , doneTarget(doneTarget) + { + } + + unsigned bytecodeIndex; + MacroAssembler::PatchableJump badTypeJump; + JITArrayMode arrayMode; + MacroAssembler::Label doneTarget; + MacroAssembler::Label slowPathTarget; + MacroAssembler::Call returnAddress; + }; + struct StructureStubCompilationInfo { MacroAssembler::DataLabelPtr hotPathBegin; MacroAssembler::Call hotPathOther; @@ -348,6 +367,20 @@ namespace JSC { jit.m_bytecodeOffset = stubInfo->bytecodeIndex; jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress, direct); } + + static void compileGetByVal(JSGlobalData* globalData, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) + { + JIT jit(globalData, codeBlock); + jit.m_bytecodeOffset = byValInfo->bytecodeIndex; + jit.privateCompileGetByVal(byValInfo, returnAddress, arrayMode); + } + + static void compilePutByVal(JSGlobalData* globalData, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) + { + JIT jit(globalData, codeBlock); + jit.m_bytecodeOffset = byValInfo->bytecodeIndex; + jit.privateCompilePutByVal(byValInfo, returnAddress, arrayMode); + } static PassRefPtr<ExecutableMemoryHandle> compileCTIMachineTrampolines(JSGlobalData* globalData, TrampolineStructure *trampolines) { @@ -379,6 +412,10 @@ namespace JSC { static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress) { JIT jit(globalData, codeBlock); +#if ENABLE(DFG_JIT) + // Force profiling to be enabled during stub generation. + jit.m_canBeOptimized = true; +#endif // ENABLE(DFG_JIT) return jit.privateCompilePatchGetArrayLength(returnAddress); } @@ -397,6 +434,9 @@ namespace JSC { void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain*, size_t count, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset, CallFrame*); void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, const Identifier&, const PropertySlot&, PropertyOffset cachedOffset, ReturnAddressPtr, CallFrame*); void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, PropertyOffset cachedOffset, StructureChain*, ReturnAddressPtr, bool direct); + + void privateCompileGetByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode); + void privateCompilePutByVal(ByValInfo*, ReturnAddressPtr, JITArrayMode); PassRefPtr<ExecutableMemoryHandle> privateCompileCTIMachineTrampolines(JSGlobalData*, TrampolineStructure*); Label privateCompileCTINativeCall(JSGlobalData*, bool isConstruct = false); @@ -434,7 +474,7 @@ namespace JSC { void emitWriteBarrier(RegisterID owner, RegisterID valueTag, RegisterID scratch, RegisterID scratch2, WriteBarrierMode, WriteBarrierUseKind); void emitWriteBarrier(JSCell* owner, RegisterID value, RegisterID scratch, WriteBarrierMode, WriteBarrierUseKind); - template<typename ClassType, bool destructor, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr); + template<typename ClassType, MarkedBlock::DestructorType, typename StructureType> void emitAllocateBasicJSObject(StructureType, RegisterID result, RegisterID storagePtr); void emitAllocateBasicStorage(size_t, ptrdiff_t offsetFromBase, RegisterID result); template<typename T> void emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID storagePtr); void emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr, RegisterID scratch); @@ -452,7 +492,27 @@ namespace JSC { void emitArrayProfilingSite(RegisterID structureAndIndexingType, RegisterID scratch, ArrayProfile*); void emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndIndexingType, RegisterID scratch, unsigned bytecodeIndex); void emitArrayProfileStoreToHoleSpecialCase(ArrayProfile*); - + + JITArrayMode chooseArrayMode(ArrayProfile*); + + // Property is in regT1, base is in regT0. regT2 contains indexing type. + // Property is int-checked and zero extended. Base is cell checked. + // Structure is already profiled. Returns the slow cases. Fall-through + // case contains result in regT0, and it is not yet profiled. + JumpList emitContiguousGetByVal(Instruction*, PatchableJump& badType); + JumpList emitArrayStorageGetByVal(Instruction*, PatchableJump& badType); + JumpList emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, const TypedArrayDescriptor&, size_t elementSize, TypedArraySignedness); + JumpList emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badType, const TypedArrayDescriptor&, size_t elementSize); + + // Property is in regT0, base is in regT0. regT2 contains indecing type. + // The value to store is not yet loaded. Property is int-checked and + // zero-extended. Base is cell checked. Structure is already profiled. + // returns the slow cases. + JumpList emitContiguousPutByVal(Instruction*, PatchableJump& badType); + JumpList emitArrayStoragePutByVal(Instruction*, PatchableJump& badType); + JumpList emitIntTypedArrayPutByVal(Instruction*, PatchableJump& badType, const TypedArrayDescriptor&, size_t elementSize, TypedArraySignedness, TypedArrayRounding); + JumpList emitFloatTypedArrayPutByVal(Instruction*, PatchableJump& badType, const TypedArrayDescriptor&, size_t elementSize); + enum FinalObjectMode { MayBeFinal, KnownNotFinal }; #if USE(JSVALUE32_64) @@ -778,12 +838,12 @@ namespace JSC { void emitInitRegister(unsigned dst); - void emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry); - void emitPutCellToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry); - void emitPutIntToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry); - void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry); - void emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister); - void emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister); + void emitPutToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry); + void emitPutCellToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry); + void emitPutIntToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry); + void emitPutImmediateToCallFrameHeader(void* value, JSStack::CallFrameHeaderEntry); + void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister); + void emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister); JSValue getConstantOperand(unsigned src); bool isOperandConstantImmediateInt(unsigned src); @@ -870,6 +930,7 @@ namespace JSC { Vector<CallRecord> m_calls; Vector<Label> m_labels; Vector<PropertyStubCompilationInfo> m_propertyAccessCompilationInfo; + Vector<ByValCompilationInfo> m_byValCompilationInfo; Vector<StructureStubCompilationInfo> m_callStructureStubCompilationInfo; Vector<MethodCallCompilationInfo> m_methodCallCompilationInfo; Vector<JumpTable> m_jmpTable; @@ -879,6 +940,7 @@ namespace JSC { Vector<SwitchRecord> m_switches; unsigned m_propertyAccessInstructionIndex; + unsigned m_byValInstructionIndex; unsigned m_globalResolveInfoIndex; unsigned m_callLinkInfoIndex; diff --git a/Source/JavaScriptCore/jit/JITCall.cpp b/Source/JavaScriptCore/jit/JITCall.cpp index b5f4f8278..1de877daa 100644 --- a/Source/JavaScriptCore/jit/JITCall.cpp +++ b/Source/JavaScriptCore/jit/JITCall.cpp @@ -74,20 +74,20 @@ void JIT::compileLoadVarargs(Instruction* instruction) emitGetVirtualRegister(arguments, regT0); slowCase.append(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(JSValue())))); - emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); + emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0); slowCase.append(branch32(Above, regT0, TrustedImm32(Arguments::MaxArguments + 1))); // regT0: argumentCountIncludingThis move(regT0, regT1); - add32(TrustedImm32(firstFreeRegister + RegisterFile::CallFrameHeaderSize), regT1); + add32(TrustedImm32(firstFreeRegister + JSStack::CallFrameHeaderSize), regT1); lshift32(TrustedImm32(3), regT1); addPtr(callFrameRegister, regT1); // regT1: newCallFrame - slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT1)); + slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->stack().addressOfEnd()), regT1)); // Initialize ArgumentCount. - store32(regT0, Address(regT1, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); + store32(regT0, Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); // Initialize 'this'. emitGetVirtualRegister(thisValue, regT2); @@ -125,7 +125,7 @@ void JIT::compileCallEval() JITStubCall stubCall(this, cti_op_call_eval); // Initializes ScopeChain; ReturnPC; CodeBlock. stubCall.call(); addSlowCase(branchPtr(Equal, regT0, TrustedImmPtr(JSValue::encode(JSValue())))); - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); sampleCodeBlock(m_codeBlock); } @@ -134,7 +134,7 @@ void JIT::compileCallEvalSlowCase(Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0); emitNakedCall(m_globalData->jitStubs->ctiVirtualCall()); sampleCodeBlock(m_codeBlock); @@ -173,14 +173,14 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca } addPtr(TrustedImm32(registerOffset * sizeof(Register)), callFrameRegister, regT1); - store32(TrustedImm32(argCount), Address(regT1, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); + store32(TrustedImm32(argCount), Address(regT1, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))); } // regT1 holds newCallFrame with ArgumentCount initialized. - store32(TrustedImm32(instruction - m_codeBlock->instructions().begin()), Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); + store32(TrustedImm32(instruction - m_codeBlock->instructions().begin()), Address(callFrameRegister, JSStack::ArgumentCount * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))); emitGetVirtualRegister(callee, regT0); // regT0 holds callee. - storePtr(callFrameRegister, Address(regT1, RegisterFile::CallerFrame * static_cast<int>(sizeof(Register)))); - storePtr(regT0, Address(regT1, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); + storePtr(callFrameRegister, Address(regT1, JSStack::CallerFrame * static_cast<int>(sizeof(Register)))); + storePtr(regT0, Address(regT1, JSStack::Callee * static_cast<int>(sizeof(Register)))); move(regT1, callFrameRegister); if (opcodeID == op_call_eval) { @@ -201,7 +201,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca m_callStructureStubCompilationInfo[callLinkInfoIndex].bytecodeIndex = m_bytecodeOffset; loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1); - emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitPutToCallFrameHeader(regT1, JSStack::ScopeChain); m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(); sampleCodeBlock(m_codeBlock); diff --git a/Source/JavaScriptCore/jit/JITCall32_64.cpp b/Source/JavaScriptCore/jit/JITCall32_64.cpp index 09727d532..ad827cdf9 100644 --- a/Source/JavaScriptCore/jit/JITCall32_64.cpp +++ b/Source/JavaScriptCore/jit/JITCall32_64.cpp @@ -59,8 +59,8 @@ void JIT::emit_op_ret(Instruction* currentInstruction) unsigned dst = currentInstruction[1].u.operand; emitLoad(dst, regT1, regT0); - emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::ReturnPC, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); restoreReturnAddressBeforeReturn(regT2); ret(); @@ -76,8 +76,8 @@ void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction) loadPtr(Address(regT0, JSCell::structureOffset()), regT2); Jump notObject = emitJumpIfNotObject(regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::ReturnPC, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); restoreReturnAddressBeforeReturn(regT2); ret(); @@ -86,8 +86,8 @@ void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction) notObject.link(this); emitLoad(thisReg, regT1, regT0); - emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::ReturnPC, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); restoreReturnAddressBeforeReturn(regT2); ret(); @@ -149,20 +149,20 @@ void JIT::compileLoadVarargs(Instruction* instruction) emitLoadTag(arguments, regT1); slowCase.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag))); - load32(payloadFor(RegisterFile::ArgumentCount), regT2); + load32(payloadFor(JSStack::ArgumentCount), regT2); slowCase.append(branch32(Above, regT2, TrustedImm32(Arguments::MaxArguments + 1))); // regT2: argumentCountIncludingThis move(regT2, regT3); - add32(TrustedImm32(firstFreeRegister + RegisterFile::CallFrameHeaderSize), regT3); + add32(TrustedImm32(firstFreeRegister + JSStack::CallFrameHeaderSize), regT3); lshift32(TrustedImm32(3), regT3); addPtr(callFrameRegister, regT3); // regT3: newCallFrame - slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->registerFile().addressOfEnd()), regT3)); + slowCase.append(branchPtr(Below, AbsoluteAddress(m_globalData->interpreter->stack().addressOfEnd()), regT3)); // Initialize ArgumentCount. - store32(regT2, payloadFor(RegisterFile::ArgumentCount, regT3)); + store32(regT2, payloadFor(JSStack::ArgumentCount, regT3)); // Initialize 'this'. emitLoad(thisValue, regT1, regT0); @@ -202,7 +202,7 @@ void JIT::compileCallEval() JITStubCall stubCall(this, cti_op_call_eval); // Initializes ScopeChain; ReturnPC; CodeBlock. stubCall.call(); addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag))); - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); sampleCodeBlock(m_codeBlock); } @@ -211,7 +211,7 @@ void JIT::compileCallEvalSlowCase(Vector<SlowCaseEntry>::iterator& iter) { linkSlowCase(iter); - emitLoad(RegisterFile::Callee, regT1, regT0); + emitLoad(JSStack::Callee, regT1, regT0); emitNakedCall(m_globalData->jitStubs->ctiVirtualCall()); sampleCodeBlock(m_codeBlock); @@ -251,14 +251,14 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca addPtr(TrustedImm32(registerOffset * sizeof(Register)), callFrameRegister, regT3); - store32(TrustedImm32(argCount), payloadFor(RegisterFile::ArgumentCount, regT3)); + store32(TrustedImm32(argCount), payloadFor(JSStack::ArgumentCount, regT3)); } // regT3 holds newCallFrame with ArgumentCount initialized. - storePtr(TrustedImmPtr(instruction), tagFor(RegisterFile::ArgumentCount, callFrameRegister)); + storePtr(TrustedImmPtr(instruction), tagFor(JSStack::ArgumentCount, callFrameRegister)); emitLoad(callee, regT1, regT0); // regT1, regT0 holds callee. - storePtr(callFrameRegister, Address(regT3, RegisterFile::CallerFrame * static_cast<int>(sizeof(Register)))); - emitStore(RegisterFile::Callee, regT1, regT0, regT3); + storePtr(callFrameRegister, Address(regT3, JSStack::CallerFrame * static_cast<int>(sizeof(Register)))); + emitStore(JSStack::Callee, regT1, regT0, regT3); move(regT3, callFrameRegister); if (opcodeID == op_call_eval) { @@ -281,7 +281,7 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca m_callStructureStubCompilationInfo[callLinkInfoIndex].bytecodeIndex = m_bytecodeOffset; loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(); sampleCodeBlock(m_codeBlock); diff --git a/Source/JavaScriptCore/jit/JITCode.h b/Source/JavaScriptCore/jit/JITCode.h index e39b4f98d..93fa88a23 100644 --- a/Source/JavaScriptCore/jit/JITCode.h +++ b/Source/JavaScriptCore/jit/JITCode.h @@ -38,7 +38,7 @@ namespace JSC { #if ENABLE(JIT) class JSGlobalData; - class RegisterFile; + class JSStack; #endif class JITCode { @@ -129,9 +129,9 @@ namespace JSC { #if ENABLE(JIT) // Execute the code! - inline JSValue execute(RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData) + inline JSValue execute(JSStack* stack, CallFrame* callFrame, JSGlobalData* globalData) { - JSValue result = JSValue::decode(ctiTrampoline(m_ref.code().executableAddress(), registerFile, callFrame, 0, 0, globalData)); + JSValue result = JSValue::decode(ctiTrampoline(m_ref.code().executableAddress(), stack, callFrame, 0, 0, globalData)); return globalData->exception ? jsNull() : result; } #endif diff --git a/Source/JavaScriptCore/jit/JITInlineMethods.h b/Source/JavaScriptCore/jit/JITInlineMethods.h index ed63ad348..a7aecd3e8 100644 --- a/Source/JavaScriptCore/jit/JITInlineMethods.h +++ b/Source/JavaScriptCore/jit/JITInlineMethods.h @@ -50,12 +50,12 @@ ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src) return m_codeBlock->getConstant(src); } -ALWAYS_INLINE void JIT::emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry) +ALWAYS_INLINE void JIT::emitPutToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry) { storePtr(from, payloadFor(entry, callFrameRegister)); } -ALWAYS_INLINE void JIT::emitPutCellToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry) +ALWAYS_INLINE void JIT::emitPutCellToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry) { #if USE(JSVALUE32_64) store32(TrustedImm32(JSValue::CellTag), tagFor(entry, callFrameRegister)); @@ -63,18 +63,18 @@ ALWAYS_INLINE void JIT::emitPutCellToCallFrameHeader(RegisterID from, RegisterFi storePtr(from, payloadFor(entry, callFrameRegister)); } -ALWAYS_INLINE void JIT::emitPutIntToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry) +ALWAYS_INLINE void JIT::emitPutIntToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry) { store32(TrustedImm32(Int32Tag), intTagFor(entry, callFrameRegister)); store32(from, intPayloadFor(entry, callFrameRegister)); } -ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry) +ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, JSStack::CallFrameHeaderEntry entry) { storePtr(TrustedImmPtr(value), Address(callFrameRegister, entry * sizeof(Register))); } -ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from) +ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from) { loadPtr(Address(from, entry * sizeof(Register)), to); #if USE(JSVALUE64) @@ -101,7 +101,7 @@ ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, cont8Bit.link(this); } -ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from) +ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from) { load32(Address(from, entry * sizeof(Register)), to); #if USE(JSVALUE64) @@ -265,9 +265,9 @@ ALWAYS_INLINE void JIT::updateTopCallFrame() ASSERT(static_cast<int>(m_bytecodeOffset) >= 0); if (m_bytecodeOffset) { #if USE(JSVALUE32_64) - storePtr(TrustedImmPtr(m_codeBlock->instructions().begin() + m_bytecodeOffset + 1), intTagFor(RegisterFile::ArgumentCount)); + storePtr(TrustedImmPtr(m_codeBlock->instructions().begin() + m_bytecodeOffset + 1), intTagFor(JSStack::ArgumentCount)); #else - store32(TrustedImm32(m_bytecodeOffset + 1), intTagFor(RegisterFile::ArgumentCount)); + store32(TrustedImm32(m_bytecodeOffset + 1), intTagFor(JSStack::ArgumentCount)); #endif } storePtr(callFrameRegister, &m_globalData->topCallFrame); @@ -405,13 +405,16 @@ ALWAYS_INLINE bool JIT::isOperandConstantImmediateChar(unsigned src) return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isString() && asString(getConstantOperand(src).asCell())->length() == 1; } -template <typename ClassType, bool destructor, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, RegisterID result, RegisterID storagePtr) +template <typename ClassType, MarkedBlock::DestructorType destructorType, typename StructureType> inline void JIT::emitAllocateBasicJSObject(StructureType structure, RegisterID result, RegisterID storagePtr) { + size_t size = ClassType::allocationSize(INLINE_STORAGE_CAPACITY); MarkedAllocator* allocator = 0; - if (destructor) - allocator = &m_globalData->heap.allocatorForObjectWithDestructor(sizeof(ClassType)); + if (destructorType == MarkedBlock::Normal) + allocator = &m_globalData->heap.allocatorForObjectWithNormalDestructor(size); + else if (destructorType == MarkedBlock::ImmortalStructure) + allocator = &m_globalData->heap.allocatorForObjectWithImmortalStructureDestructor(size); else - allocator = &m_globalData->heap.allocatorForObjectWithoutDestructor(sizeof(ClassType)); + allocator = &m_globalData->heap.allocatorForObjectWithoutDestructor(size); loadPtr(&allocator->m_freeList.head, result); addSlowCase(branchTestPtr(Zero, result)); @@ -428,7 +431,7 @@ template <typename ClassType, bool destructor, typename StructureType> inline vo template <typename T> inline void JIT::emitAllocateJSFinalObject(T structure, RegisterID result, RegisterID scratch) { - emitAllocateBasicJSObject<JSFinalObject, false, T>(structure, result, scratch); + emitAllocateBasicJSObject<JSFinalObject, MarkedBlock::None, T>(structure, result, scratch); } inline void JIT::emitAllocateBasicStorage(size_t size, ptrdiff_t offsetFromBase, RegisterID result) @@ -445,23 +448,24 @@ inline void JIT::emitAllocateBasicStorage(size_t size, ptrdiff_t offsetFromBase, inline void JIT::emitAllocateJSArray(unsigned valuesRegister, unsigned length, RegisterID cellResult, RegisterID storageResult, RegisterID storagePtr, RegisterID scratch) { - unsigned initialLength = std::max(length, 4U); - size_t initialStorage = Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(initialLength)); + unsigned initialLength = std::max(length, BASE_VECTOR_LEN); + size_t initialStorage = Butterfly::totalSize(0, 0, true, initialLength * sizeof(EncodedJSValue)); + + loadPtr(m_codeBlock->globalObject()->addressOfArrayStructure(), scratch); + load8(Address(scratch, Structure::indexingTypeOffset()), storagePtr); + and32(TrustedImm32(IndexingShapeMask), storagePtr); + addSlowCase(branch32(NotEqual, storagePtr, TrustedImm32(ContiguousShape))); // We allocate the backing store first to ensure that garbage collection // doesn't happen during JSArray initialization. emitAllocateBasicStorage(initialStorage, sizeof(IndexingHeader), storageResult); // Allocate the cell for the array. - loadPtr(m_codeBlock->globalObject()->addressOfArrayStructure(), scratch); - emitAllocateBasicJSObject<JSArray, false>(scratch, cellResult, storagePtr); + emitAllocateBasicJSObject<JSArray, MarkedBlock::None>(scratch, cellResult, storagePtr); - // Store all the necessary info in the ArrayStorage. - store32(Imm32(length), Address(storageResult, ArrayStorage::lengthOffset())); - store32(Imm32(length), Address(storageResult, ArrayStorage::numValuesInVectorOffset())); - store32(Imm32(initialLength), Address(storageResult, ArrayStorage::vectorLengthOffset())); - store32(TrustedImm32(0), Address(storageResult, ArrayStorage::indexBiasOffset())); - storePtr(TrustedImmPtr(0), Address(storageResult, ArrayStorage::sparseMapOffset())); + // Store all the necessary info in the indexing header. + store32(Imm32(length), Address(storageResult, Butterfly::offsetOfPublicLength())); + store32(Imm32(initialLength), Address(storageResult, Butterfly::offsetOfVectorLength())); // Store the newly allocated ArrayStorage. storePtr(storageResult, Address(cellResult, JSObject::butterflyOffset())); @@ -470,12 +474,12 @@ inline void JIT::emitAllocateJSArray(unsigned valuesRegister, unsigned length, R for (unsigned i = 0; i < length; i++) { #if USE(JSVALUE64) loadPtr(Address(callFrameRegister, (valuesRegister + i) * sizeof(Register)), storagePtr); - storePtr(storagePtr, Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i)); + storePtr(storagePtr, Address(storageResult, sizeof(WriteBarrier<Unknown>) * i)); #else load32(Address(callFrameRegister, (valuesRegister + i) * sizeof(Register)), storagePtr); - store32(storagePtr, Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i)); + store32(storagePtr, Address(storageResult, sizeof(WriteBarrier<Unknown>) * i)); load32(Address(callFrameRegister, (valuesRegister + i) * sizeof(Register) + sizeof(uint32_t)), storagePtr); - store32(storagePtr, Address(storageResult, ArrayStorage::vectorOffset() + sizeof(WriteBarrier<Unknown>) * i + sizeof(uint32_t))); + store32(storagePtr, Address(storageResult, sizeof(WriteBarrier<Unknown>) * i + sizeof(uint32_t))); #endif } } @@ -559,10 +563,29 @@ inline void JIT::emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndI inline void JIT::emitArrayProfileStoreToHoleSpecialCase(ArrayProfile* arrayProfile) { - if (!canBeOptimized()) - return; - +#if ENABLE(VALUE_PROFILER) store8(TrustedImm32(1), arrayProfile->addressOfMayStoreToHole()); +#else + UNUSED_PARAM(arrayProfile); +#endif +} + +static inline bool arrayProfileSaw(ArrayProfile* profile, IndexingType capability) +{ +#if ENABLE(VALUE_PROFILER) + return !!(profile->observedArrayModes() & (asArrayModes(NonArray | capability) | asArrayModes(ArrayClass | capability))); +#else + UNUSED_PARAM(profile); + UNUSED_PARAM(capability); + return false; +#endif +} + +inline JITArrayMode JIT::chooseArrayMode(ArrayProfile* profile) +{ + if (arrayProfileSaw(profile, ArrayStorageShape)) + return JITArrayStorage; + return JITContiguous; } #if USE(JSVALUE32_64) @@ -755,7 +778,7 @@ inline void JIT::unmap(RegisterID registerID) inline void JIT::unmap() { m_mappedBytecodeOffset = (unsigned)-1; - m_mappedVirtualRegisterIndex = RegisterFile::ReturnPC; + m_mappedVirtualRegisterIndex = JSStack::ReturnPC; m_mappedTag = (RegisterID)-1; m_mappedPayload = (RegisterID)-1; } diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp index 3b7f38dc7..33db1d44f 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp @@ -76,11 +76,11 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl // Finish canonical initialization before JS function call. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); // Also initialize ReturnPC for use by lazy linking and exceptions. preserveReturnAddressAfterCall(regT3); - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); storePtr(callFrameRegister, &m_globalData->topCallFrame); restoreArgumentReference(); @@ -96,11 +96,11 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl // Finish canonical initialization before JS function call. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); // Also initialize ReturnPC for use by lazy linking and exeptions. preserveReturnAddressAfterCall(regT3); - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); storePtr(callFrameRegister, &m_globalData->topCallFrame); restoreArgumentReference(); @@ -116,7 +116,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl // Finish canonical initialization before JS function call. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); Jump hasCodeBlock1 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForCall)), TrustedImm32(0)); @@ -139,7 +139,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl // Finish canonical initialization before JS function call. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); Jump hasCodeBlock2 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForConstruct)), TrustedImm32(0)); @@ -156,37 +156,37 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl callSlowCase.link(this); // Finish canonical initialization before JS function call. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2, regT2); - emitPutCellToCallFrameHeader(regT2, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2, regT2); + emitPutCellToCallFrameHeader(regT2, JSStack::ScopeChain); // Also initialize ReturnPC and CodeBlock, like a JS function would. preserveReturnAddressAfterCall(regT3); - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); - emitPutImmediateToCallFrameHeader(0, RegisterFile::CodeBlock); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); + emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock); storePtr(callFrameRegister, &m_globalData->topCallFrame); restoreArgumentReference(); Call callCallNotJSFunction = call(); - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); restoreReturnAddressBeforeReturn(regT3); ret(); constructSlowCase.link(this); // Finish canonical initialization before JS function call. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2, regT2); - emitPutCellToCallFrameHeader(regT2, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2, regT2); + emitPutCellToCallFrameHeader(regT2, JSStack::ScopeChain); // Also initialize ReturnPC and CodeBlock, like a JS function would. preserveReturnAddressAfterCall(regT3); - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); - emitPutImmediateToCallFrameHeader(0, RegisterFile::CodeBlock); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); + emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock); storePtr(callFrameRegister, &m_globalData->topCallFrame); restoreArgumentReference(); Call callConstructNotJSFunction = call(); - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); restoreReturnAddressBeforeReturn(regT3); ret(); @@ -231,18 +231,18 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon Label nativeCallThunk = align(); - emitPutImmediateToCallFrameHeader(0, RegisterFile::CodeBlock); + emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock); storePtr(callFrameRegister, &m_globalData->topCallFrame); #if CPU(X86_64) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); peek(regT1); - emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT1, JSStack::ReturnPC); // Calling convention: f(edi, esi, edx, ecx, ...); // Host function signature: f(ExecState*); @@ -250,7 +250,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon subPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister); // Align stack after call. - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::esi); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, X86Registers::esi); loadPtr(Address(X86Registers::esi, OBJECT_OFFSETOF(JSFunction, m_executable)), X86Registers::r9); move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. call(Address(X86Registers::r9, executableOffsetToFunction)); @@ -260,18 +260,18 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon #elif CPU(ARM) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT2); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); preserveReturnAddressAfterCall(regT3); // Callee preserved - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); // Calling convention: f(r0 == regT0, r1 == regT1, ...); // Host function signature: f(ExecState*); move(callFrameRegister, ARMRegisters::r0); - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, ARMRegisters::r1); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, ARMRegisters::r1); move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. loadPtr(Address(ARMRegisters::r1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); call(Address(regT2, executableOffsetToFunction)); @@ -281,12 +281,12 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon #elif CPU(MIPS) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); preserveReturnAddressAfterCall(regT3); // Callee preserved - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); // Calling convention: f(a0, a1, a2, a3); // Host function signature: f(ExecState*); @@ -299,7 +299,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon move(callFrameRegister, MIPSRegisters::a0); // Call - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, MIPSRegisters::a2); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, MIPSRegisters::a2); loadPtr(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. call(Address(regT2, executableOffsetToFunction)); @@ -382,7 +382,7 @@ void JIT::emit_op_end(Instruction* currentInstruction) { ASSERT(returnValueRegister != callFrameRegister); emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister); - restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)))); + restoreReturnAddressBeforeReturn(Address(callFrameRegister, JSStack::ReturnPC * static_cast<int>(sizeof(Register)))); ret(); } @@ -583,10 +583,10 @@ void JIT::emit_op_ret(Instruction* currentInstruction) emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister); // Grab the return address. - emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); + emitGetFromCallFrameHeaderPtr(JSStack::ReturnPC, regT1); // Restore our caller's "r". - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); // Return. restoreReturnAddressBeforeReturn(regT1); @@ -606,10 +606,10 @@ void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction) Jump notObject = emitJumpIfNotObject(regT2); // Grab the return address. - emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); + emitGetFromCallFrameHeaderPtr(JSStack::ReturnPC, regT1); // Restore our caller's "r". - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); // Return. restoreReturnAddressBeforeReturn(regT1); @@ -621,10 +621,10 @@ void JIT::emit_op_ret_object_or_this(Instruction* currentInstruction) emitGetVirtualRegister(currentInstruction[2].u.operand, returnValueRegister); // Grab the return address. - emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1); + emitGetFromCallFrameHeaderPtr(JSStack::ReturnPC, regT1); // Restore our caller's "r". - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); // Return. restoreReturnAddressBeforeReturn(regT1); @@ -798,11 +798,11 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction) void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) { unsigned src = currentInstruction[1].u.operand; - JSCell* ptr = currentInstruction[2].u.jsCell.get(); + Special::Pointer ptr = currentInstruction[2].u.specialPointer; unsigned target = currentInstruction[3].u.operand; emitGetVirtualRegister(src, regT0); - addJump(branchPtr(NotEqual, regT0, TrustedImmPtr(JSValue::encode(JSValue(ptr)))), target); + addJump(branchPtr(NotEqual, regT0, TrustedImmPtr(actualPointerFor(m_codeBlock, ptr))), target); } void JIT::emit_op_eq(Instruction* currentInstruction) @@ -1285,7 +1285,7 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction) void JIT::emit_op_create_this(Instruction* currentInstruction) { - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0); loadPtr(Address(regT0, JSFunction::offsetOfCachedInheritorID()), regT2); addSlowCase(branchTestPtr(Zero, regT2)); @@ -1509,7 +1509,7 @@ void JIT::emit_op_get_arguments_length(Instruction* currentInstruction) int dst = currentInstruction[1].u.operand; int argumentsRegister = currentInstruction[2].u.operand; addSlowCase(branchTestPtr(NonZero, addressFor(argumentsRegister))); - emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0); + emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT0); sub32(TrustedImm32(1), regT0); emitFastArithReTagImmediate(regT0, regT0); emitPutVirtualRegister(dst, regT0); @@ -1539,7 +1539,7 @@ void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction) addSlowCase(emitJumpIfNotImmediateInteger(regT1)); add32(TrustedImm32(1), regT1); // regT1 now contains the integer index of the argument we want, including this - emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT2); + emitGetFromCallFrameHeader32(JSStack::ArgumentCount, regT2); addSlowCase(branch32(AboveOrEqual, regT1, regT2)); neg32(regT1); @@ -1565,7 +1565,7 @@ void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vecto emitPutVirtualRegister(unmodifiedArgumentsRegister(arguments)); skipArgumentsCreation.link(this); - JITStubCall stubCall(this, cti_op_get_by_val); + JITStubCall stubCall(this, cti_op_get_by_val_generic); stubCall.addArgument(arguments, regT2); stubCall.addArgument(property, regT2); stubCall.callWithValueProfiling(dst); @@ -1577,7 +1577,7 @@ void JIT::emit_op_resolve_global_dynamic(Instruction* currentInstruction) { int skip = currentInstruction[5].u.operand; - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT0); bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain(); ASSERT(skip || !checkTopLevel); @@ -1661,7 +1661,8 @@ void JIT::emit_op_new_func_exp(Instruction* currentInstruction) void JIT::emit_op_new_array(Instruction* currentInstruction) { int length = currentInstruction[3].u.operand; - if (CopiedSpace::isOversize(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(length)))) { + if (m_codeBlock->globalObject()->isHavingABadTime() + || CopiedSpace::isOversize(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(length)))) { JITStubCall stubCall(this, cti_op_new_array); stubCall.addArgument(TrustedImm32(currentInstruction[2].u.operand)); stubCall.addArgument(TrustedImm32(currentInstruction[3].u.operand)); @@ -1680,8 +1681,10 @@ void JIT::emitSlow_op_new_array(Instruction* currentInstruction, Vector<SlowCase // If the allocation would be oversize, we will already make the proper stub call above in // emit_op_new_array. int length = currentInstruction[3].u.operand; - if (CopiedSpace::isOversize(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(length)))) + if (m_codeBlock->globalObject()->isHavingABadTime() + || CopiedSpace::isOversize(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(length)))) return; + linkSlowCase(iter); // We're having a bad time. linkSlowCase(iter); // Not enough space in CopiedSpace for storage. linkSlowCase(iter); // Not enough space in MarkedSpace for cell. diff --git a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp index 21744fba8..db5365535 100644 --- a/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp +++ b/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp @@ -70,11 +70,11 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl // Finish canonical initialization before JS function call. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); // Also initialize ReturnPC for use by lazy linking and exceptions. preserveReturnAddressAfterCall(regT3); - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); storePtr(callFrameRegister, &m_globalData->topCallFrame); restoreArgumentReference(); @@ -90,11 +90,11 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl // Finish canonical initialization before JS function call. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); // Also initialize ReturnPC for use by lazy linking and exeptions. preserveReturnAddressAfterCall(regT3); - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); storePtr(callFrameRegister, &m_globalData->topCallFrame); restoreArgumentReference(); @@ -110,7 +110,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl // Finish canonical initialization before JS function call. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); Jump hasCodeBlock1 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForCall)), TrustedImm32(0)); @@ -134,7 +134,7 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl // Finish canonical initialization before JS function call. loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_scope)), regT1); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); Jump hasCodeBlock2 = branch32(GreaterThanOrEqual, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParametersForConstruct)), TrustedImm32(0)); @@ -152,37 +152,37 @@ PassRefPtr<ExecutableMemoryHandle> JIT::privateCompileCTIMachineTrampolines(JSGl callSlowCase.link(this); // Finish canonical initialization before JS function call. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2, regT2); - emitPutCellToCallFrameHeader(regT2, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2, regT2); + emitPutCellToCallFrameHeader(regT2, JSStack::ScopeChain); // Also initialize ReturnPC and CodeBlock, like a JS function would. preserveReturnAddressAfterCall(regT3); - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); - emitPutImmediateToCallFrameHeader(0, RegisterFile::CodeBlock); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); + emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock); storePtr(callFrameRegister, &m_globalData->topCallFrame); restoreArgumentReference(); Call callCallNotJSFunction = call(); - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); restoreReturnAddressBeforeReturn(regT3); ret(); constructSlowCase.link(this); // Finish canonical initialization before JS function call. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2, regT2); - emitPutCellToCallFrameHeader(regT2, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2, regT2); + emitPutCellToCallFrameHeader(regT2, JSStack::ScopeChain); // Also initialize ReturnPC and CodeBlock, like a JS function would. preserveReturnAddressAfterCall(regT3); - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); - emitPutImmediateToCallFrameHeader(0, RegisterFile::CodeBlock); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); + emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock); storePtr(callFrameRegister, &m_globalData->topCallFrame); restoreArgumentReference(); Call callConstructNotJSFunction = call(); - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, callFrameRegister); restoreReturnAddressBeforeReturn(regT3); ret(); @@ -227,18 +227,18 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon Label nativeCallThunk = align(); - emitPutImmediateToCallFrameHeader(0, RegisterFile::CodeBlock); + emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock); storePtr(callFrameRegister, &m_globalData->topCallFrame); #if CPU(X86) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); peek(regT1); - emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT1, JSStack::ReturnPC); // Calling convention: f(ecx, edx, ...); // Host function signature: f(ExecState*); @@ -247,7 +247,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon subPtr(TrustedImm32(16 - sizeof(void*)), stackPointerRegister); // Align stack after call. // call the function - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT1); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT1); loadPtr(Address(regT1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT1); move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. call(Address(regT1, executableOffsetToFunction)); @@ -257,19 +257,19 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon #elif CPU(ARM) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT2); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); preserveReturnAddressAfterCall(regT3); // Callee preserved - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); // Calling convention: f(r0 == regT0, r1 == regT1, ...); // Host function signature: f(ExecState*); move(callFrameRegister, ARMRegisters::r0); // call the function - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, ARMRegisters::r1); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, ARMRegisters::r1); move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. loadPtr(Address(ARMRegisters::r1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); call(Address(regT2, executableOffsetToFunction)); @@ -278,18 +278,18 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon #elif CPU(SH4) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT2); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); preserveReturnAddressAfterCall(regT3); // Callee preserved - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); // Calling convention: f(r0 == regT4, r1 == regT5, ...); // Host function signature: f(ExecState*); move(callFrameRegister, regT4); - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT5); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT5); move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. loadPtr(Address(regT5, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); @@ -298,12 +298,12 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon #elif CPU(MIPS) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); preserveReturnAddressAfterCall(regT3); // Callee preserved - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); // Calling convention: f(a0, a1, a2, a3); // Host function signature: f(ExecState*); @@ -316,7 +316,7 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon move(callFrameRegister, MIPSRegisters::a0); // Call - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, MIPSRegisters::a2); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, MIPSRegisters::a2); loadPtr(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. call(Address(regT2, executableOffsetToFunction)); @@ -362,18 +362,18 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFu { Call nativeCall; - emitPutImmediateToCallFrameHeader(0, RegisterFile::CodeBlock); + emitPutImmediateToCallFrameHeader(0, JSStack::CodeBlock); storePtr(callFrameRegister, &m_globalData->topCallFrame); #if CPU(X86) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); peek(regT1); - emitPutToCallFrameHeader(regT1, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT1, JSStack::ReturnPC); // Calling convention: f(ecx, edx, ...); // Host function signature: f(ExecState*); @@ -391,18 +391,18 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFu #elif CPU(ARM) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT2); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); preserveReturnAddressAfterCall(regT3); // Callee preserved - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); // Calling convention: f(r0 == regT0, r1 == regT1, ...); // Host function signature: f(ExecState*); move(callFrameRegister, ARMRegisters::r0); - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, ARMRegisters::r1); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, ARMRegisters::r1); move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. loadPtr(Address(ARMRegisters::r1, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); @@ -414,12 +414,12 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFu #elif CPU(MIPS) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT0); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); preserveReturnAddressAfterCall(regT3); // Callee preserved - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); // Calling convention: f(a0, a1, a2, a3); // Host function signature: f(ExecState*); @@ -432,7 +432,7 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFu move(callFrameRegister, MIPSRegisters::a0); // Call - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, MIPSRegisters::a2); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, MIPSRegisters::a2); loadPtr(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. @@ -446,18 +446,18 @@ JIT::CodeRef JIT::privateCompileCTINativeCall(JSGlobalData* globalData, NativeFu #elif CPU(SH4) // Load caller frame's scope chain into this callframe so that whatever we call can // get to its global data. - emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT2); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT2); - emitPutCellToCallFrameHeader(regT1, RegisterFile::ScopeChain); + emitGetFromCallFrameHeaderPtr(JSStack::CallerFrame, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1, regT2); + emitPutCellToCallFrameHeader(regT1, JSStack::ScopeChain); preserveReturnAddressAfterCall(regT3); // Callee preserved - emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC); + emitPutToCallFrameHeader(regT3, JSStack::ReturnPC); // Calling convention: f(r0 == regT4, r1 == regT5, ...); // Host function signature: f(ExecState*); move(callFrameRegister, regT4); - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT5); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT5); move(regT2, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack. loadPtr(Address(regT5, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2); @@ -518,7 +518,7 @@ void JIT::emit_op_end(Instruction* currentInstruction) { ASSERT(returnValueRegister != callFrameRegister); emitLoad(currentInstruction[1].u.operand, regT1, regT0); - restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)))); + restoreReturnAddressBeforeReturn(Address(callFrameRegister, JSStack::ReturnPC * static_cast<int>(sizeof(Register)))); ret(); } @@ -975,12 +975,12 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction) void JIT::emit_op_jneq_ptr(Instruction* currentInstruction) { unsigned src = currentInstruction[1].u.operand; - JSCell* ptr = currentInstruction[2].u.jsCell.get(); + Special::Pointer ptr = currentInstruction[2].u.specialPointer; unsigned target = currentInstruction[3].u.operand; emitLoad(src, regT1, regT0); addJump(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)), target); - addJump(branchPtr(NotEqual, regT0, TrustedImmPtr(ptr)), target); + addJump(branchPtr(NotEqual, regT0, TrustedImmPtr(actualPointerFor(m_codeBlock, ptr))), target); } void JIT::emit_op_eq(Instruction* currentInstruction) @@ -1544,7 +1544,7 @@ void JIT::emit_op_init_lazy_reg(Instruction* currentInstruction) void JIT::emit_op_create_this(Instruction* currentInstruction) { - emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::Callee, regT0); loadPtr(Address(regT0, JSFunction::offsetOfCachedInheritorID()), regT2); addSlowCase(branchTestPtr(Zero, regT2)); @@ -1626,7 +1626,7 @@ void JIT::emit_op_get_arguments_length(Instruction* currentInstruction) int dst = currentInstruction[1].u.operand; int argumentsRegister = currentInstruction[2].u.operand; addSlowCase(branch32(NotEqual, tagFor(argumentsRegister), TrustedImm32(JSValue::EmptyValueTag))); - load32(payloadFor(RegisterFile::ArgumentCount), regT0); + load32(payloadFor(JSStack::ArgumentCount), regT0); sub32(TrustedImm32(1), regT0); emitStoreInt32(dst, regT0); } @@ -1654,7 +1654,7 @@ void JIT::emit_op_get_argument_by_val(Instruction* currentInstruction) addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); add32(TrustedImm32(1), regT2); // regT2 now contains the integer index of the argument we want, including this - load32(payloadFor(RegisterFile::ArgumentCount), regT3); + load32(payloadFor(JSStack::ArgumentCount), regT3); addSlowCase(branch32(AboveOrEqual, regT2, regT3)); neg32(regT2); @@ -1680,7 +1680,7 @@ void JIT::emitSlow_op_get_argument_by_val(Instruction* currentInstruction, Vecto emitStore(unmodifiedArgumentsRegister(arguments), regT1, regT0); skipArgumentsCreation.link(this); - JITStubCall stubCall(this, cti_op_get_by_val); + JITStubCall stubCall(this, cti_op_get_by_val_generic); stubCall.addArgument(arguments); stubCall.addArgument(property); stubCall.callWithValueProfiling(dst); diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp index b4d52e225..9deded62a 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp @@ -97,6 +97,7 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) unsigned dst = currentInstruction[1].u.operand; unsigned base = currentInstruction[2].u.operand; unsigned property = currentInstruction[3].u.operand; + ArrayProfile* profile = currentInstruction[4].u.arrayProfile; emitGetVirtualRegisters(base, regT0, property, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); @@ -111,17 +112,69 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) emitJumpSlowCaseIfNotJSCell(regT0, base); loadPtr(Address(regT0, JSCell::structureOffset()), regT2); - emitArrayProfilingSite(regT2, regT3, currentInstruction[4].u.arrayProfile); - addSlowCase(branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage))); + emitArrayProfilingSite(regT2, regT3, profile); + and32(TrustedImm32(IndexingShapeMask), regT2); + + PatchableJump badType; + JumpList slowCases; + + JITArrayMode mode = chooseArrayMode(profile); + switch (mode) { + case JITContiguous: + slowCases = emitContiguousGetByVal(currentInstruction, badType); + break; + case JITArrayStorage: + slowCases = emitArrayStorageGetByVal(currentInstruction, badType); + break; + default: + CRASH(); + break; + } + + addSlowCase(badType); + addSlowCase(slowCases); + + Label done = label(); + +#if !ASSERT_DISABLED + Jump resultOK = branchTestPtr(NonZero, regT0); + breakpoint(); + resultOK.link(this); +#endif + emitValueProfilingSite(); + emitPutVirtualRegister(dst); + + m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done)); +} + +JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType) +{ + JumpList slowCases; + + badType = patchableBranch32(NotEqual, regT2, TrustedImm32(ContiguousShape)); loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); - addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, ArrayStorage::vectorLengthOffset()))); + slowCases.append(branch32(AboveOrEqual, regT1, Address(regT2, Butterfly::offsetOfPublicLength()))); + loadPtr(BaseIndex(regT2, regT1, ScalePtr), regT0); + slowCases.append(branchTestPtr(Zero, regT0)); + + return slowCases; +} - loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); - addSlowCase(branchTestPtr(Zero, regT0)); +JIT::JumpList JIT::emitArrayStorageGetByVal(Instruction*, PatchableJump& badType) +{ + JumpList slowCases; - emitValueProfilingSite(); - emitPutVirtualRegister(dst); + add32(TrustedImm32(-ArrayStorageShape), regT2, regT3); + badType = patchableBranch32(Above, regT3, TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape)); + + loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); + slowCases.append(branch32(AboveOrEqual, regT1, Address(regT2, ArrayStorage::vectorLengthOffset()))); + + loadPtr(BaseIndex(regT2, regT1, ScalePtr, ArrayStorage::vectorOffset()), regT0); + slowCases.append(branchTestPtr(Zero, regT0)); + + return slowCases; } void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -146,10 +199,16 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas linkSlowCase(iter); // vector length check linkSlowCase(iter); // empty value + Label slowPath = label(); + JITStubCall stubCall(this, cti_op_get_by_val); stubCall.addArgument(base, regT2); stubCall.addArgument(property, regT2); - stubCall.call(dst); + Call call = stubCall.call(dst); + + m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath; + m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call; + m_byValInstructionIndex++; emitValueProfilingSite(); } @@ -159,16 +218,16 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID ASSERT(sizeof(JSValue) == 8); if (finalObjectMode == MayBeFinal) { - Jump isInline = branch32(LessThan, offset, TrustedImm32(inlineStorageCapacity)); + Jump isInline = branch32(LessThan, offset, TrustedImm32(firstOutOfLineOffset)); loadPtr(Address(base, JSObject::butterflyOffset()), scratch); neg32(offset); Jump done = jump(); isInline.link(this); - addPtr(TrustedImm32(JSObject::offsetOfInlineStorage() - (inlineStorageCapacity - 2) * sizeof(EncodedJSValue)), base, scratch); + addPtr(TrustedImm32(JSObject::offsetOfInlineStorage() - (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue)), base, scratch); done.link(this); } else { #if !ASSERT_DISABLED - Jump isOutOfLine = branch32(GreaterThanOrEqual, offset, TrustedImm32(inlineStorageCapacity)); + Jump isOutOfLine = branch32(GreaterThanOrEqual, offset, TrustedImm32(firstOutOfLineOffset)); breakpoint(); isOutOfLine.link(this); #endif @@ -176,7 +235,7 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID neg32(offset); } signExtend32ToPtr(offset, offset); - loadPtr(BaseIndex(scratch, offset, ScalePtr, (inlineStorageCapacity - 2) * static_cast<ptrdiff_t>(sizeof(JSValue))), result); + loadPtr(BaseIndex(scratch, offset, ScalePtr, (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue)), result); } void JIT::emit_op_get_by_pname(Instruction* currentInstruction) @@ -199,7 +258,10 @@ void JIT::emit_op_get_by_pname(Instruction* currentInstruction) load32(addressFor(i), regT3); sub32(TrustedImm32(1), regT3); addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); - add32(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_offsetBase)), regT3); + Jump inlineProperty = branch32(Below, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructureInlineCapacity))); + add32(TrustedImm32(firstOutOfLineOffset), regT3); + sub32(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructureInlineCapacity)), regT3); + inlineProperty.link(this); compileGetDirectOffset(regT0, regT0, regT3, regT1); emitPutVirtualRegister(dst, regT0); @@ -226,7 +288,7 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) { unsigned base = currentInstruction[1].u.operand; unsigned property = currentInstruction[2].u.operand; - unsigned value = currentInstruction[3].u.operand; + ArrayProfile* profile = currentInstruction[4].u.arrayProfile; emitGetVirtualRegisters(base, regT0, property, regT1); emitJumpSlowCaseIfNotImmediateInteger(regT1); @@ -234,10 +296,76 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) zeroExtend32ToPtr(regT1, regT1); emitJumpSlowCaseIfNotJSCell(regT0, base); loadPtr(Address(regT0, JSCell::structureOffset()), regT2); - emitArrayProfilingSite(regT2, regT3, currentInstruction[4].u.arrayProfile); - addSlowCase(branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage))); + emitArrayProfilingSite(regT2, regT3, profile); + and32(TrustedImm32(IndexingShapeMask), regT2); + + PatchableJump badType; + JumpList slowCases; + + JITArrayMode mode = chooseArrayMode(profile); + switch (mode) { + case JITContiguous: + slowCases = emitContiguousPutByVal(currentInstruction, badType); + break; + case JITArrayStorage: + slowCases = emitArrayStoragePutByVal(currentInstruction, badType); + break; + default: + CRASH(); + break; + } + + addSlowCase(badType); + addSlowCase(slowCases); + + Label done = label(); + + m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done)); + + emitWriteBarrier(regT0, regT3, regT1, regT3, ShouldFilterImmediates, WriteBarrierForPropertyAccess); +} + +JIT::JumpList JIT::emitContiguousPutByVal(Instruction* currentInstruction, PatchableJump& badType) +{ + unsigned value = currentInstruction[3].u.operand; + ArrayProfile* profile = currentInstruction[4].u.arrayProfile; + + badType = patchableBranch32(NotEqual, regT2, TrustedImm32(ContiguousShape)); + loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); - addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, ArrayStorage::vectorLengthOffset()))); + Jump outOfBounds = branch32(AboveOrEqual, regT1, Address(regT2, Butterfly::offsetOfPublicLength())); + + Label storeResult = label(); + emitGetVirtualRegister(value, regT3); + storePtr(regT3, BaseIndex(regT2, regT1, ScalePtr)); + + Jump done = jump(); + outOfBounds.link(this); + + JumpList slowCases; + slowCases.append(branch32(AboveOrEqual, regT1, Address(regT2, Butterfly::offsetOfVectorLength()))); + + emitArrayProfileStoreToHoleSpecialCase(profile); + + add32(TrustedImm32(1), regT1, regT3); + store32(regT3, Address(regT2, Butterfly::offsetOfPublicLength())); + jump().linkTo(storeResult, this); + + done.link(this); + + return slowCases; +} + +JIT::JumpList JIT::emitArrayStoragePutByVal(Instruction* currentInstruction, PatchableJump& badType) +{ + unsigned value = currentInstruction[3].u.operand; + ArrayProfile* profile = currentInstruction[4].u.arrayProfile; + + JumpList slowCases; + + badType = patchableBranch32(NotEqual, regT2, TrustedImm32(ArrayStorageShape)); + loadPtr(Address(regT0, JSObject::butterflyOffset()), regT2); + slowCases.append(branch32(AboveOrEqual, regT1, Address(regT2, ArrayStorage::vectorLengthOffset()))); Jump empty = branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); @@ -247,8 +375,8 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) Jump end = jump(); empty.link(this); - emitArrayProfileStoreToHoleSpecialCase(currentInstruction[4].u.arrayProfile); - add32(TrustedImm32(1), Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); + emitArrayProfileStoreToHoleSpecialCase(profile); + add32(TrustedImm32(1), Address(regT2, ArrayStorage::numValuesInVectorOffset())); branch32(Below, regT1, Address(regT2, ArrayStorage::lengthOffset())).linkTo(storeResult, this); add32(TrustedImm32(1), regT1); @@ -257,8 +385,8 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) jump().linkTo(storeResult, this); end.link(this); - - emitWriteBarrier(regT0, regT3, regT1, regT3, ShouldFilterImmediates, WriteBarrierForPropertyAccess); + + return slowCases; } void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -270,13 +398,19 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas linkSlowCase(iter); // property int32 check linkSlowCaseIfNotJSCell(iter, base); // base cell check linkSlowCase(iter); // base not array check - linkSlowCase(iter); // in vector check + linkSlowCase(iter); // out of bounds + + Label slowPath = label(); JITStubCall stubPutByValCall(this, cti_op_put_by_val); stubPutByValCall.addArgument(regT0); stubPutByValCall.addArgument(property, regT2); stubPutByValCall.addArgument(value, regT2); - stubPutByValCall.call(); + Call call = stubPutByValCall.call(); + + m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath; + m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call; + m_byValInstructionIndex++; } void JIT::emit_op_put_by_index(Instruction* currentInstruction) @@ -656,7 +790,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) loadPtr(Address(regT0, JSCell::structureOffset()), regT2); emitArrayProfilingSiteForBytecodeIndex(regT2, regT1, stubInfo->bytecodeIndex); Jump failureCases1 = branchTest32(Zero, regT2, TrustedImm32(IsArray)); - Jump failureCases2 = branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage)); + Jump failureCases2 = branchTest32(Zero, regT2, TrustedImm32(IndexingShapeMask)); // Checks out okay! - get the length from the storage loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); @@ -1060,7 +1194,7 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction) { int skip = currentInstruction[3].u.operand; - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT0); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT0); bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain(); ASSERT(skip || !checkTopLevel); if (checkTopLevel && skip--) { @@ -1085,7 +1219,7 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction) emitGetVirtualRegister(currentInstruction[3].u.operand, regT0); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT1); bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain(); ASSERT(skip || !checkTopLevel); if (checkTopLevel && skip--) { @@ -1274,6 +1408,377 @@ bool JIT::isDirectPutById(StructureStubInfo* stubInfo) } } +void JIT::privateCompileGetByVal(ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) +{ + Instruction* currentInstruction = m_codeBlock->instructions().begin() + byValInfo->bytecodeIndex; + + PatchableJump badType; + JumpList slowCases; + + switch (arrayMode) { + case JITContiguous: + slowCases = emitContiguousGetByVal(currentInstruction, badType); + break; + case JITArrayStorage: + slowCases = emitArrayStorageGetByVal(currentInstruction, badType); + break; + case JITInt8Array: + slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->int8ArrayDescriptor(), 1, SignedTypedArray); + break; + case JITInt16Array: + slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->int16ArrayDescriptor(), 2, SignedTypedArray); + break; + case JITInt32Array: + slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->int32ArrayDescriptor(), 4, SignedTypedArray); + break; + case JITUint8Array: + case JITUint8ClampedArray: + slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->uint8ArrayDescriptor(), 1, UnsignedTypedArray); + break; + case JITUint16Array: + slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->uint16ArrayDescriptor(), 2, UnsignedTypedArray); + break; + case JITUint32Array: + slowCases = emitIntTypedArrayGetByVal(currentInstruction, badType, m_globalData->uint32ArrayDescriptor(), 4, UnsignedTypedArray); + break; + case JITFloat32Array: + slowCases = emitFloatTypedArrayGetByVal(currentInstruction, badType, m_globalData->float32ArrayDescriptor(), 4); + break; + case JITFloat64Array: + slowCases = emitFloatTypedArrayGetByVal(currentInstruction, badType, m_globalData->float64ArrayDescriptor(), 8); + break; + default: + CRASH(); + } + + Jump done = jump(); + + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); + + patchBuffer.link(badType, CodeLocationLabel(returnAddress.value()).labelAtOffset(byValInfo->returnAddressToSlowPath)); + patchBuffer.link(slowCases, CodeLocationLabel(returnAddress.value()).labelAtOffset(byValInfo->returnAddressToSlowPath)); + + patchBuffer.link(done, byValInfo->badTypeJump.labelAtOffset(byValInfo->badTypeJumpToDone)); + + byValInfo->stubRoutine = FINALIZE_CODE_FOR_STUB( + patchBuffer, + ("Baseline get_by_val stub for CodeBlock %p, return point %p", m_codeBlock, returnAddress.value())); + + RepatchBuffer repatchBuffer(m_codeBlock); + repatchBuffer.relink(byValInfo->badTypeJump, CodeLocationLabel(byValInfo->stubRoutine->code().code())); + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_val_generic)); +} + +void JIT::privateCompilePutByVal(ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode) +{ + Instruction* currentInstruction = m_codeBlock->instructions().begin() + byValInfo->bytecodeIndex; + + PatchableJump badType; + JumpList slowCases; + + switch (arrayMode) { + case JITContiguous: + slowCases = emitContiguousPutByVal(currentInstruction, badType); + break; + case JITArrayStorage: + slowCases = emitArrayStoragePutByVal(currentInstruction, badType); + break; + case JITInt8Array: + slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->int8ArrayDescriptor(), 1, SignedTypedArray, TruncateRounding); + break; + case JITInt16Array: + slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->int16ArrayDescriptor(), 2, SignedTypedArray, TruncateRounding); + break; + case JITInt32Array: + slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->int32ArrayDescriptor(), 4, SignedTypedArray, TruncateRounding); + break; + case JITUint8Array: + slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->uint8ArrayDescriptor(), 1, UnsignedTypedArray, TruncateRounding); + break; + case JITUint8ClampedArray: + slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->uint8ClampedArrayDescriptor(), 1, UnsignedTypedArray, ClampRounding); + break; + case JITUint16Array: + slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->uint16ArrayDescriptor(), 2, UnsignedTypedArray, TruncateRounding); + break; + case JITUint32Array: + slowCases = emitIntTypedArrayPutByVal(currentInstruction, badType, m_globalData->uint32ArrayDescriptor(), 4, UnsignedTypedArray, TruncateRounding); + break; + case JITFloat32Array: + slowCases = emitFloatTypedArrayPutByVal(currentInstruction, badType, m_globalData->float32ArrayDescriptor(), 4); + break; + case JITFloat64Array: + slowCases = emitFloatTypedArrayPutByVal(currentInstruction, badType, m_globalData->float64ArrayDescriptor(), 8); + break; + default: + CRASH(); + break; + } + + Jump done = jump(); + + LinkBuffer patchBuffer(*m_globalData, this, m_codeBlock); + + patchBuffer.link(badType, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath)); + patchBuffer.link(slowCases, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(returnAddress.value())).labelAtOffset(byValInfo->returnAddressToSlowPath)); + + patchBuffer.link(done, byValInfo->badTypeJump.labelAtOffset(byValInfo->badTypeJumpToDone)); + + byValInfo->stubRoutine = FINALIZE_CODE_FOR_STUB( + patchBuffer, + ("Baseline put_by_val stub for CodeBlock %p, return point %p", m_codeBlock, returnAddress.value())); + + RepatchBuffer repatchBuffer(m_codeBlock); + repatchBuffer.relink(byValInfo->badTypeJump, CodeLocationLabel(byValInfo->stubRoutine->code().code())); + repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_put_by_val_generic)); +} + +JIT::JumpList JIT::emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, const TypedArrayDescriptor& descriptor, size_t elementSize, TypedArraySignedness signedness) +{ + // The best way to test the array type is to use the classInfo. We need to do so without + // clobbering the register that holds the indexing type, base, and property. + +#if USE(JSVALUE64) + RegisterID base = regT0; + RegisterID property = regT1; + RegisterID resultPayload = regT0; + RegisterID scratch = regT3; +#else + RegisterID base = regT0; + RegisterID property = regT2; + RegisterID resultPayload = regT0; + RegisterID resultTag = regT1; + RegisterID scratch = regT3; +#endif + + JumpList slowCases; + + loadPtr(Address(base, JSCell::structureOffset()), scratch); + badType = patchableBranchPtr(NotEqual, Address(scratch, Structure::classInfoOffset()), TrustedImmPtr(descriptor.m_classInfo)); + slowCases.append(branch32(AboveOrEqual, property, Address(base, descriptor.m_lengthOffset))); + loadPtr(Address(base, descriptor.m_storageOffset), base); + + switch (elementSize) { + case 1: + if (signedness == SignedTypedArray) + load8Signed(BaseIndex(base, property, TimesOne), resultPayload); + else + load8(BaseIndex(base, property, TimesOne), resultPayload); + break; + case 2: + if (signedness == SignedTypedArray) + load16Signed(BaseIndex(base, property, TimesTwo), resultPayload); + else + load16(BaseIndex(base, property, TimesTwo), resultPayload); + break; + case 4: + load32(BaseIndex(base, property, TimesFour), resultPayload); + break; + default: + CRASH(); + } + + Jump done; + if (elementSize == 4 && signedness == UnsignedTypedArray) { + Jump canBeInt = branch32(GreaterThanOrEqual, resultPayload, TrustedImm32(0)); + + convertInt32ToDouble(resultPayload, fpRegT0); + addDouble(AbsoluteAddress(&twoToThe32), fpRegT0); +#if USE(JSVALUE64) + moveDoubleToPtr(fpRegT0, resultPayload); + subPtr(tagTypeNumberRegister, resultPayload); +#else + moveDoubleToInts(fpRegT0, resultPayload, resultTag); +#endif + + done = jump(); + canBeInt.link(this); + } + +#if USE(JSVALUE64) + orPtr(tagTypeNumberRegister, resultPayload); +#else + move(TrustedImm32(JSValue::Int32Tag), resultTag); +#endif + if (done.isSet()) + done.link(this); + return slowCases; +} + +JIT::JumpList JIT::emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badType, const TypedArrayDescriptor& descriptor, size_t elementSize) +{ +#if USE(JSVALUE64) + RegisterID base = regT0; + RegisterID property = regT1; + RegisterID resultPayload = regT0; + RegisterID scratch = regT3; +#else + RegisterID base = regT0; + RegisterID property = regT2; + RegisterID resultPayload = regT0; + RegisterID resultTag = regT1; + RegisterID scratch = regT3; +#endif + + JumpList slowCases; + + loadPtr(Address(base, JSCell::structureOffset()), scratch); + badType = patchableBranchPtr(NotEqual, Address(scratch, Structure::classInfoOffset()), TrustedImmPtr(descriptor.m_classInfo)); + slowCases.append(branch32(AboveOrEqual, property, Address(base, descriptor.m_lengthOffset))); + loadPtr(Address(base, descriptor.m_storageOffset), base); + + switch (elementSize) { + case 4: + loadFloat(BaseIndex(base, property, TimesFour), fpRegT0); + convertFloatToDouble(fpRegT0, fpRegT0); + break; + case 8: { + loadDouble(BaseIndex(base, property, TimesEight), fpRegT0); + Jump notNaN = branchDouble(DoubleEqual, fpRegT0, fpRegT0); + static const double NaN = std::numeric_limits<double>::quiet_NaN(); + loadDouble(&NaN, fpRegT0); + notNaN.link(this); + break; + } + default: + CRASH(); + } + +#if USE(JSVALUE64) + moveDoubleToPtr(fpRegT0, resultPayload); + subPtr(tagTypeNumberRegister, resultPayload); +#else + moveDoubleToInts(fpRegT0, resultPayload, resultTag); +#endif + return slowCases; +} + +JIT::JumpList JIT::emitIntTypedArrayPutByVal(Instruction* currentInstruction, PatchableJump& badType, const TypedArrayDescriptor& descriptor, size_t elementSize, TypedArraySignedness signedness, TypedArrayRounding rounding) +{ + unsigned value = currentInstruction[3].u.operand; + +#if USE(JSVALUE64) + RegisterID base = regT0; + RegisterID property = regT1; + RegisterID earlyScratch = regT3; + RegisterID lateScratch = regT2; +#else + RegisterID base = regT0; + RegisterID property = regT2; + RegisterID earlyScratch = regT3; + RegisterID lateScratch = regT1; +#endif + + JumpList slowCases; + + loadPtr(Address(base, JSCell::structureOffset()), earlyScratch); + badType = patchableBranchPtr(NotEqual, Address(earlyScratch, Structure::classInfoOffset()), TrustedImmPtr(descriptor.m_classInfo)); + slowCases.append(branch32(AboveOrEqual, property, Address(base, descriptor.m_lengthOffset))); + +#if USE(JSVALUE64) + emitGetVirtualRegister(value, earlyScratch); + slowCases.append(emitJumpIfNotImmediateInteger(earlyScratch)); +#else + emitLoad(value, lateScratch, earlyScratch); + slowCases.append(branch32(NotEqual, lateScratch, TrustedImm32(JSValue::Int32Tag))); +#endif + + // We would be loading this into base as in get_by_val, except that the slow + // path expects the base to be unclobbered. + loadPtr(Address(base, descriptor.m_storageOffset), lateScratch); + + if (rounding == ClampRounding) { + ASSERT(elementSize == 1); + ASSERT_UNUSED(signedness, signedness = UnsignedTypedArray); + Jump inBounds = branch32(BelowOrEqual, earlyScratch, TrustedImm32(0xff)); + Jump tooBig = branch32(GreaterThan, earlyScratch, TrustedImm32(0xff)); + xor32(earlyScratch, earlyScratch); + Jump clamped = jump(); + tooBig.link(this); + move(TrustedImm32(0xff), earlyScratch); + clamped.link(this); + inBounds.link(this); + } + + switch (elementSize) { + case 1: + store8(earlyScratch, BaseIndex(lateScratch, property, TimesOne)); + break; + case 2: + store16(earlyScratch, BaseIndex(lateScratch, property, TimesTwo)); + break; + case 4: + store32(earlyScratch, BaseIndex(lateScratch, property, TimesFour)); + break; + default: + CRASH(); + } + + return slowCases; +} + +JIT::JumpList JIT::emitFloatTypedArrayPutByVal(Instruction* currentInstruction, PatchableJump& badType, const TypedArrayDescriptor& descriptor, size_t elementSize) +{ + unsigned value = currentInstruction[3].u.operand; + +#if USE(JSVALUE64) + RegisterID base = regT0; + RegisterID property = regT1; + RegisterID earlyScratch = regT3; + RegisterID lateScratch = regT2; +#else + RegisterID base = regT0; + RegisterID property = regT2; + RegisterID earlyScratch = regT3; + RegisterID lateScratch = regT1; +#endif + + JumpList slowCases; + + loadPtr(Address(base, JSCell::structureOffset()), earlyScratch); + badType = patchableBranchPtr(NotEqual, Address(earlyScratch, Structure::classInfoOffset()), TrustedImmPtr(descriptor.m_classInfo)); + slowCases.append(branch32(AboveOrEqual, property, Address(base, descriptor.m_lengthOffset))); + +#if USE(JSVALUE64) + emitGetVirtualRegister(value, earlyScratch); + Jump doubleCase = emitJumpIfNotImmediateInteger(earlyScratch); + convertInt32ToDouble(earlyScratch, fpRegT0); + Jump ready = jump(); + doubleCase.link(this); + slowCases.append(emitJumpIfNotImmediateNumber(earlyScratch)); + addPtr(tagTypeNumberRegister, earlyScratch); + movePtrToDouble(earlyScratch, fpRegT0); + ready.link(this); +#else + emitLoad(value, lateScratch, earlyScratch); + Jump doubleCase = branch32(NotEqual, lateScratch, TrustedImm32(JSValue::Int32Tag)); + convertInt32ToDouble(earlyScratch, fpRegT0); + Jump ready = jump(); + doubleCase.link(this); + slowCases.append(branch32(Above, lateScratch, TrustedImm32(JSValue::LowestTag))); + moveIntsToDouble(earlyScratch, lateScratch, fpRegT0, fpRegT1); + ready.link(this); +#endif + + // We would be loading this into base as in get_by_val, except that the slow + // path expects the base to be unclobbered. + loadPtr(Address(base, descriptor.m_storageOffset), lateScratch); + + switch (elementSize) { + case 4: + convertDoubleToFloat(fpRegT0, fpRegT0); + storeFloat(fpRegT0, BaseIndex(lateScratch, property, TimesFour)); + break; + case 8: + storeDouble(fpRegT0, BaseIndex(lateScratch, property, TimesEight)); + break; + default: + CRASH(); + } + + return slowCases; +} + } // namespace JSC #endif // ENABLE(JIT) diff --git a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp index ed561a28b..e7c4a479b 100644 --- a/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp +++ b/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp @@ -204,27 +204,82 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction) unsigned dst = currentInstruction[1].u.operand; unsigned base = currentInstruction[2].u.operand; unsigned property = currentInstruction[3].u.operand; + ArrayProfile* profile = currentInstruction[4].u.arrayProfile; emitLoad2(base, regT1, regT0, property, regT3, regT2); addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); emitJumpSlowCaseIfNotJSCell(base, regT1); loadPtr(Address(regT0, JSCell::structureOffset()), regT1); - emitArrayProfilingSite(regT1, regT3, currentInstruction[4].u.arrayProfile); - addSlowCase(branchTest32(Zero, regT1, TrustedImm32(HasArrayStorage))); - - loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); - addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset()))); + emitArrayProfilingSite(regT1, regT3, profile); + and32(TrustedImm32(IndexingShapeMask), regT1); + + PatchableJump badType; + JumpList slowCases; + + JITArrayMode mode = chooseArrayMode(profile); + switch (mode) { + case JITContiguous: + slowCases = emitContiguousGetByVal(currentInstruction, badType); + break; + case JITArrayStorage: + slowCases = emitArrayStorageGetByVal(currentInstruction, badType); + break; + default: + CRASH(); + } - load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag - load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload - addSlowCase(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag))); + addSlowCase(badType); + addSlowCase(slowCases); + Label done = label(); + +#if !ASSERT_DISABLED + Jump resultOK = branch32(NotEqual, regT1, TrustedImm32(JSValue::EmptyValueTag)); + breakpoint(); + resultOK.link(this); +#endif + emitValueProfilingSite(); emitStore(dst, regT1, regT0); map(m_bytecodeOffset + OPCODE_LENGTH(op_get_by_val), dst, regT1, regT0); + + m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done)); +} + +JIT::JumpList JIT::emitContiguousGetByVal(Instruction*, PatchableJump& badType) +{ + JumpList slowCases; + + badType = patchableBranch32(NotEqual, regT1, TrustedImm32(ContiguousShape)); + + loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); + slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, Butterfly::offsetOfPublicLength()))); + + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload + slowCases.append(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag))); + + return slowCases; } +JIT::JumpList JIT::emitArrayStorageGetByVal(Instruction*, PatchableJump& badType) +{ + JumpList slowCases; + + add32(TrustedImm32(-ArrayStorageShape), regT1, regT3); + badType = patchableBranch32(Above, regT3, TrustedImm32(SlowPutArrayStorageShape - ArrayStorageShape)); + + loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); + slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset()))); + + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT1); // tag + load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT0); // payload + slowCases.append(branch32(Equal, regT1, TrustedImm32(JSValue::EmptyValueTag))); + + return slowCases; +} + void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) { unsigned dst = currentInstruction[1].u.operand; @@ -248,10 +303,16 @@ void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCas linkSlowCase(iter); // vector length check linkSlowCase(iter); // empty value + Label slowPath = label(); + JITStubCall stubCall(this, cti_op_get_by_val); stubCall.addArgument(base); stubCall.addArgument(property); - stubCall.call(dst); + Call call = stubCall.call(dst); + + m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath; + m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call; + m_byValInstructionIndex++; emitValueProfilingSite(); } @@ -260,20 +321,86 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) { unsigned base = currentInstruction[1].u.operand; unsigned property = currentInstruction[2].u.operand; - unsigned value = currentInstruction[3].u.operand; + ArrayProfile* profile = currentInstruction[4].u.arrayProfile; emitLoad2(base, regT1, regT0, property, regT3, regT2); addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); emitJumpSlowCaseIfNotJSCell(base, regT1); loadPtr(Address(regT0, JSCell::structureOffset()), regT1); - emitArrayProfilingSite(regT1, regT3, currentInstruction[4].u.arrayProfile); - addSlowCase(branchTest32(Zero, regT1, TrustedImm32(HasArrayStorage))); - loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); - addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset()))); + emitArrayProfilingSite(regT1, regT3, profile); + and32(TrustedImm32(IndexingShapeMask), regT1); + + PatchableJump badType; + JumpList slowCases; + + JITArrayMode mode = chooseArrayMode(profile); + switch (mode) { + case JITContiguous: + slowCases = emitContiguousPutByVal(currentInstruction, badType); + break; + case JITArrayStorage: + slowCases = emitArrayStoragePutByVal(currentInstruction, badType); + break; + default: + CRASH(); + break; + } + + addSlowCase(badType); + addSlowCase(slowCases); + + Label done = label(); + + m_byValCompilationInfo.append(ByValCompilationInfo(m_bytecodeOffset, badType, mode, done)); +} +JIT::JumpList JIT::emitContiguousPutByVal(Instruction* currentInstruction, PatchableJump& badType) +{ + unsigned value = currentInstruction[3].u.operand; + ArrayProfile* profile = currentInstruction[4].u.arrayProfile; + + JumpList slowCases; + + badType = patchableBranch32(NotEqual, regT1, TrustedImm32(ContiguousShape)); + + loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); + Jump outOfBounds = branch32(AboveOrEqual, regT2, Address(regT3, Butterfly::offsetOfPublicLength())); + + Label storeResult = label(); + emitLoad(value, regT1, regT0); + store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload))); + store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag))); + Jump done = jump(); + + outOfBounds.link(this); + slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, Butterfly::offsetOfVectorLength()))); + + emitArrayProfileStoreToHoleSpecialCase(profile); + + add32(TrustedImm32(1), regT2, regT1); + store32(regT1, Address(regT3, Butterfly::offsetOfPublicLength())); + jump().linkTo(storeResult, this); + + done.link(this); + emitWriteBarrier(regT0, regT1, regT1, regT3, UnconditionalWriteBarrier, WriteBarrierForPropertyAccess); + return slowCases; +} + +JIT::JumpList JIT::emitArrayStoragePutByVal(Instruction* currentInstruction, PatchableJump& badType) +{ + unsigned value = currentInstruction[3].u.operand; + ArrayProfile* profile = currentInstruction[4].u.arrayProfile; + + JumpList slowCases; + + badType = patchableBranch32(NotEqual, regT1, TrustedImm32(ArrayStorageShape)); + + loadPtr(Address(regT0, JSObject::butterflyOffset()), regT3); + slowCases.append(branch32(AboveOrEqual, regT2, Address(regT3, ArrayStorage::vectorLengthOffset()))); + Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag)); Label storeResult(this); @@ -283,7 +410,7 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) Jump end = jump(); empty.link(this); - emitArrayProfileStoreToHoleSpecialCase(currentInstruction[4].u.arrayProfile); + emitArrayProfileStoreToHoleSpecialCase(profile); add32(TrustedImm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector))); branch32(Below, regT2, Address(regT3, ArrayStorage::lengthOffset())).linkTo(storeResult, this); @@ -292,6 +419,10 @@ void JIT::emit_op_put_by_val(Instruction* currentInstruction) jump().linkTo(storeResult, this); end.link(this); + + emitWriteBarrier(regT0, regT1, regT1, regT3, UnconditionalWriteBarrier, WriteBarrierForPropertyAccess); + + return slowCases; } void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) @@ -303,13 +434,19 @@ void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCas linkSlowCase(iter); // property int32 check linkSlowCaseIfNotJSCell(iter, base); // base cell check linkSlowCase(iter); // base not array check - linkSlowCase(iter); // in vector check + linkSlowCase(iter); // out of bounds + + Label slowPath = label(); JITStubCall stubPutByValCall(this, cti_op_put_by_val); stubPutByValCall.addArgument(base); stubPutByValCall.addArgument(property); stubPutByValCall.addArgument(value); - stubPutByValCall.call(); + Call call = stubPutByValCall.call(); + + m_byValCompilationInfo[m_byValInstructionIndex].slowPathTarget = slowPath; + m_byValCompilationInfo[m_byValInstructionIndex].returnAddress = call; + m_byValInstructionIndex++; } void JIT::emit_op_get_by_id(Instruction* currentInstruction) @@ -616,7 +753,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress) loadPtr(Address(regT0, JSCell::structureOffset()), regT2); emitArrayProfilingSiteForBytecodeIndex(regT2, regT3, stubInfo->bytecodeIndex); Jump failureCases1 = branchTest32(Zero, regT2, TrustedImm32(IsArray)); - Jump failureCases2 = branchTest32(Zero, regT2, TrustedImm32(HasArrayStorage)); + Jump failureCases2 = branchTest32(Zero, regT2, TrustedImm32(IndexingShapeMask)); // Checks out okay! - get the length from the storage loadPtr(Address(regT0, JSArray::butterflyOffset()), regT2); @@ -1025,24 +1162,24 @@ void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, Register ASSERT(sizeof(JSValue) == 8); if (finalObjectMode == MayBeFinal) { - Jump isInline = branch32(LessThan, offset, TrustedImm32(inlineStorageCapacity)); + Jump isInline = branch32(LessThan, offset, TrustedImm32(firstOutOfLineOffset)); loadPtr(Address(base, JSObject::butterflyOffset()), base); neg32(offset); Jump done = jump(); isInline.link(this); - addPtr(TrustedImmPtr(JSObject::offsetOfInlineStorage() - (inlineStorageCapacity - 2) * sizeof(EncodedJSValue)), base); + addPtr(TrustedImmPtr(JSObject::offsetOfInlineStorage() - (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue)), base); done.link(this); } else { #if !ASSERT_DISABLED - Jump isOutOfLine = branch32(GreaterThanOrEqual, offset, TrustedImm32(inlineStorageCapacity)); + Jump isOutOfLine = branch32(GreaterThanOrEqual, offset, TrustedImm32(firstOutOfLineOffset)); breakpoint(); isOutOfLine.link(this); #endif loadPtr(Address(base, JSObject::butterflyOffset()), base); neg32(offset); } - load32(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + (inlineStorageCapacity - 2) * sizeof(EncodedJSValue)), resultPayload); - load32(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + (inlineStorageCapacity - 2) * sizeof(EncodedJSValue)), resultTag); + load32(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload) + (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue)), resultPayload); + load32(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag) + (firstOutOfLineOffset - 2) * sizeof(EncodedJSValue)), resultTag); } void JIT::emit_op_get_by_pname(Instruction* currentInstruction) @@ -1067,7 +1204,10 @@ void JIT::emit_op_get_by_pname(Instruction* currentInstruction) load32(addressFor(i), regT3); sub32(TrustedImm32(1), regT3); addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots)))); - add32(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_offsetBase)), regT3); + Jump inlineProperty = branch32(Below, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructureInlineCapacity))); + add32(TrustedImm32(firstOutOfLineOffset), regT3); + sub32(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructureInlineCapacity)), regT3); + inlineProperty.link(this); compileGetDirectOffset(regT2, regT1, regT0, regT3); emitStore(dst, regT1, regT0); @@ -1098,7 +1238,7 @@ void JIT::emit_op_get_scoped_var(Instruction* currentInstruction) int index = currentInstruction[2].u.operand; int skip = currentInstruction[3].u.operand; - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2); bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain(); ASSERT(skip || !checkTopLevel); if (checkTopLevel && skip--) { @@ -1127,7 +1267,7 @@ void JIT::emit_op_put_scoped_var(Instruction* currentInstruction) emitLoad(value, regT1, regT0); - emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2); + emitGetFromCallFrameHeaderPtr(JSStack::ScopeChain, regT2); bool checkTopLevel = m_codeBlock->codeType() == FunctionCode && m_codeBlock->needsFullScopeChain(); ASSERT(skip || !checkTopLevel); if (checkTopLevel && skip--) { diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp index da507838a..1a2c654bc 100644 --- a/Source/JavaScriptCore/jit/JITStubs.cpp +++ b/Source/JavaScriptCore/jit/JITStubs.cpp @@ -63,6 +63,7 @@ #include "RegExpObject.h" #include "RegExpPrototype.h" #include "Register.h" +#include "RepatchBuffer.h" #include "SamplingTool.h" #include "Strong.h" #include <wtf/StdLibExtras.h> @@ -224,7 +225,7 @@ COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_ extern "C" { - __declspec(naked) EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*) + __declspec(naked) EncodedJSValue ctiTrampoline(void* code, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*) { __asm { push ebp; @@ -285,7 +286,7 @@ extern "C" { #define STACK_LENGTH 104 #elif CPU(SH4) #define SYMBOL_STRING(name) #name -/* code (r4), RegisterFile* (r5), CallFrame* (r6), void* unused1 (r7), void* unused2(sp), JSGlobalData (sp)*/ +/* code (r4), JSStack* (r5), CallFrame* (r6), void* unused1 (r7), void* unused2(sp), JSGlobalData (sp)*/ asm volatile ( ".text\n" @@ -458,7 +459,7 @@ SYMBOL_STRING(ctiTrampoline) ":" "\n" "move $16,$6 # set callFrameRegister" "\n" "li $17,512 # set timeoutCheckRegister" "\n" "move $25,$4 # move executableAddress to t9" "\n" - "sw $5," STRINGIZE_VALUE_OF(REGISTER_FILE_OFFSET) "($29) # store registerFile to current stack" "\n" + "sw $5," STRINGIZE_VALUE_OF(REGISTER_FILE_OFFSET) "($29) # store JSStack to current stack" "\n" "lw $9," STRINGIZE_VALUE_OF(STACK_LENGTH + 20) "($29) # load globalData from previous stack" "\n" "jalr $25" "\n" "sw $9," STRINGIZE_VALUE_OF(GLOBAL_DATA_OFFSET) "($29) # store globalData to current stack" "\n" @@ -659,7 +660,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n" #elif COMPILER(RVCT) && CPU(ARM_THUMB2) -__asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*) +__asm EncodedJSValue ctiTrampoline(void*, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*) { PRESERVE8 sub sp, sp, # FIRST_STACK_ARGUMENT @@ -727,7 +728,7 @@ __asm void ctiOpThrowNotCaught() #elif COMPILER(RVCT) && CPU(ARM_TRADITIONAL) -__asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*) +__asm EncodedJSValue ctiTrampoline(void*, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*) { ARM stmdb sp!, {r1-r3} @@ -796,7 +797,7 @@ JITThunks::JITThunks(JSGlobalData* globalData) ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR10) == PRESERVED_R10_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR11) == PRESERVED_R11_OFFSET); - ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == REGISTER_FILE_OFFSET); + ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, stack) == REGISTER_FILE_OFFSET); // The fifth argument is the first item already on the stack. ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, unused1) == FIRST_STACK_ARGUMENT); @@ -815,7 +816,7 @@ JITThunks::JITThunks(JSGlobalData* globalData) ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS2) == PRESERVED_S2_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == PRESERVED_RETURN_ADDRESS_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET); - ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == REGISTER_FILE_OFFSET); + ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, stack) == REGISTER_FILE_OFFSET); ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, globalData) == GLOBAL_DATA_OFFSET); #endif @@ -1049,7 +1050,7 @@ static NEVER_INLINE void returnToThrowTrampoline(JSGlobalData* globalData, Retur } while (0) // Helper function for JIT stubs that may throw an exception in the middle of -// processing a function call. This function rolls back the register file to +// processing a function call. This function rolls back the stack to // our caller, so exception processing can proceed from a valid state. template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot) { @@ -1359,12 +1360,12 @@ DEFINE_STUB_FUNCTION(int, timeout_check) return timeoutChecker.ticksUntilNextCheck(); } -DEFINE_STUB_FUNCTION(void*, register_file_check) +DEFINE_STUB_FUNCTION(void*, stack_check) { STUB_INIT_STACK_FRAME(stackFrame); CallFrame* callFrame = stackFrame.callFrame; - if (UNLIKELY(!stackFrame.registerFile->grow(&callFrame->registers()[callFrame->codeBlock()->m_numCalleeRegisters]))) + if (UNLIKELY(!stackFrame.stack->grow(&callFrame->registers()[callFrame->codeBlock()->m_numCalleeRegisters]))) return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame())); return callFrame; @@ -2191,7 +2192,7 @@ DEFINE_STUB_FUNCTION(void*, op_call_arityCheck) CallFrame* callFrame = stackFrame.callFrame; - CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall); + CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.stack, CodeForCall); if (!newCallFrame) return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame())); @@ -2204,7 +2205,7 @@ DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck) CallFrame* callFrame = stackFrame.callFrame; - CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct); + CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.stack, CodeForConstruct); if (!newCallFrame) return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame())); @@ -2414,6 +2415,30 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct) return returnValue; } +static JSValue getByVal( + CallFrame* callFrame, JSValue baseValue, JSValue subscript, ReturnAddressPtr returnAddress) +{ + if (LIKELY(baseValue.isCell() && subscript.isString())) { + if (JSValue result = baseValue.asCell()->fastGetOwnProperty(callFrame, asString(subscript)->value(callFrame))) + return result; + } + + if (subscript.isUInt32()) { + uint32_t i = subscript.asUInt32(); + if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i)) { + ctiPatchCallByReturnAddress(callFrame->codeBlock(), returnAddress, FunctionPtr(cti_op_get_by_val_string)); + return asString(baseValue)->getIndex(callFrame, i); + } + return baseValue.get(callFrame, i); + } + + if (isName(subscript)) + return baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName()); + + Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); + return baseValue.get(callFrame, property); +} + DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val) { STUB_INIT_STACK_FRAME(stackFrame); @@ -2423,35 +2448,56 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val) JSValue baseValue = stackFrame.args[0].jsValue(); JSValue subscript = stackFrame.args[1].jsValue(); - if (LIKELY(baseValue.isCell() && subscript.isString())) { - if (JSValue result = baseValue.asCell()->fastGetOwnProperty(callFrame, asString(subscript)->value(callFrame))) { - CHECK_FOR_EXCEPTION(); - return JSValue::encode(result); - } - } + if (baseValue.isObject() && subscript.isInt32()) { + // See if it's worth optimizing this at all. + JSObject* object = asObject(baseValue); + bool didOptimize = false; - if (subscript.isUInt32()) { - uint32_t i = subscript.asUInt32(); - if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i)) { - ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string)); - JSValue result = asString(baseValue)->getIndex(callFrame, i); - CHECK_FOR_EXCEPTION(); - return JSValue::encode(result); + unsigned bytecodeOffset = callFrame->bytecodeOffsetForNonDFGCode(); + ASSERT(bytecodeOffset); + ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1); + ASSERT(!byValInfo.stubRoutine); + + if (hasOptimizableIndexing(object->structure())) { + // Attempt to optimize. + JITArrayMode arrayMode = jitArrayModeForStructure(object->structure()); + if (arrayMode != byValInfo.arrayMode) { + JIT::compileGetByVal(&callFrame->globalData(), callFrame->codeBlock(), &byValInfo, STUB_RETURN_ADDRESS, arrayMode); + didOptimize = true; + } + } + + if (!didOptimize) { + // If we take slow path more than 10 times without patching then make sure we + // never make that mistake again. Or, if we failed to patch and we have some object + // that intercepts indexed get, then don't even wait until 10 times. For cases + // where we see non-index-intercepting objects, this gives 10 iterations worth of + // opportunity for us to observe that the get_by_val may be polymorphic. + if (++byValInfo.slowPathCount >= 10 + || object->structure()->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) { + // Don't ever try to optimize. + RepatchBuffer repatchBuffer(callFrame->codeBlock()); + repatchBuffer.relinkCallerToFunction(STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_generic)); + } } - JSValue result = baseValue.get(callFrame, i); - CHECK_FOR_EXCEPTION(); - return JSValue::encode(result); } + + JSValue result = getByVal(callFrame, baseValue, subscript, STUB_RETURN_ADDRESS); + CHECK_FOR_EXCEPTION(); + return JSValue::encode(result); +} + +DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_generic) +{ + STUB_INIT_STACK_FRAME(stackFrame); - if (isName(subscript)) { - JSValue result = baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName()); - CHECK_FOR_EXCEPTION(); - return JSValue::encode(result); - } + CallFrame* callFrame = stackFrame.callFrame; - Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); - JSValue result = baseValue.get(callFrame, property); - CHECK_FOR_EXCEPTION_AT_END(); + JSValue baseValue = stackFrame.args[0].jsValue(); + JSValue subscript = stackFrame.args[1].jsValue(); + + JSValue result = getByVal(callFrame, baseValue, subscript, STUB_RETURN_ADDRESS); + CHECK_FOR_EXCEPTION(); return JSValue::encode(result); } @@ -2502,23 +2548,14 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_sub) return JSValue::encode(result); } -DEFINE_STUB_FUNCTION(void, op_put_by_val) +static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript, JSValue value) { - STUB_INIT_STACK_FRAME(stackFrame); - - CallFrame* callFrame = stackFrame.callFrame; - JSGlobalData* globalData = stackFrame.globalData; - - JSValue baseValue = stackFrame.args[0].jsValue(); - JSValue subscript = stackFrame.args[1].jsValue(); - JSValue value = stackFrame.args[2].jsValue(); - if (LIKELY(subscript.isUInt32())) { uint32_t i = subscript.asUInt32(); if (baseValue.isObject()) { JSObject* object = asObject(baseValue); if (object->canSetIndexQuickly(i)) - object->setIndexQuickly(*globalData, i, value); + object->setIndexQuickly(callFrame->globalData(), i, value); else object->methodTable()->putByIndex(object, callFrame, i, value, callFrame->codeBlock()->isStrictMode()); } else @@ -2528,11 +2565,73 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val) baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot); } else { Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame)); - if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception. + if (!callFrame->globalData().exception) { // Don't put to an object if toString threw an exception. PutPropertySlot slot(callFrame->codeBlock()->isStrictMode()); baseValue.put(callFrame, property, value, slot); } } +} + +DEFINE_STUB_FUNCTION(void, op_put_by_val) +{ + STUB_INIT_STACK_FRAME(stackFrame); + + CallFrame* callFrame = stackFrame.callFrame; + + JSValue baseValue = stackFrame.args[0].jsValue(); + JSValue subscript = stackFrame.args[1].jsValue(); + JSValue value = stackFrame.args[2].jsValue(); + + if (baseValue.isObject() && subscript.isInt32()) { + // See if it's worth optimizing at all. + JSObject* object = asObject(baseValue); + bool didOptimize = false; + + unsigned bytecodeOffset = callFrame->bytecodeOffsetForNonDFGCode(); + ASSERT(bytecodeOffset); + ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1); + ASSERT(!byValInfo.stubRoutine); + + if (hasOptimizableIndexing(object->structure())) { + // Attempt to optimize. + JITArrayMode arrayMode = jitArrayModeForStructure(object->structure()); + if (arrayMode != byValInfo.arrayMode) { + JIT::compilePutByVal(&callFrame->globalData(), callFrame->codeBlock(), &byValInfo, STUB_RETURN_ADDRESS, arrayMode); + didOptimize = true; + } + } + + if (!didOptimize) { + // If we take slow path more than 10 times without patching then make sure we + // never make that mistake again. Or, if we failed to patch and we have some object + // that intercepts indexed get, then don't even wait until 10 times. For cases + // where we see non-index-intercepting objects, this gives 10 iterations worth of + // opportunity for us to observe that the get_by_val may be polymorphic. + if (++byValInfo.slowPathCount >= 10 + || object->structure()->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) { + // Don't ever try to optimize. + RepatchBuffer repatchBuffer(callFrame->codeBlock()); + repatchBuffer.relinkCallerToFunction(STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val_generic)); + } + } + } + + putByVal(callFrame, baseValue, subscript, value); + + CHECK_FOR_EXCEPTION_AT_END(); +} + +DEFINE_STUB_FUNCTION(void, op_put_by_val_generic) +{ + STUB_INIT_STACK_FRAME(stackFrame); + + CallFrame* callFrame = stackFrame.callFrame; + + JSValue baseValue = stackFrame.args[0].jsValue(); + JSValue subscript = stackFrame.args[1].jsValue(); + JSValue value = stackFrame.args[2].jsValue(); + + putByVal(callFrame, baseValue, subscript, value); CHECK_FOR_EXCEPTION_AT_END(); } @@ -2582,12 +2681,12 @@ DEFINE_STUB_FUNCTION(void*, op_load_varargs) STUB_INIT_STACK_FRAME(stackFrame); CallFrame* callFrame = stackFrame.callFrame; - RegisterFile* registerFile = stackFrame.registerFile; + JSStack* stack = stackFrame.stack; JSValue thisValue = stackFrame.args[0].jsValue(); JSValue arguments = stackFrame.args[1].jsValue(); int firstFreeRegister = stackFrame.args[2].int32(); - CallFrame* newCallFrame = loadVarargs(callFrame, registerFile, thisValue, arguments, firstFreeRegister); + CallFrame* newCallFrame = loadVarargs(callFrame, stack, thisValue, arguments, firstFreeRegister); if (!newCallFrame) VM_THROW_EXCEPTION(); return newCallFrame; @@ -3423,8 +3522,8 @@ MacroAssemblerCodeRef JITThunks::ctiStub(JSGlobalData* globalData, ThunkGenerato { CTIStubMap::AddResult entry = m_ctiStubMap.add(generator, MacroAssemblerCodeRef()); if (entry.isNewEntry) - entry.iterator->second = generator(globalData); - return entry.iterator->second; + entry.iterator->value = generator(globalData); + return entry.iterator->value; } NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, NativeFunction constructor) diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h index a4619c816..ecf415d1f 100644 --- a/Source/JavaScriptCore/jit/JITStubs.h +++ b/Source/JavaScriptCore/jit/JITStubs.h @@ -52,13 +52,13 @@ namespace JSC { class JSGlobalObject; class JSObject; class JSPropertyNameIterator; + class JSStack; class JSValue; class JSValueEncodedAsPointer; class NativeExecutable; class Profiler; class PropertySlot; class PutPropertySlot; - class RegisterFile; class RegExp; class Structure; @@ -101,7 +101,7 @@ namespace JSC { void* padding[2]; // Maintain 32-byte stack alignment (possibly overkill). void* code; - RegisterFile* registerFile; + JSStack* stack; CallFrame* callFrame; void* unused1; void* unused2; @@ -137,7 +137,7 @@ namespace JSC { void* savedEIP; void* code; - RegisterFile* registerFile; + JSStack* stack; CallFrame* callFrame; void* unused1; void* unused2; @@ -167,7 +167,7 @@ namespace JSC { void* preservedR11; // These arguments passed in r1..r3 (r0 contained the entry code pointed, which is not preserved) - RegisterFile* registerFile; + JSStack* stack; CallFrame* callFrame; // These arguments passed on the stack. @@ -196,7 +196,7 @@ namespace JSC { void* preservedR11; void* preservedLink; - RegisterFile* registerFile; + JSStack* stack; CallFrame* callFrame; void* unused1; @@ -228,7 +228,7 @@ namespace JSC { ReturnAddressPtr thunkReturnAddress; // These arguments passed in a1..a3 (a0 contained the entry code pointed, which is not preserved) - RegisterFile* registerFile; + JSStack* stack; CallFrame* callFrame; void* unused1; @@ -251,7 +251,7 @@ namespace JSC { void* savedR14; void* savedTimeoutReg; - RegisterFile* registerFile; + JSStack* stack; CallFrame* callFrame; JSValue* exception; void* unused1; @@ -284,7 +284,7 @@ namespace JSC { extern "C" void ctiVMThrowTrampoline(); extern "C" void ctiOpThrowNotCaught(); - extern "C" EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*); + extern "C" EncodedJSValue ctiTrampoline(void* code, JSStack*, CallFrame*, void* /*unused1*/, void* /*unused2*/, JSGlobalData*); #if ENABLE(DFG_JIT) extern "C" void ctiTrampolineEnd(); @@ -370,6 +370,7 @@ extern "C" { EncodedJSValue JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL; EncodedJSValue JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS_DECLARATION) WTF_INTERNAL; EncodedJSValue JIT_STUB cti_op_get_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL; + EncodedJSValue JIT_STUB cti_op_get_by_val_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL; EncodedJSValue JIT_STUB cti_op_get_by_val_string(STUB_ARGS_DECLARATION) WTF_INTERNAL; EncodedJSValue JIT_STUB cti_op_in(STUB_ARGS_DECLARATION) WTF_INTERNAL; EncodedJSValue JIT_STUB cti_op_instanceof(STUB_ARGS_DECLARATION) WTF_INTERNAL; @@ -446,6 +447,7 @@ extern "C" { void JIT_STUB cti_op_put_by_id_direct_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL; void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION) WTF_INTERNAL; void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void JIT_STUB cti_op_put_by_val_generic(STUB_ARGS_DECLARATION) WTF_INTERNAL; void JIT_STUB cti_op_put_getter_setter(STUB_ARGS_DECLARATION) WTF_INTERNAL; void JIT_STUB cti_op_put_global_var_check(STUB_ARGS_DECLARATION) WTF_INTERNAL; void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION) WTF_INTERNAL; @@ -462,7 +464,7 @@ extern "C" { void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION) WTF_INTERNAL; void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION) WTF_INTERNAL; void* JIT_STUB cti_op_throw(STUB_ARGS_DECLARATION) WTF_INTERNAL; - void* JIT_STUB cti_register_file_check(STUB_ARGS_DECLARATION) WTF_INTERNAL; + void* JIT_STUB cti_stack_check(STUB_ARGS_DECLARATION) WTF_INTERNAL; void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION) WTF_INTERNAL; void* JIT_STUB cti_vm_lazyLinkConstruct(STUB_ARGS_DECLARATION) WTF_INTERNAL; void* JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION) REFERENCED_FROM_ASM WTF_INTERNAL; diff --git a/Source/JavaScriptCore/jit/JSInterfaceJIT.h b/Source/JavaScriptCore/jit/JSInterfaceJIT.h index 52f1dd0b0..8d9a0c800 100644 --- a/Source/JavaScriptCore/jit/JSInterfaceJIT.h +++ b/Source/JavaScriptCore/jit/JSInterfaceJIT.h @@ -29,10 +29,10 @@ #include "BytecodeConventions.h" #include "JITCode.h" #include "JITStubs.h" +#include "JSStack.h" #include "JSString.h" #include "JSValue.h" #include "MacroAssembler.h" -#include "RegisterFile.h" #include <wtf/AlwaysInline.h> #include <wtf/Vector.h> diff --git a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h index 0fe606476..560f7c833 100644 --- a/Source/JavaScriptCore/jit/SpecializedThunkJIT.h +++ b/Source/JavaScriptCore/jit/SpecializedThunkJIT.h @@ -40,7 +40,7 @@ namespace JSC { SpecializedThunkJIT(int expectedArgCount) { // Check that we have the expected number of arguments - m_failures.append(branch32(NotEqual, payloadFor(RegisterFile::ArgumentCount), TrustedImm32(expectedArgCount + 1))); + m_failures.append(branch32(NotEqual, payloadFor(JSStack::ArgumentCount), TrustedImm32(expectedArgCount + 1))); } void loadDoubleArgument(int argument, FPRegisterID dst, RegisterID scratch) @@ -83,7 +83,7 @@ namespace JSC { { if (src != regT0) move(src, regT0); - loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister); + loadPtr(payloadFor(JSStack::CallerFrame, callFrameRegister), callFrameRegister); ret(); } @@ -108,7 +108,7 @@ namespace JSC { lowNonZero.link(this); highNonZero.link(this); #endif - loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister); + loadPtr(payloadFor(JSStack::CallerFrame, callFrameRegister), callFrameRegister); ret(); } @@ -117,7 +117,7 @@ namespace JSC { if (src != regT0) move(src, regT0); tagReturnAsInt32(); - loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister); + loadPtr(payloadFor(JSStack::CallerFrame, callFrameRegister), callFrameRegister); ret(); } @@ -126,7 +126,7 @@ namespace JSC { if (src != regT0) move(src, regT0); tagReturnAsJSCell(); - loadPtr(payloadFor(RegisterFile::CallerFrame, callFrameRegister), callFrameRegister); + loadPtr(payloadFor(JSStack::CallerFrame, callFrameRegister), callFrameRegister); ret(); } diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp index e5e891e04..06dad2701 100644 --- a/Source/JavaScriptCore/jsc.cpp +++ b/Source/JavaScriptCore/jsc.cpp @@ -27,12 +27,14 @@ #include "Completion.h" #include "CopiedSpaceInlineMethods.h" #include "ExceptionHelpers.h" +#include "HeapStatistics.h" #include "InitializeThreading.h" #include "Interpreter.h" #include "JSArray.h" #include "JSCTypedArrayStubs.h" #include "JSFunction.h" #include "JSLock.h" +#include "JSProxy.h" #include "JSString.h" #include "SamplingTool.h" #include <math.h> @@ -176,9 +178,13 @@ public: { GlobalObject* object = new (NotNull, allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure); object->finishCreation(globalData, arguments); + globalData.heap.addFinalizer(object, destroy); + object->setGlobalThis(globalData, JSProxy::create(globalData, JSProxy::createStructure(globalData, object, object->prototype()), object)); return object; } + static const bool needsDestruction = false; + static const ClassInfo s_info; static const GlobalObjectMethodTable s_globalObjectMethodTable; @@ -243,8 +249,8 @@ protected: putDirect(globalData, identifier, JSFunction::create(globalExec(), this, arguments, identifier.string(), function, NoIntrinsic, function)); } }; + COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false); -ASSERT_CLASS_FITS_IN_CELL(GlobalObject); const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, 0, ExecState::globalObjectTable, CREATE_METHOD_TABLE(GlobalObject) }; const GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = { &allowsAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptExperimentsEnabled }; @@ -522,6 +528,8 @@ int main(int argc, char** argv) TRY res = jscmain(argc, argv); EXCEPT(res = 3) + if (Options::logHeapStatisticsAtExit()) + HeapStatistics::reportSuccess(); return res; } diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp index c7fd741d6..8e2dacf4d 100644 --- a/Source/JavaScriptCore/llint/LLIntData.cpp +++ b/Source/JavaScriptCore/llint/LLIntData.cpp @@ -68,14 +68,14 @@ void Data::performAssertions(JSGlobalData& globalData) // Assertions to match LowLevelInterpreter.asm. If you change any of this code, be // prepared to change LowLevelInterpreter.asm as well!! - ASSERT(RegisterFile::CallFrameHeaderSize * 8 == 48); - ASSERT(RegisterFile::ArgumentCount * 8 == -48); - ASSERT(RegisterFile::CallerFrame * 8 == -40); - ASSERT(RegisterFile::Callee * 8 == -32); - ASSERT(RegisterFile::ScopeChain * 8 == -24); - ASSERT(RegisterFile::ReturnPC * 8 == -16); - ASSERT(RegisterFile::CodeBlock * 8 == -8); - ASSERT(CallFrame::argumentOffsetIncludingThis(0) == -RegisterFile::CallFrameHeaderSize - 1); + ASSERT(JSStack::CallFrameHeaderSize * 8 == 48); + ASSERT(JSStack::ArgumentCount * 8 == -48); + ASSERT(JSStack::CallerFrame * 8 == -40); + ASSERT(JSStack::Callee * 8 == -32); + ASSERT(JSStack::ScopeChain * 8 == -24); + ASSERT(JSStack::ReturnPC * 8 == -16); + ASSERT(JSStack::CodeBlock * 8 == -8); + ASSERT(CallFrame::argumentOffsetIncludingThis(0) == -JSStack::CallFrameHeaderSize - 1); #if CPU(BIG_ENDIAN) ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) == 0); ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) == 4); @@ -108,9 +108,9 @@ void Data::performAssertions(JSGlobalData& globalData) ASSERT(ImplementsHasInstance == 2); ASSERT(ImplementsDefaultHasInstance == 8); #if USE(JSVALUE64) - ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject)) - &globalData.heap.firstAllocatorWithoutDestructors() == 1); + ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(JSObject::allocationSize(INLINE_STORAGE_CAPACITY)) - &globalData.heap.firstAllocatorWithoutDestructors() == 1); #else - ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(sizeof(JSFinalObject)) - &globalData.heap.firstAllocatorWithoutDestructors() == 3); + ASSERT(&globalData.heap.allocatorForObjectWithoutDestructor(JSObject::allocationSize(INLINE_STORAGE_CAPACITY)) - &globalData.heap.firstAllocatorWithoutDestructors() == 3); #endif ASSERT(FirstConstantRegisterIndex == 0x40000000); ASSERT(GlobalCode == 0); diff --git a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h index 63488aa0b..da2d510b5 100644 --- a/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h +++ b/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h @@ -37,6 +37,7 @@ #define OFFLINE_ASM_X86 0 #define OFFLINE_ASM_ARMv7 0 #define OFFLINE_ASM_X86_64 0 +#define OFFLINE_ASM_ARMv7s 0 #else // !ENABLE(LLINT_C_LOOP) @@ -48,6 +49,12 @@ #define OFFLINE_ASM_X86 0 #endif +#ifdef __ARM_ARCH_7S__ +#define OFFLINE_ASM_ARMv7s 1 +#else +#define OFFLINE_ASM_ARMv7s 0 +#endif + #if CPU(ARM_THUMB2) #define OFFLINE_ASM_ARMv7 1 #else diff --git a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp index 3ed6d6d2f..cbfff29d6 100644 --- a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp +++ b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp @@ -38,13 +38,13 @@ #include "JSGlobalObject.h" #include "JSObject.h" #include "JSPropertyNameIterator.h" +#include "JSStack.h" #include "JSString.h" #include "JSTypeInfo.h" #include "JSVariableObject.h" #include "JumpTable.h" #include "LLIntOfflineAsmConfig.h" #include "MarkedSpace.h" -#include "RegisterFile.h" #include "Structure.h" #include "StructureChain.h" diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp index f9833e4ce..5a9b41da7 100644 --- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp +++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp @@ -396,7 +396,7 @@ LLINT_SLOW_PATH_DECL(replace) } #endif // ENABLE(JIT) -LLINT_SLOW_PATH_DECL(register_file_check) +LLINT_SLOW_PATH_DECL(stack_check) { LLINT_BEGIN(); #if LLINT_SLOW_PATH_TRACING @@ -404,10 +404,10 @@ LLINT_SLOW_PATH_DECL(register_file_check) dataLog("CodeBlock = %p.\n", exec->codeBlock()); dataLog("Num callee registers = %u.\n", exec->codeBlock()->m_numCalleeRegisters); dataLog("Num vars = %u.\n", exec->codeBlock()->m_numVars); - dataLog("Current end is at %p.\n", exec->globalData().interpreter->registerFile().end()); + dataLog("Current end is at %p.\n", exec->globalData().interpreter->stack().end()); #endif - ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->registerFile().end()); - if (UNLIKELY(!globalData.interpreter->registerFile().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) { + ASSERT(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters] > exec->globalData().interpreter->stack().end()); + if (UNLIKELY(!globalData.interpreter->stack().grow(&exec->registers()[exec->codeBlock()->m_numCalleeRegisters]))) { ReturnAddressPtr returnPC = exec->returnPC(); exec = exec->callerFrame(); globalData.exception = createStackOverflowError(exec); @@ -420,7 +420,7 @@ LLINT_SLOW_PATH_DECL(register_file_check) LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck) { LLINT_BEGIN(); - ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->registerFile(), CodeForCall); + ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->stack(), CodeForCall); if (!newExec) { ReturnAddressPtr returnPC = exec->returnPC(); exec = exec->callerFrame(); @@ -434,7 +434,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_arityCheck) LLINT_SLOW_PATH_DECL(slow_path_construct_arityCheck) { LLINT_BEGIN(); - ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->registerFile(), CodeForConstruct); + ExecState* newExec = CommonSlowPaths::arityCheckFor(exec, &globalData.interpreter->stack(), CodeForConstruct); if (!newExec) { ReturnAddressPtr returnPC = exec->returnPC(); exec = exec->callerFrame(); @@ -1408,7 +1408,7 @@ inline SlowPathReturnType genericCall(ExecState* exec, Instruction* pc, CodeSpec ExecState* execCallee = exec + pc[3].u.operand; execCallee->setArgumentCountIncludingThis(pc[2].u.operand); - execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue; + execCallee->uncheckedR(JSStack::Callee) = calleeAsValue; execCallee->setCallerFrame(exec); ASSERT(pc[4].u.callLinkInfo); @@ -1438,11 +1438,11 @@ LLINT_SLOW_PATH_DECL(slow_path_call_varargs) JSValue calleeAsValue = LLINT_OP_C(1).jsValue(); ExecState* execCallee = loadVarargs( - exec, &globalData.interpreter->registerFile(), + exec, &globalData.interpreter->stack(), LLINT_OP_C(2).jsValue(), LLINT_OP_C(3).jsValue(), pc[4].u.operand); LLINT_CALL_CHECK_EXCEPTION(exec, pc); - execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue; + execCallee->uncheckedR(JSStack::Callee) = calleeAsValue; execCallee->setCallerFrame(exec); exec->setCurrentVPC(pc + OPCODE_LENGTH(op_call_varargs)); @@ -1458,7 +1458,7 @@ LLINT_SLOW_PATH_DECL(slow_path_call_eval) execCallee->setArgumentCountIncludingThis(pc[2].u.operand); execCallee->setCallerFrame(exec); - execCallee->uncheckedR(RegisterFile::Callee) = calleeAsValue; + execCallee->uncheckedR(JSStack::Callee) = calleeAsValue; execCallee->setScope(exec->scope()); execCallee->setReturnPC(LLInt::getCodePtr(llint_generic_return_point)); execCallee->setCodeBlock(0); diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.h b/Source/JavaScriptCore/llint/LLIntSlowPaths.h index fe897d4a4..5bfb0ccdf 100644 --- a/Source/JavaScriptCore/llint/LLIntSlowPaths.h +++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.h @@ -112,7 +112,7 @@ LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_call_arityCheck); LLINT_SLOW_PATH_HIDDEN_DECL(entry_osr_function_for_construct_arityCheck); LLINT_SLOW_PATH_HIDDEN_DECL(loop_osr); LLINT_SLOW_PATH_HIDDEN_DECL(replace); -LLINT_SLOW_PATH_HIDDEN_DECL(register_file_check); +LLINT_SLOW_PATH_HIDDEN_DECL(stack_check); LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_call_arityCheck); LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_construct_arityCheck); LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_create_activation); diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm index e347ccc70..a971abf4f 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm @@ -24,7 +24,13 @@ # First come the common protocols that both interpreters use. Note that each # of these must have an ASSERT() in LLIntData.cpp -# These declarations must match interpreter/RegisterFile.h. +# Work-around for the fact that the toolchain's awareness of armv7s results in +# a separate slab in the fat binary, yet the offlineasm doesn't know to expect +# it. +if ARMv7s +end + +# These declarations must match interpreter/JSStack.h. const CallFrameHeaderSize = 48 const ArgumentCount = -48 const CallerFrame = -40 @@ -38,7 +44,7 @@ const ThisArgumentOffset = -CallFrameHeaderSize - 8 # Some register conventions. if JSVALUE64 # - Use a pair of registers to represent the PC: one register for the - # base of the register file, and one register for the index. + # base of the stack, and one register for the index. # - The PC base (or PB for short) should be stored in the csr. It will # get clobbered on calls to other JS code, but will get saved on calls # to C functions. @@ -63,8 +69,10 @@ end # Constant for reasoning about butterflies. const IsArray = 1 -const HasArrayStorage = 8 -const AllArrayTypes = 15 +const IndexingShapeMask = 30 +const ContiguousShape = 26 +const ArrayStorageShape = 28 +const SlowPutArrayStorageShape = 30 # Type constants. const StringType = 5 @@ -89,12 +97,8 @@ const LLIntReturnPC = ArgumentCount + TagOffset # String flags. const HashFlags8BitBuffer = 64 -# Property storage constants -if JSVALUE64 - const InlineStorageCapacity = 6 -else - const InlineStorageCapacity = 7 -end +# Copied from PropertyOffset.h +const firstOutOfLineOffset = 100 # Allocation constants if JSVALUE64 @@ -319,13 +323,13 @@ macro functionInitialization(profileArgSkip) # Check stack height. loadi CodeBlock::m_numCalleeRegisters[t1], t0 loadp CodeBlock::m_globalData[t1], t2 - loadp JSGlobalData::interpreter[t2], t2 # FIXME: Can get to the RegisterFile from the JITStackFrame + loadp JSGlobalData::interpreter[t2], t2 # FIXME: Can get to the JSStack from the JITStackFrame lshifti 3, t0 addp t0, cfr, t0 - bpaeq Interpreter::m_registerFile + RegisterFile::m_end[t2], t0, .stackHeightOK + bpaeq Interpreter::m_stack + JSStack::m_end[t2], t0, .stackHeightOK # Stack height check failed - need to call a slow_path. - callSlowPath(_llint_register_file_check) + callSlowPath(_llint_stack_check) .stackHeightOK: end @@ -910,3 +914,4 @@ _llint_op_put_by_id_transition: # Indicate the end of LLInt. _llint_end: crash() + diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm index 83abf380c..f0d45eb0e 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm @@ -937,24 +937,24 @@ _llint_op_is_string: dispatch(3) -macro loadPropertyAtVariableOffsetKnownNotFinal(propertyOffset, objectAndStorage, tag, payload) - assert(macro (ok) bigteq propertyOffset, InlineStorageCapacity, ok end) +macro loadPropertyAtVariableOffsetKnownNotInline(propertyOffset, objectAndStorage, tag, payload) + assert(macro (ok) bigteq propertyOffset, firstOutOfLineOffset, ok end) negi propertyOffset loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage - loadi TagOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], tag - loadi PayloadOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], payload + loadi TagOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], tag + loadi PayloadOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], payload end macro loadPropertyAtVariableOffset(propertyOffset, objectAndStorage, tag, payload) - bilt propertyOffset, InlineStorageCapacity, .isInline + bilt propertyOffset, firstOutOfLineOffset, .isInline loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage negi propertyOffset jmp .ready .isInline: - addp JSFinalObject::m_inlineStorage - (InlineStorageCapacity - 1) * 8 + sizeof IndexingHeader, objectAndStorage + addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage .ready: - loadi TagOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], tag - loadi PayloadOffset + (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffset, 8], payload + loadi TagOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], tag + loadi PayloadOffset + (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffset, 8], payload end macro resolveGlobal(size, slow) @@ -968,7 +968,7 @@ macro resolveGlobal(size, slow) loadp JSCell::m_structure[t0], t1 bpneq t1, 12[PC], slow loadi 16[PC], t1 - loadPropertyAtVariableOffsetKnownNotFinal(t1, t0, t2, t3) + loadPropertyAtVariableOffsetKnownNotInline(t1, t0, t2, t3) loadi 4[PC], t0 storei t2, TagOffset[cfr, t0, 8] storei t3, PayloadOffset[cfr, t0, 8] @@ -1171,7 +1171,7 @@ _llint_op_get_array_length: loadp JSCell::m_structure[t3], t2 arrayProfile(t2, t1, t0) btiz t2, IsArray, .opGetArrayLengthSlow - btiz t2, HasArrayStorage, .opGetArrayLengthSlow + btiz t2, IndexingShapeMask, .opGetArrayLengthSlow loadi 4[PC], t1 loadp 32[PC], t2 loadp JSObject::m_butterfly[t3], t0 @@ -1302,14 +1302,26 @@ _llint_op_get_by_val: loadp JSCell::m_structure[t0], t2 loadp 16[PC], t3 arrayProfile(t2, t3, t1) - btiz t2, HasArrayStorage, .opGetByValSlow loadi 12[PC], t3 loadConstantOrVariablePayload(t3, Int32Tag, t1, .opGetByValSlow) loadp JSObject::m_butterfly[t0], t3 + andi IndexingShapeMask, t2 + bineq t2, ContiguousShape, .opGetByValNotContiguous + + biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow + loadi TagOffset[t3, t1, 8], t2 + loadi PayloadOffset[t3, t1, 8], t1 + jmp .opGetByValDone + +.opGetByValNotContiguous: + subi ArrayStorageShape, t2 + bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow - loadi 4[PC], t0 loadi ArrayStorage::m_vector + TagOffset[t3, t1, 8], t2 loadi ArrayStorage::m_vector + PayloadOffset[t3, t1, 8], t1 + +.opGetByValDone: + loadi 4[PC], t0 bieq t2, EmptyValueTag, .opGetByValSlow storei t2, TagOffset[cfr, t0, 8] storei t1, PayloadOffset[cfr, t0, 8] @@ -1364,7 +1376,10 @@ _llint_op_get_by_pname: loadi [cfr, t0, 8], t0 subi 1, t0 biaeq t0, JSPropertyNameIterator::m_numCacheableSlots[t3], .opGetByPnameSlow - addi JSPropertyNameIterator::m_offsetBase[t3], t0 + bilt t0, JSPropertyNameIterator::m_cachedStructureInlineCapacity[t3], .opGetByPnameInlineProperty + addi firstOutOfLineOffset, t0 + subi JSPropertyNameIterator::m_cachedStructureInlineCapacity[t3], t0 +.opGetByPnameInlineProperty: loadPropertyAtVariableOffset(t0, t2, t1, t3) loadi 4[PC], t0 storei t1, TagOffset[cfr, t0, 8] @@ -1383,29 +1398,53 @@ _llint_op_put_by_val: loadp JSCell::m_structure[t1], t2 loadp 16[PC], t3 arrayProfile(t2, t3, t0) - btiz t2, HasArrayStorage, .opPutByValSlow loadi 8[PC], t0 - loadConstantOrVariablePayload(t0, Int32Tag, t2, .opPutByValSlow) + loadConstantOrVariablePayload(t0, Int32Tag, t3, .opPutByValSlow) loadp JSObject::m_butterfly[t1], t0 - biaeq t2, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow - bieq ArrayStorage::m_vector + TagOffset[t0, t2, 8], EmptyValueTag, .opPutByValEmpty -.opPutByValStoreResult: - loadi 12[PC], t3 - loadConstantOrVariable2Reg(t3, t1, t3) - writeBarrier(t1, t3) - storei t1, ArrayStorage::m_vector + TagOffset[t0, t2, 8] - storei t3, ArrayStorage::m_vector + PayloadOffset[t0, t2, 8] + andi IndexingShapeMask, t2 + bineq t2, ContiguousShape, .opPutByValNotContiguous + + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValContiguousOutOfBounds +.opPutByValContiguousStoreResult: + loadi 12[PC], t2 + loadConstantOrVariable2Reg(t2, t1, t2) + writeBarrier(t1, t2) + storei t1, TagOffset[t0, t3, 8] + storei t2, PayloadOffset[t0, t3, 8] dispatch(5) -.opPutByValEmpty: +.opPutByValContiguousOutOfBounds: + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow if VALUE_PROFILER - storeb 1, ArrayProfile::m_mayStoreToHole[t3] + loadp 16[PC], t1 + storeb 1, ArrayProfile::m_mayStoreToHole[t1] + end + addi 1, t3, t2 + storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] + jmp .opPutByValContiguousStoreResult + +.opPutByValNotContiguous: + bineq t2, ArrayStorageShape, .opPutByValSlow + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow + bieq ArrayStorage::m_vector + TagOffset[t0, t3, 8], EmptyValueTag, .opPutByValArrayStorageEmpty +.opPutByValArrayStorageStoreResult: + loadi 12[PC], t2 + loadConstantOrVariable2Reg(t2, t1, t2) + writeBarrier(t1, t2) + storei t1, ArrayStorage::m_vector + TagOffset[t0, t3, 8] + storei t2, ArrayStorage::m_vector + PayloadOffset[t0, t3, 8] + dispatch(5) + +.opPutByValArrayStorageEmpty: + if VALUE_PROFILER + loadp 16[PC], t1 + storeb 1, ArrayProfile::m_mayStoreToHole[t1] end addi 1, ArrayStorage::m_numValuesInVector[t0] - bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValStoreResult + bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult addi 1, t2, t1 storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] - jmp .opPutByValStoreResult + jmp .opPutByValArrayStorageStoreResult .opPutByValSlow: callSlowPath(_llint_slow_path_put_by_val) @@ -1485,7 +1524,10 @@ _llint_op_jneq_ptr: traceExecution() loadi 4[PC], t0 loadi 8[PC], t1 + loadp CodeBlock[cfr], t2 + loadp CodeBlock::m_globalObject[t2], t2 bineq TagOffset[cfr, t0, 8], CellTag, .opJneqPtrBranch + loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1 bpeq PayloadOffset[cfr, t0, 8], t1, .opJneqPtrFallThrough .opJneqPtrBranch: dispatchBranch(12[PC]) diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm index 4d614f51f..8b72674ab 100644 --- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm +++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm @@ -796,23 +796,23 @@ _llint_op_is_string: dispatch(3) -macro loadPropertyAtVariableOffsetKnownNotFinal(propertyOffsetAsPointer, objectAndStorage, value) - assert(macro (ok) bigteq propertyOffsetAsPointer, InlineStorageCapacity, ok end) +macro loadPropertyAtVariableOffsetKnownNotInline(propertyOffsetAsPointer, objectAndStorage, value) + assert(macro (ok) bigteq propertyOffsetAsPointer, firstOutOfLineOffset, ok end) negp propertyOffsetAsPointer loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage - loadp (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffsetAsPointer, 8], value + loadp (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsPointer, 8], value end macro loadPropertyAtVariableOffset(propertyOffsetAsInt, objectAndStorage, value) - bilt propertyOffsetAsInt, InlineStorageCapacity, .isInline + bilt propertyOffsetAsInt, firstOutOfLineOffset, .isInline loadp JSObject::m_butterfly[objectAndStorage], objectAndStorage negi propertyOffsetAsInt sxi2p propertyOffsetAsInt, propertyOffsetAsInt jmp .ready .isInline: - addp JSFinalObject::m_inlineStorage - (InlineStorageCapacity - 1) * 8 + sizeof IndexingHeader, objectAndStorage + addp sizeof JSObject - (firstOutOfLineOffset - 2) * 8, objectAndStorage .ready: - loadp (InlineStorageCapacity - 1) * 8 - sizeof IndexingHeader[objectAndStorage, propertyOffsetAsInt, 8], value + loadp (firstOutOfLineOffset - 2) * 8[objectAndStorage, propertyOffsetAsInt, 8], value end macro resolveGlobal(size, slow) @@ -826,7 +826,7 @@ macro resolveGlobal(size, slow) loadp JSCell::m_structure[t0], t1 bpneq t1, 24[PB, PC, 8], slow loadis 32[PB, PC, 8], t1 - loadPropertyAtVariableOffset(t1, t0, t2) + loadPropertyAtVariableOffsetKnownNotInline(t1, t0, t2) loadis 8[PB, PC, 8], t0 storep t2, [cfr, t0, 8] loadp (size - 1) * 8[PB, PC, 8], t0 @@ -1018,7 +1018,7 @@ _llint_op_get_array_length: loadp JSCell::m_structure[t3], t2 arrayProfile(t2, t1, t0) btiz t2, IsArray, .opGetArrayLengthSlow - btiz t2, HasArrayStorage, .opGetArrayLengthSlow + btiz t2, IndexingShapeMask, .opGetArrayLengthSlow loadis 8[PB, PC, 8], t1 loadp 64[PB, PC, 8], t2 loadp JSObject::m_butterfly[t3], t0 @@ -1147,14 +1147,27 @@ _llint_op_get_by_val: loadp 32[PB, PC, 8], t3 arrayProfile(t2, t3, t1) loadis 24[PB, PC, 8], t3 - btiz t2, HasArrayStorage, .opGetByValSlow loadConstantOrVariableInt32(t3, t1, .opGetByValSlow) sxi2p t1, t1 loadp JSObject::m_butterfly[t0], t3 + andi IndexingShapeMask, t2 + bineq t2, ContiguousShape, .opGetByValNotContiguous + + biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t3], .opGetByValSlow + loadis 8[PB, PC, 8], t0 + loadp [t3, t1, 8], t2 + btpz t2, .opGetByValSlow + jmp .opGetByValDone + +.opGetByValNotContiguous: + subi ArrayStorageShape, t2 + bia t2, SlowPutArrayStorageShape - ArrayStorageShape, .opGetByValSlow biaeq t1, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t3], .opGetByValSlow loadis 8[PB, PC, 8], t0 loadp ArrayStorage::m_vector[t3, t1, 8], t2 btpz t2, .opGetByValSlow + +.opGetByValDone: storep t2, [cfr, t0, 8] loadp 40[PB, PC, 8], t0 valueProfile(t2, t0) @@ -1208,7 +1221,10 @@ _llint_op_get_by_pname: loadi PayloadOffset[cfr, t3, 8], t3 subi 1, t3 biaeq t3, JSPropertyNameIterator::m_numCacheableSlots[t1], .opGetByPnameSlow - addi JSPropertyNameIterator::m_offsetBase[t1], t3 + bilt t3, JSPropertyNameIterator::m_cachedStructureInlineCapacity[t1], .opGetByPnameInlineProperty + addi firstOutOfLineOffset, t3 + subi JSPropertyNameIterator::m_cachedStructureInlineCapacity[t1], t3 +.opGetByPnameInlineProperty: loadPropertyAtVariableOffset(t3, t0, t0) loadis 8[PB, PC, 8], t1 storep t0, [cfr, t1, 8] @@ -1226,29 +1242,52 @@ _llint_op_put_by_val: loadp JSCell::m_structure[t1], t2 loadp 32[PB, PC, 8], t3 arrayProfile(t2, t3, t0) - btiz t2, HasArrayStorage, .opPutByValSlow loadis 16[PB, PC, 8], t0 - loadConstantOrVariableInt32(t0, t2, .opPutByValSlow) - sxi2p t2, t2 + loadConstantOrVariableInt32(t0, t3, .opPutByValSlow) + sxi2p t3, t3 loadp JSObject::m_butterfly[t1], t0 - biaeq t2, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow - btpz ArrayStorage::m_vector[t0, t2, 8], .opPutByValEmpty -.opPutByValStoreResult: - loadis 24[PB, PC, 8], t3 - loadConstantOrVariable(t3, t1) + andi IndexingShapeMask, t2 + bineq t2, ContiguousShape, .opPutByValNotContiguous + + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValContiguousOutOfBounds +.opPutByValContiguousStoreResult: + loadis 24[PB, PC, 8], t2 + loadConstantOrVariable(t2, t1) + writeBarrier(t1) + storep t1, [t0, t3, 8] + dispatch(5) + +.opPutByValContiguousOutOfBounds: + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow + if VALUE_PROFILER + loadp 32[PB, PC, 8], t2 + storeb 1, ArrayProfile::m_mayStoreToHole[t2] + end + addi 1, t3, t2 + storei t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] + jmp .opPutByValContiguousStoreResult + +.opPutByValNotContiguous: + bineq t2, ArrayStorageShape, .opPutByValSlow + biaeq t3, -sizeof IndexingHeader + IndexingHeader::m_vectorLength[t0], .opPutByValSlow + btpz ArrayStorage::m_vector[t0, t3, 8], .opPutByValArrayStorageEmpty +.opPutByValArrayStorageStoreResult: + loadis 24[PB, PC, 8], t2 + loadConstantOrVariable(t2, t1) writeBarrier(t1) - storep t1, ArrayStorage::m_vector[t0, t2, 8] + storep t1, ArrayStorage::m_vector[t0, t3, 8] dispatch(5) -.opPutByValEmpty: +.opPutByValArrayStorageEmpty: if VALUE_PROFILER - storeb 1, ArrayProfile::m_mayStoreToHole[t3] + loadp 32[PB, PC, 8], t1 + storeb 1, ArrayProfile::m_mayStoreToHole[t1] end addi 1, ArrayStorage::m_numValuesInVector[t0] - bib t2, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValStoreResult - addi 1, t2, t1 + bib t3, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0], .opPutByValArrayStorageStoreResult + addi 1, t3, t1 storei t1, -sizeof IndexingHeader + IndexingHeader::m_publicLength[t0] - jmp .opPutByValStoreResult + jmp .opPutByValArrayStorageStoreResult .opPutByValSlow: callSlowPath(_llint_slow_path_put_by_val) @@ -1328,7 +1367,10 @@ _llint_op_jneq_null: _llint_op_jneq_ptr: traceExecution() loadis 8[PB, PC, 8], t0 - loadp 16[PB, PC, 8], t1 + loadi 16[PB, PC, 8], t1 + loadp CodeBlock[cfr], t2 + loadp CodeBlock::m_globalObject[t2], t2 + loadp JSGlobalObject::m_specialPointers[t2, t1, 8], t1 bpneq t1, [cfr, t0, 8], .opJneqPtrTarget dispatch(4) diff --git a/Source/JavaScriptCore/offlineasm/armv7.rb b/Source/JavaScriptCore/offlineasm/armv7.rb index d9f9bfa01..07543574e 100644 --- a/Source/JavaScriptCore/offlineasm/armv7.rb +++ b/Source/JavaScriptCore/offlineasm/armv7.rb @@ -52,7 +52,7 @@ def armV7MoveImmediate(value, register) else $asm.puts "movw #{register.armV7Operand}, \##{value & 0xffff}" if (value & 0xffff0000) != 0 - $asm.puts "movt #{register.armV7Operand}, \##{value >> 16}" + $asm.puts "movt #{register.armV7Operand}, \##{(value >> 16) & 0xffff}" end end end diff --git a/Source/JavaScriptCore/offlineasm/offsets.rb b/Source/JavaScriptCore/offlineasm/offsets.rb index d9266d9a3..cb09918cd 100644 --- a/Source/JavaScriptCore/offlineasm/offsets.rb +++ b/Source/JavaScriptCore/offlineasm/offsets.rb @@ -60,7 +60,7 @@ end # # offsetsAndConfigurationIndex(ast, file) -> -# {[offsets, index], ...} +# [[offsets, index], ...] # # Parses the offsets from a file and returns a list of offsets and the # index of the configuration that is valid in this build target. @@ -154,16 +154,19 @@ def offsetsAndConfigurationIndex(file) | data | offsets << readInt(endianness, data) } - if not result.has_key?(offsets) - result[offsets] = index - end + result[index] = offsets } end } raise MissingMagicValuesException unless result.length >= 1 - result + # result is {index1=>offsets1, index2=>offsets2} but we want to return + # [[offsets1, index1], [offsets2, index2]]. + return result.map { + | pair | + pair.reverse + } end # diff --git a/Source/JavaScriptCore/parser/Nodes.cpp b/Source/JavaScriptCore/parser/Nodes.cpp index 14ee83805..03ee8ee12 100644 --- a/Source/JavaScriptCore/parser/Nodes.cpp +++ b/Source/JavaScriptCore/parser/Nodes.cpp @@ -153,8 +153,14 @@ PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, const JSTokenLoc FunctionParameters::FunctionParameters(ParameterNode* firstParameter) { + unsigned parameterCount = 0; for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) - append(parameter->ident()); + ++parameterCount; + + reserveInitialCapacity(parameterCount); + + for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam()) + uncheckedAppend(parameter->ident()); } inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, const JSTokenLocation& location, bool inStrictContext) diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp index 3555f07cd..0f734d3a1 100644 --- a/Source/JavaScriptCore/parser/Parser.cpp +++ b/Source/JavaScriptCore/parser/Parser.cpp @@ -35,6 +35,27 @@ #include <wtf/OwnPtr.h> #include <wtf/WTFThreadData.h> +#define fail() do { if (!m_error) updateErrorMessage(); return 0; } while (0) +#define failWithToken(tok) do { if (!m_error) updateErrorMessage(tok); return 0; } while (0) +#define failWithMessage(msg) do { if (!m_error) updateErrorMessage(msg); return 0; } while (0) +#define failWithNameAndMessage(before, name, after) do { if (!m_error) updateErrorWithNameAndMessage(before, name, after); return 0; } while (0) +#define failIfFalse(cond) do { if (!(cond)) fail(); } while (0) +#define failIfFalseWithMessage(cond, msg) do { if (!(cond)) failWithMessage(msg); } while (0) +#define failIfFalseWithNameAndMessage(cond, before, name, msg) do { if (!(cond)) failWithNameAndMessage(before, name, msg); } while (0) +#define failIfTrue(cond) do { if ((cond)) fail(); } while (0) +#define failIfTrueWithMessage(cond, msg) do { if ((cond)) failWithMessage(msg); } while (0) +#define failIfTrueWithNameAndMessage(cond, before, name, msg) do { if ((cond)) failWithNameAndMessage(before, name, msg); } while (0) +#define failIfTrueIfStrict(cond) do { if ((cond) && strictMode()) fail(); } while (0) +#define failIfTrueIfStrictWithMessage(cond, msg) do { if ((cond) && strictMode()) failWithMessage(msg); } while (0) +#define failIfTrueIfStrictWithNameAndMessage(cond, before, name, after) do { if ((cond) && strictMode()) failWithNameAndMessage(before, name, after); } while (0) +#define failIfFalseIfStrict(cond) do { if ((!(cond)) && strictMode()) fail(); } while (0) +#define failIfFalseIfStrictWithMessage(cond, msg) do { if ((!(cond)) && strictMode()) failWithMessage(msg); } while (0) +#define failIfFalseIfStrictWithNameAndMessage(cond, before, name, after) do { if ((!(cond)) && strictMode()) failWithNameAndMessage(before, name, after); } while (0) +#define consumeOrFail(tokenType) do { if (!consume(tokenType)) failWithToken(tokenType); } while (0) +#define consumeOrFailWithFlags(tokenType, flags) do { if (!consume(tokenType, flags)) failWithToken(tokenType); } while (0) +#define matchOrFail(tokenType) do { if (!match(tokenType)) failWithToken(tokenType); } while (0) +#define failIfStackOverflow() do { failIfFalseWithMessage(canRecurse(), "Code nested too deeply."); } while (0) + using namespace std; namespace JSC { @@ -1366,10 +1387,10 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseStrictObject if (!m_syntaxAlreadyValidated) { ObjectValidationMap::AddResult propertyEntry = objectValidator.add(context.getName(property).impl(), context.getType(property)); if (!propertyEntry.isNewEntry) { - failIfTrue(propertyEntry.iterator->second == PropertyNode::Constant); + failIfTrue(propertyEntry.iterator->value == PropertyNode::Constant); failIfTrue(context.getType(property) == PropertyNode::Constant); - failIfTrue(context.getType(property) & propertyEntry.iterator->second); - propertyEntry.iterator->second |= context.getType(property); + failIfTrue(context.getType(property) & propertyEntry.iterator->value); + propertyEntry.iterator->value |= context.getType(property); } } tail = context.createPropertyList(propertyLocation, property, tail); diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h index e657e12cd..4c005fa5e 100644 --- a/Source/JavaScriptCore/parser/Parser.h +++ b/Source/JavaScriptCore/parser/Parser.h @@ -57,28 +57,7 @@ class JSGlobalData; class ProgramNode; class SourceCode; -#define fail() do { if (!m_error) updateErrorMessage(); return 0; } while (0) -#define failWithToken(tok) do { if (!m_error) updateErrorMessage(tok); return 0; } while (0) -#define failWithMessage(msg) do { if (!m_error) updateErrorMessage(msg); return 0; } while (0) -#define failWithNameAndMessage(before, name, after) do { if (!m_error) updateErrorWithNameAndMessage(before, name, after); return 0; } while (0) -#define failIfFalse(cond) do { if (!(cond)) fail(); } while (0) -#define failIfFalseWithMessage(cond, msg) do { if (!(cond)) failWithMessage(msg); } while (0) -#define failIfFalseWithNameAndMessage(cond, before, name, msg) do { if (!(cond)) failWithNameAndMessage(before, name, msg); } while (0) -#define failIfTrue(cond) do { if ((cond)) fail(); } while (0) -#define failIfTrueWithMessage(cond, msg) do { if ((cond)) failWithMessage(msg); } while (0) -#define failIfTrueWithNameAndMessage(cond, before, name, msg) do { if ((cond)) failWithNameAndMessage(before, name, msg); } while (0) -#define failIfTrueIfStrict(cond) do { if ((cond) && strictMode()) fail(); } while (0) -#define failIfTrueIfStrictWithMessage(cond, msg) do { if ((cond) && strictMode()) failWithMessage(msg); } while (0) -#define failIfTrueIfStrictWithNameAndMessage(cond, before, name, after) do { if ((cond) && strictMode()) failWithNameAndMessage(before, name, after); } while (0) -#define failIfFalseIfStrict(cond) do { if ((!(cond)) && strictMode()) fail(); } while (0) -#define failIfFalseIfStrictWithMessage(cond, msg) do { if ((!(cond)) && strictMode()) failWithMessage(msg); } while (0) -#define failIfFalseIfStrictWithNameAndMessage(cond, before, name, after) do { if ((!(cond)) && strictMode()) failWithNameAndMessage(before, name, after); } while (0) -#define consumeOrFail(tokenType) do { if (!consume(tokenType)) failWithToken(tokenType); } while (0) -#define consumeOrFailWithFlags(tokenType, flags) do { if (!consume(tokenType, flags)) failWithToken(tokenType); } while (0) -#define matchOrFail(tokenType) do { if (!match(tokenType)) failWithToken(tokenType); } while (0) -#define failIfStackOverflow() do { failIfFalseWithMessage(canRecurse(), "Code nested too deeply."); } while (0) - - // Macros to make the more common TreeBuilder types a little less verbose +// Macros to make the more common TreeBuilder types a little less verbose #define TreeStatement typename TreeBuilder::Statement #define TreeExpression typename TreeBuilder::Expression #define TreeFormalParameterList typename TreeBuilder::FormalParameterList diff --git a/Source/JavaScriptCore/profiler/Profile.cpp b/Source/JavaScriptCore/profiler/Profile.cpp index 51f871898..a641580ec 100644 --- a/Source/JavaScriptCore/profiler/Profile.cpp +++ b/Source/JavaScriptCore/profiler/Profile.cpp @@ -111,7 +111,7 @@ typedef WTF::KeyValuePair<FunctionCallHashCount::ValueType, unsigned> NameCountP static inline bool functionNameCountPairComparator(const NameCountPair& a, const NameCountPair& b) { - return a.second > b.second; + return a.value > b.value; } void Profile::debugPrintDataSampleStyle() const @@ -128,7 +128,7 @@ void Profile::debugPrintDataSampleStyle() const std::sort(sortedFunctions.begin(), sortedFunctions.end(), functionNameCountPairComparator); for (NameCountPairVector::iterator it = sortedFunctions.begin(); it != sortedFunctions.end(); ++it) - dataLog(" %-12d%s\n", (*it).second, String((*it).first).utf8().data()); + dataLog(" %-12d%s\n", (*it).value, String((*it).key).utf8().data()); dataLog("\nSort by top of stack, same collapsed (when >= 5):\n"); } diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp index fdf202192..ba73b2cf2 100644 --- a/Source/JavaScriptCore/runtime/Arguments.cpp +++ b/Source/JavaScriptCore/runtime/Arguments.cpp @@ -33,9 +33,7 @@ using namespace std; namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(Arguments); - -const ClassInfo Arguments::s_info = { "Arguments", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) }; +const ClassInfo Arguments::s_info = { "Arguments", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) }; void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor) { @@ -406,19 +404,19 @@ void Arguments::tearOffForInlineCallFrame(JSGlobalData& globalData, Register* re JSValue value; Register* location = ®isters[CallFrame::argumentOffset(i)]; switch (recovery.technique()) { - case AlreadyInRegisterFile: + case AlreadyInJSStack: value = location->jsValue(); break; - case AlreadyInRegisterFileAsUnboxedInt32: + case AlreadyInJSStackAsUnboxedInt32: value = jsNumber(location->unboxedInt32()); break; - case AlreadyInRegisterFileAsUnboxedCell: + case AlreadyInJSStackAsUnboxedCell: value = location->unboxedCell(); break; - case AlreadyInRegisterFileAsUnboxedBoolean: + case AlreadyInJSStackAsUnboxedBoolean: value = jsBoolean(location->unboxedBoolean()); break; - case AlreadyInRegisterFileAsUnboxedDouble: + case AlreadyInJSStackAsUnboxedDouble: #if USE(JSVALUE64) value = jsNumber(*bitwise_cast<double*>(location)); #else diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h index 40063bead..7c8b69bd1 100644 --- a/Source/JavaScriptCore/runtime/Arguments.h +++ b/Source/JavaScriptCore/runtime/Arguments.h @@ -26,6 +26,7 @@ #include "CodeOrigin.h" #include "JSActivation.h" +#include "JSDestructibleObject.h" #include "JSFunction.h" #include "JSGlobalObject.h" #include "Interpreter.h" @@ -33,11 +34,11 @@ namespace JSC { - class Arguments : public JSNonFinalObject { + class Arguments : public JSDestructibleObject { friend class JIT; friend class DFG::SpeculativeJIT; public: - typedef JSNonFinalObject Base; + typedef JSDestructibleObject Base; static Arguments* create(JSGlobalData& globalData, CallFrame* callFrame) { @@ -147,12 +148,12 @@ namespace JSC { } inline Arguments::Arguments(CallFrame* callFrame) - : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) + : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) { } inline Arguments::Arguments(CallFrame* callFrame, NoParametersType) - : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) + : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) { } diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp index eda35e146..a13648442 100644 --- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp +++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp @@ -53,8 +53,6 @@ const ClassInfo ArrayConstructor::s_info = { "Function", &InternalFunction::s_in @end */ -ASSERT_CLASS_FITS_IN_CELL(ArrayConstructor); - ArrayConstructor::ArrayConstructor(JSGlobalObject* globalObject, Structure* structure) : InternalFunction(globalObject, structure) { diff --git a/Source/JavaScriptCore/runtime/ArrayConventions.h b/Source/JavaScriptCore/runtime/ArrayConventions.h index 3ea6b0471..a557b1ef9 100644 --- a/Source/JavaScriptCore/runtime/ArrayConventions.h +++ b/Source/JavaScriptCore/runtime/ArrayConventions.h @@ -79,7 +79,7 @@ static const unsigned minDensityMultiplier = 8; inline bool isDenseEnoughForVector(unsigned length, unsigned numValues) { - return length <= MIN_SPARSE_ARRAY_INDEX || length / minDensityMultiplier <= numValues; + return length / minDensityMultiplier <= numValues; } inline IndexingHeader indexingHeaderForArray(unsigned length, unsigned vectorLength) diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp index 1eacd1179..6975dc778 100644 --- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -42,8 +42,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(ArrayPrototype); - static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*); static EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*); static EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*); @@ -194,7 +192,8 @@ static unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument // currentCount) will be shifted to the left or right as appropriate; in the // case of shift this must be removing values, in the case of unshift this // must be introducing new values. -static inline void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length) +template<JSArray::ShiftCountMode shiftCountMode> +void shift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length) { ASSERT(currentCount > resultCount); unsigned count = currentCount - resultCount; @@ -202,9 +201,9 @@ static inline void shift(ExecState* exec, JSObject* thisObj, unsigned header, un ASSERT(header <= length); ASSERT(currentCount <= (length - header)); - if (!header && isJSArray(thisObj)) { + if (isJSArray(thisObj)) { JSArray* array = asArray(thisObj); - if (array->length() == length && asArray(thisObj)->shiftCount(exec, count)) + if (array->length() == length && asArray(thisObj)->shiftCount<shiftCountMode>(exec, header, count)) return; } @@ -231,7 +230,8 @@ static inline void shift(ExecState* exec, JSObject* thisObj, unsigned header, un } } } -static inline void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length) +template<JSArray::ShiftCountMode shiftCountMode> +void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned currentCount, unsigned resultCount, unsigned length) { ASSERT(resultCount > currentCount); unsigned count = resultCount - currentCount; @@ -245,12 +245,12 @@ static inline void unshift(ExecState* exec, JSObject* thisObj, unsigned header, return; } - if (!header && isJSArray(thisObj)) { + if (isJSArray(thisObj)) { JSArray* array = asArray(thisObj); - if (array->length() == length && asArray(thisObj)->unshiftCount(exec, count)) + if (array->length() == length && array->unshiftCount<shiftCountMode>(exec, header, count)) return; } - + for (unsigned k = length - currentCount; k > header; --k) { unsigned from = k + currentCount - 1; unsigned to = k + resultCount - 1; @@ -526,7 +526,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) array->push(exec, exec->argument(0)); return JSValue::encode(jsNumber(array->length())); } - + JSObject* thisObj = thisValue.toObject(exec); unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) @@ -544,6 +544,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) if (exec->hadException()) return JSValue::encode(jsUndefined()); } + JSValue newLength(static_cast<int64_t>(length) + static_cast<int64_t>(exec->argumentCount())); putProperty(exec, thisObj, exec->propertyNames().length, newLength); return JSValue::encode(newLength); @@ -600,7 +601,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec) result = jsUndefined(); } else { result = thisObj->get(exec, 0); - shift(exec, thisObj, 0, 1, 0, length); + shift<JSArray::ShiftCountForShift>(exec, thisObj, 0, 1, 0, length); if (exec->hadException()) return JSValue::encode(jsUndefined()); putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1)); @@ -655,7 +656,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec) CallData callData; CallType callType = getCallData(function, callData); - if (thisObj->classInfo() == &JSArray::s_info && !asArray(thisObj)->inSparseIndexingMode() && !shouldUseSlowPut(thisObj->structure()->indexingType())) { + if (thisObj->classInfo() == &JSArray::s_info && !asArray(thisObj)->hasSparseMap() && !shouldUseSlowPut(thisObj->structure()->indexingType())) { if (isNumericCompareFunction(exec, callType, callData)) asArray(thisObj)->sortNumeric(exec, function, callType, callData); else if (callType != CallTypeNone) @@ -730,7 +731,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); - + if (!exec->argumentCount()) return JSValue::encode(constructEmptyArray(exec)); @@ -762,11 +763,11 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec) unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0); if (additionalArgs < deleteCount) { - shift(exec, thisObj, begin, deleteCount, additionalArgs, length); + shift<JSArray::ShiftCountForSplice>(exec, thisObj, begin, deleteCount, additionalArgs, length); if (exec->hadException()) return JSValue::encode(jsUndefined()); } else if (additionalArgs > deleteCount) { - unshift(exec, thisObj, begin, deleteCount, additionalArgs, length); + unshift<JSArray::ShiftCountForSplice>(exec, thisObj, begin, deleteCount, additionalArgs, length); if (exec->hadException()) return JSValue::encode(jsUndefined()); } @@ -791,7 +792,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec) unsigned nrArgs = exec->argumentCount(); if (nrArgs) { - unshift(exec, thisObj, 0, 0, nrArgs, length); + unshift<JSArray::ShiftCountForShift>(exec, thisObj, 0, 0, nrArgs, length); if (exec->hadException()) return JSValue::encode(jsUndefined()); } diff --git a/Source/JavaScriptCore/runtime/ArrayStorage.h b/Source/JavaScriptCore/runtime/ArrayStorage.h index 1ab936335..ffd84b281 100644 --- a/Source/JavaScriptCore/runtime/ArrayStorage.h +++ b/Source/JavaScriptCore/runtime/ArrayStorage.h @@ -41,6 +41,8 @@ namespace JSC { // setStorage() methods. It is important to note that there may be space before the ArrayStorage that // is used to quick unshift / shift operation. The actual allocated pointer is available by using: // getStorage() - m_indexBias * sizeof(JSValue) +// All slots in ArrayStorage (slots from 0 to vectorLength) are expected to be initialized to a JSValue or, +// for hole slots, JSValue(). struct ArrayStorage { WTF_MAKE_NONCOPYABLE(ArrayStorage); private: diff --git a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp index 9b666292c..0485350ce 100644 --- a/Source/JavaScriptCore/runtime/BooleanConstructor.cpp +++ b/Source/JavaScriptCore/runtime/BooleanConstructor.cpp @@ -26,7 +26,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(BooleanConstructor); ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanConstructor); const ClassInfo BooleanConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanConstructor) }; diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp index bf2655bbb..355993864 100644 --- a/Source/JavaScriptCore/runtime/BooleanObject.cpp +++ b/Source/JavaScriptCore/runtime/BooleanObject.cpp @@ -25,7 +25,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(BooleanObject); ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanObject); const ClassInfo BooleanObject::s_info = { "Boolean", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(BooleanObject) }; diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp index c8c77220a..a331c6c15 100644 --- a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp +++ b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp @@ -47,7 +47,6 @@ const ClassInfo BooleanPrototype::s_info = { "Boolean", &BooleanObject::s_info, @end */ -ASSERT_CLASS_FITS_IN_CELL(BooleanPrototype); ASSERT_HAS_TRIVIAL_DESTRUCTOR(BooleanPrototype); BooleanPrototype::BooleanPrototype(ExecState* exec, Structure* structure) diff --git a/Source/JavaScriptCore/runtime/Butterfly.h b/Source/JavaScriptCore/runtime/Butterfly.h index 1926169ba..cb93aea8a 100644 --- a/Source/JavaScriptCore/runtime/Butterfly.h +++ b/Source/JavaScriptCore/runtime/Butterfly.h @@ -35,7 +35,7 @@ namespace JSC { class JSGlobalData; -class SlotVisitor; +class CopyVisitor; struct ArrayStorage; class Butterfly { @@ -56,6 +56,15 @@ public: return reinterpret_cast<Butterfly*>(static_cast<EncodedJSValue*>(base) + preCapacity + propertyCapacity + 1); } + // This method is here not just because it's handy, but to remind you that + // the whole point of butterflies is to do evil pointer arithmetic. + static Butterfly* fromPointer(char* ptr) + { + return reinterpret_cast<Butterfly*>(ptr); + } + + char* pointer() { return reinterpret_cast<char*>(this); } + static ptrdiff_t offsetOfIndexingHeader() { return IndexingHeader::offsetOfIndexingHeader(); } static ptrdiff_t offsetOfPublicLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfPublicLength(); } static ptrdiff_t offsetOfVectorLength() { return offsetOfIndexingHeader() + IndexingHeader::offsetOfVectorLength(); } @@ -64,15 +73,27 @@ public: static Butterfly* create(JSGlobalData&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, const IndexingHeader&, size_t indexingPayloadSizeInBytes); static Butterfly* create(JSGlobalData&, Structure*); - static Butterfly* createUninitializedDuringCollection(SlotVisitor&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes); + static Butterfly* createUninitializedDuringCollection(CopyVisitor&, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes); IndexingHeader* indexingHeader() { return IndexingHeader::from(this); } const IndexingHeader* indexingHeader() const { return IndexingHeader::from(this); } PropertyStorage propertyStorage() { return indexingHeader()->propertyStorage(); } ConstPropertyStorage propertyStorage() const { return indexingHeader()->propertyStorage(); } + + uint32_t publicLength() { return indexingHeader()->publicLength(); } + uint32_t vectorLength() { return indexingHeader()->vectorLength(); } + void setPublicLength(uint32_t value) { indexingHeader()->setPublicLength(value); } + void setVectorLength(uint32_t value) { indexingHeader()->setVectorLength(value); } + template<typename T> T* indexingPayload() { return reinterpret_cast<T*>(this); } ArrayStorage* arrayStorage() { return indexingPayload<ArrayStorage>(); } + WriteBarrier<Unknown>* contiguous() { return indexingPayload<WriteBarrier<Unknown> >(); } + + static Butterfly* fromContiguous(WriteBarrier<Unknown>* contiguous) + { + return reinterpret_cast<Butterfly*>(contiguous); + } static ptrdiff_t offsetOfPropertyStorage() { return -static_cast<ptrdiff_t>(sizeof(IndexingHeader)); } static int indexOfPropertyStorage() diff --git a/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h b/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h index 049350342..86a836bef 100644 --- a/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h +++ b/Source/JavaScriptCore/runtime/ButterflyInlineMethods.h @@ -29,8 +29,8 @@ #include "ArrayStorage.h" #include "Butterfly.h" #include "CopiedSpaceInlineMethods.h" +#include "CopyVisitor.h" #include "JSGlobalData.h" -#include "SlotVisitor.h" #include "Structure.h" namespace JSC { @@ -59,7 +59,7 @@ inline Butterfly* Butterfly::create(JSGlobalData& globalData, Structure* structu return create(globalData, 0, structure->outOfLineCapacity(), hasIndexingHeader(structure->indexingType()), IndexingHeader(), 0); } -inline Butterfly* Butterfly::createUninitializedDuringCollection(SlotVisitor& visitor, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) +inline Butterfly* Butterfly::createUninitializedDuringCollection(CopyVisitor& visitor, size_t preCapacity, size_t propertyCapacity, bool hasIndexingHeader, size_t indexingPayloadSizeInBytes) { Butterfly* result = fromBase( visitor.allocateNewSpace(totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes)), @@ -144,7 +144,7 @@ inline Butterfly* Butterfly::resizeArray(JSGlobalData& globalData, Structure* st inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots) { - ASSERT(hasIndexingHeader(structure->indexingType())); + ASSERT(hasArrayStorage(structure->indexingType())); ASSERT(numberOfSlots <= indexingHeader()->preCapacity(structure)); unsigned propertyCapacity = structure->outOfLineCapacity(); // FIXME: It would probably be wise to rewrite this as a loop since (1) we know in which @@ -163,7 +163,7 @@ inline Butterfly* Butterfly::unshift(Structure* structure, size_t numberOfSlots) inline Butterfly* Butterfly::shift(Structure* structure, size_t numberOfSlots) { - ASSERT(hasIndexingHeader(structure->indexingType())); + ASSERT(hasArrayStorage(structure->indexingType())); unsigned propertyCapacity = structure->outOfLineCapacity(); // FIXME: See comment in unshift(), above. memmove( diff --git a/Source/JavaScriptCore/runtime/ClassInfo.h b/Source/JavaScriptCore/runtime/ClassInfo.h index e8823d571..c918621fe 100644 --- a/Source/JavaScriptCore/runtime/ClassInfo.h +++ b/Source/JavaScriptCore/runtime/ClassInfo.h @@ -39,6 +39,9 @@ namespace JSC { typedef void (*VisitChildrenFunctionPtr)(JSCell*, SlotVisitor&); VisitChildrenFunctionPtr visitChildren; + typedef void (*CopyBackingStoreFunctionPtr)(JSCell*, CopyVisitor&); + CopyBackingStoreFunctionPtr copyBackingStore; + typedef CallType (*GetCallDataFunctionPtr)(JSCell*, CallData&); GetCallDataFunctionPtr getCallData; @@ -116,6 +119,7 @@ struct MemberCheck##member { \ #define CREATE_METHOD_TABLE(ClassName) { \ &ClassName::destroy, \ &ClassName::visitChildren, \ + &ClassName::copyBackingStore, \ &ClassName::getCallData, \ &ClassName::getConstructData, \ &ClassName::put, \ diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.h b/Source/JavaScriptCore/runtime/CommonSlowPaths.h index 7edd9091c..2f5159461 100644 --- a/Source/JavaScriptCore/runtime/CommonSlowPaths.h +++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.h @@ -43,7 +43,7 @@ namespace JSC { namespace CommonSlowPaths { -ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, RegisterFile* registerFile, CodeSpecializationKind kind) +ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, JSStack* stack, CodeSpecializationKind kind) { JSFunction* callee = jsCast<JSFunction*>(exec->callee()); ASSERT(!callee->isHostFunction()); @@ -51,7 +51,7 @@ ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, RegisterFile* registerFi int argumentCountIncludingThis = exec->argumentCountIncludingThis(); // This ensures enough space for the worst case scenario of zero arguments passed by the caller. - if (!registerFile->grow(exec->registers() + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters)) + if (!stack->grow(exec->registers() + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters)) return 0; ASSERT(argumentCountIncludingThis < newCodeBlock->numParameters()); @@ -71,7 +71,7 @@ ALWAYS_INLINE ExecState* arityCheckFor(ExecState* exec, RegisterFile* registerFi dst[i] = jsUndefined(); ExecState* newExec = ExecState::create(dst); - ASSERT((void*)newExec <= registerFile->end()); + ASSERT((void*)newExec <= stack->end()); return newExec; } diff --git a/Source/JavaScriptCore/runtime/DateConstructor.cpp b/Source/JavaScriptCore/runtime/DateConstructor.cpp index e4f89dd37..f78e8bf55 100644 --- a/Source/JavaScriptCore/runtime/DateConstructor.cpp +++ b/Source/JavaScriptCore/runtime/DateConstructor.cpp @@ -71,7 +71,6 @@ const ClassInfo DateConstructor::s_info = { "Function", &InternalFunction::s_inf @end */ -ASSERT_CLASS_FITS_IN_CELL(DateConstructor); ASSERT_HAS_TRIVIAL_DESTRUCTOR(DateConstructor); DateConstructor::DateConstructor(JSGlobalObject* globalObject, Structure* structure) diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp index 9b2cb164f..75da466fb 100644 --- a/Source/JavaScriptCore/runtime/DatePrototype.cpp +++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp @@ -70,8 +70,6 @@ using namespace WTF; namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(DatePrototype); - static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState*); static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState*); static EncodedJSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState*); diff --git a/Source/JavaScriptCore/runtime/Error.cpp b/Source/JavaScriptCore/runtime/Error.cpp index 27a729d0a..68ae12d90 100644 --- a/Source/JavaScriptCore/runtime/Error.cpp +++ b/Source/JavaScriptCore/runtime/Error.cpp @@ -177,8 +177,6 @@ JSObject* throwSyntaxError(ExecState* exec) return throwError(exec, createSyntaxError(exec, ASCIILiteral("Syntax error"))); } -ASSERT_CLASS_FITS_IN_CELL(StrictModeTypeErrorFunction); - const ClassInfo StrictModeTypeErrorFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(StrictModeTypeErrorFunction) }; void StrictModeTypeErrorFunction::destroy(JSCell* cell) diff --git a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp index 96272d0cf..f2578a497 100644 --- a/Source/JavaScriptCore/runtime/ErrorConstructor.cpp +++ b/Source/JavaScriptCore/runtime/ErrorConstructor.cpp @@ -27,7 +27,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(ErrorConstructor); ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorConstructor); const ClassInfo ErrorConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(ErrorConstructor) }; diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp index 6c9d6df04..a30efdc31 100644 --- a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp @@ -30,7 +30,7 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype); +ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorPrototype); static EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*); @@ -48,8 +48,6 @@ const ClassInfo ErrorPrototype::s_info = { "Error", &ErrorInstance::s_info, 0, E @end */ -ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype); - ErrorPrototype::ErrorPrototype(ExecState* exec, Structure* structure) : ErrorInstance(exec->globalData(), structure) { diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h index 6eeda3a82..76a537da3 100644 --- a/Source/JavaScriptCore/runtime/Executable.h +++ b/Source/JavaScriptCore/runtime/Executable.h @@ -81,6 +81,8 @@ namespace JSC { typedef JSCell Base; #if ENABLE(JIT) + static const bool needsDestruction = true; + static const bool hasImmortalStructure = true; static void destroy(JSCell*); #endif diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp index 570444e3c..bf74c0a97 100644 --- a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp +++ b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp @@ -34,7 +34,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor); ASSERT_HAS_TRIVIAL_DESTRUCTOR(FunctionConstructor); const ClassInfo FunctionConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionConstructor) }; diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp index dd1628b29..a4b2202c1 100644 --- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp +++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp @@ -32,7 +32,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(FunctionPrototype); ASSERT_HAS_TRIVIAL_DESTRUCTOR(FunctionPrototype); const ClassInfo FunctionPrototype::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionPrototype) }; diff --git a/Source/JavaScriptCore/runtime/Identifier.cpp b/Source/JavaScriptCore/runtime/Identifier.cpp index a9a2a66bf..45dd0bbde 100644 --- a/Source/JavaScriptCore/runtime/Identifier.cpp +++ b/Source/JavaScriptCore/runtime/Identifier.cpp @@ -30,6 +30,7 @@ #include <wtf/Assertions.h> #include <wtf/FastMalloc.h> #include <wtf/HashSet.h> +#include <wtf/text/ASCIIFastPath.h> #include <wtf/text/StringHash.h> using WTF::ThreadSpecific; @@ -80,11 +81,7 @@ struct IdentifierLCharFromUCharTranslator { { LChar* d; StringImpl* r = StringImpl::createUninitialized(buf.length, d).leakRef(); - for (unsigned i = 0; i != buf.length; i++) { - UChar c = buf.s[i]; - ASSERT(c <= 0xff); - d[i] = c; - } + WTF::copyLCharsFromUCharSource(d, buf.s, buf.length); r->setHash(hash); location = r; } @@ -102,7 +99,7 @@ PassRefPtr<StringImpl> Identifier::add(JSGlobalData* globalData, const char* c) const LiteralIdentifierTable::iterator& iter = literalIdentifierTable.find(c); if (iter != literalIdentifierTable.end()) - return iter->second; + return iter->value; HashSet<StringImpl*>::AddResult addResult = identifierTable.add<const LChar*, IdentifierASCIIStringTranslator>(reinterpret_cast<const LChar*>(c)); diff --git a/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h b/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h index e1d893b0b..22785ce24 100644 --- a/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h +++ b/Source/JavaScriptCore/runtime/IndexingHeaderInlineMethods.h @@ -42,10 +42,17 @@ inline size_t IndexingHeader::preCapacity(Structure* structure) inline size_t IndexingHeader::indexingPayloadSizeInBytes(Structure* structure) { - if (LIKELY(!hasArrayStorage(structure->indexingType()))) + switch (structure->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + return vectorLength() * sizeof(EncodedJSValue); + + case ALL_ARRAY_STORAGE_INDEXING_TYPES: + return ArrayStorage::sizeFor(arrayStorage()->vectorLength()); + + default: + ASSERT(!hasIndexedProperties(structure->indexingType())); return 0; - - return ArrayStorage::sizeFor(arrayStorage()->vectorLength()); + } } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/IndexingType.cpp b/Source/JavaScriptCore/runtime/IndexingType.cpp new file mode 100644 index 000000000..7261847a2 --- /dev/null +++ b/Source/JavaScriptCore/runtime/IndexingType.cpp @@ -0,0 +1,76 @@ +/* + * 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 "IndexingType.h" + +#include <stdio.h> +#include <wtf/StringExtras.h> + +namespace JSC { + +const char* indexingTypeToString(IndexingType indexingType) +{ + static char result[128]; + const char* basicName; + switch (indexingType & AllArrayTypes) { + case NonArray: + basicName = "NonArray"; + break; + case NonArrayWithContiguous: + basicName = "NonArrayWithContiguous"; + break; + case NonArrayWithArrayStorage: + basicName = "NonArrayWithArrayStorage"; + break; + case NonArrayWithSlowPutArrayStorage: + basicName = "NonArrayWithSlowPutArrayStorage"; + break; + case ArrayClass: + basicName = "ArrayClass"; + break; + case ArrayWithContiguous: + basicName = "ArrayWithContiguous"; + break; + case ArrayWithArrayStorage: + basicName = "ArrayWithArrayStorage"; + break; + case ArrayWithSlowPutArrayStorage: + basicName = "ArrayWithSlowPutArrayStorage"; + break; + default: + basicName = "Unknown!"; + break; + } + + snprintf( + result, sizeof(result), "%s%s", basicName, + (indexingType & MayHaveIndexedAccessors) ? "|MayHaveIndexedAccessors" : ""); + + return result; +} + +} // namespace JSC + diff --git a/Source/JavaScriptCore/runtime/IndexingType.h b/Source/JavaScriptCore/runtime/IndexingType.h index 3b97230ea..4bbe3cfa0 100644 --- a/Source/JavaScriptCore/runtime/IndexingType.h +++ b/Source/JavaScriptCore/runtime/IndexingType.h @@ -26,32 +26,44 @@ #ifndef IndexingType_h #define IndexingType_h +#include <wtf/StdLibExtras.h> + namespace JSC { typedef uint8_t IndexingType; // Flags for testing the presence of capabilities. static const IndexingType IsArray = 1; -static const IndexingType HasArrayStorage = 8; -static const IndexingType HasSlowPutArrayStorage = 16; + +// The shape of the indexed property storage. +static const IndexingType IndexingShapeMask = 30; +static const IndexingType NoIndexingShape = 0; +static const IndexingType ContiguousShape = 26; +static const IndexingType ArrayStorageShape = 28; +static const IndexingType SlowPutArrayStorageShape = 30; // Additional flags for tracking the history of the type. These are usually // masked off unless you ask for them directly. -static const IndexingType HadArrayStorage = 32; // Means that this object did have array storage in the past. -static const IndexingType MayHaveIndexedAccessors = 64; +static const IndexingType MayHaveIndexedAccessors = 32; // List of acceptable array types. static const IndexingType NonArray = 0; -static const IndexingType NonArrayWithArrayStorage = HasArrayStorage; -static const IndexingType NonArrayWithSlowPutArrayStorage = HasSlowPutArrayStorage; +static const IndexingType NonArrayWithContiguous = ContiguousShape; +static const IndexingType NonArrayWithArrayStorage = ArrayStorageShape; +static const IndexingType NonArrayWithSlowPutArrayStorage = SlowPutArrayStorageShape; static const IndexingType ArrayClass = IsArray; // I'd want to call this "Array" but this would lead to disastrous namespace pollution. -static const IndexingType ArrayWithArrayStorage = IsArray | HasArrayStorage; -static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | HasSlowPutArrayStorage; +static const IndexingType ArrayWithContiguous = IsArray | ContiguousShape; +static const IndexingType ArrayWithArrayStorage = IsArray | ArrayStorageShape; +static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | SlowPutArrayStorageShape; #define ALL_BLANK_INDEXING_TYPES \ NonArray: \ case ArrayClass +#define ALL_CONTIGUOUS_INDEXING_TYPES \ + NonArrayWithContiguous: \ + case ArrayWithContiguous + #define ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES \ ArrayWithArrayStorage: \ case ArrayWithSlowPutArrayStorage @@ -63,12 +75,7 @@ static const IndexingType ArrayWithSlowPutArrayStorage = IsArray | HasSlowPut static inline bool hasIndexedProperties(IndexingType indexingType) { - switch (indexingType) { - case ALL_BLANK_INDEXING_TYPES: - return false; - default: - return true; - } + return (indexingType & IndexingShapeMask) != NoIndexingShape; } static inline bool hasIndexingHeader(IndexingType type) @@ -76,16 +83,30 @@ static inline bool hasIndexingHeader(IndexingType type) return hasIndexedProperties(type); } +static inline bool hasContiguous(IndexingType indexingType) +{ + return (indexingType & IndexingShapeMask) == ContiguousShape; +} + +// FIXME: This is an awkward name. This should really be called hasArrayStorage() +// and then next method down should be called hasAnyArrayStorage(). +static inline bool hasFastArrayStorage(IndexingType indexingType) +{ + return (indexingType & IndexingShapeMask) == ArrayStorageShape; +} + static inline bool hasArrayStorage(IndexingType indexingType) { - return !!(indexingType & (HasArrayStorage | HasSlowPutArrayStorage)); + return static_cast<uint8_t>((indexingType & IndexingShapeMask) - ArrayStorageShape) <= static_cast<uint8_t>(SlowPutArrayStorageShape - ArrayStorageShape); } static inline bool shouldUseSlowPut(IndexingType indexingType) { - return !!(indexingType & HasSlowPutArrayStorage); + return (indexingType & IndexingShapeMask) == SlowPutArrayStorageShape; } +const char* indexingTypeToString(IndexingType); + // Mask of all possible types. static const IndexingType AllArrayTypes = 31; diff --git a/Source/JavaScriptCore/runtime/InitializeThreading.cpp b/Source/JavaScriptCore/runtime/InitializeThreading.cpp index 1a7239f60..1a6c84514 100644 --- a/Source/JavaScriptCore/runtime/InitializeThreading.cpp +++ b/Source/JavaScriptCore/runtime/InitializeThreading.cpp @@ -31,6 +31,7 @@ #include "ExecutableAllocator.h" #include "Heap.h" +#include "HeapStatistics.h" #include "Options.h" #include "Identifier.h" #include "JSDateMath.h" @@ -56,13 +57,15 @@ static void initializeThreadingOnce() WTF::initializeThreading(); GlobalJSLock::initialize(); Options::initialize(); + if (Options::recordGCPauseTimes()) + HeapStatistics::initialize(); #if ENABLE(WRITE_BARRIER_PROFILING) WriteBarrierCounters::initialize(); #endif #if ENABLE(ASSEMBLER) ExecutableAllocator::initializeAllocator(); #endif - RegisterFile::initializeThreading(); + JSStack::initializeThreading(); #if ENABLE(LLINT) LLInt::initialize(); #endif diff --git a/Source/JavaScriptCore/runtime/InternalFunction.cpp b/Source/JavaScriptCore/runtime/InternalFunction.cpp index e2de03d92..afb5e6317 100644 --- a/Source/JavaScriptCore/runtime/InternalFunction.cpp +++ b/Source/JavaScriptCore/runtime/InternalFunction.cpp @@ -29,13 +29,12 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(InternalFunction); ASSERT_HAS_TRIVIAL_DESTRUCTOR(InternalFunction); -const ClassInfo InternalFunction::s_info = { "Function", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) }; +const ClassInfo InternalFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(InternalFunction) }; InternalFunction::InternalFunction(JSGlobalObject* globalObject, Structure* structure) - : JSNonFinalObject(globalObject->globalData(), structure) + : JSDestructibleObject(globalObject->globalData(), structure) { } diff --git a/Source/JavaScriptCore/runtime/InternalFunction.h b/Source/JavaScriptCore/runtime/InternalFunction.h index e26b9f953..daeebc34d 100644 --- a/Source/JavaScriptCore/runtime/InternalFunction.h +++ b/Source/JavaScriptCore/runtime/InternalFunction.h @@ -24,16 +24,16 @@ #ifndef InternalFunction_h #define InternalFunction_h -#include "JSObject.h" #include "Identifier.h" +#include "JSDestructibleObject.h" namespace JSC { class FunctionPrototype; - class InternalFunction : public JSNonFinalObject { + class InternalFunction : public JSDestructibleObject { public: - typedef JSNonFinalObject Base; + typedef JSDestructibleObject Base; static JS_EXPORTDATA const ClassInfo s_info; diff --git a/Source/JavaScriptCore/runtime/JSActivation.cpp b/Source/JavaScriptCore/runtime/JSActivation.cpp index c34e10bc8..3b665962f 100644 --- a/Source/JavaScriptCore/runtime/JSActivation.cpp +++ b/Source/JavaScriptCore/runtime/JSActivation.cpp @@ -37,8 +37,6 @@ using namespace std; namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSActivation); - const ClassInfo JSActivation::s_info = { "JSActivation", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSActivation) }; void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor) @@ -49,7 +47,7 @@ void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor) ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); Base::visitChildren(thisObject, visitor); - // No need to mark our registers if they're still in the RegisterFile. + // No need to mark our registers if they're still in the JSStack. if (!thisObject->isTornOff()) return; @@ -116,11 +114,11 @@ void JSActivation::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec SymbolTable::const_iterator end = thisObject->symbolTable()->end(); for (SymbolTable::const_iterator it = thisObject->symbolTable()->begin(); it != end; ++it) { - if (it->second.getAttributes() & DontEnum && mode != IncludeDontEnumProperties) + if (it->value.getAttributes() & DontEnum && mode != IncludeDontEnumProperties) continue; - if (!thisObject->isValid(it->second)) + if (!thisObject->isValid(it->value)) continue; - propertyNames.add(Identifier(exec, it->first.get())); + propertyNames.add(Identifier(exec, it->key.get())); } // Skip the JSVariableObject implementation of getOwnNonIndexPropertyNames JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode); @@ -133,7 +131,7 @@ inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData, SymbolTable::iterator iter = symbolTable()->find(propertyName.publicName()); if (iter == symbolTable()->end()) return false; - SymbolTableEntry& entry = iter->second; + SymbolTableEntry& entry = iter->value; ASSERT(!entry.isNull()); if (!isValid(entry)) return false; diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp index 8398ae77d..7028c3b95 100644 --- a/Source/JavaScriptCore/runtime/JSArray.cpp +++ b/Source/JavaScriptCore/runtime/JSArray.cpp @@ -44,8 +44,6 @@ using namespace WTF; namespace JSC { - -ASSERT_CLASS_FITS_IN_CELL(JSArray); ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSArray); const ClassInfo JSArray::s_info = {"Array", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(JSArray)}; @@ -245,8 +243,8 @@ void JSArray::getOwnNonIndexPropertyNames(JSObject* object, ExecState* exec, Pro JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode); } -// This method makes room in the vector, but leaves the new space uncleared. -bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, unsigned count) +// This method makes room in the vector, but leaves the new space for count slots uncleared. +bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, bool addToFront, unsigned count) { ArrayStorage* storage = ensureArrayStorage(globalData); Butterfly* butterfly = storage->butterfly(); @@ -254,7 +252,7 @@ bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, unsigned count) unsigned propertySize = structure()->outOfLineSize(); // If not, we should have handled this on the fast path. - ASSERT(count > storage->m_indexBias); + ASSERT(!addToFront || count > storage->m_indexBias); // Step 1: // Gather 4 key metrics: @@ -278,7 +276,7 @@ bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, unsigned count) unsigned desiredCapacity = min(MAX_STORAGE_VECTOR_LENGTH, max(BASE_VECTOR_LEN, requiredVectorLength) << 1); // Step 2: - // We're either going to choose to allocate a new ArrayStorage, or we're going to reuse the existing on. + // We're either going to choose to allocate a new ArrayStorage, or we're going to reuse the existing one. void* newAllocBase = 0; unsigned newStorageCapacity; @@ -297,36 +295,48 @@ bool JSArray::unshiftCountSlowCase(JSGlobalData& globalData, unsigned count) // Work out where we're going to move things to. // Determine how much of the vector to use as pre-capacity, and how much as post-capacity. + // If we're adding to the end, we'll add all the new space to the end. // If the vector had no free post-capacity (length >= m_vectorLength), don't give it any. // If it did, we calculate the amount that will remain based on an atomic decay - leave the // vector with half the post-capacity it had previously. unsigned postCapacity = 0; - if (length < storage->vectorLength()) { + if (!addToFront) + postCapacity = max(newStorageCapacity - requiredVectorLength, count); + else if (length < storage->vectorLength()) { // Atomic decay, + the post-capacity cannot be greater than what is available. postCapacity = min((storage->vectorLength() - length) >> 1, newStorageCapacity - requiredVectorLength); // If we're moving contents within the same allocation, the post-capacity is being reduced. ASSERT(newAllocBase != butterfly->base(structure()) || postCapacity < storage->vectorLength() - length); } - + unsigned newVectorLength = requiredVectorLength + postCapacity; unsigned newIndexBias = newStorageCapacity - newVectorLength; Butterfly* newButterfly = Butterfly::fromBase(newAllocBase, newIndexBias, propertyCapacity); - - memmove(newButterfly->arrayStorage()->m_vector + count, storage->m_vector, sizeof(JSValue) * usedVectorLength); - memmove(newButterfly->propertyStorage() - propertySize, butterfly->propertyStorage() - propertySize, sizeof(JSValue) * propertySize + sizeof(IndexingHeader) + ArrayStorage::sizeFor(0)); - + + if (addToFront) { + ASSERT(count + usedVectorLength <= newVectorLength); + memmove(newButterfly->arrayStorage()->m_vector + count, storage->m_vector, sizeof(JSValue) * usedVectorLength); + memmove(newButterfly->propertyStorage() - propertySize, butterfly->propertyStorage() - propertySize, sizeof(JSValue) * propertySize + sizeof(IndexingHeader) + ArrayStorage::sizeFor(0)); + } else if ((newAllocBase != butterfly->base(structure())) || (newIndexBias != storage->m_indexBias)) { + memmove(newButterfly->propertyStorage() - propertySize, butterfly->propertyStorage() - propertySize, sizeof(JSValue) * propertySize + sizeof(IndexingHeader) + ArrayStorage::sizeFor(0)); + memmove(newButterfly->arrayStorage()->m_vector, storage->m_vector, sizeof(JSValue) * usedVectorLength); + + WriteBarrier<Unknown>* newVector = newButterfly->arrayStorage()->m_vector; + for (unsigned i = requiredVectorLength; i < newVectorLength; i++) + newVector[i].clear(); + } + newButterfly->arrayStorage()->setVectorLength(newVectorLength); newButterfly->arrayStorage()->m_indexBias = newIndexBias; - + m_butterfly = newButterfly; return true; } -bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException) +bool JSArray::setLengthWithArrayStorage(ExecState* exec, unsigned newLength, bool throwException, ArrayStorage* storage) { - ArrayStorage* storage = ensureArrayStorage(exec->globalData()); unsigned length = storage->length(); // If the length is read only then we enter sparse mode, so should enter the following 'if'. @@ -343,7 +353,7 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException keys.reserveCapacity(min(map->size(), static_cast<size_t>(length - newLength))); SparseArrayValueMap::const_iterator end = map->end(); for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) { - unsigned index = static_cast<unsigned>(it->first); + unsigned index = static_cast<unsigned>(it->key); if (index < length && index >= newLength) keys.append(index); } @@ -358,7 +368,7 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException unsigned index = keys[--i]; SparseArrayValueMap::iterator it = map->find(index); ASSERT(it != map->notFound()); - if (it->second.attributes & DontDelete) { + if (it->value.attributes & DontDelete) { storage->setLength(index + 1); return reject(exec, throwException, "Unable to delete property."); } @@ -389,12 +399,71 @@ bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException return true; } +bool JSArray::setLength(ExecState* exec, unsigned newLength, bool throwException) +{ + switch (structure()->indexingType()) { + case ArrayClass: + if (!newLength) + return true; + if (newLength >= MIN_SPARSE_ARRAY_INDEX) { + return setLengthWithArrayStorage( + exec, newLength, throwException, + convertContiguousToArrayStorage(exec->globalData())); + } + createInitialContiguous(exec->globalData(), newLength); + return true; + + case ArrayWithContiguous: + if (newLength == m_butterfly->publicLength()) + return true; + if (newLength >= MAX_ARRAY_INDEX // This case ensures that we can do fast push. + || (newLength >= MIN_SPARSE_ARRAY_INDEX + && !isDenseEnoughForVector(newLength, countElementsInContiguous(m_butterfly)))) { + return setLengthWithArrayStorage( + exec, newLength, throwException, + convertContiguousToArrayStorage(exec->globalData())); + } + if (newLength > m_butterfly->publicLength()) { + ensureContiguousLength(exec->globalData(), newLength); + return true; + } + for (unsigned i = m_butterfly->publicLength(); i-- > newLength;) + m_butterfly->contiguous()[i].clear(); + m_butterfly->setPublicLength(newLength); + return true; + + case ArrayWithArrayStorage: + case ArrayWithSlowPutArrayStorage: + return setLengthWithArrayStorage(exec, newLength, throwException, arrayStorage()); + + default: + CRASH(); + return false; + } +} + JSValue JSArray::pop(ExecState* exec) { switch (structure()->indexingType()) { case ArrayClass: return jsUndefined(); + case ArrayWithContiguous: { + unsigned length = m_butterfly->publicLength(); + + if (!length--) + return jsUndefined(); + + ASSERT(length < m_butterfly->vectorLength()); + JSValue value = m_butterfly->contiguous()[length].get(); + if (value) { + m_butterfly->contiguous()[length].clear(); + m_butterfly->setPublicLength(length); + return value; + } + break; + } + case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = m_butterfly->arrayStorage(); @@ -418,26 +487,28 @@ JSValue JSArray::pop(ExecState* exec) return element; } } - - // Let element be the result of calling the [[Get]] internal method of O with argument indx. - JSValue element = get(exec, index); - if (exec->hadException()) - return jsUndefined(); - // Call the [[Delete]] internal method of O with arguments indx and true. - if (!deletePropertyByIndex(this, exec, index)) { - throwTypeError(exec, "Unable to delete property."); - return jsUndefined(); - } - // Call the [[Put]] internal method of O with arguments "length", indx, and true. - setLength(exec, index, true); - // Return element. - return element; + break; } default: - ASSERT_NOT_REACHED(); + CRASH(); return JSValue(); } + + unsigned index = getArrayLength() - 1; + // Let element be the result of calling the [[Get]] internal method of O with argument indx. + JSValue element = get(exec, index); + if (exec->hadException()) + return jsUndefined(); + // Call the [[Delete]] internal method of O with arguments indx and true. + if (!deletePropertyByIndex(this, exec, index)) { + throwTypeError(exec, "Unable to delete property."); + return jsUndefined(); + } + // Call the [[Put]] internal method of O with arguments "length", indx, and true. + setLength(exec, index, true); + // Return element. + return element; } // Push & putIndex are almost identical, with two small differences. @@ -451,6 +522,26 @@ void JSArray::push(ExecState* exec, JSValue value) break; } + case ArrayWithContiguous: { + unsigned length = m_butterfly->publicLength(); + ASSERT(length <= m_butterfly->vectorLength()); + if (length < m_butterfly->vectorLength()) { + m_butterfly->contiguous()[length].set(exec->globalData(), this, value); + m_butterfly->setPublicLength(length + 1); + return; + } + + if (length > MAX_ARRAY_INDEX) { + methodTable()->putByIndex(this, exec, length, value, true); + if (!exec->hadException()) + throwError(exec, createRangeError(exec, "Invalid array length")); + return; + } + + putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, length, value); + return; + } + case ArrayWithSlowPutArrayStorage: { unsigned oldLength = length(); if (attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true)) { @@ -492,59 +583,139 @@ void JSArray::push(ExecState* exec, JSValue value) } } -bool JSArray::shiftCount(ExecState* exec, unsigned count) +bool JSArray::shiftCountWithArrayStorage(unsigned startIndex, unsigned count, ArrayStorage* storage) { - ASSERT(count > 0); - - ArrayStorage* storage = ensureArrayStorage(exec->globalData()); - unsigned oldLength = storage->length(); ASSERT(count <= oldLength); // If the array contains holes or is otherwise in an abnormal state, // use the generic algorithm in ArrayPrototype. - if (oldLength != storage->m_numValuesInVector || inSparseIndexingMode()) + if (oldLength != storage->m_numValuesInVector || inSparseIndexingMode() || shouldUseSlowPut(structure()->indexingType())) return false; if (!oldLength) return true; + unsigned length = oldLength - count; + storage->m_numValuesInVector -= count; - storage->setLength(oldLength - count); + storage->setLength(length); unsigned vectorLength = storage->vectorLength(); + if (!vectorLength) + return true; + + if (startIndex >= vectorLength) + return true; + + if (startIndex + count > vectorLength) + count = vectorLength - startIndex; + + unsigned usedVectorLength = min(vectorLength, oldLength); + + vectorLength -= count; + storage->setVectorLength(vectorLength); + if (vectorLength) { - count = min(vectorLength, (unsigned)count); - - vectorLength -= count; - storage->setVectorLength(vectorLength); - - if (vectorLength) { + if (startIndex < usedVectorLength - (startIndex + count)) { + if (startIndex) { + memmove( + storage->m_vector + count, + storage->m_vector, + sizeof(JSValue) * startIndex); + } m_butterfly = m_butterfly->shift(structure(), count); storage = m_butterfly->arrayStorage(); storage->m_indexBias += count; + } else { + memmove( + storage->m_vector + startIndex, + storage->m_vector + startIndex + count, + sizeof(JSValue) * (usedVectorLength - (startIndex + count))); + for (unsigned i = usedVectorLength - count; i < usedVectorLength; ++i) + storage->m_vector[i].clear(); } } return true; } +bool JSArray::shiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex, unsigned count) +{ + ASSERT(count > 0); + + switch (structure()->indexingType()) { + case ArrayClass: + return true; + + case ArrayWithContiguous: { + unsigned oldLength = m_butterfly->publicLength(); + ASSERT(count <= oldLength); + + // We may have to walk the entire array to do the shift. We're willing to do + // so only if it's not horribly slow. + if (oldLength - (startIndex + count) >= MIN_SPARSE_ARRAY_INDEX) + return shiftCountWithArrayStorage(startIndex, count, convertContiguousToArrayStorage(exec->globalData())); + + unsigned end = oldLength - count; + for (unsigned i = startIndex; i < end; ++i) { + // Storing to a hole is fine since we're still having a good time. But reading + // from a hole is totally not fine, since we might have to read from the proto + // chain. + JSValue v = m_butterfly->contiguous()[i + count].get(); + if (UNLIKELY(!v)) { + // The purpose of this path is to ensure that we don't make the same + // mistake in the future: shiftCountWithArrayStorage() can't do anything + // about holes (at least for now), but it can detect them quickly. So + // we convert to array storage and then allow the array storage path to + // figure it out. + return shiftCountWithArrayStorage(startIndex, count, convertContiguousToArrayStorage(exec->globalData())); + } + // No need for a barrier since we're just moving data around in the same vector. + // This is in line with our standing assumption that we won't have a deletion + // barrier. + m_butterfly->contiguous()[i].setWithoutWriteBarrier(v); + } + for (unsigned i = end; i < oldLength; ++i) + m_butterfly->contiguous()[i].clear(); + + m_butterfly->setPublicLength(oldLength - count); + return true; + } + + case ArrayWithArrayStorage: + case ArrayWithSlowPutArrayStorage: + return shiftCountWithArrayStorage(startIndex, count, arrayStorage()); + + default: + CRASH(); + return false; + } +} + // Returns true if the unshift can be handled, false to fallback. -bool JSArray::unshiftCount(ExecState* exec, unsigned count) +bool JSArray::unshiftCountWithArrayStorage(ExecState* exec, unsigned startIndex, unsigned count, ArrayStorage* storage) { - ArrayStorage* storage = ensureArrayStorage(exec->globalData()); unsigned length = storage->length(); + ASSERT(startIndex <= length); + // If the array contains holes or is otherwise in an abnormal state, // use the generic algorithm in ArrayPrototype. - if (length != storage->m_numValuesInVector || storage->inSparseMode()) + if (length != storage->m_numValuesInVector || storage->inSparseMode() || shouldUseSlowPut(structure()->indexingType())) return false; - if (storage->m_indexBias >= count) { + bool moveFront = !startIndex || startIndex < length / 2; + + unsigned vectorLength = storage->vectorLength(); + + if (moveFront && storage->m_indexBias >= count) { m_butterfly = storage->butterfly()->unshift(structure(), count); storage = m_butterfly->arrayStorage(); storage->m_indexBias -= count; - storage->setVectorLength(storage->vectorLength() + count); - } else if (unshiftCountSlowCase(exec->globalData(), count)) + storage->setVectorLength(vectorLength + count); + } else if (!moveFront && vectorLength - length >= count) + storage = storage->butterfly()->arrayStorage(); + else if (unshiftCountSlowCase(exec->globalData(), moveFront, count)) storage = arrayStorage(); else { throwOutOfMemoryError(exec); @@ -552,11 +723,61 @@ bool JSArray::unshiftCount(ExecState* exec, unsigned count) } WriteBarrier<Unknown>* vector = storage->m_vector; + + if (startIndex) { + if (moveFront) + memmove(vector, vector + count, startIndex * sizeof(JSValue)); + else if (length - startIndex) + memmove(vector + startIndex + count, vector + startIndex, (length - startIndex) * sizeof(JSValue)); + } + for (unsigned i = 0; i < count; i++) - vector[i].clear(); + vector[i + startIndex].clear(); return true; } +bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startIndex, unsigned count) +{ + switch (structure()->indexingType()) { + case ArrayClass: + // We could handle this. But it shouldn't ever come up, so we won't. + return false; + + case ArrayWithContiguous: { + unsigned oldLength = m_butterfly->publicLength(); + + // We may have to walk the entire array to do the unshift. We're willing to do so + // only if it's not horribly slow. + if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX) + return unshiftCountWithArrayStorage(exec, startIndex, count, convertContiguousToArrayStorage(exec->globalData())); + + ensureContiguousLength(exec->globalData(), oldLength + count); + + for (unsigned i = oldLength; i-- > startIndex;) { + JSValue v = m_butterfly->contiguous()[i].get(); + if (UNLIKELY(!v)) + return unshiftCountWithArrayStorage(exec, startIndex, count, convertContiguousToArrayStorage(exec->globalData())); + m_butterfly->contiguous()[i + count].setWithoutWriteBarrier(v); + } + + // NOTE: we're leaving being garbage in the part of the array that we shifted out + // of. This is fine because the caller is required to store over that area, and + // in contiguous mode storing into a hole is guaranteed to behave exactly the same + // as storing over an existing element. + + return true; + } + + case ArrayWithArrayStorage: + case ArrayWithSlowPutArrayStorage: + return unshiftCountWithArrayStorage(exec, startIndex, count, arrayStorage()); + + default: + CRASH(); + return false; + } +} + static int compareNumbersForQSort(const void* a, const void* b) { double da = static_cast<const JSValue*>(a)->asNumber(); @@ -571,6 +792,45 @@ static int compareByStringPairForQSort(const void* a, const void* b) return codePointCompare(va->second, vb->second); } +template<IndexingType indexingType> +void JSArray::sortNumericVector(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData) +{ + ASSERT(indexingType == ArrayWithContiguous || indexingType == ArrayWithArrayStorage); + + unsigned lengthNotIncludingUndefined; + unsigned newRelevantLength; + compactForSorting<indexingType>( + lengthNotIncludingUndefined, + newRelevantLength); + + WriteBarrier<Unknown>* data = indexingData<indexingType>(); + + if (indexingType == ArrayWithArrayStorage && arrayStorage()->m_sparseMap.get()) { + throwOutOfMemoryError(exec); + return; + } + + if (!lengthNotIncludingUndefined) + return; + + bool allValuesAreNumbers = true; + for (size_t i = 0; i < newRelevantLength; ++i) { + if (!data[i].isNumber()) { + allValuesAreNumbers = false; + break; + } + } + + if (!allValuesAreNumbers) + return sort(exec, compareFunction, callType, callData); + + // For numeric comparison, which is fast, qsort is faster than mergesort. We + // also don't require mergesort's stability, since there's no user visible + // side-effect from swapping the order of equal primitive values. + qsort(data, newRelevantLength, sizeof(WriteBarrier<Unknown>), compareNumbersForQSort); + return; +} + void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData) { ASSERT(!inSparseIndexingMode()); @@ -579,123 +839,129 @@ void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType cal case ArrayClass: return; - case ArrayWithArrayStorage: { - unsigned lengthNotIncludingUndefined = compactForSorting(exec->globalData()); - ArrayStorage* storage = m_butterfly->arrayStorage(); - - if (storage->m_sparseMap.get()) { - throwOutOfMemoryError(exec); - return; - } - - if (!lengthNotIncludingUndefined) - return; - - bool allValuesAreNumbers = true; - size_t size = storage->m_numValuesInVector; - for (size_t i = 0; i < size; ++i) { - if (!storage->m_vector[i].isNumber()) { - allValuesAreNumbers = false; - break; - } - } - - if (!allValuesAreNumbers) - return sort(exec, compareFunction, callType, callData); - - // For numeric comparison, which is fast, qsort is faster than mergesort. We - // also don't require mergesort's stability, since there's no user visible - // side-effect from swapping the order of equal primitive values. - qsort(storage->m_vector, size, sizeof(WriteBarrier<Unknown>), compareNumbersForQSort); - + case ArrayWithContiguous: + sortNumericVector<ArrayWithContiguous>(exec, compareFunction, callType, callData); + return; + + case ArrayWithArrayStorage: + sortNumericVector<ArrayWithArrayStorage>(exec, compareFunction, callType, callData); return; - } default: - ASSERT_NOT_REACHED(); + CRASH(); + return; } } -void JSArray::sort(ExecState* exec) +template<IndexingType indexingType> +void JSArray::sortCompactedVector(ExecState* exec, WriteBarrier<Unknown>* begin, unsigned relevantLength) { - ASSERT(!inSparseIndexingMode()); - - switch (structure()->indexingType()) { - case ArrayClass: + if (!relevantLength) return; + + JSGlobalData& globalData = exec->globalData(); + + // Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that. + // This is a considerable improvement over doing it twice per comparison, though it requires a large temporary + // buffer. Besides, this protects us from crashing if some objects have custom toString methods that return + // random or otherwise changing results, effectively making compare function inconsistent. - case ArrayWithArrayStorage: { - unsigned lengthNotIncludingUndefined = compactForSorting(exec->globalData()); - ArrayStorage* storage = m_butterfly->arrayStorage(); - if (storage->m_sparseMap.get()) { - throwOutOfMemoryError(exec); - return; - } - - if (!lengthNotIncludingUndefined) - return; - - // Converting JavaScript values to strings can be expensive, so we do it once up front and sort based on that. - // This is a considerable improvement over doing it twice per comparison, though it requires a large temporary - // buffer. Besides, this protects us from crashing if some objects have custom toString methods that return - // random or otherwise changing results, effectively making compare function inconsistent. - - Vector<ValueStringPair> values(lengthNotIncludingUndefined); - if (!values.begin()) { - throwOutOfMemoryError(exec); - return; - } + Vector<ValueStringPair> values(relevantLength); + if (!values.begin()) { + throwOutOfMemoryError(exec); + return; + } - Heap::heap(this)->pushTempSortVector(&values); + Heap::heap(this)->pushTempSortVector(&values); - bool isSortingPrimitiveValues = true; - for (size_t i = 0; i < lengthNotIncludingUndefined; i++) { - JSValue value = storage->m_vector[i].get(); - ASSERT(!value.isUndefined()); - values[i].first = value; - isSortingPrimitiveValues = isSortingPrimitiveValues && value.isPrimitive(); - } + bool isSortingPrimitiveValues = true; + for (size_t i = 0; i < relevantLength; i++) { + JSValue value = begin[i].get(); + ASSERT(!value.isUndefined()); + values[i].first = value; + isSortingPrimitiveValues = isSortingPrimitiveValues && value.isPrimitive(); + } - // FIXME: The following loop continues to call toString on subsequent values even after - // a toString call raises an exception. + // FIXME: The following loop continues to call toString on subsequent values even after + // a toString call raises an exception. - for (size_t i = 0; i < lengthNotIncludingUndefined; i++) - values[i].second = values[i].first.toWTFStringInline(exec); + for (size_t i = 0; i < relevantLength; i++) + values[i].second = values[i].first.toWTFStringInline(exec); - if (exec->hadException()) { - Heap::heap(this)->popTempSortVector(&values); - return; - } + if (exec->hadException()) { + Heap::heap(this)->popTempSortVector(&values); + return; + } - // FIXME: Since we sort by string value, a fast algorithm might be to use a radix sort. That would be O(N) rather - // than O(N log N). + // FIXME: Since we sort by string value, a fast algorithm might be to use a radix sort. That would be O(N) rather + // than O(N log N). #if HAVE(MERGESORT) - if (isSortingPrimitiveValues) - qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort); - else - mergesort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort); -#else - // FIXME: The qsort library function is likely to not be a stable sort. - // ECMAScript-262 does not specify a stable sort, but in practice, browsers perform a stable sort. + if (isSortingPrimitiveValues) qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort); + else + mergesort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort); +#else + // FIXME: The qsort library function is likely to not be a stable sort. + // ECMAScript-262 does not specify a stable sort, but in practice, browsers perform a stable sort. + qsort(values.begin(), values.size(), sizeof(ValueStringPair), compareByStringPairForQSort); #endif + + // If the toString function changed the length of the array or vector storage, + // increase the length to handle the orignal number of actual values. + switch (indexingType) { + case ArrayWithContiguous: + ensureContiguousLength(globalData, relevantLength); + break; - // If the toString function changed the length of the array or vector storage, - // increase the length to handle the orignal number of actual values. - if (storage->vectorLength() < lengthNotIncludingUndefined) { - increaseVectorLength(exec->globalData(), lengthNotIncludingUndefined); - storage = m_butterfly->arrayStorage(); + case ArrayWithArrayStorage: + if (arrayStorage()->vectorLength() < relevantLength) { + increaseVectorLength(exec->globalData(), relevantLength); + begin = arrayStorage()->m_vector; } - if (storage->length() < lengthNotIncludingUndefined) - storage->setLength(lengthNotIncludingUndefined); + if (arrayStorage()->length() < relevantLength) + arrayStorage()->setLength(relevantLength); + break; + + default: + CRASH(); + } + + for (size_t i = 0; i < relevantLength; i++) + begin[i].set(globalData, this, values[i].first); + + Heap::heap(this)->popTempSortVector(&values); +} + +void JSArray::sort(ExecState* exec) +{ + ASSERT(!inSparseIndexingMode()); + + switch (structure()->indexingType()) { + case ArrayClass: + return; - JSGlobalData& globalData = exec->globalData(); - for (size_t i = 0; i < lengthNotIncludingUndefined; i++) - storage->m_vector[i].set(globalData, this, values[i].first); + case ArrayWithContiguous: { + unsigned lengthNotIncludingUndefined; + unsigned newRelevantLength; + compactForSorting<ArrayWithContiguous>( + lengthNotIncludingUndefined, newRelevantLength); - Heap::heap(this)->popTempSortVector(&values); + sortCompactedVector<ArrayWithContiguous>( + exec, m_butterfly->contiguous(), lengthNotIncludingUndefined); + return; + } + + case ArrayWithArrayStorage: { + unsigned lengthNotIncludingUndefined; + unsigned newRelevantLength; + compactForSorting<ArrayWithArrayStorage>( + lengthNotIncludingUndefined, newRelevantLength); + ArrayStorage* storage = m_butterfly->arrayStorage(); + ASSERT(!storage->m_sparseMap); + sortCompactedVector<ArrayWithArrayStorage>( + exec, storage->m_vector, lengthNotIncludingUndefined); return; } @@ -781,122 +1047,116 @@ struct AVLTreeAbstractorForArrayCompare { static handle null() { return 0x7FFFFFFF; } }; -void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData) +template<IndexingType indexingType> +void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData) { ASSERT(!inSparseIndexingMode()); + ASSERT(indexingType == structure()->indexingType()); - switch (structure()->indexingType()) { - case ArrayClass: - return; - - case ArrayWithArrayStorage: { - ArrayStorage* storage = m_butterfly->arrayStorage(); - - // FIXME: This ignores exceptions raised in the compare function or in toNumber. + // FIXME: This ignores exceptions raised in the compare function or in toNumber. - // The maximum tree depth is compiled in - but the caller is clearly up to no good - // if a larger array is passed. - ASSERT(storage->length() <= static_cast<unsigned>(std::numeric_limits<int>::max())); - if (storage->length() > static_cast<unsigned>(std::numeric_limits<int>::max())) - return; - - unsigned usedVectorLength = min(storage->length(), storage->vectorLength()); - unsigned nodeCount = usedVectorLength + (storage->m_sparseMap ? storage->m_sparseMap->size() : 0); - - if (!nodeCount) - return; - - AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items - tree.abstractor().m_exec = exec; - tree.abstractor().m_compareFunction = compareFunction; - tree.abstractor().m_compareCallType = callType; - tree.abstractor().m_compareCallData = &callData; - tree.abstractor().m_nodes.grow(nodeCount); + // The maximum tree depth is compiled in - but the caller is clearly up to no good + // if a larger array is passed. + ASSERT(m_butterfly->publicLength() <= static_cast<unsigned>(std::numeric_limits<int>::max())); + if (m_butterfly->publicLength() > static_cast<unsigned>(std::numeric_limits<int>::max())) + return; - if (callType == CallTypeJS) - tree.abstractor().m_cachedCall = adoptPtr(new CachedCall(exec, jsCast<JSFunction*>(compareFunction), 2)); + unsigned usedVectorLength = relevantLength<indexingType>(); + unsigned nodeCount = usedVectorLength; - if (!tree.abstractor().m_nodes.begin()) { - throwOutOfMemoryError(exec); - return; - } + if (!nodeCount) + return; - // FIXME: If the compare function modifies the array, the vector, map, etc. could be modified - // right out from under us while we're building the tree here. + AVLTree<AVLTreeAbstractorForArrayCompare, 44> tree; // Depth 44 is enough for 2^31 items + tree.abstractor().m_exec = exec; + tree.abstractor().m_compareFunction = compareFunction; + tree.abstractor().m_compareCallType = callType; + tree.abstractor().m_compareCallData = &callData; + tree.abstractor().m_nodes.grow(nodeCount); - unsigned numDefined = 0; - unsigned numUndefined = 0; + if (callType == CallTypeJS) + tree.abstractor().m_cachedCall = adoptPtr(new CachedCall(exec, jsCast<JSFunction*>(compareFunction), 2)); - // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree. - for (; numDefined < usedVectorLength; ++numDefined) { - JSValue v = storage->m_vector[numDefined].get(); - if (!v || v.isUndefined()) - break; - tree.abstractor().m_nodes[numDefined].value = v; - tree.insert(numDefined); - } - for (unsigned i = numDefined; i < usedVectorLength; ++i) { - JSValue v = storage->m_vector[i].get(); - if (v) { - if (v.isUndefined()) - ++numUndefined; - else { - tree.abstractor().m_nodes[numDefined].value = v; - tree.insert(numDefined); - ++numDefined; - } - } - } - - unsigned newUsedVectorLength = numDefined + numUndefined; + if (!tree.abstractor().m_nodes.begin()) { + throwOutOfMemoryError(exec); + return; + } - if (SparseArrayValueMap* map = storage->m_sparseMap.get()) { - newUsedVectorLength += map->size(); - if (newUsedVectorLength > storage->vectorLength()) { - // Check that it is possible to allocate an array large enough to hold all the entries. - if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(exec->globalData(), newUsedVectorLength)) { - throwOutOfMemoryError(exec); - return; - } - storage = m_butterfly->arrayStorage(); - } - - SparseArrayValueMap::const_iterator end = map->end(); - for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) { - tree.abstractor().m_nodes[numDefined].value = it->second.getNonSparseMode(); + // FIXME: If the compare function modifies the array, the vector, map, etc. could be modified + // right out from under us while we're building the tree here. + + unsigned numDefined = 0; + unsigned numUndefined = 0; + + // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree. + for (; numDefined < usedVectorLength; ++numDefined) { + if (numDefined > m_butterfly->vectorLength()) + break; + JSValue v = indexingData<indexingType>()[numDefined].get(); + if (!v || v.isUndefined()) + break; + tree.abstractor().m_nodes[numDefined].value = v; + tree.insert(numDefined); + } + for (unsigned i = numDefined; i < usedVectorLength; ++i) { + if (i > m_butterfly->vectorLength()) + break; + JSValue v = indexingData<indexingType>()[i].get(); + if (v) { + if (v.isUndefined()) + ++numUndefined; + else { + tree.abstractor().m_nodes[numDefined].value = v; tree.insert(numDefined); ++numDefined; } - - deallocateSparseIndexMap(); } + } - ASSERT(tree.abstractor().m_nodes.size() >= numDefined); - - // FIXME: If the compare function changed the length of the array, the following might be - // modifying the vector incorrectly. + unsigned newUsedVectorLength = numDefined + numUndefined; - // Copy the values back into m_storage. - AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter; - iter.start_iter_least(tree); - JSGlobalData& globalData = exec->globalData(); - for (unsigned i = 0; i < numDefined; ++i) { - storage->m_vector[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value); - ++iter; - } + // The array size may have changed. Figure out the new bounds. + unsigned newestUsedVectorLength = relevantLength<indexingType>(); - // Put undefined values back in. - for (unsigned i = numDefined; i < newUsedVectorLength; ++i) - storage->m_vector[i].setUndefined(); + unsigned elementsToExtractThreshold = min(min(newestUsedVectorLength, numDefined), static_cast<unsigned>(tree.abstractor().m_nodes.size())); + unsigned undefinedElementsThreshold = min(newestUsedVectorLength, newUsedVectorLength); + unsigned clearElementsThreshold = min(newestUsedVectorLength, usedVectorLength); - // Ensure that unused values in the vector are zeroed out. - for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) - storage->m_vector[i].clear(); - - storage->m_numValuesInVector = newUsedVectorLength; + // Copy the values back into m_storage. + AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter; + iter.start_iter_least(tree); + JSGlobalData& globalData = exec->globalData(); + for (unsigned i = 0; i < elementsToExtractThreshold; ++i) { + indexingData<indexingType>()[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value); + ++iter; + } + // Put undefined values back in. + for (unsigned i = elementsToExtractThreshold; i < undefinedElementsThreshold; ++i) + indexingData<indexingType>()[i].setUndefined(); + + // Ensure that unused values in the vector are zeroed out. + for (unsigned i = undefinedElementsThreshold; i < clearElementsThreshold; ++i) + indexingData<indexingType>()[i].clear(); + + if (hasArrayStorage(indexingType)) + arrayStorage()->m_numValuesInVector = newUsedVectorLength; +} + +void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData) +{ + ASSERT(!inSparseIndexingMode()); + + switch (structure()->indexingType()) { + case ArrayClass: + return; + case ArrayWithContiguous: + sortVector<ArrayWithContiguous>(exec, compareFunction, callType, callData); + return; + + case ArrayWithArrayStorage: + sortVector<ArrayWithArrayStorage>(exec, compareFunction, callType, callData); return; - } default: ASSERT_NOT_REACHED(); @@ -905,129 +1165,127 @@ void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) { + unsigned i = 0; + unsigned vectorEnd; + WriteBarrier<Unknown>* vector; + switch (structure()->indexingType()) { case ArrayClass: return; + + case ArrayWithContiguous: { + vectorEnd = m_butterfly->publicLength(); + vector = m_butterfly->contiguous(); + break; + } case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = m_butterfly->arrayStorage(); - WriteBarrier<Unknown>* vector = storage->m_vector; - unsigned vectorEnd = min(storage->length(), storage->vectorLength()); - unsigned i = 0; - for (; i < vectorEnd; ++i) { - WriteBarrier<Unknown>& v = vector[i]; - if (!v) - break; - args.append(v.get()); - } - - for (; i < storage->length(); ++i) - args.append(get(exec, i)); - return; + vector = storage->m_vector; + vectorEnd = min(storage->length(), storage->vectorLength()); + break; } default: - ASSERT_NOT_REACHED(); + CRASH(); + vector = 0; + vectorEnd = 0; + break; } + + for (; i < vectorEnd; ++i) { + WriteBarrier<Unknown>& v = vector[i]; + if (!v) + break; + args.append(v.get()); + } + + for (; i < length(); ++i) + args.append(get(exec, i)); } void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t length) { + unsigned i = 0; + WriteBarrier<Unknown>* vector; + unsigned vectorEnd; + ASSERT(length == this->length()); switch (structure()->indexingType()) { case ArrayClass: return; + case ArrayWithContiguous: { + vector = m_butterfly->contiguous(); + vectorEnd = m_butterfly->publicLength(); + break; + } + case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = m_butterfly->arrayStorage(); - unsigned i = 0; - WriteBarrier<Unknown>* vector = storage->m_vector; - unsigned vectorEnd = min(length, storage->vectorLength()); - for (; i < vectorEnd; ++i) { - WriteBarrier<Unknown>& v = vector[i]; - if (!v) - break; - callFrame->setArgument(i, v.get()); - } - - for (; i < length; ++i) - callFrame->setArgument(i, get(exec, i)); - return; + vector = storage->m_vector; + vectorEnd = min(length, storage->vectorLength()); + break; } default: - ASSERT_NOT_REACHED(); + CRASH(); + vector = 0; + vectorEnd = 0; + break; + } + + for (; i < vectorEnd; ++i) { + WriteBarrier<Unknown>& v = vector[i]; + if (!v) + break; + callFrame->setArgument(i, v.get()); } + + for (; i < length; ++i) + callFrame->setArgument(i, get(exec, i)); } -unsigned JSArray::compactForSorting(JSGlobalData& globalData) +template<IndexingType indexingType> +void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLength) { ASSERT(!inSparseIndexingMode()); + ASSERT(indexingType == structure()->indexingType()); - switch (structure()->indexingType()) { - case ArrayClass: - return 0; - - case ArrayWithArrayStorage: { - ArrayStorage* storage = m_butterfly->arrayStorage(); - - unsigned usedVectorLength = min(storage->length(), storage->vectorLength()); - - unsigned numDefined = 0; - unsigned numUndefined = 0; - - for (; numDefined < usedVectorLength; ++numDefined) { - JSValue v = storage->m_vector[numDefined].get(); - if (!v || v.isUndefined()) - break; - } + unsigned myRelevantLength = relevantLength<indexingType>(); + + numDefined = 0; + unsigned numUndefined = 0; - for (unsigned i = numDefined; i < usedVectorLength; ++i) { - JSValue v = storage->m_vector[i].get(); - if (v) { - if (v.isUndefined()) - ++numUndefined; - else - storage->m_vector[numDefined++].setWithoutWriteBarrier(v); - } - } + for (; numDefined < myRelevantLength; ++numDefined) { + JSValue v = indexingData<indexingType>()[numDefined].get(); + if (!v || v.isUndefined()) + break; + } - unsigned newUsedVectorLength = numDefined + numUndefined; - - if (SparseArrayValueMap* map = storage->m_sparseMap.get()) { - newUsedVectorLength += map->size(); - if (newUsedVectorLength > storage->vectorLength()) { - // Check that it is possible to allocate an array large enough to hold all the entries - if not, - // exception is thrown by caller. - if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(globalData, newUsedVectorLength)) - return 0; - - storage = m_butterfly->arrayStorage(); - } - - SparseArrayValueMap::const_iterator end = map->end(); - for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) - storage->m_vector[numDefined++].setWithoutWriteBarrier(it->second.getNonSparseMode()); - - deallocateSparseIndexMap(); + for (unsigned i = numDefined; i < myRelevantLength; ++i) { + JSValue v = indexingData<indexingType>()[i].get(); + if (v) { + if (v.isUndefined()) + ++numUndefined; + else + indexingData<indexingType>()[numDefined++].setWithoutWriteBarrier(v); } - - for (unsigned i = numDefined; i < newUsedVectorLength; ++i) - storage->m_vector[i].setUndefined(); - for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i) - storage->m_vector[i].clear(); - - storage->m_numValuesInVector = newUsedVectorLength; - - return numDefined; } - default: - ASSERT_NOT_REACHED(); - return 0; - } -} + newRelevantLength = numDefined + numUndefined; + + if (hasArrayStorage(indexingType)) + ASSERT(!arrayStorage()->m_sparseMap); + + for (unsigned i = numDefined; i < newRelevantLength; ++i) + indexingData<indexingType>()[i].setUndefined(); + for (unsigned i = newRelevantLength; i < myRelevantLength; ++i) + indexingData<indexingType>()[i].clear(); + if (hasArrayStorage(indexingType)) + arrayStorage()->m_numValuesInVector = newRelevantLength; +} } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h index 6e539c9db..d4622aacc 100644 --- a/Source/JavaScriptCore/runtime/JSArray.h +++ b/Source/JavaScriptCore/runtime/JSArray.h @@ -71,8 +71,60 @@ namespace JSC { void push(ExecState*, JSValue); JSValue pop(ExecState*); - bool shiftCount(ExecState*, unsigned count); - bool unshiftCount(ExecState*, unsigned count); + enum ShiftCountMode { + // This form of shift hints that we're doing queueing. With this assumption in hand, + // we convert to ArrayStorage, which has queue optimizations. + ShiftCountForShift, + + // This form of shift hints that we're just doing care and feeding on an array that + // is probably typically used for ordinary accesses. With this assumption in hand, + // we try to preserve whatever indexing type it has already. + ShiftCountForSplice + }; + + bool shiftCountForShift(ExecState* exec, unsigned startIndex, unsigned count) + { + return shiftCountWithArrayStorage(startIndex, count, ensureArrayStorage(exec->globalData())); + } + bool shiftCountForSplice(ExecState* exec, unsigned startIndex, unsigned count) + { + return shiftCountWithAnyIndexingType(exec, startIndex, count); + } + template<ShiftCountMode shiftCountMode> + bool shiftCount(ExecState* exec, unsigned startIndex, unsigned count) + { + switch (shiftCountMode) { + case ShiftCountForShift: + return shiftCountForShift(exec, startIndex, count); + case ShiftCountForSplice: + return shiftCountForSplice(exec, startIndex, count); + default: + CRASH(); + return false; + } + } + + bool unshiftCountForShift(ExecState* exec, unsigned startIndex, unsigned count) + { + return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->globalData())); + } + bool unshiftCountForSplice(ExecState* exec, unsigned startIndex, unsigned count) + { + return unshiftCountWithAnyIndexingType(exec, startIndex, count); + } + template<ShiftCountMode shiftCountMode> + bool unshiftCount(ExecState* exec, unsigned startIndex, unsigned count) + { + switch (shiftCountMode) { + case ShiftCountForShift: + return unshiftCountForShift(exec, startIndex, count); + case ShiftCountForSplice: + return unshiftCountForSplice(exec, startIndex, count); + default: + CRASH(); + return false; + } + } void fillArgList(ExecState*, MarkedArgumentBuffer&); void copyToArguments(ExecState*, CallFrame*, uint32_t length); @@ -94,18 +146,44 @@ namespace JSC { { ArrayStorage* storage = arrayStorageOrNull(); if (!storage) - return false; + return true; SparseArrayValueMap* map = storage->m_sparseMap.get(); return !map || !map->lengthIsReadOnly(); } + + bool shiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count); + bool shiftCountWithArrayStorage(unsigned startIndex, unsigned count, ArrayStorage*); - void setLengthWritable(ExecState*, bool writable); + bool unshiftCountWithAnyIndexingType(ExecState*, unsigned startIndex, unsigned count); + bool unshiftCountWithArrayStorage(ExecState*, unsigned startIndex, unsigned count, ArrayStorage*); + bool unshiftCountSlowCase(JSGlobalData&, bool, unsigned); + + template<IndexingType indexingType> + void sortNumericVector(ExecState*, JSValue compareFunction, CallType, const CallData&); + + template<IndexingType indexingType> + void sortCompactedVector(ExecState*, WriteBarrier<Unknown>* begin, unsigned relevantLength); + + template<IndexingType indexingType> + void sortVector(ExecState*, JSValue compareFunction, CallType, const CallData&); - bool unshiftCountSlowCase(JSGlobalData&, unsigned count); + bool setLengthWithArrayStorage(ExecState*, unsigned newLength, bool throwException, ArrayStorage*); + void setLengthWritable(ExecState*, bool writable); - unsigned compactForSorting(JSGlobalData&); + template<IndexingType indexingType> + void compactForSorting(unsigned& numDefined, unsigned& newRelevantLength); }; + inline Butterfly* createContiguousArrayButterfly(JSGlobalData& globalData, unsigned length) + { + IndexingHeader header; + header.setVectorLength(std::max(length, BASE_VECTOR_LEN)); + header.setPublicLength(length); + Butterfly* result = Butterfly::create( + globalData, 0, 0, true, header, header.vectorLength() * sizeof(EncodedJSValue)); + return result; + } + inline Butterfly* createArrayButterfly(JSGlobalData& globalData, unsigned initialLength) { Butterfly* butterfly = Butterfly::create( @@ -121,7 +199,16 @@ namespace JSC { inline JSArray* JSArray::create(JSGlobalData& globalData, Structure* structure, unsigned initialLength) { - Butterfly* butterfly = createArrayButterfly(globalData, initialLength); + Butterfly* butterfly; + if (LIKELY(structure->indexingType() == ArrayWithContiguous)) { + butterfly = createContiguousArrayButterfly(globalData, initialLength); + ASSERT(initialLength < MIN_SPARSE_ARRAY_INDEX); + } else { + ASSERT( + structure->indexingType() == ArrayWithSlowPutArrayStorage + || (initialLength && structure->indexingType() == ArrayWithArrayStorage)); + butterfly = createArrayButterfly(globalData, initialLength); + } JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly); array->finishCreation(globalData); return array; @@ -133,15 +220,26 @@ namespace JSC { if (vectorLength > MAX_STORAGE_VECTOR_LENGTH) return 0; - void* temp; - if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp)) - return 0; - Butterfly* butterfly = Butterfly::fromBase(temp, 0, 0); - *butterfly->indexingHeader() = indexingHeaderForArray(initialLength, vectorLength); - ArrayStorage* storage = butterfly->arrayStorage(); - storage->m_indexBias = 0; - storage->m_sparseMap.clear(); - storage->m_numValuesInVector = initialLength; + Butterfly* butterfly; + if (LIKELY(structure->indexingType() == ArrayWithContiguous)) { + + void* temp; + if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, vectorLength * sizeof(EncodedJSValue)), &temp)) + return 0; + butterfly = Butterfly::fromBase(temp, 0, 0); + butterfly->setVectorLength(vectorLength); + butterfly->setPublicLength(initialLength); + } else { + void* temp; + if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp)) + return 0; + butterfly = Butterfly::fromBase(temp, 0, 0); + *butterfly->indexingHeader() = indexingHeaderForArray(initialLength, vectorLength); + ArrayStorage* storage = butterfly->arrayStorage(); + storage->m_indexBias = 0; + storage->m_sparseMap.clear(); + storage->m_numValuesInVector = initialLength; + } JSArray* array = new (NotNull, allocateCell<JSArray>(globalData.heap)) JSArray(globalData, structure, butterfly); array->finishCreation(globalData); diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp index 3815c144e..d8f611477 100644 --- a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp +++ b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp @@ -31,7 +31,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSBoundFunction); ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSBoundFunction); const ClassInfo JSBoundFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSBoundFunction) }; diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp index 739247fb2..f6f4d716d 100644 --- a/Source/JavaScriptCore/runtime/JSCell.cpp +++ b/Source/JavaScriptCore/runtime/JSCell.cpp @@ -38,6 +38,10 @@ void JSCell::destroy(JSCell* cell) cell->JSCell::~JSCell(); } +void JSCell::copyBackingStore(JSCell*, CopyVisitor&) +{ +} + bool JSCell::getString(ExecState* exec, String& stringValue) const { if (!isString()) diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h index cf6f4ec45..a39af1283 100644 --- a/Source/JavaScriptCore/runtime/JSCell.h +++ b/Source/JavaScriptCore/runtime/JSCell.h @@ -31,12 +31,15 @@ #include "JSValueInlineMethods.h" #include "SlotVisitor.h" #include "SlotVisitorInlineMethods.h" +#include "TypedArrayDescriptor.h" #include "WriteBarrier.h" #include <wtf/Noncopyable.h> #include <wtf/TypeTraits.h> namespace JSC { + class CopyVisitor; + class JSDestructibleObject; class JSGlobalObject; class LLIntOffsetsExtractor; class PropertyDescriptor; @@ -48,19 +51,6 @@ namespace JSC { IncludeDontEnumProperties }; - enum TypedArrayType { - TypedArrayNone, - TypedArrayInt8, - TypedArrayInt16, - TypedArrayInt32, - TypedArrayUint8, - TypedArrayUint8Clamped, - TypedArrayUint16, - TypedArrayUint32, - TypedArrayFloat32, - TypedArrayFloat64 - }; - class JSCell { friend class JSValue; friend class MarkedBlock; @@ -70,6 +60,9 @@ namespace JSC { public: static const unsigned StructureFlags = 0; + static const bool needsDestruction = false; + static const bool hasImmortalStructure = false; + enum CreatingEarlyCellTag { CreatingEarlyCell }; JSCell(CreatingEarlyCellTag); @@ -108,6 +101,7 @@ namespace JSC { JS_EXPORT_PRIVATE JSObject* toObject(ExecState*, JSGlobalObject*) const; static void visitChildren(JSCell*, SlotVisitor&); + JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&); // Object operations, with the toObject operation included. const ClassInfo* classInfo() const; @@ -309,46 +303,29 @@ namespace JSC { return isCell() ? asCell()->toObject(exec, globalObject) : toObjectSlowCase(exec, globalObject); } - template<class T> - struct NeedsDestructor { - static const bool value = !WTF::HasTrivialDestructor<T>::value; - }; - template<typename T> - void* allocateCell(Heap& heap) + void* allocateCell(Heap& heap, size_t size) { + ASSERT(size >= sizeof(T)); #if ENABLE(GC_VALIDATION) ASSERT(!heap.globalData()->isInitializingObject()); heap.globalData()->setInitializingObjectClass(&T::s_info); #endif JSCell* result = 0; - if (NeedsDestructor<T>::value) - result = static_cast<JSCell*>(heap.allocateWithDestructor(sizeof(T))); - else { - ASSERT(T::s_info.methodTable.destroy == JSCell::destroy); - result = static_cast<JSCell*>(heap.allocateWithoutDestructor(sizeof(T))); - } + if (T::needsDestruction && T::hasImmortalStructure) + result = static_cast<JSCell*>(heap.allocateWithImmortalStructureDestructor(size)); + else if (T::needsDestruction && !T::hasImmortalStructure) + result = static_cast<JSCell*>(heap.allocateWithNormalDestructor(size)); + else + result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size)); result->clearStructure(); return result; } template<typename T> - void* allocateCell(Heap& heap, size_t size) + void* allocateCell(Heap& heap) { - ASSERT(size >= sizeof(T)); -#if ENABLE(GC_VALIDATION) - ASSERT(!heap.globalData()->isInitializingObject()); - heap.globalData()->setInitializingObjectClass(&T::s_info); -#endif - JSCell* result = 0; - if (NeedsDestructor<T>::value) - result = static_cast<JSCell*>(heap.allocateWithDestructor(size)); - else { - ASSERT(T::s_info.methodTable.destroy == JSCell::destroy); - result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size)); - } - result->clearStructure(); - return result; + return allocateCell<T>(heap, sizeof(T)); } inline bool isZapped(const JSCell* cell) @@ -362,7 +339,7 @@ namespace JSC { ASSERT(!from || from->JSCell::inherits(&WTF::RemovePointer<To>::Type::s_info)); return static_cast<To>(from); } - + template<typename To> inline To jsCast(JSValue from) { diff --git a/Source/JavaScriptCore/runtime/JSDestructibleObject.h b/Source/JavaScriptCore/runtime/JSDestructibleObject.h new file mode 100644 index 000000000..b8479be62 --- /dev/null +++ b/Source/JavaScriptCore/runtime/JSDestructibleObject.h @@ -0,0 +1,43 @@ +#ifndef JSDestructibleObject_h +#define JSDestructibleObject_h + +#include "JSObject.h" + +namespace JSC { + +struct ClassInfo; + +class JSDestructibleObject : public JSNonFinalObject { +public: + typedef JSNonFinalObject Base; + + static const bool needsDestruction = true; + + const ClassInfo* classInfo() const { return m_classInfo; } + +protected: + JSDestructibleObject(JSGlobalData& globalData, Structure* structure, Butterfly* butterfly = 0) + : JSNonFinalObject(globalData, structure, butterfly) + , m_classInfo(structure->classInfo()) + { + ASSERT(m_classInfo); + } + +private: + const ClassInfo* m_classInfo; +}; + +inline const ClassInfo* JSCell::classInfo() const +{ + if (MarkedBlock::blockFor(this)->destructorType() == MarkedBlock::Normal) + return static_cast<const JSDestructibleObject*>(this)->classInfo(); +#if ENABLE(GC_VALIDATION) + return m_structure.unvalidatedGet()->classInfo(); +#else + return m_structure->classInfo(); +#endif +} + +} // namespace JSC + +#endif diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp index 4afe63216..891a23930 100644 --- a/Source/JavaScriptCore/runtime/JSFunction.cpp +++ b/Source/JavaScriptCore/runtime/JSFunction.cpp @@ -48,7 +48,6 @@ EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState* exec) return throwVMError(exec, createNotAConstructorError(exec, exec->callee())); } -ASSERT_CLASS_FITS_IN_CELL(JSFunction); ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSFunction); const ClassInfo JSFunction::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSFunction) }; diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp index e30a7913d..bc3d00067 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp @@ -231,7 +231,9 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread interpreter->initialize(this->canUseJIT()); +#if ENABLE(JIT) initializeHostCallReturnValue(); // This is needed to convince the linker not to drop host call return support. +#endif heap.notifyIsSafeToCollect(); diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h index 603f9f82a..6cc0aad8d 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalData.h +++ b/Source/JavaScriptCore/runtime/JSGlobalData.h @@ -44,6 +44,7 @@ #include "Strong.h" #include "Terminator.h" #include "TimeoutChecker.h" +#include "TypedArrayDescriptor.h" #include "WeakRandom.h" #include <wtf/BumpPointerAllocator.h> #include <wtf/Forward.h> @@ -108,24 +109,6 @@ namespace JSC { ThreadStackTypeSmall }; - struct TypedArrayDescriptor { - TypedArrayDescriptor() - : m_classInfo(0) - , m_storageOffset(0) - , m_lengthOffset(0) - { - } - TypedArrayDescriptor(const ClassInfo* classInfo, size_t storageOffset, size_t lengthOffset) - : m_classInfo(classInfo) - , m_storageOffset(storageOffset) - , m_lengthOffset(lengthOffset) - { - } - const ClassInfo* m_classInfo; - size_t m_storageOffset; - size_t m_lengthOffset; - }; - #if ENABLE(DFG_JIT) class ConservativeRoots; @@ -429,6 +412,35 @@ namespace JSC { registerTypedArrayFunction(float32, Float32); registerTypedArrayFunction(float64, Float64); #undef registerTypedArrayFunction + + const TypedArrayDescriptor* typedArrayDescriptor(TypedArrayType type) const + { + switch (type) { + case TypedArrayNone: + return 0; + case TypedArrayInt8: + return &int8ArrayDescriptor(); + case TypedArrayInt16: + return &int16ArrayDescriptor(); + case TypedArrayInt32: + return &int32ArrayDescriptor(); + case TypedArrayUint8: + return &uint8ArrayDescriptor(); + case TypedArrayUint8Clamped: + return &uint8ClampedArrayDescriptor(); + case TypedArrayUint16: + return &uint16ArrayDescriptor(); + case TypedArrayUint32: + return &uint32ArrayDescriptor(); + case TypedArrayFloat32: + return &float32ArrayDescriptor(); + case TypedArrayFloat64: + return &float64ArrayDescriptor(); + default: + CRASH(); + return 0; + } + } JSLock& apiLock() { return m_apiLock; } diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp index b0a0e8122..9eb266135 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -100,8 +100,6 @@ const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = { &all @end */ -ASSERT_CLASS_FITS_IN_CELL(JSGlobalObject); - // Default number of ticks before a timeout check should be done. static const int initialTickCountThreshold = 255; @@ -228,10 +226,11 @@ void JSGlobalObject::reset(JSValue prototype) m_callbackFunctionStructure.set(exec->globalData(), this, JSCallbackFunction::createStructure(exec->globalData(), this, m_functionPrototype.get())); m_argumentsStructure.set(exec->globalData(), this, Arguments::createStructure(exec->globalData(), this, m_objectPrototype.get())); m_callbackConstructorStructure.set(exec->globalData(), this, JSCallbackConstructor::createStructure(exec->globalData(), this, m_objectPrototype.get())); - m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSNonFinalObject>::createStructure(exec->globalData(), this, m_objectPrototype.get())); + m_callbackObjectStructure.set(exec->globalData(), this, JSCallbackObject<JSDestructibleObject>::createStructure(exec->globalData(), this, m_objectPrototype.get())); m_arrayPrototype.set(exec->globalData(), this, ArrayPrototype::create(exec, this, ArrayPrototype::createStructure(exec->globalData(), this, m_objectPrototype.get()))); - m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage)); + m_arrayStructure.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithContiguous)); + m_arrayStructureWithArrayStorage.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithArrayStorage)); m_arrayStructureForSlowPut.set(exec->globalData(), this, JSArray::createStructure(exec->globalData(), this, m_arrayPrototype.get(), ArrayWithSlowPutArrayStorage)); m_regExpMatchesArrayStructure.set(exec->globalData(), this, RegExpMatchesArray::createStructure(exec->globalData(), this, m_arrayPrototype.get())); @@ -318,6 +317,9 @@ void JSGlobalObject::reset(JSValue prototype) GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly) }; addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals)); + + m_specialPointers[Special::CallFunction] = m_callFunction.get(); + m_specialPointers[Special::ApplyFunction] = m_applyFunction.get(); if (m_experimentsEnabled) { NamePrototype* privateNamePrototype = NamePrototype::create(exec, NamePrototype::createStructure(exec->globalData(), this, m_objectPrototype.get())); @@ -354,7 +356,8 @@ ObjectsWithBrokenIndexingFinder::ObjectsWithBrokenIndexingFinder( inline bool hasBrokenIndexing(JSObject* object) { // This will change if we have more indexing types. - return !!(object->structure()->indexingType() & HasArrayStorage); + IndexingType type = object->structure()->indexingType(); + return hasContiguous(type) || hasFastArrayStorage(type); } void ObjectsWithBrokenIndexingFinder::operator()(JSCell* cell) @@ -407,6 +410,7 @@ void JSGlobalObject::haveABadTime(JSGlobalData& globalData) // Make sure that all JSArray allocations that load the appropriate structure from // this object now load a structure that uses SlowPut. m_arrayStructure.set(globalData, this, m_arrayStructureForSlowPut.get()); + m_arrayStructureWithArrayStorage.set(globalData, this, m_arrayStructureForSlowPut.get()); // Make sure that all objects that have indexed storage switch to the slow kind of // indexed storage. @@ -482,6 +486,7 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) visitor.append(&thisObject->m_nameScopeStructure); visitor.append(&thisObject->m_argumentsStructure); visitor.append(&thisObject->m_arrayStructure); + visitor.append(&thisObject->m_arrayStructureWithArrayStorage); visitor.append(&thisObject->m_arrayStructureForSlowPut); visitor.append(&thisObject->m_booleanObjectStructure); visitor.append(&thisObject->m_callbackConstructorStructure); @@ -502,9 +507,14 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) visitor.append(&thisObject->m_internalFunctionStructure); } +JSObject* JSGlobalObject::toThisObject(JSCell* cell, ExecState*) +{ + return jsCast<JSGlobalObject*>(cell)->globalThis(); +} + ExecState* JSGlobalObject::globalExec() { - return CallFrame::create(m_globalCallFrame + RegisterFile::CallFrameHeaderSize); + return CallFrame::create(m_globalCallFrame + JSStack::CallFrameHeaderSize); } void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count) diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h index ad56783cc..2994aa64b 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.h +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h @@ -24,10 +24,10 @@ #include "JSArray.h" #include "JSGlobalData.h" -#include "JSGlobalThis.h" #include "JSSegmentedVariableObject.h" #include "JSWeakObjectMapRefInternal.h" #include "NumberPrototype.h" +#include "SpecialPointer.h" #include "StringPrototype.h" #include "StructureChain.h" #include "Watchpoint.h" @@ -46,12 +46,12 @@ namespace JSC { class FunctionPrototype; class GetterSetter; class GlobalCodeBlock; + class JSStack; class LLIntOffsetsExtractor; class NativeErrorConstructor; class ProgramCodeBlock; class RegExpConstructor; class RegExpPrototype; - class RegisterFile; struct ActivationStackNode; struct HashTable; @@ -77,7 +77,6 @@ namespace JSC { class JSGlobalObject : public JSSegmentedVariableObject { private: - typedef JSSegmentedVariableObject Base; typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet; struct JSGlobalObjectRareData { @@ -92,7 +91,7 @@ namespace JSC { protected: - Register m_globalCallFrame[RegisterFile::CallFrameHeaderSize]; + Register m_globalCallFrame[JSStack::CallFrameHeaderSize]; WriteBarrier<JSObject> m_globalThis; WriteBarrier<JSObject> m_methodCallDummy; @@ -127,6 +126,7 @@ namespace JSC { WriteBarrier<Structure> m_nameScopeStructure; WriteBarrier<Structure> m_argumentsStructure; WriteBarrier<Structure> m_arrayStructure; // This gets set to m_arrayStructureForSlowPut as soon as we decide to have a bad time. + WriteBarrier<Structure> m_arrayStructureWithArrayStorage; // This gets set to m_arrayStructureForSlowPut as soon as we decide to have a bad time. WriteBarrier<Structure> m_arrayStructureForSlowPut; WriteBarrier<Structure> m_booleanObjectStructure; WriteBarrier<Structure> m_callbackConstructorStructure; @@ -146,6 +146,8 @@ namespace JSC { WriteBarrier<Structure> m_regExpStructure; WriteBarrier<Structure> m_stringObjectStructure; WriteBarrier<Structure> m_internalFunctionStructure; + + void* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT. Debugger* m_debugger; @@ -168,14 +170,16 @@ namespace JSC { if (m_rareData) return; m_rareData = adoptPtr(new JSGlobalObjectRareData); - Heap::heap(this)->addFinalizer(this, clearRareData); } public: + typedef JSSegmentedVariableObject Base; + static JSGlobalObject* create(JSGlobalData& globalData, Structure* structure) { JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(globalData.heap)) JSGlobalObject(globalData, structure); globalObject->finishCreation(globalData); + globalData.heap.addFinalizer(globalObject, destroy); return globalObject; } @@ -192,7 +196,7 @@ namespace JSC { init(this); } - void finishCreation(JSGlobalData& globalData, JSGlobalThis* thisValue) + void finishCreation(JSGlobalData& globalData, JSObject* thisValue) { Base::finishCreation(globalData); structure()->setGlobalObject(globalData, this); @@ -203,6 +207,8 @@ namespace JSC { public: JS_EXPORT_PRIVATE ~JSGlobalObject(); JS_EXPORT_PRIVATE static void destroy(JSCell*); + // We don't need a destructor because we use a finalizer instead. + static const bool needsDestruction = false; JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); @@ -262,7 +268,9 @@ namespace JSC { Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); } Structure* argumentsStructure() const { return m_argumentsStructure.get(); } Structure* arrayStructure() const { return m_arrayStructure.get(); } + Structure* arrayStructureWithArrayStorage() const { return m_arrayStructureWithArrayStorage.get(); } void* addressOfArrayStructure() { return &m_arrayStructure; } + void* addressOfArrayStructureWithArrayStorage() { return &m_arrayStructureWithArrayStorage; } Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); } Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); } Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); } @@ -282,6 +290,12 @@ namespace JSC { Structure* regExpStructure() const { return m_regExpStructure.get(); } Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); } + void* actualPointerFor(Special::Pointer pointer) + { + ASSERT(pointer < Special::TableSize); + return m_specialPointers[pointer]; + } + WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); } WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); } @@ -366,13 +380,16 @@ namespace JSC { }; JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count); + JS_EXPORT_PRIVATE static JSC::JSObject* toThisObject(JSC::JSCell*, JSC::ExecState*); + + JS_EXPORT_PRIVATE void setGlobalThis(JSGlobalData&, JSObject* globalThis); + private: friend class LLIntOffsetsExtractor; // FIXME: Fold reset into init. JS_EXPORT_PRIVATE void init(JSObject* thisValue); void reset(JSValue prototype); - void setGlobalThis(JSGlobalData&, JSObject* globalThis); void createThrowTypeError(ExecState*); @@ -465,7 +482,7 @@ namespace JSC { inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject, unsigned initialLength = 0) { - return JSArray::create(exec->globalData(), globalObject->arrayStructure(), initialLength); + return JSArray::create(exec->globalData(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureWithArrayStorage() : globalObject->arrayStructure(), initialLength); } inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength = 0) diff --git a/Source/JavaScriptCore/runtime/JSGlobalThis.h b/Source/JavaScriptCore/runtime/JSGlobalThis.h deleted file mode 100644 index 0ca99414a..000000000 --- a/Source/JavaScriptCore/runtime/JSGlobalThis.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 JSGlobalThis_h -#define JSGlobalThis_h - -#include "JSObject.h" - -namespace JSC { - -class JSGlobalThis : public JSNonFinalObject { -public: - typedef JSNonFinalObject Base; - - static JSGlobalThis* create(JSGlobalData& globalData, Structure* structure) - { - JSGlobalThis* globalThis = new (NotNull, allocateCell<JSGlobalThis>(globalData.heap)) JSGlobalThis(globalData, structure); - globalThis->finishCreation(globalData); - return globalThis; - } - - static Structure* createStructure(JSGlobalData& globalData, JSValue prototype) - { - return Structure::create(globalData, 0, prototype, TypeInfo(GlobalThisType, StructureFlags), &s_info); - } - - static JS_EXPORTDATA const JSC::ClassInfo s_info; - - JSGlobalObject* unwrappedObject() const { return m_unwrappedObject.get(); } - -protected: - JSGlobalThis(JSGlobalData& globalData, Structure* structure) - : JSNonFinalObject(globalData, structure) - { - } - - void finishCreation(JSGlobalData& globalData) - { - Base::finishCreation(globalData); - } - - static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; - - JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); - - JS_EXPORT_PRIVATE void setUnwrappedObject(JSGlobalData&, JSGlobalObject*); - -private: - WriteBarrier<JSGlobalObject> m_unwrappedObject; -}; - -} // namespace JSC - -#endif // JSGlobalThis_h diff --git a/Source/JavaScriptCore/runtime/JSLock.cpp b/Source/JavaScriptCore/runtime/JSLock.cpp index 9f02b69b8..85dbdfedb 100644 --- a/Source/JavaScriptCore/runtime/JSLock.cpp +++ b/Source/JavaScriptCore/runtime/JSLock.cpp @@ -140,13 +140,13 @@ bool JSLock::currentThreadIsHoldingLock() // context if the thread leaves JSC by making a call out to an external // function through a callback. // -// All threads using the context share the same JS stack (the RegisterFile). -// Whenever a thread calls into JSC it starts using the RegisterFile from the +// All threads using the context share the same JS stack (the JSStack). +// Whenever a thread calls into JSC it starts using the JSStack from the // previous 'high water mark' - the maximum point the stack has ever grown to -// (returned by RegisterFile::end()). So if a first thread calls out to a +// (returned by JSStack::end()). So if a first thread calls out to a // callback, and a second thread enters JSC, then also exits by calling out // to a callback, we can be left with stackframes from both threads in the -// RegisterFile. As such, a problem may occur should the first thread's +// JSStack. As such, a problem may occur should the first thread's // callback complete first, and attempt to return to JSC. Were we to allow // this to happen, and were its stack to grow further, then it may potentially // write over the second thread's call frames. diff --git a/Source/JavaScriptCore/runtime/JSNameScope.cpp b/Source/JavaScriptCore/runtime/JSNameScope.cpp index 5dc665c44..335631fd0 100644 --- a/Source/JavaScriptCore/runtime/JSNameScope.cpp +++ b/Source/JavaScriptCore/runtime/JSNameScope.cpp @@ -30,8 +30,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSNameScope); - const ClassInfo JSNameScope::s_info = { "NameScope", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNameScope) }; void JSNameScope::visitChildren(JSCell* cell, SlotVisitor& visitor) diff --git a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp index f75fa1f96..53592ba2b 100644 --- a/Source/JavaScriptCore/runtime/JSNotAnObject.cpp +++ b/Source/JavaScriptCore/runtime/JSNotAnObject.cpp @@ -34,7 +34,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSNotAnObject); ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSNotAnObject); const ClassInfo JSNotAnObject::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNotAnObject) }; diff --git a/Source/JavaScriptCore/runtime/JSONObject.cpp b/Source/JavaScriptCore/runtime/JSONObject.cpp index fe894afba..fd939934e 100644 --- a/Source/JavaScriptCore/runtime/JSONObject.cpp +++ b/Source/JavaScriptCore/runtime/JSONObject.cpp @@ -41,7 +41,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSONObject); ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSONObject); static EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState*); diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp index bf38f6876..6a3fb84e4 100644 --- a/Source/JavaScriptCore/runtime/JSObject.cpp +++ b/Source/JavaScriptCore/runtime/JSObject.cpp @@ -26,13 +26,14 @@ #include "ButterflyInlineMethods.h" #include "CopiedSpaceInlineMethods.h" +#include "CopyVisitor.h" +#include "CopyVisitorInlineMethods.h" #include "DatePrototype.h" #include "ErrorConstructor.h" #include "GetterSetter.h" #include "IndexingHeaderInlineMethods.h" #include "JSFunction.h" #include "JSGlobalObject.h" -#include "JSGlobalThis.h" #include "Lookup.h" #include "NativeErrorConstructor.h" #include "Nodes.h" @@ -63,10 +64,6 @@ JSCell* getCallableObjectSlow(JSCell* cell) return 0; } -ASSERT_CLASS_FITS_IN_CELL(JSObject); -ASSERT_CLASS_FITS_IN_CELL(JSNonFinalObject); -ASSERT_CLASS_FITS_IN_CELL(JSFinalObject); - ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSObject); ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSFinalObject); @@ -95,7 +92,7 @@ static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* class } } -ALWAYS_INLINE void JSObject::visitButterfly(SlotVisitor& visitor, Butterfly* butterfly, size_t storageSize) +ALWAYS_INLINE void JSObject::copyButterfly(CopyVisitor& visitor, Butterfly* butterfly, size_t storageSize) { ASSERT(butterfly); @@ -112,61 +109,93 @@ ALWAYS_INLINE void JSObject::visitButterfly(SlotVisitor& visitor, Butterfly* but preCapacity = 0; indexingPayloadSizeInBytes = 0; } - size_t capacityInBytes = Butterfly::totalSize( - preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); - if (visitor.checkIfShouldCopyAndPinOtherwise( - butterfly->base(preCapacity, propertyCapacity), capacityInBytes)) { + size_t capacityInBytes = Butterfly::totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); + if (visitor.checkIfShouldCopy(butterfly->base(preCapacity, propertyCapacity), capacityInBytes)) { Butterfly* newButterfly = Butterfly::createUninitializedDuringCollection(visitor, preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); - // Mark and copy the properties. + // Copy the properties. PropertyStorage currentTarget = newButterfly->propertyStorage(); PropertyStorage currentSource = butterfly->propertyStorage(); - for (size_t count = storageSize; count--;) { - JSValue value = (--currentSource)->get(); - ASSERT(value); - visitor.appendUnbarrieredValue(&value); - (--currentTarget)->setWithoutWriteBarrier(value); - } + for (size_t count = storageSize; count--;) + (--currentTarget)->setWithoutWriteBarrier((--currentSource)->get()); if (UNLIKELY(hasIndexingHeader)) { *newButterfly->indexingHeader() = *butterfly->indexingHeader(); - // Mark and copy the array if appropriate. + // Copy the array if appropriate. + + WriteBarrier<Unknown>* currentTarget; + WriteBarrier<Unknown>* currentSource; + size_t count; + switch (structure->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: { + currentTarget = newButterfly->contiguous(); + currentSource = butterfly->contiguous(); + ASSERT(newButterfly->publicLength() <= newButterfly->vectorLength()); + count = newButterfly->vectorLength(); + break; + } + case ALL_ARRAY_STORAGE_INDEXING_TYPES: { newButterfly->arrayStorage()->copyHeaderFromDuringGC(*butterfly->arrayStorage()); - WriteBarrier<Unknown>* currentTarget = newButterfly->arrayStorage()->m_vector; - WriteBarrier<Unknown>* currentSource = butterfly->arrayStorage()->m_vector; - for (size_t count = newButterfly->arrayStorage()->vectorLength(); count--;) { - JSValue value = (currentSource++)->get(); - if (value) - visitor.appendUnbarrieredValue(&value); - (currentTarget++)->setWithoutWriteBarrier(value); - } - if (newButterfly->arrayStorage()->m_sparseMap) - visitor.append(&newButterfly->arrayStorage()->m_sparseMap); + currentTarget = newButterfly->arrayStorage()->m_vector; + currentSource = butterfly->arrayStorage()->m_vector; + count = newButterfly->arrayStorage()->vectorLength(); break; } default: + CRASH(); + currentTarget = 0; + currentSource = 0; + count = 0; break; } + + while (count--) + (currentTarget++)->setWithoutWriteBarrier((currentSource++)->get()); } m_butterfly = newButterfly; + visitor.didCopy(butterfly->base(preCapacity, propertyCapacity), capacityInBytes); + } +} + +ALWAYS_INLINE void JSObject::visitButterfly(SlotVisitor& visitor, Butterfly* butterfly, size_t storageSize) +{ + ASSERT(butterfly); + + Structure* structure = this->structure(); + + size_t propertyCapacity = structure->outOfLineCapacity(); + size_t preCapacity; + size_t indexingPayloadSizeInBytes; + bool hasIndexingHeader = JSC::hasIndexingHeader(structure->indexingType()); + if (UNLIKELY(hasIndexingHeader)) { + preCapacity = butterfly->indexingHeader()->preCapacity(structure); + indexingPayloadSizeInBytes = butterfly->indexingHeader()->indexingPayloadSizeInBytes(structure); } else { - // Mark the properties. - visitor.appendValues(butterfly->propertyStorage() - storageSize, storageSize); - - // Mark the array if appropriate. - switch (structure->indexingType()) { - case ALL_ARRAY_STORAGE_INDEXING_TYPES: - visitor.appendValues(butterfly->arrayStorage()->m_vector, butterfly->arrayStorage()->vectorLength()); - if (butterfly->arrayStorage()->m_sparseMap) - visitor.append(&butterfly->arrayStorage()->m_sparseMap); - break; - default: - break; - } + preCapacity = 0; + indexingPayloadSizeInBytes = 0; + } + size_t capacityInBytes = Butterfly::totalSize(preCapacity, propertyCapacity, hasIndexingHeader, indexingPayloadSizeInBytes); + + // Mark the properties. + visitor.appendValues(butterfly->propertyStorage() - storageSize, storageSize); + visitor.copyLater(butterfly->base(preCapacity, propertyCapacity), capacityInBytes); + + // Mark the array if appropriate. + switch (structure->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + visitor.appendValues(butterfly->contiguous(), butterfly->publicLength()); + break; + case ALL_ARRAY_STORAGE_INDEXING_TYPES: + visitor.appendValues(butterfly->arrayStorage()->m_vector, butterfly->arrayStorage()->vectorLength()); + if (butterfly->arrayStorage()->m_sparseMap) + visitor.append(&butterfly->arrayStorage()->m_sparseMap); + break; + default: + break; } } @@ -183,13 +212,23 @@ void JSObject::visitChildren(JSCell* cell, SlotVisitor& visitor) Butterfly* butterfly = thisObject->butterfly(); if (butterfly) - thisObject->visitButterfly(visitor, butterfly, thisObject->structure()->outOfLineSizeForKnownNonFinalObject()); + thisObject->visitButterfly(visitor, butterfly, thisObject->structure()->outOfLineSize()); #if !ASSERT_DISABLED visitor.m_isCheckingForDefaultMarkViolation = wasCheckingForDefaultMarkViolation; #endif } +void JSObject::copyBackingStore(JSCell* cell, CopyVisitor& visitor) +{ + JSObject* thisObject = jsCast<JSObject*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + + Butterfly* butterfly = thisObject->butterfly(); + if (butterfly) + thisObject->copyButterfly(visitor, butterfly, thisObject->structure()->outOfLineSize()); +} + void JSFinalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) { JSFinalObject* thisObject = jsCast<JSFinalObject*>(cell); @@ -203,9 +242,9 @@ void JSFinalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) Butterfly* butterfly = thisObject->butterfly(); if (butterfly) - thisObject->visitButterfly(visitor, butterfly, thisObject->structure()->outOfLineSizeForKnownFinalObject()); + thisObject->visitButterfly(visitor, butterfly, thisObject->structure()->outOfLineSize()); - size_t storageSize = thisObject->structure()->inlineSizeForKnownFinalObject(); + size_t storageSize = thisObject->structure()->inlineSize(); visitor.appendValues(thisObject->inlineStorage(), storageSize); #if !ASSERT_DISABLED @@ -235,6 +274,20 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned case ALL_BLANK_INDEXING_TYPES: break; + case ALL_CONTIGUOUS_INDEXING_TYPES: { + Butterfly* butterfly = thisObject->m_butterfly; + if (i >= butterfly->vectorLength()) + return false; + + JSValue value = butterfly->contiguous()[i].get(); + if (value) { + slot.setValue(value); + return true; + } + + return false; + } + case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = thisObject->m_butterfly->arrayStorage(); if (i >= storage->length()) @@ -249,7 +302,7 @@ bool JSObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned } else if (SparseArrayValueMap* map = storage->m_sparseMap.get()) { SparseArrayValueMap::iterator it = map->find(i); if (it != map->notFound()) { - it->second.get(slot); + it->value.get(slot); return true; } } @@ -352,6 +405,16 @@ void JSObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, case ALL_BLANK_INDEXING_TYPES: break; + case ALL_CONTIGUOUS_INDEXING_TYPES: { + Butterfly* butterfly = thisObject->m_butterfly; + if (propertyName >= butterfly->vectorLength()) + break; + butterfly->contiguous()[propertyName].set(exec->globalData(), thisObject, value); + if (propertyName >= butterfly->publicLength()) + butterfly->setPublicLength(propertyName + 1); + return; + } + case NonArrayWithArrayStorage: case ArrayWithArrayStorage: { ArrayStorage* storage = thisObject->m_butterfly->arrayStorage(); @@ -426,7 +489,7 @@ ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists // This will always be a new entry in the map, so no need to check we can write, // and attributes are default so no need to set them. if (value) - map->add(this, i).iterator->second.set(globalData, this, value); + map->add(this, i).iterator->value.set(globalData, this, value); } Butterfly* newButterfly = storage->butterfly()->resizeArray(globalData, structure(), 0, ArrayStorage::sizeFor(0)); @@ -444,6 +507,11 @@ ArrayStorage* JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists void JSObject::enterDictionaryIndexingMode(JSGlobalData& globalData) { switch (structure()->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + // NOTE: this is horribly inefficient, as it will perform two conversions. We could optimize + // this case if we ever cared. + enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData)); + break; case ALL_ARRAY_STORAGE_INDEXING_TYPES: enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage()); break; @@ -466,6 +534,24 @@ void JSObject::notifyPresenceOfIndexedAccessors(JSGlobalData& globalData) globalObject()->haveABadTime(globalData); } +WriteBarrier<Unknown>* JSObject::createInitialContiguous(JSGlobalData& globalData, unsigned length) +{ + ASSERT(length < MAX_ARRAY_INDEX); + IndexingType oldType = structure()->indexingType(); + ASSERT_UNUSED(oldType, !hasIndexedProperties(oldType)); + ASSERT(!structure()->needsSlowPutIndexing()); + ASSERT(!indexingShouldBeSparse()); + unsigned vectorLength = std::max(length, BASE_VECTOR_LEN); + Butterfly* newButterfly = m_butterfly->growArrayRight( + globalData, structure(), structure()->outOfLineCapacity(), false, 0, + sizeof(EncodedJSValue) * vectorLength); + newButterfly->setPublicLength(length); + newButterfly->setVectorLength(vectorLength); + Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), AllocateContiguous); + setButterfly(globalData, newButterfly, newStructure); + return newButterfly->contiguous(); +} + ArrayStorage* JSObject::createArrayStorage(JSGlobalData& globalData, unsigned length, unsigned vectorLength) { IndexingType oldType = structure()->indexingType(); @@ -481,7 +567,7 @@ ArrayStorage* JSObject::createArrayStorage(JSGlobalData& globalData, unsigned le result->m_sparseMap.clear(); result->m_numValuesInVector = 0; result->m_indexBias = 0; - Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), structure()->suggestedIndexingTransition()); + Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), structure()->suggestedArrayStorageTransition()); setButterfly(globalData, newButterfly, newStructure); return result; } @@ -491,9 +577,107 @@ ArrayStorage* JSObject::createInitialArrayStorage(JSGlobalData& globalData) return createArrayStorage(globalData, 0, BASE_VECTOR_LEN); } +ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition, unsigned neededLength) +{ + ASSERT(hasContiguous(structure()->indexingType())); + + unsigned publicLength = m_butterfly->publicLength(); + unsigned propertyCapacity = structure()->outOfLineCapacity(); + unsigned propertySize = structure()->outOfLineSize(); + + Butterfly* newButterfly = Butterfly::createUninitialized( + globalData, 0, propertyCapacity, true, ArrayStorage::sizeFor(neededLength)); + + memcpy( + newButterfly->propertyStorage() - propertySize, + m_butterfly->propertyStorage() - propertySize, + propertySize * sizeof(EncodedJSValue)); + + ArrayStorage* newStorage = newButterfly->arrayStorage(); + newStorage->setVectorLength(neededLength); + newStorage->setLength(publicLength); + newStorage->m_sparseMap.clear(); + newStorage->m_indexBias = 0; + newStorage->m_numValuesInVector = 0; + for (unsigned i = publicLength; i--;) { + JSValue v = m_butterfly->contiguous()[i].get(); + if (!v) + continue; + newStorage->m_vector[i].setWithoutWriteBarrier(v); + newStorage->m_numValuesInVector++; + } + + Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), transition); + setButterfly(globalData, newButterfly, newStructure); + return newStorage; +} + +ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData, NonPropertyTransition transition) +{ + return convertContiguousToArrayStorage(globalData, transition, m_butterfly->vectorLength()); +} + +ArrayStorage* JSObject::convertContiguousToArrayStorage(JSGlobalData& globalData) +{ + return convertContiguousToArrayStorage(globalData, structure()->suggestedArrayStorageTransition()); +} + +WriteBarrier<Unknown>* JSObject::ensureContiguousSlow(JSGlobalData& globalData) +{ + switch (structure()->indexingType()) { + case ALL_BLANK_INDEXING_TYPES: + if (UNLIKELY(indexingShouldBeSparse() || structure()->needsSlowPutIndexing())) + return 0; + return createInitialContiguous(globalData, 0); + + default: + ASSERT_NOT_REACHED(); + return 0; + } +} + +ArrayStorage* JSObject::ensureArrayStorageSlow(JSGlobalData& globalData) +{ + switch (structure()->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + ASSERT(!indexingShouldBeSparse()); + ASSERT(!structure()->needsSlowPutIndexing()); + return convertContiguousToArrayStorage(globalData); + + case ALL_BLANK_INDEXING_TYPES: + if (UNLIKELY(indexingShouldBeSparse())) + return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData); + return createInitialArrayStorage(globalData); + + default: + ASSERT_NOT_REACHED(); + return 0; + } +} + +Butterfly* JSObject::ensureIndexedStorageSlow(JSGlobalData& globalData) +{ + switch (structure()->indexingType()) { + case ALL_BLANK_INDEXING_TYPES: + if (UNLIKELY(structure()->needsSlowPutIndexing())) + return createInitialArrayStorage(globalData)->butterfly(); + if (UNLIKELY(indexingShouldBeSparse())) + return ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData)->butterfly(); + return Butterfly::fromContiguous(createInitialContiguous(globalData, 0)); + + default: + ASSERT_NOT_REACHED(); + return 0; + } +} + ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData& globalData) { switch (structure()->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + // FIXME: This could be made way more efficient, if we cared. + return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, convertContiguousToArrayStorage(globalData)); + case ALL_ARRAY_STORAGE_INDEXING_TYPES: return enterDictionaryIndexingModeWhenArrayStorageAlreadyExists(globalData, m_butterfly->arrayStorage()); @@ -513,6 +697,11 @@ ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(J void JSObject::switchToSlowPutArrayStorage(JSGlobalData& globalData) { switch (structure()->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: { + convertContiguousToArrayStorage(globalData, AllocateSlowPutArrayStorage); + break; + } + case NonArrayWithArrayStorage: case ArrayWithArrayStorage: { Structure* newStructure = Structure::nonPropertyTransition(globalData, structure(), SwitchToSlowPutArrayStorage); @@ -556,8 +745,7 @@ void JSObject::setPrototype(JSGlobalData& globalData, JSValue prototype) if (shouldUseSlowPut(structure()->indexingType())) return; - newStructure = Structure::nonPropertyTransition(globalData, newStructure, SwitchToSlowPutArrayStorage); - setStructure(globalData, newStructure); + switchToSlowPutArrayStorage(globalData); } bool JSObject::setPrototypeWithCycleCheck(JSGlobalData& globalData, JSValue prototype) @@ -691,6 +879,14 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) case ALL_BLANK_INDEXING_TYPES: return true; + case ALL_CONTIGUOUS_INDEXING_TYPES: { + Butterfly* butterfly = thisObject->m_butterfly; + if (i >= butterfly->vectorLength()) + return true; + butterfly->contiguous()[i].clear(); + return true; + } + case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = thisObject->m_butterfly->arrayStorage(); @@ -703,7 +899,7 @@ bool JSObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) } else if (SparseArrayValueMap* map = storage->m_sparseMap.get()) { SparseArrayValueMap::iterator it = map->find(i); if (it != map->notFound()) { - if (it->second.attributes & DontDelete) + if (it->value.attributes & DontDelete) return false; map->remove(it); } @@ -864,6 +1060,17 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa case ALL_BLANK_INDEXING_TYPES: break; + case ALL_CONTIGUOUS_INDEXING_TYPES: { + Butterfly* butterfly = object->m_butterfly; + unsigned usedLength = butterfly->publicLength(); + for (unsigned i = 0; i < usedLength; ++i) { + if (!butterfly->contiguous()[i]) + continue; + propertyNames.add(Identifier::from(exec, i)); + } + break; + } + case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = object->m_butterfly->arrayStorage(); @@ -879,8 +1086,8 @@ void JSObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNa SparseArrayValueMap::const_iterator end = map->end(); for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) { - if (mode == IncludeDontEnumProperties || !(it->second.attributes & DontEnum)) - keys.append(static_cast<unsigned>(it->first)); + if (mode == IncludeDontEnumProperties || !(it->value.attributes & DontEnum)) + keys.append(static_cast<unsigned>(it->key)); } std::sort(keys.begin(), keys.end()); @@ -1089,9 +1296,6 @@ bool JSObject::defineOwnIndexedProperty(ExecState* exec, unsigned index, Propert { ASSERT(index <= MAX_ARRAY_INDEX); - if (descriptor.attributes() & (ReadOnly | Accessor)) - notifyPresenceOfIndexedAccessors(exec->globalData()); - if (!inSparseIndexingMode()) { // Fast case: we're putting a regular property to a regular array // FIXME: this will pessimistically assume that if attributes are missing then they'll default to false @@ -1101,16 +1305,19 @@ bool JSObject::defineOwnIndexedProperty(ExecState* exec, unsigned index, Propert ASSERT(!descriptor.isAccessorDescriptor()); return putDirectIndex(exec, index, descriptor.value(), 0, throwException ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow); } - + ensureArrayStorageExistsAndEnterDictionaryIndexingMode(exec->globalData()); } + if (descriptor.attributes() & (ReadOnly | Accessor)) + notifyPresenceOfIndexedAccessors(exec->globalData()); + SparseArrayValueMap* map = m_butterfly->arrayStorage()->m_sparseMap.get(); ASSERT(map); // 1. Let current be the result of calling the [[GetOwnProperty]] internal method of O with property name P. SparseArrayValueMap::AddResult result = map->add(this, index); - SparseArrayEntry* entryInMap = &result.iterator->second; + SparseArrayEntry* entryInMap = &result.iterator->value; // 2. Let extensible be the value of the [[Extensible]] internal property of O. // 3. If current is undefined and extensible is false, then Reject. @@ -1230,8 +1437,8 @@ bool JSObject::attemptToInterceptPutByIndexOnHoleForPrototype(ExecState* exec, J ArrayStorage* storage = current->arrayStorageOrNull(); if (storage && storage->m_sparseMap) { SparseArrayValueMap::iterator iter = storage->m_sparseMap->find(i); - if (iter != storage->m_sparseMap->notFound() && (iter->second.attributes & (Accessor | ReadOnly))) { - iter->second.put(exec, thisValue, storage->m_sparseMap.get(), value, shouldThrow); + if (iter != storage->m_sparseMap->notFound() && (iter->value.attributes & (Accessor | ReadOnly))) { + iter->value.put(exec, thisValue, storage->m_sparseMap.get(), value, shouldThrow); return true; } } @@ -1253,6 +1460,35 @@ bool JSObject::attemptToInterceptPutByIndexOnHole(ExecState* exec, unsigned i, J return asObject(prototypeValue)->attemptToInterceptPutByIndexOnHoleForPrototype(exec, this, i, value, shouldThrow); } +void JSObject::putByIndexBeyondVectorLengthContiguousWithoutAttributes(ExecState* exec, unsigned i, JSValue value) +{ + ASSERT(hasContiguous(structure()->indexingType())); + ASSERT(!indexingShouldBeSparse()); + + // For us to get here, the index is either greater than the public length, or greater than + // or equal to the vector length. + ASSERT(i >= m_butterfly->vectorLength()); + + JSGlobalData& globalData = exec->globalData(); + + if (i >= MAX_ARRAY_INDEX - 1 + || (i >= MIN_SPARSE_ARRAY_INDEX + && !isDenseEnoughForVector(i, countElementsInContiguous(m_butterfly)))) { + ASSERT(i <= MAX_ARRAY_INDEX); + convertContiguousToArrayStorage(globalData, AllocateArrayStorage); + SparseArrayValueMap* map = allocateSparseIndexMap(globalData); + map->putEntry(exec, this, i, value, false); + ASSERT(i >= arrayStorage()->length()); + arrayStorage()->setLength(i + 1); + return; + } + + ensureContiguousLength(globalData, i + 1); + + ASSERT(i < m_butterfly->vectorLength()); + m_butterfly->contiguous()[i].set(globalData, this, value); +} + void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, unsigned i, JSValue value, bool shouldThrow, ArrayStorage* storage) { JSGlobalData& globalData = exec->globalData(); @@ -1315,7 +1551,7 @@ void JSObject::putByIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, uns WriteBarrier<Unknown>* vector = storage->m_vector; SparseArrayValueMap::const_iterator end = map->end(); for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) - vector[it->first].set(globalData, this, it->second.getNonSparseMode()); + vector[it->key].set(globalData, this, it->value.getNonSparseMode()); deallocateSparseIndexMap(); // Store the new property into the vector. @@ -1335,17 +1571,29 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: { if (indexingShouldBeSparse()) { - putByIndexBeyondVectorLengthWithArrayStorage(exec, i, value, shouldThrow, ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData)); + putByIndexBeyondVectorLengthWithArrayStorage( + exec, i, value, shouldThrow, + ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData)); + break; + } + if (i >= MIN_SPARSE_ARRAY_INDEX) { + putByIndexBeyondVectorLengthWithArrayStorage( + exec, i, value, shouldThrow, createArrayStorage(globalData, 0, 0)); break; } - if (!isDenseEnoughForVector(i, 0) || i >= MAX_STORAGE_VECTOR_LENGTH) { - putByIndexBeyondVectorLengthWithArrayStorage(exec, i, value, shouldThrow, createArrayStorage(globalData, 0, 0)); + if (structure()->needsSlowPutIndexing()) { + ArrayStorage* storage = createArrayStorage(globalData, i + 1, getNewVectorLength(0, 0, i + 1)); + storage->m_vector[i].set(globalData, this, value); + storage->m_numValuesInVector++; break; } + + createInitialContiguous(globalData, i + 1)[i].set(globalData, this, value); + break; + } - ArrayStorage* storage = createArrayStorage(globalData, i + 1, getNewVectorLength(0, 0, i + 1)); - storage->m_vector[i].set(globalData, this, value); - storage->m_numValuesInVector = 1; + case ALL_CONTIGUOUS_INDEXING_TYPES: { + putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, i, value); break; } @@ -1371,8 +1619,10 @@ void JSObject::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue bool JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode, ArrayStorage* storage) { JSGlobalData& globalData = exec->globalData(); - + // i should be a valid array index that is outside of the current vector. + ASSERT(hasArrayStorage(structure()->indexingType())); + ASSERT(arrayStorage() == storage); ASSERT(i >= storage->vectorLength() || attributes); ASSERT(i <= MAX_ARRAY_INDEX); @@ -1431,7 +1681,7 @@ bool JSObject::putDirectIndexBeyondVectorLengthWithArrayStorage(ExecState* exec, WriteBarrier<Unknown>* vector = storage->m_vector; SparseArrayValueMap::const_iterator end = map->end(); for (SparseArrayValueMap::const_iterator it = map->begin(); it != end; ++it) - vector[it->first].set(globalData, this, it->second.getNonSparseMode()); + vector[it->key].set(globalData, this, it->value.getNonSparseMode()); deallocateSparseIndexMap(); // Store the new property into the vector. @@ -1454,14 +1704,32 @@ bool JSObject::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSV switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: { - if (indexingShouldBeSparse() || attributes) - return putDirectIndexBeyondVectorLengthWithArrayStorage(exec, i, value, attributes, mode, ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData)); - if (!isDenseEnoughForVector(i, 0) || i >= MAX_STORAGE_VECTOR_LENGTH) - return putDirectIndexBeyondVectorLengthWithArrayStorage(exec, i, value, attributes, mode, createArrayStorage(globalData, 0, 0)); + if (indexingShouldBeSparse() || attributes) { + return putDirectIndexBeyondVectorLengthWithArrayStorage( + exec, i, value, attributes, mode, + ensureArrayStorageExistsAndEnterDictionaryIndexingMode(globalData)); + } + if (i >= MIN_SPARSE_ARRAY_INDEX) { + return putDirectIndexBeyondVectorLengthWithArrayStorage( + exec, i, value, attributes, mode, createArrayStorage(globalData, 0, 0)); + } + if (structure()->needsSlowPutIndexing()) { + ArrayStorage* storage = createArrayStorage(globalData, i + 1, getNewVectorLength(0, 0, i + 1)); + storage->m_vector[i].set(globalData, this, value); + storage->m_numValuesInVector++; + return true; + } - ArrayStorage* storage = createArrayStorage(globalData, i + 1, getNewVectorLength(0, 0, i + 1)); - storage->m_vector[i].set(globalData, this, value); - storage->m_numValuesInVector = 1; + createInitialContiguous(globalData, i + 1)[i].set(globalData, this, value); + return true; + } + + case ALL_CONTIGUOUS_INDEXING_TYPES: { + if (attributes & (ReadOnly | Accessor)) { + return putDirectIndexBeyondVectorLengthWithArrayStorage( + exec, i, value, attributes, mode, convertContiguousToArrayStorage(globalData)); + } + putByIndexBeyondVectorLengthContiguousWithoutAttributes(exec, i, value); return true; } @@ -1486,12 +1754,7 @@ ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned currentVectorLength else if (!currentVectorLength) increasedLength = std::max(desiredLength, lastArraySize); else { - // Mathematically equivalent to: - // increasedLength = (newLength * 3 + 1) / 2; - // or: - // increasedLength = (unsigned)ceil(newLength * 1.5)); - // This form is not prone to internal overflow. - increasedLength = desiredLength + (desiredLength >> 1) + (desiredLength & 1); + increasedLength = timesThreePlusOneDividedByTwo(desiredLength); } ASSERT(increasedLength >= desiredLength); @@ -1511,9 +1774,10 @@ ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned desiredLength) vectorLength = 0; length = 0; break; + case ALL_CONTIGUOUS_INDEXING_TYPES: case ALL_ARRAY_STORAGE_INDEXING_TYPES: - vectorLength = m_butterfly->arrayStorage()->vectorLength(); - length = m_butterfly->arrayStorage()->length(); + vectorLength = m_butterfly->vectorLength(); + length = m_butterfly->publicLength(); break; default: CRASH(); @@ -1522,6 +1786,16 @@ ALWAYS_INLINE unsigned JSObject::getNewVectorLength(unsigned desiredLength) return getNewVectorLength(vectorLength, length, desiredLength); } +unsigned JSObject::countElementsInContiguous(Butterfly* butterfly) +{ + unsigned numValues = 0; + for (unsigned i = butterfly->publicLength(); i--;) { + if (butterfly->contiguous()[i]) + numValues++; + } + return numValues; +} + bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength) { // This function leaves the array in an internally inconsistent state, because it does not move any values from sparse value map @@ -1530,6 +1804,10 @@ bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength return false; ArrayStorage* storage = arrayStorage(); + + if (newLength >= MIN_SPARSE_ARRAY_INDEX + && !isDenseEnoughForVector(newLength, storage->m_numValuesInVector)) + return false; unsigned indexBias = storage->m_indexBias; unsigned vectorLength = storage->vectorLength(); @@ -1561,6 +1839,22 @@ bool JSObject::increaseVectorLength(JSGlobalData& globalData, unsigned newLength return true; } +void JSObject::ensureContiguousLengthSlow(JSGlobalData& globalData, unsigned length) +{ + ASSERT(length < MAX_ARRAY_INDEX); + ASSERT(hasContiguous(structure()->indexingType())); + ASSERT(length > m_butterfly->vectorLength()); + + unsigned newVectorLength = std::min( + length << 1, + MAX_STORAGE_VECTOR_LENGTH); + m_butterfly = m_butterfly->growArrayRight( + globalData, structure(), structure()->outOfLineCapacity(), true, + m_butterfly->vectorLength() * sizeof(EncodedJSValue), + newVectorLength * sizeof(EncodedJSValue)); + m_butterfly->setVectorLength(newVectorLength); +} + Butterfly* JSObject::growOutOfLineStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize) { ASSERT(newSize > oldSize); @@ -1589,6 +1883,17 @@ bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prope case ALL_BLANK_INDEXING_TYPES: return false; + case ALL_CONTIGUOUS_INDEXING_TYPES: { + Butterfly* butterfly = object->m_butterfly; + if (i >= butterfly->vectorLength()) + return false; + JSValue value = butterfly->contiguous()[i].get(); + if (!value) + return false; + descriptor.setDescriptor(value, 0); + return true; + } + case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = object->m_butterfly->arrayStorage(); if (i >= storage->length()) @@ -1604,7 +1909,7 @@ bool JSObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, Prope SparseArrayValueMap::iterator it = map->find(i); if (it == map->notFound()) return false; - it->second.get(descriptor); + it->value.get(descriptor); return true; } return false; diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h index 4b9cff5ad..9204099cb 100644 --- a/Source/JavaScriptCore/runtime/JSObject.h +++ b/Source/JavaScriptCore/runtime/JSObject.h @@ -109,7 +109,13 @@ namespace JSC { public: typedef JSCell Base; + static size_t allocationSize(size_t inlineCapacity) + { + return sizeof(JSObject) + inlineCapacity * sizeof(WriteBarrierBase<Unknown>); + } + JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); + JS_EXPORT_PRIVATE static void copyBackingStore(JSCell*, CopyVisitor&); JS_EXPORT_PRIVATE static String className(const JSObject*); @@ -148,8 +154,9 @@ namespace JSC { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: return 0; + case ALL_CONTIGUOUS_INDEXING_TYPES: case ALL_ARRAY_STORAGE_INDEXING_TYPES: - return m_butterfly->arrayStorage()->length(); + return m_butterfly->publicLength(); default: ASSERT_NOT_REACHED(); return 0; @@ -161,8 +168,9 @@ namespace JSC { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: return 0; + case ALL_CONTIGUOUS_INDEXING_TYPES: case ALL_ARRAY_STORAGE_INDEXING_TYPES: - return m_butterfly->arrayStorage()->vectorLength(); + return m_butterfly->vectorLength(); default: ASSERT_NOT_REACHED(); return 0; @@ -207,6 +215,8 @@ namespace JSC { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: return false; + case ALL_CONTIGUOUS_INDEXING_TYPES: + return i < m_butterfly->vectorLength() && m_butterfly->contiguous()[i]; case ALL_ARRAY_STORAGE_INDEXING_TYPES: return i < m_butterfly->arrayStorage()->vectorLength() && m_butterfly->arrayStorage()->m_vector[i]; default: @@ -218,6 +228,8 @@ namespace JSC { JSValue getIndexQuickly(unsigned i) { switch (structure()->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + return m_butterfly->contiguous()[i].get(); case ALL_ARRAY_STORAGE_INDEXING_TYPES: return m_butterfly->arrayStorage()->m_vector[i].get(); default: @@ -231,12 +243,13 @@ namespace JSC { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: break; + case ALL_CONTIGUOUS_INDEXING_TYPES: + if (i < m_butterfly->publicLength()) + return m_butterfly->contiguous()[i].get(); + break; case ALL_ARRAY_STORAGE_INDEXING_TYPES: - if (i < m_butterfly->arrayStorage()->vectorLength()) { - JSValue v = m_butterfly->arrayStorage()->m_vector[i].get(); - if (v) - return v; - } + if (i < m_butterfly->arrayStorage()->vectorLength()) + return m_butterfly->arrayStorage()->m_vector[i].get(); break; default: ASSERT_NOT_REACHED(); @@ -267,9 +280,10 @@ namespace JSC { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: return false; + case ALL_CONTIGUOUS_INDEXING_TYPES: case NonArrayWithArrayStorage: case ArrayWithArrayStorage: - return i < m_butterfly->arrayStorage()->vectorLength(); + return i < m_butterfly->vectorLength(); case NonArrayWithSlowPutArrayStorage: case ArrayWithSlowPutArrayStorage: return i < m_butterfly->arrayStorage()->vectorLength() @@ -285,8 +299,9 @@ namespace JSC { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: return false; + case ALL_CONTIGUOUS_INDEXING_TYPES: case ALL_ARRAY_STORAGE_INDEXING_TYPES: - return i < m_butterfly->arrayStorage()->vectorLength(); + return i < m_butterfly->vectorLength(); default: ASSERT_NOT_REACHED(); return false; @@ -296,15 +311,23 @@ namespace JSC { void setIndexQuickly(JSGlobalData& globalData, unsigned i, JSValue v) { switch (structure()->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: { + ASSERT(i < m_butterfly->vectorLength()); + m_butterfly->contiguous()[i].set(globalData, this, v); + if (i >= m_butterfly->publicLength()) + m_butterfly->setPublicLength(i + 1); + break; + } case ALL_ARRAY_STORAGE_INDEXING_TYPES: { - WriteBarrier<Unknown>& x = m_butterfly->arrayStorage()->m_vector[i]; - if (!x) { - ArrayStorage* storage = m_butterfly->arrayStorage(); + ArrayStorage* storage = m_butterfly->arrayStorage(); + WriteBarrier<Unknown>& x = storage->m_vector[i]; + JSValue old = x.get(); + x.set(globalData, this, v); + if (!old) { ++storage->m_numValuesInVector; if (i >= storage->length()) storage->setLength(i + 1); } - x.set(globalData, this, v); break; } default: @@ -315,6 +338,12 @@ namespace JSC { void initializeIndex(JSGlobalData& globalData, unsigned i, JSValue v) { switch (structure()->indexingType()) { + case ALL_CONTIGUOUS_INDEXING_TYPES: { + ASSERT(i < m_butterfly->publicLength()); + ASSERT(i < m_butterfly->vectorLength()); + m_butterfly->contiguous()[i].set(globalData, this, v); + break; + } case ALL_ARRAY_STORAGE_INDEXING_TYPES: { ArrayStorage* storage = m_butterfly->arrayStorage(); ASSERT(i < storage->length()); @@ -327,10 +356,25 @@ namespace JSC { } } + bool hasSparseMap() + { + switch (structure()->indexingType()) { + case ALL_BLANK_INDEXING_TYPES: + case ALL_CONTIGUOUS_INDEXING_TYPES: + return false; + case ALL_ARRAY_STORAGE_INDEXING_TYPES: + return m_butterfly->arrayStorage()->m_sparseMap; + default: + ASSERT_NOT_REACHED(); + return false; + } + } + bool inSparseIndexingMode() { switch (structure()->indexingType()) { case ALL_BLANK_INDEXING_TYPES: + case ALL_CONTIGUOUS_INDEXING_TYPES: return false; case ALL_ARRAY_STORAGE_INDEXING_TYPES: return m_butterfly->arrayStorage()->inSparseMode(); @@ -448,10 +492,10 @@ namespace JSC { { PropertyOffset result; size_t offsetInInlineStorage = location - inlineStorageUnsafe(); - if (offsetInInlineStorage < static_cast<size_t>(inlineStorageCapacity)) + if (offsetInInlineStorage < static_cast<size_t>(firstOutOfLineOffset)) result = offsetInInlineStorage; else - result = outOfLineStorage() - location + (inlineStorageCapacity - 1); + result = outOfLineStorage() - location + (firstOutOfLineOffset - 1); validateOffset(result, structure()->typeInfo().type()); return result; } @@ -481,7 +525,7 @@ namespace JSC { bool isNameScopeObject() const; bool isActivationObject() const; bool isErrorInstance() const; - bool isGlobalThis() const; + bool isProxy() const; void seal(JSGlobalData&); void freeze(JSGlobalData&); @@ -528,23 +572,34 @@ namespace JSC { // foo->attemptToInterceptPutByIndexOnHole(...); bool attemptToInterceptPutByIndexOnHoleForPrototype(ExecState*, JSValue thisValue, unsigned propertyName, JSValue, bool shouldThrow); + // Returns 0 if contiguous storage cannot be created - either because + // indexing should be sparse or because we're having a bad time. + WriteBarrier<Unknown>* ensureContiguous(JSGlobalData& globalData) + { + if (LIKELY(hasContiguous(structure()->indexingType()))) + return m_butterfly->contiguous(); + + return ensureContiguousSlow(globalData); + } + // Ensure that the object is in a mode where it has array storage. Use // this if you're about to perform actions that would have required the // object to be converted to have array storage, if it didn't have it // already. ArrayStorage* ensureArrayStorage(JSGlobalData& globalData) { - switch (structure()->indexingType()) { - case ALL_ARRAY_STORAGE_INDEXING_TYPES: + if (LIKELY(hasArrayStorage(structure()->indexingType()))) return m_butterfly->arrayStorage(); - - case ALL_BLANK_INDEXING_TYPES: - return createInitialArrayStorage(globalData); - - default: - ASSERT_NOT_REACHED(); - return 0; - } + + return ensureArrayStorageSlow(globalData); + } + + Butterfly* ensureIndexedStorage(JSGlobalData& globalData) + { + if (LIKELY(hasIndexedProperties(structure()->indexingType()))) + return m_butterfly; + + return ensureIndexedStorageSlow(globalData); } static size_t offsetOfInlineStorage(); @@ -585,6 +640,7 @@ namespace JSC { void resetInheritorID(JSGlobalData&); void visitButterfly(SlotVisitor&, Butterfly*, size_t storageSize); + void copyButterfly(CopyVisitor&, Butterfly*, size_t storageSize); // Call this if you know that the object is in a mode where it has array // storage. This will assert otherwise. @@ -609,11 +665,16 @@ namespace JSC { ArrayStorage* createArrayStorage(JSGlobalData&, unsigned length, unsigned vectorLength); ArrayStorage* createInitialArrayStorage(JSGlobalData&); + WriteBarrier<Unknown>* createInitialContiguous(JSGlobalData&, unsigned length); + ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition, unsigned neededLength); + ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&, NonPropertyTransition); + ArrayStorage* convertContiguousToArrayStorage(JSGlobalData&); ArrayStorage* ensureArrayStorageExistsAndEnterDictionaryIndexingMode(JSGlobalData&); bool defineOwnNonIndexProperty(ExecState*, PropertyName, PropertyDescriptor&, bool throwException); + void putByIndexBeyondVectorLengthContiguousWithoutAttributes(ExecState*, unsigned propertyName, JSValue); void putByIndexBeyondVectorLengthWithArrayStorage(ExecState*, unsigned propertyName, JSValue, bool shouldThrow, ArrayStorage*); bool increaseVectorLength(JSGlobalData&, unsigned newLength); @@ -624,6 +685,56 @@ namespace JSC { void notifyPresenceOfIndexedAccessors(JSGlobalData&); bool attemptToInterceptPutByIndexOnHole(ExecState*, unsigned index, JSValue, bool shouldThrow); + + // Call this if you want setIndexQuickly to succeed and you're sure that + // the array is contiguous. + void ensureContiguousLength(JSGlobalData& globalData, unsigned length) + { + ASSERT(length < MAX_ARRAY_INDEX); + ASSERT(hasContiguous(structure()->indexingType())); + + if (m_butterfly->vectorLength() < length) + ensureContiguousLengthSlow(globalData, length); + + if (m_butterfly->publicLength() < length) + m_butterfly->setPublicLength(length); + } + + unsigned countElementsInContiguous(Butterfly*); + + template<IndexingType indexingType> + WriteBarrier<Unknown>* indexingData() + { + switch (indexingType) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + return m_butterfly->contiguous(); + + case ALL_ARRAY_STORAGE_INDEXING_TYPES: + return m_butterfly->arrayStorage()->m_vector; + + default: + CRASH(); + return 0; + } + } + + template<IndexingType indexingType> + unsigned relevantLength() + { + switch (indexingType) { + case ALL_CONTIGUOUS_INDEXING_TYPES: + return m_butterfly->publicLength(); + + case ALL_ARRAY_STORAGE_INDEXING_TYPES: + return std::min( + m_butterfly->arrayStorage()->length(), + m_butterfly->arrayStorage()->vectorLength()); + + default: + CRASH(); + return 0; + } + } private: friend class LLIntOffsetsExtractor; @@ -658,6 +769,12 @@ namespace JSC { JS_EXPORT_PRIVATE bool getOwnPropertySlotSlow(ExecState*, PropertyName, PropertySlot&); + void ensureContiguousLengthSlow(JSGlobalData&, unsigned length); + + WriteBarrier<Unknown>* ensureContiguousSlow(JSGlobalData&); + ArrayStorage* ensureArrayStorageSlow(JSGlobalData&); + Butterfly* ensureIndexedStorageSlow(JSGlobalData&); + protected: Butterfly* m_butterfly; }; @@ -677,11 +794,6 @@ namespace JSC { return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); } - static bool hasInlineStorage() - { - return false; - } - protected: explicit JSNonFinalObject(JSGlobalData& globalData, Structure* structure, Butterfly* butterfly = 0) : JSObject(globalData, structure, butterfly) @@ -709,45 +821,43 @@ namespace JSC { static JSFinalObject* create(ExecState*, Structure*); static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) { - return Structure::create(globalData, globalObject, prototype, TypeInfo(FinalObjectType, StructureFlags), &s_info); + return Structure::create(globalData, globalObject, prototype, TypeInfo(FinalObjectType, StructureFlags), &s_info, NonArray, INLINE_STORAGE_CAPACITY); } JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); static JS_EXPORTDATA const ClassInfo s_info; - static bool hasInlineStorage() - { - return true; - } protected: void visitChildrenCommon(SlotVisitor&); void finishCreation(JSGlobalData& globalData) { Base::finishCreation(globalData); - ASSERT(!(OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage) % sizeof(double))); - ASSERT(this->structure()->inlineCapacity() == static_cast<unsigned>(inlineStorageCapacity)); - ASSERT(this->structure()->totalStorageCapacity() == static_cast<unsigned>(inlineStorageCapacity)); + ASSERT(structure()->totalStorageCapacity() == structure()->inlineCapacity()); ASSERT(classInfo()); } private: friend class LLIntOffsetsExtractor; - + explicit JSFinalObject(JSGlobalData& globalData, Structure* structure) : JSObject(globalData, structure) { } static const unsigned StructureFlags = JSObject::StructureFlags; - - WriteBarrierBase<Unknown> m_inlineStorage[INLINE_STORAGE_CAPACITY]; }; inline JSFinalObject* JSFinalObject::create(ExecState* exec, Structure* structure) { - JSFinalObject* finalObject = new (NotNull, allocateCell<JSFinalObject>(*exec->heap())) JSFinalObject(exec->globalData(), structure); + JSFinalObject* finalObject = new ( + NotNull, + allocateCell<JSFinalObject>( + *exec->heap(), + allocationSize(structure->inlineCapacity()) + ) + ) JSFinalObject(exec->globalData(), structure); finalObject->finishCreation(exec->globalData()); return finalObject; } @@ -764,7 +874,7 @@ inline bool isJSFinalObject(JSValue value) inline size_t JSObject::offsetOfInlineStorage() { - return OBJECT_OFFSETOF(JSFinalObject, m_inlineStorage); + return sizeof(JSObject); } inline bool JSObject::isGlobalObject() const @@ -792,9 +902,9 @@ inline bool JSObject::isErrorInstance() const return structure()->typeInfo().type() == ErrorInstanceType; } -inline bool JSObject::isGlobalThis() const +inline bool JSObject::isProxy() const { - return structure()->typeInfo().type() == GlobalThisType; + return structure()->typeInfo().type() == ProxyType; } inline void JSObject::setButterfly(JSGlobalData& globalData, Butterfly* butterfly, Structure* structure) @@ -856,14 +966,14 @@ inline JSValue JSObject::prototype() const return structure()->storedPrototype(); } -inline bool JSCell::inherits(const ClassInfo* info) const +inline const MethodTable* JSCell::methodTable() const { - return classInfo()->isSubClassOf(info); + return &classInfo()->methodTable; } -inline const MethodTable* JSCell::methodTable() const +inline bool JSCell::inherits(const ClassInfo* info) const { - return &classInfo()->methodTable; + return classInfo()->isSubClassOf(info); } // this method is here to be after the inline declaration of JSCell::inherits @@ -1257,6 +1367,8 @@ inline int offsetRelativeToBase(PropertyOffset offset) return JSObject::offsetOfInlineStorage() + offsetInInlineStorage(offset) * sizeof(EncodedJSValue); } +COMPILE_ASSERT(!(sizeof(JSObject) % sizeof(WriteBarrierBase<Unknown>)), JSObject_inline_storage_has_correct_alignment); + } // namespace JSC #endif // JSObject_h diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp index 897ceff8c..225401fbd 100644 --- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp +++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp @@ -33,8 +33,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator); - const ClassInfo JSPropertyNameIterator::s_info = { "JSPropertyNameIterator", 0, 0, 0, CREATE_METHOD_TABLE(JSPropertyNameIterator) }; inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots) diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h index 057ffe293..e59a5c6a4 100644 --- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h +++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h @@ -48,6 +48,8 @@ namespace JSC { static JSPropertyNameIterator* create(ExecState*, JSObject*); + static const bool needsDestruction = true; + static const bool hasImmortalStructure = true; static void destroy(JSCell*); static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) @@ -57,14 +59,6 @@ namespace JSC { static void visitChildren(JSCell*, SlotVisitor&); - bool getOffset(size_t i, PropertyOffset& offset) - { - if (i >= m_numCacheableSlots) - return false; - offset = i + m_offsetBase; - return true; - } - JSValue get(ExecState*, JSObject*, size_t i); size_t size() { return m_jsStringsSize; } @@ -88,7 +82,7 @@ namespace JSC { PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector(); for (size_t i = 0; i < m_jsStringsSize; ++i) m_jsStrings[i].set(exec->globalData(), this, jsOwnedString(exec, propertyNameVector[i].string())); - m_offsetBase = object->structure()->firstValidOffset(); + m_cachedStructureInlineCapacity = object->structure()->inlineCapacity(); } private: @@ -100,7 +94,7 @@ namespace JSC { WriteBarrier<StructureChain> m_cachedPrototypeChain; uint32_t m_numCacheableSlots; uint32_t m_jsStringsSize; - PropertyOffset m_offsetBase; + unsigned m_cachedStructureInlineCapacity; OwnArrayPtr<WriteBarrier<Unknown> > m_jsStrings; }; diff --git a/Source/JavaScriptCore/runtime/JSProxy.cpp b/Source/JavaScriptCore/runtime/JSProxy.cpp new file mode 100644 index 000000000..7108dcfa0 --- /dev/null +++ b/Source/JavaScriptCore/runtime/JSProxy.cpp @@ -0,0 +1,129 @@ +/* + * 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. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSProxy.h" + +#include "JSGlobalObject.h" + +namespace JSC { + +ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSProxy); + +const ClassInfo JSProxy::s_info = { "JSProxy", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSProxy) }; + +void JSProxy::visitChildren(JSCell* cell, SlotVisitor& visitor) +{ + JSProxy* thisObject = jsCast<JSProxy*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + + COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); + ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); + + Base::visitChildren(thisObject, visitor); + visitor.append(&thisObject->m_target); +} + +void JSProxy::setTarget(JSGlobalData& globalData, JSGlobalObject* globalObject) +{ + ASSERT_ARG(globalObject, globalObject); + m_target.set(globalData, this, globalObject); + setPrototype(globalData, globalObject->prototype()); + resetInheritorID(globalData); +} + +String JSProxy::className(const JSObject* object) +{ + const JSProxy* thisObject = jsCast<const JSProxy*>(object); + return thisObject->target()->methodTable()->className(thisObject->target()); +} + +bool JSProxy::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) +{ + JSProxy* thisObject = jsCast<JSProxy*>(cell); + return thisObject->target()->methodTable()->getOwnPropertySlot(thisObject->target(), exec, propertyName, slot); +} + +bool JSProxy::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot) +{ + JSProxy* thisObject = jsCast<JSProxy*>(cell); + return thisObject->target()->methodTable()->getOwnPropertySlotByIndex(thisObject->target(), exec, propertyName, slot); +} + +bool JSProxy::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) +{ + JSProxy* thisObject = jsCast<JSProxy*>(object); + return thisObject->target()->methodTable()->getOwnPropertyDescriptor(thisObject->target(), exec, propertyName, descriptor); +} + +void JSProxy::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) +{ + JSProxy* thisObject = jsCast<JSProxy*>(cell); + thisObject->target()->methodTable()->put(thisObject->target(), exec, propertyName, value, slot); +} + +void JSProxy::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow) +{ + JSProxy* thisObject = jsCast<JSProxy*>(cell); + thisObject->target()->methodTable()->putByIndex(thisObject->target(), exec, propertyName, value, shouldThrow); +} + +void JSProxy::putDirectVirtual(JSObject* object, ExecState* exec, PropertyName propertyName, JSValue value, unsigned attributes) +{ + JSProxy* thisObject = jsCast<JSProxy*>(object); + thisObject->target()->putDirectVirtual(thisObject->target(), exec, propertyName, value, attributes); +} + +bool JSProxy::defineOwnProperty(JSC::JSObject* object, JSC::ExecState* exec, JSC::PropertyName propertyName, JSC::PropertyDescriptor& descriptor, bool shouldThrow) +{ + JSProxy* thisObject = jsCast<JSProxy*>(object); + return thisObject->target()->methodTable()->defineOwnProperty(thisObject->target(), exec, propertyName, descriptor, shouldThrow); +} + +bool JSProxy::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) +{ + JSProxy* thisObject = jsCast<JSProxy*>(cell); + return thisObject->target()->methodTable()->deleteProperty(thisObject->target(), exec, propertyName); +} + +bool JSProxy::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName) +{ + JSProxy* thisObject = jsCast<JSProxy*>(cell); + return thisObject->target()->methodTable()->deletePropertyByIndex(thisObject->target(), exec, propertyName); +} + +void JSProxy::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) +{ + JSProxy* thisObject = jsCast<JSProxy*>(object); + thisObject->target()->methodTable()->getPropertyNames(thisObject->target(), exec, propertyNames, mode); +} + +void JSProxy::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) +{ + JSProxy* thisObject = jsCast<JSProxy*>(object); + thisObject->target()->methodTable()->getOwnPropertyNames(thisObject->target(), exec, propertyNames, mode); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSProxy.h b/Source/JavaScriptCore/runtime/JSProxy.h new file mode 100644 index 000000000..144085a79 --- /dev/null +++ b/Source/JavaScriptCore/runtime/JSProxy.h @@ -0,0 +1,95 @@ +/* + * 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 JSProxy_h +#define JSProxy_h + +#include "JSDestructibleObject.h" + +namespace JSC { + +class JSProxy : public JSDestructibleObject { +public: + typedef JSDestructibleObject Base; + + static JSProxy* create(JSGlobalData& globalData, Structure* structure, JSObject* target) + { + JSProxy* proxy = new (NotNull, allocateCell<JSProxy>(globalData.heap)) JSProxy(globalData, structure); + proxy->finishCreation(globalData, target); + return proxy; + } + + static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(globalData, globalObject, prototype, TypeInfo(ProxyType, StructureFlags), &s_info); + } + + static JS_EXPORTDATA const ClassInfo s_info; + + JSObject* target() const { return m_target.get(); } + +protected: + JSProxy(JSGlobalData& globalData, Structure* structure) + : JSDestructibleObject(globalData, structure) + { + } + + void finishCreation(JSGlobalData& globalData) + { + Base::finishCreation(globalData); + } + + void finishCreation(JSGlobalData& globalData, JSObject* target) + { + Base::finishCreation(globalData); + m_target.set(globalData, this, target); + } + + static const unsigned StructureFlags = OverridesVisitChildren | OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags; + + JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); + + JS_EXPORT_PRIVATE void setTarget(JSGlobalData&, JSGlobalObject*); + + JS_EXPORT_PRIVATE static String className(const JSObject*); + JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); + JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned, PropertySlot&); + JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); + JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); + JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned, JSValue, bool shouldThrow); + JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes); + JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName); + JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned); + JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow); + +private: + WriteBarrier<JSObject> m_target; +}; + +} // namespace JSC + +#endif // JSProxy_h diff --git a/Source/JavaScriptCore/runtime/JSScope.cpp b/Source/JavaScriptCore/runtime/JSScope.cpp index b22211970..8fd49b861 100644 --- a/Source/JavaScriptCore/runtime/JSScope.cpp +++ b/Source/JavaScriptCore/runtime/JSScope.cpp @@ -33,7 +33,7 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSScope); +ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSScope); void JSScope::visitChildren(JSCell* cell, SlotVisitor& visitor) { diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h index 1500636f2..245c48a51 100644 --- a/Source/JavaScriptCore/runtime/JSString.h +++ b/Source/JavaScriptCore/runtime/JSString.h @@ -71,6 +71,8 @@ namespace JSC { typedef JSCell Base; + static const bool needsDestruction = true; + static const bool hasImmortalStructure = true; static void destroy(JSCell*); private: diff --git a/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp b/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp index 765e1d3d4..7dcde4700 100644 --- a/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp +++ b/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp @@ -61,8 +61,8 @@ void JSSymbolTableObject::getOwnNonIndexPropertyNames(JSObject* object, ExecStat JSSymbolTableObject* thisObject = jsCast<JSSymbolTableObject*>(object); SymbolTable::const_iterator end = thisObject->symbolTable()->end(); for (SymbolTable::const_iterator it = thisObject->symbolTable()->begin(); it != end; ++it) { - if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties)) - propertyNames.add(Identifier(exec, it->first.get())); + if (!(it->value.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties)) + propertyNames.add(Identifier(exec, it->key.get())); } JSObject::getOwnNonIndexPropertyNames(thisObject, exec, propertyNames, mode); diff --git a/Source/JavaScriptCore/runtime/JSSymbolTableObject.h b/Source/JavaScriptCore/runtime/JSSymbolTableObject.h index b4d313c19..913679f80 100644 --- a/Source/JavaScriptCore/runtime/JSSymbolTableObject.h +++ b/Source/JavaScriptCore/runtime/JSSymbolTableObject.h @@ -76,7 +76,7 @@ inline bool symbolTableGet( SymbolTable::iterator iter = symbolTable.find(propertyName.publicName()); if (iter == symbolTable.end()) return false; - SymbolTableEntry::Fast entry = iter->second; + SymbolTableEntry::Fast entry = iter->value; ASSERT(!entry.isNull()); slot.setValue(object->registerAt(entry.getIndex()).get()); return true; @@ -90,7 +90,7 @@ inline bool symbolTableGet( SymbolTable::iterator iter = symbolTable.find(propertyName.publicName()); if (iter == symbolTable.end()) return false; - SymbolTableEntry::Fast entry = iter->second; + SymbolTableEntry::Fast entry = iter->value; ASSERT(!entry.isNull()); descriptor.setDescriptor( object->registerAt(entry.getIndex()).get(), entry.getAttributes() | DontDelete); @@ -106,7 +106,7 @@ inline bool symbolTableGet( SymbolTable::iterator iter = symbolTable.find(propertyName.publicName()); if (iter == symbolTable.end()) return false; - SymbolTableEntry::Fast entry = iter->second; + SymbolTableEntry::Fast entry = iter->value; ASSERT(!entry.isNull()); slot.setValue(object->registerAt(entry.getIndex()).get()); slotIsWriteable = !entry.isReadOnly(); @@ -126,7 +126,7 @@ inline bool symbolTablePut( if (iter == symbolTable.end()) return false; bool wasFat; - SymbolTableEntry::Fast fastEntry = iter->second.getFast(wasFat); + SymbolTableEntry::Fast fastEntry = iter->value.getFast(wasFat); ASSERT(!fastEntry.isNull()); if (fastEntry.isReadOnly()) { if (shouldThrow) @@ -134,7 +134,7 @@ inline bool symbolTablePut( return true; } if (UNLIKELY(wasFat)) - iter->second.notifyWrite(); + iter->value.notifyWrite(); object->registerAt(fastEntry.getIndex()).set(globalData, object, value); return true; } @@ -149,7 +149,7 @@ inline bool symbolTablePutWithAttributes( SymbolTable::iterator iter = object->symbolTable()->find(propertyName.publicName()); if (iter == object->symbolTable()->end()) return false; - SymbolTableEntry& entry = iter->second; + SymbolTableEntry& entry = iter->value; ASSERT(!entry.isNull()); entry.notifyWrite(); entry.setAttributes(attributes); diff --git a/Source/JavaScriptCore/runtime/JSType.h b/Source/JavaScriptCore/runtime/JSType.h index b8ab330f5..03f4a7790 100644 --- a/Source/JavaScriptCore/runtime/JSType.h +++ b/Source/JavaScriptCore/runtime/JSType.h @@ -48,7 +48,7 @@ enum JSType { NameInstanceType, NumberObjectType, ErrorInstanceType, - GlobalThisType, + ProxyType, WithScopeType, NameScopeObjectType, diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp index ac00fad3d..651e50cec 100644 --- a/Source/JavaScriptCore/runtime/JSValue.cpp +++ b/Source/JavaScriptCore/runtime/JSValue.cpp @@ -195,7 +195,7 @@ void JSValue::putToPrimitiveByIndex(ExecState* exec, unsigned propertyName, JSVa char* JSValue::description() const { - static const size_t size = 128; + static const size_t size = 256; static char description[size]; if (!*this) @@ -213,9 +213,12 @@ char* JSValue::description() const u.asDouble = asDouble(); snprintf(description, size, "Double: %08x:%08x, %lf", u.asTwoInt32s[1], u.asTwoInt32s[0], asDouble()); #endif - } else if (isCell()) - snprintf(description, size, "Cell: %p", asCell()); - else if (isTrue()) + } else if (isCell()) { + snprintf( + description, size, "Cell: %p (%p: %s, %s)", + asCell(), asCell()->structure(), asCell()->structure()->classInfo()->className, + indexingTypeToString(asCell()->structure()->indexingTypeIncludingHistory())); + } else if (isTrue()) snprintf(description, size, "True"); else if (isFalse()) snprintf(description, size, "False"); diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h index 55952820e..25961dc09 100644 --- a/Source/JavaScriptCore/runtime/JSVariableObject.h +++ b/Source/JavaScriptCore/runtime/JSVariableObject.h @@ -68,7 +68,7 @@ namespace JSC { { } - WriteBarrierBase<Unknown>* m_registers; // "r" in the register file. + WriteBarrierBase<Unknown>* m_registers; // "r" in the stack. }; } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSWithScope.cpp b/Source/JavaScriptCore/runtime/JSWithScope.cpp index 0c4b6e2cc..7d74e63c3 100644 --- a/Source/JavaScriptCore/runtime/JSWithScope.cpp +++ b/Source/JavaScriptCore/runtime/JSWithScope.cpp @@ -28,8 +28,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSWithScope); - const ClassInfo JSWithScope::s_info = { "WithScope", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSWithScope) }; void JSWithScope::visitChildren(JSCell* cell, SlotVisitor& visitor) diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.cpp b/Source/JavaScriptCore/runtime/JSWrapperObject.cpp index 4a46c2c69..ff80c1e20 100644 --- a/Source/JavaScriptCore/runtime/JSWrapperObject.cpp +++ b/Source/JavaScriptCore/runtime/JSWrapperObject.cpp @@ -24,7 +24,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSWrapperObject); ASSERT_HAS_TRIVIAL_DESTRUCTOR(JSWrapperObject); void JSWrapperObject::visitChildren(JSCell* cell, SlotVisitor& visitor) diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.h b/Source/JavaScriptCore/runtime/JSWrapperObject.h index 65b4bdb7f..72bc1874c 100644 --- a/Source/JavaScriptCore/runtime/JSWrapperObject.h +++ b/Source/JavaScriptCore/runtime/JSWrapperObject.h @@ -22,15 +22,15 @@ #ifndef JSWrapperObject_h #define JSWrapperObject_h -#include "JSObject.h" +#include "JSDestructibleObject.h" namespace JSC { // This class is used as a base for classes such as String, // Number, Boolean and Date which are wrappers for primitive types. - class JSWrapperObject : public JSNonFinalObject { + class JSWrapperObject : public JSDestructibleObject { public: - typedef JSNonFinalObject Base; + typedef JSDestructibleObject Base; JSValue internalValue() const; void setInternalValue(JSGlobalData&, JSValue); @@ -42,7 +42,7 @@ namespace JSC { protected: explicit JSWrapperObject(JSGlobalData&, Structure*); - static const unsigned StructureFlags = OverridesVisitChildren | JSNonFinalObject::StructureFlags; + static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; static void visitChildren(JSCell*, SlotVisitor&); @@ -51,7 +51,7 @@ namespace JSC { }; inline JSWrapperObject::JSWrapperObject(JSGlobalData& globalData, Structure* structure) - : JSNonFinalObject(globalData, structure) + : JSDestructibleObject(globalData, structure) { } diff --git a/Source/JavaScriptCore/runtime/MathObject.cpp b/Source/JavaScriptCore/runtime/MathObject.cpp index 2a550a38b..2f4df375a 100644 --- a/Source/JavaScriptCore/runtime/MathObject.cpp +++ b/Source/JavaScriptCore/runtime/MathObject.cpp @@ -32,7 +32,7 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(MathObject); +ASSERT_HAS_TRIVIAL_DESTRUCTOR(MathObject); static EncodedJSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*); static EncodedJSValue JSC_HOST_CALL mathProtoFuncACos(ExecState*); @@ -59,9 +59,7 @@ static EncodedJSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*); namespace JSC { -ASSERT_HAS_TRIVIAL_DESTRUCTOR(MathObject); - -const ClassInfo MathObject::s_info = { "Math", &JSNonFinalObject::s_info, 0, ExecState::mathTable, CREATE_METHOD_TABLE(MathObject) }; +const ClassInfo MathObject::s_info = { "Math", &Base::s_info, 0, ExecState::mathTable, CREATE_METHOD_TABLE(MathObject) }; /* Source for MathObject.lut.h @begin mathTable diff --git a/Source/JavaScriptCore/runtime/MemoryStatistics.cpp b/Source/JavaScriptCore/runtime/MemoryStatistics.cpp index b35e9fbda..0f8efc604 100644 --- a/Source/JavaScriptCore/runtime/MemoryStatistics.cpp +++ b/Source/JavaScriptCore/runtime/MemoryStatistics.cpp @@ -28,7 +28,7 @@ #include "ExecutableAllocator.h" #include "JSGlobalData.h" -#include "RegisterFile.h" +#include "JSStack.h" namespace JSC { @@ -36,7 +36,7 @@ GlobalMemoryStatistics globalMemoryStatistics() { GlobalMemoryStatistics stats; - stats.stackBytes = RegisterFile::committedByteCount(); + stats.stackBytes = JSStack::committedByteCount(); #if ENABLE(EXECUTABLE_ALLOCATOR_FIXED) || ((PLATFORM(BLACKBERRY) || PLATFORM(EFL)) && ENABLE(JIT)) stats.JITBytes = ExecutableAllocator::committedByteCount(); #else diff --git a/Source/JavaScriptCore/runtime/NameConstructor.cpp b/Source/JavaScriptCore/runtime/NameConstructor.cpp index 63f1f647a..b5facc7cf 100644 --- a/Source/JavaScriptCore/runtime/NameConstructor.cpp +++ b/Source/JavaScriptCore/runtime/NameConstructor.cpp @@ -31,7 +31,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(NameConstructor); ASSERT_HAS_TRIVIAL_DESTRUCTOR(NameConstructor); const ClassInfo NameConstructor::s_info = { "Function", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(NameConstructor) }; diff --git a/Source/JavaScriptCore/runtime/NameInstance.h b/Source/JavaScriptCore/runtime/NameInstance.h index c5931e8ef..129e7c407 100644 --- a/Source/JavaScriptCore/runtime/NameInstance.h +++ b/Source/JavaScriptCore/runtime/NameInstance.h @@ -26,14 +26,14 @@ #ifndef NameInstance_h #define NameInstance_h -#include "JSObject.h" +#include "JSDestructibleObject.h" #include "PrivateName.h" namespace JSC { -class NameInstance : public JSNonFinalObject { +class NameInstance : public JSDestructibleObject { public: - typedef JSNonFinalObject Base; + typedef JSDestructibleObject Base; static const ClassInfo s_info; diff --git a/Source/JavaScriptCore/runtime/NamePrototype.cpp b/Source/JavaScriptCore/runtime/NamePrototype.cpp index 3e52856b6..f14e58522 100644 --- a/Source/JavaScriptCore/runtime/NamePrototype.cpp +++ b/Source/JavaScriptCore/runtime/NamePrototype.cpp @@ -30,8 +30,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(NamePrototype); - static EncodedJSValue JSC_HOST_CALL privateNameProtoFuncToString(ExecState*); } @@ -48,8 +46,6 @@ const ClassInfo NamePrototype::s_info = { "Name", &Base::s_info, 0, ExecState::p @end */ -ASSERT_CLASS_FITS_IN_CELL(NamePrototype); - NamePrototype::NamePrototype(ExecState* exec, Structure* structure) : Base(exec->globalData(), structure, jsEmptyString(exec)) { diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp index a4ba240fd..1f1730805 100644 --- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp +++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp @@ -28,7 +28,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(NativeErrorConstructor); ASSERT_HAS_TRIVIAL_DESTRUCTOR(NativeErrorConstructor); const ClassInfo NativeErrorConstructor::s_info = { "Function", &InternalFunction::s_info, 0, 0, CREATE_METHOD_TABLE(NativeErrorConstructor) }; diff --git a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp index 7fee213fa..296a86a22 100644 --- a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp +++ b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp @@ -27,8 +27,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype); - NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, Structure* structure) : ErrorPrototype(exec, structure) { diff --git a/Source/JavaScriptCore/runtime/NumberConstructor.cpp b/Source/JavaScriptCore/runtime/NumberConstructor.cpp index 03d616073..daa643da7 100644 --- a/Source/JavaScriptCore/runtime/NumberConstructor.cpp +++ b/Source/JavaScriptCore/runtime/NumberConstructor.cpp @@ -28,8 +28,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(NumberConstructor); - static JSValue numberConstructorNaNValue(ExecState*, JSValue, PropertyName); static JSValue numberConstructorNegInfinity(ExecState*, JSValue, PropertyName); static JSValue numberConstructorPosInfinity(ExecState*, JSValue, PropertyName); diff --git a/Source/JavaScriptCore/runtime/NumberObject.cpp b/Source/JavaScriptCore/runtime/NumberObject.cpp index 1fea25464..b87753d4d 100644 --- a/Source/JavaScriptCore/runtime/NumberObject.cpp +++ b/Source/JavaScriptCore/runtime/NumberObject.cpp @@ -27,7 +27,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(NumberObject); ASSERT_HAS_TRIVIAL_DESTRUCTOR(NumberObject); const ClassInfo NumberObject::s_info = { "Number", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(NumberObject) }; diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.cpp b/Source/JavaScriptCore/runtime/NumberPrototype.cpp index 4a10efd6d..23c9dbfdd 100644 --- a/Source/JavaScriptCore/runtime/NumberPrototype.cpp +++ b/Source/JavaScriptCore/runtime/NumberPrototype.cpp @@ -68,7 +68,6 @@ const ClassInfo NumberPrototype::s_info = { "Number", &NumberObject::s_info, 0, @end */ -ASSERT_CLASS_FITS_IN_CELL(NumberPrototype); ASSERT_HAS_TRIVIAL_DESTRUCTOR(NumberPrototype); NumberPrototype::NumberPrototype(ExecState* exec, Structure* structure) diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp index 8614b9c45..7df047d28 100644 --- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp +++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp @@ -35,8 +35,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(ObjectConstructor); - static EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState*); static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState*); static EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState*); diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp index b1a5b9fb3..e94edfadf 100644 --- a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp @@ -63,8 +63,6 @@ const ClassInfo ObjectPrototype::s_info = { "Object", &JSNonFinalObject::s_info, @end */ -ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype); - ObjectPrototype::ObjectPrototype(ExecState* exec, Structure* stucture) : JSNonFinalObject(exec->globalData(), stucture) { diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp index ed0720b54..386eb4fcf 100644 --- a/Source/JavaScriptCore/runtime/Options.cpp +++ b/Source/JavaScriptCore/runtime/Options.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "Options.h" +#include "HeapStatistics.h" #include <algorithm> #include <limits> #include <stdio.h> @@ -41,10 +42,6 @@ #include <sys/sysctl.h> #endif -// Set to 1 to control the heuristics using environment variables. -#define ENABLE_RUN_TIME_HEURISTICS 0 - - namespace JSC { static bool parse(const char* string, bool& value) @@ -75,10 +72,10 @@ static bool parse(const char* string, double& value) return sscanf(string, "%lf", &value) == 1; } -#if ENABLE(RUN_TIME_HEURISTICS) template<typename T> void overrideOptionWithHeuristic(T& variable, const char* name) { +#if !OS(WINCE) const char* stringValue = getenv(name); if (!stringValue) return; @@ -87,9 +84,8 @@ void overrideOptionWithHeuristic(T& variable, const char* name) return; fprintf(stderr, "WARNING: failed to parse %s=%s\n", name, stringValue); -} #endif - +} static unsigned computeNumberOfGCMarkers(int maxNumberOfGCMarkers) { @@ -130,17 +126,19 @@ void Options::initialize() #if USE(CF) || OS(UNIX) objectsAreImmortal() = !!getenv("JSImmortalZombieEnabled"); useZombieMode() = !!getenv("JSImmortalZombieEnabled") || !!getenv("JSZombieEnabled"); + + gcMaxHeapSize() = getenv("GCMaxHeapSize") ? HeapStatistics::parseMemoryAmount(getenv("GCMaxHeapSize")) : 0; + recordGCPauseTimes() = !!getenv("JSRecordGCPauseTimes"); + logHeapStatisticsAtExit() = gcMaxHeapSize() || recordGCPauseTimes(); #endif // Allow environment vars to override options if applicable. // The evn var should be the name of the option prefixed with // "JSC_". -#if ENABLE(RUN_TIME_HEURISTICS) #define FOR_EACH_OPTION(type_, name_, defaultValue_) \ overrideOptionWithHeuristic(name_(), "JSC_" #name_); JSC_OPTIONS(FOR_EACH_OPTION) #undef FOR_EACH_OPTION -#endif // RUN_TIME_HEURISTICS #if 0 ; // Deconfuse editors that do auto indentation @@ -153,7 +151,7 @@ void Options::initialize() #if !ENABLE(YARR_JIT) useRegExpJIT() = false; #endif - + // Do range checks where needed and make corrections to the options: ASSERT(thresholdForOptimizeAfterLongWarmUp() >= thresholdForOptimizeAfterWarmUp()); ASSERT(thresholdForOptimizeAfterWarmUp() >= thresholdForOptimizeSoon()); diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h index 7571f9138..d6d8c66c8 100644 --- a/Source/JavaScriptCore/runtime/Options.h +++ b/Source/JavaScriptCore/runtime/Options.h @@ -51,9 +51,8 @@ namespace JSC { // purposes, you can do so in Options::initialize() after the default values // are set. // -// Alternatively, you can enable RUN_TIME_HEURISTICS which will allow you -// to override the default values by specifying environment variables of the -// form: JSC_<name of JSC option>. +// Alternatively, you can override the default values by specifying +// environment variables of the form: JSC_<name of JSC option>. // // Note: Options::initialize() tries to ensure some sanity on the option values // which are set by doing some range checks, and value corrections. These @@ -116,14 +115,19 @@ namespace JSC { v(unsigned, gcMarkStackSegmentSize, pageSize()) \ v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7)) \ v(unsigned, opaqueRootMergeThreshold, 1000) \ + v(double, minHeapUtilization, 0.8) \ + v(double, minCopiedBlockUtilization, 0.9) \ \ v(bool, forceWeakRandomSeed, false) \ v(unsigned, forcedWeakRandomSeed, 0) \ \ v(bool, useZombieMode, false) \ v(bool, objectsAreImmortal, false) \ - v(bool, showHeapStatistics, false) - + v(bool, showObjectStatistics, false) \ + \ + v(unsigned, gcMaxHeapSize, 0) \ + v(bool, recordGCPauseTimes, false) \ + v(bool, logHeapStatisticsAtExit, false) class Options { public: @@ -161,7 +165,7 @@ private: boolType, unsignedType, doubleType, - int32Type + int32Type, }; // For storing for an option value: diff --git a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h index 2d0f27a3e..9c6ddb20f 100644 --- a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h +++ b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h @@ -178,7 +178,7 @@ public: PropertyOffset getDeletedOffset(); void addDeletedOffset(PropertyOffset); - PropertyOffset nextOffset(JSType); + PropertyOffset nextOffset(PropertyOffset inlineCapacity); // Copy this PropertyTable, ensuring the copy has at least the capacity provided. PassOwnPtr<PropertyTable> copy(JSGlobalData&, JSCell* owner, unsigned newCapacity); @@ -486,15 +486,12 @@ inline void PropertyTable::addDeletedOffset(PropertyOffset offset) m_deletedOffsets->append(offset); } -inline PropertyOffset PropertyTable::nextOffset(JSType type) +inline PropertyOffset PropertyTable::nextOffset(PropertyOffset inlineCapacity) { if (hasDeletedOffset()) return getDeletedOffset(); - - if (type == FinalObjectType) - return size(); - - return size() + firstOutOfLineOffset; + + return propertyOffsetFor(size(), inlineCapacity); } inline PassOwnPtr<PropertyTable> PropertyTable::copy(JSGlobalData& globalData, JSCell* owner, unsigned newCapacity) diff --git a/Source/JavaScriptCore/runtime/PropertyOffset.h b/Source/JavaScriptCore/runtime/PropertyOffset.h index 2aea2981e..1a2bba446 100644 --- a/Source/JavaScriptCore/runtime/PropertyOffset.h +++ b/Source/JavaScriptCore/runtime/PropertyOffset.h @@ -26,7 +26,6 @@ #ifndef PropertyOffset_h #define PropertyOffset_h -#include "JSType.h" #include <wtf/Platform.h> #include <wtf/StdLibExtras.h> #include <wtf/UnusedParam.h> @@ -42,14 +41,13 @@ namespace JSC { typedef int PropertyOffset; static const PropertyOffset invalidOffset = -1; -static const PropertyOffset inlineStorageCapacity = INLINE_STORAGE_CAPACITY; -static const PropertyOffset firstOutOfLineOffset = inlineStorageCapacity; +static const PropertyOffset firstOutOfLineOffset = 100; // Declare all of the functions because they tend to do forward calls. inline void checkOffset(PropertyOffset); -inline void checkOffset(PropertyOffset, JSType); +inline void checkOffset(PropertyOffset, PropertyOffset inlineCapacity); inline void validateOffset(PropertyOffset); -inline void validateOffset(PropertyOffset, JSType); +inline void validateOffset(PropertyOffset, PropertyOffset inlineCapacity); inline bool isValidOffset(PropertyOffset); inline bool isInlineOffset(PropertyOffset); inline bool isOutOfLineOffset(PropertyOffset); @@ -57,9 +55,7 @@ inline size_t offsetInInlineStorage(PropertyOffset); inline size_t offsetInOutOfLineStorage(PropertyOffset); inline size_t offsetInRespectiveStorage(PropertyOffset); inline size_t numberOfOutOfLineSlotsForLastOffset(PropertyOffset); -inline size_t numberOfSlotsForLastOffset(PropertyOffset, JSType); -inline PropertyOffset nextPropertyOffsetFor(PropertyOffset, JSType); -inline PropertyOffset firstPropertyOffsetFor(JSType); +inline size_t numberOfSlotsForLastOffset(PropertyOffset, PropertyOffset inlineCapacity); inline void checkOffset(PropertyOffset offset) { @@ -67,14 +63,14 @@ inline void checkOffset(PropertyOffset offset) ASSERT(offset >= invalidOffset); } -inline void checkOffset(PropertyOffset offset, JSType type) +inline void checkOffset(PropertyOffset offset, PropertyOffset inlineCapacity) { UNUSED_PARAM(offset); - UNUSED_PARAM(type); + UNUSED_PARAM(inlineCapacity); ASSERT(offset >= invalidOffset); ASSERT(offset == invalidOffset - || type == FinalObjectType - || isOutOfLineOffset(offset)); + || offset < inlineCapacity + || isOutOfLineOffset(offset)); } inline void validateOffset(PropertyOffset offset) @@ -83,9 +79,9 @@ inline void validateOffset(PropertyOffset offset) ASSERT(isValidOffset(offset)); } -inline void validateOffset(PropertyOffset offset, JSType type) +inline void validateOffset(PropertyOffset offset, PropertyOffset inlineCapacity) { - checkOffset(offset, type); + checkOffset(offset, inlineCapacity); ASSERT(isValidOffset(offset)); } @@ -98,7 +94,7 @@ inline bool isValidOffset(PropertyOffset offset) inline bool isInlineOffset(PropertyOffset offset) { checkOffset(offset); - return offset < inlineStorageCapacity; + return offset < firstOutOfLineOffset; } inline bool isOutOfLineOffset(PropertyOffset offset) @@ -136,28 +132,24 @@ inline size_t numberOfOutOfLineSlotsForLastOffset(PropertyOffset offset) return offset - firstOutOfLineOffset + 1; } -inline size_t numberOfSlotsForLastOffset(PropertyOffset offset, JSType type) +inline size_t numberOfSlotsForLastOffset(PropertyOffset offset, PropertyOffset inlineCapacity) { - checkOffset(offset, type); - if (type == FinalObjectType) + checkOffset(offset, inlineCapacity); + if (offset < inlineCapacity) return offset + 1; - return numberOfOutOfLineSlotsForLastOffset(offset); + return inlineCapacity + numberOfOutOfLineSlotsForLastOffset(offset); } -inline PropertyOffset nextPropertyOffsetFor(PropertyOffset offset, JSType type) +inline PropertyOffset propertyOffsetFor(PropertyOffset propertyNumber, PropertyOffset inlineCapacity) { - checkOffset(offset, type); - if (type != FinalObjectType && offset == invalidOffset) - return firstOutOfLineOffset; - return offset + 1; -} - -inline PropertyOffset firstPropertyOffsetFor(JSType type) -{ - return nextPropertyOffsetFor(invalidOffset, type); + PropertyOffset offset = propertyNumber; + if (offset >= inlineCapacity) { + offset += firstOutOfLineOffset; + offset -= inlineCapacity; + } + return offset; } } // namespace JSC #endif // PropertyOffset_h - diff --git a/Source/JavaScriptCore/runtime/RegExp.h b/Source/JavaScriptCore/runtime/RegExp.h index 287444b95..b2b65d90c 100644 --- a/Source/JavaScriptCore/runtime/RegExp.h +++ b/Source/JavaScriptCore/runtime/RegExp.h @@ -47,6 +47,8 @@ namespace JSC { typedef JSCell Base; JS_EXPORT_PRIVATE static RegExp* create(JSGlobalData&, const String& pattern, RegExpFlags); + static const bool needsDestruction = true; + static const bool hasImmortalStructure = true; static void destroy(JSCell*); bool global() const { return m_flags & FlagGlobal; } diff --git a/Source/JavaScriptCore/runtime/RegExpCache.cpp b/Source/JavaScriptCore/runtime/RegExpCache.cpp index c67dab8e6..8acafba23 100644 --- a/Source/JavaScriptCore/runtime/RegExpCache.cpp +++ b/Source/JavaScriptCore/runtime/RegExpCache.cpp @@ -80,7 +80,7 @@ void RegExpCache::invalidateCode() RegExpCacheMap::iterator end = m_weakCache.end(); for (RegExpCacheMap::iterator it = m_weakCache.begin(); it != end; ++it) { - RegExp* regExp = it->second.get(); + RegExp* regExp = it->value.get(); if (!regExp) // Skip zombies. continue; regExp->invalidateCode(); diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp index b8c4cd0b3..cc6ceb1d1 100644 --- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp +++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp @@ -53,8 +53,6 @@ static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValue); namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(RegExpConstructor); - const ClassInfo RegExpConstructor::s_info = { "Function", &InternalFunction::s_info, 0, ExecState::regExpConstructorTable, CREATE_METHOD_TABLE(RegExpConstructor) }; /* Source for RegExpConstructor.lut.h diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp index 04fea60e8..ce9c2d2db 100644 --- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp +++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp @@ -30,8 +30,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(RegExpMatchesArray); - const ClassInfo RegExpMatchesArray::s_info = {"Array", &JSArray::s_info, 0, 0, CREATE_METHOD_TABLE(RegExpMatchesArray)}; RegExpMatchesArray::RegExpMatchesArray(JSGlobalData& globalData, Butterfly* butterfly, JSGlobalObject* globalObject, JSString* input, RegExp* regExp, MatchResult result) diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp index bed44f22c..dfbf533f7 100644 --- a/Source/JavaScriptCore/runtime/RegExpObject.cpp +++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp @@ -49,9 +49,9 @@ static JSValue regExpObjectSource(ExecState*, JSValue, PropertyName); namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(RegExpObject); +ASSERT_HAS_TRIVIAL_DESTRUCTOR(RegExpObject); -const ClassInfo RegExpObject::s_info = { "RegExp", &JSNonFinalObject::s_info, 0, ExecState::regExpTable, CREATE_METHOD_TABLE(RegExpObject) }; +const ClassInfo RegExpObject::s_info = { "RegExp", &Base::s_info, 0, ExecState::regExpTable, CREATE_METHOD_TABLE(RegExpObject) }; /* Source for RegExpObject.lut.h @begin regExpTable diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp index 3c742a0d3..e4bf2cf9a 100644 --- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp +++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp @@ -59,8 +59,6 @@ const ClassInfo RegExpPrototype::s_info = { "RegExp", &RegExpObject::s_info, 0, @end */ -ASSERT_CLASS_FITS_IN_CELL(RegExpPrototype); - RegExpPrototype::RegExpPrototype(JSGlobalObject* globalObject, Structure* structure, RegExp* regExp) : RegExpObject(globalObject, structure, regExp) { diff --git a/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp b/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp index b9ba25735..7f21e2c9f 100644 --- a/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp +++ b/Source/JavaScriptCore/runtime/SparseArrayValueMap.cpp @@ -88,7 +88,7 @@ SparseArrayValueMap::AddResult SparseArrayValueMap::add(JSObject* array, unsigne void SparseArrayValueMap::putEntry(ExecState* exec, JSObject* array, unsigned i, JSValue value, bool shouldThrow) { AddResult result = add(array, i); - SparseArrayEntry& entry = result.iterator->second; + SparseArrayEntry& entry = result.iterator->value; // To save a separate find & add, we first always add to the sparse map. // In the uncommon case that this is a new property, and the array is not @@ -106,7 +106,7 @@ void SparseArrayValueMap::putEntry(ExecState* exec, JSObject* array, unsigned i, bool SparseArrayValueMap::putDirect(ExecState* exec, JSObject* array, unsigned i, JSValue value, unsigned attributes, PutDirectIndexMode mode) { AddResult result = add(array, i); - SparseArrayEntry& entry = result.iterator->second; + SparseArrayEntry& entry = result.iterator->value; // To save a separate find & add, we first always add to the sparse map. // In the uncommon case that this is a new property, and the array is not @@ -207,7 +207,7 @@ void SparseArrayValueMap::visitChildren(JSCell* thisObject, SlotVisitor& visitor SparseArrayValueMap* thisMap = jsCast<SparseArrayValueMap*>(thisObject); iterator end = thisMap->m_map.end(); for (iterator it = thisMap->m_map.begin(); it != end; ++it) - visitor.append(&it->second); + visitor.append(&it->value); } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/SparseArrayValueMap.h b/Source/JavaScriptCore/runtime/SparseArrayValueMap.h index 5d8d0577a..366a7b8ba 100644 --- a/Source/JavaScriptCore/runtime/SparseArrayValueMap.h +++ b/Source/JavaScriptCore/runtime/SparseArrayValueMap.h @@ -81,6 +81,8 @@ public: static SparseArrayValueMap* create(JSGlobalData&); + static const bool needsDestruction = true; + static const bool hasImmortalStructure = true; static void destroy(JSCell*); static Structure* createStructure(JSGlobalData&, JSGlobalObject*, JSValue prototype); diff --git a/Source/JavaScriptCore/runtime/StringConstructor.cpp b/Source/JavaScriptCore/runtime/StringConstructor.cpp index 460343761..7f36a84be 100644 --- a/Source/JavaScriptCore/runtime/StringConstructor.cpp +++ b/Source/JavaScriptCore/runtime/StringConstructor.cpp @@ -45,7 +45,6 @@ const ClassInfo StringConstructor::s_info = { "Function", &InternalFunction::s_i @end */ -ASSERT_CLASS_FITS_IN_CELL(StringConstructor); ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringConstructor); StringConstructor::StringConstructor(JSGlobalObject* globalObject, Structure* structure) diff --git a/Source/JavaScriptCore/runtime/StringObject.cpp b/Source/JavaScriptCore/runtime/StringObject.cpp index 15900913d..ab7d6cb23 100644 --- a/Source/JavaScriptCore/runtime/StringObject.cpp +++ b/Source/JavaScriptCore/runtime/StringObject.cpp @@ -27,7 +27,6 @@ namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(StringObject); ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringObject); const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringObject) }; diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp index 8daa0f335..1540177be 100644 --- a/Source/JavaScriptCore/runtime/StringPrototype.cpp +++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp @@ -47,7 +47,6 @@ using namespace WTF; namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(StringPrototype); ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringPrototype); static EncodedJSValue JSC_HOST_CALL stringProtoFuncToString(ExecState*); diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp index a59a0860d..a931def27 100644 --- a/Source/JavaScriptCore/runtime/Structure.cpp +++ b/Source/JavaScriptCore/runtime/Structure.cpp @@ -149,7 +149,7 @@ void Structure::dumpStatistics() #endif } -Structure::Structure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType) +Structure::Structure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, PropertyOffset inlineCapacity) : JSCell(globalData, globalData.structureStructure.get()) , m_typeInfo(typeInfo) , m_indexingType(indexingType) @@ -158,6 +158,7 @@ Structure::Structure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSV , m_classInfo(classInfo) , m_transitionWatchpointSet(InitializedWatching) , m_outOfLineCapacity(0) + , m_inlineCapacity(inlineCapacity) , m_offset(invalidOffset) , m_dictionaryKind(NoneDictionaryKind) , m_isPinnedPropertyTable(false) @@ -182,6 +183,7 @@ Structure::Structure(JSGlobalData& globalData) , m_classInfo(&s_info) , m_transitionWatchpointSet(InitializedWatching) , m_outOfLineCapacity(0) + , m_inlineCapacity(0) , m_offset(invalidOffset) , m_dictionaryKind(NoneDictionaryKind) , m_isPinnedPropertyTable(false) @@ -204,6 +206,7 @@ Structure::Structure(JSGlobalData& globalData, const Structure* previous) , m_classInfo(previous->m_classInfo) , m_transitionWatchpointSet(InitializedWatching) , m_outOfLineCapacity(previous->m_outOfLineCapacity) + , m_inlineCapacity(previous->m_inlineCapacity) , m_offset(invalidOffset) , m_dictionaryKind(previous->m_dictionaryKind) , m_isPinnedPropertyTable(false) @@ -323,11 +326,15 @@ bool Structure::anyObjectInChainMayInterceptIndexedAccesses() const } } -NonPropertyTransition Structure::suggestedIndexingTransition() const +bool Structure::needsSlowPutIndexing() const { - ASSERT(!hasIndexedProperties(indexingType())); - - if (anyObjectInChainMayInterceptIndexedAccesses() || globalObject()->isHavingABadTime()) + return anyObjectInChainMayInterceptIndexedAccesses() + || globalObject()->isHavingABadTime(); +} + +NonPropertyTransition Structure::suggestedArrayStorageTransition() const +{ + if (needsSlowPutIndexing()) return AllocateSlowPutArrayStorage; return AllocateArrayStorage; @@ -546,6 +553,7 @@ Structure* Structure::nonPropertyTransition(JSGlobalData& globalData, Structure* transition->m_previous.set(globalData, transition, structure); transition->m_attributesInPrevious = attributes; transition->m_indexingType = indexingType; + transition->m_offset = structure->m_offset; if (structure->m_propertyTable) { if (structure->m_isPinnedPropertyTable) @@ -608,20 +616,21 @@ Structure* Structure::flattenDictionaryStructure(JSGlobalData& globalData, JSObj ASSERT(m_propertyTable); size_t propertyCount = m_propertyTable->size(); + + // Holds our values compacted by insertion order. Vector<JSValue> values(propertyCount); - + + // Copies out our values from their hashed locations, compacting property table offsets as we go. unsigned i = 0; - PropertyOffset firstOffset = firstPropertyOffsetFor(m_typeInfo.type()); PropertyTable::iterator end = m_propertyTable->end(); for (PropertyTable::iterator iter = m_propertyTable->begin(); iter != end; ++iter, ++i) { values[i] = object->getDirectOffset(iter->offset); - // Update property table to have the new property offsets - iter->offset = i + firstOffset; + iter->offset = propertyOffsetFor(i, m_inlineCapacity); } - // Copy the original property values into their final locations + // Copies in our values to their compacted locations. for (unsigned i = 0; i < propertyCount; i++) - object->putDirectOffset(globalData, firstOffset + i, values[i]); + object->putDirectOffset(globalData, propertyOffsetFor(i, m_inlineCapacity), values[i]); m_propertyTable->clearDeletedOffsets(); } @@ -759,7 +768,7 @@ PropertyOffset Structure::putSpecificValue(JSGlobalData& globalData, PropertyNam if (!m_propertyTable) createPropertyMap(); - PropertyOffset newOffset = m_propertyTable->nextOffset(m_typeInfo.type()); + PropertyOffset newOffset = m_propertyTable->nextOffset(m_inlineCapacity); m_propertyTable->add(PropertyMapEntry(globalData, this, rep, newOffset, attributes, specificValue)); diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h index e77287b20..f45e9f1d9 100644 --- a/Source/JavaScriptCore/runtime/Structure.h +++ b/Source/JavaScriptCore/runtime/Structure.h @@ -69,7 +69,7 @@ namespace JSC { typedef JSCell Base; - static Structure* create(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = 0); + static Structure* create(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = NonArray, PropertyOffset inlineCapacity = 0); protected: void finishCreation(JSGlobalData& globalData) @@ -128,6 +128,8 @@ namespace JSC { Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*); + static const bool needsDestruction = true; + static const bool hasImmortalStructure = true; static void destroy(JSCell*); // These should be used with caution. @@ -152,7 +154,8 @@ namespace JSC { bool anyObjectInChainMayInterceptIndexedAccesses() const; - NonPropertyTransition suggestedIndexingTransition() const; + bool needsSlowPutIndexing() const; + NonPropertyTransition suggestedArrayStorageTransition() const; JSGlobalObject* globalObject() const { return m_globalObject.get(); } void setGlobalObject(JSGlobalData& globalData, JSGlobalObject* globalObject) { m_globalObject.set(globalData, this, globalObject); } @@ -177,24 +180,6 @@ namespace JSC { ASSERT(structure()->classInfo() == &s_info); return m_outOfLineCapacity; } - unsigned outOfLineSizeForKnownFinalObject() const - { - ASSERT(m_typeInfo.type() == FinalObjectType); - if (m_propertyTable) { - unsigned totalSize = m_propertyTable->propertyStorageSize(); - if (totalSize < static_cast<unsigned>(inlineStorageCapacity)) - return 0; - return totalSize - inlineStorageCapacity; - } - return numberOfOutOfLineSlotsForLastOffset(m_offset); - } - unsigned outOfLineSizeForKnownNonFinalObject() const - { - ASSERT(m_typeInfo.type() != FinalObjectType); - if (m_propertyTable) - return m_propertyTable->propertyStorageSize(); - return numberOfOutOfLineSlotsForLastOffset(m_offset); - } unsigned outOfLineSize() const { ASSERT(structure()->classInfo() == &s_info); @@ -209,31 +194,20 @@ namespace JSC { } bool hasInlineStorage() const { - return m_typeInfo.type() == FinalObjectType; + return !!m_inlineCapacity; } unsigned inlineCapacity() const { - if (hasInlineStorage()) - return inlineStorageCapacity; - return 0; + return m_inlineCapacity; } - unsigned inlineSizeForKnownFinalObject() const + unsigned inlineSize() const { - ASSERT(m_typeInfo.type() == FinalObjectType); unsigned result; if (m_propertyTable) result = m_propertyTable->propertyStorageSize(); else result = m_offset + 1; - if (result > static_cast<unsigned>(inlineStorageCapacity)) - return inlineStorageCapacity; - return result; - } - unsigned inlineSize() const - { - if (!hasInlineStorage()) - return 0; - return inlineSizeForKnownFinalObject(); + return std::min<unsigned>(result, m_inlineCapacity); } unsigned totalStorageSize() const { @@ -251,16 +225,12 @@ namespace JSC { { if (hasInlineStorage()) return 0; - return inlineStorageCapacity; + return firstOutOfLineOffset; } PropertyOffset lastValidOffset() const { - if (m_propertyTable) { - PropertyOffset size = m_propertyTable->propertyStorageSize(); - if (!hasInlineStorage()) - size += inlineStorageCapacity; - return size - 1; - } + if (m_propertyTable) + return propertyOffsetFor(m_propertyTable->propertyStorageSize() - 1, m_inlineCapacity); return m_offset; } bool isValidOffset(PropertyOffset offset) const @@ -381,7 +351,7 @@ namespace JSC { private: friend class LLIntOffsetsExtractor; - JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType = 0); + JS_EXPORT_PRIVATE Structure(JSGlobalData&, JSGlobalObject*, JSValue prototype, const TypeInfo&, const ClassInfo*, IndexingType, PropertyOffset inlineCapacity); Structure(JSGlobalData&); Structure(JSGlobalData&, const Structure*); @@ -457,6 +427,8 @@ namespace JSC { mutable InlineWatchpointSet m_transitionWatchpointSet; uint32_t m_outOfLineCapacity; + uint8_t m_inlineCapacity; + COMPILE_ASSERT(firstOutOfLineOffset < 256, firstOutOfLineOffset_fits); // m_offset does not account for anonymous slots PropertyOffset m_offset; @@ -473,22 +445,11 @@ namespace JSC { unsigned m_staticFunctionReified; }; - template <> inline void* allocateCell<Structure>(Heap& heap) - { -#if ENABLE(GC_VALIDATION) - ASSERT(!heap.globalData()->isInitializingObject()); - heap.globalData()->setInitializingObjectClass(&Structure::s_info); -#endif - JSCell* result = static_cast<JSCell*>(heap.allocateStructure(sizeof(Structure))); - result->clearStructure(); - return result; - } - - inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType) + inline Structure* Structure::create(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, PropertyOffset inlineCapacity) { ASSERT(globalData.structureStructure); ASSERT(classInfo); - Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, globalObject, prototype, typeInfo, classInfo, indexingType); + Structure* structure = new (NotNull, allocateCell<Structure>(globalData.heap)) Structure(globalData, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity); structure->finishCreation(globalData); return structure; } @@ -628,15 +589,6 @@ namespace JSC { ASSERT(m_structure || !globalData.structureStructure); } - inline const ClassInfo* JSCell::classInfo() const - { -#if ENABLE(GC_VALIDATION) - return m_structure.unvalidatedGet()->classInfo(); -#else - return m_structure->classInfo(); -#endif - } - } // namespace JSC #endif // Structure_h diff --git a/Source/JavaScriptCore/runtime/StructureChain.h b/Source/JavaScriptCore/runtime/StructureChain.h index 3b19d4cf1..878f606b4 100644 --- a/Source/JavaScriptCore/runtime/StructureChain.h +++ b/Source/JavaScriptCore/runtime/StructureChain.h @@ -59,6 +59,10 @@ namespace JSC { static ClassInfo s_info; + static const bool needsDestruction = true; + static const bool hasImmortalStructure = true; + static void destroy(JSCell*); + protected: void finishCreation(JSGlobalData& globalData, Structure* head) { @@ -78,7 +82,6 @@ namespace JSC { friend class LLIntOffsetsExtractor; StructureChain(JSGlobalData&, Structure*); - static void destroy(JSCell*); OwnArrayPtr<WriteBarrier<Structure> > m_vector; }; diff --git a/Source/JavaScriptCore/runtime/StructureTransitionTable.h b/Source/JavaScriptCore/runtime/StructureTransitionTable.h index 90cb6a4db..3ab7b2014 100644 --- a/Source/JavaScriptCore/runtime/StructureTransitionTable.h +++ b/Source/JavaScriptCore/runtime/StructureTransitionTable.h @@ -43,6 +43,7 @@ static const unsigned FirstInternalAttribute = 1 << 6; // Use for transitions th // Support for attributes used to indicate transitions not related to properties. // If any of these are used, the string portion of the key should be 0. enum NonPropertyTransition { + AllocateContiguous, AllocateArrayStorage, AllocateSlowPutArrayStorage, SwitchToSlowPutArrayStorage, @@ -57,13 +58,18 @@ inline unsigned toAttributes(NonPropertyTransition transition) inline IndexingType newIndexingType(IndexingType oldType, NonPropertyTransition transition) { switch (transition) { + case AllocateContiguous: + ASSERT(!hasIndexedProperties(oldType)); + return oldType | ContiguousShape; case AllocateArrayStorage: - return oldType | HasArrayStorage; + ASSERT(!hasIndexedProperties(oldType) || hasContiguous(oldType)); + return (oldType & ~IndexingShapeMask) | ArrayStorageShape; case AllocateSlowPutArrayStorage: - return oldType | HasSlowPutArrayStorage; + ASSERT(!hasIndexedProperties(oldType) || hasContiguous(oldType)); + return (oldType & ~IndexingShapeMask) | SlowPutArrayStorageShape; case SwitchToSlowPutArrayStorage: - ASSERT(oldType & HasArrayStorage); - return (oldType & ~HasArrayStorage) | HasSlowPutArrayStorage; + ASSERT(hasFastArrayStorage(oldType)); + return (oldType & ~IndexingShapeMask) | SlowPutArrayStorageShape; case AddIndexedAccessors: return oldType | MayHaveIndexedAccessors; default: diff --git a/Source/JavaScriptCore/runtime/SymbolTable.h b/Source/JavaScriptCore/runtime/SymbolTable.h index 6063dbab4..debb76499 100644 --- a/Source/JavaScriptCore/runtime/SymbolTable.h +++ b/Source/JavaScriptCore/runtime/SymbolTable.h @@ -344,12 +344,16 @@ namespace JSC { class SharedSymbolTable : public JSCell, public SymbolTable { public: + typedef JSCell Base; + static SharedSymbolTable* create(JSGlobalData& globalData) { SharedSymbolTable* sharedSymbolTable = new (NotNull, allocateCell<SharedSymbolTable>(globalData.heap)) SharedSymbolTable(globalData); sharedSymbolTable->finishCreation(globalData); return sharedSymbolTable; } + static const bool needsDestruction = true; + static const bool hasImmortalStructure = true; static void destroy(JSCell*); static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) @@ -396,6 +400,7 @@ namespace JSC { OwnArrayPtr<SlowArgument> m_slowArguments; }; + } // namespace JSC #endif // SymbolTable_h diff --git a/Source/JavaScriptCore/runtime/TypedArrayDescriptor.h b/Source/JavaScriptCore/runtime/TypedArrayDescriptor.h new file mode 100644 index 000000000..1ae4818be --- /dev/null +++ b/Source/JavaScriptCore/runtime/TypedArrayDescriptor.h @@ -0,0 +1,76 @@ +/* + * 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 TypedArrayDescriptor_h +#define TypedArrayDescriptor_h + +namespace JSC { + +struct ClassInfo; + +enum TypedArrayType { + TypedArrayNone, + TypedArrayInt8, + TypedArrayInt16, + TypedArrayInt32, + TypedArrayUint8, + TypedArrayUint8Clamped, + TypedArrayUint16, + TypedArrayUint32, + TypedArrayFloat32, + TypedArrayFloat64 +}; + +struct TypedArrayDescriptor { + TypedArrayDescriptor() + : m_classInfo(0) + , m_storageOffset(0) + , m_lengthOffset(0) + { + } + TypedArrayDescriptor(const ClassInfo* classInfo, size_t storageOffset, size_t lengthOffset) + : m_classInfo(classInfo) + , m_storageOffset(storageOffset) + , m_lengthOffset(lengthOffset) + { + } + const ClassInfo* m_classInfo; + size_t m_storageOffset; + size_t m_lengthOffset; +}; + +enum TypedArraySignedness { + SignedTypedArray, + UnsignedTypedArray +}; +enum TypedArrayRounding { + TruncateRounding, + ClampRounding +}; + +} // namespace JSC + +#endif // TypedArrayDescriptor_h + diff --git a/Source/JavaScriptCore/runtime/WeakGCMap.h b/Source/JavaScriptCore/runtime/WeakGCMap.h index 6926165a7..52e5e2946 100644 --- a/Source/JavaScriptCore/runtime/WeakGCMap.h +++ b/Source/JavaScriptCore/runtime/WeakGCMap.h @@ -63,7 +63,7 @@ public: { typename MapType::iterator end = m_map.end(); for (typename MapType::iterator ptr = m_map.begin(); ptr != end; ++ptr) - WeakSet::deallocate(ptr->second); + WeakSet::deallocate(ptr->value); m_map.clear(); } @@ -80,8 +80,8 @@ public: ASSERT_UNUSED(globalData, globalData.apiLock().currentThreadIsHoldingLock()); typename MapType::AddResult result = m_map.add(key, 0); if (!result.isNewEntry) - WeakSet::deallocate(result.iterator->second); - result.iterator->second = WeakSet::allocate(value, this, FinalizerCallback::finalizerContextFor(key)); + WeakSet::deallocate(result.iterator->value); + result.iterator->value = WeakSet::allocate(value, this, FinalizerCallback::finalizerContextFor(key)); } void remove(const KeyType& key) diff --git a/Source/JavaScriptCore/shell/CMakeLists.txt b/Source/JavaScriptCore/shell/CMakeLists.txt index 71b8963cc..d1b4abf52 100644 --- a/Source/JavaScriptCore/shell/CMakeLists.txt +++ b/Source/JavaScriptCore/shell/CMakeLists.txt @@ -7,6 +7,10 @@ SET(JSC_LIBRARIES ${JavaScriptCore_LIBRARY_NAME} ) +IF ("${JavaScriptCore_LIBRARY_TYPE}" MATCHES "STATIC") + ADD_DEFINITIONS(-DSTATICALLY_LINKED_WITH_JavaScriptCore) +ENDIF () + WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS() WEBKIT_WRAP_SOURCELIST(${JSC_SOURCES}) diff --git a/Source/JavaScriptCore/testRegExp.cpp b/Source/JavaScriptCore/testRegExp.cpp index b0b126f1c..60e6c4650 100644 --- a/Source/JavaScriptCore/testRegExp.cpp +++ b/Source/JavaScriptCore/testRegExp.cpp @@ -115,11 +115,15 @@ public: static GlobalObject* create(JSGlobalData& globalData, Structure* structure, const Vector<String>& arguments) { - return new (NotNull, allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure, arguments); + GlobalObject* globalObject = new (NotNull, allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure, arguments); + globalData.heap.addFinalizer(globalObject, destroy); + return globalObject; } static const ClassInfo s_info; + static const bool needsDestructor = false; + static Structure* createStructure(JSGlobalData& globalData, JSValue prototype) { return Structure::create(globalData, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info); @@ -134,7 +138,6 @@ protected: }; COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false); -ASSERT_CLASS_FITS_IN_CELL(GlobalObject); const ClassInfo GlobalObject::s_info = { "global", &JSGlobalObject::s_info, 0, ExecState::globalObjectTable, CREATE_METHOD_TABLE(GlobalObject) }; diff --git a/Source/JavaScriptCore/tools/ProfileTreeNode.h b/Source/JavaScriptCore/tools/ProfileTreeNode.h index 7b51efb85..7b5a95ec4 100644 --- a/Source/JavaScriptCore/tools/ProfileTreeNode.h +++ b/Source/JavaScriptCore/tools/ProfileTreeNode.h @@ -51,7 +51,7 @@ public: ProfileTreeNode newEntry; Map::AddResult result = m_children->add(String(name), newEntry); - ProfileTreeNode* childInMap = &result.iterator->second; + ProfileTreeNode* childInMap = &result.iterator->value; ++childInMap->m_count; return childInMap; } @@ -72,7 +72,7 @@ public: return 0; uint64_t childCount = 0; for (Map::iterator it = m_children->begin(); it != m_children->end(); ++it) - childCount += it->second.count(); + childCount += it->value.count(); return childCount; } @@ -97,19 +97,19 @@ private: for (unsigned i = 0; i < indent; ++i) dataLog(" "); dataLog("% 8lld: %s (%lld stack top)\n", - static_cast<long long>(entry->second.count()), - entry->first.utf8().data(), - static_cast<long long>(entry->second.count() - entry->second.childCount())); + static_cast<long long>(entry->value.count()), + entry->key.utf8().data(), + static_cast<long long>(entry->value.count() - entry->value.childCount())); // Recursively dump the child nodes. - entry->second.dumpInternal(indent + 1); + entry->value.dumpInternal(indent + 1); } } static int compareEntries(const void* a, const void* b) { - uint64_t da = (*static_cast<MapEntry* const *>(a))->second.count(); - uint64_t db = (*static_cast<MapEntry* const *>(b))->second.count(); + uint64_t da = (*static_cast<MapEntry* const *>(a))->value.count(); + uint64_t db = (*static_cast<MapEntry* const *>(b))->value.count(); return (da < db) - (da > db); } |