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