Title: [243626] trunk
Revision
243626
Author
[email protected]
Date
2019-03-28 15:05:34 -0700 (Thu, 28 Mar 2019)

Log Message

CodeBlock::jettison() should disallow repatching its own calls
https://bugs.webkit.org/show_bug.cgi?id=196359
<rdar://problem/48973663>

Reviewed by Saam Barati.

JSTests:

* stress/call-link-info-osrexit-repatch.js: Added.
(foo):

Source/_javascript_Core:

CodeBlock::jettison() calls CommonData::invalidate, which replaces the `hlt`
instruction with the jump to OSR exit. However, if the `hlt` was immediately
followed by a call to the CodeBlock being jettisoned, we would write over the
OSR exit address while unlinking all the incoming CallLinkInfos later in
CodeBlock::jettison().

Change it so that we set a flag, `clearedByJettison`, in all the CallLinkInfos
owned by the CodeBlock being jettisoned. If the flag is set, we will avoid
repatching the call during unlinking. This is safe because this call will never
be reachable again after the CodeBlock is jettisoned.

* bytecode/CallLinkInfo.cpp:
(JSC::CallLinkInfo::CallLinkInfo):
(JSC::CallLinkInfo::setCallee):
(JSC::CallLinkInfo::clearCallee):
(JSC::CallLinkInfo::setCodeBlock):
(JSC::CallLinkInfo::clearCodeBlock):
* bytecode/CallLinkInfo.h:
(JSC::CallLinkInfo::clearedByJettison):
(JSC::CallLinkInfo::setClearedByJettison):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::jettison):
* jit/Repatch.cpp:
(JSC::revertCall):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (243625 => 243626)


--- trunk/JSTests/ChangeLog	2019-03-28 22:03:40 UTC (rev 243625)
+++ trunk/JSTests/ChangeLog	2019-03-28 22:05:34 UTC (rev 243626)
@@ -1,3 +1,14 @@
+2019-03-28  Tadeu Zagallo  <[email protected]>
+
+        CodeBlock::jettison() should disallow repatching its own calls
+        https://bugs.webkit.org/show_bug.cgi?id=196359
+        <rdar://problem/48973663>
+
+        Reviewed by Saam Barati.
+
+        * stress/call-link-info-osrexit-repatch.js: Added.
+        (foo):
+
 2019-03-28  Yusuke Suzuki  <[email protected]>
 
         [JSC] imports-oom.js intermittently fails

Added: trunk/JSTests/stress/call-link-info-osrexit-repatch.js (0 => 243626)


--- trunk/JSTests/stress/call-link-info-osrexit-repatch.js	                        (rev 0)
+++ trunk/JSTests/stress/call-link-info-osrexit-repatch.js	2019-03-28 22:05:34 UTC (rev 243626)
@@ -0,0 +1,18 @@
+//@ runFTLEager("--watchdog=1000", "--watchdog-exception-ok")
+
+function foo(a, b) {
+    'use strict';
+    if (a === 0) {
+        return;
+    }
+    if (a === 0) {
+        return foo(a + 0);
+    }
+    if (a === 0) {
+        return foo(+a, 0);
+    }
+    return foo(b / 1, a, 0);
+    0 === 0
+}
+
+foo(1, 5);

Modified: trunk/Source/_javascript_Core/ChangeLog (243625 => 243626)


--- trunk/Source/_javascript_Core/ChangeLog	2019-03-28 22:03:40 UTC (rev 243625)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-03-28 22:05:34 UTC (rev 243626)
@@ -1,3 +1,36 @@
+2019-03-28  Tadeu Zagallo  <[email protected]>
+
+        CodeBlock::jettison() should disallow repatching its own calls
+        https://bugs.webkit.org/show_bug.cgi?id=196359
+        <rdar://problem/48973663>
+
+        Reviewed by Saam Barati.
+
+        CodeBlock::jettison() calls CommonData::invalidate, which replaces the `hlt`
+        instruction with the jump to OSR exit. However, if the `hlt` was immediately
+        followed by a call to the CodeBlock being jettisoned, we would write over the
+        OSR exit address while unlinking all the incoming CallLinkInfos later in
+        CodeBlock::jettison().
+
+        Change it so that we set a flag, `clearedByJettison`, in all the CallLinkInfos
+        owned by the CodeBlock being jettisoned. If the flag is set, we will avoid
+        repatching the call during unlinking. This is safe because this call will never
+        be reachable again after the CodeBlock is jettisoned.
+
+        * bytecode/CallLinkInfo.cpp:
+        (JSC::CallLinkInfo::CallLinkInfo):
+        (JSC::CallLinkInfo::setCallee):
+        (JSC::CallLinkInfo::clearCallee):
+        (JSC::CallLinkInfo::setCodeBlock):
+        (JSC::CallLinkInfo::clearCodeBlock):
+        * bytecode/CallLinkInfo.h:
+        (JSC::CallLinkInfo::clearedByJettison):
+        (JSC::CallLinkInfo::setClearedByJettison):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::jettison):
+        * jit/Repatch.cpp:
+        (JSC::revertCall):
+
 2019-03-27  Yusuke Suzuki  <[email protected]>
 
         [JSC] Drop VM and Context cache map in _javascript_Core.framework

Modified: trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp (243625 => 243626)


--- trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp	2019-03-28 22:03:40 UTC (rev 243625)
+++ trunk/Source/_javascript_Core/bytecode/CallLinkInfo.cpp	2019-03-28 22:05:34 UTC (rev 243626)
@@ -61,7 +61,7 @@
     , m_clearedByGC(false)
     , m_clearedByVirtual(false)
     , m_allowStubs(true)
-    , m_isLinked(false)
+    , m_clearedByJettison(false)
     , m_callType(None)
     , m_calleeGPR(255)
     , m_maxNumArguments(0)
@@ -127,7 +127,6 @@
     RELEASE_ASSERT(!isDirect());
     MacroAssembler::repatchPointer(hotPathBegin(), callee);
     m_calleeOrCodeBlock.set(vm, owner, callee);
-    m_isLinked = true;
 }
 
 void CallLinkInfo::clearCallee()
@@ -135,7 +134,6 @@
     RELEASE_ASSERT(!isDirect());
     MacroAssembler::repatchPointer(hotPathBegin(), nullptr);
     m_calleeOrCodeBlock.clear();
-    m_isLinked = false;
 }
 
 JSObject* CallLinkInfo::callee()
@@ -148,7 +146,6 @@
 {
     RELEASE_ASSERT(isDirect());
     m_calleeOrCodeBlock.setMayBeNull(vm, owner, codeBlock);
-    m_isLinked = true;
 }
 
 void CallLinkInfo::clearCodeBlock()
@@ -155,7 +152,6 @@
 {
     RELEASE_ASSERT(isDirect());
     m_calleeOrCodeBlock.clear();
-    m_isLinked = false;
 }
 
 FunctionCodeBlock* CallLinkInfo::codeBlock()

Modified: trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h (243625 => 243626)


--- trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h	2019-03-28 22:03:40 UTC (rev 243625)
+++ trunk/Source/_javascript_Core/bytecode/CallLinkInfo.h	2019-03-28 22:05:34 UTC (rev 243626)
@@ -270,10 +270,20 @@
         return m_clearedByVirtual;
     }
 
+    bool clearedByJettison()
+    {
+        return m_clearedByJettison;
+    }
+
     void setClearedByVirtual()
     {
         m_clearedByVirtual = true;
     }
+
+    void setClearedByJettison()
+    {
+        m_clearedByJettison = true;
+    }
     
     void setCallType(CallType callType)
     {
@@ -350,7 +360,7 @@
     bool m_clearedByGC : 1;
     bool m_clearedByVirtual : 1;
     bool m_allowStubs : 1;
-    bool m_isLinked : 1;
+    bool m_clearedByJettison : 1;
     unsigned m_callType : 4; // CallType
     unsigned m_calleeGPR : 8;
     uint32_t m_maxNumArguments; // For varargs: the profiled maximum number of arguments. For direct: the number of stack slots allocated for arguments.

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (243625 => 243626)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2019-03-28 22:03:40 UTC (rev 243625)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2019-03-28 22:05:34 UTC (rev 243626)
@@ -2049,6 +2049,16 @@
     if (vm.heap.isCurrentThreadBusy() && !vm.heap.isMarked(ownerExecutable()))
         return;
 
+#if ENABLE(JIT)
+    {
+        ConcurrentJSLocker locker(m_lock);
+        if (JITData* jitData = m_jitData.get()) {
+            for (CallLinkInfo* callLinkInfo : jitData->m_callLinkInfos)
+                callLinkInfo->setClearedByJettison();
+        }
+    }
+#endif
+
     // This accomplishes (2).
     ownerExecutable()->installCode(vm, alternative(), codeType(), specializationKind());
 

Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (243625 => 243626)


--- trunk/Source/_javascript_Core/jit/Repatch.cpp	2019-03-28 22:03:40 UTC (rev 243625)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp	2019-03-28 22:05:34 UTC (rev 243626)
@@ -895,18 +895,20 @@
 
 static void revertCall(VM* vm, CallLinkInfo& callLinkInfo, MacroAssemblerCodeRef<JITStubRoutinePtrTag> codeRef)
 {
-    if (callLinkInfo.isDirect()) {
-        callLinkInfo.clearCodeBlock();
-        if (callLinkInfo.callType() == CallLinkInfo::DirectTailCall)
-            MacroAssembler::repatchJump(callLinkInfo.patchableJump(), callLinkInfo.slowPathStart());
-        else
-            MacroAssembler::repatchNearCall(callLinkInfo.hotPathOther(), callLinkInfo.slowPathStart());
-    } else {
-        MacroAssembler::revertJumpReplacementToBranchPtrWithPatch(
-            MacroAssembler::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin()),
-            static_cast<MacroAssembler::RegisterID>(callLinkInfo.calleeGPR()), 0);
-        linkSlowFor(vm, callLinkInfo, codeRef);
-        callLinkInfo.clearCallee();
+    if (!callLinkInfo.clearedByJettison()) {
+        if (callLinkInfo.isDirect()) {
+            callLinkInfo.clearCodeBlock();
+            if (callLinkInfo.callType() == CallLinkInfo::DirectTailCall)
+                MacroAssembler::repatchJump(callLinkInfo.patchableJump(), callLinkInfo.slowPathStart());
+            else
+                MacroAssembler::repatchNearCall(callLinkInfo.hotPathOther(), callLinkInfo.slowPathStart());
+        } else {
+            MacroAssembler::revertJumpReplacementToBranchPtrWithPatch(
+                MacroAssembler::startOfBranchPtrWithPatchOnRegister(callLinkInfo.hotPathBegin()),
+                static_cast<MacroAssembler::RegisterID>(callLinkInfo.calleeGPR()), 0);
+            linkSlowFor(vm, callLinkInfo, codeRef);
+            callLinkInfo.clearCallee();
+        }
     }
     callLinkInfo.clearSeen();
     callLinkInfo.clearStub();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to