GetById list caching should use something object-oriented rather than PolymorphicAcce...
[WebKit-https.git] / Source / JavaScriptCore / bytecode / CodeBlock.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "CodeBlock.h"
32
33 #include "BytecodeGenerator.h"
34 #include "BytecodeUseDef.h"
35 #include "CallLinkStatus.h"
36 #include "DFGCapabilities.h"
37 #include "DFGCommon.h"
38 #include "DFGDriver.h"
39 #include "DFGJITCode.h"
40 #include "DFGNode.h"
41 #include "DFGWorklist.h"
42 #include "Debugger.h"
43 #include "Interpreter.h"
44 #include "JIT.h"
45 #include "JITStubs.h"
46 #include "JSActivation.h"
47 #include "JSCJSValue.h"
48 #include "JSFunction.h"
49 #include "JSNameScope.h"
50 #include "LLIntEntrypoint.h"
51 #include "LowLevelInterpreter.h"
52 #include "JSCInlines.h"
53 #include "PolymorphicGetByIdList.h"
54 #include "PolymorphicPutByIdList.h"
55 #include "ReduceWhitespace.h"
56 #include "Repatch.h"
57 #include "RepatchBuffer.h"
58 #include "SlotVisitorInlines.h"
59 #include "UnlinkedInstructionStream.h"
60 #include <wtf/BagToHashMap.h>
61 #include <wtf/CommaPrinter.h>
62 #include <wtf/StringExtras.h>
63 #include <wtf/StringPrintStream.h>
64
65 #if ENABLE(DFG_JIT)
66 #include "DFGOperations.h"
67 #endif
68
69 #if ENABLE(FTL_JIT)
70 #include "FTLJITCode.h"
71 #endif
72
73 namespace JSC {
74
75 CString CodeBlock::inferredName() const
76 {
77     switch (codeType()) {
78     case GlobalCode:
79         return "<global>";
80     case EvalCode:
81         return "<eval>";
82     case FunctionCode:
83         return jsCast<FunctionExecutable*>(ownerExecutable())->inferredName().utf8();
84     default:
85         CRASH();
86         return CString("", 0);
87     }
88 }
89
90 bool CodeBlock::hasHash() const
91 {
92     return !!m_hash;
93 }
94
95 bool CodeBlock::isSafeToComputeHash() const
96 {
97     return !isCompilationThread();
98 }
99
100 CodeBlockHash CodeBlock::hash() const
101 {
102     if (!m_hash) {
103         RELEASE_ASSERT(isSafeToComputeHash());
104         m_hash = CodeBlockHash(ownerExecutable()->source(), specializationKind());
105     }
106     return m_hash;
107 }
108
109 CString CodeBlock::sourceCodeForTools() const
110 {
111     if (codeType() != FunctionCode)
112         return ownerExecutable()->source().toUTF8();
113     
114     SourceProvider* provider = source();
115     FunctionExecutable* executable = jsCast<FunctionExecutable*>(ownerExecutable());
116     UnlinkedFunctionExecutable* unlinked = executable->unlinkedExecutable();
117     unsigned unlinkedStartOffset = unlinked->startOffset();
118     unsigned linkedStartOffset = executable->source().startOffset();
119     int delta = linkedStartOffset - unlinkedStartOffset;
120     unsigned rangeStart = delta + unlinked->unlinkedFunctionNameStart();
121     unsigned rangeEnd = delta + unlinked->startOffset() + unlinked->sourceLength();
122     return toCString(
123         "function ",
124         provider->source().impl()->utf8ForRange(rangeStart, rangeEnd - rangeStart));
125 }
126
127 CString CodeBlock::sourceCodeOnOneLine() const
128 {
129     return reduceWhitespace(sourceCodeForTools());
130 }
131
132 void CodeBlock::dumpAssumingJITType(PrintStream& out, JITCode::JITType jitType) const
133 {
134     out.print(inferredName(), "#");
135     if (hasHash() || isSafeToComputeHash())
136         out.print(hash());
137     else
138         out.print("<no-hash>");
139     out.print(":[", RawPointer(this), "->");
140     if (!!m_alternative)
141         out.print(RawPointer(m_alternative.get()), "->");
142     out.print(RawPointer(ownerExecutable()), ", ", jitType, codeType());
143
144     if (codeType() == FunctionCode)
145         out.print(specializationKind());
146     out.print(", ", instructionCount());
147     if (this->jitType() == JITCode::BaselineJIT && m_shouldAlwaysBeInlined)
148         out.print(" (SABI)");
149     if (ownerExecutable()->neverInline())
150         out.print(" (NeverInline)");
151     if (ownerExecutable()->isStrictMode())
152         out.print(" (StrictMode)");
153     if (this->jitType() == JITCode::BaselineJIT && m_didFailFTLCompilation)
154         out.print(" (FTLFail)");
155     if (this->jitType() == JITCode::BaselineJIT && m_hasBeenCompiledWithFTL)
156         out.print(" (HadFTLReplacement)");
157     out.print("]");
158 }
159
160 void CodeBlock::dump(PrintStream& out) const
161 {
162     dumpAssumingJITType(out, jitType());
163 }
164
165 static CString constantName(int k, JSValue value)
166 {
167     return toCString(value, "(@k", k - FirstConstantRegisterIndex, ")");
168 }
169
170 static CString idName(int id0, const Identifier& ident)
171 {
172     return toCString(ident.impl(), "(@id", id0, ")");
173 }
174
175 CString CodeBlock::registerName(int r) const
176 {
177     if (r == missingThisObjectMarker())
178         return "<null>";
179
180     if (isConstantRegisterIndex(r))
181         return constantName(r, getConstant(r));
182
183     if (operandIsArgument(r)) {
184         if (!VirtualRegister(r).toArgument())
185             return "this";
186         return toCString("arg", VirtualRegister(r).toArgument());
187     }
188
189     return toCString("loc", VirtualRegister(r).toLocal());
190 }
191
192 static CString regexpToSourceString(RegExp* regExp)
193 {
194     char postfix[5] = { '/', 0, 0, 0, 0 };
195     int index = 1;
196     if (regExp->global())
197         postfix[index++] = 'g';
198     if (regExp->ignoreCase())
199         postfix[index++] = 'i';
200     if (regExp->multiline())
201         postfix[index] = 'm';
202
203     return toCString("/", regExp->pattern().impl(), postfix);
204 }
205
206 static CString regexpName(int re, RegExp* regexp)
207 {
208     return toCString(regexpToSourceString(regexp), "(@re", re, ")");
209 }
210
211 NEVER_INLINE static const char* debugHookName(int debugHookID)
212 {
213     switch (static_cast<DebugHookID>(debugHookID)) {
214         case DidEnterCallFrame:
215             return "didEnterCallFrame";
216         case WillLeaveCallFrame:
217             return "willLeaveCallFrame";
218         case WillExecuteStatement:
219             return "willExecuteStatement";
220         case WillExecuteProgram:
221             return "willExecuteProgram";
222         case DidExecuteProgram:
223             return "didExecuteProgram";
224         case DidReachBreakpoint:
225             return "didReachBreakpoint";
226     }
227
228     RELEASE_ASSERT_NOT_REACHED();
229     return "";
230 }
231
232 void CodeBlock::printUnaryOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op)
233 {
234     int r0 = (++it)->u.operand;
235     int r1 = (++it)->u.operand;
236
237     printLocationAndOp(out, exec, location, it, op);
238     out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
239 }
240
241 void CodeBlock::printBinaryOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op)
242 {
243     int r0 = (++it)->u.operand;
244     int r1 = (++it)->u.operand;
245     int r2 = (++it)->u.operand;
246     printLocationAndOp(out, exec, location, it, op);
247     out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data());
248 }
249
250 void CodeBlock::printConditionalJump(PrintStream& out, ExecState* exec, const Instruction*, const Instruction*& it, int location, const char* op)
251 {
252     int r0 = (++it)->u.operand;
253     int offset = (++it)->u.operand;
254     printLocationAndOp(out, exec, location, it, op);
255     out.printf("%s, %d(->%d)", registerName(r0).data(), offset, location + offset);
256 }
257
258 void CodeBlock::printGetByIdOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it)
259 {
260     const char* op;
261     switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
262     case op_get_by_id:
263         op = "get_by_id";
264         break;
265     case op_get_by_id_out_of_line:
266         op = "get_by_id_out_of_line";
267         break;
268     case op_get_array_length:
269         op = "array_length";
270         break;
271     default:
272         RELEASE_ASSERT_NOT_REACHED();
273         op = 0;
274     }
275     int r0 = (++it)->u.operand;
276     int r1 = (++it)->u.operand;
277     int id0 = (++it)->u.operand;
278     printLocationAndOp(out, exec, location, it, op);
279     out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data());
280     it += 4; // Increment up to the value profiler.
281 }
282
283 #if ENABLE(JIT) || ENABLE(LLINT) // unused in some configurations
284 static void dumpStructure(PrintStream& out, const char* name, ExecState* exec, Structure* structure, const Identifier& ident)
285 {
286     if (!structure)
287         return;
288     
289     out.printf("%s = %p", name, structure);
290     
291     PropertyOffset offset = structure->getConcurrently(exec->vm(), ident.impl());
292     if (offset != invalidOffset)
293         out.printf(" (offset = %d)", offset);
294 }
295 #endif
296
297 #if ENABLE(JIT) // unused when not ENABLE(JIT), leading to silly warnings
298 static void dumpChain(PrintStream& out, ExecState* exec, StructureChain* chain, const Identifier& ident)
299 {
300     out.printf("chain = %p: [", chain);
301     bool first = true;
302     for (WriteBarrier<Structure>* currentStructure = chain->head();
303          *currentStructure;
304          ++currentStructure) {
305         if (first)
306             first = false;
307         else
308             out.printf(", ");
309         dumpStructure(out, "struct", exec, currentStructure->get(), ident);
310     }
311     out.printf("]");
312 }
313 #endif
314
315 void CodeBlock::printGetByIdCacheStatus(PrintStream& out, ExecState* exec, int location, const StubInfoMap& map)
316 {
317     Instruction* instruction = instructions().begin() + location;
318
319     const Identifier& ident = identifier(instruction[3].u.operand);
320     
321     UNUSED_PARAM(ident); // tell the compiler to shut up in certain platform configurations.
322     
323 #if ENABLE(LLINT)
324     if (exec->interpreter()->getOpcodeID(instruction[0].u.opcode) == op_get_array_length)
325         out.printf(" llint(array_length)");
326     else if (Structure* structure = instruction[4].u.structure.get()) {
327         out.printf(" llint(");
328         dumpStructure(out, "struct", exec, structure, ident);
329         out.printf(")");
330     }
331 #endif
332
333 #if ENABLE(JIT)
334     if (StructureStubInfo* stubPtr = map.get(CodeOrigin(location))) {
335         StructureStubInfo& stubInfo = *stubPtr;
336         if (stubInfo.resetByGC)
337             out.print(" (Reset By GC)");
338         
339         if (stubInfo.seen) {
340             out.printf(" jit(");
341             
342             Structure* baseStructure = 0;
343             Structure* prototypeStructure = 0;
344             StructureChain* chain = 0;
345             PolymorphicGetByIdList* list = 0;
346             
347             switch (stubInfo.accessType) {
348             case access_get_by_id_self:
349                 out.printf("self");
350                 baseStructure = stubInfo.u.getByIdSelf.baseObjectStructure.get();
351                 break;
352             case access_get_by_id_chain:
353                 out.printf("chain");
354                 baseStructure = stubInfo.u.getByIdChain.baseObjectStructure.get();
355                 chain = stubInfo.u.getByIdChain.chain.get();
356                 break;
357             case access_get_by_id_list:
358                 out.printf("list");
359                 list = stubInfo.u.getByIdList.list;
360                 break;
361             case access_unset:
362                 out.printf("unset");
363                 break;
364             default:
365                 RELEASE_ASSERT_NOT_REACHED();
366                 break;
367             }
368             
369             if (baseStructure) {
370                 out.printf(", ");
371                 dumpStructure(out, "struct", exec, baseStructure, ident);
372             }
373             
374             if (prototypeStructure) {
375                 out.printf(", ");
376                 dumpStructure(out, "prototypeStruct", exec, baseStructure, ident);
377             }
378             
379             if (chain) {
380                 out.printf(", ");
381                 dumpChain(out, exec, chain, ident);
382             }
383             
384             if (list) {
385                 out.printf(", list = %p: [", list);
386                 for (unsigned i = 0; i < list->size(); ++i) {
387                     if (i)
388                         out.printf(", ");
389                     out.printf("(");
390                     dumpStructure(out, "base", exec, list->at(i).structure(), ident);
391                     if (list->at(i).chain()) {
392                         out.printf(", ");
393                         dumpChain(out, exec, list->at(i).chain(), ident);
394                     }
395                     out.printf(")");
396                 }
397                 out.printf("]");
398             }
399             out.printf(")");
400         }
401     }
402 #else
403     UNUSED_PARAM(map);
404 #endif
405 }
406
407 void CodeBlock::printCallOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op, CacheDumpMode cacheDumpMode, bool& hasPrintedProfiling)
408 {
409     int dst = (++it)->u.operand;
410     int func = (++it)->u.operand;
411     int argCount = (++it)->u.operand;
412     int registerOffset = (++it)->u.operand;
413     printLocationAndOp(out, exec, location, it, op);
414     out.printf("%s, %s, %d, %d", registerName(dst).data(), registerName(func).data(), argCount, registerOffset);
415     if (cacheDumpMode == DumpCaches) {
416 #if ENABLE(LLINT)
417         LLIntCallLinkInfo* callLinkInfo = it[1].u.callLinkInfo;
418         if (callLinkInfo->lastSeenCallee) {
419             out.printf(
420                 " llint(%p, exec %p)",
421                 callLinkInfo->lastSeenCallee.get(),
422                 callLinkInfo->lastSeenCallee->executable());
423         }
424 #endif
425 #if ENABLE(JIT)
426         if (numberOfCallLinkInfos()) {
427             JSFunction* target = getCallLinkInfo(location).lastSeenCallee.get();
428             if (target)
429                 out.printf(" jit(%p, exec %p)", target, target->executable());
430         }
431         out.print(" status(", CallLinkStatus::computeFor(this, location), ")");
432 #endif
433     }
434     ++it;
435     ++it;
436     dumpArrayProfiling(out, it, hasPrintedProfiling);
437     dumpValueProfiling(out, it, hasPrintedProfiling);
438 }
439
440 void CodeBlock::printPutByIdOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op)
441 {
442     int r0 = (++it)->u.operand;
443     int id0 = (++it)->u.operand;
444     int r1 = (++it)->u.operand;
445     printLocationAndOp(out, exec, location, it, op);
446     out.printf("%s, %s, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data());
447     it += 5;
448 }
449
450 void CodeBlock::dumpBytecode(PrintStream& out)
451 {
452     // We only use the ExecState* for things that don't actually lead to JS execution,
453     // like converting a JSString to a String. Hence the globalExec is appropriate.
454     ExecState* exec = m_globalObject->globalExec();
455     
456     size_t instructionCount = 0;
457
458     for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)])
459         ++instructionCount;
460
461     out.print(*this);
462     out.printf(
463         ": %lu m_instructions; %lu bytes; %d parameter(s); %d callee register(s); %d variable(s)",
464         static_cast<unsigned long>(instructions().size()),
465         static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
466         m_numParameters, m_numCalleeRegisters, m_numVars);
467     if (symbolTable() && symbolTable()->captureCount()) {
468         out.printf(
469             "; %d captured var(s) (from r%d to r%d, inclusive)",
470             symbolTable()->captureCount(), symbolTable()->captureStart(), symbolTable()->captureEnd() + 1);
471     }
472     if (usesArguments()) {
473         out.printf(
474             "; uses arguments, in r%d, r%d",
475             argumentsRegister().offset(),
476             unmodifiedArgumentsRegister(argumentsRegister()).offset());
477     }
478     if (needsActivation() && codeType() == FunctionCode)
479         out.printf("; activation in r%d", activationRegister().offset());
480     out.printf("\n");
481     
482     StubInfoMap stubInfos;
483     getStubInfoMap(stubInfos);
484     
485     const Instruction* begin = instructions().begin();
486     const Instruction* end = instructions().end();
487     for (const Instruction* it = begin; it != end; ++it)
488         dumpBytecode(out, exec, begin, it, stubInfos);
489     
490     if (numberOfIdentifiers()) {
491         out.printf("\nIdentifiers:\n");
492         size_t i = 0;
493         do {
494             out.printf("  id%u = %s\n", static_cast<unsigned>(i), identifier(i).string().utf8().data());
495             ++i;
496         } while (i != numberOfIdentifiers());
497     }
498
499     if (!m_constantRegisters.isEmpty()) {
500         out.printf("\nConstants:\n");
501         size_t i = 0;
502         do {
503             out.printf("   k%u = %s\n", static_cast<unsigned>(i), toCString(m_constantRegisters[i].get()).data());
504             ++i;
505         } while (i < m_constantRegisters.size());
506     }
507
508     if (size_t count = m_unlinkedCode->numberOfRegExps()) {
509         out.printf("\nm_regexps:\n");
510         size_t i = 0;
511         do {
512             out.printf("  re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_unlinkedCode->regexp(i)).data());
513             ++i;
514         } while (i < count);
515     }
516
517     if (m_rareData && !m_rareData->m_exceptionHandlers.isEmpty()) {
518         out.printf("\nException Handlers:\n");
519         unsigned i = 0;
520         do {
521             out.printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] depth: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target, m_rareData->m_exceptionHandlers[i].scopeDepth);
522             ++i;
523         } while (i < m_rareData->m_exceptionHandlers.size());
524     }
525     
526     if (m_rareData && !m_rareData->m_switchJumpTables.isEmpty()) {
527         out.printf("Switch Jump Tables:\n");
528         unsigned i = 0;
529         do {
530             out.printf("  %1d = {\n", i);
531             int entry = 0;
532             Vector<int32_t>::const_iterator end = m_rareData->m_switchJumpTables[i].branchOffsets.end();
533             for (Vector<int32_t>::const_iterator iter = m_rareData->m_switchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
534                 if (!*iter)
535                     continue;
536                 out.printf("\t\t%4d => %04d\n", entry + m_rareData->m_switchJumpTables[i].min, *iter);
537             }
538             out.printf("      }\n");
539             ++i;
540         } while (i < m_rareData->m_switchJumpTables.size());
541     }
542     
543     if (m_rareData && !m_rareData->m_stringSwitchJumpTables.isEmpty()) {
544         out.printf("\nString Switch Jump Tables:\n");
545         unsigned i = 0;
546         do {
547             out.printf("  %1d = {\n", i);
548             StringJumpTable::StringOffsetTable::const_iterator end = m_rareData->m_stringSwitchJumpTables[i].offsetTable.end();
549             for (StringJumpTable::StringOffsetTable::const_iterator iter = m_rareData->m_stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter)
550                 out.printf("\t\t\"%s\" => %04d\n", String(iter->key).utf8().data(), iter->value.branchOffset);
551             out.printf("      }\n");
552             ++i;
553         } while (i < m_rareData->m_stringSwitchJumpTables.size());
554     }
555
556     out.printf("\n");
557 }
558
559 void CodeBlock::beginDumpProfiling(PrintStream& out, bool& hasPrintedProfiling)
560 {
561     if (hasPrintedProfiling) {
562         out.print("; ");
563         return;
564     }
565     
566     out.print("    ");
567     hasPrintedProfiling = true;
568 }
569
570 void CodeBlock::dumpValueProfiling(PrintStream& out, const Instruction*& it, bool& hasPrintedProfiling)
571 {
572     ConcurrentJITLocker locker(m_lock);
573     
574     ++it;
575     CString description = it->u.profile->briefDescription(locker);
576     if (!description.length())
577         return;
578     beginDumpProfiling(out, hasPrintedProfiling);
579     out.print(description);
580 }
581
582 void CodeBlock::dumpArrayProfiling(PrintStream& out, const Instruction*& it, bool& hasPrintedProfiling)
583 {
584     ConcurrentJITLocker locker(m_lock);
585     
586     ++it;
587     if (!it->u.arrayProfile)
588         return;
589     CString description = it->u.arrayProfile->briefDescription(locker, this);
590     if (!description.length())
591         return;
592     beginDumpProfiling(out, hasPrintedProfiling);
593     out.print(description);
594 }
595
596 void CodeBlock::dumpRareCaseProfile(PrintStream& out, const char* name, RareCaseProfile* profile, bool& hasPrintedProfiling)
597 {
598     if (!profile || !profile->m_counter)
599         return;
600
601     beginDumpProfiling(out, hasPrintedProfiling);
602     out.print(name, profile->m_counter);
603 }
604
605 void CodeBlock::printLocationAndOp(PrintStream& out, ExecState*, int location, const Instruction*&, const char* op)
606 {
607     out.printf("[%4d] %-17s ", location, op);
608 }
609
610 void CodeBlock::printLocationOpAndRegisterOperand(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op, int operand)
611 {
612     printLocationAndOp(out, exec, location, it, op);
613     out.printf("%s", registerName(operand).data());
614 }
615
616 void CodeBlock::dumpBytecode(PrintStream& out, ExecState* exec, const Instruction* begin, const Instruction*& it, const StubInfoMap& map)
617 {
618     int location = it - begin;
619     bool hasPrintedProfiling = false;
620     switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
621         case op_enter: {
622             printLocationAndOp(out, exec, location, it, "enter");
623             break;
624         }
625         case op_touch_entry: {
626             printLocationAndOp(out, exec, location, it, "touch_entry");
627             break;
628         }
629         case op_create_activation: {
630             int r0 = (++it)->u.operand;
631             printLocationOpAndRegisterOperand(out, exec, location, it, "create_activation", r0);
632             break;
633         }
634         case op_create_arguments: {
635             int r0 = (++it)->u.operand;
636             printLocationOpAndRegisterOperand(out, exec, location, it, "create_arguments", r0);
637             break;
638         }
639         case op_init_lazy_reg: {
640             int r0 = (++it)->u.operand;
641             printLocationOpAndRegisterOperand(out, exec, location, it, "init_lazy_reg", r0);
642             break;
643         }
644         case op_get_callee: {
645             int r0 = (++it)->u.operand;
646             printLocationOpAndRegisterOperand(out, exec, location, it, "get_callee", r0);
647             ++it;
648             break;
649         }
650         case op_create_this: {
651             int r0 = (++it)->u.operand;
652             int r1 = (++it)->u.operand;
653             unsigned inferredInlineCapacity = (++it)->u.operand;
654             printLocationAndOp(out, exec, location, it, "create_this");
655             out.printf("%s, %s, %u", registerName(r0).data(), registerName(r1).data(), inferredInlineCapacity);
656             break;
657         }
658         case op_to_this: {
659             int r0 = (++it)->u.operand;
660             printLocationOpAndRegisterOperand(out, exec, location, it, "to_this", r0);
661             Structure* structure = (++it)->u.structure.get();
662             if (structure)
663                 out.print(" cache(struct = ", RawPointer(structure), ")");
664             break;
665         }
666         case op_new_object: {
667             int r0 = (++it)->u.operand;
668             unsigned inferredInlineCapacity = (++it)->u.operand;
669             printLocationAndOp(out, exec, location, it, "new_object");
670             out.printf("%s, %u", registerName(r0).data(), inferredInlineCapacity);
671             ++it; // Skip object allocation profile.
672             break;
673         }
674         case op_new_array: {
675             int dst = (++it)->u.operand;
676             int argv = (++it)->u.operand;
677             int argc = (++it)->u.operand;
678             printLocationAndOp(out, exec, location, it, "new_array");
679             out.printf("%s, %s, %d", registerName(dst).data(), registerName(argv).data(), argc);
680             ++it; // Skip array allocation profile.
681             break;
682         }
683         case op_new_array_with_size: {
684             int dst = (++it)->u.operand;
685             int length = (++it)->u.operand;
686             printLocationAndOp(out, exec, location, it, "new_array_with_size");
687             out.printf("%s, %s", registerName(dst).data(), registerName(length).data());
688             ++it; // Skip array allocation profile.
689             break;
690         }
691         case op_new_array_buffer: {
692             int dst = (++it)->u.operand;
693             int argv = (++it)->u.operand;
694             int argc = (++it)->u.operand;
695             printLocationAndOp(out, exec, location, it, "new_array_buffer");
696             out.printf("%s, %d, %d", registerName(dst).data(), argv, argc);
697             ++it; // Skip array allocation profile.
698             break;
699         }
700         case op_new_regexp: {
701             int r0 = (++it)->u.operand;
702             int re0 = (++it)->u.operand;
703             printLocationAndOp(out, exec, location, it, "new_regexp");
704             out.printf("%s, ", registerName(r0).data());
705             if (r0 >=0 && r0 < (int)m_unlinkedCode->numberOfRegExps())
706                 out.printf("%s", regexpName(re0, regexp(re0)).data());
707             else
708                 out.printf("bad_regexp(%d)", re0);
709             break;
710         }
711         case op_mov: {
712             int r0 = (++it)->u.operand;
713             int r1 = (++it)->u.operand;
714             printLocationAndOp(out, exec, location, it, "mov");
715             out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
716             break;
717         }
718         case op_captured_mov: {
719             int r0 = (++it)->u.operand;
720             int r1 = (++it)->u.operand;
721             printLocationAndOp(out, exec, location, it, "captured_mov");
722             out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
723             ++it;
724             break;
725         }
726         case op_not: {
727             printUnaryOp(out, exec, location, it, "not");
728             break;
729         }
730         case op_eq: {
731             printBinaryOp(out, exec, location, it, "eq");
732             break;
733         }
734         case op_eq_null: {
735             printUnaryOp(out, exec, location, it, "eq_null");
736             break;
737         }
738         case op_neq: {
739             printBinaryOp(out, exec, location, it, "neq");
740             break;
741         }
742         case op_neq_null: {
743             printUnaryOp(out, exec, location, it, "neq_null");
744             break;
745         }
746         case op_stricteq: {
747             printBinaryOp(out, exec, location, it, "stricteq");
748             break;
749         }
750         case op_nstricteq: {
751             printBinaryOp(out, exec, location, it, "nstricteq");
752             break;
753         }
754         case op_less: {
755             printBinaryOp(out, exec, location, it, "less");
756             break;
757         }
758         case op_lesseq: {
759             printBinaryOp(out, exec, location, it, "lesseq");
760             break;
761         }
762         case op_greater: {
763             printBinaryOp(out, exec, location, it, "greater");
764             break;
765         }
766         case op_greatereq: {
767             printBinaryOp(out, exec, location, it, "greatereq");
768             break;
769         }
770         case op_inc: {
771             int r0 = (++it)->u.operand;
772             printLocationOpAndRegisterOperand(out, exec, location, it, "inc", r0);
773             break;
774         }
775         case op_dec: {
776             int r0 = (++it)->u.operand;
777             printLocationOpAndRegisterOperand(out, exec, location, it, "dec", r0);
778             break;
779         }
780         case op_to_number: {
781             printUnaryOp(out, exec, location, it, "to_number");
782             break;
783         }
784         case op_negate: {
785             printUnaryOp(out, exec, location, it, "negate");
786             break;
787         }
788         case op_add: {
789             printBinaryOp(out, exec, location, it, "add");
790             ++it;
791             break;
792         }
793         case op_mul: {
794             printBinaryOp(out, exec, location, it, "mul");
795             ++it;
796             break;
797         }
798         case op_div: {
799             printBinaryOp(out, exec, location, it, "div");
800             ++it;
801             break;
802         }
803         case op_mod: {
804             printBinaryOp(out, exec, location, it, "mod");
805             break;
806         }
807         case op_sub: {
808             printBinaryOp(out, exec, location, it, "sub");
809             ++it;
810             break;
811         }
812         case op_lshift: {
813             printBinaryOp(out, exec, location, it, "lshift");
814             break;            
815         }
816         case op_rshift: {
817             printBinaryOp(out, exec, location, it, "rshift");
818             break;
819         }
820         case op_urshift: {
821             printBinaryOp(out, exec, location, it, "urshift");
822             break;
823         }
824         case op_bitand: {
825             printBinaryOp(out, exec, location, it, "bitand");
826             ++it;
827             break;
828         }
829         case op_bitxor: {
830             printBinaryOp(out, exec, location, it, "bitxor");
831             ++it;
832             break;
833         }
834         case op_bitor: {
835             printBinaryOp(out, exec, location, it, "bitor");
836             ++it;
837             break;
838         }
839         case op_check_has_instance: {
840             int r0 = (++it)->u.operand;
841             int r1 = (++it)->u.operand;
842             int r2 = (++it)->u.operand;
843             int offset = (++it)->u.operand;
844             printLocationAndOp(out, exec, location, it, "check_has_instance");
845             out.printf("%s, %s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), offset, location + offset);
846             break;
847         }
848         case op_instanceof: {
849             int r0 = (++it)->u.operand;
850             int r1 = (++it)->u.operand;
851             int r2 = (++it)->u.operand;
852             printLocationAndOp(out, exec, location, it, "instanceof");
853             out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data());
854             break;
855         }
856         case op_unsigned: {
857             printUnaryOp(out, exec, location, it, "unsigned");
858             break;
859         }
860         case op_typeof: {
861             printUnaryOp(out, exec, location, it, "typeof");
862             break;
863         }
864         case op_is_undefined: {
865             printUnaryOp(out, exec, location, it, "is_undefined");
866             break;
867         }
868         case op_is_boolean: {
869             printUnaryOp(out, exec, location, it, "is_boolean");
870             break;
871         }
872         case op_is_number: {
873             printUnaryOp(out, exec, location, it, "is_number");
874             break;
875         }
876         case op_is_string: {
877             printUnaryOp(out, exec, location, it, "is_string");
878             break;
879         }
880         case op_is_object: {
881             printUnaryOp(out, exec, location, it, "is_object");
882             break;
883         }
884         case op_is_function: {
885             printUnaryOp(out, exec, location, it, "is_function");
886             break;
887         }
888         case op_in: {
889             printBinaryOp(out, exec, location, it, "in");
890             break;
891         }
892         case op_init_global_const_nop: {
893             printLocationAndOp(out, exec, location, it, "init_global_const_nop");
894             it++;
895             it++;
896             it++;
897             it++;
898             break;
899         }
900         case op_init_global_const: {
901             WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
902             int r0 = (++it)->u.operand;
903             printLocationAndOp(out, exec, location, it, "init_global_const");
904             out.printf("g%d(%p), %s", m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(r0).data());
905             it++;
906             it++;
907             break;
908         }
909         case op_get_by_id:
910         case op_get_by_id_out_of_line:
911         case op_get_array_length: {
912             printGetByIdOp(out, exec, location, it);
913             printGetByIdCacheStatus(out, exec, location, map);
914             dumpValueProfiling(out, it, hasPrintedProfiling);
915             break;
916         }
917         case op_get_arguments_length: {
918             printUnaryOp(out, exec, location, it, "get_arguments_length");
919             it++;
920             break;
921         }
922         case op_put_by_id: {
923             printPutByIdOp(out, exec, location, it, "put_by_id");
924             break;
925         }
926         case op_put_by_id_out_of_line: {
927             printPutByIdOp(out, exec, location, it, "put_by_id_out_of_line");
928             break;
929         }
930         case op_put_by_id_transition_direct: {
931             printPutByIdOp(out, exec, location, it, "put_by_id_transition_direct");
932             break;
933         }
934         case op_put_by_id_transition_direct_out_of_line: {
935             printPutByIdOp(out, exec, location, it, "put_by_id_transition_direct_out_of_line");
936             break;
937         }
938         case op_put_by_id_transition_normal: {
939             printPutByIdOp(out, exec, location, it, "put_by_id_transition_normal");
940             break;
941         }
942         case op_put_by_id_transition_normal_out_of_line: {
943             printPutByIdOp(out, exec, location, it, "put_by_id_transition_normal_out_of_line");
944             break;
945         }
946         case op_put_getter_setter: {
947             int r0 = (++it)->u.operand;
948             int id0 = (++it)->u.operand;
949             int r1 = (++it)->u.operand;
950             int r2 = (++it)->u.operand;
951             printLocationAndOp(out, exec, location, it, "put_getter_setter");
952             out.printf("%s, %s, %s, %s", registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(), registerName(r2).data());
953             break;
954         }
955         case op_del_by_id: {
956             int r0 = (++it)->u.operand;
957             int r1 = (++it)->u.operand;
958             int id0 = (++it)->u.operand;
959             printLocationAndOp(out, exec, location, it, "del_by_id");
960             out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data());
961             break;
962         }
963         case op_get_by_val: {
964             int r0 = (++it)->u.operand;
965             int r1 = (++it)->u.operand;
966             int r2 = (++it)->u.operand;
967             printLocationAndOp(out, exec, location, it, "get_by_val");
968             out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data());
969             dumpArrayProfiling(out, it, hasPrintedProfiling);
970             dumpValueProfiling(out, it, hasPrintedProfiling);
971             break;
972         }
973         case op_get_argument_by_val: {
974             int r0 = (++it)->u.operand;
975             int r1 = (++it)->u.operand;
976             int r2 = (++it)->u.operand;
977             printLocationAndOp(out, exec, location, it, "get_argument_by_val");
978             out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data());
979             ++it;
980             dumpValueProfiling(out, it, hasPrintedProfiling);
981             break;
982         }
983         case op_get_by_pname: {
984             int r0 = (++it)->u.operand;
985             int r1 = (++it)->u.operand;
986             int r2 = (++it)->u.operand;
987             int r3 = (++it)->u.operand;
988             int r4 = (++it)->u.operand;
989             int r5 = (++it)->u.operand;
990             printLocationAndOp(out, exec, location, it, "get_by_pname");
991             out.printf("%s, %s, %s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data(), registerName(r4).data(), registerName(r5).data());
992             break;
993         }
994         case op_put_by_val: {
995             int r0 = (++it)->u.operand;
996             int r1 = (++it)->u.operand;
997             int r2 = (++it)->u.operand;
998             printLocationAndOp(out, exec, location, it, "put_by_val");
999             out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data());
1000             dumpArrayProfiling(out, it, hasPrintedProfiling);
1001             break;
1002         }
1003         case op_put_by_val_direct: {
1004             int r0 = (++it)->u.operand;
1005             int r1 = (++it)->u.operand;
1006             int r2 = (++it)->u.operand;
1007             printLocationAndOp(out, exec, location, it, "put_by_val_direct");
1008             out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data());
1009             dumpArrayProfiling(out, it, hasPrintedProfiling);
1010             break;
1011         }
1012         case op_del_by_val: {
1013             int r0 = (++it)->u.operand;
1014             int r1 = (++it)->u.operand;
1015             int r2 = (++it)->u.operand;
1016             printLocationAndOp(out, exec, location, it, "del_by_val");
1017             out.printf("%s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data());
1018             break;
1019         }
1020         case op_put_by_index: {
1021             int r0 = (++it)->u.operand;
1022             unsigned n0 = (++it)->u.operand;
1023             int r1 = (++it)->u.operand;
1024             printLocationAndOp(out, exec, location, it, "put_by_index");
1025             out.printf("%s, %u, %s", registerName(r0).data(), n0, registerName(r1).data());
1026             break;
1027         }
1028         case op_jmp: {
1029             int offset = (++it)->u.operand;
1030             printLocationAndOp(out, exec, location, it, "jmp");
1031             out.printf("%d(->%d)", offset, location + offset);
1032             break;
1033         }
1034         case op_jtrue: {
1035             printConditionalJump(out, exec, begin, it, location, "jtrue");
1036             break;
1037         }
1038         case op_jfalse: {
1039             printConditionalJump(out, exec, begin, it, location, "jfalse");
1040             break;
1041         }
1042         case op_jeq_null: {
1043             printConditionalJump(out, exec, begin, it, location, "jeq_null");
1044             break;
1045         }
1046         case op_jneq_null: {
1047             printConditionalJump(out, exec, begin, it, location, "jneq_null");
1048             break;
1049         }
1050         case op_jneq_ptr: {
1051             int r0 = (++it)->u.operand;
1052             Special::Pointer pointer = (++it)->u.specialPointer;
1053             int offset = (++it)->u.operand;
1054             printLocationAndOp(out, exec, location, it, "jneq_ptr");
1055             out.printf("%s, %d (%p), %d(->%d)", registerName(r0).data(), pointer, m_globalObject->actualPointerFor(pointer), offset, location + offset);
1056             break;
1057         }
1058         case op_jless: {
1059             int r0 = (++it)->u.operand;
1060             int r1 = (++it)->u.operand;
1061             int offset = (++it)->u.operand;
1062             printLocationAndOp(out, exec, location, it, "jless");
1063             out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset);
1064             break;
1065         }
1066         case op_jlesseq: {
1067             int r0 = (++it)->u.operand;
1068             int r1 = (++it)->u.operand;
1069             int offset = (++it)->u.operand;
1070             printLocationAndOp(out, exec, location, it, "jlesseq");
1071             out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset);
1072             break;
1073         }
1074         case op_jgreater: {
1075             int r0 = (++it)->u.operand;
1076             int r1 = (++it)->u.operand;
1077             int offset = (++it)->u.operand;
1078             printLocationAndOp(out, exec, location, it, "jgreater");
1079             out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset);
1080             break;
1081         }
1082         case op_jgreatereq: {
1083             int r0 = (++it)->u.operand;
1084             int r1 = (++it)->u.operand;
1085             int offset = (++it)->u.operand;
1086             printLocationAndOp(out, exec, location, it, "jgreatereq");
1087             out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset);
1088             break;
1089         }
1090         case op_jnless: {
1091             int r0 = (++it)->u.operand;
1092             int r1 = (++it)->u.operand;
1093             int offset = (++it)->u.operand;
1094             printLocationAndOp(out, exec, location, it, "jnless");
1095             out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset);
1096             break;
1097         }
1098         case op_jnlesseq: {
1099             int r0 = (++it)->u.operand;
1100             int r1 = (++it)->u.operand;
1101             int offset = (++it)->u.operand;
1102             printLocationAndOp(out, exec, location, it, "jnlesseq");
1103             out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset);
1104             break;
1105         }
1106         case op_jngreater: {
1107             int r0 = (++it)->u.operand;
1108             int r1 = (++it)->u.operand;
1109             int offset = (++it)->u.operand;
1110             printLocationAndOp(out, exec, location, it, "jngreater");
1111             out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset);
1112             break;
1113         }
1114         case op_jngreatereq: {
1115             int r0 = (++it)->u.operand;
1116             int r1 = (++it)->u.operand;
1117             int offset = (++it)->u.operand;
1118             printLocationAndOp(out, exec, location, it, "jngreatereq");
1119             out.printf("%s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), offset, location + offset);
1120             break;
1121         }
1122         case op_loop_hint: {
1123             printLocationAndOp(out, exec, location, it, "loop_hint");
1124             break;
1125         }
1126         case op_switch_imm: {
1127             int tableIndex = (++it)->u.operand;
1128             int defaultTarget = (++it)->u.operand;
1129             int scrutineeRegister = (++it)->u.operand;
1130             printLocationAndOp(out, exec, location, it, "switch_imm");
1131             out.printf("%d, %d(->%d), %s", tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).data());
1132             break;
1133         }
1134         case op_switch_char: {
1135             int tableIndex = (++it)->u.operand;
1136             int defaultTarget = (++it)->u.operand;
1137             int scrutineeRegister = (++it)->u.operand;
1138             printLocationAndOp(out, exec, location, it, "switch_char");
1139             out.printf("%d, %d(->%d), %s", tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).data());
1140             break;
1141         }
1142         case op_switch_string: {
1143             int tableIndex = (++it)->u.operand;
1144             int defaultTarget = (++it)->u.operand;
1145             int scrutineeRegister = (++it)->u.operand;
1146             printLocationAndOp(out, exec, location, it, "switch_string");
1147             out.printf("%d, %d(->%d), %s", tableIndex, defaultTarget, location + defaultTarget, registerName(scrutineeRegister).data());
1148             break;
1149         }
1150         case op_new_func: {
1151             int r0 = (++it)->u.operand;
1152             int f0 = (++it)->u.operand;
1153             int shouldCheck = (++it)->u.operand;
1154             printLocationAndOp(out, exec, location, it, "new_func");
1155             out.printf("%s, f%d, %s", registerName(r0).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>");
1156             break;
1157         }
1158         case op_new_captured_func: {
1159             int r0 = (++it)->u.operand;
1160             int f0 = (++it)->u.operand;
1161             printLocationAndOp(out, exec, location, it, "new_captured_func");
1162             out.printf("%s, f%d", registerName(r0).data(), f0);
1163             ++it;
1164             break;
1165         }
1166         case op_new_func_exp: {
1167             int r0 = (++it)->u.operand;
1168             int f0 = (++it)->u.operand;
1169             printLocationAndOp(out, exec, location, it, "new_func_exp");
1170             out.printf("%s, f%d", registerName(r0).data(), f0);
1171             break;
1172         }
1173         case op_call: {
1174             printCallOp(out, exec, location, it, "call", DumpCaches, hasPrintedProfiling);
1175             break;
1176         }
1177         case op_call_eval: {
1178             printCallOp(out, exec, location, it, "call_eval", DontDumpCaches, hasPrintedProfiling);
1179             break;
1180         }
1181         case op_call_varargs: {
1182             int result = (++it)->u.operand;
1183             int callee = (++it)->u.operand;
1184             int thisValue = (++it)->u.operand;
1185             int arguments = (++it)->u.operand;
1186             int firstFreeRegister = (++it)->u.operand;
1187             int varArgOffset = (++it)->u.operand;
1188             ++it;
1189             printLocationAndOp(out, exec, location, it, "call_varargs");
1190             out.printf("%s, %s, %s, %s, %d, %d", registerName(result).data(), registerName(callee).data(), registerName(thisValue).data(), registerName(arguments).data(), firstFreeRegister, varArgOffset);
1191             dumpValueProfiling(out, it, hasPrintedProfiling);
1192             break;
1193         }
1194         case op_tear_off_activation: {
1195             int r0 = (++it)->u.operand;
1196             printLocationOpAndRegisterOperand(out, exec, location, it, "tear_off_activation", r0);
1197             break;
1198         }
1199         case op_tear_off_arguments: {
1200             int r0 = (++it)->u.operand;
1201             int r1 = (++it)->u.operand;
1202             printLocationAndOp(out, exec, location, it, "tear_off_arguments");
1203             out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
1204             break;
1205         }
1206         case op_ret: {
1207             int r0 = (++it)->u.operand;
1208             printLocationOpAndRegisterOperand(out, exec, location, it, "ret", r0);
1209             break;
1210         }
1211         case op_ret_object_or_this: {
1212             int r0 = (++it)->u.operand;
1213             int r1 = (++it)->u.operand;
1214             printLocationAndOp(out, exec, location, it, "constructor_ret");
1215             out.printf("%s %s", registerName(r0).data(), registerName(r1).data());
1216             break;
1217         }
1218         case op_construct: {
1219             printCallOp(out, exec, location, it, "construct", DumpCaches, hasPrintedProfiling);
1220             break;
1221         }
1222         case op_strcat: {
1223             int r0 = (++it)->u.operand;
1224             int r1 = (++it)->u.operand;
1225             int count = (++it)->u.operand;
1226             printLocationAndOp(out, exec, location, it, "strcat");
1227             out.printf("%s, %s, %d", registerName(r0).data(), registerName(r1).data(), count);
1228             break;
1229         }
1230         case op_to_primitive: {
1231             int r0 = (++it)->u.operand;
1232             int r1 = (++it)->u.operand;
1233             printLocationAndOp(out, exec, location, it, "to_primitive");
1234             out.printf("%s, %s", registerName(r0).data(), registerName(r1).data());
1235             break;
1236         }
1237         case op_get_pnames: {
1238             int r0 = it[1].u.operand;
1239             int r1 = it[2].u.operand;
1240             int r2 = it[3].u.operand;
1241             int r3 = it[4].u.operand;
1242             int offset = it[5].u.operand;
1243             printLocationAndOp(out, exec, location, it, "get_pnames");
1244             out.printf("%s, %s, %s, %s, %d(->%d)", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data(), offset, location + offset);
1245             it += OPCODE_LENGTH(op_get_pnames) - 1;
1246             break;
1247         }
1248         case op_next_pname: {
1249             int dest = it[1].u.operand;
1250             int base = it[2].u.operand;
1251             int i = it[3].u.operand;
1252             int size = it[4].u.operand;
1253             int iter = it[5].u.operand;
1254             int offset = it[6].u.operand;
1255             printLocationAndOp(out, exec, location, it, "next_pname");
1256             out.printf("%s, %s, %s, %s, %s, %d(->%d)", registerName(dest).data(), registerName(base).data(), registerName(i).data(), registerName(size).data(), registerName(iter).data(), offset, location + offset);
1257             it += OPCODE_LENGTH(op_next_pname) - 1;
1258             break;
1259         }
1260         case op_push_with_scope: {
1261             int r0 = (++it)->u.operand;
1262             printLocationOpAndRegisterOperand(out, exec, location, it, "push_with_scope", r0);
1263             break;
1264         }
1265         case op_pop_scope: {
1266             printLocationAndOp(out, exec, location, it, "pop_scope");
1267             break;
1268         }
1269         case op_push_name_scope: {
1270             int id0 = (++it)->u.operand;
1271             int r1 = (++it)->u.operand;
1272             unsigned attributes = (++it)->u.operand;
1273             printLocationAndOp(out, exec, location, it, "push_name_scope");
1274             out.printf("%s, %s, %u", idName(id0, identifier(id0)).data(), registerName(r1).data(), attributes);
1275             break;
1276         }
1277         case op_catch: {
1278             int r0 = (++it)->u.operand;
1279             printLocationOpAndRegisterOperand(out, exec, location, it, "catch", r0);
1280             break;
1281         }
1282         case op_throw: {
1283             int r0 = (++it)->u.operand;
1284             printLocationOpAndRegisterOperand(out, exec, location, it, "throw", r0);
1285             break;
1286         }
1287         case op_throw_static_error: {
1288             int k0 = (++it)->u.operand;
1289             int k1 = (++it)->u.operand;
1290             printLocationAndOp(out, exec, location, it, "throw_static_error");
1291             out.printf("%s, %s", constantName(k0, getConstant(k0)).data(), k1 ? "true" : "false");
1292             break;
1293         }
1294         case op_debug: {
1295             int debugHookID = (++it)->u.operand;
1296             int hasBreakpointFlag = (++it)->u.operand;
1297             printLocationAndOp(out, exec, location, it, "debug");
1298             out.printf("%s %d", debugHookName(debugHookID), hasBreakpointFlag);
1299             break;
1300         }
1301         case op_profile_will_call: {
1302             int function = (++it)->u.operand;
1303             printLocationOpAndRegisterOperand(out, exec, location, it, "profile_will_call", function);
1304             break;
1305         }
1306         case op_profile_did_call: {
1307             int function = (++it)->u.operand;
1308             printLocationOpAndRegisterOperand(out, exec, location, it, "profile_did_call", function);
1309             break;
1310         }
1311         case op_end: {
1312             int r0 = (++it)->u.operand;
1313             printLocationOpAndRegisterOperand(out, exec, location, it, "end", r0);
1314             break;
1315         }
1316         case op_resolve_scope: {
1317             int r0 = (++it)->u.operand;
1318             int id0 = (++it)->u.operand;
1319             ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand);
1320             int depth = (++it)->u.operand;
1321             printLocationAndOp(out, exec, location, it, "resolve_scope");
1322             out.printf("%s, %s, %u<%s|%s>, %d", registerName(r0).data(), idName(id0, identifier(id0)).data(),
1323                 modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
1324                 depth);
1325             ++it;
1326             break;
1327         }
1328         case op_get_from_scope: {
1329             int r0 = (++it)->u.operand;
1330             int r1 = (++it)->u.operand;
1331             int id0 = (++it)->u.operand;
1332             ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand);
1333             ++it; // Structure
1334             int operand = (++it)->u.operand; // Operand
1335             ++it; // Skip value profile.
1336             printLocationAndOp(out, exec, location, it, "get_from_scope");
1337             out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d",
1338                 registerName(r0).data(), registerName(r1).data(), idName(id0, identifier(id0)).data(),
1339                 modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
1340                 operand);
1341             break;
1342         }
1343         case op_put_to_scope: {
1344             int r0 = (++it)->u.operand;
1345             int id0 = (++it)->u.operand;
1346             int r1 = (++it)->u.operand;
1347             ResolveModeAndType modeAndType = ResolveModeAndType((++it)->u.operand);
1348             ++it; // Structure
1349             int operand = (++it)->u.operand; // Operand
1350             printLocationAndOp(out, exec, location, it, "put_to_scope");
1351             out.printf("%s, %s, %s, %u<%s|%s>, <structure>, %d",
1352                 registerName(r0).data(), idName(id0, identifier(id0)).data(), registerName(r1).data(),
1353                 modeAndType.operand(), resolveModeName(modeAndType.mode()), resolveTypeName(modeAndType.type()),
1354                 operand);
1355             break;
1356         }
1357 #if ENABLE(LLINT_C_LOOP)
1358         default:
1359             RELEASE_ASSERT_NOT_REACHED();
1360 #endif
1361     }
1362
1363     dumpRareCaseProfile(out, "rare case: ", rareCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
1364     dumpRareCaseProfile(out, "special fast case: ", specialFastCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
1365     
1366 #if ENABLE(DFG_JIT)
1367     Vector<DFG::FrequentExitSite> exitSites = exitProfile().exitSitesFor(location);
1368     if (!exitSites.isEmpty()) {
1369         out.print(" !! frequent exits: ");
1370         CommaPrinter comma;
1371         for (unsigned i = 0; i < exitSites.size(); ++i)
1372             out.print(comma, exitSites[i].kind(), " ", exitSites[i].jitType());
1373     }
1374 #else // ENABLE(DFG_JIT)
1375     UNUSED_PARAM(location);
1376 #endif // ENABLE(DFG_JIT)
1377     out.print("\n");
1378 }
1379
1380 void CodeBlock::dumpBytecode(PrintStream& out, unsigned bytecodeOffset, const StubInfoMap& map)
1381 {
1382     ExecState* exec = m_globalObject->globalExec();
1383     const Instruction* it = instructions().begin() + bytecodeOffset;
1384     dumpBytecode(out, exec, instructions().begin(), it, map);
1385 }
1386
1387 #define FOR_EACH_MEMBER_VECTOR(macro) \
1388     macro(instructions) \
1389     macro(callLinkInfos) \
1390     macro(linkedCallerList) \
1391     macro(identifiers) \
1392     macro(functionExpressions) \
1393     macro(constantRegisters)
1394
1395 #define FOR_EACH_MEMBER_VECTOR_RARE_DATA(macro) \
1396     macro(regexps) \
1397     macro(functions) \
1398     macro(exceptionHandlers) \
1399     macro(switchJumpTables) \
1400     macro(stringSwitchJumpTables) \
1401     macro(evalCodeCache) \
1402     macro(expressionInfo) \
1403     macro(lineInfo) \
1404     macro(callReturnIndexVector)
1405
1406 template<typename T>
1407 static size_t sizeInBytes(const Vector<T>& vector)
1408 {
1409     return vector.capacity() * sizeof(T);
1410 }
1411
1412 CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
1413     : m_globalObject(other.m_globalObject)
1414     , m_heap(other.m_heap)
1415     , m_numCalleeRegisters(other.m_numCalleeRegisters)
1416     , m_numVars(other.m_numVars)
1417     , m_isConstructor(other.m_isConstructor)
1418     , m_shouldAlwaysBeInlined(true)
1419     , m_didFailFTLCompilation(false)
1420     , m_hasBeenCompiledWithFTL(false)
1421     , m_unlinkedCode(*other.m_vm, other.m_ownerExecutable.get(), other.m_unlinkedCode.get())
1422     , m_hasDebuggerStatement(false)
1423     , m_steppingMode(SteppingModeDisabled)
1424     , m_numBreakpoints(0)
1425     , m_ownerExecutable(*other.m_vm, other.m_ownerExecutable.get(), other.m_ownerExecutable.get())
1426     , m_vm(other.m_vm)
1427     , m_instructions(other.m_instructions)
1428     , m_thisRegister(other.m_thisRegister)
1429     , m_argumentsRegister(other.m_argumentsRegister)
1430     , m_activationRegister(other.m_activationRegister)
1431     , m_isStrictMode(other.m_isStrictMode)
1432     , m_needsActivation(other.m_needsActivation)
1433     , m_source(other.m_source)
1434     , m_sourceOffset(other.m_sourceOffset)
1435     , m_firstLineColumnOffset(other.m_firstLineColumnOffset)
1436     , m_codeType(other.m_codeType)
1437     , m_constantRegisters(other.m_constantRegisters)
1438     , m_functionDecls(other.m_functionDecls)
1439     , m_functionExprs(other.m_functionExprs)
1440     , m_osrExitCounter(0)
1441     , m_optimizationDelayCounter(0)
1442     , m_reoptimizationRetryCounter(0)
1443     , m_hash(other.m_hash)
1444 #if ENABLE(JIT)
1445     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
1446 #endif
1447 {
1448     ASSERT(m_heap->isDeferred());
1449     
1450     if (SymbolTable* symbolTable = other.symbolTable())
1451         m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable);
1452     
1453     setNumParameters(other.numParameters());
1454     optimizeAfterWarmUp();
1455     jitAfterWarmUp();
1456
1457     if (other.m_rareData) {
1458         createRareDataIfNecessary();
1459         
1460         m_rareData->m_exceptionHandlers = other.m_rareData->m_exceptionHandlers;
1461         m_rareData->m_constantBuffers = other.m_rareData->m_constantBuffers;
1462         m_rareData->m_switchJumpTables = other.m_rareData->m_switchJumpTables;
1463         m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables;
1464     }
1465     
1466     m_heap->m_codeBlocks.add(this);
1467     m_heap->reportExtraMemoryCost(sizeof(CodeBlock));
1468 }
1469
1470 CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
1471     : m_globalObject(scope->globalObject()->vm(), ownerExecutable, scope->globalObject())
1472     , m_heap(&m_globalObject->vm().heap)
1473     , m_numCalleeRegisters(unlinkedCodeBlock->m_numCalleeRegisters)
1474     , m_numVars(unlinkedCodeBlock->m_numVars)
1475     , m_isConstructor(unlinkedCodeBlock->isConstructor())
1476     , m_shouldAlwaysBeInlined(true)
1477     , m_didFailFTLCompilation(false)
1478     , m_hasBeenCompiledWithFTL(false)
1479     , m_unlinkedCode(m_globalObject->vm(), ownerExecutable, unlinkedCodeBlock)
1480     , m_hasDebuggerStatement(false)
1481     , m_steppingMode(SteppingModeDisabled)
1482     , m_numBreakpoints(0)
1483     , m_ownerExecutable(m_globalObject->vm(), ownerExecutable, ownerExecutable)
1484     , m_vm(unlinkedCodeBlock->vm())
1485     , m_thisRegister(unlinkedCodeBlock->thisRegister())
1486     , m_argumentsRegister(unlinkedCodeBlock->argumentsRegister())
1487     , m_activationRegister(unlinkedCodeBlock->activationRegister())
1488     , m_isStrictMode(unlinkedCodeBlock->isStrictMode())
1489     , m_needsActivation(unlinkedCodeBlock->hasActivationRegister() && unlinkedCodeBlock->codeType() == FunctionCode)
1490     , m_source(sourceProvider)
1491     , m_sourceOffset(sourceOffset)
1492     , m_firstLineColumnOffset(firstLineColumnOffset)
1493     , m_codeType(unlinkedCodeBlock->codeType())
1494     , m_osrExitCounter(0)
1495     , m_optimizationDelayCounter(0)
1496     , m_reoptimizationRetryCounter(0)
1497 #if ENABLE(JIT)
1498     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
1499 #endif
1500 {
1501     ASSERT(m_heap->isDeferred());
1502
1503     bool didCloneSymbolTable = false;
1504     
1505     if (SymbolTable* symbolTable = unlinkedCodeBlock->symbolTable()) {
1506         if (codeType() == FunctionCode && symbolTable->captureCount()) {
1507             m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable->cloneCapturedNames(*m_vm));
1508             didCloneSymbolTable = true;
1509         } else
1510             m_symbolTable.set(*m_vm, m_ownerExecutable.get(), symbolTable);
1511     }
1512     
1513     ASSERT(m_source);
1514     setNumParameters(unlinkedCodeBlock->numParameters());
1515
1516     setConstantRegisters(unlinkedCodeBlock->constantRegisters());
1517     if (unlinkedCodeBlock->usesGlobalObject())
1518         m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, ownerExecutable, m_globalObject.get());
1519     m_functionDecls.resizeToFit(unlinkedCodeBlock->numberOfFunctionDecls());
1520     for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
1521         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
1522         unsigned lineCount = unlinkedExecutable->lineCount();
1523         unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
1524         bool startColumnIsOnOwnerStartLine = !unlinkedExecutable->firstLineOffset();
1525         unsigned startColumn = unlinkedExecutable->unlinkedBodyStartColumn() + (startColumnIsOnOwnerStartLine ? ownerExecutable->startColumn() : 1);
1526         bool endColumnIsOnStartLine = !lineCount;
1527         unsigned endColumn = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? startColumn : 1);
1528         unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
1529         unsigned sourceLength = unlinkedExecutable->sourceLength();
1530         SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine, startColumn);
1531         FunctionExecutable* executable = FunctionExecutable::create(*m_vm, code, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn, endColumn);
1532         m_functionDecls[i].set(*m_vm, ownerExecutable, executable);
1533     }
1534
1535     m_functionExprs.resizeToFit(unlinkedCodeBlock->numberOfFunctionExprs());
1536     for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) {
1537         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
1538         unsigned lineCount = unlinkedExecutable->lineCount();
1539         unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
1540         bool startColumnIsOnOwnerStartLine = !unlinkedExecutable->firstLineOffset();
1541         unsigned startColumn = unlinkedExecutable->unlinkedBodyStartColumn() + (startColumnIsOnOwnerStartLine ? ownerExecutable->startColumn() : 1);
1542         bool endColumnIsOnStartLine = !lineCount;
1543         unsigned endColumn = unlinkedExecutable->unlinkedBodyEndColumn() + (endColumnIsOnStartLine ? startColumn : 1);
1544         unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
1545         unsigned sourceLength = unlinkedExecutable->sourceLength();
1546         SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine, startColumn);
1547         FunctionExecutable* executable = FunctionExecutable::create(*m_vm, code, unlinkedExecutable, firstLine, firstLine + lineCount, startColumn, endColumn);
1548         m_functionExprs[i].set(*m_vm, ownerExecutable, executable);
1549     }
1550
1551     if (unlinkedCodeBlock->hasRareData()) {
1552         createRareDataIfNecessary();
1553         if (size_t count = unlinkedCodeBlock->constantBufferCount()) {
1554             m_rareData->m_constantBuffers.grow(count);
1555             for (size_t i = 0; i < count; i++) {
1556                 const UnlinkedCodeBlock::ConstantBuffer& buffer = unlinkedCodeBlock->constantBuffer(i);
1557                 m_rareData->m_constantBuffers[i] = buffer;
1558             }
1559         }
1560         if (size_t count = unlinkedCodeBlock->numberOfExceptionHandlers()) {
1561             m_rareData->m_exceptionHandlers.resizeToFit(count);
1562             size_t nonLocalScopeDepth = scope->depth();
1563             for (size_t i = 0; i < count; i++) {
1564                 const UnlinkedHandlerInfo& handler = unlinkedCodeBlock->exceptionHandler(i);
1565                 m_rareData->m_exceptionHandlers[i].start = handler.start;
1566                 m_rareData->m_exceptionHandlers[i].end = handler.end;
1567                 m_rareData->m_exceptionHandlers[i].target = handler.target;
1568                 m_rareData->m_exceptionHandlers[i].scopeDepth = nonLocalScopeDepth + handler.scopeDepth;
1569 #if ENABLE(JIT) && ENABLE(LLINT)
1570                 m_rareData->m_exceptionHandlers[i].nativeCode = CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(llint_op_catch)));
1571 #endif
1572             }
1573         }
1574
1575         if (size_t count = unlinkedCodeBlock->numberOfStringSwitchJumpTables()) {
1576             m_rareData->m_stringSwitchJumpTables.grow(count);
1577             for (size_t i = 0; i < count; i++) {
1578                 UnlinkedStringJumpTable::StringOffsetTable::iterator ptr = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.begin();
1579                 UnlinkedStringJumpTable::StringOffsetTable::iterator end = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.end();
1580                 for (; ptr != end; ++ptr) {
1581                     OffsetLocation offset;
1582                     offset.branchOffset = ptr->value;
1583                     m_rareData->m_stringSwitchJumpTables[i].offsetTable.add(ptr->key, offset);
1584                 }
1585             }
1586         }
1587
1588         if (size_t count = unlinkedCodeBlock->numberOfSwitchJumpTables()) {
1589             m_rareData->m_switchJumpTables.grow(count);
1590             for (size_t i = 0; i < count; i++) {
1591                 UnlinkedSimpleJumpTable& sourceTable = unlinkedCodeBlock->switchJumpTable(i);
1592                 SimpleJumpTable& destTable = m_rareData->m_switchJumpTables[i];
1593                 destTable.branchOffsets = sourceTable.branchOffsets;
1594                 destTable.min = sourceTable.min;
1595             }
1596         }
1597     }
1598
1599     // Allocate metadata buffers for the bytecode
1600 #if ENABLE(LLINT)
1601     if (size_t size = unlinkedCodeBlock->numberOfLLintCallLinkInfos())
1602         m_llintCallLinkInfos.resizeToFit(size);
1603 #endif
1604     if (size_t size = unlinkedCodeBlock->numberOfArrayProfiles())
1605         m_arrayProfiles.grow(size);
1606     if (size_t size = unlinkedCodeBlock->numberOfArrayAllocationProfiles())
1607         m_arrayAllocationProfiles.resizeToFit(size);
1608     if (size_t size = unlinkedCodeBlock->numberOfValueProfiles())
1609         m_valueProfiles.resizeToFit(size);
1610     if (size_t size = unlinkedCodeBlock->numberOfObjectAllocationProfiles())
1611         m_objectAllocationProfiles.resizeToFit(size);
1612
1613     // Copy and translate the UnlinkedInstructions
1614     unsigned instructionCount = unlinkedCodeBlock->instructions().count();
1615     UnlinkedInstructionStream::Reader instructionReader(unlinkedCodeBlock->instructions());
1616
1617     Vector<Instruction, 0, UnsafeVectorOverflow> instructions(instructionCount);
1618     for (unsigned i = 0; !instructionReader.atEnd(); ) {
1619         const UnlinkedInstruction* pc = instructionReader.next();
1620
1621         unsigned opLength = opcodeLength(pc[0].u.opcode);
1622
1623         instructions[i] = vm()->interpreter->getOpcode(pc[0].u.opcode);
1624         for (size_t j = 1; j < opLength; ++j) {
1625             if (sizeof(int32_t) != sizeof(intptr_t))
1626                 instructions[i + j].u.pointer = 0;
1627             instructions[i + j].u.operand = pc[j].u.operand;
1628         }
1629         switch (pc[0].u.opcode) {
1630         case op_call_varargs:
1631         case op_get_by_val:
1632         case op_get_argument_by_val: {
1633             int arrayProfileIndex = pc[opLength - 2].u.operand;
1634             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
1635
1636             instructions[i + opLength - 2] = &m_arrayProfiles[arrayProfileIndex];
1637             FALLTHROUGH;
1638         }
1639         case op_get_by_id: {
1640             ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
1641             ASSERT(profile->m_bytecodeOffset == -1);
1642             profile->m_bytecodeOffset = i;
1643             instructions[i + opLength - 1] = profile;
1644             break;
1645         }
1646         case op_put_by_val: {
1647             int arrayProfileIndex = pc[opLength - 1].u.operand;
1648             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
1649             instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex];
1650             break;
1651         }
1652         case op_put_by_val_direct: {
1653             int arrayProfileIndex = pc[opLength - 1].u.operand;
1654             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
1655             instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex];
1656             break;
1657         }
1658
1659         case op_new_array:
1660         case op_new_array_buffer:
1661         case op_new_array_with_size: {
1662             int arrayAllocationProfileIndex = pc[opLength - 1].u.operand;
1663             instructions[i + opLength - 1] = &m_arrayAllocationProfiles[arrayAllocationProfileIndex];
1664             break;
1665         }
1666         case op_new_object: {
1667             int objectAllocationProfileIndex = pc[opLength - 1].u.operand;
1668             ObjectAllocationProfile* objectAllocationProfile = &m_objectAllocationProfiles[objectAllocationProfileIndex];
1669             int inferredInlineCapacity = pc[opLength - 2].u.operand;
1670
1671             instructions[i + opLength - 1] = objectAllocationProfile;
1672             objectAllocationProfile->initialize(*vm(),
1673                 m_ownerExecutable.get(), m_globalObject->objectPrototype(), inferredInlineCapacity);
1674             break;
1675         }
1676
1677         case op_call:
1678         case op_call_eval: {
1679             ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
1680             ASSERT(profile->m_bytecodeOffset == -1);
1681             profile->m_bytecodeOffset = i;
1682             instructions[i + opLength - 1] = profile;
1683             int arrayProfileIndex = pc[opLength - 2].u.operand;
1684             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
1685             instructions[i + opLength - 2] = &m_arrayProfiles[arrayProfileIndex];
1686 #if ENABLE(LLINT)
1687             instructions[i + 5] = &m_llintCallLinkInfos[pc[5].u.operand];
1688 #endif
1689             break;
1690         }
1691         case op_construct: {
1692 #if ENABLE(LLINT)
1693             instructions[i + 5] = &m_llintCallLinkInfos[pc[5].u.operand];
1694 #endif
1695             ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
1696             ASSERT(profile->m_bytecodeOffset == -1);
1697             profile->m_bytecodeOffset = i;
1698             instructions[i + opLength - 1] = profile;
1699             break;
1700         }
1701         case op_get_by_id_out_of_line:
1702         case op_get_array_length:
1703             CRASH();
1704
1705         case op_init_global_const_nop: {
1706             ASSERT(codeType() == GlobalCode);
1707             Identifier ident = identifier(pc[4].u.operand);
1708             SymbolTableEntry entry = m_globalObject->symbolTable()->get(ident.impl());
1709             if (entry.isNull())
1710                 break;
1711
1712             instructions[i + 0] = vm()->interpreter->getOpcode(op_init_global_const);
1713             instructions[i + 1] = &m_globalObject->registerAt(entry.getIndex());
1714             break;
1715         }
1716
1717         case op_resolve_scope: {
1718             const Identifier& ident = identifier(pc[2].u.operand);
1719             ResolveType type = static_cast<ResolveType>(pc[3].u.operand);
1720
1721             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Get, type);
1722             instructions[i + 3].u.operand = op.type;
1723             instructions[i + 4].u.operand = op.depth;
1724             if (op.activation)
1725                 instructions[i + 5].u.activation.set(*vm(), ownerExecutable, op.activation);
1726             break;
1727         }
1728
1729         case op_get_from_scope: {
1730             ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
1731             ASSERT(profile->m_bytecodeOffset == -1);
1732             profile->m_bytecodeOffset = i;
1733             instructions[i + opLength - 1] = profile;
1734
1735             // get_from_scope dst, scope, id, ResolveModeAndType, Structure, Operand
1736             const Identifier& ident = identifier(pc[3].u.operand);
1737             ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
1738             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Get, modeAndType.type());
1739
1740             instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
1741             if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks)
1742                 instructions[i + 5].u.watchpointSet = op.watchpointSet;
1743             else if (op.structure)
1744                 instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
1745             instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
1746             break;
1747         }
1748
1749         case op_put_to_scope: {
1750             // put_to_scope scope, id, value, ResolveModeAndType, Structure, Operand
1751             const Identifier& ident = identifier(pc[2].u.operand);
1752             ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
1753             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), scope, ident, Put, modeAndType.type());
1754
1755             instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand();
1756             if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks)
1757                 instructions[i + 5].u.watchpointSet = op.watchpointSet;
1758             else if (op.type == ClosureVar || op.type == ClosureVarWithVarInjectionChecks) {
1759                 if (op.watchpointSet)
1760                     op.watchpointSet->invalidate();
1761             } else if (op.structure)
1762                 instructions[i + 5].u.structure.set(*vm(), ownerExecutable, op.structure);
1763             instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
1764             break;
1765         }
1766             
1767         case op_captured_mov:
1768         case op_new_captured_func: {
1769             if (pc[3].u.index == UINT_MAX) {
1770                 instructions[i + 3].u.watchpointSet = 0;
1771                 break;
1772             }
1773             StringImpl* uid = identifier(pc[3].u.index).impl();
1774             RELEASE_ASSERT(didCloneSymbolTable);
1775             ConcurrentJITLocker locker(m_symbolTable->m_lock);
1776             SymbolTable::Map::iterator iter = m_symbolTable->find(locker, uid);
1777             ASSERT(iter != m_symbolTable->end(locker));
1778             iter->value.prepareToWatch();
1779             instructions[i + 3].u.watchpointSet = iter->value.watchpointSet();
1780             break;
1781         }
1782
1783         case op_debug: {
1784             if (pc[1].u.index == DidReachBreakpoint)
1785                 m_hasDebuggerStatement = true;
1786             break;
1787         }
1788
1789         default:
1790             break;
1791         }
1792         i += opLength;
1793     }
1794     m_instructions = WTF::RefCountedArray<Instruction>(instructions);
1795
1796     // Set optimization thresholds only after m_instructions is initialized, since these
1797     // rely on the instruction count (and are in theory permitted to also inspect the
1798     // instruction stream to more accurate assess the cost of tier-up).
1799     optimizeAfterWarmUp();
1800     jitAfterWarmUp();
1801
1802     // If the concurrent thread will want the code block's hash, then compute it here
1803     // synchronously.
1804     if (Options::alwaysComputeHash())
1805         hash();
1806
1807     if (Options::dumpGeneratedBytecodes())
1808         dumpBytecode();
1809     
1810     m_heap->m_codeBlocks.add(this);
1811     m_heap->reportExtraMemoryCost(sizeof(CodeBlock) + m_instructions.size() * sizeof(Instruction));
1812 }
1813
1814 CodeBlock::~CodeBlock()
1815 {
1816     if (m_vm->m_perBytecodeProfiler)
1817         m_vm->m_perBytecodeProfiler->notifyDestruction(this);
1818     
1819 #if ENABLE(VERBOSE_VALUE_PROFILE)
1820     dumpValueProfiles();
1821 #endif
1822
1823 #if ENABLE(LLINT)    
1824     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
1825         m_incomingLLIntCalls.begin()->remove();
1826 #endif // ENABLE(LLINT)
1827 #if ENABLE(JIT)
1828     // We may be destroyed before any CodeBlocks that refer to us are destroyed.
1829     // Consider that two CodeBlocks become unreachable at the same time. There
1830     // is no guarantee about the order in which the CodeBlocks are destroyed.
1831     // So, if we don't remove incoming calls, and get destroyed before the
1832     // CodeBlock(s) that have calls into us, then the CallLinkInfo vector's
1833     // destructor will try to remove nodes from our (no longer valid) linked list.
1834     while (m_incomingCalls.begin() != m_incomingCalls.end())
1835         m_incomingCalls.begin()->remove();
1836     
1837     // Note that our outgoing calls will be removed from other CodeBlocks'
1838     // m_incomingCalls linked lists through the execution of the ~CallLinkInfo
1839     // destructors.
1840
1841     for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter)
1842         (*iter)->deref();
1843 #endif // ENABLE(JIT)
1844 }
1845
1846 void CodeBlock::setNumParameters(int newValue)
1847 {
1848     m_numParameters = newValue;
1849
1850     m_argumentValueProfiles.resizeToFit(newValue);
1851 }
1852
1853 void EvalCodeCache::visitAggregate(SlotVisitor& visitor)
1854 {
1855     EvalCacheMap::iterator end = m_cacheMap.end();
1856     for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr)
1857         visitor.append(&ptr->value);
1858 }
1859
1860 CodeBlock* CodeBlock::specialOSREntryBlockOrNull()
1861 {
1862 #if ENABLE(FTL_JIT)
1863     if (jitType() != JITCode::DFGJIT)
1864         return 0;
1865     DFG::JITCode* jitCode = m_jitCode->dfg();
1866     return jitCode->osrEntryBlock.get();
1867 #else // ENABLE(FTL_JIT)
1868     return 0;
1869 #endif // ENABLE(FTL_JIT)
1870 }
1871
1872 void CodeBlock::visitAggregate(SlotVisitor& visitor)
1873 {
1874 #if ENABLE(PARALLEL_GC)
1875     // I may be asked to scan myself more than once, and it may even happen concurrently.
1876     // To this end, use a CAS loop to check if I've been called already. Only one thread
1877     // may proceed past this point - whichever one wins the CAS race.
1878     unsigned oldValue;
1879     do {
1880         oldValue = m_visitAggregateHasBeenCalled;
1881         if (oldValue) {
1882             // Looks like someone else won! Return immediately to ensure that we don't
1883             // trace the same CodeBlock concurrently. Doing so is hazardous since we will
1884             // be mutating the state of ValueProfiles, which contain JSValues, which can
1885             // have word-tearing on 32-bit, leading to awesome timing-dependent crashes
1886             // that are nearly impossible to track down.
1887             
1888             // Also note that it must be safe to return early as soon as we see the
1889             // value true (well, (unsigned)1), since once a GC thread is in this method
1890             // and has won the CAS race (i.e. was responsible for setting the value true)
1891             // it will definitely complete the rest of this method before declaring
1892             // termination.
1893             return;
1894         }
1895     } while (!WTF::weakCompareAndSwap(&m_visitAggregateHasBeenCalled, 0, 1));
1896 #endif // ENABLE(PARALLEL_GC)
1897     
1898     if (!!m_alternative)
1899         m_alternative->visitAggregate(visitor);
1900     
1901     if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
1902         otherBlock->visitAggregate(visitor);
1903
1904     visitor.reportExtraMemoryUsage(ownerExecutable(), sizeof(CodeBlock));
1905     if (m_jitCode)
1906         visitor.reportExtraMemoryUsage(ownerExecutable(), m_jitCode->size());
1907     if (m_instructions.size()) {
1908         // Divide by refCount() because m_instructions points to something that is shared
1909         // by multiple CodeBlocks, and we only want to count it towards the heap size once.
1910         // Having each CodeBlock report only its proportional share of the size is one way
1911         // of accomplishing this.
1912         visitor.reportExtraMemoryUsage(ownerExecutable(), m_instructions.size() * sizeof(Instruction) / m_instructions.refCount());
1913     }
1914
1915     visitor.append(&m_unlinkedCode);
1916
1917     // There are three things that may use unconditional finalizers: lazy bytecode freeing,
1918     // inline cache clearing, and jettisoning. The probability of us wanting to do at
1919     // least one of those things is probably quite close to 1. So we add one no matter what
1920     // and when it runs, it figures out whether it has any work to do.
1921     visitor.addUnconditionalFinalizer(this);
1922     
1923     // There are two things that we use weak reference harvesters for: DFG fixpoint for
1924     // jettisoning, and trying to find structures that would be live based on some
1925     // inline cache. So it makes sense to register them regardless.
1926     visitor.addWeakReferenceHarvester(this);
1927     m_allTransitionsHaveBeenMarked = false;
1928     
1929     if (shouldImmediatelyAssumeLivenessDuringScan()) {
1930         // This code block is live, so scan all references strongly and return.
1931         stronglyVisitStrongReferences(visitor);
1932         stronglyVisitWeakReferences(visitor);
1933         propagateTransitions(visitor);
1934         return;
1935     }
1936     
1937 #if ENABLE(DFG_JIT)
1938     // We get here if we're live in the sense that our owner executable is live,
1939     // but we're not yet live for sure in another sense: we may yet decide that this
1940     // code block should be jettisoned based on its outgoing weak references being
1941     // stale. Set a flag to indicate that we're still assuming that we're dead, and
1942     // perform one round of determining if we're live. The GC may determine, based on
1943     // either us marking additional objects, or by other objects being marked for
1944     // other reasons, that this iteration should run again; it will notify us of this
1945     // decision by calling harvestWeakReferences().
1946     
1947     m_jitCode->dfgCommon()->livenessHasBeenProved = false;
1948     
1949     propagateTransitions(visitor);
1950     determineLiveness(visitor);
1951 #else // ENABLE(DFG_JIT)
1952     RELEASE_ASSERT_NOT_REACHED();
1953 #endif // ENABLE(DFG_JIT)
1954 }
1955
1956 void CodeBlock::propagateTransitions(SlotVisitor& visitor)
1957 {
1958     UNUSED_PARAM(visitor);
1959
1960     if (m_allTransitionsHaveBeenMarked)
1961         return;
1962
1963     bool allAreMarkedSoFar = true;
1964         
1965 #if ENABLE(LLINT)
1966     Interpreter* interpreter = m_vm->interpreter;
1967     if (jitType() == JITCode::InterpreterThunk) {
1968         const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
1969         for (size_t i = 0; i < propertyAccessInstructions.size(); ++i) {
1970             Instruction* instruction = &instructions()[propertyAccessInstructions[i]];
1971             switch (interpreter->getOpcodeID(instruction[0].u.opcode)) {
1972             case op_put_by_id_transition_direct:
1973             case op_put_by_id_transition_normal:
1974             case op_put_by_id_transition_direct_out_of_line:
1975             case op_put_by_id_transition_normal_out_of_line: {
1976                 if (Heap::isMarked(instruction[4].u.structure.get()))
1977                     visitor.append(&instruction[6].u.structure);
1978                 else
1979                     allAreMarkedSoFar = false;
1980                 break;
1981             }
1982             default:
1983                 break;
1984             }
1985         }
1986     }
1987 #endif // ENABLE(LLINT)
1988
1989 #if ENABLE(JIT)
1990     if (JITCode::isJIT(jitType())) {
1991         for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
1992             StructureStubInfo& stubInfo = **iter;
1993             switch (stubInfo.accessType) {
1994             case access_put_by_id_transition_normal:
1995             case access_put_by_id_transition_direct: {
1996                 JSCell* origin = stubInfo.codeOrigin.codeOriginOwner();
1997                 if ((!origin || Heap::isMarked(origin))
1998                     && Heap::isMarked(stubInfo.u.putByIdTransition.previousStructure.get()))
1999                     visitor.append(&stubInfo.u.putByIdTransition.structure);
2000                 else
2001                     allAreMarkedSoFar = false;
2002                 break;
2003             }
2004
2005             case access_put_by_id_list: {
2006                 PolymorphicPutByIdList* list = stubInfo.u.putByIdList.list;
2007                 JSCell* origin = stubInfo.codeOrigin.codeOriginOwner();
2008                 if (origin && !Heap::isMarked(origin)) {
2009                     allAreMarkedSoFar = false;
2010                     break;
2011                 }
2012                 for (unsigned j = list->size(); j--;) {
2013                     PutByIdAccess& access = list->m_list[j];
2014                     if (!access.isTransition())
2015                         continue;
2016                     if (Heap::isMarked(access.oldStructure()))
2017                         visitor.append(&access.m_newStructure);
2018                     else
2019                         allAreMarkedSoFar = false;
2020                 }
2021                 break;
2022             }
2023             
2024             default:
2025                 break;
2026             }
2027         }
2028     }
2029 #endif // ENABLE(JIT)
2030     
2031 #if ENABLE(DFG_JIT)
2032     if (JITCode::isOptimizingJIT(jitType())) {
2033         DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
2034         for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
2035             if ((!dfgCommon->transitions[i].m_codeOrigin
2036                  || Heap::isMarked(dfgCommon->transitions[i].m_codeOrigin.get()))
2037                 && Heap::isMarked(dfgCommon->transitions[i].m_from.get())) {
2038                 // If the following three things are live, then the target of the
2039                 // transition is also live:
2040                 // - This code block. We know it's live already because otherwise
2041                 //   we wouldn't be scanning ourselves.
2042                 // - The code origin of the transition. Transitions may arise from
2043                 //   code that was inlined. They are not relevant if the user's
2044                 //   object that is required for the inlinee to run is no longer
2045                 //   live.
2046                 // - The source of the transition. The transition checks if some
2047                 //   heap location holds the source, and if so, stores the target.
2048                 //   Hence the source must be live for the transition to be live.
2049                 visitor.append(&dfgCommon->transitions[i].m_to);
2050             } else
2051                 allAreMarkedSoFar = false;
2052         }
2053     }
2054 #endif // ENABLE(DFG_JIT)
2055     
2056     if (allAreMarkedSoFar)
2057         m_allTransitionsHaveBeenMarked = true;
2058 }
2059
2060 void CodeBlock::determineLiveness(SlotVisitor& visitor)
2061 {
2062     UNUSED_PARAM(visitor);
2063     
2064     if (shouldImmediatelyAssumeLivenessDuringScan())
2065         return;
2066     
2067 #if ENABLE(DFG_JIT)
2068     // Check if we have any remaining work to do.
2069     DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
2070     if (dfgCommon->livenessHasBeenProved)
2071         return;
2072     
2073     // Now check all of our weak references. If all of them are live, then we
2074     // have proved liveness and so we scan our strong references. If at end of
2075     // GC we still have not proved liveness, then this code block is toast.
2076     bool allAreLiveSoFar = true;
2077     for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) {
2078         if (!Heap::isMarked(dfgCommon->weakReferences[i].get())) {
2079             allAreLiveSoFar = false;
2080             break;
2081         }
2082     }
2083     
2084     // If some weak references are dead, then this fixpoint iteration was
2085     // unsuccessful.
2086     if (!allAreLiveSoFar)
2087         return;
2088     
2089     // All weak references are live. Record this information so we don't
2090     // come back here again, and scan the strong references.
2091     dfgCommon->livenessHasBeenProved = true;
2092     stronglyVisitStrongReferences(visitor);
2093 #endif // ENABLE(DFG_JIT)
2094 }
2095
2096 void CodeBlock::visitWeakReferences(SlotVisitor& visitor)
2097 {
2098     propagateTransitions(visitor);
2099     determineLiveness(visitor);
2100 }
2101
2102 void CodeBlock::finalizeUnconditionally()
2103 {
2104     Interpreter* interpreter = m_vm->interpreter;
2105     if (JITCode::couldBeInterpreted(jitType())) {
2106         const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
2107         for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
2108             Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]];
2109             switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
2110             case op_get_by_id:
2111             case op_get_by_id_out_of_line:
2112             case op_put_by_id:
2113             case op_put_by_id_out_of_line:
2114                 if (!curInstruction[4].u.structure || Heap::isMarked(curInstruction[4].u.structure.get()))
2115                     break;
2116                 if (Options::verboseOSR())
2117                     dataLogF("Clearing LLInt property access with structure %p.\n", curInstruction[4].u.structure.get());
2118                 curInstruction[4].u.structure.clear();
2119                 curInstruction[5].u.operand = 0;
2120                 break;
2121             case op_put_by_id_transition_direct:
2122             case op_put_by_id_transition_normal:
2123             case op_put_by_id_transition_direct_out_of_line:
2124             case op_put_by_id_transition_normal_out_of_line:
2125                 if (Heap::isMarked(curInstruction[4].u.structure.get())
2126                     && Heap::isMarked(curInstruction[6].u.structure.get())
2127                     && Heap::isMarked(curInstruction[7].u.structureChain.get()))
2128                     break;
2129                 if (Options::verboseOSR()) {
2130                     dataLogF("Clearing LLInt put transition with structures %p -> %p, chain %p.\n",
2131                             curInstruction[4].u.structure.get(),
2132                             curInstruction[6].u.structure.get(),
2133                             curInstruction[7].u.structureChain.get());
2134                 }
2135                 curInstruction[4].u.structure.clear();
2136                 curInstruction[6].u.structure.clear();
2137                 curInstruction[7].u.structureChain.clear();
2138                 curInstruction[0].u.opcode = interpreter->getOpcode(op_put_by_id);
2139                 break;
2140             case op_get_array_length:
2141                 break;
2142             case op_to_this:
2143                 if (!curInstruction[2].u.structure || Heap::isMarked(curInstruction[2].u.structure.get()))
2144                     break;
2145                 if (Options::verboseOSR())
2146                     dataLogF("Clearing LLInt to_this with structure %p.\n", curInstruction[2].u.structure.get());
2147                 curInstruction[2].u.structure.clear();
2148                 break;
2149             case op_get_callee:
2150                 if (!curInstruction[2].u.jsCell || Heap::isMarked(curInstruction[2].u.jsCell.get()))
2151                     break;
2152                 if (Options::verboseOSR())
2153                     dataLogF("Clearing LLInt get callee with function %p.\n", curInstruction[2].u.jsCell.get());
2154                 curInstruction[2].u.jsCell.clear();
2155                 break;
2156             case op_resolve_scope: {
2157                 WriteBarrierBase<JSActivation>& activation = curInstruction[5].u.activation;
2158                 if (!activation || Heap::isMarked(activation.get()))
2159                     break;
2160                 if (Options::verboseOSR())
2161                     dataLogF("Clearing dead activation %p.\n", activation.get());
2162                 activation.clear();
2163                 break;
2164             }
2165             case op_get_from_scope:
2166             case op_put_to_scope: {
2167                 ResolveModeAndType modeAndType =
2168                     ResolveModeAndType(curInstruction[4].u.operand);
2169                 if (modeAndType.type() == GlobalVar || modeAndType.type() == GlobalVarWithVarInjectionChecks)
2170                     continue;
2171                 WriteBarrierBase<Structure>& structure = curInstruction[5].u.structure;
2172                 if (!structure || Heap::isMarked(structure.get()))
2173                     break;
2174                 if (Options::verboseOSR())
2175                     dataLogF("Clearing scope access with structure %p.\n", structure.get());
2176                 structure.clear();
2177                 break;
2178             }
2179             default:
2180                 RELEASE_ASSERT_NOT_REACHED();
2181             }
2182         }
2183
2184 #if ENABLE(LLINT)
2185         for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
2186             if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
2187                 if (Options::verboseOSR())
2188                     dataLog("Clearing LLInt call from ", *this, "\n");
2189                 m_llintCallLinkInfos[i].unlink();
2190             }
2191             if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get()))
2192                 m_llintCallLinkInfos[i].lastSeenCallee.clear();
2193         }
2194 #endif // ENABLE(LLINT)
2195     }
2196
2197 #if ENABLE(DFG_JIT)
2198     // Check if we're not live. If we are, then jettison.
2199     if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_jitCode->dfgCommon()->livenessHasBeenProved)) {
2200         if (Options::verboseOSR())
2201             dataLog(*this, " has dead weak references, jettisoning during GC.\n");
2202
2203         if (DFG::shouldShowDisassembly()) {
2204             dataLog(*this, " will be jettisoned because of the following dead references:\n");
2205             DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
2206             for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
2207                 DFG::WeakReferenceTransition& transition = dfgCommon->transitions[i];
2208                 JSCell* origin = transition.m_codeOrigin.get();
2209                 JSCell* from = transition.m_from.get();
2210                 JSCell* to = transition.m_to.get();
2211                 if ((!origin || Heap::isMarked(origin)) && Heap::isMarked(from))
2212                     continue;
2213                 dataLog("    Transition under ", RawPointer(origin), ", ", RawPointer(from), " -> ", RawPointer(to), ".\n");
2214             }
2215             for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) {
2216                 JSCell* weak = dfgCommon->weakReferences[i].get();
2217                 if (Heap::isMarked(weak))
2218                     continue;
2219                 dataLog("    Weak reference ", RawPointer(weak), ".\n");
2220             }
2221         }
2222         
2223         jettison(Profiler::JettisonDueToWeakReference);
2224         return;
2225     }
2226 #endif // ENABLE(DFG_JIT)
2227
2228 #if ENABLE(JIT)
2229     // Handle inline caches.
2230     if (!!jitCode()) {
2231         RepatchBuffer repatchBuffer(this);
2232         for (unsigned i = 0; i < numberOfCallLinkInfos(); ++i) {
2233             if (callLinkInfo(i).isLinked()) {
2234                 if (ClosureCallStubRoutine* stub = callLinkInfo(i).stub.get()) {
2235                     if (!Heap::isMarked(stub->structure())
2236                         || !Heap::isMarked(stub->executable())) {
2237                         if (Options::verboseOSR()) {
2238                             dataLog(
2239                                 "Clearing closure call from ", *this, " to ",
2240                                 stub->executable()->hashFor(callLinkInfo(i).specializationKind()),
2241                                 ", stub routine ", RawPointer(stub), ".\n");
2242                         }
2243                         callLinkInfo(i).unlink(*m_vm, repatchBuffer);
2244                     }
2245                 } else if (!Heap::isMarked(callLinkInfo(i).callee.get())) {
2246                     if (Options::verboseOSR()) {
2247                         dataLog(
2248                             "Clearing call from ", *this, " to ",
2249                             RawPointer(callLinkInfo(i).callee.get()), " (",
2250                             callLinkInfo(i).callee.get()->executable()->hashFor(
2251                                 callLinkInfo(i).specializationKind()),
2252                             ").\n");
2253                     }
2254                     callLinkInfo(i).unlink(*m_vm, repatchBuffer);
2255                 }
2256             }
2257             if (!!callLinkInfo(i).lastSeenCallee
2258                 && !Heap::isMarked(callLinkInfo(i).lastSeenCallee.get()))
2259                 callLinkInfo(i).lastSeenCallee.clear();
2260         }
2261         for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
2262             StructureStubInfo& stubInfo = **iter;
2263             
2264             if (stubInfo.visitWeakReferences())
2265                 continue;
2266             
2267             resetStubDuringGCInternal(repatchBuffer, stubInfo);
2268         }
2269     }
2270 #endif
2271 }
2272
2273 void CodeBlock::getStubInfoMap(const ConcurrentJITLocker&, StubInfoMap& result)
2274 {
2275 #if ENABLE(JIT)
2276     toHashMap(m_stubInfos, getStructureStubInfoCodeOrigin, result);
2277 #else
2278     UNUSED_PARAM(result);
2279 #endif
2280 }
2281
2282 void CodeBlock::getStubInfoMap(StubInfoMap& result)
2283 {
2284     ConcurrentJITLocker locker(m_lock);
2285     getStubInfoMap(locker, result);
2286 }
2287
2288 #if ENABLE(JIT)
2289 StructureStubInfo* CodeBlock::addStubInfo()
2290 {
2291     ConcurrentJITLocker locker(m_lock);
2292     return m_stubInfos.add();
2293 }
2294
2295 void CodeBlock::resetStub(StructureStubInfo& stubInfo)
2296 {
2297     if (stubInfo.accessType == access_unset)
2298         return;
2299     
2300     ConcurrentJITLocker locker(m_lock);
2301     
2302     RepatchBuffer repatchBuffer(this);
2303     resetStubInternal(repatchBuffer, stubInfo);
2304 }
2305
2306 void CodeBlock::resetStubInternal(RepatchBuffer& repatchBuffer, StructureStubInfo& stubInfo)
2307 {
2308     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
2309     
2310     if (Options::verboseOSR()) {
2311         // This can be called from GC destructor calls, so we don't try to do a full dump
2312         // of the CodeBlock.
2313         dataLog("Clearing structure cache (kind ", static_cast<int>(stubInfo.accessType), ") in ", RawPointer(this), ".\n");
2314     }
2315     
2316     RELEASE_ASSERT(JITCode::isJIT(jitType()));
2317     
2318     if (isGetByIdAccess(accessType))
2319         resetGetByID(repatchBuffer, stubInfo);
2320     else if (isPutByIdAccess(accessType))
2321         resetPutByID(repatchBuffer, stubInfo);
2322     else {
2323         RELEASE_ASSERT(isInAccess(accessType));
2324         resetIn(repatchBuffer, stubInfo);
2325     }
2326     
2327     stubInfo.reset();
2328 }
2329
2330 void CodeBlock::resetStubDuringGCInternal(RepatchBuffer& repatchBuffer, StructureStubInfo& stubInfo)
2331 {
2332     resetStubInternal(repatchBuffer, stubInfo);
2333     stubInfo.resetByGC = true;
2334 }
2335 #endif
2336
2337 void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
2338 {
2339     visitor.append(&m_globalObject);
2340     visitor.append(&m_ownerExecutable);
2341     visitor.append(&m_symbolTable);
2342     visitor.append(&m_unlinkedCode);
2343     if (m_rareData)
2344         m_rareData->m_evalCodeCache.visitAggregate(visitor);
2345     visitor.appendValues(m_constantRegisters.data(), m_constantRegisters.size());
2346     for (size_t i = 0; i < m_functionExprs.size(); ++i)
2347         visitor.append(&m_functionExprs[i]);
2348     for (size_t i = 0; i < m_functionDecls.size(); ++i)
2349         visitor.append(&m_functionDecls[i]);
2350     for (unsigned i = 0; i < m_objectAllocationProfiles.size(); ++i)
2351         m_objectAllocationProfiles[i].visitAggregate(visitor);
2352
2353     updateAllPredictions();
2354 }
2355
2356 void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor)
2357 {
2358     UNUSED_PARAM(visitor);
2359
2360 #if ENABLE(DFG_JIT)
2361     if (!JITCode::isOptimizingJIT(jitType()))
2362         return;
2363     
2364     DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
2365
2366     for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
2367         if (!!dfgCommon->transitions[i].m_codeOrigin)
2368             visitor.append(&dfgCommon->transitions[i].m_codeOrigin); // Almost certainly not necessary, since the code origin should also be a weak reference. Better to be safe, though.
2369         visitor.append(&dfgCommon->transitions[i].m_from);
2370         visitor.append(&dfgCommon->transitions[i].m_to);
2371     }
2372     
2373     for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i)
2374         visitor.append(&dfgCommon->weakReferences[i]);
2375 #endif    
2376 }
2377
2378 CodeBlock* CodeBlock::baselineAlternative()
2379 {
2380 #if ENABLE(JIT)
2381     CodeBlock* result = this;
2382     while (result->alternative())
2383         result = result->alternative();
2384     RELEASE_ASSERT(result);
2385     RELEASE_ASSERT(JITCode::isBaselineCode(result->jitType()) || result->jitType() == JITCode::None);
2386     return result;
2387 #else
2388     return this;
2389 #endif
2390 }
2391
2392 CodeBlock* CodeBlock::baselineVersion()
2393 {
2394 #if ENABLE(JIT)
2395     if (JITCode::isBaselineCode(jitType()))
2396         return this;
2397     CodeBlock* result = replacement();
2398     if (!result) {
2399         // This can happen if we're creating the original CodeBlock for an executable.
2400         // Assume that we're the baseline CodeBlock.
2401         RELEASE_ASSERT(jitType() == JITCode::None);
2402         return this;
2403     }
2404     result = result->baselineAlternative();
2405     return result;
2406 #else
2407     return this;
2408 #endif
2409 }
2410
2411 #if ENABLE(JIT)
2412 bool CodeBlock::hasOptimizedReplacement(JITCode::JITType typeToReplace)
2413 {
2414     return JITCode::isHigherTier(replacement()->jitType(), typeToReplace);
2415 }
2416
2417 bool CodeBlock::hasOptimizedReplacement()
2418 {
2419     return hasOptimizedReplacement(jitType());
2420 }
2421 #endif
2422
2423 bool CodeBlock::isCaptured(VirtualRegister operand, InlineCallFrame* inlineCallFrame) const
2424 {
2425     if (operand.isArgument())
2426         return operand.toArgument() && usesArguments();
2427
2428     if (inlineCallFrame)
2429         return inlineCallFrame->capturedVars.get(operand.toLocal());
2430
2431     // The activation object isn't in the captured region, but it's "captured"
2432     // in the sense that stores to its location can be observed indirectly.
2433     if (needsActivation() && operand == activationRegister())
2434         return true;
2435
2436     // Ditto for the arguments object.
2437     if (usesArguments() && operand == argumentsRegister())
2438         return true;
2439
2440     // Ditto for the arguments object.
2441     if (usesArguments() && operand == unmodifiedArgumentsRegister(argumentsRegister()))
2442         return true;
2443
2444     // We're in global code so there are no locals to capture
2445     if (!symbolTable())
2446         return false;
2447
2448     return symbolTable()->isCaptured(operand.offset());
2449 }
2450
2451 int CodeBlock::framePointerOffsetToGetActivationRegisters(int machineCaptureStart)
2452 {
2453     // We'll be adding this to the stack pointer to get a registers pointer that looks
2454     // like it would have looked in the baseline engine. For example, if bytecode would
2455     // have put the first captured variable at offset -5 but we put it at offset -1, then
2456     // we'll have an offset of 4.
2457     int32_t offset = 0;
2458     
2459     // Compute where we put the captured variables. This offset will point the registers
2460     // pointer directly at the first captured var.
2461     offset += machineCaptureStart;
2462     
2463     // Now compute the offset needed to make the runtime see the captured variables at the
2464     // same offset that the bytecode would have used.
2465     offset -= symbolTable()->captureStart();
2466     
2467     return offset;
2468 }
2469
2470 int CodeBlock::framePointerOffsetToGetActivationRegisters()
2471 {
2472     if (!JITCode::isOptimizingJIT(jitType()))
2473         return 0;
2474 #if ENABLE(DFG_JIT)
2475     return framePointerOffsetToGetActivationRegisters(jitCode()->dfgCommon()->machineCaptureStart);
2476 #else
2477     RELEASE_ASSERT_NOT_REACHED();
2478     return 0;
2479 #endif
2480 }
2481
2482 HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
2483 {
2484     RELEASE_ASSERT(bytecodeOffset < instructions().size());
2485
2486     if (!m_rareData)
2487         return 0;
2488     
2489     Vector<HandlerInfo>& exceptionHandlers = m_rareData->m_exceptionHandlers;
2490     for (size_t i = 0; i < exceptionHandlers.size(); ++i) {
2491         // Handlers are ordered innermost first, so the first handler we encounter
2492         // that contains the source address is the correct handler to use.
2493         if (exceptionHandlers[i].start <= bytecodeOffset && exceptionHandlers[i].end > bytecodeOffset)
2494             return &exceptionHandlers[i];
2495     }
2496
2497     return 0;
2498 }
2499
2500 unsigned CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
2501 {
2502     RELEASE_ASSERT(bytecodeOffset < instructions().size());
2503     return m_ownerExecutable->lineNo() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset);
2504 }
2505
2506 unsigned CodeBlock::columnNumberForBytecodeOffset(unsigned bytecodeOffset)
2507 {
2508     int divot;
2509     int startOffset;
2510     int endOffset;
2511     unsigned line;
2512     unsigned column;
2513     expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
2514     return column;
2515 }
2516
2517 void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
2518 {
2519     m_unlinkedCode->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
2520     divot += m_sourceOffset;
2521     column += line ? 1 : firstLineColumnOffset();
2522     line += m_ownerExecutable->lineNo();
2523 }
2524
2525 bool CodeBlock::hasOpDebugForLineAndColumn(unsigned line, unsigned column)
2526 {
2527     Interpreter* interpreter = vm()->interpreter;
2528     const Instruction* begin = instructions().begin();
2529     const Instruction* end = instructions().end();
2530     for (const Instruction* it = begin; it != end;) {
2531         OpcodeID opcodeID = interpreter->getOpcodeID(it->u.opcode);
2532         if (opcodeID == op_debug) {
2533             unsigned bytecodeOffset = it - begin;
2534             int unused;
2535             unsigned opDebugLine;
2536             unsigned opDebugColumn;
2537             expressionRangeForBytecodeOffset(bytecodeOffset, unused, unused, unused, opDebugLine, opDebugColumn);
2538             if (line == opDebugLine && (column == Breakpoint::unspecifiedColumn || column == opDebugColumn))
2539                 return true;
2540         }
2541         it += opcodeLengths[opcodeID];
2542     }
2543     return false;
2544 }
2545
2546 void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
2547 {
2548     m_rareCaseProfiles.shrinkToFit();
2549     m_specialFastCaseProfiles.shrinkToFit();
2550     
2551     if (shrinkMode == EarlyShrink) {
2552         m_constantRegisters.shrinkToFit();
2553         
2554         if (m_rareData) {
2555             m_rareData->m_switchJumpTables.shrinkToFit();
2556             m_rareData->m_stringSwitchJumpTables.shrinkToFit();
2557         }
2558     } // else don't shrink these, because we would have already pointed pointers into these tables.
2559 }
2560
2561 unsigned CodeBlock::addOrFindConstant(JSValue v)
2562 {
2563     unsigned result;
2564     if (findConstant(v, result))
2565         return result;
2566     return addConstant(v);
2567 }
2568
2569 bool CodeBlock::findConstant(JSValue v, unsigned& index)
2570 {
2571     unsigned numberOfConstants = numberOfConstantRegisters();
2572     for (unsigned i = 0; i < numberOfConstants; ++i) {
2573         if (getConstant(FirstConstantRegisterIndex + i) == v) {
2574             index = i;
2575             return true;
2576         }
2577     }
2578     index = numberOfConstants;
2579     return false;
2580 }
2581
2582 #if ENABLE(JIT)
2583 void CodeBlock::unlinkCalls()
2584 {
2585     if (!!m_alternative)
2586         m_alternative->unlinkCalls();
2587 #if ENABLE(LLINT)
2588     for (size_t i = 0; i < m_llintCallLinkInfos.size(); ++i) {
2589         if (m_llintCallLinkInfos[i].isLinked())
2590             m_llintCallLinkInfos[i].unlink();
2591     }
2592 #endif
2593     if (!m_callLinkInfos.size())
2594         return;
2595     if (!m_vm->canUseJIT())
2596         return;
2597     RepatchBuffer repatchBuffer(this);
2598     for (size_t i = 0; i < m_callLinkInfos.size(); i++) {
2599         if (!m_callLinkInfos[i].isLinked())
2600             continue;
2601         m_callLinkInfos[i].unlink(*m_vm, repatchBuffer);
2602     }
2603 }
2604
2605 void CodeBlock::linkIncomingCall(ExecState* callerFrame, CallLinkInfo* incoming)
2606 {
2607     noticeIncomingCall(callerFrame);
2608     m_incomingCalls.push(incoming);
2609 }
2610 #endif // ENABLE(JIT)
2611
2612 void CodeBlock::unlinkIncomingCalls()
2613 {
2614 #if ENABLE(LLINT)
2615     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
2616         m_incomingLLIntCalls.begin()->unlink();
2617 #endif // ENABLE(LLINT)
2618 #if ENABLE(JIT)
2619     if (m_incomingCalls.isEmpty())
2620         return;
2621     RepatchBuffer repatchBuffer(this);
2622     while (m_incomingCalls.begin() != m_incomingCalls.end())
2623         m_incomingCalls.begin()->unlink(*m_vm, repatchBuffer);
2624 #endif // ENABLE(JIT)
2625 }
2626
2627 #if ENABLE(LLINT)
2628 void CodeBlock::linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo* incoming)
2629 {
2630     noticeIncomingCall(callerFrame);
2631     m_incomingLLIntCalls.push(incoming);
2632 }
2633 #endif // ENABLE(LLINT)
2634
2635 void CodeBlock::clearEvalCache()
2636 {
2637     if (!!m_alternative)
2638         m_alternative->clearEvalCache();
2639     if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
2640         otherBlock->clearEvalCache();
2641     if (!m_rareData)
2642         return;
2643     m_rareData->m_evalCodeCache.clear();
2644 }
2645
2646 void CodeBlock::install()
2647 {
2648     ownerExecutable()->installCode(this);
2649 }
2650
2651 PassRefPtr<CodeBlock> CodeBlock::newReplacement()
2652 {
2653     return ownerExecutable()->newReplacementCodeBlockFor(specializationKind());
2654 }
2655
2656 const SlowArgument* CodeBlock::machineSlowArguments()
2657 {
2658     if (!JITCode::isOptimizingJIT(jitType()))
2659         return symbolTable()->slowArguments();
2660     
2661 #if ENABLE(DFG_JIT)
2662     return jitCode()->dfgCommon()->slowArguments.get();
2663 #else // ENABLE(DFG_JIT)
2664     return 0;
2665 #endif // ENABLE(DFG_JIT)
2666 }
2667
2668 #if ENABLE(JIT)
2669 CodeBlock* ProgramCodeBlock::replacement()
2670 {
2671     return jsCast<ProgramExecutable*>(ownerExecutable())->codeBlock();
2672 }
2673
2674 CodeBlock* EvalCodeBlock::replacement()
2675 {
2676     return jsCast<EvalExecutable*>(ownerExecutable())->codeBlock();
2677 }
2678
2679 CodeBlock* FunctionCodeBlock::replacement()
2680 {
2681     return jsCast<FunctionExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall);
2682 }
2683
2684 DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal()
2685 {
2686     return DFG::programCapabilityLevel(this);
2687 }
2688
2689 DFG::CapabilityLevel EvalCodeBlock::capabilityLevelInternal()
2690 {
2691     return DFG::evalCapabilityLevel(this);
2692 }
2693
2694 DFG::CapabilityLevel FunctionCodeBlock::capabilityLevelInternal()
2695 {
2696     if (m_isConstructor)
2697         return DFG::functionForConstructCapabilityLevel(this);
2698     return DFG::functionForCallCapabilityLevel(this);
2699 }
2700 #endif
2701
2702 void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode)
2703 {
2704     RELEASE_ASSERT(reason != Profiler::NotJettisoned);
2705     
2706 #if ENABLE(DFG_JIT)
2707     if (DFG::shouldShowDisassembly()) {
2708         dataLog("Jettisoning ", *this);
2709         if (mode == CountReoptimization)
2710             dataLog(" and counting reoptimization");
2711         dataLog(" due to ", reason, ".\n");
2712     }
2713     
2714     DeferGCForAWhile deferGC(*m_heap);
2715     RELEASE_ASSERT(JITCode::isOptimizingJIT(jitType()));
2716     
2717     if (Profiler::Compilation* compilation = jitCode()->dfgCommon()->compilation.get())
2718         compilation->setJettisonReason(reason);
2719     
2720     // We want to accomplish two things here:
2721     // 1) Make sure that if this CodeBlock is on the stack right now, then if we return to it
2722     //    we should OSR exit at the top of the next bytecode instruction after the return.
2723     // 2) Make sure that if we call the owner executable, then we shouldn't call this CodeBlock.
2724     
2725     // This accomplishes the OSR-exit-on-return part, and does its own book-keeping about
2726     // whether the invalidation has already happened.
2727     if (!jitCode()->dfgCommon()->invalidate()) {
2728         // Nothing to do since we've already been invalidated. That means that we cannot be
2729         // the optimized replacement.
2730         RELEASE_ASSERT(this != replacement());
2731         return;
2732     }
2733     
2734     if (DFG::shouldShowDisassembly())
2735         dataLog("    Did invalidate ", *this, "\n");
2736     
2737     // Count the reoptimization if that's what the user wanted.
2738     if (mode == CountReoptimization) {
2739         // FIXME: Maybe this should call alternative().
2740         // https://bugs.webkit.org/show_bug.cgi?id=123677
2741         baselineAlternative()->countReoptimization();
2742         if (DFG::shouldShowDisassembly())
2743             dataLog("    Did count reoptimization for ", *this, "\n");
2744     }
2745     
2746     // Now take care of the entrypoint.
2747     if (this != replacement()) {
2748         // This means that we were never the entrypoint. This can happen for OSR entry code
2749         // blocks.
2750         return;
2751     }
2752     alternative()->optimizeAfterWarmUp();
2753     tallyFrequentExitSites();
2754     alternative()->install();
2755     if (DFG::shouldShowDisassembly())
2756         dataLog("    Did install baseline version of ", *this, "\n");
2757 #else // ENABLE(DFG_JIT)
2758     UNUSED_PARAM(mode);
2759     UNREACHABLE_FOR_PLATFORM();
2760 #endif // ENABLE(DFG_JIT)
2761 }
2762
2763 JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin)
2764 {
2765     if (!codeOrigin.inlineCallFrame)
2766         return globalObject();
2767     return jsCast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())->eitherCodeBlock()->globalObject();
2768 }
2769
2770 void CodeBlock::noticeIncomingCall(ExecState* callerFrame)
2771 {
2772     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
2773     
2774     if (Options::verboseCallLink())
2775         dataLog("Noticing call link from ", *callerCodeBlock, " to ", *this, "\n");
2776     
2777     if (!m_shouldAlwaysBeInlined)
2778         return;
2779
2780 #if ENABLE(DFG_JIT)
2781     if (!hasBaselineJITProfiling())
2782         return;
2783
2784     if (!DFG::mightInlineFunction(this))
2785         return;
2786
2787     if (!canInline(m_capabilityLevelState))
2788         return;
2789     
2790     if (!DFG::isSmallEnoughToInlineCodeInto(callerCodeBlock)) {
2791         m_shouldAlwaysBeInlined = false;
2792         if (Options::verboseCallLink())
2793             dataLog("    Clearing SABI because caller is too large.\n");
2794         return;
2795     }
2796
2797     if (callerCodeBlock->jitType() == JITCode::InterpreterThunk) {
2798         // If the caller is still in the interpreter, then we can't expect inlining to
2799         // happen anytime soon. Assume it's profitable to optimize it separately. This
2800         // ensures that a function is SABI only if it is called no more frequently than
2801         // any of its callers.
2802         m_shouldAlwaysBeInlined = false;
2803         if (Options::verboseCallLink())
2804             dataLog("    Clearing SABI because caller is in LLInt.\n");
2805         return;
2806     }
2807     
2808     if (callerCodeBlock->codeType() != FunctionCode) {
2809         // If the caller is either eval or global code, assume that that won't be
2810         // optimized anytime soon. For eval code this is particularly true since we
2811         // delay eval optimization by a *lot*.
2812         m_shouldAlwaysBeInlined = false;
2813         if (Options::verboseCallLink())
2814             dataLog("    Clearing SABI because caller is not a function.\n");
2815         return;
2816     }
2817     
2818     ExecState* frame = callerFrame;
2819     for (unsigned i = Options::maximumInliningDepth(); i--; frame = frame->callerFrame()) {
2820         if (frame->isVMEntrySentinel())
2821             break;
2822         if (frame->codeBlock() == this) {
2823             // Recursive calls won't be inlined.
2824             if (Options::verboseCallLink())
2825                 dataLog("    Clearing SABI because recursion was detected.\n");
2826             m_shouldAlwaysBeInlined = false;
2827             return;
2828         }
2829     }
2830     
2831     RELEASE_ASSERT(callerCodeBlock->m_capabilityLevelState != DFG::CapabilityLevelNotSet);
2832     
2833     if (canCompile(callerCodeBlock->m_capabilityLevelState))
2834         return;
2835     
2836     if (Options::verboseCallLink())
2837         dataLog("    Clearing SABI because the caller is not a DFG candidate.\n");
2838     
2839     m_shouldAlwaysBeInlined = false;
2840 #endif
2841 }
2842
2843 unsigned CodeBlock::reoptimizationRetryCounter() const
2844 {
2845 #if ENABLE(JIT)
2846     ASSERT(m_reoptimizationRetryCounter <= Options::reoptimizationRetryCounterMax());
2847     return m_reoptimizationRetryCounter;
2848 #else
2849     return 0;
2850 #endif // ENABLE(JIT)
2851 }
2852
2853 #if ENABLE(JIT)
2854 void CodeBlock::countReoptimization()
2855 {
2856     m_reoptimizationRetryCounter++;
2857     if (m_reoptimizationRetryCounter > Options::reoptimizationRetryCounterMax())
2858         m_reoptimizationRetryCounter = Options::reoptimizationRetryCounterMax();
2859 }
2860
2861 unsigned CodeBlock::numberOfDFGCompiles()
2862 {
2863     ASSERT(JITCode::isBaselineCode(jitType()));
2864     if (Options::testTheFTL()) {
2865         if (m_didFailFTLCompilation)
2866             return 1000000;
2867         return (m_hasBeenCompiledWithFTL ? 1 : 0) + m_reoptimizationRetryCounter;
2868     }
2869     return (JITCode::isOptimizingJIT(replacement()->jitType()) ? 1 : 0) + m_reoptimizationRetryCounter;
2870 }
2871
2872 int32_t CodeBlock::codeTypeThresholdMultiplier() const
2873 {
2874     if (codeType() == EvalCode)
2875         return Options::evalThresholdMultiplier();
2876     
2877     return 1;
2878 }
2879
2880 double CodeBlock::optimizationThresholdScalingFactor()
2881 {
2882     // This expression arises from doing a least-squares fit of
2883     //
2884     // F[x_] =: a * Sqrt[x + b] + Abs[c * x] + d
2885     //
2886     // against the data points:
2887     //
2888     //    x       F[x_]
2889     //    10       0.9          (smallest reasonable code block)
2890     //   200       1.0          (typical small-ish code block)
2891     //   320       1.2          (something I saw in 3d-cube that I wanted to optimize)
2892     //  1268       5.0          (something I saw in 3d-cube that I didn't want to optimize)
2893     //  4000       5.5          (random large size, used to cause the function to converge to a shallow curve of some sort)
2894     // 10000       6.0          (similar to above)
2895     //
2896     // I achieve the minimization using the following Mathematica code:
2897     //
2898     // MyFunctionTemplate[x_, a_, b_, c_, d_] := a*Sqrt[x + b] + Abs[c*x] + d
2899     //
2900     // samples = {{10, 0.9}, {200, 1}, {320, 1.2}, {1268, 5}, {4000, 5.5}, {10000, 6}}
2901     //
2902     // solution = 
2903     //     Minimize[Plus @@ ((MyFunctionTemplate[#[[1]], a, b, c, d] - #[[2]])^2 & /@ samples),
2904     //         {a, b, c, d}][[2]]
2905     //
2906     // And the code below (to initialize a, b, c, d) is generated by:
2907     //
2908     // Print["const double " <> ToString[#[[1]]] <> " = " <>
2909     //     If[#[[2]] < 0.00001, "0.0", ToString[#[[2]]]] <> ";"] & /@ solution
2910     //
2911     // We've long known the following to be true:
2912     // - Small code blocks are cheap to optimize and so we should do it sooner rather
2913     //   than later.
2914     // - Large code blocks are expensive to optimize and so we should postpone doing so,
2915     //   and sometimes have a large enough threshold that we never optimize them.
2916     // - The difference in cost is not totally linear because (a) just invoking the
2917     //   DFG incurs some base cost and (b) for large code blocks there is enough slop
2918     //   in the correlation between instruction count and the actual compilation cost
2919     //   that for those large blocks, the instruction count should not have a strong
2920     //   influence on our threshold.
2921     //
2922     // I knew the goals but I didn't know how to achieve them; so I picked an interesting
2923     // example where the heuristics were right (code block in 3d-cube with instruction
2924     // count 320, which got compiled early as it should have been) and one where they were
2925     // totally wrong (code block in 3d-cube with instruction count 1268, which was expensive
2926     // to compile and didn't run often enough to warrant compilation in my opinion), and
2927     // then threw in additional data points that represented my own guess of what our
2928     // heuristics should do for some round-numbered examples.
2929     //
2930     // The expression to which I decided to fit the data arose because I started with an
2931     // affine function, and then did two things: put the linear part in an Abs to ensure
2932     // that the fit didn't end up choosing a negative value of c (which would result in
2933     // the function turning over and going negative for large x) and I threw in a Sqrt
2934     // term because Sqrt represents my intution that the function should be more sensitive
2935     // to small changes in small values of x, but less sensitive when x gets large.
2936     
2937     // Note that the current fit essentially eliminates the linear portion of the
2938     // expression (c == 0.0).
2939     const double a = 0.061504;
2940     const double b = 1.02406;
2941     const double c = 0.0;
2942     const double d = 0.825914;
2943     
2944     double instructionCount = this->instructionCount();
2945     
2946     ASSERT(instructionCount); // Make sure this is called only after we have an instruction stream; otherwise it'll just return the value of d, which makes no sense.
2947     
2948     double result = d + a * sqrt(instructionCount + b) + c * instructionCount;
2949     
2950     result *= codeTypeThresholdMultiplier();
2951     
2952     if (Options::verboseOSR()) {
2953         dataLog(
2954             *this, ": instruction count is ", instructionCount,
2955             ", scaling execution counter by ", result, " * ", codeTypeThresholdMultiplier(),
2956             "\n");
2957     }
2958     return result;
2959 }
2960
2961 static int32_t clipThreshold(double threshold)
2962 {
2963     if (threshold < 1.0)
2964         return 1;
2965     
2966     if (threshold > static_cast<double>(std::numeric_limits<int32_t>::max()))
2967         return std::numeric_limits<int32_t>::max();
2968     
2969     return static_cast<int32_t>(threshold);
2970 }
2971
2972 int32_t CodeBlock::adjustedCounterValue(int32_t desiredThreshold)
2973 {
2974     return clipThreshold(
2975         static_cast<double>(desiredThreshold) *
2976         optimizationThresholdScalingFactor() *
2977         (1 << reoptimizationRetryCounter()));
2978 }
2979
2980 bool CodeBlock::checkIfOptimizationThresholdReached()
2981 {
2982 #if ENABLE(DFG_JIT)
2983     if (DFG::Worklist* worklist = DFG::existingGlobalDFGWorklistOrNull()) {
2984         if (worklist->compilationState(DFG::CompilationKey(this, DFG::DFGMode))
2985             == DFG::Worklist::Compiled) {
2986             optimizeNextInvocation();
2987             return true;
2988         }
2989     }
2990 #endif
2991     
2992     return m_jitExecuteCounter.checkIfThresholdCrossedAndSet(this);
2993 }
2994
2995 void CodeBlock::optimizeNextInvocation()
2996 {
2997     if (Options::verboseOSR())
2998         dataLog(*this, ": Optimizing next invocation.\n");
2999     m_jitExecuteCounter.setNewThreshold(0, this);
3000 }
3001
3002 void CodeBlock::dontOptimizeAnytimeSoon()
3003 {
3004     if (Options::verboseOSR())
3005         dataLog(*this, ": Not optimizing anytime soon.\n");
3006     m_jitExecuteCounter.deferIndefinitely();
3007 }
3008
3009 void CodeBlock::optimizeAfterWarmUp()
3010 {
3011     if (Options::verboseOSR())
3012         dataLog(*this, ": Optimizing after warm-up.\n");
3013 #if ENABLE(DFG_JIT)
3014     m_jitExecuteCounter.setNewThreshold(
3015         adjustedCounterValue(Options::thresholdForOptimizeAfterWarmUp()), this);
3016 #endif
3017 }
3018
3019 void CodeBlock::optimizeAfterLongWarmUp()
3020 {
3021     if (Options::verboseOSR())
3022         dataLog(*this, ": Optimizing after long warm-up.\n");
3023 #if ENABLE(DFG_JIT)
3024     m_jitExecuteCounter.setNewThreshold(
3025         adjustedCounterValue(Options::thresholdForOptimizeAfterLongWarmUp()), this);
3026 #endif
3027 }
3028
3029 void CodeBlock::optimizeSoon()
3030 {
3031     if (Options::verboseOSR())
3032         dataLog(*this, ": Optimizing soon.\n");
3033 #if ENABLE(DFG_JIT)
3034     m_jitExecuteCounter.setNewThreshold(
3035         adjustedCounterValue(Options::thresholdForOptimizeSoon()), this);
3036 #endif
3037 }
3038
3039 void CodeBlock::forceOptimizationSlowPathConcurrently()
3040 {
3041     if (Options::verboseOSR())
3042         dataLog(*this, ": Forcing slow path concurrently.\n");
3043     m_jitExecuteCounter.forceSlowPathConcurrently();
3044 }
3045
3046 #if ENABLE(DFG_JIT)
3047 void CodeBlock::setOptimizationThresholdBasedOnCompilationResult(CompilationResult result)
3048 {
3049     RELEASE_ASSERT(jitType() == JITCode::BaselineJIT);
3050     RELEASE_ASSERT((result == CompilationSuccessful) == (replacement() != this));
3051     switch (result) {
3052     case CompilationSuccessful:
3053         RELEASE_ASSERT(JITCode::isOptimizingJIT(replacement()->jitType()));
3054         optimizeNextInvocation();
3055         return;
3056     case CompilationFailed:
3057         dontOptimizeAnytimeSoon();
3058         return;
3059     case CompilationDeferred:
3060         // We'd like to do dontOptimizeAnytimeSoon() but we cannot because
3061         // forceOptimizationSlowPathConcurrently() is inherently racy. It won't
3062         // necessarily guarantee anything. So, we make sure that even if that
3063         // function ends up being a no-op, we still eventually retry and realize
3064         // that we have optimized code ready.
3065         optimizeAfterWarmUp();
3066         return;
3067     case CompilationInvalidated:
3068         // Retry with exponential backoff.
3069         countReoptimization();
3070         optimizeAfterWarmUp();
3071         return;
3072     }
3073     RELEASE_ASSERT_NOT_REACHED();
3074 }
3075
3076 #endif
3077     
3078 uint32_t CodeBlock::adjustedExitCountThreshold(uint32_t desiredThreshold)
3079 {
3080     ASSERT(JITCode::isOptimizingJIT(jitType()));
3081     // Compute this the lame way so we don't saturate. This is called infrequently
3082     // enough that this loop won't hurt us.
3083     unsigned result = desiredThreshold;
3084     for (unsigned n = baselineVersion()->reoptimizationRetryCounter(); n--;) {
3085         unsigned newResult = result << 1;
3086         if (newResult < result)
3087             return std::numeric_limits<uint32_t>::max();
3088         result = newResult;
3089     }
3090     return result;
3091 }
3092
3093 uint32_t CodeBlock::exitCountThresholdForReoptimization()
3094 {
3095     return adjustedExitCountThreshold(Options::osrExitCountForReoptimization() * codeTypeThresholdMultiplier());
3096 }
3097
3098 uint32_t CodeBlock::exitCountThresholdForReoptimizationFromLoop()
3099 {
3100     return adjustedExitCountThreshold(Options::osrExitCountForReoptimizationFromLoop() * codeTypeThresholdMultiplier());
3101 }
3102
3103 bool CodeBlock::shouldReoptimizeNow()
3104 {
3105     return osrExitCounter() >= exitCountThresholdForReoptimization();
3106 }
3107
3108 bool CodeBlock::shouldReoptimizeFromLoopNow()
3109 {
3110     return osrExitCounter() >= exitCountThresholdForReoptimizationFromLoop();
3111 }
3112 #endif
3113
3114 ArrayProfile* CodeBlock::getArrayProfile(unsigned bytecodeOffset)
3115 {
3116     for (unsigned i = 0; i < m_arrayProfiles.size(); ++i) {
3117         if (m_arrayProfiles[i].bytecodeOffset() == bytecodeOffset)
3118             return &m_arrayProfiles[i];
3119     }
3120     return 0;
3121 }
3122
3123 ArrayProfile* CodeBlock::getOrAddArrayProfile(unsigned bytecodeOffset)
3124 {
3125     ArrayProfile* result = getArrayProfile(bytecodeOffset);
3126     if (result)
3127         return result;
3128     return addArrayProfile(bytecodeOffset);
3129 }
3130
3131 void CodeBlock::updateAllPredictionsAndCountLiveness(unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles)
3132 {
3133     ConcurrentJITLocker locker(m_lock);
3134     
3135     numberOfLiveNonArgumentValueProfiles = 0;
3136     numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full.
3137     for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) {
3138         ValueProfile* profile = getFromAllValueProfiles(i);
3139         unsigned numSamples = profile->totalNumberOfSamples();
3140         if (numSamples > ValueProfile::numberOfBuckets)
3141             numSamples = ValueProfile::numberOfBuckets; // We don't want profiles that are extremely hot to be given more weight.
3142         numberOfSamplesInProfiles += numSamples;
3143         if (profile->m_bytecodeOffset < 0) {
3144             profile->computeUpdatedPrediction(locker);
3145             continue;
3146         }
3147         if (profile->numberOfSamples() || profile->m_prediction != SpecNone)
3148             numberOfLiveNonArgumentValueProfiles++;
3149         profile->computeUpdatedPrediction(locker);
3150     }
3151     
3152 #if ENABLE(DFG_JIT)
3153     m_lazyOperandValueProfiles.computeUpdatedPredictions(locker);
3154 #endif
3155 }
3156
3157 void CodeBlock::updateAllValueProfilePredictions()
3158 {
3159     unsigned ignoredValue1, ignoredValue2;
3160     updateAllPredictionsAndCountLiveness(ignoredValue1, ignoredValue2);
3161 }
3162
3163 void CodeBlock::updateAllArrayPredictions()
3164 {
3165     ConcurrentJITLocker locker(m_lock);
3166     
3167     for (unsigned i = m_arrayProfiles.size(); i--;)
3168         m_arrayProfiles[i].computeUpdatedPrediction(locker, this);
3169     
3170     // Don't count these either, for similar reasons.
3171     for (unsigned i = m_arrayAllocationProfiles.size(); i--;)
3172         m_arrayAllocationProfiles[i].updateIndexingType();
3173 }
3174
3175 void CodeBlock::updateAllPredictions()
3176 {
3177     updateAllValueProfilePredictions();
3178     updateAllArrayPredictions();
3179 }
3180
3181 bool CodeBlock::shouldOptimizeNow()
3182 {
3183     if (Options::verboseOSR())
3184         dataLog("Considering optimizing ", *this, "...\n");
3185
3186     if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay())
3187         return true;
3188     
3189     updateAllArrayPredictions();
3190     
3191     unsigned numberOfLiveNonArgumentValueProfiles;
3192     unsigned numberOfSamplesInProfiles;
3193     updateAllPredictionsAndCountLiveness(numberOfLiveNonArgumentValueProfiles, numberOfSamplesInProfiles);
3194
3195     if (Options::verboseOSR()) {
3196         dataLogF(
3197             "Profile hotness: %lf (%u / %u), %lf (%u / %u)\n",
3198             (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(),
3199             numberOfLiveNonArgumentValueProfiles, numberOfValueProfiles(),
3200             (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles(),
3201             numberOfSamplesInProfiles, ValueProfile::numberOfBuckets * numberOfValueProfiles());
3202     }
3203
3204     if ((!numberOfValueProfiles() || (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles() >= Options::desiredProfileLivenessRate())
3205         && (!totalNumberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / totalNumberOfValueProfiles() >= Options::desiredProfileFullnessRate())
3206         && static_cast<unsigned>(m_optimizationDelayCounter) + 1 >= Options::minimumOptimizationDelay())
3207         return true;
3208     
3209     ASSERT(m_optimizationDelayCounter < std::numeric_limits<uint8_t>::max());
3210     m_optimizationDelayCounter++;
3211     optimizeAfterWarmUp();
3212     return false;
3213 }
3214
3215 #if ENABLE(DFG_JIT)
3216 void CodeBlock::tallyFrequentExitSites()
3217 {
3218     ASSERT(JITCode::isOptimizingJIT(jitType()));
3219     ASSERT(alternative()->jitType() == JITCode::BaselineJIT);
3220     
3221     CodeBlock* profiledBlock = alternative();
3222     
3223     switch (jitType()) {
3224     case JITCode::DFGJIT: {
3225         DFG::JITCode* jitCode = m_jitCode->dfg();
3226         for (unsigned i = 0; i < jitCode->osrExit.size(); ++i) {
3227             DFG::OSRExit& exit = jitCode->osrExit[i];
3228             
3229             if (!exit.considerAddingAsFrequentExitSite(profiledBlock))
3230                 continue;
3231         }
3232         break;
3233     }
3234
3235 #if ENABLE(FTL_JIT)
3236     case JITCode::FTLJIT: {
3237         // There is no easy way to avoid duplicating this code since the FTL::JITCode::osrExit
3238         // vector contains a totally different type, that just so happens to behave like
3239         // DFG::J