<!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>[164205] 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/164205">164205</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-02-16 22:25:05 -0800 (Sun, 16 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>DFG::prepareOSREntry should be nice to the stack
https://bugs.webkit.org/show_bug.cgi?id=128883

Reviewed by Oliver Hunt.
        
Previously OSR entry had some FIXME's and some really badly commented-out code for
clearing stack entries to help GC. It also did some permutations on a stack frame
above us, in such a way that it wasn't obviously that we wouldn't clobber our own
stack frame. This function also crashed in ASan.
        
It just seems like there was too much badness to the whole idea of prepareOSREntry
directly editing the stack. So, I changed it to create a stack frame in a scratch
buffer on the side and then have some assembly code just copy it into place. This
works fine, fixes a FIXME, possibly fixes some stack clobbering, and might help us
make more progress with ASan.

* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* dfg/DFGOSREntry.h:
* dfg/DFGThunks.cpp:
(JSC::DFG::osrEntryThunkGenerator):
* dfg/DFGThunks.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emitSlow_op_loop_hint):
* jit/JITOperations.cpp:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSREntrycpp">trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOSREntryh">trunk/Source/JavaScriptCore/dfg/DFGOSREntry.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGThunkscpp">trunk/Source/JavaScriptCore/dfg/DFGThunks.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGThunksh">trunk/Source/JavaScriptCore/dfg/DFGThunks.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (164204 => 164205)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-17 03:52:02 UTC (rev 164204)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-17 06:25:05 UTC (rev 164205)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2014-02-16  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        DFG::prepareOSREntry should be nice to the stack
+        https://bugs.webkit.org/show_bug.cgi?id=128883
+
+        Reviewed by Oliver Hunt.
+        
+        Previously OSR entry had some FIXME's and some really badly commented-out code for
+        clearing stack entries to help GC. It also did some permutations on a stack frame
+        above us, in such a way that it wasn't obviously that we wouldn't clobber our own
+        stack frame. This function also crashed in ASan.
+        
+        It just seems like there was too much badness to the whole idea of prepareOSREntry
+        directly editing the stack. So, I changed it to create a stack frame in a scratch
+        buffer on the side and then have some assembly code just copy it into place. This
+        works fine, fixes a FIXME, possibly fixes some stack clobbering, and might help us
+        make more progress with ASan.
+
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::prepareOSREntry):
+        * dfg/DFGOSREntry.h:
+        * dfg/DFGThunks.cpp:
+        (JSC::DFG::osrEntryThunkGenerator):
+        * dfg/DFGThunks.h:
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emitSlow_op_loop_hint):
+        * jit/JITOperations.cpp:
+
</ins><span class="cx"> 2014-02-15  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Vector with inline capacity should work with non-PODs
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSREntrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp (164204 => 164205)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp        2014-02-17 03:52:02 UTC (rev 164204)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSREntry.cpp        2014-02-17 06:25:05 UTC (rev 164205)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 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">@@ -188,8 +188,8 @@
</span><span class="cx">     //    it seems silly: you'd be diverting the program to error handling when it
</span><span class="cx">     //    would have otherwise just kept running albeit less quickly.
</span><span class="cx">     
</span><del>-    unsigned frameSize = jitCode-&gt;common.requiredRegisterCountForExecutionAndExit();
-    if (!vm-&gt;interpreter-&gt;stack().ensureCapacityFor(&amp;exec-&gt;registers()[virtualRegisterForLocal(frameSize - 1).offset()])) {
</del><ins>+    unsigned frameSizeForCheck = jitCode-&gt;common.requiredRegisterCountForExecutionAndExit();
+    if (!vm-&gt;interpreter-&gt;stack().ensureCapacityFor(&amp;exec-&gt;registers()[virtualRegisterForLocal(frameSizeForCheck - 1).offset()])) {
</ins><span class="cx">         if (Options::verboseOSR())
</span><span class="cx">             dataLogF(&quot;    OSR failed because stack growth failed.\n&quot;);
</span><span class="cx">         return 0;
</span><span class="lines">@@ -197,47 +197,68 @@
</span><span class="cx">     
</span><span class="cx">     if (Options::verboseOSR())
</span><span class="cx">         dataLogF(&quot;    OSR should succeed.\n&quot;);
</span><ins>+
+    // At this point we're committed to entering. We will do some work to set things up,
+    // but we also rely on our caller recognizing that when we return a non-null pointer,
+    // that means that we're already past the point of no return and we must succeed at
+    // entering.
</ins><span class="cx">     
</span><del>-    // 3) Perform data format conversions.
-    for (size_t local = 0; local &lt; entry-&gt;m_expectedValues.numberOfLocals(); ++local) {
-        if (entry-&gt;m_localsForcedDouble.get(local))
-            *bitwise_cast&lt;double*&gt;(exec-&gt;registers() + virtualRegisterForLocal(local).offset()) = exec-&gt;registers()[virtualRegisterForLocal(local).offset()].jsValue().asNumber();
-        if (entry-&gt;m_localsForcedMachineInt.get(local))
-            *bitwise_cast&lt;int64_t*&gt;(exec-&gt;registers() + virtualRegisterForLocal(local).offset()) = exec-&gt;registers()[virtualRegisterForLocal(local).offset()].jsValue().asMachineInt() &lt;&lt; JSValue::int52ShiftAmount;
</del><ins>+    // 3) Set up the data in the scratch buffer and perform data format conversions.
+
+    unsigned frameSize = jitCode-&gt;common.frameRegisterCount;
+    
+    Register* scratch = bitwise_cast&lt;Register*&gt;(vm-&gt;scratchBufferForSize(sizeof(Register) * (2 + JSStack::CallFrameHeaderSize + frameSize))-&gt;dataBuffer());
+    
+    *bitwise_cast&lt;size_t*&gt;(scratch + 0) = frameSize;
+    
+    void* targetPC = codeBlock-&gt;jitCode()-&gt;executableAddressAtOffset(entry-&gt;m_machineCodeOffset);
+    if (Options::verboseOSR())
+        dataLogF(&quot;    OSR using target PC %p.\n&quot;, targetPC);
+    RELEASE_ASSERT(targetPC);
+    *bitwise_cast&lt;void**&gt;(scratch + 1) = targetPC;
+    
+    Register* pivot = scratch + 2 + JSStack::CallFrameHeaderSize;
+    
+    for (int index = -JSStack::CallFrameHeaderSize; index &lt; static_cast&lt;int&gt;(frameSize); ++index) {
+        VirtualRegister reg(-1 - index);
+        
+        if (reg.isLocal()) {
+            if (entry-&gt;m_localsForcedDouble.get(reg.toLocal())) {
+                *bitwise_cast&lt;double*&gt;(pivot + index) = exec-&gt;registers()[reg.offset()].jsValue().asNumber();
+                continue;
+            }
+            
+            if (entry-&gt;m_localsForcedMachineInt.get(reg.toLocal())) {
+                *bitwise_cast&lt;int64_t*&gt;(pivot + index) = exec-&gt;registers()[reg.offset()].jsValue().asMachineInt() &lt;&lt; JSValue::int52ShiftAmount;
+                continue;
+            }
+        }
+        
+        pivot[index] = exec-&gt;registers()[reg.offset()].jsValue();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // 4) Reshuffle those registers that need reshuffling.
</span><del>-    
-    Vector&lt;EncodedJSValue&gt; temporaryLocals(entry-&gt;m_reshufflings.size());
-    EncodedJSValue* registers = bitwise_cast&lt;EncodedJSValue*&gt;(exec-&gt;registers());
</del><ins>+    Vector&lt;JSValue&gt; temporaryLocals(entry-&gt;m_reshufflings.size());
</ins><span class="cx">     for (unsigned i = entry-&gt;m_reshufflings.size(); i--;)
</span><del>-        temporaryLocals[i] = registers[entry-&gt;m_reshufflings[i].fromOffset];
</del><ins>+        temporaryLocals[i] = pivot[VirtualRegister(entry-&gt;m_reshufflings[i].fromOffset).toLocal()].jsValue();
</ins><span class="cx">     for (unsigned i = entry-&gt;m_reshufflings.size(); i--;)
</span><del>-        registers[entry-&gt;m_reshufflings[i].toOffset] = temporaryLocals[i];
</del><ins>+        pivot[VirtualRegister(entry-&gt;m_reshufflings[i].toOffset).toLocal()] = temporaryLocals[i];
</ins><span class="cx">     
</span><del>-    // 5) Clear those parts of the call frame that the DFG ain't using. This helps GC on some
-    //    programs by eliminating some stale pointer pathologies.
-
-#if 0 // FIXME: CStack - This needs to be verified before being enabled
</del><ins>+    // 5) Clear those parts of the call frame that the DFG ain't using. This helps GC on
+    //    some programs by eliminating some stale pointer pathologies.
</ins><span class="cx">     for (unsigned i = frameSize; i--;) {
</span><span class="cx">         if (entry-&gt;m_machineStackUsed.get(i))
</span><span class="cx">             continue;
</span><del>-        registers[virtualRegisterForLocal(i).offset()] = JSValue::encode(JSValue());
</del><ins>+        pivot[i] = JSValue();
</ins><span class="cx">     }
</span><del>-#endif
</del><span class="cx">     
</span><del>-    // 6) Fix the call frame.
</del><ins>+    // 6) Fix the call frame to have the right code block.
</ins><span class="cx">     
</span><del>-    exec-&gt;setCodeBlock(codeBlock);
</del><ins>+    *bitwise_cast&lt;CodeBlock**&gt;(pivot - 1 - JSStack::CodeBlock) = codeBlock;
</ins><span class="cx">     
</span><del>-    // 7) Find and return the destination machine code address.
-    
-    void* result = codeBlock-&gt;jitCode()-&gt;executableAddressAtOffset(entry-&gt;m_machineCodeOffset);
-    
</del><span class="cx">     if (Options::verboseOSR())
</span><del>-        dataLogF(&quot;    OSR returning machine code address %p.\n&quot;, result);
-    
-    return result;
</del><ins>+        dataLogF(&quot;    OSR returning data buffer %p.\n&quot;, scratch);
+    return scratch;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOSREntryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOSREntry.h (164204 => 164205)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOSREntry.h        2014-02-17 03:52:02 UTC (rev 164204)
+++ trunk/Source/JavaScriptCore/dfg/DFGOSREntry.h        2014-02-17 06:25:05 UTC (rev 164205)
</span><span class="lines">@@ -67,6 +67,8 @@
</span><span class="cx">     return osrEntryData-&gt;m_bytecodeIndex;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// Returns a pointer to a data buffer that the OSR entry thunk will recognize and
+// parse. If this returns null, it means 
</ins><span class="cx"> void* prepareOSREntry(ExecState*, CodeBlock*, unsigned bytecodeIndex);
</span><span class="cx"> #else
</span><span class="cx"> inline void* prepareOSREntry(ExecState*, CodeBlock*, unsigned) { return 0; }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGThunkscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGThunks.cpp (164204 => 164205)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGThunks.cpp        2014-02-17 03:52:02 UTC (rev 164204)
+++ trunk/Source/JavaScriptCore/dfg/DFGThunks.cpp        2014-02-17 06:25:05 UTC (rev 164205)
</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">@@ -96,6 +96,46 @@
</span><span class="cx">     return FINALIZE_CODE(patchBuffer, (&quot;DFG OSR exit generation thunk&quot;));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+MacroAssemblerCodeRef osrEntryThunkGenerator(VM* vm)
+{
+    MacroAssembler jit;
+    
+    // We get passed the address of a scratch buffer. The first 8-byte slot of the buffer
+    // is the frame size. The second 8-byte slot is the pointer to where we are supposed to
+    // jump. The remaining bytes are the new call frame header followed by the locals.
+    
+    ptrdiff_t offsetOfFrameSize = 0; // This is the DFG frame count.
+    ptrdiff_t offsetOfTargetPC = offsetOfFrameSize + sizeof(EncodedJSValue);
+    ptrdiff_t offsetOfPayload = offsetOfTargetPC + sizeof(EncodedJSValue);
+    ptrdiff_t offsetOfLocals = offsetOfPayload + sizeof(Register) * JSStack::CallFrameHeaderSize;
+    
+    jit.move(GPRInfo::returnValueGPR2, GPRInfo::regT0);
+    jit.loadPtr(MacroAssembler::Address(GPRInfo::regT0, offsetOfFrameSize), GPRInfo::regT1); // Load the frame size.
+    jit.move(GPRInfo::regT1, GPRInfo::regT2);
+    jit.lshiftPtr(MacroAssembler::Imm32(3), GPRInfo::regT2);
+    jit.move(GPRInfo::callFrameRegister, MacroAssembler::stackPointerRegister);
+    jit.subPtr(GPRInfo::regT2, MacroAssembler::stackPointerRegister);
+    
+    MacroAssembler::Label loop = jit.label();
+    jit.subPtr(MacroAssembler::TrustedImm32(1), GPRInfo::regT1);
+    jit.move(GPRInfo::regT1, GPRInfo::regT4);
+    jit.negPtr(GPRInfo::regT4);
+    jit.load32(MacroAssembler::BaseIndex(GPRInfo::regT0, GPRInfo::regT1, MacroAssembler::TimesEight, offsetOfLocals), GPRInfo::regT2);
+    jit.load32(MacroAssembler::BaseIndex(GPRInfo::regT0, GPRInfo::regT1, MacroAssembler::TimesEight, offsetOfLocals + sizeof(int32_t)), GPRInfo::regT3);
+    jit.store32(GPRInfo::regT2, MacroAssembler::BaseIndex(GPRInfo::callFrameRegister, GPRInfo::regT4, MacroAssembler::TimesEight, -static_cast&lt;intptr_t&gt;(sizeof(Register))));
+    jit.store32(GPRInfo::regT3, MacroAssembler::BaseIndex(GPRInfo::callFrameRegister, GPRInfo::regT4, MacroAssembler::TimesEight, -static_cast&lt;intptr_t&gt;(sizeof(Register)) + static_cast&lt;intptr_t&gt;(sizeof(int32_t))));
+    jit.branchPtr(MacroAssembler::NotEqual, GPRInfo::regT1, MacroAssembler::TrustedImmPtr(bitwise_cast&lt;void*&gt;(-static_cast&lt;intptr_t&gt;(JSStack::CallFrameHeaderSize)))).linkTo(loop, &amp;jit);
+    
+    jit.loadPtr(MacroAssembler::Address(GPRInfo::regT0, offsetOfTargetPC), GPRInfo::regT1);
+    MacroAssembler::Jump ok = jit.branchPtr(MacroAssembler::Above, GPRInfo::regT1, MacroAssembler::TrustedImmPtr(bitwise_cast&lt;void*&gt;(static_cast&lt;intptr_t&gt;(1000))));
+    jit.breakpoint();
+    ok.link(&amp;jit);
+    jit.jump(GPRInfo::regT1);
+    
+    LinkBuffer patchBuffer(*vm, &amp;jit, GLOBAL_THUNK_ID);
+    return FINALIZE_CODE(patchBuffer, (&quot;DFG OSR entry thunk&quot;));
+}
+
</ins><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(DFG_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGThunksh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGThunks.h (164204 => 164205)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGThunks.h        2014-02-17 03:52:02 UTC (rev 164204)
+++ trunk/Source/JavaScriptCore/dfg/DFGThunks.h        2014-02-17 06:25:05 UTC (rev 164205)
</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">@@ -39,6 +39,7 @@
</span><span class="cx"> namespace DFG {
</span><span class="cx"> 
</span><span class="cx"> MacroAssemblerCodeRef osrExitGenerationThunkGenerator(VM*);
</span><ins>+MacroAssemblerCodeRef osrEntryThunkGenerator(VM*);
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::DFG
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (164204 => 164205)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-02-17 03:52:02 UTC (rev 164204)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2014-02-17 06:25:05 UTC (rev 164205)
</span><span class="lines">@@ -1106,7 +1106,11 @@
</span><span class="cx">         
</span><span class="cx">         callOperation(operationOptimize, m_bytecodeOffset);
</span><span class="cx">         Jump noOptimizedEntry = branchTestPtr(Zero, returnValueGPR);
</span><del>-        move(returnValueGPR2, stackPointerRegister);
</del><ins>+        if (!ASSERT_DISABLED) {
+            Jump ok = branchPtr(MacroAssembler::Above, regT0, TrustedImmPtr(bitwise_cast&lt;void*&gt;(static_cast&lt;intptr_t&gt;(1000))));
+            breakpoint();
+            ok.link(this);
+        }
</ins><span class="cx">         jump(returnValueGPR);
</span><span class="cx">         noOptimizedEntry.link(this);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (164204 => 164205)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-02-17 03:52:02 UTC (rev 164204)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-02-17 06:25:05 UTC (rev 164205)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;DFGCompilationMode.h&quot;
</span><span class="cx"> #include &quot;DFGDriver.h&quot;
</span><span class="cx"> #include &quot;DFGOSREntry.h&quot;
</span><ins>+#include &quot;DFGThunks.h&quot;
</ins><span class="cx"> #include &quot;DFGWorklist.h&quot;
</span><span class="cx"> #include &quot;Error.h&quot;
</span><span class="cx"> #include &quot;ErrorHandlingScope.h&quot;
</span><span class="lines">@@ -1189,16 +1190,14 @@
</span><span class="cx">     CodeBlock* optimizedCodeBlock = codeBlock-&gt;replacement();
</span><span class="cx">     ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock-&gt;jitType()));
</span><span class="cx">     
</span><del>-    if (void* address = DFG::prepareOSREntry(exec, optimizedCodeBlock, bytecodeIndex)) {
</del><ins>+    if (void* dataBuffer = DFG::prepareOSREntry(exec, optimizedCodeBlock, bytecodeIndex)) {
</ins><span class="cx">         if (Options::verboseOSR()) {
</span><span class="cx">             dataLog(
</span><del>-                &quot;Performing OSR &quot;, *codeBlock, &quot; -&gt; &quot;, *optimizedCodeBlock, &quot;, address &quot;,
-                RawPointer(OUR_RETURN_ADDRESS), &quot; -&gt; &quot;, RawPointer(address), &quot;.\n&quot;);
</del><ins>+                &quot;Performing OSR &quot;, *codeBlock, &quot; -&gt; &quot;, *optimizedCodeBlock, &quot;.\n&quot;);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         codeBlock-&gt;optimizeSoon();
</span><del>-        ASSERT(exec-&gt;codeBlock() == optimizedCodeBlock);
-        return encodeResult(address, exec-&gt;topOfFrame());
</del><ins>+        return encodeResult(vm.getCTIStub(DFG::osrEntryThunkGenerator).code().executableAddress(), dataBuffer);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (Options::verboseOSR()) {
</span></span></pre>
</div>
</div>

</body>
</html>