<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[278875] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/278875">278875</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2021-06-15 09:09:27 -0700 (Tue, 15 Jun 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Move setting of scratch buffer active lengths to the runtime functions.
https://bugs.webkit.org/show_bug.cgi?id=227013
rdar://79325068

Reviewed by Keith Miller.

We previously emit JIT'ed code to set and unset the ScratchBuffer active length
around calls into C++ runtime functions.  This was needed because the runtime
functions may allow GC to run, and GC needs to be able to scan the values stored
in the ScratchBuffer.

In this patch, we change it so that the runtime functions that need it will
declare an ActiveScratchBufferScope RAII object that will set the ScratchBuffer
active length, and unset it on exit.  This allows us to:

1. Emit less JIT code.  The runtime function can take care of it.
2. Elide setting the ScratchBuffer active length if not needed.  The runtime
   functions know whether they can GC or not.  They only need to set the active
   length if they can GC.

Note that scanning of the active ScratchBuffer is done synchronously on the
mutator thread via Heap::gatherScratchBufferRoots(), which is called as part of
the GC conservative root scan.  This means there is no urgency / sequencing that
requires that the active length be set before calling into the runtime function.
Setting it in the runtime function itself is fine as long as it is done before
the function executes any operations that can GC.

This patch also made the following changes:

1. Introduce ActiveScratchBufferScope RAII object used to set/unset the
   ScratchBuffer length in the runtime functions.  ActiveScratchBufferScope takes
   the active length in units of number of stack slots / Registers / JSValues
   instead of bytes.

2. Deleted ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall()
   and ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall().
   These functions are unused.

The reasoning behind what values to pass to ActiveScratchBufferScope, is any:

1. AssemblyHelpers::debugCall() in AssemblyHelpers.cpp:
   The ScratchBuffer is only used for operationDebugPrintSpeculationFailure(),
   which now declares an ActiveScratchBufferScope.

   The active length is GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters.
   See scratchSize in AssemblyHelpers::debugCall().

2. genericGenerationThunkGenerator() in FTLThunks.cpp:
   The scratch buffer size for determining the active length is
   requiredScratchMemorySizeInBytes().  

   However, genericGenerationThunkGenerator() generates code to call either
   operationCompileFTLOSRExit() or operationCompileFTLLazySlowPath().  Both of
   these functions will DeferGCForAWhile.  Hence, GC cannot run, and we don't need
   to set the active length here.

3. compileArrayPush() in FTLLowerDFGToB3.cpp:

   Cases Array::Int32, Array::Contiguous, or Array::Double calls
   operationArrayPushMultiple() or operationArrayPushDoubleMultiple().

   For operationArrayPushMultiple(), the active length is elementCount.  See
   computation of scratchSize.

   For operationArrayPushDoubleMultiple(), we don't need to set the active length
   because the ScratchBuffer only contains double values.  The GC does not need
   to scan those.

   Case Array::ArrayStorage calls operationArrayPushMultiple().
   The active length is elementCount.  See computation of scratchSize.

   compileNewArray() in FTLLowerDFGToB3.cpp:

   Calls operationNewArray().  Active length is m_node->numChildren(), which is
   passed to operationNewArray() as the size parameter.  See computation of
   scratchSize.

   compileNewArrayWithSpread() in FTLLowerDFGToB3.cpp:

   Calls operationNewArrayWithSpreadSlow().  Active length is m_node->numChildren(),
   which is passes to operationNewArrayWithSpreadSlow() as the numItems parameter.
   See computation of scratchSize.

4. osrExitGenerationThunkGenerator() in DFGThunks.cpp:

   Calls operationCompileOSRExit().  Active length is GPRInfo::numberOfRegisters +
   FPRInfo::numberOfRegisters.  See computation of scratchSize.

5. compileNewArray() in DFGSpeculativeJIT.cpp:

   Calls operationNewArray().  Active length is node->numChildren(), which is
   passed in as the size parameter.

   compileNewArrayWithSpread() in DFGSpeculativeJIT.cpp:

   Calls operationNewArrayWithSpreadSlow().  Active length is node->numChildren(),
   which is passed in as the numItems parameter.

   compileArrayPush() in DFGSpeculativeJIT.cpp:

   Calls operationArrayPushMultiple().  Active length is elementCount, which is
   passed in as the elementCount parameter.

   Calls operationArrayPushDoubleMultiple().  Active length is elementCount, but
   we don't need to set it because the ScratchBuffer only contains double values.


* dfg/DFGOSRExit.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileNewArray):
(JSC::DFG::SpeculativeJIT::compileNewArrayWithSpread):
(JSC::DFG::SpeculativeJIT::compileArrayPush):
* dfg/DFGThunks.cpp:
(JSC::DFG::osrExitGenerationThunkGenerator):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileArrayPush):
(JSC::FTL::DFG::LowerDFGToB3::compileNewArray):
(JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::JSC_DEFINE_JIT_OPERATION):
* ftl/FTLOperations.cpp:
(JSC::FTL::JSC_DEFINE_JIT_OPERATION):
* ftl/FTLThunks.cpp:
(JSC::FTL::genericGenerationThunkGenerator):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::debugCall):
* jit/ScratchRegisterAllocator.cpp:
(JSC::ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall): Deleted.
(JSC::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall): Deleted.
* jit/ScratchRegisterAllocator.h:
* runtime/VM.h:
* runtime/VMInlines.h:
(JSC::ActiveScratchBufferScope::ActiveScratchBufferScope):
(JSC::ActiveScratchBufferScope::~ActiveScratchBufferScope):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSRExitcpp">trunk/Source/JavaScriptCore/dfg/DFGOSRExit.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGThunkscpp">trunk/Source/JavaScriptCore/dfg/DFGThunks.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOperationscpp">trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLThunkscpp">trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitAssemblyHelperscpp">trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitScratchRegisterAllocatorcpp">trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitScratchRegisterAllocatorh">trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMInlinesh">trunk/Source/JavaScriptCore/runtime/VMInlines.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/ChangeLog       2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -1,3 +1,143 @@
</span><ins>+2021-06-15  Mark Lam  <mark.lam@apple.com>
+
+        Move setting of scratch buffer active lengths to the runtime functions.
+        https://bugs.webkit.org/show_bug.cgi?id=227013
+        rdar://79325068
+
+        Reviewed by Keith Miller.
+
+        We previously emit JIT'ed code to set and unset the ScratchBuffer active length
+        around calls into C++ runtime functions.  This was needed because the runtime
+        functions may allow GC to run, and GC needs to be able to scan the values stored
+        in the ScratchBuffer.
+
+        In this patch, we change it so that the runtime functions that need it will
+        declare an ActiveScratchBufferScope RAII object that will set the ScratchBuffer
+        active length, and unset it on exit.  This allows us to:
+
+        1. Emit less JIT code.  The runtime function can take care of it.
+        2. Elide setting the ScratchBuffer active length if not needed.  The runtime
+           functions know whether they can GC or not.  They only need to set the active
+           length if they can GC.
+
+        Note that scanning of the active ScratchBuffer is done synchronously on the
+        mutator thread via Heap::gatherScratchBufferRoots(), which is called as part of
+        the GC conservative root scan.  This means there is no urgency / sequencing that
+        requires that the active length be set before calling into the runtime function.
+        Setting it in the runtime function itself is fine as long as it is done before
+        the function executes any operations that can GC.
+
+        This patch also made the following changes:
+
+        1. Introduce ActiveScratchBufferScope RAII object used to set/unset the
+           ScratchBuffer length in the runtime functions.  ActiveScratchBufferScope takes
+           the active length in units of number of stack slots / Registers / JSValues
+           instead of bytes.
+
+        2. Deleted ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall()
+           and ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall().
+           These functions are unused.
+
+        The reasoning behind what values to pass to ActiveScratchBufferScope, is any:
+
+        1. AssemblyHelpers::debugCall() in AssemblyHelpers.cpp:
+           The ScratchBuffer is only used for operationDebugPrintSpeculationFailure(),
+           which now declares an ActiveScratchBufferScope.
+
+           The active length is GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters.
+           See scratchSize in AssemblyHelpers::debugCall().
+
+        2. genericGenerationThunkGenerator() in FTLThunks.cpp:
+           The scratch buffer size for determining the active length is
+           requiredScratchMemorySizeInBytes().  
+
+           However, genericGenerationThunkGenerator() generates code to call either
+           operationCompileFTLOSRExit() or operationCompileFTLLazySlowPath().  Both of
+           these functions will DeferGCForAWhile.  Hence, GC cannot run, and we don't need
+           to set the active length here.
+
+        3. compileArrayPush() in FTLLowerDFGToB3.cpp:
+
+           Cases Array::Int32, Array::Contiguous, or Array::Double calls
+           operationArrayPushMultiple() or operationArrayPushDoubleMultiple().
+
+           For operationArrayPushMultiple(), the active length is elementCount.  See
+           computation of scratchSize.
+
+           For operationArrayPushDoubleMultiple(), we don't need to set the active length
+           because the ScratchBuffer only contains double values.  The GC does not need
+           to scan those.
+
+           Case Array::ArrayStorage calls operationArrayPushMultiple().
+           The active length is elementCount.  See computation of scratchSize.
+
+           compileNewArray() in FTLLowerDFGToB3.cpp:
+
+           Calls operationNewArray().  Active length is m_node->numChildren(), which is
+           passed to operationNewArray() as the size parameter.  See computation of
+           scratchSize.
+
+           compileNewArrayWithSpread() in FTLLowerDFGToB3.cpp:
+
+           Calls operationNewArrayWithSpreadSlow().  Active length is m_node->numChildren(),
+           which is passes to operationNewArrayWithSpreadSlow() as the numItems parameter.
+           See computation of scratchSize.
+
+        4. osrExitGenerationThunkGenerator() in DFGThunks.cpp:
+
+           Calls operationCompileOSRExit().  Active length is GPRInfo::numberOfRegisters +
+           FPRInfo::numberOfRegisters.  See computation of scratchSize.
+
+        5. compileNewArray() in DFGSpeculativeJIT.cpp:
+
+           Calls operationNewArray().  Active length is node->numChildren(), which is
+           passed in as the size parameter.
+
+           compileNewArrayWithSpread() in DFGSpeculativeJIT.cpp:
+
+           Calls operationNewArrayWithSpreadSlow().  Active length is node->numChildren(),
+           which is passed in as the numItems parameter.
+
+           compileArrayPush() in DFGSpeculativeJIT.cpp:
+
+           Calls operationArrayPushMultiple().  Active length is elementCount, which is
+           passed in as the elementCount parameter.
+
+           Calls operationArrayPushDoubleMultiple().  Active length is elementCount, but
+           we don't need to set it because the ScratchBuffer only contains double values.
+
+
+        * dfg/DFGOSRExit.cpp:
+        (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::JSC_DEFINE_JIT_OPERATION):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNewArray):
+        (JSC::DFG::SpeculativeJIT::compileNewArrayWithSpread):
+        (JSC::DFG::SpeculativeJIT::compileArrayPush):
+        * dfg/DFGThunks.cpp:
+        (JSC::DFG::osrExitGenerationThunkGenerator):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileArrayPush):
+        (JSC::FTL::DFG::LowerDFGToB3::compileNewArray):
+        (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::JSC_DEFINE_JIT_OPERATION):
+        * ftl/FTLOperations.cpp:
+        (JSC::FTL::JSC_DEFINE_JIT_OPERATION):
+        * ftl/FTLThunks.cpp:
+        (JSC::FTL::genericGenerationThunkGenerator):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::debugCall):
+        * jit/ScratchRegisterAllocator.cpp:
+        (JSC::ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall): Deleted.
+        (JSC::ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall): Deleted.
+        * jit/ScratchRegisterAllocator.h:
+        * runtime/VM.h:
+        * runtime/VMInlines.h:
+        (JSC::ActiveScratchBufferScope::ActiveScratchBufferScope):
+        (JSC::ActiveScratchBufferScope::~ActiveScratchBufferScope):
+
</ins><span class="cx"> 2021-06-14  Yusuke Suzuki  <ysuzuki@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [JSC] Workaround ICU uloc_addLikelySubtags / uloc_minimizeSubtags bugs
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSRExitcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSRExit.cpp (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSRExit.cpp   2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSRExit.cpp      2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include "JSCJSValueInlines.h"
</span><span class="cx"> #include "OperandsInlines.h"
</span><span class="cx"> #include "ProbeContext.h"
</span><ins>+#include "VMInlines.h"
</ins><span class="cx"> 
</span><span class="cx"> #include <wtf/Scope.h>
</span><span class="cx"> 
</span><span class="lines">@@ -144,6 +145,7 @@
</span><span class="cx"> {
</span><span class="cx">     VM& vm = callFrame->deprecatedVM();
</span><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><ins>+    ActiveScratchBufferScope activeScratchBufferScope(vm, GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters);
</ins><span class="cx"> 
</span><span class="cx">     if constexpr (validateDFGDoesGC) {
</span><span class="cx">         // We're about to exit optimized code. So, there's no longer any optimized
</span><span class="lines">@@ -890,6 +892,7 @@
</span><span class="cx"> {
</span><span class="cx">     VM& vm = callFrame->deprecatedVM();
</span><span class="cx">     NativeCallFrameTracer tracer(vm, callFrame);
</span><ins>+    ActiveScratchBufferScope activeScratchBufferScope(vm, GPRInfo::numberOfRegisters + FPRInfo::numberOfRegisters);
</ins><span class="cx"> 
</span><span class="cx">     SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
</span><span class="cx">     CodeBlock* codeBlock = debugInfo->codeBlock;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp   2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -1039,6 +1039,7 @@
</span><span class="cx">     VM& vm = globalObject->vm();
</span><span class="cx">     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
</span><span class="cx">     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
</span><ins>+    ActiveScratchBufferScope activeScratchBufferScope(vm, elementCount);
</ins><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><span class="cx">     // We assume that multiple JSArray::push calls with ArrayWithInt32/ArrayWithContiguous do not cause JS traps.
</span><span class="lines">@@ -1064,6 +1065,7 @@
</span><span class="cx">     VM& vm = globalObject->vm();
</span><span class="cx">     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
</span><span class="cx">     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
</span><ins>+    // Don't need a ActiveScratchBufferScope here because the scratch buffer only contains double values for this call.
</ins><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><span class="cx">     // We assume that multiple JSArray::push calls with ArrayWithDouble do not cause JS traps.
</span><span class="lines">@@ -1732,7 +1734,8 @@
</span><span class="cx">     VM& vm = globalObject->vm();
</span><span class="cx">     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
</span><span class="cx">     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
</span><del>-    
</del><ins>+    ActiveScratchBufferScope activeScratchBufferScope(vm, size);
+
</ins><span class="cx">     return bitwise_cast<char*>(constructArray(globalObject, arrayStructure, static_cast<JSValue*>(buffer), size));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -3039,6 +3042,7 @@
</span><span class="cx">     VM& vm = globalObject->vm();
</span><span class="cx">     CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
</span><span class="cx">     JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
</span><ins>+    ActiveScratchBufferScope activeScratchBufferScope(vm, numItems);
</ins><span class="cx">     auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><span class="cx">     EncodedJSValue* values = static_cast<EncodedJSValue*>(buffer);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp    2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp       2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -9167,14 +9167,6 @@
</span><span class="cx"> 
</span><span class="cx">     flushRegisters();
</span><span class="cx"> 
</span><del>-    if (scratchSize) {
-        GPRTemporary scratch(this);
-
-        // Tell GC mark phase how much of the scratch buffer is active during call.
-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratch.gpr());
-        m_jit.storePtr(TrustedImmPtr(scratchSize), scratch.gpr());
-    }
-
</del><span class="cx">     GPRFlushedCallResult result(this);
</span><span class="cx"> 
</span><span class="cx">     callOperation(
</span><span class="lines">@@ -9182,13 +9174,6 @@
</span><span class="cx">         static_cast<void*>(buffer), size_t(node->numChildren()));
</span><span class="cx">     m_jit.exceptionCheck();
</span><span class="cx"> 
</span><del>-    if (scratchSize) {
-        GPRTemporary scratch(this);
-
-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratch.gpr());
-        m_jit.storePtr(TrustedImmPtr(nullptr), scratch.gpr());
-    }
-
</del><span class="cx">     cellResult(result.gpr(), node, UseChildrenCalledExplicitly);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -9339,12 +9324,6 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    {
-        GPRTemporary scratch(this);
-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratch.gpr());
-        m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(scratch.gpr()));
-    }
-
</del><span class="cx">     flushRegisters();
</span><span class="cx"> 
</span><span class="cx">     GPRFlushedCallResult result(this);
</span><span class="lines">@@ -9352,11 +9331,6 @@
</span><span class="cx"> 
</span><span class="cx">     callOperation(operationNewArrayWithSpreadSlow, resultGPR, TrustedImmPtr::weakPointer(m_graph, globalObject), buffer, node->numChildren());
</span><span class="cx">     m_jit.exceptionCheck();
</span><del>-    {
-        GPRTemporary scratch(this);
-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratch.gpr());
-        m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(scratch.gpr()));
-    }
</del><span class="cx"> 
</span><span class="cx">     cellResult(resultGPR, node);
</span><span class="cx"> }
</span><span class="lines">@@ -9875,8 +9849,6 @@
</span><span class="cx">         size_t scratchSize = sizeof(EncodedJSValue) * elementCount;
</span><span class="cx">         ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize);
</span><span class="cx">         m_jit.move(TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())), bufferGPR);
</span><del>-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), storageLengthGPR);
-        m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(storageLengthGPR));
</del><span class="cx"> 
</span><span class="cx">         storageDone.link(&m_jit);
</span><span class="cx">         for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
</span><span class="lines">@@ -9892,9 +9864,6 @@
</span><span class="cx"> 
</span><span class="cx">         addSlowPathGenerator(slowPathCall(m_jit.jump(), this, operationArrayPushMultiple, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, bufferGPR, TrustedImm32(elementCount)));
</span><span class="cx"> 
</span><del>-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), bufferGPR);
-        m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(bufferGPR));
-
</del><span class="cx">         base.use();
</span><span class="cx">         storage.use();
</span><span class="cx"> 
</span><span class="lines">@@ -9949,8 +9918,6 @@
</span><span class="cx">         size_t scratchSize = sizeof(double) * elementCount;
</span><span class="cx">         ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize);
</span><span class="cx">         m_jit.move(TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())), bufferGPR);
</span><del>-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), storageLengthGPR);
-        m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(storageLengthGPR));
</del><span class="cx"> 
</span><span class="cx">         storageDone.link(&m_jit);
</span><span class="cx">         for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
</span><span class="lines">@@ -9966,9 +9933,6 @@
</span><span class="cx"> 
</span><span class="cx">         addSlowPathGenerator(slowPathCall(m_jit.jump(), this, operationArrayPushDoubleMultiple, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, bufferGPR, TrustedImm32(elementCount)));
</span><span class="cx"> 
</span><del>-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), bufferGPR);
-        m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(bufferGPR));
-
</del><span class="cx">         base.use();
</span><span class="cx">         storage.use();
</span><span class="cx"> 
</span><span class="lines">@@ -10030,8 +9994,6 @@
</span><span class="cx">         size_t scratchSize = sizeof(EncodedJSValue) * elementCount;
</span><span class="cx">         ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize);
</span><span class="cx">         m_jit.move(TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())), bufferGPR);
</span><del>-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), storageLengthGPR);
-        m_jit.storePtr(TrustedImmPtr(scratchSize), MacroAssembler::Address(storageLengthGPR));
</del><span class="cx"> 
</span><span class="cx">         storageDone.link(&m_jit);
</span><span class="cx">         for (unsigned elementIndex = 0; elementIndex < elementCount; ++elementIndex) {
</span><span class="lines">@@ -10048,9 +10010,6 @@
</span><span class="cx">         addSlowPathGenerator(
</span><span class="cx">             slowPathCall(m_jit.jump(), this, operationArrayPushMultiple, resultRegs, TrustedImmPtr::weakPointer(m_graph, m_graph.globalObjectFor(node->origin.semantic)), baseGPR, bufferGPR, TrustedImm32(elementCount)));
</span><span class="cx"> 
</span><del>-        m_jit.move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), bufferGPR);
-        m_jit.storePtr(TrustedImmPtr(nullptr), MacroAssembler::Address(bufferGPR));
-
</del><span class="cx">         base.use();
</span><span class="cx">         storage.use();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGThunkscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGThunks.cpp (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGThunks.cpp    2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/dfg/DFGThunks.cpp       2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -31,11 +31,11 @@
</span><span class="cx"> #include "CCallHelpers.h"
</span><span class="cx"> #include "DFGJITCode.h"
</span><span class="cx"> #include "DFGOSRExit.h"
</span><ins>+#include "DFGOSRExitCompilerCommon.h"
</ins><span class="cx"> #include "FPRInfo.h"
</span><span class="cx"> #include "GPRInfo.h"
</span><span class="cx"> #include "LinkBuffer.h"
</span><span class="cx"> #include "MacroAssembler.h"
</span><del>-#include "DFGOSRExitCompilerCommon.h"
</del><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace DFG {
</span><span class="cx"> 
</span><span class="lines">@@ -62,10 +62,6 @@
</span><span class="cx">         jit.storeDouble(FPRInfo::toRegister(i), MacroAssembler::Address(GPRInfo::regT0));
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    // Tell GC mark phase how much of the scratch buffer is active during call.
-    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::regT0);
-    jit.storePtr(MacroAssembler::TrustedImmPtr(scratchSize), MacroAssembler::Address(GPRInfo::regT0));
-
</del><span class="cx">     // Set up one argument.
</span><span class="cx">     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
</span><span class="cx">     jit.prepareCallOperation(vm);
</span><span class="lines">@@ -72,9 +68,6 @@
</span><span class="cx"> 
</span><span class="cx">     MacroAssembler::Call functionCall = jit.call(OperationPtrTag);
</span><span class="cx"> 
</span><del>-    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::regT0);
-    jit.storePtr(MacroAssembler::TrustedImmPtr(nullptr), MacroAssembler::Address(GPRInfo::regT0));
-
</del><span class="cx">     for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
</span><span class="cx">         jit.move(MacroAssembler::TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0);
</span><span class="cx">         jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::toRegister(i));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp      2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp 2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -6162,7 +6162,6 @@
</span><span class="cx">             static_assert(sizeof(EncodedJSValue) == sizeof(double), "");
</span><span class="cx">             ASSERT(scratchSize);
</span><span class="cx">             ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize);
</span><del>-            m_out.storePtr(m_out.constIntPtr(scratchSize), m_out.absolute(scratchBuffer->addressOfActiveLength()));
</del><span class="cx">             ValueFromBlock slowBufferResult = m_out.anchor(m_out.constIntPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())));
</span><span class="cx">             m_out.jump(setup);
</span><span class="cx"> 
</span><span class="lines">@@ -6192,7 +6191,6 @@
</span><span class="cx">             if (m_node->arrayMode().type() == Array::Double)
</span><span class="cx">                 operation = &operationArrayPushDoubleMultiple;
</span><span class="cx">             ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, operation, weakPointer(globalObject), base, buffer, m_out.constInt32(elementCount)));
</span><del>-            m_out.storePtr(m_out.constIntPtr(0), m_out.absolute(scratchBuffer->addressOfActiveLength()));
</del><span class="cx">             m_out.jump(continuation);
</span><span class="cx"> 
</span><span class="cx">             m_out.appendTo(continuation, lastNext);
</span><span class="lines">@@ -6268,7 +6266,6 @@
</span><span class="cx">             size_t scratchSize = sizeof(EncodedJSValue) * elementCount;
</span><span class="cx">             ASSERT(scratchSize);
</span><span class="cx">             ScratchBuffer* scratchBuffer = vm().scratchBufferForSize(scratchSize);
</span><del>-            m_out.storePtr(m_out.constIntPtr(scratchSize), m_out.absolute(scratchBuffer->addressOfActiveLength()));
</del><span class="cx">             ValueFromBlock slowBufferResult = m_out.anchor(m_out.constIntPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer())));
</span><span class="cx">             m_out.jump(setup);
</span><span class="cx"> 
</span><span class="lines">@@ -6286,7 +6283,6 @@
</span><span class="cx"> 
</span><span class="cx">             m_out.appendTo(slowCallPath, continuation);
</span><span class="cx">             ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, operationArrayPushMultiple, weakPointer(globalObject), base, buffer, m_out.constInt32(elementCount)));
</span><del>-            m_out.storePtr(m_out.constIntPtr(0), m_out.absolute(scratchBuffer->addressOfActiveLength()));
</del><span class="cx">             m_out.jump(continuation);
</span><span class="cx"> 
</span><span class="cx">             m_out.appendTo(continuation, lastNext);
</span><span class="lines">@@ -7278,17 +7274,12 @@
</span><span class="cx">             }
</span><span class="cx">             m_out.store64(valueToStore, m_out.absolute(buffer + operandIndex));
</span><span class="cx">         }
</span><del>-        
-        m_out.storePtr(
-            m_out.constIntPtr(scratchSize), m_out.absolute(scratchBuffer->addressOfActiveLength()));
-        
</del><ins>+
</ins><span class="cx">         LValue result = vmCall(
</span><span class="cx">             Int64, operationNewArray, weakPointer(globalObject),
</span><span class="cx">             weakStructure(structure), m_out.constIntPtr(buffer),
</span><span class="cx">             m_out.constIntPtr(m_node->numChildren()));
</span><del>-        
-        m_out.storePtr(m_out.intPtrZero, m_out.absolute(scratchBuffer->addressOfActiveLength()));
-        
</del><ins>+
</ins><span class="cx">         setJSValue(result);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -7524,9 +7515,7 @@
</span><span class="cx">             m_out.store64(value, m_out.absolute(&buffer[i]));
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        m_out.storePtr(m_out.constIntPtr(scratchSize), m_out.absolute(scratchBuffer->addressOfActiveLength()));
</del><span class="cx">         LValue result = vmCall(Int64, operationNewArrayWithSpreadSlow, weakPointer(globalObject), m_out.constIntPtr(buffer), m_out.constInt32(m_node->numChildren()));
</span><del>-        m_out.storePtr(m_out.constIntPtr(0), m_out.absolute(scratchBuffer->addressOfActiveLength()));
</del><span class="cx"> 
</span><span class="cx">         setJSValue(result);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp   2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp      2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -523,6 +523,7 @@
</span><span class="cx">         dataLog("Compiling OSR exit with exitID = ", exitID, "\n");
</span><span class="cx"> 
</span><span class="cx">     VM& vm = callFrame->deprecatedVM();
</span><ins>+    // Don't need an ActiveScratchBufferScope here because we DeferGCForAWhile below.
</ins><span class="cx"> 
</span><span class="cx">     if constexpr (validateDFGDoesGC) {
</span><span class="cx">         // We're about to exit optimized code. So, there's no longer any optimized
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp        2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp   2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2021 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -730,6 +730,7 @@
</span><span class="cx"> JSC_DEFINE_JIT_OPERATION(operationCompileFTLLazySlowPath, void*, (CallFrame* callFrame, unsigned index))
</span><span class="cx"> {
</span><span class="cx">     VM& vm = callFrame->deprecatedVM();
</span><ins>+    // Don't need an ActiveScratchBufferScope here because we DeferGCForAWhile.
</ins><span class="cx"> 
</span><span class="cx">     // We cannot GC. We've got pointers in evil places.
</span><span class="cx">     DeferGCForAWhile deferGC(vm.heap);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLThunkscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp    2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/ftl/FTLThunks.cpp       2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -76,10 +76,6 @@
</span><span class="cx">     char* buffer = static_cast<char*>(scratchBuffer->dataBuffer());
</span><span class="cx">     
</span><span class="cx">     saveAllRegisters(jit, buffer);
</span><del>-    
-    // Tell GC mark phase how much of the scratch buffer is active during call.
-    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::nonArgGPR1);
-    jit.storePtr(MacroAssembler::TrustedImmPtr(requiredScratchMemorySizeInBytes()), GPRInfo::nonArgGPR1);
</del><span class="cx"> 
</span><span class="cx">     jit.loadPtr(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
</span><span class="cx">     jit.peek(
</span><span class="lines">@@ -94,11 +90,7 @@
</span><span class="cx">     // return address "slot" (be it a register or the stack).
</span><span class="cx">     
</span><span class="cx">     jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0);
</span><del>-    
-    // Make sure we tell the GC that we're not using the scratch buffer anymore.
-    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::regT1);
-    jit.storePtr(MacroAssembler::TrustedImmPtr(nullptr), GPRInfo::regT1);
-    
</del><ins>+
</ins><span class="cx">     // Prepare for tail call.
</span><span class="cx">     while (numberOfRequiredPops--)
</span><span class="cx">         jit.popToRestore(GPRInfo::regT1);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitAssemblyHelperscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp      2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp 2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -966,10 +966,6 @@
</span><span class="cx">         storeDouble(FPRInfo::toRegister(i), GPRInfo::regT0);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Tell GC mark phase how much of the scratch buffer is active during call.
-    move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::regT0);
-    storePtr(TrustedImmPtr(scratchSize), GPRInfo::regT0);
-
</del><span class="cx"> #if CPU(X86_64) || CPU(ARM_THUMB2) || CPU(ARM64) || CPU(MIPS)
</span><span class="cx">     move(TrustedImmPtr(buffer), GPRInfo::argumentGPR2);
</span><span class="cx">     move(TrustedImmPtr(argument), GPRInfo::argumentGPR1);
</span><span class="lines">@@ -982,9 +978,6 @@
</span><span class="cx">     move(TrustedImmPtr(tagCFunctionPtr<OperationPtrTag>(function)), scratch);
</span><span class="cx">     call(scratch, OperationPtrTag);
</span><span class="cx"> 
</span><del>-    move(TrustedImmPtr(scratchBuffer->addressOfActiveLength()), GPRInfo::regT0);
-    storePtr(TrustedImmPtr(nullptr), GPRInfo::regT0);
-
</del><span class="cx">     for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
</span><span class="cx">         move(TrustedImmPtr(buffer + GPRInfo::numberOfRegisters + i), GPRInfo::regT0);
</span><span class="cx">         loadDouble(GPRInfo::regT0, FPRInfo::toRegister(i));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitScratchRegisterAllocatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp     2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.cpp        2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -161,73 +161,6 @@
</span><span class="cx">     return usedRegistersForCall().numberOfSetRegisters() * sizeof(JSValue);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScratchRegisterAllocator::preserveUsedRegistersToScratchBufferForCall(MacroAssembler& jit, ScratchBuffer* scratchBuffer, GPRReg scratchGPR)
-{
-    RegisterSet usedRegisters = usedRegistersForCall();
-    if (!usedRegisters.numberOfSetRegisters())
-        return;
-    
-    unsigned count = 0;
-    for (GPRReg reg = MacroAssembler::firstRegister(); reg <= MacroAssembler::lastRegister(); reg = MacroAssembler::nextRegister(reg)) {
-        if (usedRegisters.get(reg)) {
-            jit.storePtr(reg, static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) + count);
-            count++;
-        }
-        if (GPRInfo::toIndex(reg) != GPRInfo::InvalidIndex
-            && scratchGPR == InvalidGPRReg
-            && !m_lockedRegisters.get(reg) && !m_scratchRegisters.get(reg))
-            scratchGPR = reg;
-    }
-    RELEASE_ASSERT(scratchGPR != InvalidGPRReg);
-    for (FPRReg reg = MacroAssembler::firstFPRegister(); reg <= MacroAssembler::lastFPRegister(); reg = MacroAssembler::nextFPRegister(reg)) {
-        if (usedRegisters.get(reg)) {
-            jit.move(MacroAssembler::TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) + count), scratchGPR);
-            count++;
-            jit.storeDouble(reg, scratchGPR);
-        }
-    }
-    RELEASE_ASSERT(count * sizeof(JSValue) == desiredScratchBufferSizeForCall());
-    
-    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratchGPR);
-    jit.storePtr(MacroAssembler::TrustedImmPtr(static_cast<size_t>(count * sizeof(JSValue))), scratchGPR);
-}
-
-void ScratchRegisterAllocator::restoreUsedRegistersFromScratchBufferForCall(MacroAssembler& jit, ScratchBuffer* scratchBuffer, GPRReg scratchGPR)
-{
-    RegisterSet usedRegisters = usedRegistersForCall();
-    if (!usedRegisters.numberOfSetRegisters())
-        return;
-    
-    if (scratchGPR == InvalidGPRReg) {
-        // Find a scratch register.
-        for (unsigned i = GPRInfo::numberOfRegisters; i--;) {
-            if (m_lockedRegisters.getGPRByIndex(i) || m_scratchRegisters.getGPRByIndex(i))
-                continue;
-            scratchGPR = GPRInfo::toRegister(i);
-            break;
-        }
-    }
-    RELEASE_ASSERT(scratchGPR != InvalidGPRReg);
-    
-    jit.move(MacroAssembler::TrustedImmPtr(scratchBuffer->addressOfActiveLength()), scratchGPR);
-    jit.storePtr(MacroAssembler::TrustedImmPtr(nullptr), scratchGPR);
-
-    // Restore double registers first.
-    unsigned count = usedRegisters.numberOfSetGPRs();
-    for (FPRReg reg = MacroAssembler::firstFPRegister(); reg <= MacroAssembler::lastFPRegister(); reg = MacroAssembler::nextFPRegister(reg)) {
-        if (usedRegisters.get(reg)) {
-            jit.move(MacroAssembler::TrustedImmPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) + (count++)), scratchGPR);
-            jit.loadDouble(scratchGPR, reg);
-        }
-    }
-        
-    count = 0;
-    for (GPRReg reg = MacroAssembler::firstRegister(); reg <= MacroAssembler::lastRegister(); reg = MacroAssembler::nextRegister(reg)) {
-        if (usedRegisters.get(reg))
-            jit.loadPtr(static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) + (count++), reg);
-    }
-}
-
</del><span class="cx"> unsigned ScratchRegisterAllocator::preserveRegistersToStackForCall(MacroAssembler& jit, const RegisterSet& usedRegisters, unsigned extraBytesAtTopOfStack)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(extraBytesAtTopOfStack % sizeof(void*) == 0);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitScratchRegisterAllocatorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h       2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/jit/ScratchRegisterAllocator.h  2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -91,9 +91,6 @@
</span><span class="cx">     
</span><span class="cx">     unsigned desiredScratchBufferSizeForCall() const;
</span><span class="cx">     
</span><del>-    void preserveUsedRegistersToScratchBufferForCall(MacroAssembler& jit, ScratchBuffer* scratchBuffer, GPRReg scratchGPR = InvalidGPRReg);
-    void restoreUsedRegistersFromScratchBufferForCall(MacroAssembler& jit, ScratchBuffer* scratchBuffer, GPRReg scratchGPR = InvalidGPRReg);
-
</del><span class="cx">     static unsigned preserveRegistersToStackForCall(MacroAssembler& jit, const RegisterSet& usedRegisters, unsigned extraPaddingInBytes);
</span><span class="cx">     static void restoreRegistersFromStackForCall(MacroAssembler& jit, const RegisterSet& usedRegisters, const RegisterSet& ignore, unsigned numberOfStackBytesUsedForRegisterPreservation, unsigned extraPaddingInBytes);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h 2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/runtime/VM.h    2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -280,6 +280,15 @@
</span><span class="cx"> #pragma warning(pop)
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+class ActiveScratchBufferScope {
+public:
+    ActiveScratchBufferScope(VM&, size_t activeScratchBufferSizeInJSValues);
+    ~ActiveScratchBufferScope();
+
+private:
+    ScratchBuffer* m_scratchBuffer;
+};
+
</ins><span class="cx"> class VM : public ThreadSafeRefCounted<VM>, public DoublyLinkedListNode<VM> {
</span><span class="cx"> public:
</span><span class="cx">     // WebCore has a one-to-one mapping of threads to VMs;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VMInlines.h (278874 => 278875)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VMInlines.h  2021-06-15 14:47:54 UTC (rev 278874)
+++ trunk/Source/JavaScriptCore/runtime/VMInlines.h     2021-06-15 16:09:27 UTC (rev 278875)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2021 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -31,7 +31,22 @@
</span><span class="cx"> #include "Watchdog.h"
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><del>-    
</del><ins>+
+inline ActiveScratchBufferScope::ActiveScratchBufferScope(VM& vm, size_t activeScratchBufferSizeInJSValues)
+    : m_scratchBuffer(vm.scratchBufferForSize(activeScratchBufferSizeInJSValues * sizeof(EncodedJSValue)))
+{
+    // Tell GC mark phase how much of the scratch buffer is active during the call operation this scope is used in.
+    if (m_scratchBuffer)
+        m_scratchBuffer->u.m_activeLength = activeScratchBufferSizeInJSValues * sizeof(EncodedJSValue);
+}
+
+inline ActiveScratchBufferScope::~ActiveScratchBufferScope()
+{
+    // Tell the GC that we're not using the scratch buffer anymore.
+    if (m_scratchBuffer)
+        m_scratchBuffer->u.m_activeLength = 0;
+}
+
</ins><span class="cx"> bool VM::ensureStackCapacityFor(Register* newTopOfStack)
</span><span class="cx"> {
</span><span class="cx"> #if !ENABLE(C_LOOP)
</span></span></pre>
</div>
</div>

</body>
</html>