Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (201572 => 201573)
--- trunk/Source/_javascript_Core/ChangeLog 2016-06-01 21:43:52 UTC (rev 201572)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-06-01 22:22:04 UTC (rev 201573)
@@ -1,3 +1,18 @@
+2016-06-01 Geoffrey Garen <[email protected]>
+
+ Unreviewed, rolling in r201436.
+ https://bugs.webkit.org/show_bug.cgi?id=158143
+
+ r201562 should haved fixed the Dromaeo DOM core regression.
+
+ Restored 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-06-01 Commit Queue <[email protected]>
Unreviewed, rolling out r201488.
Modified: trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp (201572 => 201573)
--- trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp 2016-06-01 21:43:52 UTC (rev 201572)
+++ trunk/Source/_javascript_Core/bytecode/ObjectPropertyConditionSet.cpp 2016-06-01 22:22:04 UTC (rev 201573)
@@ -251,12 +251,18 @@
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 (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);
- else {
+ } else {
if (verbose)
dataLog("Cannot flatten dictionary when not on main thread, so invalid.\n");
return ObjectPropertyConditionSet::invalid();
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (201572 => 201573)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2016-06-01 21:43:52 UTC (rev 201572)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2016-06-01 22:22:04 UTC (rev 201573)
@@ -941,6 +941,9 @@
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,6 +1192,9 @@
}
}
+ if (variableObject->structure()->isUncacheableDictionary())
+ variableObject->flattenDictionaryObject(vm);
+
if (numVariables || numFunctions) {
BatchedTransitionOptimizer optimizer(vm, variableObject);
if (variableObject->next())
@@ -1246,6 +1252,9 @@
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 (201572 => 201573)
--- trunk/Source/_javascript_Core/runtime/BatchedTransitionOptimizer.h 2016-06-01 21:43:52 UTC (rev 201572)
+++ trunk/Source/_javascript_Core/runtime/BatchedTransitionOptimizer.h 2016-06-01 22:22:04 UTC (rev 201573)
@@ -35,22 +35,10 @@
WTF_MAKE_NONCOPYABLE(BatchedTransitionOptimizer);
public:
BatchedTransitionOptimizer(VM& vm, JSObject* object)
- : m_vm(&vm)
- , m_object(object)
{
- if (!m_object->structure(vm)->isDictionary())
- m_object->convertToDictionary(vm);
+ if (!object->structure(vm)->isDictionary())
+ 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 (201572 => 201573)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2016-06-01 21:43:52 UTC (rev 201572)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2016-06-01 22:22:04 UTC (rev 201573)
@@ -319,6 +319,8 @@
{
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 (201572 => 201573)
--- trunk/Source/_javascript_Core/runtime/Operations.cpp 2016-06-01 21:43:52 UTC (rev 201572)
+++ trunk/Source/_javascript_Core/runtime/Operations.cpp 2016-06-01 22:22:04 UTC (rev 201573)
@@ -120,4 +120,27 @@
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 (201572 => 201573)
--- trunk/Source/_javascript_Core/runtime/Operations.h 2016-06-01 21:43:52 UTC (rev 201572)
+++ trunk/Source/_javascript_Core/runtime/Operations.h 2016-06-01 22:22:04 UTC (rev 201573)
@@ -28,11 +28,14 @@
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)
{
@@ -192,30 +195,6 @@
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