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