Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (201444 => 201445)
--- trunk/Source/_javascript_Core/ChangeLog 2016-05-27 03:19:20 UTC (rev 201444)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-05-27 03:31:18 UTC (rev 201445)
@@ -1,3 +1,18 @@
+2016-05-26 Commit Queue <[email protected]>
+
+ Unreviewed, rolling out r201436.
+ https://bugs.webkit.org/show_bug.cgi?id=158143
+
+ Caused 30% regression on Dromaeo DOM core tests (Requested by
+ rniwa on #webkit).
+
+ Reverted changeset:
+
+ "REGRESSION: JSBench spends a lot of time transitioning
+ to/from dictionary"
+ https://bugs.webkit.org/show_bug.cgi?id=158045
+ http://trac.webkit.org/changeset/201436
+
2016-05-26 Geoffrey Garen <[email protected]>
REGRESSION: JSBench spends a lot of time transitioning to/from dictionary
Modified: trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp (201444 => 201445)
--- trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp 2016-05-27 03:19:20 UTC (rev 201444)
+++ trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp 2016-05-27 03:31:18 UTC (rev 201445)
@@ -263,13 +263,10 @@
JSObject* object = jsCast<JSObject*>(value);
structure = object->structure(vm);
+ // Since we're accessing a prototype repeatedly, it's a good bet that it should not be
+ // treated as a dictionary.
if (structure->isDictionary()) {
if (concurrency == MainThread) {
- if (structure->hasBeenFlattenedBefore()) {
- if (verbose)
- dataLog("Dictionary has been flattened before, so invalid.\n");
- return ObjectPropertyConditionSet::invalid();
- }
if (verbose)
dataLog("Flattening ", pointerDump(structure));
structure->flattenDictionaryStructure(vm, object);
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (201444 => 201445)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2016-05-27 03:19:20 UTC (rev 201444)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2016-05-27 03:31:18 UTC (rev 201445)
@@ -938,9 +938,6 @@
if (UNLIKELY(vm.shouldTriggerTermination(callFrame)))
return throwTerminatedExecutionException(callFrame);
- if (scope->structure()->isUncacheableDictionary())
- scope->flattenDictionaryObject(vm);
-
ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
ProtoCallFrame protoCallFrame;
@@ -1189,9 +1186,6 @@
}
}
- if (variableObject->structure()->isUncacheableDictionary())
- variableObject->flattenDictionaryObject(vm);
-
if (numVariables || numFunctions) {
BatchedTransitionOptimizer optimizer(vm, variableObject);
if (variableObject->next())
@@ -1249,9 +1243,6 @@
if (UNLIKELY(vm.shouldTriggerTermination(callFrame)))
return throwTerminatedExecutionException(callFrame);
- if (scope->structure()->isUncacheableDictionary())
- scope->flattenDictionaryObject(vm);
-
ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
// The |this| of the module is always `undefined`.
Modified: trunk/Source/_javascript_Core/runtime/BatchedTransitionOptimizer.h (201444 => 201445)
--- trunk/Source/_javascript_Core/runtime/BatchedTransitionOptimizer.h 2016-05-27 03:19:20 UTC (rev 201444)
+++ trunk/Source/_javascript_Core/runtime/BatchedTransitionOptimizer.h 2016-05-27 03:31:18 UTC (rev 201445)
@@ -35,10 +35,22 @@
WTF_MAKE_NONCOPYABLE(BatchedTransitionOptimizer);
public:
BatchedTransitionOptimizer(VM& vm, JSObject* object)
+ : m_vm(&vm)
+ , m_object(object)
{
- if (!object->structure(vm)->isDictionary())
- object->convertToDictionary(vm);
+ if (!m_object->structure(vm)->isDictionary())
+ m_object->convertToDictionary(vm);
}
+
+ ~BatchedTransitionOptimizer()
+ {
+ if (m_object->structure()->isDictionary())
+ m_object->flattenDictionaryObject(*m_vm);
+ }
+
+private:
+ VM* m_vm;
+ JSObject* m_object;
};
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (201444 => 201445)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2016-05-27 03:19:20 UTC (rev 201444)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2016-05-27 03:31:18 UTC (rev 201445)
@@ -319,8 +319,6 @@
{
ASSERT(vm.currentThreadIsHoldingAPILock());
- Base::setStructure(vm, Structure::toCacheableDictionaryTransition(vm, structure()));
-
JSGlobalObject::globalExec()->init(0, 0, CallFrame::noCaller(), 0, 0);
m_debugger = 0;
Modified: trunk/Source/_javascript_Core/runtime/Operations.cpp (201444 => 201445)
--- trunk/Source/_javascript_Core/runtime/Operations.cpp 2016-05-27 03:19:20 UTC (rev 201444)
+++ trunk/Source/_javascript_Core/runtime/Operations.cpp 2016-05-27 03:31:18 UTC (rev 201445)
@@ -120,27 +120,4 @@
return false;
}
-size_t normalizePrototypeChain(CallFrame* callFrame, Structure* structure)
-{
- VM& vm = callFrame->vm();
- size_t count = 0;
- while (1) {
- if (structure->isProxy())
- return InvalidPrototypeChain;
- JSValue v = structure->prototypeForLookup(callFrame);
- if (v.isNull())
- return count;
-
- JSCell* base = v.asCell();
- structure = base->structure(vm);
- if (structure->isDictionary()) {
- if (structure->hasBeenFlattenedBefore())
- return InvalidPrototypeChain;
- structure->flattenDictionaryStructure(vm, asObject(base));
- }
-
- ++count;
- }
-}
-
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/Operations.h (201444 => 201445)
--- trunk/Source/_javascript_Core/runtime/Operations.h 2016-05-27 03:19:20 UTC (rev 201444)
+++ trunk/Source/_javascript_Core/runtime/Operations.h 2016-05-27 03:31:18 UTC (rev 201445)
@@ -28,14 +28,11 @@
namespace JSC {
-#define InvalidPrototypeChain (std::numeric_limits<size_t>::max())
-
NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
JSValue jsTypeStringForValue(CallFrame*, JSValue);
JSValue jsTypeStringForValue(VM&, JSGlobalObject*, JSValue);
bool jsIsObjectTypeOrNull(CallFrame*, JSValue);
bool jsIsFunctionType(JSValue);
-size_t normalizePrototypeChain(CallFrame*, Structure*);
ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
{
@@ -195,6 +192,30 @@
return jsAddSlowCase(callFrame, v1, v2);
}
+#define InvalidPrototypeChain (std::numeric_limits<size_t>::max())
+
+inline size_t normalizePrototypeChain(CallFrame* callFrame, Structure* structure)
+{
+ VM& vm = callFrame->vm();
+ size_t count = 0;
+ while (1) {
+ if (structure->isProxy())
+ return InvalidPrototypeChain;
+ JSValue v = structure->prototypeForLookup(callFrame);
+ if (v.isNull())
+ return count;
+
+ JSCell* base = v.asCell();
+ structure = base->structure(vm);
+ // Since we're accessing a prototype in a loop, it's a good bet that it
+ // should not be treated as a dictionary.
+ if (structure->isDictionary())
+ structure->flattenDictionaryStructure(vm, asObject(base));
+
+ ++count;
+ }
+}
+
} // namespace JSC
#endif // Operations_h