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