<!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>[37831] trunk/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/37831">37831</a></dd>
<dt>Author</dt> <dd>barraclough@apple.com</dd>
<dt>Date</dt> <dd>2008-10-23 15:29:54 -0700 (Thu, 23 Oct 2008)</dd>
</dl>

<h3>Log Message</h3>
<pre>2008-10-23  Gavin Barraclough  &lt;barraclough@apple.com&gt;

        Reviewed by Oliver Hunt.

        Fix hideous pathological case performance when looking up repatch info, bug #21727.

        When repatching JIT code to optimize we look up records providing information about
        the generated code (also used to track recsources used in linking to be later released). 
        The lookup was being performed using a linear scan of all such records.

        (1) Split up the different types of reptach information.  This means we can search them
            separately, and in some cases should reduce their size.
        (2) In the case of property accesses, search with a binary chop over the data.
        (3) In the case of calls, pass a pointer to the repatch info into the relink function.

        * VM/CTI.cpp:
        (JSC::CTI::CTI):
        (JSC::CTI::compileOpCall):
        (JSC::CTI::privateCompileMainPass):
        (JSC::CTI::privateCompileSlowCases):
        (JSC::CTI::privateCompile):
        (JSC::CTI::unlinkCall):
        (JSC::CTI::linkCall):
        * VM/CTI.h:
        * VM/CodeBlock.cpp:
        (JSC::CodeBlock::dump):
        (JSC::CodeBlock::~CodeBlock):
        (JSC::CodeBlock::unlinkCallers):
        (JSC::CodeBlock::derefStructureIDs):
        * VM/CodeBlock.h:
        (JSC::StructureStubInfo::StructureStubInfo):
        (JSC::CallLinkInfo::CallLinkInfo):
        (JSC::CallLinkInfo::setUnlinked):
        (JSC::CallLinkInfo::isLinked):
        (JSC::getStructureStubInfoReturnLocation):
        (JSC::binaryChop):
        (JSC::CodeBlock::addCaller):
        (JSC::CodeBlock::getStubInfo):
        * VM/CodeGenerator.cpp:
        (JSC::CodeGenerator::emitResolve):
        (JSC::CodeGenerator::emitGetById):
        (JSC::CodeGenerator::emitPutById):
        (JSC::CodeGenerator::emitCall):
        (JSC::CodeGenerator::emitConstruct):
        * VM/Machine.cpp:
        (JSC::Machine::cti_vm_lazyLinkCall):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJavaScriptCoreChangeLog">trunk/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkJavaScriptCoreVMCTIcpp">trunk/JavaScriptCore/VM/CTI.cpp</a></li>
<li><a href="#trunkJavaScriptCoreVMCTIh">trunk/JavaScriptCore/VM/CTI.h</a></li>
<li><a href="#trunkJavaScriptCoreVMCodeBlockcpp">trunk/JavaScriptCore/VM/CodeBlock.cpp</a></li>
<li><a href="#trunkJavaScriptCoreVMCodeBlockh">trunk/JavaScriptCore/VM/CodeBlock.h</a></li>
<li><a href="#trunkJavaScriptCoreVMCodeGeneratorcpp">trunk/JavaScriptCore/VM/CodeGenerator.cpp</a></li>
<li><a href="#trunkJavaScriptCoreVMMachinecpp">trunk/JavaScriptCore/VM/Machine.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/ChangeLog (37830 => 37831)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/ChangeLog        2008-10-23 22:12:18 UTC (rev 37830)
+++ trunk/JavaScriptCore/ChangeLog        2008-10-23 22:29:54 UTC (rev 37831)
</span><span class="lines">@@ -1,3 +1,50 @@
</span><ins>+2008-10-23  Gavin Barraclough  &lt;barraclough@apple.com&gt;
+
+        Reviewed by Oliver Hunt.
+
+        Fix hideous pathological case performance when looking up repatch info, bug #21727.
+
+        When repatching JIT code to optimize we look up records providing information about
+        the generated code (also used to track recsources used in linking to be later released). 
+        The lookup was being performed using a linear scan of all such records.
+
+        (1) Split up the different types of reptach information.  This means we can search them
+            separately, and in some cases should reduce their size.
+        (2) In the case of property accesses, search with a binary chop over the data.
+        (3) In the case of calls, pass a pointer to the repatch info into the relink function.
+
+        * VM/CTI.cpp:
+        (JSC::CTI::CTI):
+        (JSC::CTI::compileOpCall):
+        (JSC::CTI::privateCompileMainPass):
+        (JSC::CTI::privateCompileSlowCases):
+        (JSC::CTI::privateCompile):
+        (JSC::CTI::unlinkCall):
+        (JSC::CTI::linkCall):
+        * VM/CTI.h:
+        * VM/CodeBlock.cpp:
+        (JSC::CodeBlock::dump):
+        (JSC::CodeBlock::~CodeBlock):
+        (JSC::CodeBlock::unlinkCallers):
+        (JSC::CodeBlock::derefStructureIDs):
+        * VM/CodeBlock.h:
+        (JSC::StructureStubInfo::StructureStubInfo):
+        (JSC::CallLinkInfo::CallLinkInfo):
+        (JSC::CallLinkInfo::setUnlinked):
+        (JSC::CallLinkInfo::isLinked):
+        (JSC::getStructureStubInfoReturnLocation):
+        (JSC::binaryChop):
+        (JSC::CodeBlock::addCaller):
+        (JSC::CodeBlock::getStubInfo):
+        * VM/CodeGenerator.cpp:
+        (JSC::CodeGenerator::emitResolve):
+        (JSC::CodeGenerator::emitGetById):
+        (JSC::CodeGenerator::emitPutById):
+        (JSC::CodeGenerator::emitCall):
+        (JSC::CodeGenerator::emitConstruct):
+        * VM/Machine.cpp:
+        (JSC::Machine::cti_vm_lazyLinkCall):
+
</ins><span class="cx"> 2008-10-23  Peter Kasting  &lt;pkasting@google.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Reviewed by Adam Roben.
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMCTIcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/CTI.cpp (37830 => 37831)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/CTI.cpp        2008-10-23 22:12:18 UTC (rev 37830)
+++ trunk/JavaScriptCore/VM/CTI.cpp        2008-10-23 22:29:54 UTC (rev 37831)
</span><span class="lines">@@ -513,7 +513,8 @@
</span><span class="cx">     , m_callFrame(callFrame)
</span><span class="cx">     , m_codeBlock(codeBlock)
</span><span class="cx">     , m_labels(codeBlock ? codeBlock-&gt;instructions.size() : 0)
</span><del>-    , m_structureStubCompilationInfo(codeBlock ? codeBlock-&gt;structureIDInstructions.size() : 0)
</del><ins>+    , m_propertyAccessCompilationInfo(codeBlock ? codeBlock-&gt;propertyAccessInstructions.size() : 0)
+    , m_callStructureStubCompilationInfo(codeBlock ? codeBlock-&gt;callLinkInfos.size() : 0)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -576,7 +577,7 @@
</span><span class="cx">         emitGetPutArg(instruction[3].u.operand, 16, X86::eax);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CTI::compileOpCall(Instruction* instruction, unsigned i, unsigned structureIDInstructionIndex, CompileOpCallType type)
</del><ins>+void CTI::compileOpCall(Instruction* instruction, unsigned i, unsigned callLinkInfoIndex, CompileOpCallType type)
</ins><span class="cx"> {
</span><span class="cx">     int dst = instruction[1].u.operand;
</span><span class="cx">     int callee = instruction[2].u.operand;
</span><span class="lines">@@ -614,7 +615,7 @@
</span><span class="cx">     X86Assembler::JmpDst addressOfLinkedFunctionCheck = m_jit.label();
</span><span class="cx">     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
</span><span class="cx">     ASSERT(X86Assembler::getDifferenceBetweenLabels(addressOfLinkedFunctionCheck, m_jit.label()) == repatchOffsetOpCallCall);
</span><del>-    m_structureStubCompilationInfo[structureIDInstructionIndex].hotPathBegin = addressOfLinkedFunctionCheck;
</del><ins>+    m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
</ins><span class="cx"> 
</span><span class="cx">     // The following is the fast case, only used whan a callee can be linked.
</span><span class="cx"> 
</span><span class="lines">@@ -638,7 +639,7 @@
</span><span class="cx">     m_jit.addl_i32r(registerOffset * sizeof(Register), X86::edi);
</span><span class="cx"> 
</span><span class="cx">     // Call to the callee
</span><del>-    m_structureStubCompilationInfo[structureIDInstructionIndex].hotPathOther = emitNakedCall(i, unreachable);
</del><ins>+    m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(i, unreachable);
</ins><span class="cx">     
</span><span class="cx">     if (type == OpCallEval)
</span><span class="cx">         m_jit.link(wasEval, m_jit.label());
</span><span class="lines">@@ -949,7 +950,8 @@
</span><span class="cx">     Instruction* instruction = m_codeBlock-&gt;instructions.begin();
</span><span class="cx">     unsigned instructionCount = m_codeBlock-&gt;instructions.size();
</span><span class="cx"> 
</span><del>-    unsigned structureIDInstructionIndex = 0;
</del><ins>+    unsigned propertyAccessInstructionIndex = 0;
+    unsigned callLinkInfoIndex = 0;
</ins><span class="cx"> 
</span><span class="cx">     for (unsigned i = 0; i &lt; instructionCount; ) {
</span><span class="cx">         m_labels[i] = m_jit.label();
</span><span class="lines">@@ -1094,10 +1096,10 @@
</span><span class="cx">             emitGetArg(instruction[i + 1].u.operand, X86::eax);
</span><span class="cx">             emitGetArg(instruction[i + 3].u.operand, X86::edx);
</span><span class="cx"> 
</span><del>-            ASSERT(m_codeBlock-&gt;structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);
</del><ins>+            ASSERT(m_codeBlock-&gt;propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i);
</ins><span class="cx">             X86Assembler::JmpDst hotPathBegin = m_jit.label();
</span><del>-            m_structureStubCompilationInfo[structureIDInstructionIndex].hotPathBegin = hotPathBegin;
-            ++structureIDInstructionIndex;
</del><ins>+            m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
+            ++propertyAccessInstructionIndex;
</ins><span class="cx"> 
</span><span class="cx">             // Jump to a slow case if either the base object is an immediate, or if the StructureID does not match.
</span><span class="cx">             emitJumpSlowCaseIfNotJSCell(X86::eax, i);
</span><span class="lines">@@ -1122,11 +1124,11 @@
</span><span class="cx"> 
</span><span class="cx">             emitGetArg(instruction[i + 2].u.operand, X86::eax);
</span><span class="cx"> 
</span><del>-            ASSERT(m_codeBlock-&gt;structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);
</del><ins>+            ASSERT(m_codeBlock-&gt;propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i);
</ins><span class="cx"> 
</span><span class="cx">             X86Assembler::JmpDst hotPathBegin = m_jit.label();
</span><del>-            m_structureStubCompilationInfo[structureIDInstructionIndex].hotPathBegin = hotPathBegin;
-            ++structureIDInstructionIndex;
</del><ins>+            m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
+            ++propertyAccessInstructionIndex;
</ins><span class="cx"> 
</span><span class="cx">             emitJumpSlowCaseIfNotJSCell(X86::eax, i);
</span><span class="cx">             m_jit.cmpl_i32m(repatchGetByIdDefaultStructureID, OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
</span><span class="lines">@@ -1252,7 +1254,7 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case op_call: {
</span><del>-            compileOpCall(instruction + i, i, structureIDInstructionIndex++);
</del><ins>+            compileOpCall(instruction + i, i, callLinkInfoIndex++);
</ins><span class="cx">             i += 7;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -1348,7 +1350,7 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case op_construct: {
</span><del>-            compileOpCall(instruction + i, i, structureIDInstructionIndex++, OpConstruct);
</del><ins>+            compileOpCall(instruction + i, i, callLinkInfoIndex++, OpConstruct);
</ins><span class="cx">             i += 7;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -1490,8 +1492,7 @@
</span><span class="cx">             m_jit.movl_i32r(globalObject, X86::eax);
</span><span class="cx">             m_jit.movl_mr(structureIDAddr, X86::edx);
</span><span class="cx">             m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
</span><del>-            X86Assembler::JmpSrc slowCase = m_jit.emitUnlinkedJne(); // StructureIDs don't match
-            m_slowCases.append(SlowCaseEntry(slowCase, i));
</del><ins>+            X86Assembler::JmpSrc noMatch = m_jit.emitUnlinkedJne(); // StructureIDs don't match
</ins><span class="cx"> 
</span><span class="cx">             // Load cached property
</span><span class="cx">             m_jit.movl_mr(OBJECT_OFFSET(JSGlobalObject, m_propertyStorage), X86::eax, X86::eax);
</span><span class="lines">@@ -1501,7 +1502,7 @@
</span><span class="cx">             X86Assembler::JmpSrc end = m_jit.emitUnlinkedJmp();
</span><span class="cx"> 
</span><span class="cx">             // Slow case
</span><del>-            m_jit.link(slowCase, m_jit.label());
</del><ins>+            m_jit.link(noMatch, m_jit.label());
</ins><span class="cx">             emitPutArgConstant(globalObject, 0);
</span><span class="cx">             emitPutArgConstant(reinterpret_cast&lt;unsigned&gt;(ident), 4);
</span><span class="cx">             emitPutArgConstant(reinterpret_cast&lt;unsigned&gt;(instruction + i), 8);
</span><span class="lines">@@ -1509,7 +1510,6 @@
</span><span class="cx">             emitPutResult(instruction[i + 1].u.operand);
</span><span class="cx">             m_jit.link(end, m_jit.label());
</span><span class="cx">             i += 6;
</span><del>-            ++structureIDInstructionIndex;
</del><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         CTI_COMPILE_BINARY_OP(op_div)
</span><span class="lines">@@ -1841,7 +1841,7 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case op_call_eval: {
</span><del>-            compileOpCall(instruction + i, i, structureIDInstructionIndex++, OpCallEval);
</del><ins>+            compileOpCall(instruction + i, i, callLinkInfoIndex++, OpCallEval);
</ins><span class="cx">             i += 7;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -2192,7 +2192,8 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ASSERT(structureIDInstructionIndex == m_codeBlock-&gt;structureIDInstructions.size());
</del><ins>+    ASSERT(propertyAccessInstructionIndex == m_codeBlock-&gt;propertyAccessInstructions.size());
+    ASSERT(callLinkInfoIndex == m_codeBlock-&gt;callLinkInfos.size());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -2217,7 +2218,8 @@
</span><span class="cx">     
</span><span class="cx"> void CTI::privateCompileSlowCases()
</span><span class="cx"> {
</span><del>-    unsigned structureIDInstructionIndex = 0;
</del><ins>+    unsigned propertyAccessInstructionIndex = 0;
+    unsigned callLinkInfoIndex = 0;
</ins><span class="cx"> 
</span><span class="cx">     Instruction* instruction = m_codeBlock-&gt;instructions.begin();
</span><span class="cx">     for (Vector&lt;SlowCaseEntry&gt;::iterator iter = m_slowCases.begin(); iter != m_slowCases.end(); ++iter) {
</span><span class="lines">@@ -2361,9 +2363,9 @@
</span><span class="cx">             X86Assembler::JmpSrc call = emitCTICall(i, Machine::cti_op_put_by_id);
</span><span class="cx"> 
</span><span class="cx">             // Track the location of the call; this will be used to recover repatch information.
</span><del>-            ASSERT(m_codeBlock-&gt;structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);
-            m_structureStubCompilationInfo[structureIDInstructionIndex].callReturnLocation = call;
-            ++structureIDInstructionIndex;
</del><ins>+            ASSERT(m_codeBlock-&gt;propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i);
+            m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
+            ++propertyAccessInstructionIndex;
</ins><span class="cx"> 
</span><span class="cx">             i += 8;
</span><span class="cx">             break;
</span><span class="lines">@@ -2389,18 +2391,13 @@
</span><span class="cx">             emitPutResult(instruction[i + 1].u.operand);
</span><span class="cx"> 
</span><span class="cx">             // Track the location of the call; this will be used to recover repatch information.
</span><del>-            ASSERT(m_codeBlock-&gt;structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);
-            m_structureStubCompilationInfo[structureIDInstructionIndex].callReturnLocation = call;
-            ++structureIDInstructionIndex;
</del><ins>+            ASSERT(m_codeBlock-&gt;propertyAccessInstructions[propertyAccessInstructionIndex].opcodeIndex == i);
+            m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
+            ++propertyAccessInstructionIndex;
</ins><span class="cx"> 
</span><span class="cx">             i += 8;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><del>-        case op_resolve_global: {
-            ++structureIDInstructionIndex;
-            i += 6;
-            break;
-        }
</del><span class="cx">         case op_loop_if_lesseq: {
</span><span class="cx">             emitSlowScriptCheck(i);
</span><span class="cx"> 
</span><span class="lines">@@ -2710,13 +2707,15 @@
</span><span class="cx">             m_jit.movl_rr(X86::edx, X86::edi);
</span><span class="cx"> 
</span><span class="cx">             // Try to link &amp; repatch this call.
</span><del>-            m_structureStubCompilationInfo[structureIDInstructionIndex].callReturnLocation =
</del><ins>+            CallLinkInfo* info = &amp;(m_codeBlock-&gt;callLinkInfos[callLinkInfoIndex]);
+            emitPutArgConstant(reinterpret_cast&lt;unsigned&gt;(info), 4);
+            m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation =
</ins><span class="cx">                 emitCTICall(i, Machine::cti_vm_lazyLinkCall);
</span><span class="cx">             emitNakedCall(i, X86::eax);
</span><span class="cx">             X86Assembler::JmpSrc storeResultForFirstRun = m_jit.emitUnlinkedJmp();
</span><span class="cx"> 
</span><span class="cx">             // This is the address for the cold path *after* the first run (which tries to link the call).
</span><del>-            m_structureStubCompilationInfo[structureIDInstructionIndex].coldPathOther = m_jit.label();
</del><ins>+            m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = m_jit.label();
</ins><span class="cx"> 
</span><span class="cx">             // The arguments have been set up on the hot path for op_call_eval
</span><span class="cx">             if (opcodeID != op_call_eval)
</span><span class="lines">@@ -2763,7 +2762,7 @@
</span><span class="cx">             m_jit.link(storeResultForFirstRun, storeResult);
</span><span class="cx">             emitPutResult(dst);
</span><span class="cx"> 
</span><del>-            ++structureIDInstructionIndex;
</del><ins>+            ++callLinkInfoIndex;
</ins><span class="cx">             i += 7;
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="lines">@@ -2787,7 +2786,8 @@
</span><span class="cx">         m_jit.link(m_jit.emitUnlinkedJmp(), m_labels[i]);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ASSERT(structureIDInstructionIndex == m_codeBlock-&gt;structureIDInstructions.size());
</del><ins>+    ASSERT(propertyAccessInstructionIndex == m_codeBlock-&gt;propertyAccessInstructions.size());
+    ASSERT(callLinkInfoIndex == m_codeBlock-&gt;callLinkInfos.size());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CTI::privateCompile()
</span><span class="lines">@@ -2866,13 +2866,18 @@
</span><span class="cx">     for (Vector&lt;JSRInfo&gt;::iterator iter = m_jsrSites.begin(); iter != m_jsrSites.end(); ++iter)
</span><span class="cx">         X86Assembler::linkAbsoluteAddress(code, iter-&gt;addrPosition, iter-&gt;target);
</span><span class="cx"> 
</span><del>-    for (unsigned i = 0; i &lt; m_codeBlock-&gt;structureIDInstructions.size(); ++i) {
-        StructureStubInfo&amp; info = m_codeBlock-&gt;structureIDInstructions[i];
-        info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_structureStubCompilationInfo[i].callReturnLocation);
-        info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_structureStubCompilationInfo[i].hotPathBegin);
-        info.hotPathOther = X86Assembler::getRelocatedAddress(code, m_structureStubCompilationInfo[i].hotPathOther);
-        info.coldPathOther = X86Assembler::getRelocatedAddress(code, m_structureStubCompilationInfo[i].coldPathOther);
</del><ins>+    for (unsigned i = 0; i &lt; m_codeBlock-&gt;propertyAccessInstructions.size(); ++i) {
+        StructureStubInfo&amp; info = m_codeBlock-&gt;propertyAccessInstructions[i];
+        info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_propertyAccessCompilationInfo[i].callReturnLocation);
+        info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_propertyAccessCompilationInfo[i].hotPathBegin);
</ins><span class="cx">     }
</span><ins>+    for (unsigned i = 0; i &lt; m_codeBlock-&gt;callLinkInfos.size(); ++i) {
+        CallLinkInfo&amp; info = m_codeBlock-&gt;callLinkInfos[i];
+        info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].callReturnLocation);
+        info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].hotPathBegin);
+        info.hotPathOther = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].hotPathOther);
+        info.coldPathOther = X86Assembler::getRelocatedAddress(code, m_callStructureStubCompilationInfo[i].coldPathOther);
+    }
</ins><span class="cx"> 
</span><span class="cx">     m_codeBlock-&gt;ctiCode = code;
</span><span class="cx"> }
</span><span class="lines">@@ -3154,31 +3159,29 @@
</span><span class="cx">     ctiRepatchCallByReturnAddress(returnAddress, code);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CTI::unlinkCall(StructureStubInfo* structureStubInfo)
</del><ins>+void CTI::unlinkCall(CallLinkInfo* callLinkInfo)
</ins><span class="cx"> {
</span><span class="cx">     // When the JSFunction is deleted the pointer embedded in the instruction stream will no longer be valid
</span><span class="cx">     // (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive
</span><span class="cx">     // match).  Reset the check so it no longer matches.
</span><del>-    reinterpret_cast&lt;void**&gt;(structureStubInfo-&gt;hotPathBegin)[-1] = asPointer(JSImmediate::impossibleValue());
</del><ins>+    reinterpret_cast&lt;void**&gt;(callLinkInfo-&gt;hotPathBegin)[-1] = asPointer(JSImmediate::impossibleValue());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void CTI::linkCall(CodeBlock* callerCodeBlock, JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, void* returnAddress, int callerArgCount)
</del><ins>+void CTI::linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount)
</ins><span class="cx"> {
</span><del>-    StructureStubInfo&amp; stubInfo = callerCodeBlock-&gt;getStubInfo(returnAddress);
-
</del><span class="cx">     // Currently we only link calls with the exact number of arguments.
</span><span class="cx">     if (callerArgCount == calleeCodeBlock-&gt;numParameters) {
</span><del>-        ASSERT(!stubInfo.linkInfoPtr);
</del><ins>+        ASSERT(!callLinkInfo-&gt;isLinked());
</ins><span class="cx">     
</span><del>-        calleeCodeBlock-&gt;addCaller(&amp;stubInfo);
</del><ins>+        calleeCodeBlock-&gt;addCaller(callLinkInfo);
</ins><span class="cx">     
</span><del>-        reinterpret_cast&lt;void**&gt;(stubInfo.hotPathBegin)[-1] = callee;
-        ctiRepatchCallByReturnAddress(stubInfo.hotPathOther, ctiCode);
</del><ins>+        reinterpret_cast&lt;void**&gt;(callLinkInfo-&gt;hotPathBegin)[-1] = callee;
+        ctiRepatchCallByReturnAddress(callLinkInfo-&gt;hotPathOther, ctiCode);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // repatch the instruction that jumps out to the cold path, so that we only try to link once.
</span><del>-    void* repatchCheck = reinterpret_cast&lt;void*&gt;(reinterpret_cast&lt;ptrdiff_t&gt;(stubInfo.hotPathBegin) + repatchOffsetOpCallCall);
-    ctiRepatchCallByReturnAddress(repatchCheck, stubInfo.coldPathOther);
</del><ins>+    void* repatchCheck = reinterpret_cast&lt;void*&gt;(reinterpret_cast&lt;ptrdiff_t&gt;(callLinkInfo-&gt;hotPathBegin) + repatchOffsetOpCallCall);
+    ctiRepatchCallByReturnAddress(repatchCheck, callLinkInfo-&gt;coldPathOther);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void* CTI::privateCompileArrayLengthTrampoline()
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMCTIh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/CTI.h (37830 => 37831)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/CTI.h        2008-10-23 22:12:18 UTC (rev 37830)
+++ trunk/JavaScriptCore/VM/CTI.h        2008-10-23 22:29:54 UTC (rev 37831)
</span><span class="lines">@@ -79,6 +79,7 @@
</span><span class="cx"> #define ARG_instr4 static_cast&lt;Instruction*&gt;(ARGS[4])
</span><span class="cx"> #define ARG_instr5 static_cast&lt;Instruction*&gt;(ARGS[5])
</span><span class="cx"> #define ARG_instr6 static_cast&lt;Instruction*&gt;(ARGS[6])
</span><ins>+#define ARG_linkInfo2 static_cast&lt;CallLinkInfo*&gt;(ARGS[2])
</ins><span class="cx"> 
</span><span class="cx"> #define CTI_RETURN_ADDRESS_SLOT (ARGS[-1])
</span><span class="cx"> 
</span><span class="lines">@@ -94,9 +95,9 @@
</span><span class="cx">     class StringJumpTable;
</span><span class="cx">     class StructureIDChain;
</span><span class="cx"> 
</span><ins>+    struct CallLinkInfo;
</ins><span class="cx">     struct Instruction;
</span><span class="cx">     struct OperandTypes;
</span><del>-    struct StructureStubInfo;
</del><span class="cx"> 
</span><span class="cx">     typedef JSValue* (SFX_CALL *CTIHelper_j)(CTI_ARGS);
</span><span class="cx">     typedef JSObject* (SFX_CALL *CTIHelper_o)(CTI_ARGS);
</span><span class="lines">@@ -334,8 +335,8 @@
</span><span class="cx">             return cti.privateCompilePatchGetArrayLength(returnAddress);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        static void linkCall(CodeBlock* callerCodeBlock, JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, void* returnAddress, int callerArgCount);
-        static void unlinkCall(StructureStubInfo*);
</del><ins>+        static void linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount);
+        static void unlinkCall(CallLinkInfo*);
</ins><span class="cx"> 
</span><span class="cx">         inline static JSValuePtr execute(void* code, RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData, JSValuePtr* exception)
</span><span class="cx">         {
</span><span class="lines">@@ -433,7 +434,8 @@
</span><span class="cx"> 
</span><span class="cx">         Vector&lt;CallRecord&gt; m_calls;
</span><span class="cx">         Vector&lt;X86Assembler::JmpDst&gt; m_labels;
</span><del>-        Vector&lt;StructureStubCompilationInfo&gt; m_structureStubCompilationInfo;
</del><ins>+        Vector&lt;StructureStubCompilationInfo&gt; m_propertyAccessCompilationInfo;
+        Vector&lt;StructureStubCompilationInfo&gt; m_callStructureStubCompilationInfo;
</ins><span class="cx">         Vector&lt;JmpTable&gt; m_jmpTable;
</span><span class="cx"> 
</span><span class="cx">         struct JSRInfo {
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/CodeBlock.cpp (37830 => 37831)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/CodeBlock.cpp        2008-10-23 22:12:18 UTC (rev 37830)
+++ trunk/JavaScriptCore/VM/CodeBlock.cpp        2008-10-23 22:29:54 UTC (rev 37831)
</span><span class="lines">@@ -275,14 +275,23 @@
</span><span class="cx">         } while (i &lt; regexps.size());
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (structureIDInstructions.size()) {
</del><ins>+    if (globalResolveInstructions.size() || propertyAccessInstructions.size())
</ins><span class="cx">         printf(&quot;\nStructureIDs:\n&quot;);
</span><ins>+
+    if (globalResolveInstructions.size()) {
</ins><span class="cx">         size_t i = 0;
</span><span class="cx">         do {
</span><del>-             printStructureIDs(&amp;instructions[structureIDInstructions[i].opcodeIndex]);
</del><ins>+             printStructureIDs(&amp;instructions[globalResolveInstructions[i]]);
</ins><span class="cx">              ++i;
</span><del>-        } while (i &lt; structureIDInstructions.size());
</del><ins>+        } while (i &lt; globalResolveInstructions.size());
</ins><span class="cx">     }
</span><ins>+    if (propertyAccessInstructions.size()) {
+        size_t i = 0;
+        do {
+             printStructureIDs(&amp;instructions[propertyAccessInstructions[i].opcodeIndex]);
+             ++i;
+        } while (i &lt; propertyAccessInstructions.size());
+    }
</ins><span class="cx">  
</span><span class="cx">     if (exceptionHandlers.size()) {
</span><span class="cx">         printf(&quot;\nException Handlers:\n&quot;);
</span><span class="lines">@@ -941,15 +950,20 @@
</span><span class="cx"> 
</span><span class="cx"> CodeBlock::~CodeBlock()
</span><span class="cx"> {
</span><del>-    size_t size = structureIDInstructions.size();
-    for (size_t i = 0; i &lt; size; ++i) {
-        derefStructureIDs(&amp;instructions[structureIDInstructions[i].opcodeIndex]);
-        if (structureIDInstructions[i].stubRoutine)
-            WTF::fastFreeExecutable(structureIDInstructions[i].stubRoutine);
-        if (CallLinkInfo* callLinkInfo = structureIDInstructions[i].linkInfoPtr) {
</del><ins>+    for (size_t size = globalResolveInstructions.size(), i = 0; i &lt; size; ++i) {
+        derefStructureIDs(&amp;instructions[globalResolveInstructions[i]]);
+    }
+
+    for (size_t size = propertyAccessInstructions.size(), i = 0; i &lt; size; ++i) {
+        derefStructureIDs(&amp;instructions[propertyAccessInstructions[i].opcodeIndex]);
+        if (propertyAccessInstructions[i].stubRoutine)
+            WTF::fastFreeExecutable(propertyAccessInstructions[i].stubRoutine);
+    }
+
+    for (size_t size = callLinkInfos.size(), i = 0; i &lt; size; ++i) {
+        CallLinkInfo* callLinkInfo = &amp;callLinkInfos[i];
+        if (callLinkInfo-&gt;isLinked())
</ins><span class="cx">             callLinkInfo-&gt;callee-&gt;removeCaller(callLinkInfo);
</span><del>-            delete callLinkInfo;
-        }
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CTI) 
</span><span class="lines">@@ -966,9 +980,8 @@
</span><span class="cx">     size_t size = linkedCallerList.size();
</span><span class="cx">     for (size_t i = 0; i &lt; size; ++i) {
</span><span class="cx">         CallLinkInfo* currentCaller = linkedCallerList[i];
</span><del>-        CTI::unlinkCall(currentCaller-&gt;callerStructureStubInfo);
-        currentCaller-&gt;callerStructureStubInfo-&gt;linkInfoPtr = 0;
-        delete currentCaller;
</del><ins>+        CTI::unlinkCall(currentCaller);
+        currentCaller-&gt;setUnlinked();
</ins><span class="cx">     }
</span><span class="cx">     linkedCallerList.clear();
</span><span class="cx"> }
</span><span class="lines">@@ -1009,8 +1022,7 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // These instructions don't ref their StructureIDs.
</span><del>-    ASSERT(vPC[0].u.opcode == machine-&gt;getOpcode(op_get_by_id) || vPC[0].u.opcode == machine-&gt;getOpcode(op_put_by_id) || vPC[0].u.opcode == machine-&gt;getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == machine-&gt;getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == machine-&gt;getOpcode(op_get_array_length) || vPC[0].u.opcode == machine-&gt;getOpcode(op_get_string_length)
-        || vPC[0].u.opcode == machine-&gt;getOpcode(op_call_eval) || vPC[0].u.opcode == machine-&gt;getOpcode(op_call) || vPC[0].u.opcode == machine-&gt;getOpcode(op_construct));
</del><ins>+    ASSERT(vPC[0].u.opcode == machine-&gt;getOpcode(op_get_by_id) || vPC[0].u.opcode == machine-&gt;getOpcode(op_put_by_id) || vPC[0].u.opcode == machine-&gt;getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == machine-&gt;getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == machine-&gt;getOpcode(op_get_array_length) || vPC[0].u.opcode == machine-&gt;getOpcode(op_get_string_length));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void CodeBlock::refStructureIDs(Instruction* vPC) const
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/CodeBlock.h (37830 => 37831)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/CodeBlock.h        2008-10-23 22:12:18 UTC (rev 37830)
+++ trunk/JavaScriptCore/VM/CodeBlock.h        2008-10-23 22:29:54 UTC (rev 37831)
</span><span class="lines">@@ -78,40 +78,83 @@
</span><span class="cx"> #endif
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    struct CallLinkInfo;
-
</del><span class="cx">     struct StructureStubInfo {
</span><span class="cx">         StructureStubInfo(unsigned opcodeIndex)
</span><span class="cx">             : opcodeIndex(opcodeIndex)
</span><span class="cx">             , stubRoutine(0)
</span><span class="cx">             , callReturnLocation(0)
</span><span class="cx">             , hotPathBegin(0)
</span><ins>+        {
+        }
+    
+        unsigned opcodeIndex;
+        void* stubRoutine;
+        void* callReturnLocation;
+        void* hotPathBegin;
+    };
+
+    struct CallLinkInfo {
+        CallLinkInfo()
+            : callReturnLocation(0)
+            , hotPathBegin(0)
</ins><span class="cx">             , hotPathOther(0)
</span><span class="cx">             , coldPathOther(0)
</span><del>-            , linkInfoPtr(0)
</del><ins>+            , callee(0)
</ins><span class="cx">         {
</span><span class="cx">         }
</span><span class="cx">     
</span><span class="cx">         unsigned opcodeIndex;
</span><del>-        void* stubRoutine;
</del><span class="cx">         void* callReturnLocation;
</span><span class="cx">         void* hotPathBegin;
</span><span class="cx">         void* hotPathOther;
</span><span class="cx">         void* coldPathOther;
</span><del>-        CallLinkInfo* linkInfoPtr;
-    };
-
-    struct CallLinkInfo {
</del><span class="cx">         CodeBlock* callee;
</span><del>-        StructureStubInfo* callerStructureStubInfo;
</del><span class="cx">         unsigned position;
</span><ins>+        
+        void setUnlinked() { callee = 0; }
+        bool isLinked() { return callee; }
+    };
</ins><span class="cx"> 
</span><del>-        CallLinkInfo(CodeBlock* c, StructureStubInfo* css)
-        {
-            callee = c;
-            callerStructureStubInfo = css;
</del><ins>+    inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
+    {
+        return structureStubInfo-&gt;callReturnLocation;
+    }
+
+    // Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array,
+    // compares result with key (KeyTypes should be comparable with '--', '&lt;', '&gt;').
+    // Optimized for cases where the array contains the key, checked by assertions.
+    template&lt;typename ArrayType, typename KeyType, KeyType(*valueAtPosition)(ArrayType*)&gt;
+    inline ArrayType* binaryChop(ArrayType* array, size_t size, KeyType key)
+    {
+        // The array must contain at least one element (pre-condition, array does conatin key).
+        // If the array only contains one element, no need to do the comparison.
+        while (size &gt; 1) {
+            // Pick an element to check, half way through the array, and read the value.
+            int pos = (size - 1) &gt;&gt; 1;
+            KeyType val = valueAtPosition(&amp;array[pos]);
+            
+            // If the key matches, success!
+            if (val == key)
+                return &amp;array[pos];
+            // The item we are looking for is smaller than the item being check; reduce the value of 'size',
+            // chopping off the right hand half of the array.
+            else if (key &lt; val)
+                size = pos;
+            // Discard all values in the left hand half of the array, up to and including the item at pos.
+            else {
+                size -= (pos + 1);
+                array += (pos + 1);
+            }
+
+            // 'size' should never reach zero.
+            ASSERT(size);
</ins><span class="cx">         }
</span><del>-    };
</del><ins>+        
+        // If we reach this point we've chopped down to one element, no need to check it matches
+        ASSERT(size == 1);
+        ASSERT(key == valueAtPosition(&amp;array[0]));
+        return &amp;array[0];
+    }
</ins><span class="cx"> 
</span><span class="cx">     struct StringJumpTable {
</span><span class="cx">         typedef HashMap&lt;RefPtr&lt;UString::Rep&gt;, OffsetLocation&gt; StringOffsetTable;
</span><span class="lines">@@ -227,12 +270,11 @@
</span><span class="cx">         void unlinkCallers();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-        void addCaller(StructureStubInfo* caller)
</del><ins>+        void addCaller(CallLinkInfo* caller)
</ins><span class="cx">         {
</span><del>-            CallLinkInfo* callLinkInfo = new CallLinkInfo(this, caller);
-            caller-&gt;linkInfoPtr = callLinkInfo;
-            callLinkInfo-&gt;position = linkedCallerList.size();
-            linkedCallerList.append(callLinkInfo);
</del><ins>+            caller-&gt;callee = this;
+            caller-&gt;position = linkedCallerList.size();
+            linkedCallerList.append(caller);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         void removeCaller(CallLinkInfo* caller)
</span><span class="lines">@@ -263,12 +305,7 @@
</span><span class="cx"> 
</span><span class="cx">         StructureStubInfo&amp; getStubInfo(void* returnAddress)
</span><span class="cx">         {
</span><del>-            // FIXME: would a binary chop be faster here?
-            for (unsigned i = 0; ; ++i) {
-                ASSERT(i &lt; structureIDInstructions.size());
-                if (structureIDInstructions[i].callReturnLocation == returnAddress)
-                    return structureIDInstructions[i];
-            }
</del><ins>+            return *(binaryChop&lt;StructureStubInfo, void*, getStructureStubInfoReturnLocation&gt;(propertyAccessInstructions.begin(), propertyAccessInstructions.size(), returnAddress));
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         ScopeNode* ownerNode;
</span><span class="lines">@@ -295,7 +332,9 @@
</span><span class="cx">         unsigned sourceOffset;
</span><span class="cx"> 
</span><span class="cx">         Vector&lt;Instruction&gt; instructions;
</span><del>-        Vector&lt;StructureStubInfo&gt; structureIDInstructions;
</del><ins>+        Vector&lt;unsigned&gt; globalResolveInstructions;
+        Vector&lt;StructureStubInfo&gt; propertyAccessInstructions;
+        Vector&lt;CallLinkInfo&gt; callLinkInfos;
</ins><span class="cx">         Vector&lt;CallLinkInfo*&gt; linkedCallerList;
</span><span class="cx"> 
</span><span class="cx">         // Constant pool
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMCodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/CodeGenerator.cpp (37830 => 37831)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/CodeGenerator.cpp        2008-10-23 22:12:18 UTC (rev 37830)
+++ trunk/JavaScriptCore/VM/CodeGenerator.cpp        2008-10-23 22:29:54 UTC (rev 37831)
</span><span class="lines">@@ -965,7 +965,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (globalObject) {
</span><del>-        m_codeBlock-&gt;structureIDInstructions.append(instructions().size());
</del><ins>+        m_codeBlock-&gt;globalResolveInstructions.append(instructions().size());
</ins><span class="cx">         emitOpcode(op_resolve_global);
</span><span class="cx">         instructions().append(dst-&gt;index());
</span><span class="cx">         instructions().append(globalObject);
</span><span class="lines">@@ -1045,7 +1045,7 @@
</span><span class="cx"> 
</span><span class="cx"> RegisterID* CodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier&amp; property)
</span><span class="cx"> {
</span><del>-    m_codeBlock-&gt;structureIDInstructions.append(instructions().size());
</del><ins>+    m_codeBlock-&gt;propertyAccessInstructions.append(instructions().size());
</ins><span class="cx"> 
</span><span class="cx">     emitOpcode(op_get_by_id);
</span><span class="cx">     instructions().append(dst-&gt;index());
</span><span class="lines">@@ -1060,7 +1060,7 @@
</span><span class="cx"> 
</span><span class="cx"> RegisterID* CodeGenerator::emitPutById(RegisterID* base, const Identifier&amp; property, RegisterID* value)
</span><span class="cx"> {
</span><del>-    m_codeBlock-&gt;structureIDInstructions.append(instructions().size());
</del><ins>+    m_codeBlock-&gt;propertyAccessInstructions.append(instructions().size());
</ins><span class="cx"> 
</span><span class="cx">     emitOpcode(op_put_by_id);
</span><span class="cx">     instructions().append(base-&gt;index());
</span><span class="lines">@@ -1219,7 +1219,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     emitExpressionInfo(divot, startOffset, endOffset);
</span><del>-    m_codeBlock-&gt;structureIDInstructions.append(instructions().size());
</del><ins>+    m_codeBlock-&gt;callLinkInfos.append(CallLinkInfo());
</ins><span class="cx">     emitOpcode(opcodeID);
</span><span class="cx">     instructions().append(dst-&gt;index());
</span><span class="cx">     instructions().append(func-&gt;index());
</span><span class="lines">@@ -1283,7 +1283,7 @@
</span><span class="cx">         callFrame.append(newTemporary());
</span><span class="cx"> 
</span><span class="cx">     emitExpressionInfo(divot, startOffset, endOffset);
</span><del>-    m_codeBlock-&gt;structureIDInstructions.append(instructions().size());
</del><ins>+    m_codeBlock-&gt;callLinkInfos.append(CallLinkInfo());
</ins><span class="cx">     emitOpcode(op_construct);
</span><span class="cx">     instructions().append(dst-&gt;index());
</span><span class="cx">     instructions().append(func-&gt;index());
</span></span></pre></div>
<a id="trunkJavaScriptCoreVMMachinecpp"></a>
<div class="modfile"><h4>Modified: trunk/JavaScriptCore/VM/Machine.cpp (37830 => 37831)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JavaScriptCore/VM/Machine.cpp        2008-10-23 22:12:18 UTC (rev 37830)
+++ trunk/JavaScriptCore/VM/Machine.cpp        2008-10-23 22:29:54 UTC (rev 37831)
</span><span class="lines">@@ -4741,16 +4741,13 @@
</span><span class="cx"> 
</span><span class="cx">     Machine* machine = ARG_globalData-&gt;machine;
</span><span class="cx">     CallFrame* callFrame = CallFrame::create(ARG_callFrame);
</span><del>-    CallFrame* callerCallFrame = callFrame-&gt;callerFrame();
-    CodeBlock* callerCodeBlock = callerCallFrame-&gt;codeBlock();
</del><span class="cx"> 
</span><span class="cx">     JSFunction* callee = asFunction(ARG_src1);
</span><span class="cx">     CodeBlock* codeBlock = &amp;callee-&gt;m_body-&gt;byteCode(callee-&gt;m_scopeChain.node());
</span><span class="cx">     if (!codeBlock-&gt;ctiCode)
</span><span class="cx">         CTI::compile(machine, callFrame, codeBlock);
</span><span class="cx"> 
</span><del>-    int argCount = ARG_int3;
-    CTI::linkCall(callerCodeBlock, callee, codeBlock, codeBlock-&gt;ctiCode, CTI_RETURN_ADDRESS, argCount);
</del><ins>+    CTI::linkCall(callee, codeBlock, codeBlock-&gt;ctiCode, ARG_linkInfo2, ARG_int3);
</ins><span class="cx"> 
</span><span class="cx">     return codeBlock-&gt;ctiCode;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>