Title: [153381] trunk
Revision
153381
Author
[email protected]
Date
2013-07-26 14:12:30 -0700 (Fri, 26 Jul 2013)

Log Message

REGRESSION: Crash when opening a message on Gmail
https://bugs.webkit.org/show_bug.cgi?id=119105

Source/_javascript_Core: 

Reviewed by Oliver Hunt and Mark Hahnenberg.
        
- GetById patching in the DFG needs to be more disciplined about how it derives the
  slow path.
        
- Fix some dumping code thread safety issues.

* bytecode/CallLinkStatus.cpp:
(JSC::CallLinkStatus::dump):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* dfg/DFGRepatch.cpp:
(JSC::DFG::getPolymorphicStructureList):
(JSC::DFG::tryBuildGetByIDList):

LayoutTests: 

Reviewed by Oliver Hunt and Mark Hahnenberg.

* fast/js/dfg-get-by-id-unset-then-proto-less-warmup.html: Added.
* fast/js/dfg-get-by-id-unset-then-proto-more-warmup.html: Added.
* fast/js/dfg-get-by-id-unset-then-proto.html: Added.
* fast/js/jsc-test-list
* fast/js/script-tests/dfg-get-by-id-unset-then-proto-less-warmup.js: Added.
(foo):
(Blah):
* fast/js/script-tests/dfg-get-by-id-unset-then-proto-more-warmup.js: Added.
(foo):
(Blah):
* fast/js/script-tests/dfg-get-by-id-unset-then-proto.js: Added.
(foo):
(Blah):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (153380 => 153381)


--- trunk/LayoutTests/ChangeLog	2013-07-26 20:41:32 UTC (rev 153380)
+++ trunk/LayoutTests/ChangeLog	2013-07-26 21:12:30 UTC (rev 153381)
@@ -1,3 +1,24 @@
+2013-07-26  Filip Pizlo  <[email protected]>
+
+        REGRESSION: Crash when opening a message on Gmail
+        https://bugs.webkit.org/show_bug.cgi?id=119105
+
+        Reviewed by Oliver Hunt and Mark Hahnenberg.
+
+        * fast/js/dfg-get-by-id-unset-then-proto-less-warmup.html: Added.
+        * fast/js/dfg-get-by-id-unset-then-proto-more-warmup.html: Added.
+        * fast/js/dfg-get-by-id-unset-then-proto.html: Added.
+        * fast/js/jsc-test-list
+        * fast/js/script-tests/dfg-get-by-id-unset-then-proto-less-warmup.js: Added.
+        (foo):
+        (Blah):
+        * fast/js/script-tests/dfg-get-by-id-unset-then-proto-more-warmup.js: Added.
+        (foo):
+        (Blah):
+        * fast/js/script-tests/dfg-get-by-id-unset-then-proto.js: Added.
+        (foo):
+        (Blah):
+
 2013-07-19  Mark Hahnenberg  <[email protected]>
 
         Setting a large numeric property on an object causes it to allocate a huge backing store

Added: trunk/LayoutTests/fast/js/dfg-get-by-id-unset-then-proto-less-warmup.html (0 => 153381)


--- trunk/LayoutTests/fast/js/dfg-get-by-id-unset-then-proto-less-warmup.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-get-by-id-unset-then-proto-less-warmup.html	2013-07-26 21:12:30 UTC (rev 153381)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/js/dfg-get-by-id-unset-then-proto-more-warmup.html (0 => 153381)


--- trunk/LayoutTests/fast/js/dfg-get-by-id-unset-then-proto-more-warmup.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-get-by-id-unset-then-proto-more-warmup.html	2013-07-26 21:12:30 UTC (rev 153381)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: trunk/LayoutTests/fast/js/dfg-get-by-id-unset-then-proto.html (0 => 153381)


--- trunk/LayoutTests/fast/js/dfg-get-by-id-unset-then-proto.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-get-by-id-unset-then-proto.html	2013-07-26 21:12:30 UTC (rev 153381)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/fast/js/jsc-test-list (153380 => 153381)


--- trunk/LayoutTests/fast/js/jsc-test-list	2013-07-26 20:41:32 UTC (rev 153380)
+++ trunk/LayoutTests/fast/js/jsc-test-list	2013-07-26 21:12:30 UTC (rev 153381)
@@ -142,6 +142,9 @@
 fast/js/dfg-float64array
 fast/js/dfg-flush-get-local
 fast/js/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop
+fast/js/dfg-get-by-id-unset-then-proto
+fast/js/dfg-get-by-id-unset-then-proto-less-warmup
+fast/js/dfg-get-by-id-unset-then-proto-more-warmup
 fast/js/dfg-get-by-val-clobber
 fast/js/dfg-get-by-val-getter-cse
 fast/js/dfg-getter

Added: trunk/LayoutTests/fast/js/script-tests/dfg-get-by-id-unset-then-proto-less-warmup.js (0 => 153381)


--- trunk/LayoutTests/fast/js/script-tests/dfg-get-by-id-unset-then-proto-less-warmup.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-get-by-id-unset-then-proto-less-warmup.js	2013-07-26 21:12:30 UTC (rev 153381)
@@ -0,0 +1,42 @@
+description(
+"Tests what happens when the first attempt to cache an access goes down the unset route and then subsequently it tries to cache using a proto (less warmup)."
+);
+
+function foo(p, o) {
+    if (p)
+        return o.f;
+    return 42;
+}
+
+noInline(foo);
+
+// Get foo into the LLInt
+for (var i = 0; i < 10; ++i)
+    foo(false, {});
+
+// Warm up foo()'s p=true path and make it as polymorphic as possible.
+for (var i = 0; i < 3; ++i) {
+    foo(true, {f:42});
+    foo(true, {g:1, f:23});
+}
+
+// Force compilation by going down p=false.
+while (!dfgCompiled({f:foo}))
+    foo(false, {});
+
+// Hit the unset case.
+for (var j = 0; j < 1; ++j) {
+    var o = {};
+    for (var i = 0; i < 1000; ++i)
+        o["i" + i] = i;
+    o.f = 42;
+    shouldBe("foo(true, o)", "42");
+}
+
+function Blah() {
+}
+Blah.prototype.f = 23;
+
+// Hit the prototype case.
+shouldBe("foo(true, new Blah())", "23");
+

Added: trunk/LayoutTests/fast/js/script-tests/dfg-get-by-id-unset-then-proto-more-warmup.js (0 => 153381)


--- trunk/LayoutTests/fast/js/script-tests/dfg-get-by-id-unset-then-proto-more-warmup.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-get-by-id-unset-then-proto-more-warmup.js	2013-07-26 21:12:30 UTC (rev 153381)
@@ -0,0 +1,42 @@
+description(
+"Tests what happens when the first attempt to cache an access goes down the unset route and then subsequently it tries to cache using a proto (more warmup)."
+);
+
+function foo(p, o) {
+    if (p)
+        return o.f;
+    return 42;
+}
+
+noInline(foo);
+
+// Get foo into the LLInt
+for (var i = 0; i < 10; ++i)
+    foo(false, {});
+
+// Warm up foo()'s p=true path and make it as polymorphic as possible.
+for (var i = 0; i < 3; ++i) {
+    foo(true, {f:42});
+    foo(true, {g:1, f:23});
+}
+
+// Force compilation by going down p=false.
+while (!dfgCompiled({f:foo}))
+    foo(false, {});
+
+// Hit the unset case.
+for (var j = 0; j < 3; ++j) {
+    var o = {};
+    for (var i = 0; i < 1000; ++i)
+        o["i" + i] = i;
+    o.f = 42;
+    shouldBe("foo(true, o)", "42");
+}
+
+function Blah() {
+}
+Blah.prototype.f = 23;
+
+// Hit the prototype case.
+shouldBe("foo(true, new Blah())", "23");
+

Added: trunk/LayoutTests/fast/js/script-tests/dfg-get-by-id-unset-then-proto.js (0 => 153381)


--- trunk/LayoutTests/fast/js/script-tests/dfg-get-by-id-unset-then-proto.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-get-by-id-unset-then-proto.js	2013-07-26 21:12:30 UTC (rev 153381)
@@ -0,0 +1,42 @@
+description(
+"Tests what happens when the first attempt to cache an access goes down the unset route and then subsequently it tries to cache using a proto."
+);
+
+function foo(p, o) {
+    if (p)
+        return o.f;
+    return 42;
+}
+
+noInline(foo);
+
+// Get foo into the LLInt
+for (var i = 0; i < 10; ++i)
+    foo(false, {});
+
+// Warm up foo()'s p=true path and make it as polymorphic as possible.
+for (var i = 0; i < 3; ++i) {
+    foo(true, {f:42});
+    foo(true, {g:1, f:23});
+}
+
+// Force compilation by going down p=false.
+while (!dfgCompiled({f:foo}))
+    foo(false, {});
+
+// Hit the unset case.
+for (var j = 0; j < 2; ++j) {
+    var o = {};
+    for (var i = 0; i < 1000; ++i)
+        o["i" + i] = i;
+    o.f = 42;
+    shouldBe("foo(true, o)", "42");
+}
+
+function Blah() {
+}
+Blah.prototype.f = 23;
+
+// Hit the prototype case.
+shouldBe("foo(true, new Blah())", "23");
+

Modified: trunk/Source/_javascript_Core/ChangeLog (153380 => 153381)


--- trunk/Source/_javascript_Core/ChangeLog	2013-07-26 20:41:32 UTC (rev 153380)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-07-26 21:12:30 UTC (rev 153381)
@@ -1,3 +1,23 @@
+2013-07-26  Filip Pizlo  <[email protected]>
+
+        REGRESSION: Crash when opening a message on Gmail
+        https://bugs.webkit.org/show_bug.cgi?id=119105
+
+        Reviewed by Oliver Hunt and Mark Hahnenberg.
+        
+        - GetById patching in the DFG needs to be more disciplined about how it derives the
+          slow path.
+        
+        - Fix some dumping code thread safety issues.
+
+        * bytecode/CallLinkStatus.cpp:
+        (JSC::CallLinkStatus::dump):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * dfg/DFGRepatch.cpp:
+        (JSC::DFG::getPolymorphicStructureList):
+        (JSC::DFG::tryBuildGetByIDList):
+
 2013-07-26  Balazs Kilvady  <[email protected]>
 
         [mips] Fix LLINT build for mips backend

Modified: trunk/Source/_javascript_Core/bytecode/CallLinkStatus.cpp (153380 => 153381)


--- trunk/Source/_javascript_Core/bytecode/CallLinkStatus.cpp	2013-07-26 20:41:32 UTC (rev 153380)
+++ trunk/Source/_javascript_Core/bytecode/CallLinkStatus.cpp	2013-07-26 21:12:30 UTC (rev 153381)
@@ -143,8 +143,11 @@
     if (m_callTarget)
         out.print(comma, "Known target: ", m_callTarget);
     
-    if (m_executable)
-        out.print(comma, "Executable/CallHash: ", RawPointer(m_executable), "/", m_executable->hashFor(CodeForCall));
+    if (m_executable) {
+        out.print(comma, "Executable/CallHash: ", RawPointer(m_executable));
+        if (!isCompilationThread())
+            out.print("/", m_executable->hashFor(CodeForCall));
+    }
     
     if (m_structure)
         out.print(comma, "Structure: ", RawPointer(m_structure));

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (153380 => 153381)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2013-07-26 20:41:32 UTC (rev 153380)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2013-07-26 21:12:30 UTC (rev 153381)
@@ -487,7 +487,6 @@
     }
     if (needsFullScopeChain() && codeType() == FunctionCode)
         out.printf("; activation in r%d", activationRegister());
-    out.print("\n\nSource: ", sourceCodeOnOneLine(), "\n\n");
 
     const Instruction* begin = instructions().begin();
     const Instruction* end = instructions().end();

Modified: trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp (153380 => 153381)


--- trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp	2013-07-26 20:41:32 UTC (rev 153380)
+++ trunk/Source/_javascript_Core/dfg/DFGRepatch.cpp	2013-07-26 21:12:30 UTC (rev 153381)
@@ -370,8 +370,11 @@
 
 static bool getPolymorphicStructureList(
     VM* vm, CodeBlock* codeBlock, StructureStubInfo& stubInfo,
-    PolymorphicAccessStructureList*& polymorphicStructureList, int& listIndex)
+    PolymorphicAccessStructureList*& polymorphicStructureList, int& listIndex,
+    CodeLocationLabel& slowCase)
 {
+    slowCase = stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase);
+    
     if (stubInfo.accessType == access_unset) {
         RELEASE_ASSERT(!stubInfo.stubRoutine);
         polymorphicStructureList = new PolymorphicAccessStructureList();
@@ -379,11 +382,12 @@
         listIndex = 0;
     } else if (stubInfo.accessType == access_get_by_id_self) {
         RELEASE_ASSERT(!stubInfo.stubRoutine);
-        polymorphicStructureList = new PolymorphicAccessStructureList(*vm, codeBlock->ownerExecutable(), JITStubRoutine::createSelfManagedRoutine(stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase)), stubInfo.u.getByIdSelf.baseObjectStructure.get(), true);
+        polymorphicStructureList = new PolymorphicAccessStructureList(*vm, codeBlock->ownerExecutable(), JITStubRoutine::createSelfManagedRoutine(slowCase), stubInfo.u.getByIdSelf.baseObjectStructure.get(), true);
         stubInfo.initGetByIdSelfList(polymorphicStructureList, 1, true);
         listIndex = 1;
     } else if (stubInfo.accessType == access_get_by_id_chain) {
         RELEASE_ASSERT(!!stubInfo.stubRoutine);
+        slowCase = CodeLocationLabel(stubInfo.stubRoutine->code().code());
         polymorphicStructureList = new PolymorphicAccessStructureList(*vm, codeBlock->ownerExecutable(), stubInfo.stubRoutine, stubInfo.u.getByIdChain.baseObjectStructure.get(), stubInfo.u.getByIdChain.chain.get(), true);
         stubInfo.stubRoutine.clear();
         stubInfo.initGetByIdSelfList(polymorphicStructureList, 1, false);
@@ -392,6 +396,7 @@
         RELEASE_ASSERT(stubInfo.accessType == access_get_by_id_self_list);
         polymorphicStructureList = stubInfo.u.getByIdSelfList.structureList;
         listIndex = stubInfo.u.getByIdSelfList.listSize;
+        slowCase = CodeLocationLabel(polymorphicStructureList->list[listIndex - 1].stubRoutine->code().code());
     }
     
     if (listIndex == POLYMORPHIC_LIST_CACHE_SIZE)
@@ -441,8 +446,9 @@
     
         PolymorphicAccessStructureList* polymorphicStructureList;
         int listIndex;
+        CodeLocationLabel slowCase;
 
-        if (!getPolymorphicStructureList(vm, codeBlock, stubInfo, polymorphicStructureList, listIndex))
+        if (!getPolymorphicStructureList(vm, codeBlock, stubInfo, polymorphicStructureList, listIndex, slowCase))
             return false;
         
         stubInfo.u.getByIdSelfList.listSize++;
@@ -545,14 +551,7 @@
 
         LinkBuffer patchBuffer(*vm, &stubJit, codeBlock);
         
-        CodeLocationLabel lastProtoBegin;
-        if (listIndex)
-            lastProtoBegin = CodeLocationLabel(polymorphicStructureList->list[listIndex - 1].stubRoutine->code().code());
-        else
-            lastProtoBegin = stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToSlowCase);
-        ASSERT(!!lastProtoBegin);
-        
-        patchBuffer.link(wrongStruct, lastProtoBegin);
+        patchBuffer.link(wrongStruct, slowCase);
         patchBuffer.link(success, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone));
         if (!isDirect) {
             patchBuffer.link(operationCall, operationFunction);
@@ -592,17 +591,15 @@
     
     PolymorphicAccessStructureList* polymorphicStructureList;
     int listIndex;
-    if (!getPolymorphicStructureList(vm, codeBlock, stubInfo, polymorphicStructureList, listIndex))
+    CodeLocationLabel slowCase;
+    if (!getPolymorphicStructureList(vm, codeBlock, stubInfo, polymorphicStructureList, listIndex, slowCase))
         return false;
     
     stubInfo.u.getByIdProtoList.listSize++;
     
-    CodeLocationLabel lastProtoBegin = CodeLocationLabel(polymorphicStructureList->list[listIndex - 1].stubRoutine->code().code());
-    ASSERT(!!lastProtoBegin);
-    
     RefPtr<JITStubRoutine> stubRoutine;
     
-    generateProtoChainAccessStub(exec, stubInfo, prototypeChain, count, offset, structure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone), lastProtoBegin, stubRoutine);
+    generateProtoChainAccessStub(exec, stubInfo, prototypeChain, count, offset, structure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.dfg.deltaCallToDone), slowCase, stubRoutine);
     
     polymorphicStructureList->list[listIndex].set(*vm, codeBlock->ownerExecutable(), stubRoutine, structure, true);
     
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to