<!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>[265586] branches/safari-610.1-branch/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/265586">265586</a></dd>
<dt>Author</dt> <dd>alancoon@apple.com</dd>
<dt>Date</dt> <dd>2020-08-12 18:46:10 -0700 (Wed, 12 Aug 2020)</dd>
</dl>

<h3>Log Message</h3>
<pre>Cherry-pick <a href="http://trac.webkit.org/projects/webkit/changeset/265405">r265405</a>. rdar://problem/66943811

    [JSC] Speculate children first in DFG NewArray
    https://bugs.webkit.org/show_bug.cgi?id=215308
    <rdar://problem/64749263>

    Reviewed by Mark Lam.

    SpeculativeJIT::emitAllocateRawObject can create uninitialized butterfly since we later fill them.
    However, DFG NewArray node has speculation after that. So if speculation failure happens, we release
    half-baked butterfly.

    Let's see the example.

       8459         emitAllocateRawObject(resultGPR, structure, storageGPR, numElements, vectorLengthHint);
       ...
       8482             case ALL_INT32_INDEXING_TYPES:
       8483             case ALL_CONTIGUOUS_INDEXING_TYPES: {
       8484                 JSValueOperand operand(this, use, ManualOperandSpeculation);
       8485                 JSValueRegs operandRegs = operand.jsValueRegs();
       8486                 if (hasInt32(node->indexingType())) {
       8487                     DFG_TYPE_CHECK(
       8488                         operandRegs, use, SpecInt32Only,
       8489                         m_jit.branchIfNotInt32(operandRegs));
       8490                 }
       8491                 m_jit.storeValue(operandRegs, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx));
       8492                 break;
       8493             }

    L8487-L8489 is doing speculation check. If it failed, the rest of the butterfly can be filled with garbage. This looks OK since
    it is Int32 butterfly so GC never scans it. However, if have-a-bad-time happens and the array is reachable from the conservative root,
    this half-baked array is converted from Int32 array to ArrayStorage. At that time, since Int32 butterfly should hold JSInt32,
    we store this garbage to ArrayStorage. Later, if conservative root still holds this array, and GC scans this garbage as as JSValue,
    this value confuses GC.

    In this patch, we first perform speculation before creating uninitialized JSArray so that we can ensure that we never exit after
    creating this array until we fill it. This strategy is the same to FTL's NewArray implementation.

    And we also found that emitAllocateRawObject is allocating an object from JSFinalObject space while we use it for JSArray too.
    We should get per-type allocator to ensure JSArray is allocated in its IsoSubspace.

    * dfg/DFGOperations.cpp:
    * dfg/DFGSpeculativeJIT.cpp:
    (JSC::DFG::SpeculativeJIT::emitAllocateRawObject):
    (JSC::DFG::SpeculativeJIT::compileNewArray):
    (JSC::DFG::SpeculativeJIT::compileMaterializeNewObject):
    * ftl/FTLLowerDFGToB3.cpp:
    (JSC::FTL::DFG::LowerDFGToB3::compileNewArray):
    (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject):
    * runtime/JSObject.h:
    (JSC::JSObject::createRawObject): Deleted.

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265405 268f45cc-cd09-0410-ab3c-d52691b4dbfc</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari6101branchSourceJavaScriptCoreChangeLog">branches/safari-610.1-branch/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchessafari6101branchSourceJavaScriptCoredfgDFGOperationscpp">branches/safari-610.1-branch/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#branchessafari6101branchSourceJavaScriptCoredfgDFGSpeculativeJITcpp">branches/safari-610.1-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#branchessafari6101branchSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">branches/safari-610.1-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#branchessafari6101branchSourceJavaScriptCoreruntimeJSObjecth">branches/safari-610.1-branch/Source/JavaScriptCore/runtime/JSObject.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari6101branchSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/JavaScriptCore/ChangeLog (265585 => 265586)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/JavaScriptCore/ChangeLog     2020-08-13 01:46:07 UTC (rev 265585)
+++ branches/safari-610.1-branch/Source/JavaScriptCore/ChangeLog        2020-08-13 01:46:10 UTC (rev 265586)
</span><span class="lines">@@ -1,3 +1,111 @@
</span><ins>+2020-08-12  Alan Coon  <alancoon@apple.com>
+
+        Cherry-pick r265405. rdar://problem/66943811
+
+    [JSC] Speculate children first in DFG NewArray
+    https://bugs.webkit.org/show_bug.cgi?id=215308
+    <rdar://problem/64749263>
+    
+    Reviewed by Mark Lam.
+    
+    SpeculativeJIT::emitAllocateRawObject can create uninitialized butterfly since we later fill them.
+    However, DFG NewArray node has speculation after that. So if speculation failure happens, we release
+    half-baked butterfly.
+    
+    Let's see the example.
+    
+       8459         emitAllocateRawObject(resultGPR, structure, storageGPR, numElements, vectorLengthHint);
+       ...
+       8482             case ALL_INT32_INDEXING_TYPES:
+       8483             case ALL_CONTIGUOUS_INDEXING_TYPES: {
+       8484                 JSValueOperand operand(this, use, ManualOperandSpeculation);
+       8485                 JSValueRegs operandRegs = operand.jsValueRegs();
+       8486                 if (hasInt32(node->indexingType())) {
+       8487                     DFG_TYPE_CHECK(
+       8488                         operandRegs, use, SpecInt32Only,
+       8489                         m_jit.branchIfNotInt32(operandRegs));
+       8490                 }
+       8491                 m_jit.storeValue(operandRegs, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx));
+       8492                 break;
+       8493             }
+    
+    L8487-L8489 is doing speculation check. If it failed, the rest of the butterfly can be filled with garbage. This looks OK since
+    it is Int32 butterfly so GC never scans it. However, if have-a-bad-time happens and the array is reachable from the conservative root,
+    this half-baked array is converted from Int32 array to ArrayStorage. At that time, since Int32 butterfly should hold JSInt32,
+    we store this garbage to ArrayStorage. Later, if conservative root still holds this array, and GC scans this garbage as as JSValue,
+    this value confuses GC.
+    
+    In this patch, we first perform speculation before creating uninitialized JSArray so that we can ensure that we never exit after
+    creating this array until we fill it. This strategy is the same to FTL's NewArray implementation.
+    
+    And we also found that emitAllocateRawObject is allocating an object from JSFinalObject space while we use it for JSArray too.
+    We should get per-type allocator to ensure JSArray is allocated in its IsoSubspace.
+    
+    * dfg/DFGOperations.cpp:
+    * dfg/DFGSpeculativeJIT.cpp:
+    (JSC::DFG::SpeculativeJIT::emitAllocateRawObject):
+    (JSC::DFG::SpeculativeJIT::compileNewArray):
+    (JSC::DFG::SpeculativeJIT::compileMaterializeNewObject):
+    * ftl/FTLLowerDFGToB3.cpp:
+    (JSC::FTL::DFG::LowerDFGToB3::compileNewArray):
+    (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject):
+    * runtime/JSObject.h:
+    (JSC::JSObject::createRawObject): Deleted.
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@265405 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-08-08  Yusuke Suzuki  <ysuzuki@apple.com>
+
+            [JSC] Speculate children first in DFG NewArray
+            https://bugs.webkit.org/show_bug.cgi?id=215308
+            <rdar://problem/64749263>
+
+            Reviewed by Mark Lam.
+
+            SpeculativeJIT::emitAllocateRawObject can create uninitialized butterfly since we later fill them.
+            However, DFG NewArray node has speculation after that. So if speculation failure happens, we release
+            half-baked butterfly.
+
+            Let's see the example.
+
+               8459         emitAllocateRawObject(resultGPR, structure, storageGPR, numElements, vectorLengthHint);
+               ...
+               8482             case ALL_INT32_INDEXING_TYPES:
+               8483             case ALL_CONTIGUOUS_INDEXING_TYPES: {
+               8484                 JSValueOperand operand(this, use, ManualOperandSpeculation);
+               8485                 JSValueRegs operandRegs = operand.jsValueRegs();
+               8486                 if (hasInt32(node->indexingType())) {
+               8487                     DFG_TYPE_CHECK(
+               8488                         operandRegs, use, SpecInt32Only,
+               8489                         m_jit.branchIfNotInt32(operandRegs));
+               8490                 }
+               8491                 m_jit.storeValue(operandRegs, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx));
+               8492                 break;
+               8493             }
+
+            L8487-L8489 is doing speculation check. If it failed, the rest of the butterfly can be filled with garbage. This looks OK since
+            it is Int32 butterfly so GC never scans it. However, if have-a-bad-time happens and the array is reachable from the conservative root,
+            this half-baked array is converted from Int32 array to ArrayStorage. At that time, since Int32 butterfly should hold JSInt32,
+            we store this garbage to ArrayStorage. Later, if conservative root still holds this array, and GC scans this garbage as as JSValue,
+            this value confuses GC.
+
+            In this patch, we first perform speculation before creating uninitialized JSArray so that we can ensure that we never exit after
+            creating this array until we fill it. This strategy is the same to FTL's NewArray implementation.
+
+            And we also found that emitAllocateRawObject is allocating an object from JSFinalObject space while we use it for JSArray too.
+            We should get per-type allocator to ensure JSArray is allocated in its IsoSubspace.
+
+            * dfg/DFGOperations.cpp:
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::emitAllocateRawObject):
+            (JSC::DFG::SpeculativeJIT::compileNewArray):
+            (JSC::DFG::SpeculativeJIT::compileMaterializeNewObject):
+            * ftl/FTLLowerDFGToB3.cpp:
+            (JSC::FTL::DFG::LowerDFGToB3::compileNewArray):
+            (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject):
+            * runtime/JSObject.h:
+            (JSC::JSObject::createRawObject): Deleted.
+
</ins><span class="cx"> 2020-08-10  Alan Coon  <alancoon@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Cherry-pick r265272. rdar://problem/66604070
</span></span></pre></div>
<a id="branchessafari6101branchSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/JavaScriptCore/dfg/DFGOperations.cpp (265585 => 265586)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/JavaScriptCore/dfg/DFGOperations.cpp 2020-08-13 01:46:07 UTC (rev 265585)
+++ branches/safari-610.1-branch/Source/JavaScriptCore/dfg/DFGOperations.cpp    2020-08-13 01:46:10 UTC (rev 265586)
</span><span class="lines">@@ -2919,8 +2919,9 @@
</span><span class="cx">             length * sizeof(EncodedJSValue));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    JSObject* result = JSObject::createRawObject(vm, structure, butterfly);
-    return bitwise_cast<char*>(result);
</del><ins>+    if (structure->type() == JSType::ArrayType)
+        return bitwise_cast<char*>(JSArray::createWithButterfly(vm, nullptr, structure, butterfly));
+    return bitwise_cast<char*>(JSFinalObject::create(vm, structure, butterfly));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSCell* JIT_OPERATION operationNewObjectWithButterfly(VM* vmPointer, Structure* structure, Butterfly* butterfly)
</span><span class="lines">@@ -2934,8 +2935,9 @@
</span><span class="cx">             vm, nullptr, 0, structure->outOfLineCapacity(), false, IndexingHeader(), 0);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    JSObject* result = JSObject::createRawObject(vm, structure, butterfly);
-    return result;
</del><ins>+    if (structure->type() == JSType::ArrayType)
+        return JSArray::createWithButterfly(vm, nullptr, structure, butterfly);
+    return JSFinalObject::create(vm, structure, butterfly);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSCell* JIT_OPERATION operationNewObjectWithButterflyWithIndexingHeaderAndVectorLength(VM* vmPointer, Structure* structure, unsigned length, Butterfly* butterfly)
</span><span class="lines">@@ -2955,9 +2957,9 @@
</span><span class="cx">             sizeof(EncodedJSValue) * length);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    // Paradoxically this may allocate a JSArray. That's totally cool.
-    JSObject* result = JSObject::createRawObject(vm, structure, butterfly);
-    return result;
</del><ins>+    if (structure->type() == JSType::ArrayType)
+        return JSArray::createWithButterfly(vm, nullptr, structure, butterfly);
+    return JSFinalObject::create(vm, structure, butterfly);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSCell* JIT_OPERATION operationNewArrayWithSpreadSlow(JSGlobalObject* globalObject, void* buffer, uint32_t numItems)
</span></span></pre></div>
<a id="branchessafari6101branchSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (265585 => 265586)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp     2020-08-13 01:46:07 UTC (rev 265585)
+++ branches/safari-610.1-branch/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2020-08-13 01:46:10 UTC (rev 265586)
</span><span class="lines">@@ -130,8 +130,11 @@
</span><span class="cx">             slowCases.append(m_jit.jump());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    size_t allocationSize = JSFinalObject::allocationSize(inlineCapacity);
-    Allocator allocator = allocatorForNonVirtualConcurrently<JSFinalObject>(vm, allocationSize, AllocatorForMode::AllocatorIfExists);
</del><ins>+    Allocator allocator;
+    if (structure->type() == JSType::ArrayType)
+        allocator = allocatorForNonVirtualConcurrently<JSArray>(vm, JSArray::allocationSize(inlineCapacity), AllocatorForMode::AllocatorIfExists);
+    else
+        allocator = allocatorForNonVirtualConcurrently<JSFinalObject>(vm, JSFinalObject::allocationSize(inlineCapacity), AllocatorForMode::AllocatorIfExists);
</ins><span class="cx">     if (allocator) {
</span><span class="cx">         emitAllocateJSObject(resultGPR, JITAllocator::constant(allocator), scratchGPR, TrustedImmPtr(structure), storageGPR, scratch2GPR, slowCases);
</span><span class="cx">         m_jit.emitInitializeInlineStorage(resultGPR, structure->inlineCapacity());
</span><span class="lines">@@ -8450,6 +8453,11 @@
</span><span class="cx">         unsigned vectorLengthHint = node->vectorLengthHint();
</span><span class="cx">         ASSERT(vectorLengthHint >= numElements);
</span><span class="cx"> 
</span><ins>+        // Because we first speculate on all of the children here, we can never exit after creating
+        // uninitialized contiguous JSArray, which ensures that we will never produce a half-baked JSArray.
+        for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex)
+            speculate(node, m_jit.graph().varArgChild(node, operandIndex));
+
</ins><span class="cx">         GPRTemporary result(this);
</span><span class="cx">         GPRTemporary storage(this);
</span><span class="cx"> 
</span><span class="lines">@@ -8463,8 +8471,8 @@
</span><span class="cx"> 
</span><span class="cx">         ASSERT(!hasUndecided(structure->indexingType()) || !node->numChildren());
</span><span class="cx"> 
</span><del>-        for (unsigned operandIdx = 0; operandIdx < node->numChildren(); ++operandIdx) {
-            Edge use = m_jit.graph().m_varArgChildren[node->firstChild() + operandIdx];
</del><ins>+        for (unsigned operandIndex = 0; operandIndex < node->numChildren(); ++operandIndex) {
+            Edge use = m_jit.graph().varArgChild(node, operandIndex);
</ins><span class="cx">             switch (node->indexingType()) {
</span><span class="cx">             case ALL_BLANK_INDEXING_TYPES:
</span><span class="cx">             case ALL_UNDECIDED_INDEXING_TYPES:
</span><span class="lines">@@ -8473,10 +8481,7 @@
</span><span class="cx">             case ALL_DOUBLE_INDEXING_TYPES: {
</span><span class="cx">                 SpeculateDoubleOperand operand(this, use);
</span><span class="cx">                 FPRReg opFPR = operand.fpr();
</span><del>-                DFG_TYPE_CHECK(
-                    JSValueRegs(), use, SpecDoubleReal,
-                    m_jit.branchIfNaN(opFPR));
-                m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIdx));
</del><ins>+                m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIndex));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             case ALL_INT32_INDEXING_TYPES:
</span><span class="lines">@@ -8483,12 +8488,7 @@
</span><span class="cx">             case ALL_CONTIGUOUS_INDEXING_TYPES: {
</span><span class="cx">                 JSValueOperand operand(this, use, ManualOperandSpeculation);
</span><span class="cx">                 JSValueRegs operandRegs = operand.jsValueRegs();
</span><del>-                if (hasInt32(node->indexingType())) {
-                    DFG_TYPE_CHECK(
-                        operandRegs, use, SpecInt32Only,
-                        m_jit.branchIfNotInt32(operandRegs));
-                }
-                m_jit.storeValue(operandRegs, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx));
</del><ins>+                m_jit.storeValue(operandRegs, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIndex));
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             default:
</span><span class="lines">@@ -12233,6 +12233,8 @@
</span><span class="cx">     GPRReg storageGPR = storage.gpr();
</span><span class="cx">     
</span><span class="cx">     emitAllocateRawObject(resultGPR, structure, storageGPR, 0, vectorLength);
</span><ins>+
+    // After the allocation, we must not exit until we fill butterfly completely.
</ins><span class="cx">     
</span><span class="cx">     m_jit.store32(
</span><span class="cx">         JITCompiler::TrustedImm32(publicLength),
</span></span></pre></div>
<a id="branchessafari6101branchSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (265585 => 265586)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp       2020-08-13 01:46:07 UTC (rev 265585)
+++ branches/safari-610.1-branch/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp  2020-08-13 01:46:10 UTC (rev 265586)
</span><span class="lines">@@ -6751,6 +6751,8 @@
</span><span class="cx">         // that doing the speculations up here might be unprofitable for RA - so we can consider
</span><span class="cx">         // sinking this to below the allocation fast path if we find that this has a lot of
</span><span class="cx">         // register pressure.
</span><ins>+        // Because we first speculate on all of the children here, we can never exit after creating
+        // uninitialized contiguous JSArray, which ensures that we will never produce a half-baked JSArray.
</ins><span class="cx">         for (unsigned operandIndex = 0; operandIndex < m_node->numChildren(); ++operandIndex)
</span><span class="cx">             speculate(m_graph.varArgChild(m_node, operandIndex));
</span><span class="cx">         
</span><span class="lines">@@ -12558,8 +12560,11 @@
</span><span class="cx">             LValue butterfly;
</span><span class="cx">             
</span><span class="cx">             if (structure->outOfLineCapacity() || hasIndexedProperties(structure->indexingType())) {
</span><del>-                size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
-                Allocator cellAllocator = allocatorForNonVirtualConcurrently<JSFinalObject>(vm(), allocationSize, AllocatorForMode::AllocatorIfExists);
</del><ins>+                Allocator cellAllocator;
+                if (structure->type() == JSType::ArrayType)
+                    cellAllocator = allocatorForNonVirtualConcurrently<JSArray>(vm(), JSArray::allocationSize(structure->inlineCapacity()), AllocatorForMode::AllocatorIfExists);
+                else
+                    cellAllocator = allocatorForNonVirtualConcurrently<JSFinalObject>(vm(), JSFinalObject::allocationSize(structure->inlineCapacity()), AllocatorForMode::AllocatorIfExists);
</ins><span class="cx"> 
</span><span class="cx">                 bool hasIndexingHeader = hasIndexedProperties(structure->indexingType());
</span><span class="cx">                 unsigned indexingHeaderSize = 0;
</span></span></pre></div>
<a id="branchessafari6101branchSourceJavaScriptCoreruntimeJSObjecth"></a>
<div class="modfile"><h4>Modified: branches/safari-610.1-branch/Source/JavaScriptCore/runtime/JSObject.h (265585 => 265586)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-610.1-branch/Source/JavaScriptCore/runtime/JSObject.h    2020-08-13 01:46:07 UTC (rev 265585)
+++ branches/safari-610.1-branch/Source/JavaScriptCore/runtime/JSObject.h       2020-08-13 01:46:10 UTC (rev 265586)
</span><span class="lines">@@ -114,10 +114,6 @@
</span><span class="cx"> public:
</span><span class="cx">     using Base = JSCell;
</span><span class="cx"> 
</span><del>-    // This is a super dangerous method for JITs. Sometimes the JITs will want to create either a
-    // JSFinalObject or a JSArray. This is the method that will do that.
-    static JSObject* createRawObject(VM& vm, Structure* structure, Butterfly* = nullptr);
-
</del><span class="cx">     JS_EXPORT_PRIVATE static size_t estimatedSize(JSCell*, VM&);
</span><span class="cx">     JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
</span><span class="cx">     JS_EXPORT_PRIVATE static void analyzeHeap(JSCell*, HeapAnalyzer&);
</span><span class="lines">@@ -1244,19 +1240,6 @@
</span><span class="cx"> 
</span><span class="cx"> JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL objectPrivateFuncInstanceOf(JSGlobalObject*, CallFrame*);
</span><span class="cx"> 
</span><del>-inline JSObject* JSObject::createRawObject(VM& vm, Structure* structure, Butterfly* butterfly)
-{
-    JSObject* finalObject = new (
-        NotNull, 
-        allocateCell<JSFinalObject>(
-            vm.heap,
-            JSFinalObject::allocationSize(structure->inlineCapacity())
-        )
-    ) JSObject(vm, structure, butterfly);
-    finalObject->finishCreation(vm);
-    return finalObject;
-}
-
</del><span class="cx"> inline JSFinalObject* JSFinalObject::create(VM& vm, Structure* structure, Butterfly* butterfly)
</span><span class="cx"> {
</span><span class="cx">     JSFinalObject* finalObject = new (
</span></span></pre>
</div>
</div>

</body>
</html>