CodeBlock::shrinkToFit is racy
[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     dumpResultProfile(out, resultProfileForBytecodeOffset(location), hasPrintedProfiling);
1764     
1765 #if ENABLE(DFG_JIT)
1766     Vector<DFG::FrequentExitSite> exitSites = exitProfile().exitSitesFor(location);
1767     if (!exitSites.isEmpty()) {
1768         out.print(" !! frequent exits: ");
1769         CommaPrinter comma;
1770         for (unsigned i = 0; i < exitSites.size(); ++i)
1771             out.print(comma, exitSites[i].kind(), " ", exitSites[i].jitType());
1772     }
1773 #else // ENABLE(DFG_JIT)
1774     UNUSED_PARAM(location);
1775 #endif // ENABLE(DFG_JIT)
1776     out.print("\n");
1777 }
1778
1779 void CodeBlock::dumpBytecode(
1780     PrintStream& out, unsigned bytecodeOffset,
1781     const StubInfoMap& stubInfos, const CallLinkInfoMap& callLinkInfos)
1782 {
1783     ExecState* exec = m_globalObject->globalExec();
1784     const Instruction* it = instructions().begin() + bytecodeOffset;
1785     dumpBytecode(out, exec, instructions().begin(), it, stubInfos, callLinkInfos);
1786 }
1787
1788 #define FOR_EACH_MEMBER_VECTOR(macro) \
1789     macro(instructions) \
1790     macro(callLinkInfos) \
1791     macro(linkedCallerList) \
1792     macro(identifiers) \
1793     macro(functionExpressions) \
1794     macro(constantRegisters)
1795
1796 #define FOR_EACH_MEMBER_VECTOR_RARE_DATA(macro) \
1797     macro(regexps) \
1798     macro(functions) \
1799     macro(exceptionHandlers) \
1800     macro(switchJumpTables) \
1801     macro(stringSwitchJumpTables) \
1802     macro(evalCodeCache) \
1803     macro(expressionInfo) \
1804     macro(lineInfo) \
1805     macro(callReturnIndexVector)
1806
1807 template<typename T>
1808 static size_t sizeInBytes(const Vector<T>& vector)
1809 {
1810     return vector.capacity() * sizeof(T);
1811 }
1812
1813 namespace {
1814
1815 class PutToScopeFireDetail : public FireDetail {
1816 public:
1817     PutToScopeFireDetail(CodeBlock* codeBlock, const Identifier& ident)
1818         : m_codeBlock(codeBlock)
1819         , m_ident(ident)
1820     {
1821     }
1822     
1823     void dump(PrintStream& out) const override
1824     {
1825         out.print("Linking put_to_scope in ", FunctionExecutableDump(jsCast<FunctionExecutable*>(m_codeBlock->ownerExecutable())), " for ", m_ident);
1826     }
1827     
1828 private:
1829     CodeBlock* m_codeBlock;
1830     const Identifier& m_ident;
1831 };
1832
1833 } // anonymous namespace
1834
1835 CodeBlock::CodeBlock(VM* vm, Structure* structure, CopyParsedBlockTag, CodeBlock& other)
1836     : JSCell(*vm, structure)
1837     , m_globalObject(other.m_globalObject)
1838     , m_numCalleeLocals(other.m_numCalleeLocals)
1839     , m_numVars(other.m_numVars)
1840     , m_shouldAlwaysBeInlined(true)
1841 #if ENABLE(JIT)
1842     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
1843 #endif
1844     , m_didFailJITCompilation(false)
1845     , m_didFailFTLCompilation(false)
1846     , m_hasBeenCompiledWithFTL(false)
1847     , m_isConstructor(other.m_isConstructor)
1848     , m_isStrictMode(other.m_isStrictMode)
1849     , m_codeType(other.m_codeType)
1850     , m_unlinkedCode(*other.m_vm, this, other.m_unlinkedCode.get())
1851     , m_hasDebuggerStatement(false)
1852     , m_steppingMode(SteppingModeDisabled)
1853     , m_numBreakpoints(0)
1854     , m_ownerExecutable(*other.m_vm, this, other.m_ownerExecutable.get())
1855     , m_vm(other.m_vm)
1856     , m_instructions(other.m_instructions)
1857     , m_thisRegister(other.m_thisRegister)
1858     , m_scopeRegister(other.m_scopeRegister)
1859     , m_hash(other.m_hash)
1860     , m_source(other.m_source)
1861     , m_sourceOffset(other.m_sourceOffset)
1862     , m_firstLineColumnOffset(other.m_firstLineColumnOffset)
1863     , m_constantRegisters(other.m_constantRegisters)
1864     , m_constantsSourceCodeRepresentation(other.m_constantsSourceCodeRepresentation)
1865     , m_functionDecls(other.m_functionDecls)
1866     , m_functionExprs(other.m_functionExprs)
1867     , m_osrExitCounter(0)
1868     , m_optimizationDelayCounter(0)
1869     , m_reoptimizationRetryCounter(0)
1870     , m_creationTime(std::chrono::steady_clock::now())
1871 {
1872     m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed);
1873
1874     ASSERT(heap()->isDeferred());
1875     ASSERT(m_scopeRegister.isLocal());
1876
1877     setNumParameters(other.numParameters());
1878 }
1879
1880 void CodeBlock::finishCreation(VM& vm, CopyParsedBlockTag, CodeBlock& other)
1881 {
1882     Base::finishCreation(vm);
1883
1884     optimizeAfterWarmUp();
1885     jitAfterWarmUp();
1886
1887     if (other.m_rareData) {
1888         createRareDataIfNecessary();
1889         
1890         m_rareData->m_exceptionHandlers = other.m_rareData->m_exceptionHandlers;
1891         m_rareData->m_constantBuffers = other.m_rareData->m_constantBuffers;
1892         m_rareData->m_switchJumpTables = other.m_rareData->m_switchJumpTables;
1893         m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables;
1894         m_rareData->m_liveCalleeLocalsAtYield = other.m_rareData->m_liveCalleeLocalsAtYield;
1895     }
1896     
1897     heap()->m_codeBlocks.add(this);
1898 }
1899
1900 CodeBlock::CodeBlock(VM* vm, Structure* structure, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock,
1901     JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, unsigned firstLineColumnOffset)
1902     : JSCell(*vm, structure)
1903     , m_globalObject(scope->globalObject()->vm(), this, scope->globalObject())
1904     , m_numCalleeLocals(unlinkedCodeBlock->m_numCalleeLocals)
1905     , m_numVars(unlinkedCodeBlock->m_numVars)
1906     , m_shouldAlwaysBeInlined(true)
1907 #if ENABLE(JIT)
1908     , m_capabilityLevelState(DFG::CapabilityLevelNotSet)
1909 #endif
1910     , m_didFailJITCompilation(false)
1911     , m_didFailFTLCompilation(false)
1912     , m_hasBeenCompiledWithFTL(false)
1913     , m_isConstructor(unlinkedCodeBlock->isConstructor())
1914     , m_isStrictMode(unlinkedCodeBlock->isStrictMode())
1915     , m_codeType(unlinkedCodeBlock->codeType())
1916     , m_unlinkedCode(m_globalObject->vm(), this, unlinkedCodeBlock)
1917     , m_hasDebuggerStatement(false)
1918     , m_steppingMode(SteppingModeDisabled)
1919     , m_numBreakpoints(0)
1920     , m_ownerExecutable(m_globalObject->vm(), this, ownerExecutable)
1921     , m_vm(unlinkedCodeBlock->vm())
1922     , m_thisRegister(unlinkedCodeBlock->thisRegister())
1923     , m_scopeRegister(unlinkedCodeBlock->scopeRegister())
1924     , m_source(sourceProvider)
1925     , m_sourceOffset(sourceOffset)
1926     , m_firstLineColumnOffset(firstLineColumnOffset)
1927     , m_osrExitCounter(0)
1928     , m_optimizationDelayCounter(0)
1929     , m_reoptimizationRetryCounter(0)
1930     , m_creationTime(std::chrono::steady_clock::now())
1931 {
1932     m_visitWeaklyHasBeenCalled.store(false, std::memory_order_relaxed);
1933
1934     ASSERT(heap()->isDeferred());
1935     ASSERT(m_scopeRegister.isLocal());
1936
1937     ASSERT(m_source);
1938     setNumParameters(unlinkedCodeBlock->numParameters());
1939 }
1940
1941 void CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock,
1942     JSScope* scope)
1943 {
1944     Base::finishCreation(vm);
1945
1946     if (vm.typeProfiler() || vm.controlFlowProfiler())
1947         vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(), ownerExecutable->typeProfilingEndOffset());
1948
1949     setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
1950     if (unlinkedCodeBlock->usesGlobalObject())
1951         m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, this, m_globalObject.get());
1952
1953     for (unsigned i = 0; i < LinkTimeConstantCount; i++) {
1954         LinkTimeConstant type = static_cast<LinkTimeConstant>(i);
1955         if (unsigned registerIndex = unlinkedCodeBlock->registerIndexForLinkTimeConstant(type))
1956             m_constantRegisters[registerIndex].set(*m_vm, this, m_globalObject->jsCellForLinkTimeConstant(type));
1957     }
1958
1959     // We already have the cloned symbol table for the module environment since we need to instantiate
1960     // the module environments before linking the code block. We replace the stored symbol table with the already cloned one.
1961     if (UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock = jsDynamicCast<UnlinkedModuleProgramCodeBlock*>(unlinkedCodeBlock)) {
1962         SymbolTable* clonedSymbolTable = jsCast<ModuleProgramExecutable*>(ownerExecutable)->moduleEnvironmentSymbolTable();
1963         if (m_vm->typeProfiler()) {
1964             ConcurrentJITLocker locker(clonedSymbolTable->m_lock);
1965             clonedSymbolTable->prepareForTypeProfiling(locker);
1966         }
1967         replaceConstant(unlinkedModuleProgramCodeBlock->moduleEnvironmentSymbolTableConstantRegisterOffset(), clonedSymbolTable);
1968     }
1969
1970     bool shouldUpdateFunctionHasExecutedCache = vm.typeProfiler() || vm.controlFlowProfiler();
1971     m_functionDecls = RefCountedArray<WriteBarrier<FunctionExecutable>>(unlinkedCodeBlock->numberOfFunctionDecls());
1972     for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
1973         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
1974         if (shouldUpdateFunctionHasExecutedCache)
1975             vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
1976         m_functionDecls[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
1977     }
1978
1979     m_functionExprs = RefCountedArray<WriteBarrier<FunctionExecutable>>(unlinkedCodeBlock->numberOfFunctionExprs());
1980     for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) {
1981         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
1982         if (shouldUpdateFunctionHasExecutedCache)
1983             vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
1984         m_functionExprs[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
1985     }
1986
1987     if (unlinkedCodeBlock->hasRareData()) {
1988         createRareDataIfNecessary();
1989         if (size_t count = unlinkedCodeBlock->constantBufferCount()) {
1990             m_rareData->m_constantBuffers.grow(count);
1991             for (size_t i = 0; i < count; i++) {
1992                 const UnlinkedCodeBlock::ConstantBuffer& buffer = unlinkedCodeBlock->constantBuffer(i);
1993                 m_rareData->m_constantBuffers[i] = buffer;
1994             }
1995         }
1996         if (size_t count = unlinkedCodeBlock->numberOfExceptionHandlers()) {
1997             m_rareData->m_exceptionHandlers.resizeToFit(count);
1998             for (size_t i = 0; i < count; i++) {
1999                 const UnlinkedHandlerInfo& unlinkedHandler = unlinkedCodeBlock->exceptionHandler(i);
2000                 HandlerInfo& handler = m_rareData->m_exceptionHandlers[i];
2001 #if ENABLE(JIT)
2002                 handler.initialize(unlinkedHandler, CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(op_catch))));
2003 #else
2004                 handler.initialize(unlinkedHandler);
2005 #endif
2006             }
2007         }
2008
2009         if (size_t count = unlinkedCodeBlock->numberOfStringSwitchJumpTables()) {
2010             m_rareData->m_stringSwitchJumpTables.grow(count);
2011             for (size_t i = 0; i < count; i++) {
2012                 UnlinkedStringJumpTable::StringOffsetTable::iterator ptr = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.begin();
2013                 UnlinkedStringJumpTable::StringOffsetTable::iterator end = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.end();
2014                 for (; ptr != end; ++ptr) {
2015                     OffsetLocation offset;
2016                     offset.branchOffset = ptr->value;
2017                     m_rareData->m_stringSwitchJumpTables[i].offsetTable.add(ptr->key, offset);
2018                 }
2019             }
2020         }
2021
2022         if (size_t count = unlinkedCodeBlock->numberOfSwitchJumpTables()) {
2023             m_rareData->m_switchJumpTables.grow(count);
2024             for (size_t i = 0; i < count; i++) {
2025                 UnlinkedSimpleJumpTable& sourceTable = unlinkedCodeBlock->switchJumpTable(i);
2026                 SimpleJumpTable& destTable = m_rareData->m_switchJumpTables[i];
2027                 destTable.branchOffsets = sourceTable.branchOffsets;
2028                 destTable.min = sourceTable.min;
2029             }
2030         }
2031     }
2032
2033     // Allocate metadata buffers for the bytecode
2034     if (size_t size = unlinkedCodeBlock->numberOfLLintCallLinkInfos())
2035         m_llintCallLinkInfos = RefCountedArray<LLIntCallLinkInfo>(size);
2036     if (size_t size = unlinkedCodeBlock->numberOfArrayProfiles())
2037         m_arrayProfiles.grow(size);
2038     if (size_t size = unlinkedCodeBlock->numberOfArrayAllocationProfiles())
2039         m_arrayAllocationProfiles = RefCountedArray<ArrayAllocationProfile>(size);
2040     if (size_t size = unlinkedCodeBlock->numberOfValueProfiles())
2041         m_valueProfiles = RefCountedArray<ValueProfile>(size);
2042     if (size_t size = unlinkedCodeBlock->numberOfObjectAllocationProfiles())
2043         m_objectAllocationProfiles = RefCountedArray<ObjectAllocationProfile>(size);
2044
2045 #if ENABLE(JIT)
2046     setCalleeSaveRegisters(RegisterSet::llintBaselineCalleeSaveRegisters());
2047 #endif
2048
2049     // Copy and translate the UnlinkedInstructions
2050     unsigned instructionCount = unlinkedCodeBlock->instructions().count();
2051     UnlinkedInstructionStream::Reader instructionReader(unlinkedCodeBlock->instructions());
2052
2053     // Bookkeep the strongly referenced module environments.
2054     HashSet<JSModuleEnvironment*> stronglyReferencedModuleEnvironments;
2055
2056     // Bookkeep the merge point bytecode offsets.
2057     Vector<size_t> mergePointBytecodeOffsets;
2058
2059     RefCountedArray<Instruction> instructions(instructionCount);
2060
2061     for (unsigned i = 0; !instructionReader.atEnd(); ) {
2062         const UnlinkedInstruction* pc = instructionReader.next();
2063
2064         unsigned opLength = opcodeLength(pc[0].u.opcode);
2065
2066         instructions[i] = vm.interpreter->getOpcode(pc[0].u.opcode);
2067         for (size_t j = 1; j < opLength; ++j) {
2068             if (sizeof(int32_t) != sizeof(intptr_t))
2069                 instructions[i + j].u.pointer = 0;
2070             instructions[i + j].u.operand = pc[j].u.operand;
2071         }
2072         switch (pc[0].u.opcode) {
2073         case op_has_indexed_property: {
2074             int arrayProfileIndex = pc[opLength - 1].u.operand;
2075             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
2076
2077             instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex];
2078             break;
2079         }
2080         case op_call_varargs:
2081         case op_tail_call_varargs:
2082         case op_tail_call_forward_arguments:
2083         case op_construct_varargs:
2084         case op_get_by_val: {
2085             int arrayProfileIndex = pc[opLength - 2].u.operand;
2086             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
2087
2088             instructions[i + opLength - 2] = &m_arrayProfiles[arrayProfileIndex];
2089             FALLTHROUGH;
2090         }
2091         case op_get_direct_pname:
2092         case op_get_by_id:
2093         case op_get_from_arguments: {
2094             ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
2095             ASSERT(profile->m_bytecodeOffset == -1);
2096             profile->m_bytecodeOffset = i;
2097             instructions[i + opLength - 1] = profile;
2098             break;
2099         }
2100         case op_put_by_val: {
2101             int arrayProfileIndex = pc[opLength - 1].u.operand;
2102             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
2103             instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex];
2104             break;
2105         }
2106         case op_put_by_val_direct: {
2107             int arrayProfileIndex = pc[opLength - 1].u.operand;
2108             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
2109             instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex];
2110             break;
2111         }
2112
2113         case op_new_array:
2114         case op_new_array_buffer:
2115         case op_new_array_with_size: {
2116             int arrayAllocationProfileIndex = pc[opLength - 1].u.operand;
2117             instructions[i + opLength - 1] = &m_arrayAllocationProfiles[arrayAllocationProfileIndex];
2118             break;
2119         }
2120         case op_new_object: {
2121             int objectAllocationProfileIndex = pc[opLength - 1].u.operand;
2122             ObjectAllocationProfile* objectAllocationProfile = &m_objectAllocationProfiles[objectAllocationProfileIndex];
2123             int inferredInlineCapacity = pc[opLength - 2].u.operand;
2124
2125             instructions[i + opLength - 1] = objectAllocationProfile;
2126             objectAllocationProfile->initialize(vm,
2127                 this, m_globalObject->objectPrototype(), inferredInlineCapacity);
2128             break;
2129         }
2130
2131         case op_call:
2132         case op_tail_call:
2133         case op_call_eval: {
2134             ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
2135             ASSERT(profile->m_bytecodeOffset == -1);
2136             profile->m_bytecodeOffset = i;
2137             instructions[i + opLength - 1] = profile;
2138             int arrayProfileIndex = pc[opLength - 2].u.operand;
2139             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
2140             instructions[i + opLength - 2] = &m_arrayProfiles[arrayProfileIndex];
2141             instructions[i + 5] = &m_llintCallLinkInfos[pc[5].u.operand];
2142             break;
2143         }
2144         case op_construct: {
2145             instructions[i + 5] = &m_llintCallLinkInfos[pc[5].u.operand];
2146             ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
2147             ASSERT(profile->m_bytecodeOffset == -1);
2148             profile->m_bytecodeOffset = i;
2149             instructions[i + opLength - 1] = profile;
2150             break;
2151         }
2152         case op_get_array_length:
2153             CRASH();
2154
2155         case op_resolve_scope: {
2156             const Identifier& ident = identifier(pc[3].u.operand);
2157             ResolveType type = static_cast<ResolveType>(pc[4].u.operand);
2158             RELEASE_ASSERT(type != LocalClosureVar);
2159             int localScopeDepth = pc[5].u.operand;
2160
2161             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, type, InitializationMode::NotInitialization);
2162             instructions[i + 4].u.operand = op.type;
2163             instructions[i + 5].u.operand = op.depth;
2164             if (op.lexicalEnvironment) {
2165                 if (op.type == ModuleVar) {
2166                     // Keep the linked module environment strongly referenced.
2167                     if (stronglyReferencedModuleEnvironments.add(jsCast<JSModuleEnvironment*>(op.lexicalEnvironment)).isNewEntry)
2168                         addConstant(op.lexicalEnvironment);
2169                     instructions[i + 6].u.jsCell.set(vm, this, op.lexicalEnvironment);
2170                 } else
2171                     instructions[i + 6].u.symbolTable.set(vm, this, op.lexicalEnvironment->symbolTable());
2172             } else if (JSScope* constantScope = JSScope::constantScopeForCodeBlock(op.type, this))
2173                 instructions[i + 6].u.jsCell.set(vm, this, constantScope);
2174             else
2175                 instructions[i + 6].u.pointer = nullptr;
2176             break;
2177         }
2178
2179         case op_get_from_scope: {
2180             ValueProfile* profile = &m_valueProfiles[pc[opLength - 1].u.operand];
2181             ASSERT(profile->m_bytecodeOffset == -1);
2182             profile->m_bytecodeOffset = i;
2183             instructions[i + opLength - 1] = profile;
2184
2185             // get_from_scope dst, scope, id, GetPutInfo, Structure, Operand
2186
2187             int localScopeDepth = pc[5].u.operand;
2188             instructions[i + 5].u.pointer = nullptr;
2189
2190             GetPutInfo getPutInfo = GetPutInfo(pc[4].u.operand);
2191             ASSERT(!isInitialization(getPutInfo.initializationMode()));
2192             if (getPutInfo.resolveType() == LocalClosureVar) {
2193                 instructions[i + 4] = GetPutInfo(getPutInfo.resolveMode(), ClosureVar, getPutInfo.initializationMode()).operand();
2194                 break;
2195             }
2196
2197             const Identifier& ident = identifier(pc[3].u.operand);
2198             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, getPutInfo.resolveType(), InitializationMode::NotInitialization);
2199
2200             instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), op.type, getPutInfo.initializationMode()).operand();
2201             if (op.type == ModuleVar)
2202                 instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), ClosureVar, getPutInfo.initializationMode()).operand();
2203             if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks || op.type == GlobalLexicalVar || op.type == GlobalLexicalVarWithVarInjectionChecks)
2204                 instructions[i + 5].u.watchpointSet = op.watchpointSet;
2205             else if (op.structure)
2206                 instructions[i + 5].u.structure.set(vm, this, op.structure);
2207             instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
2208             break;
2209         }
2210
2211         case op_put_to_scope: {
2212             // put_to_scope scope, id, value, GetPutInfo, Structure, Operand
2213             GetPutInfo getPutInfo = GetPutInfo(pc[4].u.operand);
2214             if (getPutInfo.resolveType() == LocalClosureVar) {
2215                 // Only do watching if the property we're putting to is not anonymous.
2216                 if (static_cast<unsigned>(pc[2].u.operand) != UINT_MAX) {
2217                     int symbolTableIndex = pc[5].u.operand;
2218                     SymbolTable* symbolTable = jsCast<SymbolTable*>(getConstant(symbolTableIndex));
2219                     const Identifier& ident = identifier(pc[2].u.operand);
2220                     ConcurrentJITLocker locker(symbolTable->m_lock);
2221                     auto iter = symbolTable->find(locker, ident.impl());
2222                     ASSERT(iter != symbolTable->end(locker));
2223                     iter->value.prepareToWatch();
2224                     instructions[i + 5].u.watchpointSet = iter->value.watchpointSet();
2225                 } else
2226                     instructions[i + 5].u.watchpointSet = nullptr;
2227                 break;
2228             }
2229
2230             const Identifier& ident = identifier(pc[2].u.operand);
2231             int localScopeDepth = pc[5].u.operand;
2232             instructions[i + 5].u.pointer = nullptr;
2233             ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Put, getPutInfo.resolveType(), getPutInfo.initializationMode());
2234
2235             instructions[i + 4].u.operand = GetPutInfo(getPutInfo.resolveMode(), op.type, getPutInfo.initializationMode()).operand();
2236             if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks || op.type == GlobalLexicalVar || op.type == GlobalLexicalVarWithVarInjectionChecks)
2237                 instructions[i + 5].u.watchpointSet = op.watchpointSet;
2238             else if (op.type == ClosureVar || op.type == ClosureVarWithVarInjectionChecks) {
2239                 if (op.watchpointSet)
2240                     op.watchpointSet->invalidate(PutToScopeFireDetail(this, ident));
2241             } else if (op.structure)
2242                 instructions[i + 5].u.structure.set(vm, this, op.structure);
2243             instructions[i + 6].u.pointer = reinterpret_cast<void*>(op.operand);
2244
2245             break;
2246         }
2247
2248         case op_profile_type: {
2249             RELEASE_ASSERT(vm.typeProfiler());
2250             // The format of this instruction is: op_profile_type regToProfile, TypeLocation*, flag, identifier?, resolveType?
2251             size_t instructionOffset = i + opLength - 1;
2252             unsigned divotStart, divotEnd;
2253             GlobalVariableID globalVariableID = 0;
2254             RefPtr<TypeSet> globalTypeSet;
2255             bool shouldAnalyze = m_unlinkedCode->typeProfilerExpressionInfoForBytecodeOffset(instructionOffset, divotStart, divotEnd);
2256             VirtualRegister profileRegister(pc[1].u.operand);
2257             ProfileTypeBytecodeFlag flag = static_cast<ProfileTypeBytecodeFlag>(pc[3].u.operand);
2258             SymbolTable* symbolTable = nullptr;
2259
2260             switch (flag) {
2261             case ProfileTypeBytecodeClosureVar: {
2262                 const Identifier& ident = identifier(pc[4].u.operand);
2263                 int localScopeDepth = pc[2].u.operand;
2264                 ResolveType type = static_cast<ResolveType>(pc[5].u.operand);
2265                 // Even though type profiling may be profiling either a Get or a Put, we can always claim a Get because
2266                 // we're abstractly "read"ing from a JSScope.
2267                 ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, type, InitializationMode::NotInitialization);
2268
2269                 if (op.type == ClosureVar || op.type == ModuleVar)
2270                     symbolTable = op.lexicalEnvironment->symbolTable();
2271                 else if (op.type == GlobalVar)
2272                     symbolTable = m_globalObject.get()->symbolTable();
2273
2274                 UniquedStringImpl* impl = (op.type == ModuleVar) ? op.importedName.get() : ident.impl();
2275                 if (symbolTable) {
2276                     ConcurrentJITLocker locker(symbolTable->m_lock);
2277                     // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet.
2278                     symbolTable->prepareForTypeProfiling(locker);
2279                     globalVariableID = symbolTable->uniqueIDForVariable(locker, impl, vm);
2280                     globalTypeSet = symbolTable->globalTypeSetForVariable(locker, impl, vm);
2281                 } else
2282                     globalVariableID = TypeProfilerNoGlobalIDExists;
2283
2284                 break;
2285             }
2286             case ProfileTypeBytecodeLocallyResolved: {
2287                 int symbolTableIndex = pc[2].u.operand;
2288                 SymbolTable* symbolTable = jsCast<SymbolTable*>(getConstant(symbolTableIndex));
2289                 const Identifier& ident = identifier(pc[4].u.operand);
2290                 ConcurrentJITLocker locker(symbolTable->m_lock);
2291                 // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet.
2292                 globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), vm);
2293                 globalTypeSet = symbolTable->globalTypeSetForVariable(locker, ident.impl(), vm);
2294
2295                 break;
2296             }
2297             case ProfileTypeBytecodeDoesNotHaveGlobalID: 
2298             case ProfileTypeBytecodeFunctionArgument: {
2299                 globalVariableID = TypeProfilerNoGlobalIDExists;
2300                 break;
2301             }
2302             case ProfileTypeBytecodeFunctionReturnStatement: {
2303                 RELEASE_ASSERT(ownerExecutable->isFunctionExecutable());
2304                 globalTypeSet = jsCast<FunctionExecutable*>(ownerExecutable)->returnStatementTypeSet();
2305                 globalVariableID = TypeProfilerReturnStatement;
2306                 if (!shouldAnalyze) {
2307                     // Because a return statement can be added implicitly to return undefined at the end of a function,
2308                     // and these nodes don't emit expression ranges because they aren't in the actual source text of
2309                     // the user's program, give the type profiler some range to identify these return statements.
2310                     // Currently, the text offset that is used as identification is "f" in the function keyword
2311                     // and is stored on TypeLocation's m_divotForFunctionOffsetIfReturnStatement member variable.
2312                     divotStart = divotEnd = ownerExecutable->typeProfilingStartOffset();
2313                     shouldAnalyze = true;
2314                 }
2315                 break;
2316             }
2317             }
2318
2319             std::pair<TypeLocation*, bool> locationPair = vm.typeProfiler()->typeLocationCache()->getTypeLocation(globalVariableID,
2320                 ownerExecutable->sourceID(), divotStart, divotEnd, globalTypeSet, &vm);
2321             TypeLocation* location = locationPair.first;
2322             bool isNewLocation = locationPair.second;
2323
2324             if (flag == ProfileTypeBytecodeFunctionReturnStatement)
2325                 location->m_divotForFunctionOffsetIfReturnStatement = ownerExecutable->typeProfilingStartOffset();
2326
2327             if (shouldAnalyze && isNewLocation)
2328                 vm.typeProfiler()->insertNewLocation(location);
2329
2330             instructions[i + 2].u.location = location;
2331             break;
2332         }
2333
2334         case op_debug: {
2335             if (pc[1].u.index == DidReachBreakpoint)
2336                 m_hasDebuggerStatement = true;
2337             break;
2338         }
2339
2340         case op_save: {
2341             unsigned liveCalleeLocalsIndex = pc[2].u.index;
2342             int offset = pc[3].u.operand;
2343             if (liveCalleeLocalsIndex >= mergePointBytecodeOffsets.size())
2344                 mergePointBytecodeOffsets.resize(liveCalleeLocalsIndex + 1);
2345             mergePointBytecodeOffsets[liveCalleeLocalsIndex] = i + offset;
2346             break;
2347         }
2348
2349         default:
2350             break;
2351         }
2352         i += opLength;
2353     }
2354
2355     if (vm.controlFlowProfiler())
2356         insertBasicBlockBoundariesForControlFlowProfiler(instructions);
2357
2358     m_instructions = WTFMove(instructions);
2359
2360     // Perform bytecode liveness analysis to determine which locals are live and should be resumed when executing op_resume.
2361     if (unlinkedCodeBlock->parseMode() == SourceParseMode::GeneratorBodyMode) {
2362         if (size_t count = mergePointBytecodeOffsets.size()) {
2363             createRareDataIfNecessary();
2364             BytecodeLivenessAnalysis liveness(this);
2365             m_rareData->m_liveCalleeLocalsAtYield.grow(count);
2366             size_t liveCalleeLocalsIndex = 0;
2367             for (size_t bytecodeOffset : mergePointBytecodeOffsets) {
2368                 m_rareData->m_liveCalleeLocalsAtYield[liveCalleeLocalsIndex] = liveness.getLivenessInfoAtBytecodeOffset(bytecodeOffset);
2369                 ++liveCalleeLocalsIndex;
2370             }
2371         }
2372     }
2373
2374     // Set optimization thresholds only after m_instructions is initialized, since these
2375     // rely on the instruction count (and are in theory permitted to also inspect the
2376     // instruction stream to more accurate assess the cost of tier-up).
2377     optimizeAfterWarmUp();
2378     jitAfterWarmUp();
2379
2380     // If the concurrent thread will want the code block's hash, then compute it here
2381     // synchronously.
2382     if (Options::alwaysComputeHash())
2383         hash();
2384
2385     if (Options::dumpGeneratedBytecodes())
2386         dumpBytecode();
2387     
2388     heap()->m_codeBlocks.add(this);
2389     heap()->reportExtraMemoryAllocated(m_instructions.size() * sizeof(Instruction));
2390 }
2391
2392 #if ENABLE(WEBASSEMBLY)
2393 CodeBlock::CodeBlock(VM* vm, Structure* structure, WebAssemblyExecutable* ownerExecutable, JSGlobalObject* globalObject)
2394     : JSCell(*vm, structure)
2395     , m_globalObject(globalObject->vm(), this, globalObject)
2396     , m_numCalleeLocals(0)
2397     , m_numVars(0)
2398     , m_shouldAlwaysBeInlined(false)
2399 #if ENABLE(JIT)
2400     , m_capabilityLevelState(DFG::CannotCompile)
2401 #endif
2402     , m_didFailJITCompilation(false)
2403     , m_didFailFTLCompilation(false)
2404     , m_hasBeenCompiledWithFTL(false)
2405     , m_isConstructor(false)
2406     , m_isStrictMode(false)
2407     , m_codeType(FunctionCode)
2408     , m_hasDebuggerStatement(false)
2409     , m_steppingMode(SteppingModeDisabled)
2410     , m_numBreakpoints(0)
2411     , m_ownerExecutable(m_globalObject->vm(), this, ownerExecutable)
2412     , m_vm(vm)
2413     , m_osrExitCounter(0)
2414     , m_optimizationDelayCounter(0)
2415     , m_reoptimizationRetryCounter(0)
2416     , m_creationTime(std::chrono::steady_clock::now())
2417 {
2418     ASSERT(heap()->isDeferred());
2419 }
2420
2421 void CodeBlock::finishCreation(VM& vm, WebAssemblyExecutable*, JSGlobalObject*)
2422 {
2423     Base::finishCreation(vm);
2424
2425     heap()->m_codeBlocks.add(this);
2426 }
2427 #endif
2428
2429 CodeBlock::~CodeBlock()
2430 {
2431     if (m_vm->m_perBytecodeProfiler)
2432         m_vm->m_perBytecodeProfiler->notifyDestruction(this);
2433
2434     if (unlinkedCodeBlock()->didOptimize() == MixedTriState)
2435         unlinkedCodeBlock()->setDidOptimize(FalseTriState);
2436
2437 #if ENABLE(VERBOSE_VALUE_PROFILE)
2438     dumpValueProfiles();
2439 #endif
2440
2441     // We may be destroyed before any CodeBlocks that refer to us are destroyed.
2442     // Consider that two CodeBlocks become unreachable at the same time. There
2443     // is no guarantee about the order in which the CodeBlocks are destroyed.
2444     // So, if we don't remove incoming calls, and get destroyed before the
2445     // CodeBlock(s) that have calls into us, then the CallLinkInfo vector's
2446     // destructor will try to remove nodes from our (no longer valid) linked list.
2447     unlinkIncomingCalls();
2448     
2449     // Note that our outgoing calls will be removed from other CodeBlocks'
2450     // m_incomingCalls linked lists through the execution of the ~CallLinkInfo
2451     // destructors.
2452
2453 #if ENABLE(JIT)
2454     for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
2455         StructureStubInfo* stub = *iter;
2456         stub->aboutToDie();
2457         stub->deref();
2458     }
2459 #endif // ENABLE(JIT)
2460 }
2461
2462 void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)
2463 {
2464     ASSERT(constants.size() == constantsSourceCodeRepresentation.size());
2465     size_t count = constants.size();
2466     m_constantRegisters.resizeToFit(count);
2467     bool hasTypeProfiler = !!m_vm->typeProfiler();
2468     for (size_t i = 0; i < count; i++) {
2469         JSValue constant = constants[i].get();
2470
2471         if (!constant.isEmpty()) {
2472             if (SymbolTable* symbolTable = jsDynamicCast<SymbolTable*>(constant)) {
2473                 if (hasTypeProfiler) {
2474                     ConcurrentJITLocker locker(symbolTable->m_lock);
2475                     symbolTable->prepareForTypeProfiling(locker);
2476                 }
2477                 constant = symbolTable->cloneScopePart(*m_vm);
2478             }
2479         }
2480
2481         m_constantRegisters[i].set(*m_vm, this, constant);
2482     }
2483
2484     m_constantsSourceCodeRepresentation = constantsSourceCodeRepresentation;
2485 }
2486
2487 void CodeBlock::setAlternative(VM& vm, CodeBlock* alternative)
2488 {
2489     m_alternative.set(vm, this, alternative);
2490 }
2491
2492 void CodeBlock::setNumParameters(int newValue)
2493 {
2494     m_numParameters = newValue;
2495
2496     m_argumentValueProfiles = RefCountedArray<ValueProfile>(newValue);
2497 }
2498
2499 void EvalCodeCache::visitAggregate(SlotVisitor& visitor)
2500 {
2501     EvalCacheMap::iterator end = m_cacheMap.end();
2502     for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr)
2503         visitor.append(&ptr->value);
2504 }
2505
2506 CodeBlock* CodeBlock::specialOSREntryBlockOrNull()
2507 {
2508 #if ENABLE(FTL_JIT)
2509     if (jitType() != JITCode::DFGJIT)
2510         return 0;
2511     DFG::JITCode* jitCode = m_jitCode->dfg();
2512     return jitCode->osrEntryBlock();
2513 #else // ENABLE(FTL_JIT)
2514     return 0;
2515 #endif // ENABLE(FTL_JIT)
2516 }
2517
2518 void CodeBlock::visitWeakly(SlotVisitor& visitor)
2519 {
2520     bool setByMe = m_visitWeaklyHasBeenCalled.compareExchangeStrong(false, true);
2521     if (!setByMe)
2522         return;
2523
2524     if (Heap::isMarked(this))
2525         return;
2526
2527     if (shouldVisitStrongly()) {
2528         visitor.appendUnbarrieredReadOnlyPointer(this);
2529         return;
2530     }
2531
2532     // There are two things that may use unconditional finalizers: inline cache clearing
2533     // and jettisoning. The probability of us wanting to do at least one of those things
2534     // is probably quite close to 1. So we add one no matter what and when it runs, it
2535     // figures out whether it has any work to do.
2536     visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer);
2537
2538     if (!JITCode::isOptimizingJIT(jitType()))
2539         return;
2540
2541     // If we jettison ourselves we'll install our alternative, so make sure that it
2542     // survives GC even if we don't.
2543     visitor.append(&m_alternative);
2544     
2545     // There are two things that we use weak reference harvesters for: DFG fixpoint for
2546     // jettisoning, and trying to find structures that would be live based on some
2547     // inline cache. So it makes sense to register them regardless.
2548     visitor.addWeakReferenceHarvester(&m_weakReferenceHarvester);
2549
2550 #if ENABLE(DFG_JIT)
2551     // We get here if we're live in the sense that our owner executable is live,
2552     // but we're not yet live for sure in another sense: we may yet decide that this
2553     // code block should be jettisoned based on its outgoing weak references being
2554     // stale. Set a flag to indicate that we're still assuming that we're dead, and
2555     // perform one round of determining if we're live. The GC may determine, based on
2556     // either us marking additional objects, or by other objects being marked for
2557     // other reasons, that this iteration should run again; it will notify us of this
2558     // decision by calling harvestWeakReferences().
2559
2560     m_allTransitionsHaveBeenMarked = false;
2561     propagateTransitions(visitor);
2562
2563     m_jitCode->dfgCommon()->livenessHasBeenProved = false;
2564     determineLiveness(visitor);
2565 #endif // ENABLE(DFG_JIT)
2566 }
2567
2568 size_t CodeBlock::estimatedSize(JSCell* cell)
2569 {
2570     CodeBlock* thisObject = jsCast<CodeBlock*>(cell);
2571     size_t extraMemoryAllocated = thisObject->m_instructions.size() * sizeof(Instruction);
2572     if (thisObject->m_jitCode)
2573         extraMemoryAllocated += thisObject->m_jitCode->size();
2574     return Base::estimatedSize(cell) + extraMemoryAllocated;
2575 }
2576
2577 void CodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
2578 {
2579     CodeBlock* thisObject = jsCast<CodeBlock*>(cell);
2580     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
2581     JSCell::visitChildren(thisObject, visitor);
2582     thisObject->visitChildren(visitor);
2583 }
2584
2585 void CodeBlock::visitChildren(SlotVisitor& visitor)
2586 {
2587     // There are two things that may use unconditional finalizers: inline cache clearing
2588     // and jettisoning. The probability of us wanting to do at least one of those things
2589     // is probably quite close to 1. So we add one no matter what and when it runs, it
2590     // figures out whether it has any work to do.
2591     visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer);
2592
2593     if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
2594         visitor.appendUnbarrieredReadOnlyPointer(otherBlock);
2595
2596     if (m_jitCode)
2597         visitor.reportExtraMemoryVisited(m_jitCode->size());
2598     if (m_instructions.size())
2599         visitor.reportExtraMemoryVisited(m_instructions.size() * sizeof(Instruction) / m_instructions.refCount());
2600
2601     stronglyVisitStrongReferences(visitor);
2602     stronglyVisitWeakReferences(visitor);
2603
2604     m_allTransitionsHaveBeenMarked = false;
2605     propagateTransitions(visitor);
2606 }
2607
2608 bool CodeBlock::shouldVisitStrongly()
2609 {
2610     if (Options::forceCodeBlockLiveness())
2611         return true;
2612
2613     if (shouldJettisonDueToOldAge())
2614         return false;
2615
2616     // Interpreter and Baseline JIT CodeBlocks don't need to be jettisoned when
2617     // their weak references go stale. So if a basline JIT CodeBlock gets
2618     // scanned, we can assume that this means that it's live.
2619     if (!JITCode::isOptimizingJIT(jitType()))
2620         return true;
2621
2622     return false;
2623 }
2624
2625 bool CodeBlock::shouldJettisonDueToWeakReference()
2626 {
2627     if (!JITCode::isOptimizingJIT(jitType()))
2628         return false;
2629     return !Heap::isMarked(this);
2630 }
2631
2632 bool CodeBlock::shouldJettisonDueToOldAge()
2633 {
2634     return false;
2635 }
2636
2637 #if ENABLE(DFG_JIT)
2638 static bool shouldMarkTransition(DFG::WeakReferenceTransition& transition)
2639 {
2640     if (transition.m_codeOrigin && !Heap::isMarked(transition.m_codeOrigin.get()))
2641         return false;
2642     
2643     if (!Heap::isMarked(transition.m_from.get()))
2644         return false;
2645     
2646     return true;
2647 }
2648 #endif // ENABLE(DFG_JIT)
2649
2650 void CodeBlock::propagateTransitions(SlotVisitor& visitor)
2651 {
2652     UNUSED_PARAM(visitor);
2653
2654     if (m_allTransitionsHaveBeenMarked)
2655         return;
2656
2657     bool allAreMarkedSoFar = true;
2658         
2659     Interpreter* interpreter = m_vm->interpreter;
2660     if (jitType() == JITCode::InterpreterThunk) {
2661         const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
2662         for (size_t i = 0; i < propertyAccessInstructions.size(); ++i) {
2663             Instruction* instruction = &instructions()[propertyAccessInstructions[i]];
2664             switch (interpreter->getOpcodeID(instruction[0].u.opcode)) {
2665             case op_put_by_id: {
2666                 StructureID oldStructureID = instruction[4].u.structureID;
2667                 StructureID newStructureID = instruction[6].u.structureID;
2668                 if (!oldStructureID || !newStructureID)
2669                     break;
2670                 Structure* oldStructure =
2671                     m_vm->heap.structureIDTable().get(oldStructureID);
2672                 Structure* newStructure =
2673                     m_vm->heap.structureIDTable().get(newStructureID);
2674                 if (Heap::isMarked(oldStructure))
2675                     visitor.appendUnbarrieredReadOnlyPointer(newStructure);
2676                 else
2677                     allAreMarkedSoFar = false;
2678                 break;
2679             }
2680             default:
2681                 break;
2682             }
2683         }
2684     }
2685
2686 #if ENABLE(JIT)
2687     if (JITCode::isJIT(jitType())) {
2688         for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter)
2689             allAreMarkedSoFar &= (*iter)->propagateTransitions(visitor);
2690     }
2691 #endif // ENABLE(JIT)
2692     
2693 #if ENABLE(DFG_JIT)
2694     if (JITCode::isOptimizingJIT(jitType())) {
2695         DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
2696         for (auto& weakReference : dfgCommon->weakStructureReferences)
2697             allAreMarkedSoFar &= weakReference->markIfCheap(visitor);
2698         
2699         for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
2700             if (shouldMarkTransition(dfgCommon->transitions[i])) {
2701                 // If the following three things are live, then the target of the
2702                 // transition is also live:
2703                 //
2704                 // - This code block. We know it's live already because otherwise
2705                 //   we wouldn't be scanning ourselves.
2706                 //
2707                 // - The code origin of the transition. Transitions may arise from
2708                 //   code that was inlined. They are not relevant if the user's
2709                 //   object that is required for the inlinee to run is no longer
2710                 //   live.
2711                 //
2712                 // - The source of the transition. The transition checks if some
2713                 //   heap location holds the source, and if so, stores the target.
2714                 //   Hence the source must be live for the transition to be live.
2715                 //
2716                 // We also short-circuit the liveness if the structure is harmless
2717                 // to mark (i.e. its global object and prototype are both already
2718                 // live).
2719                 
2720                 visitor.append(&dfgCommon->transitions[i].m_to);
2721             } else
2722                 allAreMarkedSoFar = false;
2723         }
2724     }
2725 #endif // ENABLE(DFG_JIT)
2726     
2727     if (allAreMarkedSoFar)
2728         m_allTransitionsHaveBeenMarked = true;
2729 }
2730
2731 void CodeBlock::determineLiveness(SlotVisitor& visitor)
2732 {
2733     UNUSED_PARAM(visitor);
2734     
2735 #if ENABLE(DFG_JIT)
2736     // Check if we have any remaining work to do.
2737     DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
2738     if (dfgCommon->livenessHasBeenProved)
2739         return;
2740     
2741     // Now check all of our weak references. If all of them are live, then we
2742     // have proved liveness and so we scan our strong references. If at end of
2743     // GC we still have not proved liveness, then this code block is toast.
2744     bool allAreLiveSoFar = true;
2745     for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) {
2746         if (!Heap::isMarked(dfgCommon->weakReferences[i].get())) {
2747             allAreLiveSoFar = false;
2748             break;
2749         }
2750     }
2751     if (allAreLiveSoFar) {
2752         for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i) {
2753             if (!Heap::isMarked(dfgCommon->weakStructureReferences[i].get())) {
2754                 allAreLiveSoFar = false;
2755                 break;
2756             }
2757         }
2758     }
2759     
2760     // If some weak references are dead, then this fixpoint iteration was
2761     // unsuccessful.
2762     if (!allAreLiveSoFar)
2763         return;
2764     
2765     // All weak references are live. Record this information so we don't
2766     // come back here again, and scan the strong references.
2767     dfgCommon->livenessHasBeenProved = true;
2768     visitor.appendUnbarrieredReadOnlyPointer(this);
2769 #endif // ENABLE(DFG_JIT)
2770 }
2771
2772 void CodeBlock::WeakReferenceHarvester::visitWeakReferences(SlotVisitor& visitor)
2773 {
2774     CodeBlock* codeBlock =
2775         bitwise_cast<CodeBlock*>(
2776             bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_weakReferenceHarvester));
2777
2778     codeBlock->propagateTransitions(visitor);
2779     codeBlock->determineLiveness(visitor);
2780 }
2781
2782 void CodeBlock::finalizeLLIntInlineCaches()
2783 {
2784 #if ENABLE(WEBASSEMBLY)
2785     if (m_ownerExecutable->isWebAssemblyExecutable())
2786         return;
2787 #endif
2788
2789     Interpreter* interpreter = m_vm->interpreter;
2790     const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
2791     for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
2792         Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]];
2793         switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
2794         case op_get_by_id:
2795         case op_get_by_id_proto_load:
2796         case op_get_by_id_unset: {
2797             StructureID oldStructureID = curInstruction[4].u.structureID;
2798             if (!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID)))
2799                 break;
2800             if (Options::verboseOSR())
2801                 dataLogF("Clearing LLInt property access.\n");
2802             clearLLIntGetByIdCache(curInstruction);
2803             break;
2804         }
2805         case op_put_by_id: {
2806             StructureID oldStructureID = curInstruction[4].u.structureID;
2807             StructureID newStructureID = curInstruction[6].u.structureID;
2808             StructureChain* chain = curInstruction[7].u.structureChain.get();
2809             if ((!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID))) &&
2810                 (!newStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(newStructureID))) &&
2811                 (!chain || Heap::isMarked(chain)))
2812                 break;
2813             if (Options::verboseOSR())
2814                 dataLogF("Clearing LLInt put transition.\n");
2815             curInstruction[4].u.structureID = 0;
2816             curInstruction[5].u.operand = 0;
2817             curInstruction[6].u.structureID = 0;
2818             curInstruction[7].u.structureChain.clear();
2819             break;
2820         }
2821         case op_get_array_length:
2822             break;
2823         case op_to_this:
2824             if (!curInstruction[2].u.structure || Heap::isMarked(curInstruction[2].u.structure.get()))
2825                 break;
2826             if (Options::verboseOSR())
2827                 dataLogF("Clearing LLInt to_this with structure %p.\n", curInstruction[2].u.structure.get());
2828             curInstruction[2].u.structure.clear();
2829             curInstruction[3].u.toThisStatus = merge(
2830                 curInstruction[3].u.toThisStatus, ToThisClearedByGC);
2831             break;
2832         case op_create_this: {
2833             auto& cacheWriteBarrier = curInstruction[4].u.jsCell;
2834             if (!cacheWriteBarrier || cacheWriteBarrier.unvalidatedGet() == JSCell::seenMultipleCalleeObjects())
2835                 break;
2836             JSCell* cachedFunction = cacheWriteBarrier.get();
2837             if (Heap::isMarked(cachedFunction))
2838                 break;
2839             if (Options::verboseOSR())
2840                 dataLogF("Clearing LLInt create_this with cached callee %p.\n", cachedFunction);
2841             cacheWriteBarrier.clear();
2842             break;
2843         }
2844         case op_resolve_scope: {
2845             // Right now this isn't strictly necessary. Any symbol tables that this will refer to
2846             // are for outer functions, and we refer to those functions strongly, and they refer
2847             // to the symbol table strongly. But it's nice to be on the safe side.
2848             WriteBarrierBase<SymbolTable>& symbolTable = curInstruction[6].u.symbolTable;
2849             if (!symbolTable || Heap::isMarked(symbolTable.get()))
2850                 break;
2851             if (Options::verboseOSR())
2852                 dataLogF("Clearing dead symbolTable %p.\n", symbolTable.get());
2853             symbolTable.clear();
2854             break;
2855         }
2856         case op_get_from_scope:
2857         case op_put_to_scope: {
2858             GetPutInfo getPutInfo = GetPutInfo(curInstruction[4].u.operand);
2859             if (getPutInfo.resolveType() == GlobalVar || getPutInfo.resolveType() == GlobalVarWithVarInjectionChecks 
2860                 || getPutInfo.resolveType() == LocalClosureVar || getPutInfo.resolveType() == GlobalLexicalVar || getPutInfo.resolveType() == GlobalLexicalVarWithVarInjectionChecks)
2861                 continue;
2862             WriteBarrierBase<Structure>& structure = curInstruction[5].u.structure;
2863             if (!structure || Heap::isMarked(structure.get()))
2864                 break;
2865             if (Options::verboseOSR())
2866                 dataLogF("Clearing scope access with structure %p.\n", structure.get());
2867             structure.clear();
2868             break;
2869         }
2870         default:
2871             OpcodeID opcodeID = interpreter->getOpcodeID(curInstruction[0].u.opcode);
2872             ASSERT_WITH_MESSAGE_UNUSED(opcodeID, false, "Unhandled opcode in CodeBlock::finalizeUnconditionally, %s(%d) at bc %u", opcodeNames[opcodeID], opcodeID, propertyAccessInstructions[i]);
2873         }
2874     }
2875
2876     // We can't just remove all the sets when we clear the caches since we might have created a watchpoint set
2877     // then cleared the cache without GCing in between.
2878     m_llintGetByIdWatchpointMap.removeIf([](const StructureWatchpointMap::KeyValuePairType& pair) -> bool {
2879         return !Heap::isMarked(pair.key);
2880     });
2881
2882     for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
2883         if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
2884             if (Options::verboseOSR())
2885                 dataLog("Clearing LLInt call from ", *this, "\n");
2886             m_llintCallLinkInfos[i].unlink();
2887         }
2888         if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get()))
2889             m_llintCallLinkInfos[i].lastSeenCallee.clear();
2890     }
2891 }
2892
2893 void CodeBlock::finalizeBaselineJITInlineCaches()
2894 {
2895 #if ENABLE(JIT)
2896     for (auto iter = callLinkInfosBegin(); !!iter; ++iter)
2897         (*iter)->visitWeak(*vm());
2898
2899     for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
2900         StructureStubInfo& stubInfo = **iter;
2901         stubInfo.visitWeakReferences(this);
2902     }
2903 #endif
2904 }
2905
2906 void CodeBlock::UnconditionalFinalizer::finalizeUnconditionally()
2907 {
2908     CodeBlock* codeBlock = bitwise_cast<CodeBlock*>(
2909         bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_unconditionalFinalizer));
2910
2911 #if ENABLE(DFG_JIT)
2912     if (codeBlock->shouldJettisonDueToWeakReference()) {
2913         codeBlock->jettison(Profiler::JettisonDueToWeakReference);
2914         return;
2915     }
2916 #endif // ENABLE(DFG_JIT)
2917
2918     if (codeBlock->shouldJettisonDueToOldAge()) {
2919         codeBlock->jettison(Profiler::JettisonDueToOldAge);
2920         return;
2921     }
2922
2923     if (JITCode::couldBeInterpreted(codeBlock->jitType()))
2924         codeBlock->finalizeLLIntInlineCaches();
2925
2926 #if ENABLE(JIT)
2927     if (!!codeBlock->jitCode())
2928         codeBlock->finalizeBaselineJITInlineCaches();
2929 #endif
2930 }
2931
2932 void CodeBlock::getStubInfoMap(const ConcurrentJITLocker&, StubInfoMap& result)
2933 {
2934 #if ENABLE(JIT)
2935     toHashMap(m_stubInfos, getStructureStubInfoCodeOrigin, result);
2936 #else
2937     UNUSED_PARAM(result);
2938 #endif
2939 }
2940
2941 void CodeBlock::getStubInfoMap(StubInfoMap& result)
2942 {
2943     ConcurrentJITLocker locker(m_lock);
2944     getStubInfoMap(locker, result);
2945 }
2946
2947 void CodeBlock::getCallLinkInfoMap(const ConcurrentJITLocker&, CallLinkInfoMap& result)
2948 {
2949 #if ENABLE(JIT)
2950     toHashMap(m_callLinkInfos, getCallLinkInfoCodeOrigin, result);
2951 #else
2952     UNUSED_PARAM(result);
2953 #endif
2954 }
2955
2956 void CodeBlock::getCallLinkInfoMap(CallLinkInfoMap& result)
2957 {
2958     ConcurrentJITLocker locker(m_lock);
2959     getCallLinkInfoMap(locker, result);
2960 }
2961
2962 void CodeBlock::getByValInfoMap(const ConcurrentJITLocker&, ByValInfoMap& result)
2963 {
2964 #if ENABLE(JIT)
2965     for (auto* byValInfo : m_byValInfos)
2966         result.add(CodeOrigin(byValInfo->bytecodeIndex), byValInfo);
2967 #else
2968     UNUSED_PARAM(result);
2969 #endif
2970 }
2971
2972 void CodeBlock::getByValInfoMap(ByValInfoMap& result)
2973 {
2974     ConcurrentJITLocker locker(m_lock);
2975     getByValInfoMap(locker, result);
2976 }
2977
2978 #if ENABLE(JIT)
2979 StructureStubInfo* CodeBlock::addStubInfo(AccessType accessType)
2980 {
2981     ConcurrentJITLocker locker(m_lock);
2982     return m_stubInfos.add(accessType);
2983 }
2984
2985 StructureStubInfo* CodeBlock::findStubInfo(CodeOrigin codeOrigin)
2986 {
2987     for (StructureStubInfo* stubInfo : m_stubInfos) {
2988         if (stubInfo->codeOrigin == codeOrigin)
2989             return stubInfo;
2990     }
2991     return nullptr;
2992 }
2993
2994 ByValInfo* CodeBlock::addByValInfo()
2995 {
2996     ConcurrentJITLocker locker(m_lock);
2997     return m_byValInfos.add();
2998 }
2999
3000 CallLinkInfo* CodeBlock::addCallLinkInfo()
3001 {
3002     ConcurrentJITLocker locker(m_lock);
3003     return m_callLinkInfos.add();
3004 }
3005
3006 CallLinkInfo* CodeBlock::getCallLinkInfoForBytecodeIndex(unsigned index)
3007 {
3008     for (auto iter = m_callLinkInfos.begin(); !!iter; ++iter) {
3009         if ((*iter)->codeOrigin() == CodeOrigin(index))
3010             return *iter;
3011     }
3012     return nullptr;
3013 }
3014 #endif
3015
3016 void CodeBlock::visitOSRExitTargets(SlotVisitor& visitor)
3017 {
3018     // We strongly visit OSR exits targets because we don't want to deal with
3019     // the complexity of generating an exit target CodeBlock on demand and
3020     // guaranteeing that it matches the details of the CodeBlock we compiled
3021     // the OSR exit against.
3022
3023     visitor.append(&m_alternative);
3024
3025 #if ENABLE(DFG_JIT)
3026     DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
3027     if (dfgCommon->inlineCallFrames) {
3028         for (auto* inlineCallFrame : *dfgCommon->inlineCallFrames) {
3029             ASSERT(inlineCallFrame->baselineCodeBlock);
3030             visitor.append(&inlineCallFrame->baselineCodeBlock);
3031         }
3032     }
3033 #endif
3034 }
3035
3036 void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
3037 {
3038     visitor.append(&m_globalObject);
3039     visitor.append(&m_ownerExecutable);
3040     visitor.append(&m_unlinkedCode);
3041     if (m_rareData)
3042         m_rareData->m_evalCodeCache.visitAggregate(visitor);
3043     visitor.appendValues(m_constantRegisters.data(), m_constantRegisters.size());
3044     for (size_t i = 0; i < m_functionExprs.size(); ++i)
3045         visitor.append(&m_functionExprs[i]);
3046     for (size_t i = 0; i < m_functionDecls.size(); ++i)
3047         visitor.append(&m_functionDecls[i]);
3048     for (unsigned i = 0; i < m_objectAllocationProfiles.size(); ++i)
3049         m_objectAllocationProfiles[i].visitAggregate(visitor);
3050
3051 #if ENABLE(DFG_JIT)
3052     if (JITCode::isOptimizingJIT(jitType()))
3053         visitOSRExitTargets(visitor);
3054 #endif
3055
3056     updateAllPredictions();
3057 }
3058
3059 void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor)
3060 {
3061     UNUSED_PARAM(visitor);
3062
3063 #if ENABLE(DFG_JIT)
3064     if (!JITCode::isOptimizingJIT(jitType()))
3065         return;
3066     
3067     DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
3068
3069     for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
3070         if (!!dfgCommon->transitions[i].m_codeOrigin)
3071             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.
3072         visitor.append(&dfgCommon->transitions[i].m_from);
3073         visitor.append(&dfgCommon->transitions[i].m_to);
3074     }
3075     
3076     for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i)
3077         visitor.append(&dfgCommon->weakReferences[i]);
3078
3079     for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i)
3080         visitor.append(&dfgCommon->weakStructureReferences[i]);
3081
3082     dfgCommon->livenessHasBeenProved = true;
3083 #endif    
3084 }
3085
3086 CodeBlock* CodeBlock::baselineAlternative()
3087 {
3088 #if ENABLE(JIT)
3089     CodeBlock* result = this;
3090     while (result->alternative())
3091         result = result->alternative();
3092     RELEASE_ASSERT(result);
3093     RELEASE_ASSERT(JITCode::isBaselineCode(result->jitType()) || result->jitType() == JITCode::None);
3094     return result;
3095 #else
3096     return this;
3097 #endif
3098 }
3099
3100 CodeBlock* CodeBlock::baselineVersion()
3101 {
3102 #if ENABLE(JIT)
3103     if (JITCode::isBaselineCode(jitType()))
3104         return this;
3105     CodeBlock* result = replacement();
3106     if (!result) {
3107         // This can happen if we're creating the original CodeBlock for an executable.
3108         // Assume that we're the baseline CodeBlock.
3109         RELEASE_ASSERT(jitType() == JITCode::None);
3110         return this;
3111     }
3112     result = result->baselineAlternative();
3113     return result;
3114 #else
3115     return this;
3116 #endif
3117 }
3118
3119 #if ENABLE(JIT)
3120 bool CodeBlock::hasOptimizedReplacement(JITCode::JITType typeToReplace)
3121 {
3122     return JITCode::isHigherTier(replacement()->jitType(), typeToReplace);
3123 }
3124
3125 bool CodeBlock::hasOptimizedReplacement()
3126 {
3127     return hasOptimizedReplacement(jitType());
3128 }
3129 #endif
3130
3131 HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler requiredHandler)
3132 {
3133     RELEASE_ASSERT(bytecodeOffset < instructions().size());
3134     return handlerForIndex(bytecodeOffset, requiredHandler);
3135 }
3136
3137 HandlerInfo* CodeBlock::handlerForIndex(unsigned index, RequiredHandler requiredHandler)
3138 {
3139     if (!m_rareData)
3140         return 0;
3141     
3142     Vector<HandlerInfo>& exceptionHandlers = m_rareData->m_exceptionHandlers;
3143     for (size_t i = 0; i < exceptionHandlers.size(); ++i) {
3144         HandlerInfo& handler = exceptionHandlers[i];
3145         if ((requiredHandler == RequiredHandler::CatchHandler) && !handler.isCatchHandler())
3146             continue;
3147
3148         // Handlers are ordered innermost first, so the first handler we encounter
3149         // that contains the source address is the correct handler to use.
3150         // This index used is either the BytecodeOffset or a CallSiteIndex.
3151         if (handler.start <= index && handler.end > index)
3152             return &handler;
3153     }
3154
3155     return 0;
3156 }
3157
3158 CallSiteIndex CodeBlock::newExceptionHandlingCallSiteIndex(CallSiteIndex originalCallSite)
3159 {
3160 #if ENABLE(DFG_JIT)
3161     RELEASE_ASSERT(JITCode::isOptimizingJIT(jitType()));
3162     RELEASE_ASSERT(canGetCodeOrigin(originalCallSite));
3163     ASSERT(!!handlerForIndex(originalCallSite.bits()));
3164     CodeOrigin originalOrigin = codeOrigin(originalCallSite);
3165     return m_jitCode->dfgCommon()->addUniqueCallSiteIndex(originalOrigin);
3166 #else
3167     // We never create new on-the-fly exception handling
3168     // call sites outside the DFG/FTL inline caches.
3169     UNUSED_PARAM(originalCallSite);
3170     RELEASE_ASSERT_NOT_REACHED();
3171     return CallSiteIndex(0u);
3172 #endif
3173 }
3174
3175 void CodeBlock::removeExceptionHandlerForCallSite(CallSiteIndex callSiteIndex)
3176 {
3177     RELEASE_ASSERT(m_rareData);
3178     Vector<HandlerInfo>& exceptionHandlers = m_rareData->m_exceptionHandlers;
3179     unsigned index = callSiteIndex.bits();
3180     for (size_t i = 0; i < exceptionHandlers.size(); ++i) {
3181         HandlerInfo& handler = exceptionHandlers[i];
3182         if (handler.start <= index && handler.end > index) {
3183             exceptionHandlers.remove(i);
3184             return;
3185         }
3186     }
3187
3188     RELEASE_ASSERT_NOT_REACHED();
3189 }
3190
3191 unsigned CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
3192 {
3193     RELEASE_ASSERT(bytecodeOffset < instructions().size());
3194     return ownerScriptExecutable()->firstLine() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset);
3195 }
3196
3197 unsigned CodeBlock::columnNumberForBytecodeOffset(unsigned bytecodeOffset)
3198 {
3199     int divot;
3200     int startOffset;
3201     int endOffset;
3202     unsigned line;
3203     unsigned column;
3204     expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
3205     return column;
3206 }
3207
3208 void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column) const
3209 {
3210     m_unlinkedCode->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
3211     divot += m_sourceOffset;
3212     column += line ? 1 : firstLineColumnOffset();
3213     line += ownerScriptExecutable()->firstLine();
3214 }
3215
3216 bool CodeBlock::hasOpDebugForLineAndColumn(unsigned line, unsigned column)
3217 {
3218     Interpreter* interpreter = vm()->interpreter;
3219     const Instruction* begin = instructions().begin();
3220     const Instruction* end = instructions().end();
3221     for (const Instruction* it = begin; it != end;) {
3222         OpcodeID opcodeID = interpreter->getOpcodeID(it->u.opcode);
3223         if (opcodeID == op_debug) {
3224             unsigned bytecodeOffset = it - begin;
3225             int unused;
3226             unsigned opDebugLine;
3227             unsigned opDebugColumn;
3228             expressionRangeForBytecodeOffset(bytecodeOffset, unused, unused, unused, opDebugLine, opDebugColumn);
3229             if (line == opDebugLine && (column == Breakpoint::unspecifiedColumn || column == opDebugColumn))
3230                 return true;
3231         }
3232         it += opcodeLengths[opcodeID];
3233     }
3234     return false;
3235 }
3236
3237 void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
3238 {
3239     ConcurrentJITLocker locker(m_lock);
3240
3241     m_rareCaseProfiles.shrinkToFit();
3242     m_resultProfiles.shrinkToFit();
3243     
3244     if (shrinkMode == EarlyShrink) {
3245         m_constantRegisters.shrinkToFit();
3246         m_constantsSourceCodeRepresentation.shrinkToFit();
3247         
3248         if (m_rareData) {
3249             m_rareData->m_switchJumpTables.shrinkToFit();
3250             m_rareData->m_stringSwitchJumpTables.shrinkToFit();
3251             m_rareData->m_liveCalleeLocalsAtYield.shrinkToFit();
3252         }
3253     } // else don't shrink these, because we would have already pointed pointers into these tables.
3254 }
3255
3256 #if ENABLE(JIT)
3257 void CodeBlock::linkIncomingCall(ExecState* callerFrame, CallLinkInfo* incoming)
3258 {
3259     noticeIncomingCall(callerFrame);
3260     m_incomingCalls.push(incoming);
3261 }
3262
3263 void CodeBlock::linkIncomingPolymorphicCall(ExecState* callerFrame, PolymorphicCallNode* incoming)
3264 {
3265     noticeIncomingCall(callerFrame);
3266     m_incomingPolymorphicCalls.push(incoming);
3267 }
3268 #endif // ENABLE(JIT)
3269
3270 void CodeBlock::unlinkIncomingCalls()
3271 {
3272     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
3273         m_incomingLLIntCalls.begin()->unlink();
3274 #if ENABLE(JIT)
3275     while (m_incomingCalls.begin() != m_incomingCalls.end())
3276         m_incomingCalls.begin()->unlink(*vm());
3277     while (m_incomingPolymorphicCalls.begin() != m_incomingPolymorphicCalls.end())
3278         m_incomingPolymorphicCalls.begin()->unlink(*vm());
3279 #endif // ENABLE(JIT)
3280 }
3281
3282 void CodeBlock::linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo* incoming)
3283 {
3284     noticeIncomingCall(callerFrame);
3285     m_incomingLLIntCalls.push(incoming);
3286 }
3287
3288 CodeBlock* CodeBlock::newReplacement()
3289 {
3290     return ownerScriptExecutable()->newReplacementCodeBlockFor(specializationKind());
3291 }
3292
3293 #if ENABLE(JIT)
3294 CodeBlock* CodeBlock::replacement()
3295 {
3296     const ClassInfo* classInfo = this->classInfo();
3297
3298     if (classInfo == FunctionCodeBlock::info())
3299         return jsCast<FunctionExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall);
3300
3301     if (classInfo == EvalCodeBlock::info())
3302         return jsCast<EvalExecutable*>(ownerExecutable())->codeBlock();
3303
3304     if (classInfo == ProgramCodeBlock::info())
3305         return jsCast<ProgramExecutable*>(ownerExecutable())->codeBlock();
3306
3307     if (classInfo == ModuleProgramCodeBlock::info())
3308         return jsCast<ModuleProgramExecutable*>(ownerExecutable())->codeBlock();
3309
3310 #if ENABLE(WEBASSEMBLY)
3311     if (classInfo == WebAssemblyCodeBlock::info())
3312         return nullptr;
3313 #endif
3314
3315     RELEASE_ASSERT_NOT_REACHED();
3316     return nullptr;
3317 }
3318
3319 DFG::CapabilityLevel CodeBlock::computeCapabilityLevel()
3320 {
3321     const ClassInfo* classInfo = this->classInfo();
3322
3323     if (classInfo == FunctionCodeBlock::info()) {
3324         if (m_isConstructor)
3325             return DFG::functionForConstructCapabilityLevel(this);
3326         return DFG::functionForCallCapabilityLevel(this);
3327     }
3328
3329     if (classInfo == EvalCodeBlock::info())
3330         return DFG::evalCapabilityLevel(this);
3331
3332     if (classInfo == ProgramCodeBlock::info())
3333         return DFG::programCapabilityLevel(this);
3334
3335     if (classInfo == ModuleProgramCodeBlock::info())
3336         return DFG::programCapabilityLevel(this);
3337
3338 #if ENABLE(WEBASSEMBLY)
3339     if (classInfo == WebAssemblyCodeBlock::info())
3340         return DFG::CannotCompile;
3341 #endif
3342
3343     RELEASE_ASSERT_NOT_REACHED();
3344     return DFG::CannotCompile;
3345 }
3346
3347 #endif // ENABLE(JIT)
3348
3349 void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail)
3350 {
3351 #if !ENABLE(DFG_JIT)
3352     UNUSED_PARAM(mode);
3353     UNUSED_PARAM(detail);
3354 #endif
3355     
3356     CODEBLOCK_LOG_EVENT(this, "jettison", ("due to ", reason, ", counting = ", mode == CountReoptimization, ", detail = ", pointerDump(detail)));
3357
3358     RELEASE_ASSERT(reason != Profiler::NotJettisoned);
3359     
3360 #if ENABLE(DFG_JIT)
3361     if (DFG::shouldDumpDisassembly()) {
3362         dataLog("Jettisoning ", *this);
3363         if (mode == CountReoptimization)
3364             dataLog(" and counting reoptimization");
3365         dataLog(" due to ", reason);
3366         if (detail)
3367             dataLog(", ", *detail);
3368         dataLog(".\n");
3369     }
3370     
3371     if (reason == Profiler::JettisonDueToWeakReference) {
3372         if (DFG::shouldDumpDisassembly()) {
3373             dataLog(*this, " will be jettisoned because of the following dead references:\n");
3374             DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
3375             for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
3376                 DFG::WeakReferenceTransition& transition = dfgCommon->transitions[i];
3377                 JSCell* origin = transition.m_codeOrigin.get();
3378                 JSCell* from = transition.m_from.get();
3379                 JSCell* to = transition.m_to.get();
3380                 if ((!origin || Heap::isMarked(origin)) && Heap::isMarked(from))
3381                     continue;
3382                 dataLog("    Transition under ", RawPointer(origin), ", ", RawPointer(from), " -> ", RawPointer(to), ".\n");
3383             }
3384             for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) {
3385                 JSCell* weak = dfgCommon->weakReferences[i].get();
3386                 if (Heap::isMarked(weak))
3387                     continue;
3388                 dataLog("    Weak reference ", RawPointer(weak), ".\n");
3389             }
3390         }
3391     }
3392 #endif // ENABLE(DFG_JIT)
3393
3394     DeferGCForAWhile deferGC(*heap());
3395     
3396     // We want to accomplish two things here:
3397     // 1) Make sure that if this CodeBlock is on the stack right now, then if we return to it
3398     //    we should OSR exit at the top of the next bytecode instruction after the return.
3399     // 2) Make sure that if we call the owner executable, then we shouldn't call this CodeBlock.
3400
3401 #if ENABLE(DFG_JIT)
3402     if (reason != Profiler::JettisonDueToOldAge) {
3403         if (Profiler::Compilation* compilation = jitCode()->dfgCommon()->compilation.get())
3404             compilation->setJettisonReason(reason, detail);
3405         
3406         // This accomplishes (1), and does its own book-keeping about whether it has already happened.
3407         if (!jitCode()->dfgCommon()->invalidate()) {
3408             // We've already been invalidated.
3409             RELEASE_ASSERT(this != replacement());
3410             return;
3411         }
3412     }
3413     
3414     if (DFG::shouldDumpDisassembly())
3415         dataLog("    Did invalidate ", *this, "\n");
3416     
3417     // Count the reoptimization if that's what the user wanted.
3418     if (mode == CountReoptimization) {
3419         // FIXME: Maybe this should call alternative().
3420         // https://bugs.webkit.org/show_bug.cgi?id=123677
3421         baselineAlternative()->countReoptimization();
3422         if (DFG::shouldDumpDisassembly())
3423             dataLog("    Did count reoptimization for ", *this, "\n");
3424     }
3425     
3426     if (this != replacement()) {
3427         // This means that we were never the entrypoint. This can happen for OSR entry code
3428         // blocks.
3429         return;
3430     }
3431
3432     if (alternative())
3433         alternative()->optimizeAfterWarmUp();
3434
3435     if (reason != Profiler::JettisonDueToOldAge)
3436         tallyFrequentExitSites();
3437 #endif // ENABLE(DFG_JIT)
3438
3439     // This accomplishes (2).
3440     ownerScriptExecutable()->installCode(
3441         m_globalObject->vm(), alternative(), codeType(), specializationKind());
3442
3443 #if ENABLE(DFG_JIT)
3444     if (DFG::shouldDumpDisassembly())
3445         dataLog("    Did install baseline version of ", *this, "\n");
3446 #endif // ENABLE(DFG_JIT)
3447 }
3448
3449 JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin)
3450 {
3451     if (!codeOrigin.inlineCallFrame)
3452         return globalObject();
3453     return codeOrigin.inlineCallFrame->baselineCodeBlock->globalObject();
3454 }
3455
3456 class RecursionCheckFunctor {
3457 public:
3458     RecursionCheckFunctor(CallFrame* startCallFrame, CodeBlock* codeBlock, unsigned depthToCheck)
3459         : m_startCallFrame(startCallFrame)
3460         , m_codeBlock(codeBlock)
3461         , m_depthToCheck(depthToCheck)
3462         , m_foundStartCallFrame(false)
3463         , m_didRecurse(false)
3464     { }
3465
3466     StackVisitor::Status operator()(StackVisitor& visitor) const
3467     {
3468         CallFrame* currentCallFrame = visitor->callFrame();
3469
3470         if (currentCallFrame == m_startCallFrame)
3471             m_foundStartCallFrame = true;
3472
3473         if (m_foundStartCallFrame) {
3474             if (visitor->callFrame()->codeBlock() == m_codeBlock) {
3475                 m_didRecurse = true;
3476                 return StackVisitor::Done;
3477             }
3478
3479             if (!m_depthToCheck--)
3480                 return StackVisitor::Done;
3481         }
3482
3483         return StackVisitor::Continue;
3484     }
3485
3486     bool didRecurse() const { return m_didRecurse; }
3487
3488 private:
3489     CallFrame* m_startCallFrame;
3490     CodeBlock* m_codeBlock;
3491     mutable unsigned m_depthToCheck;
3492     mutable bool m_foundStartCallFrame;
3493     mutable bool m_didRecurse;
3494 };
3495
3496 void CodeBlock::noticeIncomingCall(ExecState* callerFrame)
3497 {
3498     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
3499     
3500     if (Options::verboseCallLink())
3501         dataLog("Noticing call link from ", pointerDump(callerCodeBlock), " to ", *this, "\n");
3502     
3503 #if ENABLE(DFG_JIT)
3504     if (!m_shouldAlwaysBeInlined)
3505         return;
3506     
3507     if (!callerCodeBlock) {
3508         m_shouldAlwaysBeInlined = false;
3509         if (Options::verboseCallLink())
3510             dataLog("    Clearing SABI because caller is native.\n");
3511         return;
3512     }
3513
3514     if (!hasBaselineJITProfiling())
3515         return;
3516
3517     if (!DFG::mightInlineFunction(this))
3518         return;
3519
3520     if (!canInline(capabilityLevelState()))
3521         return;
3522     
3523     if (!DFG::isSmallEnoughToInlineCodeInto(callerCodeBlock)) {
3524         m_shouldAlwaysBeInlined = false;
3525         if (Options::verboseCallLink())
3526             dataLog("    Clearing SABI because caller is too large.\n");
3527         return;
3528     }
3529
3530     if (callerCodeBlock->jitType() == JITCode::InterpreterThunk) {
3531         // If the caller is still in the interpreter, then we can't expect inlining to
3532         // happen anytime soon. Assume it's profitable to optimize it separately. This
3533         // ensures that a function is SABI only if it is called no more frequently than
3534         // any of its callers.
3535         m_shouldAlwaysBeInlined = false;
3536         if (Options::verboseCallLink())
3537             dataLog("    Clearing SABI because caller is in LLInt.\n");
3538         return;
3539     }
3540     
3541     if (JITCode::isOptimizingJIT(callerCodeBlock->jitType())) {
3542         m_shouldAlwaysBeInlined = false;
3543         if (Options::verboseCallLink())
3544             dataLog("    Clearing SABI bcause caller was already optimized.\n");
3545         return;
3546     }
3547     
3548     if (callerCodeBlock->codeType() != FunctionCode) {
3549         // If the caller is either eval or global code, assume that that won't be
3550         // optimized anytime soon. For eval code this is particularly true since we
3551         // delay eval optimization by a *lot*.
3552         m_shouldAlwaysBeInlined = false;
3553         if (Options::verboseCallLink())
3554             dataLog("    Clearing SABI because caller is not a function.\n");
3555         return;
3556     }
3557
3558     // Recursive calls won't be inlined.
3559     RecursionCheckFunctor functor(callerFrame, this, Options::maximumInliningDepth());
3560     vm()->topCallFrame->iterate(functor);
3561
3562     if (functor.didRecurse()) {
3563         if (Options::verboseCallLink())
3564             dataLog("    Clearing SABI because recursion was detected.\n");
3565         m_shouldAlwaysBeInlined = false;
3566         return;
3567     }
3568     
3569     if (callerCodeBlock->capabilityLevelState() == DFG::CapabilityLevelNotSet) {
3570         dataLog("In call from ", *callerCodeBlock, " ", callerFrame->codeOrigin(), " to ", *this, ": caller's DFG capability level is not set.\n");
3571         CRASH();
3572     }
3573     
3574     if (canCompile(callerCodeBlock->capabilityLevelState()))
3575         return;
3576     
3577     if (Options::verboseCallLink())
3578         dataLog("    Clearing SABI because the caller is not a DFG candidate.\n");
3579     
3580     m_shouldAlwaysBeInlined = false;
3581 #endif
3582 }
3583
3584 unsigned CodeBlock::reoptimizationRetryCounter() const
3585 {
3586 #if ENABLE(JIT)
3587     ASSERT(m_reoptimizationRetryCounter <= Options::reoptimizationRetryCounterMax());
3588     return m_reoptimizationRetryCounter;
3589 #else
3590     return 0;
3591 #endif // ENABLE(JIT)
3592 }
3593
3594 #if ENABLE(JIT)
3595 void CodeBlock::setCalleeSaveRegisters(RegisterSet calleeSaveRegisters)
3596 {
3597     m_calleeSaveRegisters = std::make_unique<RegisterAtOffsetList>(calleeSaveRegisters);
3598 }
3599
3600 void CodeBlock::setCalleeSaveRegisters(std::unique_ptr<RegisterAtOffsetList> registerAtOffsetList)
3601 {
3602     m_calleeSaveRegisters = WTFMove(registerAtOffsetList);
3603 }
3604     
3605 static size_t roundCalleeSaveSpaceAsVirtualRegisters(size_t calleeSaveRegisters)
3606 {
3607     static const unsigned cpuRegisterSize = sizeof(void*);
3608     return (WTF::roundUpToMultipleOf(sizeof(Register), calleeSaveRegisters * cpuRegisterSize) / sizeof(Register));
3609
3610 }
3611
3612 size_t CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()
3613 {
3614     return roundCalleeSaveSpaceAsVirtualRegisters(numberOfLLIntBaselineCalleeSaveRegisters());
3615 }
3616
3617 size_t CodeBlock::calleeSaveSpaceAsVirtualRegisters()
3618 {
3619     return roundCalleeSaveSpaceAsVirtualRegisters(m_calleeSaveRegisters->size());
3620 }
3621
3622 void CodeBlock::countReoptimization()
3623 {
3624     m_reoptimizationRetryCounter++;
3625     if (m_reoptimizationRetryCounter > Options::reoptimizationRetryCounterMax())
3626         m_reoptimizationRetryCounter = Options::reoptimizationRetryCounterMax();
3627 }
3628
3629 unsigned CodeBlock::numberOfDFGCompiles()
3630 {
3631     ASSERT(JITCode::isBaselineCode(jitType()));
3632     if (Options::testTheFTL()) {
3633         if (m_didFailFTLCompilation)
3634             return 1000000;
3635         return (m_hasBeenCompiledWithFTL ? 1 : 0) + m_reoptimizationRetryCounter;
3636     }
3637     return (JITCode::isOptimizingJIT(replacement()->jitType()) ? 1 : 0) + m_reoptimizationRetryCounter;
3638 }
3639
3640 int32_t CodeBlock::codeTypeThresholdMultiplier() const
3641 {
3642     if (codeType() == EvalCode)
3643         return Options::evalThresholdMultiplier();
3644     
3645     return 1;
3646 }
3647
3648 double CodeBlock::optimizationThresholdScalingFactor()
3649 {
3650     // This expression arises from doing a least-squares fit of
3651     //
3652     // F[x_] =: a * Sqrt[x + b] + Abs[c * x] + d
3653     //
3654     // against the data points:
3655     //
3656     //    x       F[x_]
3657     //    10       0.9          (smallest reasonable code block)
3658     //   200       1.0          (typical small-ish code block)
3659     //   320       1.2          (something I saw in 3d-cube that I wanted to optimize)
3660     //  1268       5.0          (something I saw in 3d-cube that I didn't want to optimize)
3661     //  4000       5.5          (random large size, used to cause the function to converge to a shallow curve of some sort)
3662     // 10000       6.0          (similar to above)
3663     //
3664     // I achieve the minimization using the following Mathematica code:
3665     //
3666     // MyFunctionTemplate[x_, a_, b_, c_, d_] := a*Sqrt[x + b] + Abs[c*x] + d
3667     //
3668     // samples = {{10, 0.9}, {200, 1}, {320, 1.2}, {1268, 5}, {4000, 5.5}, {10000, 6}}
3669     //
3670     // solution = 
3671     //     Minimize[Plus @@ ((MyFunctionTemplate[#[[1]], a, b, c, d] - #[[2]])^2 & /@ samples),
3672     //         {a, b, c, d}][[2]]
3673     //
3674     // And the code below (to initialize a, b, c, d) is generated by:
3675     //
3676     // Print["const double " <> ToString[#[[1]]] <> " = " <>
3677     //     If[#[[2]] < 0.00001, "0.0", ToString[#[[2]]]] <> ";"] & /@ solution
3678     //
3679     // We've long known the following to be true:
3680     // - Small code blocks are cheap to optimize and so we should do it sooner rather
3681     //   than later.
3682     // - Large code blocks are expensive to optimize and so we should postpone doing so,
3683     //   and sometimes have a large enough threshold that we never optimize them.
3684     // - The difference in cost is not totally linear because (a) just invoking the
3685     //   DFG incurs some base cost and (b) for large code blocks there is enough slop
3686     //   in the correlation between instruction count and the actual compilation cost
3687     //   that for those large blocks, the instruction count should not have a strong
3688     //   influence on our threshold.
3689     //
3690     // I knew the goals but I didn't know how to achieve them; so I picked an interesting
3691     // example where the heuristics were right (code block in 3d-cube with instruction
3692     // count 320, which got compiled early as it should have been) and one where they were
3693     // totally wrong (code block in 3d-cube with instruction count 1268, which was expensive
3694     // to compile and didn't run often enough to warrant compilation in my opinion), and
3695     // then threw in additional data points that represented my own guess of what our
3696     // heuristics should do for some round-numbered examples.
3697     //
3698     // The expression to which I decided to fit the data arose because I started with an
3699     // affine function, and then did two things: put the linear part in an Abs to ensure
3700     // that the fit didn't end up choosing a negative value of c (which would result in
3701     // the function turning over and going negative for large x) and I threw in a Sqrt
3702     // term because Sqrt represents my intution that the function should be more sensitive
3703     // to small changes in small values of x, but less sensitive when x gets large.
3704     
3705     // Note that the current fit essentially eliminates the linear portion of the
3706     // expression (c == 0.0).
3707     const double a = 0.061504;
3708     const double b = 1.02406;
3709     const double c = 0.0;
3710     const double d = 0.825914;
3711     
3712     double instructionCount = this->instructionCount();
3713     
3714     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.
3715     
3716     double result = d + a * sqrt(instructionCount + b) + c * instructionCount;
3717     
3718     result *= codeTypeThresholdMultiplier();
3719     
3720     if (Options::verboseOSR()) {
3721         dataLog(
3722             *this, ": instruction count is ", instructionCount,
3723             ", scaling execution counter by ", result, " * ", codeTypeThresholdMultiplier(),
3724             "\n");
3725     }
3726     return result;
3727 }
3728
3729 static int32_t clipThreshold(double threshold)
3730 {
3731     if (threshold < 1.0)
3732         return 1;
3733     
3734     if (threshold > static_cast<double>(std::numeric_limits<int32_t>::max()))
3735         return std::numeric_limits<int32_t>::max();
3736     
3737     return static_cast<int32_t>(threshold);
3738 }
3739
3740 int32_t CodeBlock::adjustedCounterValue(int32_t desiredThreshold)
3741 {
3742     return clipThreshold(
3743         static_cast<double>(desiredThreshold) *
3744         optimizationThresholdScalingFactor() *
3745         (1 << reoptimizationRetryCounter()));
3746 }
3747
3748 bool CodeBlock::checkIfOptimizationThresholdReached()
3749 {
3750 #if ENABLE(DFG_JIT)
3751     if (DFG::Worklist* worklist = DFG::existingGlobalDFGWorklistOrNull()) {
3752         if (worklist->compilationState(DFG::CompilationKey(this, DFG::DFGMode))
3753             == DFG::Worklist::Compiled) {
3754             optimizeNextInvocation();
3755             return true;
3756         }
3757     }
3758 #endif
3759     
3760     return m_jitExecuteCounter.checkIfThresholdCrossedAndSet(this);
3761 }
3762
3763 void CodeBlock::optimizeNextInvocation()
3764 {
3765     if (Options::verboseOSR())
3766         dataLog(*this, ": Optimizing next invocation.\n");
3767     m_jitExecuteCounter.setNewThreshold(0, this);
3768 }
3769
3770 void CodeBlock::dontOptimizeAnytimeSoon()
3771 {
3772     if (Options::verboseOSR())
3773         dataLog(*this, ": Not optimizing anytime soon.\n");
3774     m_jitExecuteCounter.deferIndefinitely();
3775 }
3776
3777 void CodeBlock::optimizeAfterWarmUp()
3778 {
3779     if (Options::verboseOSR())
3780         dataLog(*this, ": Optimizing after warm-up.\n");
3781 #if ENABLE(DFG_JIT)
3782     m_jitExecuteCounter.setNewThreshold(
3783         adjustedCounterValue(Options::thresholdForOptimizeAfterWarmUp()), this);
3784 #endif
3785 }
3786
3787 void CodeBlock::optimizeAfterLongWarmUp()
3788 {
3789     if (Options::verboseOSR())
3790         dataLog(*this, ": Optimizing after long warm-up.\n");
3791 #if ENABLE(DFG_JIT)
3792     m_jitExecuteCounter.setNewThreshold(
3793         adjustedCounterValue(Options::thresholdForOptimizeAfterLongWarmUp()), this);
3794 #endif
3795 }
3796
3797 void CodeBlock::optimizeSoon()
3798 {
3799     if (Options::verboseOSR())
3800         dataLog(*this, ": Optimizing soon.\n");
3801 #if ENABLE(DFG_JIT)
3802     m_jitExecuteCounter.setNewThreshold(
3803         adjustedCounterValue(Options::thresholdForOptimizeSoon()), this);
3804 #endif
3805 }
3806
3807 void CodeBlock::forceOptimizationSlowPathConcurrently()
3808 {
3809     if (Options::verboseOSR())
3810         dataLog(*this, ": Forcing slow path concurrently.\n");
3811     m_jitExecuteCounter.forceSlowPathConcurrently();
3812 }
3813
3814 #if ENABLE(DFG_JIT)
3815 void CodeBlock::setOptimizationThresholdBasedOnCompilationResult(CompilationResult result)
3816 {
3817     JITCode::JITType type = jitType();
3818     if (type != JITCode::BaselineJIT) {
3819         dataLog(*this, ": expected to have baseline code but have ", type, "\n");
3820         RELEASE_ASSERT_NOT_REACHED();
3821     }
3822     
3823     CodeBlock* theReplacement = replacement();
3824     if ((result == CompilationSuccessful) != (theReplacement != this)) {
3825         dataLog(*this, ": we have result = ", result, " but ");
3826         if (theReplacement == this)
3827             dataLog("we are our own replacement.\n");
3828         else
3829             dataLog("our replacement is ", pointerDump(theReplacement), "\n");
3830         RELEASE_ASSERT_NOT_REACHED();
3831     }
3832     
3833     switch (result) {
3834     case CompilationSuccessful:
3835         RELEASE_ASSERT(JITCode::isOptimizingJIT(replacement()->jitType()));
3836