<!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>[199275] 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/199275">199275</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-04-09 13:41:04 -0700 (Sat, 09 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Debug JSC test failure: stress/multi-put-by-offset-reallocation-butterfly-cse.js.ftl-no-cjit-small-pool
https://bugs.webkit.org/show_bug.cgi?id=156406

Reviewed by Saam Barati.

The failure was because the GC ran from within the butterfly allocation call in a put_by_id
transition AccessCase that had to deal with indexing storage. When the GC runs in a call from a stub,
then we need to be extra careful:

1) The GC may reset the IC and delete the stub. So, the stub needs to tell the GC that it might be on
   the stack during GC, so that the GC keeps it alive if it's currently running.
        
2) If the stub uses (dereferences or stores) some object after the call, then we need to ensure that
   the stub routine knows about that object independently of the IC.
        
In the case of put_by_id transitions that use a helper to allocate the butterfly, we have both
issues. A long time ago, we had to deal with (2), and we still had code to handle that case, although
it appears to be dead. This change revives that code and glues it together with PolymorphicAccess.

* bytecode/PolymorphicAccess.cpp:
(JSC::AccessCase::alternateBase):
(JSC::AccessCase::doesCalls):
(JSC::AccessCase::couldStillSucceed):
(JSC::AccessCase::generate):
(JSC::PolymorphicAccess::regenerate):
* bytecode/PolymorphicAccess.h:
(JSC::AccessCase::customSlotBase):
(JSC::AccessCase::isGetter):
(JSC::AccessCase::doesCalls): Deleted.
* jit/GCAwareJITStubRoutine.cpp:
(JSC::GCAwareJITStubRoutine::markRequiredObjectsInternal):
(JSC::MarkingGCAwareJITStubRoutine::MarkingGCAwareJITStubRoutine):
(JSC::MarkingGCAwareJITStubRoutine::~MarkingGCAwareJITStubRoutine):
(JSC::MarkingGCAwareJITStubRoutine::markRequiredObjectsInternal):
(JSC::GCAwareJITStubRoutineWithExceptionHandler::GCAwareJITStubRoutineWithExceptionHandler):
(JSC::createJITStubRoutine):
(JSC::MarkingGCAwareJITStubRoutineWithOneObject::MarkingGCAwareJITStubRoutineWithOneObject): Deleted.
(JSC::MarkingGCAwareJITStubRoutineWithOneObject::~MarkingGCAwareJITStubRoutineWithOneObject): Deleted.
(JSC::MarkingGCAwareJITStubRoutineWithOneObject::markRequiredObjectsInternal): Deleted.
* jit/GCAwareJITStubRoutine.h:
(JSC::createJITStubRoutine):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicAccesscpp">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicAccessh">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitGCAwareJITStubRoutinecpp">trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitGCAwareJITStubRoutineh">trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (199274 => 199275)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-04-09 20:13:12 UTC (rev 199274)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-04-09 20:41:04 UTC (rev 199275)
</span><span class="lines">@@ -1,3 +1,47 @@
</span><ins>+2016-04-09  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Debug JSC test failure: stress/multi-put-by-offset-reallocation-butterfly-cse.js.ftl-no-cjit-small-pool
+        https://bugs.webkit.org/show_bug.cgi?id=156406
+
+        Reviewed by Saam Barati.
+
+        The failure was because the GC ran from within the butterfly allocation call in a put_by_id
+        transition AccessCase that had to deal with indexing storage. When the GC runs in a call from a stub,
+        then we need to be extra careful:
+
+        1) The GC may reset the IC and delete the stub. So, the stub needs to tell the GC that it might be on
+           the stack during GC, so that the GC keeps it alive if it's currently running.
+        
+        2) If the stub uses (dereferences or stores) some object after the call, then we need to ensure that
+           the stub routine knows about that object independently of the IC.
+        
+        In the case of put_by_id transitions that use a helper to allocate the butterfly, we have both
+        issues. A long time ago, we had to deal with (2), and we still had code to handle that case, although
+        it appears to be dead. This change revives that code and glues it together with PolymorphicAccess.
+
+        * bytecode/PolymorphicAccess.cpp:
+        (JSC::AccessCase::alternateBase):
+        (JSC::AccessCase::doesCalls):
+        (JSC::AccessCase::couldStillSucceed):
+        (JSC::AccessCase::generate):
+        (JSC::PolymorphicAccess::regenerate):
+        * bytecode/PolymorphicAccess.h:
+        (JSC::AccessCase::customSlotBase):
+        (JSC::AccessCase::isGetter):
+        (JSC::AccessCase::doesCalls): Deleted.
+        * jit/GCAwareJITStubRoutine.cpp:
+        (JSC::GCAwareJITStubRoutine::markRequiredObjectsInternal):
+        (JSC::MarkingGCAwareJITStubRoutine::MarkingGCAwareJITStubRoutine):
+        (JSC::MarkingGCAwareJITStubRoutine::~MarkingGCAwareJITStubRoutine):
+        (JSC::MarkingGCAwareJITStubRoutine::markRequiredObjectsInternal):
+        (JSC::GCAwareJITStubRoutineWithExceptionHandler::GCAwareJITStubRoutineWithExceptionHandler):
+        (JSC::createJITStubRoutine):
+        (JSC::MarkingGCAwareJITStubRoutineWithOneObject::MarkingGCAwareJITStubRoutineWithOneObject): Deleted.
+        (JSC::MarkingGCAwareJITStubRoutineWithOneObject::~MarkingGCAwareJITStubRoutineWithOneObject): Deleted.
+        (JSC::MarkingGCAwareJITStubRoutineWithOneObject::markRequiredObjectsInternal): Deleted.
+        * jit/GCAwareJITStubRoutine.h:
+        (JSC::createJITStubRoutine):
+
</ins><span class="cx"> 2016-04-08  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: XHRs and Web Worker scripts are not searchable
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (199274 => 199275)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2016-04-09 20:13:12 UTC (rev 199274)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2016-04-09 20:41:04 UTC (rev 199275)
</span><span class="lines">@@ -413,6 +413,29 @@
</span><span class="cx">     return conditionSet().slotBaseCondition().object();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool AccessCase::doesCalls(Vector&lt;JSCell*&gt;* cellsToMark) const
+{
+    switch (type()) {
+    case Getter:
+    case Setter:
+    case CustomValueGetter:
+    case CustomAccessorGetter:
+    case CustomValueSetter:
+    case CustomAccessorSetter:
+        return true;
+    case Transition:
+        if (newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity()
+            &amp;&amp; structure()-&gt;couldHaveIndexingHeader()) {
+            if (cellsToMark)
+                cellsToMark-&gt;append(newStructure());
+            return true;
+        }
+        return false;
+    default:
+        return false;
+    }
+}
+
</ins><span class="cx"> bool AccessCase::couldStillSucceed() const
</span><span class="cx"> {
</span><span class="cx">     return m_conditionSet.structuresEnsureValidityAssumingImpurePropertyWatchpoint();
</span><span class="lines">@@ -1093,6 +1116,8 @@
</span><span class="cx">         } else if (verbose)
</span><span class="cx">             dataLog(&quot;Don't have type.\n&quot;);
</span><span class="cx">         
</span><ins>+        // NOTE: This logic is duplicated in AccessCase::doesCalls(). It's important that doesCalls() knows
+        // exactly when this would make calls.
</ins><span class="cx">         bool allocating = newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity();
</span><span class="cx">         bool reallocating = allocating &amp;&amp; structure()-&gt;outOfLineCapacity();
</span><span class="cx">         bool allocatingInline = allocating &amp;&amp; !structure()-&gt;couldHaveIndexingHeader();
</span><span class="lines">@@ -1632,10 +1657,11 @@
</span><span class="cx">         (&quot;%s&quot;, toCString(&quot;Access stub for &quot;, *codeBlock, &quot; &quot;, stubInfo.codeOrigin, &quot; with return point &quot;, successLabel, &quot;: &quot;, listDump(cases)).data()));
</span><span class="cx"> 
</span><span class="cx">     bool doesCalls = false;
</span><ins>+    Vector&lt;JSCell*&gt; cellsToMark;
</ins><span class="cx">     for (auto&amp; entry : cases)
</span><del>-        doesCalls |= entry-&gt;doesCalls();
</del><ins>+        doesCalls |= entry-&gt;doesCalls(&amp;cellsToMark);
</ins><span class="cx">     
</span><del>-    m_stubRoutine = createJITStubRoutine(code, vm, codeBlock, doesCalls, nullptr, codeBlockThatOwnsExceptionHandlers, callSiteIndexForExceptionHandling);
</del><ins>+    m_stubRoutine = createJITStubRoutine(code, vm, codeBlock, doesCalls, cellsToMark, codeBlockThatOwnsExceptionHandlers, callSiteIndexForExceptionHandling);
</ins><span class="cx">     m_watchpoints = WTFMove(state.watchpoints);
</span><span class="cx">     if (!state.weakReferences.isEmpty())
</span><span class="cx">         m_weakReferences = std::make_unique&lt;Vector&lt;WriteBarrier&lt;JSCell&gt;&gt;&gt;(WTFMove(state.weakReferences));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h (199274 => 199275)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2016-04-09 20:13:12 UTC (rev 199274)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2016-04-09 20:41:04 UTC (rev 199275)
</span><span class="lines">@@ -153,22 +153,11 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     JSObject* alternateBase() const;
</span><del>-    
-    bool doesCalls() const
-    {
-        switch (type()) {
-        case Getter:
-        case Setter:
-        case CustomValueGetter:
-        case CustomAccessorGetter:
-        case CustomValueSetter:
-        case CustomAccessorSetter:
-            return true;
-        default:
-            return false;
-        }
-    }
</del><span class="cx"> 
</span><ins>+    // If you supply the optional vector, this will append the set of cells that this will need to keep alive
+    // past the call.
+    bool doesCalls(Vector&lt;JSCell*&gt;* cellsToMark = nullptr) const;
+
</ins><span class="cx">     bool isGetter() const
</span><span class="cx">     {
</span><span class="cx">         switch (type()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitGCAwareJITStubRoutinecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp (199274 => 199275)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp        2016-04-09 20:13:12 UTC (rev 199274)
+++ trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.cpp        2016-04-09 20:41:04 UTC (rev 199275)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2016 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">@@ -79,28 +79,31 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-MarkingGCAwareJITStubRoutineWithOneObject::MarkingGCAwareJITStubRoutineWithOneObject(
</del><ins>+MarkingGCAwareJITStubRoutine::MarkingGCAwareJITStubRoutine(
</ins><span class="cx">     const MacroAssemblerCodeRef&amp; code, VM&amp; vm, const JSCell* owner,
</span><del>-    JSCell* object)
</del><ins>+    const Vector&lt;JSCell*&gt;&amp; cells)
</ins><span class="cx">     : GCAwareJITStubRoutine(code, vm)
</span><del>-    , m_object(vm, owner, object)
</del><ins>+    , m_cells(cells.size())
</ins><span class="cx"> {
</span><ins>+    for (unsigned i = cells.size(); i--;)
+        m_cells[i].set(vm, owner, cells[i]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-MarkingGCAwareJITStubRoutineWithOneObject::~MarkingGCAwareJITStubRoutineWithOneObject()
</del><ins>+MarkingGCAwareJITStubRoutine::~MarkingGCAwareJITStubRoutine()
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void MarkingGCAwareJITStubRoutineWithOneObject::markRequiredObjectsInternal(SlotVisitor&amp; visitor)
</del><ins>+void MarkingGCAwareJITStubRoutine::markRequiredObjectsInternal(SlotVisitor&amp; visitor)
</ins><span class="cx"> {
</span><del>-    visitor.append(&amp;m_object);
</del><ins>+    for (auto&amp; entry : m_cells)
+        visitor.append(&amp;entry);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> GCAwareJITStubRoutineWithExceptionHandler::GCAwareJITStubRoutineWithExceptionHandler(
</span><del>-    const MacroAssemblerCodeRef&amp; code, VM&amp; vm, 
</del><ins>+    const MacroAssemblerCodeRef&amp; code, VM&amp; vm,  const JSCell* owner, const Vector&lt;JSCell*&gt;&amp; cells,
</ins><span class="cx">     CodeBlock* codeBlockForExceptionHandlers, CallSiteIndex exceptionHandlerCallSiteIndex)
</span><del>-    : GCAwareJITStubRoutine(code, vm)
</del><ins>+    : MarkingGCAwareJITStubRoutine(code, vm, owner, cells)
</ins><span class="cx">     , m_codeBlockWithExceptionHandler(codeBlockForExceptionHandlers)
</span><span class="cx">     , m_exceptionHandlerCallSiteIndex(exceptionHandlerCallSiteIndex)
</span><span class="cx"> {
</span><span class="lines">@@ -132,7 +135,7 @@
</span><span class="cx">     VM&amp; vm,
</span><span class="cx">     const JSCell* owner,
</span><span class="cx">     bool makesCalls,
</span><del>-    JSCell* object,
</del><ins>+    const Vector&lt;JSCell*&gt;&amp; cells,
</ins><span class="cx">     CodeBlock* codeBlockForExceptionHandlers,
</span><span class="cx">     CallSiteIndex exceptionHandlerCallSiteIndex)
</span><span class="cx"> {
</span><span class="lines">@@ -140,19 +143,18 @@
</span><span class="cx">         return adoptRef(new JITStubRoutine(code));
</span><span class="cx">     
</span><span class="cx">     if (codeBlockForExceptionHandlers) {
</span><del>-        RELEASE_ASSERT(!object); // We're not a marking stub routine.
</del><span class="cx">         RELEASE_ASSERT(JITCode::isOptimizingJIT(codeBlockForExceptionHandlers-&gt;jitType()));
</span><span class="cx">         return static_pointer_cast&lt;JITStubRoutine&gt;(
</span><del>-            adoptRef(new GCAwareJITStubRoutineWithExceptionHandler(code, vm, codeBlockForExceptionHandlers, exceptionHandlerCallSiteIndex)));
</del><ins>+            adoptRef(new GCAwareJITStubRoutineWithExceptionHandler(code, vm, owner, cells, codeBlockForExceptionHandlers, exceptionHandlerCallSiteIndex)));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!object) {
</del><ins>+    if (cells.isEmpty()) {
</ins><span class="cx">         return static_pointer_cast&lt;JITStubRoutine&gt;(
</span><span class="cx">             adoptRef(new GCAwareJITStubRoutine(code, vm)));
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     return static_pointer_cast&lt;JITStubRoutine&gt;(
</span><del>-        adoptRef(new MarkingGCAwareJITStubRoutineWithOneObject(code, vm, owner, object)));
</del><ins>+        adoptRef(new MarkingGCAwareJITStubRoutine(code, vm, owner, cells)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitGCAwareJITStubRoutineh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h (199274 => 199275)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h        2016-04-09 20:13:12 UTC (rev 199274)
+++ trunk/Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h        2016-04-09 20:41:04 UTC (rev 199275)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2014, 2016 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">@@ -76,28 +76,28 @@
</span><span class="cx"> 
</span><span class="cx"> // Use this if you want to mark one additional object during GC if your stub
</span><span class="cx"> // routine is known to be executing.
</span><del>-class MarkingGCAwareJITStubRoutineWithOneObject : public GCAwareJITStubRoutine {
</del><ins>+class MarkingGCAwareJITStubRoutine : public GCAwareJITStubRoutine {
</ins><span class="cx"> public:
</span><del>-    MarkingGCAwareJITStubRoutineWithOneObject(
-        const MacroAssemblerCodeRef&amp;, VM&amp;, const JSCell* owner, JSCell*);
-    virtual ~MarkingGCAwareJITStubRoutineWithOneObject();
</del><ins>+    MarkingGCAwareJITStubRoutine(
+        const MacroAssemblerCodeRef&amp;, VM&amp;, const JSCell* owner, const Vector&lt;JSCell*&gt;&amp;);
+    virtual ~MarkingGCAwareJITStubRoutine();
</ins><span class="cx">     
</span><span class="cx"> protected:
</span><span class="cx">     void markRequiredObjectsInternal(SlotVisitor&amp;) override;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    WriteBarrier&lt;JSCell&gt; m_object;
</del><ins>+    Vector&lt;WriteBarrier&lt;JSCell&gt;&gt; m_cells;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> // The stub has exception handlers in it. So it clears itself from exception
</span><span class="cx"> // handling table when it dies. It also frees space in CodeOrigin table
</span><span class="cx"> // for new exception handlers to use the same CallSiteIndex.
</span><del>-class GCAwareJITStubRoutineWithExceptionHandler : public GCAwareJITStubRoutine {
</del><ins>+class GCAwareJITStubRoutineWithExceptionHandler : public MarkingGCAwareJITStubRoutine {
</ins><span class="cx"> public:
</span><span class="cx">     typedef GCAwareJITStubRoutine Base;
</span><span class="cx"> 
</span><del>-    GCAwareJITStubRoutineWithExceptionHandler(const MacroAssemblerCodeRef&amp;, VM&amp;, CodeBlock*, CallSiteIndex);
</del><ins>+    GCAwareJITStubRoutineWithExceptionHandler(const MacroAssemblerCodeRef&amp;, VM&amp;, const JSCell* owner, const Vector&lt;JSCell*&gt;&amp;, CodeBlock*, CallSiteIndex);
</ins><span class="cx"> 
</span><span class="cx">     void aboutToDie() override;
</span><span class="cx">     void observeZeroRefCount() override;
</span><span class="lines">@@ -128,14 +128,9 @@
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;JITStubRoutine&gt; createJITStubRoutine(
</span><span class="cx">     const MacroAssemblerCodeRef&amp;, VM&amp;, const JSCell* owner, bool makesCalls,
</span><del>-    JSCell* = nullptr, 
</del><ins>+    const Vector&lt;JSCell*&gt;&amp; = { }, 
</ins><span class="cx">     CodeBlock* codeBlockForExceptionHandlers = nullptr, CallSiteIndex exceptionHandlingCallSiteIndex = CallSiteIndex(std::numeric_limits&lt;unsigned&gt;::max()));
</span><span class="cx"> 
</span><del>-// Helper for the creation of simple stub routines that need no help from the GC. Note
-// that codeBlock gets &quot;executed&quot; more than once.
-#define FINALIZE_CODE_FOR_GC_AWARE_STUB(codeBlock, patchBuffer, makesCalls, cell, dataLogFArguments) \
-    (createJITStubRoutine(FINALIZE_CODE_FOR((codeBlock), (patchBuffer), dataLogFArguments), *(codeBlock)-&gt;vm(), (codeBlock), (makesCalls), (cell)))
-
</del><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(JIT)
</span></span></pre>
</div>
</div>

</body>
</html>