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