<!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>[161927] branches/jsCStack/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/161927">161927</a></dd>
<dt>Author</dt> <dd>mark.lam@apple.com</dd>
<dt>Date</dt> <dd>2014-01-13 17:08:05 -0800 (Mon, 13 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>CStack: Fix 64-bit C Loop LLINT.
https://bugs.webkit.org/show_bug.cgi?id=126790.

Reviewed by Geoffrey Garen.

1. Fixed miscellaneous bugs relevant for the C Loop LLINT (details below).

2. Simplified CLoop::execute() by making it more emulate CPU calls as well.
   This is done by automatically synthesizing an opcode label at the return
   point after the call to JS code. The &quot;lr&quot; register (named after the ARM
   link register) will be set to that return opcode label before the call.
   The call itself is implemented as an opcode dispatch.

* heap/Heap.cpp:
(JSC::Heap::markRoots):
- Fixed typo: LLINT_CLOOP ==&gt; LLINT_C_LOOP.
* interpreter/JSStack.cpp:
(JSC::JSStack::gatherConservativeRoots):
- Previously, we were declaring a span from baseOfStack() to topOfStack().
  baseOfStack() points to the highest slot in the stack.
  topOfStack() points to the word below the lowest slot in the stack.
  The ConservativeRoots class will invert the high and low pointers to
  ensure that it iterates from low to high. However, with this span, the
  GC will miss not scan the highest slot in the stack, and will instead
  scan the slot below the stack which is technically outside the stack.

  The span is now fixed to be from topOfStack() + 1 to highAddress().
  highAddress() points at the slot above the highest slot in the stack.
  This means GC will now correctly scan the stack from its lowest to its
  highest slots (inclusive).

(JSC::JSStack::sanitizeStack):
- Similar to the gatherConservativeRoots() case, sanitizeStack() is
  nullifying a span of stack that starts at 2 past the lowest slot in
  the stack.

  This is because topOfStack() points at the slot below the lowest slot
  in the stack. m_lastStackTop() points to an old topOfStack() i.e. it
  potentially points to a slot that is not in the region of memory
  allocated for the stack.

  We now add 1 to both of these values to ensure that we're zeroing a
  region that is in the stack's allocated memory, and stop at the slot
  (inclusive) just below the stack's current lowest used slot.

* interpreter/JSStack.h:
* interpreter/JSStackInlines.h:
- Made topOfStack() public because CLoop::execute() needs it.
- The LLINT assembly (in CLoop::execute()) now takes care of pushing
  and popping the stack. Hence, we no longer need JSStack's pushFrame,
  popFrame, and stack fence infrastruture which relies on pushFrame
  and popFrame. These are now removed.

* llint/LLIntOpcode.h:
- Added new pseudo opcodes:
  - llint_return_to_host: this is the pseudo return address for returning
    to the host i.e. return from CLoop::execute().
  - llint_cloop_did_return_from_js_X: these are synthesized by the cloop offlineasm
    as needed i.e. every time it needs to generate code for a cloopCallJSFunction
    &quot;instruction&quot;. These are the opcodes that will serve as the return point
    that we store in lr and return to when we see a &quot;ret&quot; opcode.

    While the offlineasm automatically generates these in LLIntAssembly.h,
    we have to manually add the declaration of these opcodes here. If we end
    up generating more or less in the future (due to changes in the LLINT
    assembly code), then we'll get compiler errors that will tell us to
    update this list.

* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::llint_stack_check_at_vm_entry):
* llint/LLIntSlowPaths.h:
- This slow path isn't needed for the non C loop build because the stack is
  finite sized and grows itself on access. For the C loop, we need this check
  function to give the JSStack a chance to grow the stack.

* llint/LowLevelInterpreter64.asm:
- Added call to llint_stack_check_at_vm_entry in doCallToJavaScript().
- Fixed up calls and stack adjustments.

- In makeHostFunctionCall(), the non C loop build will push lr and cfr when
  we call the host function. That's why we adjust the sp by 16 before the call.
  For the C loop build, we need to set the lr and cfr ourselves here.

- In nativeCallTrampoline(), unlike makeHostFunctionCall(), the return address
  and cfr has already been set in the frame. Hence, we didn't have to do
  anything extra. Also got rid of the distinct block for the C_LOOP and just
  reuse the block for ARM64 since it is exactly what the C_LOOP needs for
  the most part.

* llint/LowLevelInterpreter.asm:
- Added push/pop or lr and cfr as needed.
- In callTargetFunction(), make the C_LOOP use the same code as other
  targets except for the call instruction.
- Same for slowPathForCall().
- In prologue(), exclude the OSR check code for the C_LOOP build since it
  is not needed. Also added popping of cfr and lr since I'm working through
  this logic already.

* llint/LowLevelInterpreter.cpp:
(JSC::CLoopRegister::operator Register*):
(JSC::CLoop::execute):
- Added TRACE_OPCODE() for debugging use only.
- Simplified some CLoopRegister names.
- Initialize the needed registers and incoming arguments before entering
  the interpreter loop.
- Added llint_return_to_host as the exit opcode for returning from
  CLoop::execute(). We set it as the value for lr (the return address)
  before we enter the interpreter loop.
- Updated the getHostCallReturnValue opcode handler to match the current
  getHostCallReturnValue and getHostCallReturnValueWithExecState code in
  JITOperations.cpp.

* offlineasm/cloop.rb:
- Updated C loop register names.
- Added tracking of the number of cloop_did_return_from_js labels.
- Added push, pop, and change the implementation of the cloopCallJSFunction
  pseudo instruction to use synthesized cloop_did_return_from_js opcodes
  / labels as return addresses.

* runtime/Executable.cpp:
- Fix C loop build breaker by a prior patch.

* runtime/VM.cpp:
(JSC::VM::VM):
- Fixed typo: LLINT_CLOOP ==&gt; LLINT_C_LOOP.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsCStackSourceJavaScriptCoreChangeLog">branches/jsCStack/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreheapHeapcpp">branches/jsCStack/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterJSStackcpp">branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterJSStackh">branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreinterpreterJSStackInlinesh">branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntOpcodeh">branches/jsCStack/Source/JavaScriptCore/llint/LLIntOpcode.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp">branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathsh">branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreterasm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpretercpp">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter64asm">branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreofflineasmclooprb">branches/jsCStack/Source/JavaScriptCore/offlineasm/cloop.rb</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreruntimeExecutablecpp">branches/jsCStack/Source/JavaScriptCore/runtime/Executable.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreruntimeVMcpp">branches/jsCStack/Source/JavaScriptCore/runtime/VM.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsCStackSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ChangeLog (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -1,3 +1,131 @@
</span><ins>+2014-01-13  Mark Lam  &lt;mark.lam@apple.com&gt;
+
+        CStack: Fix 64-bit C Loop LLINT.
+        https://bugs.webkit.org/show_bug.cgi?id=126790.
+
+        Reviewed by Geoffrey Garen.
+
+        1. Fixed miscellaneous bugs relevant for the C Loop LLINT (details below).
+
+        2. Simplified CLoop::execute() by making it more emulate CPU calls as well.
+           This is done by automatically synthesizing an opcode label at the return
+           point after the call to JS code. The &quot;lr&quot; register (named after the ARM
+           link register) will be set to that return opcode label before the call.
+           The call itself is implemented as an opcode dispatch.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        - Fixed typo: LLINT_CLOOP ==&gt; LLINT_C_LOOP.
+        * interpreter/JSStack.cpp:
+        (JSC::JSStack::gatherConservativeRoots):
+        - Previously, we were declaring a span from baseOfStack() to topOfStack().
+          baseOfStack() points to the highest slot in the stack.
+          topOfStack() points to the word below the lowest slot in the stack.
+          The ConservativeRoots class will invert the high and low pointers to
+          ensure that it iterates from low to high. However, with this span, the
+          GC will miss not scan the highest slot in the stack, and will instead
+          scan the slot below the stack which is technically outside the stack.
+
+          The span is now fixed to be from topOfStack() + 1 to highAddress().
+          highAddress() points at the slot above the highest slot in the stack.
+          This means GC will now correctly scan the stack from its lowest to its
+          highest slots (inclusive).
+
+        (JSC::JSStack::sanitizeStack):
+        - Similar to the gatherConservativeRoots() case, sanitizeStack() is
+          nullifying a span of stack that starts at 2 past the lowest slot in
+          the stack.
+
+          This is because topOfStack() points at the slot below the lowest slot
+          in the stack. m_lastStackTop() points to an old topOfStack() i.e. it
+          potentially points to a slot that is not in the region of memory
+          allocated for the stack.
+
+          We now add 1 to both of these values to ensure that we're zeroing a
+          region that is in the stack's allocated memory, and stop at the slot
+          (inclusive) just below the stack's current lowest used slot.
+
+        * interpreter/JSStack.h:
+        * interpreter/JSStackInlines.h:
+        - Made topOfStack() public because CLoop::execute() needs it.
+        - The LLINT assembly (in CLoop::execute()) now takes care of pushing
+          and popping the stack. Hence, we no longer need JSStack's pushFrame,
+          popFrame, and stack fence infrastruture which relies on pushFrame
+          and popFrame. These are now removed.
+
+        * llint/LLIntOpcode.h:
+        - Added new pseudo opcodes:
+          - llint_return_to_host: this is the pseudo return address for returning
+            to the host i.e. return from CLoop::execute().
+          - llint_cloop_did_return_from_js_X: these are synthesized by the cloop offlineasm
+            as needed i.e. every time it needs to generate code for a cloopCallJSFunction
+            &quot;instruction&quot;. These are the opcodes that will serve as the return point
+            that we store in lr and return to when we see a &quot;ret&quot; opcode.
+
+            While the offlineasm automatically generates these in LLIntAssembly.h,
+            we have to manually add the declaration of these opcodes here. If we end
+            up generating more or less in the future (due to changes in the LLINT
+            assembly code), then we'll get compiler errors that will tell us to
+            update this list.
+
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::llint_stack_check_at_vm_entry):
+        * llint/LLIntSlowPaths.h:
+        - This slow path isn't needed for the non C loop build because the stack is
+          finite sized and grows itself on access. For the C loop, we need this check
+          function to give the JSStack a chance to grow the stack.
+
+        * llint/LowLevelInterpreter64.asm:
+        - Added call to llint_stack_check_at_vm_entry in doCallToJavaScript().
+        - Fixed up calls and stack adjustments.
+
+        - In makeHostFunctionCall(), the non C loop build will push lr and cfr when
+          we call the host function. That's why we adjust the sp by 16 before the call.
+          For the C loop build, we need to set the lr and cfr ourselves here.
+
+        - In nativeCallTrampoline(), unlike makeHostFunctionCall(), the return address
+          and cfr has already been set in the frame. Hence, we didn't have to do
+          anything extra. Also got rid of the distinct block for the C_LOOP and just
+          reuse the block for ARM64 since it is exactly what the C_LOOP needs for
+          the most part.
+
+        * llint/LowLevelInterpreter.asm:
+        - Added push/pop or lr and cfr as needed.
+        - In callTargetFunction(), make the C_LOOP use the same code as other
+          targets except for the call instruction.
+        - Same for slowPathForCall().
+        - In prologue(), exclude the OSR check code for the C_LOOP build since it
+          is not needed. Also added popping of cfr and lr since I'm working through
+          this logic already.
+
+        * llint/LowLevelInterpreter.cpp:
+        (JSC::CLoopRegister::operator Register*):
+        (JSC::CLoop::execute):
+        - Added TRACE_OPCODE() for debugging use only.
+        - Simplified some CLoopRegister names.
+        - Initialize the needed registers and incoming arguments before entering
+          the interpreter loop.
+        - Added llint_return_to_host as the exit opcode for returning from
+          CLoop::execute(). We set it as the value for lr (the return address)
+          before we enter the interpreter loop.
+        - Updated the getHostCallReturnValue opcode handler to match the current
+          getHostCallReturnValue and getHostCallReturnValueWithExecState code in
+          JITOperations.cpp.
+
+        * offlineasm/cloop.rb:
+        - Updated C loop register names.
+        - Added tracking of the number of cloop_did_return_from_js labels.
+        - Added push, pop, and change the implementation of the cloopCallJSFunction
+          pseudo instruction to use synthesized cloop_did_return_from_js opcodes
+          / labels as return addresses.
+
+        * runtime/Executable.cpp:
+        - Fix C loop build breaker by a prior patch.
+
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        - Fixed typo: LLINT_CLOOP ==&gt; LLINT_C_LOOP.
+
</ins><span class="cx"> 2014-01-13  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         CStack Branch: Fix unwind on branch for X86-64
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/heap/Heap.cpp (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/heap/Heap.cpp        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/heap/Heap.cpp        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2013 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2007 Eric Seidel &lt;eric@webkit.org&gt;
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -459,7 +459,7 @@
</span><span class="cx">         m_machineThreads.gatherConservativeRoots(machineThreadRoots, m_jitStubRoutines, m_codeBlocks, &amp;dummy);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-#if ENABLE(LLINT_CLOOP)
</del><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx">     ConservativeRoots stackRoots(&amp;m_objectSpace.blocks(), &amp;m_storageSpace);
</span><span class="cx">     {
</span><span class="cx">         GCPHASE(GatherStackRoots);
</span><span class="lines">@@ -499,7 +499,7 @@
</span><span class="cx">             visitor.append(machineThreadRoots);
</span><span class="cx">             visitor.donateAndDrain();
</span><span class="cx">         }
</span><del>-#if ENABLE(LLINT_CLOOP)
</del><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx">         {
</span><span class="cx">             GCPHASE(VisitStackRoots);
</span><span class="cx">             MARK_LOG_ROOT(visitor, &quot;Stack&quot;);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterJSStackcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.cpp        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -107,12 +107,12 @@
</span><span class="cx"> 
</span><span class="cx"> void JSStack::gatherConservativeRoots(ConservativeRoots&amp; conservativeRoots)
</span><span class="cx"> {
</span><del>-    conservativeRoots.add(baseOfStack(), topOfStack());
</del><ins>+    conservativeRoots.add(topOfStack() + 1, highAddress());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSStack::gatherConservativeRoots(ConservativeRoots&amp; conservativeRoots, JITStubRoutineSet&amp; jitStubRoutines, CodeBlockSet&amp; codeBlocks)
</span><span class="cx"> {
</span><del>-    conservativeRoots.add(baseOfStack(), topOfStack(), jitStubRoutines, codeBlocks);
</del><ins>+    conservativeRoots.add(topOfStack() + 1, highAddress(), jitStubRoutines, codeBlocks);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSStack::sanitizeStack()
</span><span class="lines">@@ -120,8 +120,8 @@
</span><span class="cx">     ASSERT(topOfStack() &lt;= baseOfStack());
</span><span class="cx">     
</span><span class="cx">     if (m_lastStackTop &lt; topOfStack()) {
</span><del>-        char* begin = reinterpret_cast&lt;char*&gt;(m_lastStackTop);
-        char* end = reinterpret_cast&lt;char*&gt;(topOfStack());
</del><ins>+        char* begin = reinterpret_cast&lt;char*&gt;(m_lastStackTop + 1);
+        char* end = reinterpret_cast&lt;char*&gt;(topOfStack() + 1);
</ins><span class="cx">         memset(begin, 0, end - begin);
</span><span class="cx">     }
</span><span class="cx">     
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterJSStackh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/JSStack.h        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -35,13 +35,6 @@
</span><span class="cx"> #include &lt;wtf/PageReservation.h&gt;
</span><span class="cx"> #include &lt;wtf/VMTags.h&gt;
</span><span class="cx"> 
</span><del>-#if ENABLE(LLINT_C_LOOP)
-#define ENABLE_DEBUG_JSSTACK 0
-#if !defined(NDEBUG) &amp;&amp; !defined(ENABLE_DEBUG_JSSTACK)
-#define ENABLE_DEBUG_JSSTACK 1
-#endif
-#endif // ENABLE(LLINT_C_LOOP)
-
</del><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx">     class CodeBlockSet;
</span><span class="lines">@@ -109,25 +102,11 @@
</span><span class="cx"> 
</span><span class="cx">         void setReservedZoneSize(size_t);
</span><span class="cx"> 
</span><del>-        CallFrame* pushFrame(class CodeBlock*, JSScope*, int argsCount, JSObject* callee);
-
-        void popFrame(CallFrame*);
-
-#if ENABLE(DEBUG_JSSTACK)
-        void installFence(CallFrame*, const char *function = &quot;&quot;, int lineNo = 0);
-        void validateFence(CallFrame*, const char *function = &quot;&quot;, int lineNo = 0);
-        static const int FenceSize = 4;
-#else // !ENABLE(DEBUG_JSSTACK)
-        void installFence(CallFrame*, const char* = &quot;&quot;, int = 0) { }
-        void validateFence(CallFrame*, const char* = &quot;&quot;, int = 0) { }
-#endif // !ENABLE(DEBUG_JSSTACK)
</del><ins>+        inline Register* topOfStack();
</ins><span class="cx"> #endif // ENABLE(LLINT_C_LOOP)
</span><span class="cx"> 
</span><span class="cx">     private:
</span><span class="cx"> 
</span><del>-        inline Register* topOfFrameFor(CallFrame*);
-        inline Register* topOfStack();
-
</del><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><span class="cx">         Register* lowAddress() const
</span><span class="cx">         {
</span><span class="lines">@@ -144,20 +123,14 @@
</span><span class="cx"> #endif // ENABLE(LLINT_C_LOOP)
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><ins>+        inline Register* topOfFrameFor(CallFrame*);
+
</ins><span class="cx">         Register* reservationTop() const
</span><span class="cx">         {
</span><span class="cx">             char* reservationTop = static_cast&lt;char*&gt;(m_reservation.base());
</span><span class="cx">             return reinterpret_cast_ptr&lt;Register*&gt;(reservationTop);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-#if ENABLE(DEBUG_JSSTACK)
-        static JSValue generateFenceValue(size_t argIndex);
-        void installTrapsAfterFrame(CallFrame*);
-        Register* startOfFrameFor(CallFrame*);
-#else
-        void installTrapsAfterFrame(CallFrame*) { }
-#endif
-
</del><span class="cx">         bool grow(Register* newTopOfStack);
</span><span class="cx">         bool growSlowCase(Register* newTopOfStack);
</span><span class="cx">         void shrink(Register* newTopOfStack);
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreinterpreterJSStackInlinesh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/interpreter/JSStackInlines.h        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -43,6 +43,8 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(LLINT_C_LOOP)
+
</ins><span class="cx"> inline Register* JSStack::topOfFrameFor(CallFrame* frame)
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(LLINT_C_LOOP)
</span><span class="lines">@@ -57,100 +59,6 @@
</span><span class="cx">     return topOfFrameFor(m_topCallFrame);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if ENABLE(LLINT_C_LOOP)
-
-#if ENABLE(DEBUG_JSSTACK)
-inline Register* JSStack::startOfFrameFor(CallFrame* frame)
-{
-    CallFrame* callerFrame = frame-&gt;callerFrameSkippingVMEntrySentinel();
-    return topOfFrameFor(callerFrame);
-}
-#endif // ENABLE(DEBUG_JSSTACK)
-
-inline CallFrame* JSStack::pushFrame(class CodeBlock* codeBlock, JSScope* scope, int argsCount, JSObject* callee)
-{
-    ASSERT(!!scope);
-    Register* oldEnd = topOfStack();
-
-    // Ensure that we have enough space for the parameters:
-    size_t paddedArgsCount = argsCount;
-    if (codeBlock) {
-        size_t numParameters = codeBlock-&gt;numParameters();
-        if (paddedArgsCount &lt; numParameters)
-            paddedArgsCount = numParameters;
-    }
-
-    Register* newCallFrameSlot = oldEnd - paddedArgsCount - (2 * JSStack::CallFrameHeaderSize) + 1;
-
-#if ENABLE(DEBUG_JSSTACK)
-    newCallFrameSlot -= JSStack::FenceSize;
-#endif
-
-    Register* topOfStack = newCallFrameSlot;
-    if (!!codeBlock)
-        topOfStack += codeBlock-&gt;stackPointerOffset();
-
-    // Ensure that we have the needed stack capacity to push the new frame:
-    if (!grow(topOfStack))
-        return 0;
-
-    // Compute the address of the new VM sentinel frame for this invocation:
-    CallFrame* newVMEntrySentinelFrame = CallFrame::create(newCallFrameSlot + paddedArgsCount + JSStack::CallFrameHeaderSize);
-    ASSERT(!!newVMEntrySentinelFrame);
-
-    // Compute the address of the new frame for this invocation:
-    CallFrame* newCallFrame = CallFrame::create(newCallFrameSlot);
-    ASSERT(!!newCallFrame);
-
-    // The caller frame should always be the real previous frame on the stack,
-    // and not a potential GlobalExec that was passed in. Point callerFrame to
-    // the top frame on the stack.
-    CallFrame* callerFrame = m_topCallFrame;
-
-    // Initialize the VM sentinel frame header:
-    newVMEntrySentinelFrame-&gt;initializeVMEntrySentinelFrame(callerFrame);
-
-    // Initialize the callee frame header:
-    newCallFrame-&gt;init(codeBlock, 0, scope, newVMEntrySentinelFrame, argsCount, callee);
-
-    ASSERT(!!newCallFrame-&gt;scope());
-
-    // Pad additional args if needed:
-    // Note: we need to subtract 1 from argsCount and paddedArgsCount to
-    // exclude the this pointer.
-    for (size_t i = argsCount-1; i &lt; paddedArgsCount-1; ++i)
-        newCallFrame-&gt;setArgument(i, jsUndefined());
-
-    installFence(newCallFrame, __FUNCTION__, __LINE__);
-    validateFence(newCallFrame, __FUNCTION__, __LINE__);
-    installTrapsAfterFrame(newCallFrame);
-
-    // Push the new frame:
-    m_topCallFrame = newCallFrame;
-
-    return newCallFrame;
-}
-
-inline void JSStack::popFrame(CallFrame* frame)
-{
-    validateFence(frame, __FUNCTION__, __LINE__);
-
-    // Pop off the callee frame and the sentinel frame.
-    CallFrame* callerFrame = frame-&gt;callerFrame()-&gt;vmEntrySentinelCallerFrame();
-
-    // Pop to the caller:
-    m_topCallFrame = callerFrame;
-
-    // If we are popping the very first frame from the stack i.e. no more
-    // frames before this, then we can now safely shrink the stack. In
-    // this case, we're shrinking all the way to the beginning since there
-    // are no more frames on the stack.
-    if (!callerFrame)
-        shrink(highAddress());
-
-    installTrapsAfterFrame(callerFrame);
-}
-
</del><span class="cx"> inline void JSStack::shrink(Register* newTopOfStack)
</span><span class="cx"> {
</span><span class="cx">     Register* newEnd = newTopOfStack - 1;
</span><span class="lines">@@ -183,107 +91,6 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if ENABLE(DEBUG_JSSTACK)
-inline JSValue JSStack::generateFenceValue(size_t argIndex)
-{
-    unsigned fenceBits = 0xfacebad0 | ((argIndex+1) &amp; 0xf);
-    JSValue fenceValue = JSValue(fenceBits);
-    return fenceValue;
-}
-
-// The JSStack fences mechanism works as follows:
-// 1. A fence is a number (JSStack::FenceSize) of JSValues that are initialized
-//    with values generated by JSStack::generateFenceValue().
-// 2. When pushFrame() is called, the fence is installed after the max extent
-//    of the previous topCallFrame and the last arg of the new frame:
-//
-//                     | ...                                  |
-//                     |--------------------------------------|
-//                     | Frame Header of previous frame       |
-//                     |--------------------------------------|
-//    topCallFrame --&gt; |                                      |
-//                     | Locals of previous frame             |
-//                     |--------------------------------------|
-//                     | *** the Fence ***                    |
-//                     |--------------------------------------|
-//                     | VM entry sentinel frame header       |
-//                     |--------------------------------------|
-//                     | Args of new frame                    |
-//                     |--------------------------------------|
-//                     | Frame Header of new frame            |
-//                     |--------------------------------------|
-//           frame --&gt; | Locals of new frame                  |
-//                     |                                      |
-//
-// 3. In popFrame() and elsewhere, we can call JSStack::validateFence() to
-//    assert that the fence contains the values we expect.
-
-inline void JSStack::installFence(CallFrame* frame, const char *function, int lineNo)
-{
-    UNUSED_PARAM(function);
-    UNUSED_PARAM(lineNo);
-    Register* startOfFrame = startOfFrameFor(frame);
-
-    // The last argIndex is at:
-    size_t maxIndex = frame-&gt;argIndexForRegister(startOfFrame) + 1;
-    size_t startIndex = maxIndex - FenceSize;
-    for (size_t i = startIndex; i &lt; maxIndex; ++i) {
-        JSValue fenceValue = generateFenceValue(i);
-        frame-&gt;setArgument(i, fenceValue);
-    }
-}
-
-inline void JSStack::validateFence(CallFrame* frame, const char *function, int lineNo)
-{
-    UNUSED_PARAM(function);
-    UNUSED_PARAM(lineNo);
-    ASSERT(!!frame-&gt;scope());
-    Register* startOfFrame = startOfFrameFor(frame);
-    size_t maxIndex = frame-&gt;argIndexForRegister(startOfFrame) + 1;
-    size_t startIndex = maxIndex - FenceSize;
-    for (size_t i = startIndex; i &lt; maxIndex; ++i) {
-        JSValue fenceValue = generateFenceValue(i);
-        JSValue actualValue = frame-&gt;getArgumentUnsafe(i);
-        ASSERT(fenceValue == actualValue);
-    }
-}
-
-// When debugging the JSStack, we install bad values after the extent of the
-// topCallFrame at the end of pushFrame() and popFrame(). The intention is
-// to trigger crashes in the event that memory in this supposedly unused
-// region is read and consumed without proper initialization. After the trap
-// words are installed, the stack looks like this:
-//
-//                     | ...                         |
-//                     |-----------------------------|
-//                     | Frame Header of frame       |
-//                     |-----------------------------|
-//    topCallFrame --&gt; |                             |
-//                     | Locals of frame             |
-//                     |-----------------------------|
-//                     | *** Trap words ***          |
-//                     |-----------------------------|
-//                     | Unused space ...            |
-//                     | ...                         |
-
-inline void JSStack::installTrapsAfterFrame(CallFrame* frame)
-{
-    Register* topOfFrame = topOfFrameFor(frame);
-    const int sizeOfTrap = 64;
-    int32_t* startOfTrap = reinterpret_cast&lt;int32_t*&gt;(topOfFrame);
-    int32_t* endOfTrap = startOfTrap - sizeOfTrap;
-    int32_t* endOfCommitedMemory = reinterpret_cast&lt;int32_t*&gt;(m_commitTop);
-
-    // Make sure we're not exceeding the amount of available memory to write to:
-    if (endOfTrap &lt; endOfCommitedMemory)
-        endOfTrap = endOfCommitedMemory;
-
-    // Lay the traps:
-    int32_t* p = startOfTrap;
-    while (--p &gt;= endOfTrap)
-        *p = 0xabadcafe; // A bad word to trigger a crash if deref'ed.
-}
-#endif // ENABLE(DEBUG_JSSTACK)
</del><span class="cx"> #endif // ENABLE(LLINT_C_LOOP)
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntOpcodeh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntOpcode.h (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntOpcode.h        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntOpcode.h        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2013, 2014 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">@@ -34,9 +34,18 @@
</span><span class="cx"> 
</span><span class="cx"> #define FOR_EACH_LLINT_NOJIT_NATIVE_HELPER(macro) \
</span><span class="cx">     macro(getHostCallReturnValue, 1) \
</span><ins>+    macro(llint_return_to_host, 1) \
</ins><span class="cx">     macro(llint_call_to_javascript, 1) \
</span><span class="cx">     macro(llint_call_to_native_function, 1) \
</span><del>-    macro(handleUncaughtException, 1)
</del><ins>+    macro(handleUncaughtException, 1) \
+    \
+    macro(llint_cloop_did_return_from_js_1, 1) \
+    macro(llint_cloop_did_return_from_js_2, 1) \
+    macro(llint_cloop_did_return_from_js_3, 1) \
+    macro(llint_cloop_did_return_from_js_4, 1) \
+    macro(llint_cloop_did_return_from_js_5, 1) \
+    macro(llint_cloop_did_return_from_js_6, 1) \
+    macro(llint_cloop_did_return_from_js_7, 1) \
</ins><span class="cx"> 
</span><span class="cx"> #else // !ENABLE(LLINT_C_LOOP)
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2012, 2013, 2014 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">@@ -1429,6 +1429,14 @@
</span><span class="cx">     return encodeResult(0, 0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(LLINT_C_LOOP)
+SlowPathReturnType llint_stack_check_at_vm_entry(VM* vm, Register* newTopOfStack)
+{
+    bool success = vm-&gt;interpreter-&gt;stack().ensureCapacityFor(newTopOfStack);
+    return encodeResult(reinterpret_cast&lt;void*&gt;(success), 0);
+}
+#endif
+
</ins><span class="cx"> } } // namespace JSC::LLInt
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(LLINT)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2014 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">@@ -124,6 +124,9 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope);
</span><span class="cx"> extern &quot;C&quot; SlowPathReturnType llint_throw_stack_overflow_error(VM*, ProtoCallFrame*);
</span><ins>+#if ENABLE(LLINT_C_LOOP)
+extern &quot;C&quot; SlowPathReturnType llint_stack_check_at_vm_entry(VM*, Register*);
+#endif
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::LLInt
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -217,8 +217,10 @@
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro checkStackPointerAlignment(tempReg, location)
</span><del>-    if ARM64
</del><ins>+    if ARM64 or C_LOOP
</ins><span class="cx">         # ARM64 will check for us!
</span><ins>+        # C_LOOP does not need the alignment, and can use a little perf
+        # improvement from avoiding useless work.
</ins><span class="cx">     else
</span><span class="cx">         andp sp, 0xf, tempReg
</span><span class="cx">         btpz tempReg, .stackPointerOkay
</span><span class="lines">@@ -230,9 +232,9 @@
</span><span class="cx"> 
</span><span class="cx"> macro preserveCallerPCAndCFR()
</span><span class="cx">     if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
</span><del>-        # In C_LOOP case, we're only preserving the bytecode vPC.
-        # FIXME: Need to fix for other ports
-        # move lr, destinationRegister
</del><ins>+        push lr
+        push cfr
+        move sp, cfr
</ins><span class="cx">     elsif X86 or X86_64
</span><span class="cx">         push cfr
</span><span class="cx">         move sp, cfr
</span><span class="lines">@@ -246,9 +248,9 @@
</span><span class="cx"> 
</span><span class="cx"> macro restoreCallerPCAndCFR()
</span><span class="cx">     if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
</span><del>-        # In C_LOOP case, we're only preserving the bytecode vPC.
-        # FIXME: Need to fix for other ports
-        # move lr, destinationRegister
</del><ins>+        move cfr, sp
+        pop cfr
+        pop lr
</ins><span class="cx">     elsif X86 or X86_64
</span><span class="cx">         move cfr, sp
</span><span class="cx">         pop cfr
</span><span class="lines">@@ -285,9 +287,9 @@
</span><span class="cx">         push cfr
</span><span class="cx">     elsif ARM64
</span><span class="cx">         pushLRAndFP
</span><del>-    elsif ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
</del><ins>+    elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
+        push lr
</ins><span class="cx">         push cfr
</span><del>-        push lr
</del><span class="cx">     end
</span><span class="cx">     move sp, cfr
</span><span class="cx"> end
</span><span class="lines">@@ -297,9 +299,9 @@
</span><span class="cx">         pop cfr
</span><span class="cx">     elsif ARM64
</span><span class="cx">         popLRAndFP
</span><del>-    elsif ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
</del><ins>+    elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
+        pop cfr
</ins><span class="cx">         pop lr
</span><del>-        pop cfr
</del><span class="cx">     end
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -310,8 +312,9 @@
</span><span class="cx">         push t0
</span><span class="cx">     elsif ARM64
</span><span class="cx">         pushLRAndFP
</span><del>-    elsif ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
</del><ins>+    elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
</ins><span class="cx">         push lr
</span><ins>+        push lr
</ins><span class="cx">         push cfr
</span><span class="cx">     end
</span><span class="cx">     pushCalleeSaves
</span><span class="lines">@@ -327,8 +330,9 @@
</span><span class="cx">         pop cfr
</span><span class="cx">     elsif ARM64
</span><span class="cx">         popLRAndFP
</span><del>-    elsif ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
</del><ins>+    elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
</ins><span class="cx">         pop cfr
</span><ins>+        pop cfr
</ins><span class="cx">         pop lr
</span><span class="cx">     end
</span><span class="cx"> end
</span><span class="lines">@@ -352,30 +356,30 @@
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro callTargetFunction(callLinkInfo, calleeFramePtr)
</span><ins>+    move calleeFramePtr, sp
</ins><span class="cx">     if C_LOOP
</span><span class="cx">         cloopCallJSFunction LLIntCallLinkInfo::machineCodeTarget[callLinkInfo]
</span><span class="cx">     else
</span><del>-        move calleeFramePtr, sp
</del><span class="cx">         call LLIntCallLinkInfo::machineCodeTarget[callLinkInfo]
</span><del>-        restoreStackPointerAfterCall()
-        dispatchAfterCall()
</del><span class="cx">     end
</span><ins>+    restoreStackPointerAfterCall()
+    dispatchAfterCall()
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro slowPathForCall(slowPath)
</span><span class="cx">     callCallSlowPath(
</span><span class="cx">         slowPath,
</span><span class="cx">         macro (callee)
</span><ins>+            btpz t1, .dontUpdateSP
+            addp CallerFrameAndPCSize, t1, sp
+        .dontUpdateSP:
</ins><span class="cx">             if C_LOOP
</span><span class="cx">                 cloopCallJSFunction callee
</span><span class="cx">             else
</span><del>-                btpz t1, .dontUpdateSP
-                addp CallerFrameAndPCSize, t1, sp
-            .dontUpdateSP:
</del><span class="cx">                 call callee
</span><del>-                restoreStackPointerAfterCall()
-                dispatchAfterCall()
</del><span class="cx">             end
</span><ins>+            restoreStackPointerAfterCall()
+            dispatchAfterCall()
</ins><span class="cx">         end)
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -439,6 +443,8 @@
</span><span class="cx">         callSlowPath(traceSlowPath)
</span><span class="cx">     end
</span><span class="cx">     codeBlockGetter(t1)
</span><ins>+if C_LOOP
+else
</ins><span class="cx">     baddis 5, CodeBlock::m_llintExecuteCounter + ExecutionCounter::m_counter[t1], .continue
</span><span class="cx">     cCall2(osrSlowPath, cfr, PC)
</span><span class="cx">     btpz t0, .recover
</span><span class="lines">@@ -446,6 +452,9 @@
</span><span class="cx">     # pop the callerFrame since we will jump to a function that wants to save it
</span><span class="cx">     if ARM64
</span><span class="cx">         popLRAndFP
</span><ins>+    elsif ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS or SH4
+        pop cfr
+        pop lr
</ins><span class="cx">     else
</span><span class="cx">         pop cfr
</span><span class="cx">     end
</span><span class="lines">@@ -453,6 +462,8 @@
</span><span class="cx"> .recover:
</span><span class="cx">     codeBlockGetter(t1)
</span><span class="cx"> .continue:
</span><ins>+end
+
</ins><span class="cx">     codeBlockSetter(t1)
</span><span class="cx">     
</span><span class="cx">     moveStackPointerForCodeBlock(t1, t2)
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpretercpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp        2014-01-14 01:08:05 UTC (rev 161927)
</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, 2014 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">@@ -90,6 +90,12 @@
</span><span class="cx"> #define OFFLINE_ASM_BEGIN
</span><span class="cx"> #define OFFLINE_ASM_END
</span><span class="cx"> 
</span><ins>+#if ENABLE(OPCODE_TRACING)
+#define TRACE_OPCODE(opcode) dataLogF(&quot;   op %s\n&quot;, #opcode)
+#else
+#define TRACE_OPCODE(opcode)
+#endif
+
</ins><span class="cx"> // To keep compilers happy in case of unused labels, force usage of the label:
</span><span class="cx"> #define USE_LABEL(label) \
</span><span class="cx">     do { \
</span><span class="lines">@@ -97,7 +103,7 @@
</span><span class="cx">             goto label; \
</span><span class="cx">     } while (false)
</span><span class="cx"> 
</span><del>-#define OFFLINE_ASM_OPCODE_LABEL(opcode) DEFINE_OPCODE(opcode) USE_LABEL(opcode);
</del><ins>+#define OFFLINE_ASM_OPCODE_LABEL(opcode) DEFINE_OPCODE(opcode) USE_LABEL(opcode); TRACE_OPCODE(opcode);
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(COMPUTED_GOTO_OPCODES)
</span><span class="cx"> #define OFFLINE_ASM_GLUE_LABEL(label)  label: USE_LABEL(label);
</span><span class="lines">@@ -212,8 +218,10 @@
</span><span class="cx"> #endif // !CPU(BIG_ENDIAN)
</span><span class="cx"> #endif // !USE(JSVALUE64)
</span><span class="cx"> 
</span><ins>+        intptr_t* ip;
</ins><span class="cx">         int8_t* i8p;
</span><span class="cx">         void* vp;
</span><ins>+        CallFrame* callFrame;
</ins><span class="cx">         ExecState* execState;
</span><span class="cx">         void* instruction;
</span><span class="cx">         VM* vm;
</span><span class="lines">@@ -232,6 +240,7 @@
</span><span class="cx">     operator Instruction*() { return reinterpret_cast&lt;Instruction*&gt;(instruction); }
</span><span class="cx">     operator VM*() { return vm; }
</span><span class="cx">     operator ProtoCallFrame*() { return protoCallFrame; }
</span><ins>+    operator Register*() { return reinterpret_cast&lt;Register*&gt;(vp); }
</ins><span class="cx"> 
</span><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     inline void clearHighWord() { i32padding = 0; }
</span><span class="lines">@@ -313,18 +322,20 @@
</span><span class="cx">     // 2. 32 bit result values will be in the low 32-bit of t0.
</span><span class="cx">     // 3. 64 bit result values will be in t0.
</span><span class="cx"> 
</span><del>-    CLoopRegister t0, t1, t2, t3, t5, sp;
</del><ins>+    CLoopRegister t0, t1, t2, t3, t5, sp, cfr, lr, pc;
</ins><span class="cx"> #if USE(JSVALUE64)
</span><del>-    CLoopRegister rBasePC, tagTypeNumber, tagMask;
</del><ins>+    CLoopRegister pcBase, tagTypeNumber, tagMask;
</ins><span class="cx"> #endif
</span><del>-    CLoopRegister rRetVPC;
</del><span class="cx">     CLoopDoubleRegister d0, d1;
</span><span class="cx"> 
</span><del>-    Instruction* vPC;
</del><ins>+    lr.opcode = getOpcode(llint_return_to_host);
+    sp.vp = vm-&gt;interpreter-&gt;stack().topOfStack() + 1;
+    cfr.callFrame = vm-&gt;topCallFrame;
+#ifndef NDEBUG
+    void* startSP = sp.vp;
+    CallFrame* startCFR = cfr.callFrame;
+#endif
</ins><span class="cx"> 
</span><del>-    // rPC is an alias for vPC. Set up the alias:
-    CLoopRegister&amp; rPC = *CAST&lt;CLoopRegister*&gt;(&amp;vPC);
-
</del><span class="cx">     // Initialize the incoming args for doCallToJavaScript:
</span><span class="cx">     t0.vp = executableAddress;
</span><span class="cx">     t1.vm = vm;
</span><span class="lines">@@ -337,18 +348,23 @@
</span><span class="cx">     tagMask.i = 0xFFFF000000000002;
</span><span class="cx"> #endif // USE(JSVALUE64)
</span><span class="cx"> 
</span><del>-    // cfr is an alias for callFrame. Set up this alias:
-    CallFrame* callFrame;
-    CLoopRegister&amp; cfr = *CAST&lt;CLoopRegister*&gt;(&amp;callFrame);
-
-    // Simulate a native return PC which should never be used:
-    rRetVPC.i = 0xbbadbeef;
-
</del><span class="cx">     // Interpreter variables for value passing between opcodes and/or helpers:
</span><span class="cx">     NativeFunction nativeFunc = 0;
</span><span class="cx">     JSValue functionReturnValue;
</span><span class="cx">     Opcode opcode = getOpcode(entryOpcodeID);
</span><span class="cx"> 
</span><ins>+    #define PUSH(cloopReg) \
+        do { \
+            sp.ip--; \
+            *sp.ip = cloopReg.i; \
+        } while (false)
+    
+    #define POP(cloopReg) \
+        do { \
+            cloopReg.i = *sp.ip; \
+            sp.ip++; \
+        } while (false)
+
</ins><span class="cx">     #if ENABLE(OPCODE_STATS)
</span><span class="cx">         #define RECORD_OPCODE_STATS(__opcode) \
</span><span class="cx">             OpcodeStats::recordInstruction(__opcode)
</span><span class="lines">@@ -357,9 +373,9 @@
</span><span class="cx">     #endif
</span><span class="cx"> 
</span><span class="cx">     #if USE(JSVALUE32_64)
</span><del>-        #define FETCH_OPCODE() vPC-&gt;u.opcode
</del><ins>+        #define FETCH_OPCODE() pc.opcode
</ins><span class="cx">     #else // USE(JSVALUE64)
</span><del>-        #define FETCH_OPCODE() *bitwise_cast&lt;Opcode*&gt;(rBasePC.i8p + rPC.i * 8)
</del><ins>+        #define FETCH_OPCODE() *bitwise_cast&lt;Opcode*&gt;(pcBase.i8p + pc.i * 8)
</ins><span class="cx">     #endif // USE(JSVALUE64)
</span><span class="cx"> 
</span><span class="cx">     #define NEXT_INSTRUCTION() \
</span><span class="lines">@@ -408,14 +424,22 @@
</span><span class="cx"> 
</span><span class="cx">         #include &quot;LLIntAssembly.h&quot;
</span><span class="cx"> 
</span><ins>+        OFFLINE_ASM_GLUE_LABEL(llint_return_to_host)
+        {
+            ASSERT(startSP == sp.vp);
+            ASSERT(startCFR == cfr.callFrame);
+#if USE(JSVALUE32_64)
+            return JSValue(t1.i, t0.i); // returning JSValue(tag, payload);
+#else
+            return JSValue::decode(t0.encodedJSValue);
+#endif
+        }
+
</ins><span class="cx">         // In the ASM llint, getHostCallReturnValue() is a piece of glue
</span><del>-        // function provided by the JIT (see dfg/DFGOperations.cpp).
</del><ins>+        // function provided by the JIT (see jit/JITOperations.cpp).
</ins><span class="cx">         // We simulate it here with a pseduo-opcode handler.
</span><span class="cx">         OFFLINE_ASM_GLUE_LABEL(getHostCallReturnValue)
</span><span class="cx">         {
</span><del>-            // The ASM part pops the frame:
-            callFrame = callFrame-&gt;callerFrame();
-
</del><span class="cx">             // The part in getHostCallReturnValueWithExecState():
</span><span class="cx">             JSValue result = vm-&gt;hostCallReturnValue;
</span><span class="cx"> #if USE(JSVALUE32_64)
</span><span class="lines">@@ -424,7 +448,8 @@
</span><span class="cx"> #else
</span><span class="cx">             t0.encodedJSValue = JSValue::encode(result);
</span><span class="cx"> #endif
</span><del>-            goto doReturnHelper;
</del><ins>+            opcode = lr.opcode;
+            DISPATCH_OPCODE();
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx"> #if !ENABLE(COMPUTED_GOTO_OPCODES)
</span><span class="lines">@@ -434,55 +459,6 @@
</span><span class="cx"> 
</span><span class="cx">     } // END bytecode handler cases.
</span><span class="cx"> 
</span><del>-    //========================================================================
-    // Bytecode helpers:
-
-    doReturnHelper: {
-        ASSERT(!!callFrame);
-        if (callFrame-&gt;isVMEntrySentinel()) {
-#if USE(JSVALUE32_64)
-            return JSValue(t1.i, t0.i); // returning JSValue(tag, payload);
-#else
-            return JSValue::decode(t0.encodedJSValue);
-#endif
-        }
-
-        // The normal ASM llint call implementation returns to the caller as
-        // recorded in rRetVPC, and the caller would fetch the return address
-        // from ArgumentCount.tag() (see the dispatchAfterCall() macro used in
-        // the callTargetFunction() macro in the llint asm files).
-        //
-        // For the C loop, we don't have the JIT stub to do this work for us. So,
-        // we jump to llint_generic_return_point.
-
-        vPC = callFrame-&gt;currentVPC();
-
-#if USE(JSVALUE64)
-        // Based on LowLevelInterpreter64.asm's dispatchAfterCall():
-
-        // When returning from a native trampoline call, unlike the assembly
-        // LLInt, we can't simply return to the caller. In our case, we grab
-        // the caller's VPC and resume execution there. However, the caller's
-        // VPC returned by callFrame-&gt;currentVPC() is in the form of the real
-        // address of the target bytecode, but the 64-bit llint expects the
-        // VPC to be a bytecode offset. Hence, we need to map it back to a
-        // bytecode offset before we dispatch via the usual dispatch mechanism
-        // i.e. NEXT_INSTRUCTION():
-
-        CodeBlock* codeBlock = callFrame-&gt;codeBlock();
-        ASSERT(codeBlock);
-        rPC.vp = callFrame-&gt;currentVPC();
-        rPC.i = rPC.i8p - reinterpret_cast&lt;int8_t*&gt;(codeBlock-&gt;instructions().begin());
-        rPC.i &gt;&gt;= 3;
-
-        rBasePC.vp = codeBlock-&gt;instructions().begin();
-#endif // USE(JSVALUE64)
-
-        goto llint_generic_return_point;
-
-    } // END doReturnHelper.
-
-
</del><span class="cx"> #if ENABLE(COMPUTED_GOTO_OPCODES)
</span><span class="cx">     // Keep the compiler happy so that it doesn't complain about unused
</span><span class="cx">     // labels for the LLInt trampoline glue. The labels are automatically
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCorellintLowLevelInterpreter64asm"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -150,9 +150,17 @@
</span><span class="cx">     move cfr, sp
</span><span class="cx"> 
</span><span class="cx">     if C_LOOP
</span><del>-    # FIXME: Need to call stack check here to see if we can grow the stack.
-    # Will need to preserve registers so that we can recover if we do not end
-    # up throwing a StackOverflowError.
</del><ins>+        move entry, temp2
+        move vm, temp3
+        cloopCallSlowPath _llint_stack_check_at_vm_entry, vm, temp1
+        bpeq t0, 0, .stackCheckFailed
+        move temp2, entry
+        move temp3, vm
+        jmp .stackHeightOK
+
+.stackCheckFailed:
+        move temp2, entry
+        move temp3, vm
</ins><span class="cx">     end
</span><span class="cx"> 
</span><span class="cx">     cCall2(_llint_throw_stack_overflow_error, vm, protoCallFrame)
</span><span class="lines">@@ -225,7 +233,11 @@
</span><span class="cx"> 
</span><span class="cx"> macro makeJavaScriptCall(entry, temp)
</span><span class="cx">     addp 16, sp
</span><del>-    call entry
</del><ins>+    if C_LOOP
+        cloopCallJSFunction entry
+    else
+        call entry
+    end
</ins><span class="cx">     subp 16, sp
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -237,9 +249,15 @@
</span><span class="cx">     elsif ARM64 or C_LOOP
</span><span class="cx">         move sp, a0
</span><span class="cx">     end
</span><del>-    addp 16, sp
-    call temp
-    subp 16, sp
</del><ins>+    if C_LOOP
+        storep cfr, [sp]
+        storep lr, 8[sp]
+        cloopCallNative temp
+    else
+        addp 16, sp 
+        call temp
+        subp 16, sp
+    end
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -1895,7 +1913,7 @@
</span><span class="cx">         loadp ScopeChain[cfr], t3
</span><span class="cx">         andp MarkedBlockMask, t3
</span><span class="cx">         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span><del>-    elsif ARM64
</del><ins>+    elsif ARM64 or C_LOOP
</ins><span class="cx">         loadp ScopeChain[cfr], t0
</span><span class="cx">         andp MarkedBlockMask, t0
</span><span class="cx">         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t0], t0
</span><span class="lines">@@ -1909,34 +1927,15 @@
</span><span class="cx">         loadp Callee[cfr], t1
</span><span class="cx">         loadp JSFunction::m_executable[t1], t1
</span><span class="cx">         move t2, cfr # Restore cfr to avoid loading from stack
</span><del>-        call executableOffsetToFunction[t1]
</del><ins>+        if C_LOOP
+            cloopCallNative executableOffsetToFunction[t1]
+        else
+            call executableOffsetToFunction[t1]
+        end
</ins><span class="cx">         restoreReturnAddressBeforeReturn(t3)
</span><span class="cx">         loadp ScopeChain[cfr], t3
</span><span class="cx">         andp MarkedBlockMask, t3
</span><span class="cx">         loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</span><del>-    elsif C_LOOP
-        loadp CallerFrame[cfr], t0
-        loadp ScopeChain[t0], t1
-        storep t1, ScopeChain[cfr]
-
-        loadp ScopeChain[cfr], t3
-        andp MarkedBlockMask, t3
-        loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
-        storep cfr, VM::topCallFrame[t3]
-
-        move t0, t2
-        preserveReturnAddressAfterCall(t3)
-        storep t3, ReturnPC[cfr]
-        move cfr, t0
-        loadp Callee[cfr], t1
-        loadp JSFunction::m_executable[t1], t1
-        move t2, cfr
-        cloopCallNative executableOffsetToFunction[t1]
-
-        restoreReturnAddressBeforeReturn(t3)
-        loadp ScopeChain[cfr], t3
-        andp MarkedBlockMask, t3
-        loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
</del><span class="cx">     else
</span><span class="cx">         error
</span><span class="cx">     end
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreofflineasmclooprb"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/offlineasm/cloop.rb (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/offlineasm/cloop.rb        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/offlineasm/cloop.rb        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-# Copyright (C) 2012 Apple Inc. All rights reserved.
</del><ins>+# Copyright (C) 2012, 2014 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,11 +79,11 @@
</span><span class="cx">         when &quot;t3&quot;, &quot;a3&quot;
</span><span class="cx">             &quot;t3&quot;
</span><span class="cx">         when &quot;t4&quot;
</span><del>-            &quot;rPC&quot;
</del><ins>+            &quot;pc&quot;
</ins><span class="cx">         when &quot;t5&quot;
</span><span class="cx">             &quot;t5&quot;
</span><span class="cx">         when &quot;t6&quot;
</span><del>-            &quot;rBasePC&quot;
</del><ins>+            &quot;pcBase&quot;
</ins><span class="cx">         when &quot;csr1&quot;
</span><span class="cx">             &quot;tagTypeNumber&quot;
</span><span class="cx">         when &quot;csr2&quot;
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx">         when &quot;cfr&quot;
</span><span class="cx">             &quot;cfr&quot;
</span><span class="cx">         when &quot;lr&quot;
</span><del>-            &quot;rRetVPC&quot;
</del><ins>+            &quot;lr&quot;
</ins><span class="cx">         when &quot;sp&quot;
</span><span class="cx">             &quot;sp&quot;
</span><span class="cx">         else
</span><span class="lines">@@ -544,11 +544,13 @@
</span><span class="cx"> def cloopEmitCallSlowPath(operands)
</span><span class="cx">     $asm.putc &quot;{&quot;
</span><span class="cx">     $asm.putc &quot;    SlowPathReturnType result = #{operands[0].cLabel}(#{operands[1].clDump}, #{operands[2].clDump});&quot;
</span><del>-    $asm.putc &quot;    decodeResult(result, t0.instruction, t1.vp);&quot;
</del><ins>+    $asm.putc &quot;    decodeResult(result, t0.vp, t1.vp);&quot;
</ins><span class="cx">     $asm.putc &quot;}&quot;
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> class Instruction
</span><ins>+    @@didReturnFromJSLabelCounter = 0
+
</ins><span class="cx">     def lowerC_LOOP
</span><span class="cx">         $asm.codeOrigin codeOriginString if $enableCodeOriginComments
</span><span class="cx">         $asm.annotation annotation if $enableInstrAnnotations &amp;&amp; (opcode != &quot;cloopDo&quot;)
</span><span class="lines">@@ -862,7 +864,8 @@
</span><span class="cx">         when &quot;break&quot;
</span><span class="cx">             $asm.putc &quot;CRASH(); // break instruction not implemented.&quot;
</span><span class="cx">         when &quot;ret&quot;
</span><del>-            $asm.putc &quot;goto doReturnHelper;&quot;
</del><ins>+            $asm.putc &quot;opcode = lr.opcode;&quot;
+            $asm.putc &quot;DISPATCH_OPCODE();&quot;
</ins><span class="cx"> 
</span><span class="cx">         when &quot;cbeq&quot;
</span><span class="cx">             cloopEmitCompareAndSet(operands, :uint8, &quot;==&quot;)
</span><span class="lines">@@ -1083,8 +1086,11 @@
</span><span class="cx">             cloopEmitOpAndBranch(operands, &quot;|&quot;, :int32, &quot;!= 0&quot;)
</span><span class="cx">             
</span><span class="cx">         when &quot;memfence&quot;
</span><ins>+
+        when &quot;push&quot;
+            $asm.putc &quot;PUSH(#{operands[0].clDump});&quot;
</ins><span class="cx">         when &quot;pop&quot;
</span><del>-            $asm.putc &quot;RELEASE_ASSERT_NOT_REACHED(); // pop not implemented.&quot;
</del><ins>+            $asm.putc &quot;POP(#{operands[0].clDump});&quot;
</ins><span class="cx"> 
</span><span class="cx">         when &quot;pushCalleeSaves&quot;
</span><span class="cx">         when &quot;popCalleeSaves&quot;
</span><span class="lines">@@ -1102,8 +1108,11 @@
</span><span class="cx">         # use of the call instruction. Instead, we just implement JS calls
</span><span class="cx">         # as an opcode dispatch.
</span><span class="cx">         when &quot;cloopCallJSFunction&quot;
</span><ins>+            @@didReturnFromJSLabelCounter += 1
+            $asm.putc &quot;lr.opcode = getOpcode(llint_cloop_did_return_from_js_#{@@didReturnFromJSLabelCounter});&quot;
</ins><span class="cx">             $asm.putc &quot;opcode = #{operands[0].clValue(:opcode)};&quot;
</span><span class="cx">             $asm.putc &quot;DISPATCH_OPCODE();&quot;
</span><ins>+            $asm.putsLabel(&quot;llint_cloop_did_return_from_js_#{@@didReturnFromJSLabelCounter}&quot;)
</ins><span class="cx"> 
</span><span class="cx">         # We can't do generic function calls with an arbitrary set of args, but
</span><span class="cx">         # fortunately we don't have to here. All native function calls always
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreruntimeExecutablecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/runtime/Executable.cpp (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/runtime/Executable.cpp        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/runtime/Executable.cpp        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -34,6 +34,7 @@
</span><span class="cx"> #include &quot;LLIntEntrypoint.h&quot;
</span><span class="cx"> #include &quot;Operations.h&quot;
</span><span class="cx"> #include &quot;Parser.h&quot;
</span><ins>+#include &lt;wtf/CommaPrinter.h&gt;
</ins><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringBuilder.h&gt;
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/runtime/VM.cpp (161926 => 161927)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/runtime/VM.cpp        2014-01-14 01:05:17 UTC (rev 161926)
+++ branches/jsCStack/Source/JavaScriptCore/runtime/VM.cpp        2014-01-14 01:08:05 UTC (rev 161927)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2011, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2011, 2013, 2014 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">@@ -221,7 +221,7 @@
</span><span class="cx">     , m_initializingObjectClass(0)
</span><span class="cx"> #endif
</span><span class="cx">     , m_stackLimit(0)
</span><del>-#if ENABLE(LLINT_CLOOP)
</del><ins>+#if ENABLE(LLINT_C_LOOP)
</ins><span class="cx">     , m_jsStackLimit(0)
</span><span class="cx"> #endif
</span><span class="cx">     , m_inDefineOwnProperty(false)
</span></span></pre>
</div>
</div>

</body>
</html>