Rename CONCURRENT_JIT/ConcurrentJIT to CONCURRENT_JS/ConcurrentJS
[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.store(false, std::memory_order_relaxed);
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.store(false, std::memory_order_relaxed);
1936
1937     ASSERT(heap()->isDeferred());
1938     ASSERT(m_scopeRegister.isLocal());
1939
1940     ASSERT(m_source);
1941     setNumParameters(unlinkedCodeBlock->numParameters());
1942 }
1943
1944 void CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock,
1945     JSScope* scope)
1946 {
1947     Base::finishCreation(vm);
1948
1949     if (vm.typeProfiler() || vm.controlFlowProfiler())
1950         vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(), ownerExecutable->typeProfilingEndOffset());
1951
1952     setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
1953     if (unlinkedCodeBlock->usesGlobalObject())
1954         m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, this, m_globalObject.get());
1955
1956     for (unsigned i = 0; i < LinkTimeConstantCount; i++) {
1957         LinkTimeConstant type = static_cast<LinkTimeConstant>(i);
1958         if (unsigned registerIndex = unlinkedCodeBlock->registerIndexForLinkTimeConstant(type))
1959             m_constantRegisters[registerIndex].set(*m_vm, this, m_globalObject->jsCellForLinkTimeConstant(type));
1960     }
1961
1962     // We already have the cloned symbol table for the module environment since we need to instantiate
1963     // the module environments before linking the code block. We replace the stored symbol table with the already cloned one.
1964     if (UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock = jsDynamicCast<UnlinkedModuleProgramCodeBlock*>(unlinkedCodeBlock)) {
1965         SymbolTable* clonedSymbolTable = jsCast<ModuleProgramExecutable*>(ownerExecutable)->moduleEnvironmentSymbolTable();
1966         if (m_vm->typeProfiler()) {
1967             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     bool setByMe = !m_visitWeaklyHasBeenCalled.compareExchangeStrong(false, true);
2512     if (!setByMe)
2513         return;
2514
2515     if (Heap::isMarkedConcurrently(this))
2516         return;
2517
2518     if (shouldVisitStrongly()) {
2519         visitor.appendUnbarrieredReadOnlyPointer(this);
2520         return;
2521     }
2522
2523     // There are two things that may use unconditional finalizers: inline cache clearing
2524     // and jettisoning. The probability of us wanting to do at least one of those things
2525     // is probably quite close to 1. So we add one no matter what and when it runs, it
2526     // figures out whether it has any work to do.
2527     visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer);
2528
2529     if (!JITCode::isOptimizingJIT(jitType()))
2530         return;
2531
2532     // If we jettison ourselves we'll install our alternative, so make sure that it
2533     // survives GC even if we don't.
2534     visitor.append(&m_alternative);
2535     
2536     // There are two things that we use weak reference harvesters for: DFG fixpoint for
2537     // jettisoning, and trying to find structures that would be live based on some
2538     // inline cache. So it makes sense to register them regardless.
2539     visitor.addWeakReferenceHarvester(&m_weakReferenceHarvester);
2540
2541 #if ENABLE(DFG_JIT)
2542     // We get here if we're live in the sense that our owner executable is live,
2543     // but we're not yet live for sure in another sense: we may yet decide that this
2544     // code block should be jettisoned based on its outgoing weak references being
2545     // stale. Set a flag to indicate that we're still assuming that we're dead, and
2546     // perform one round of determining if we're live. The GC may determine, based on
2547     // either us marking additional objects, or by other objects being marked for
2548     // other reasons, that this iteration should run again; it will notify us of this
2549     // decision by calling harvestWeakReferences().
2550
2551     m_allTransitionsHaveBeenMarked = false;
2552     propagateTransitions(visitor);
2553
2554     m_jitCode->dfgCommon()->livenessHasBeenProved = false;
2555     determineLiveness(visitor);
2556 #endif // ENABLE(DFG_JIT)
2557 }
2558
2559 size_t CodeBlock::estimatedSize(JSCell* cell)
2560 {
2561     CodeBlock* thisObject = jsCast<CodeBlock*>(cell);
2562     size_t extraMemoryAllocated = thisObject->m_instructions.size() * sizeof(Instruction);
2563     if (thisObject->m_jitCode)
2564         extraMemoryAllocated += thisObject->m_jitCode->size();
2565     return Base::estimatedSize(cell) + extraMemoryAllocated;
2566 }
2567
2568 void CodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor)
2569 {
2570     CodeBlock* thisObject = jsCast<CodeBlock*>(cell);
2571     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
2572     JSCell::visitChildren(thisObject, visitor);
2573     thisObject->visitChildren(visitor);
2574 }
2575
2576 void CodeBlock::visitChildren(SlotVisitor& visitor)
2577 {
2578     // There are two things that may use unconditional finalizers: inline cache clearing
2579     // and jettisoning. The probability of us wanting to do at least one of those things
2580     // is probably quite close to 1. So we add one no matter what and when it runs, it
2581     // figures out whether it has any work to do.
2582     visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer);
2583
2584     if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
2585         visitor.appendUnbarrieredReadOnlyPointer(otherBlock);
2586
2587     if (m_jitCode)
2588         visitor.reportExtraMemoryVisited(m_jitCode->size());
2589     if (m_instructions.size()) {
2590         unsigned refCount = m_instructions.refCount();
2591         RELEASE_ASSERT(refCount);
2592         visitor.reportExtraMemoryVisited(m_instructions.size() * sizeof(Instruction) / refCount);
2593     }
2594
2595     stronglyVisitStrongReferences(visitor);
2596     stronglyVisitWeakReferences(visitor);
2597
2598     m_allTransitionsHaveBeenMarked = false;
2599     propagateTransitions(visitor);
2600 }
2601
2602 bool CodeBlock::shouldVisitStrongly()
2603 {
2604     if (Options::forceCodeBlockLiveness())
2605         return true;
2606
2607     if (shouldJettisonDueToOldAge())
2608         return false;
2609
2610     // Interpreter and Baseline JIT CodeBlocks don't need to be jettisoned when
2611     // their weak references go stale. So if a basline JIT CodeBlock gets
2612     // scanned, we can assume that this means that it's live.
2613     if (!JITCode::isOptimizingJIT(jitType()))
2614         return true;
2615
2616     return false;
2617 }
2618
2619 bool CodeBlock::shouldJettisonDueToWeakReference()
2620 {
2621     if (!JITCode::isOptimizingJIT(jitType()))
2622         return false;
2623     return !Heap::isMarked(this);
2624 }
2625
2626 static std::chrono::milliseconds timeToLive(JITCode::JITType jitType)
2627 {
2628     if (UNLIKELY(Options::useEagerCodeBlockJettisonTiming())) {
2629         switch (jitType) {
2630         case JITCode::InterpreterThunk:
2631             return std::chrono::milliseconds(10);
2632         case JITCode::BaselineJIT:
2633             return std::chrono::milliseconds(10 + 20);
2634         case JITCode::DFGJIT:
2635             return std::chrono::milliseconds(40);
2636         case JITCode::FTLJIT:
2637             return std::chrono::milliseconds(120);
2638         default:
2639             return std::chrono::milliseconds::max();
2640         }
2641     }
2642
2643     switch (jitType) {
2644     case JITCode::InterpreterThunk:
2645         return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::seconds(5));
2646     case JITCode::BaselineJIT:
2647         // Effectively 10 additional seconds, since BaselineJIT and
2648         // InterpreterThunk share a CodeBlock.
2649         return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::seconds(5 + 10));
2650     case JITCode::DFGJIT:
2651         return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::seconds(20));
2652     case JITCode::FTLJIT:
2653         return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::seconds(60));
2654     default:
2655         return std::chrono::milliseconds::max();
2656     }
2657 }
2658
2659 bool CodeBlock::shouldJettisonDueToOldAge()
2660 {
2661     if (Heap::isMarkedConcurrently(this))
2662         return false;
2663
2664     if (UNLIKELY(Options::forceCodeBlockToJettisonDueToOldAge()))
2665         return true;
2666     
2667     if (timeSinceCreation() < timeToLive(jitType()))
2668         return false;
2669     
2670     return true;
2671 }
2672
2673 #if ENABLE(DFG_JIT)
2674 static bool shouldMarkTransition(DFG::WeakReferenceTransition& transition)
2675 {
2676     if (transition.m_codeOrigin && !Heap::isMarkedConcurrently(transition.m_codeOrigin.get()))
2677         return false;
2678     
2679     if (!Heap::isMarkedConcurrently(transition.m_from.get()))
2680         return false;
2681     
2682     return true;
2683 }
2684 #endif // ENABLE(DFG_JIT)
2685
2686 void CodeBlock::propagateTransitions(SlotVisitor& visitor)
2687 {
2688     UNUSED_PARAM(visitor);
2689
2690     if (m_allTransitionsHaveBeenMarked)
2691         return;
2692
2693     bool allAreMarkedSoFar = true;
2694         
2695     Interpreter* interpreter = m_vm->interpreter;
2696     if (jitType() == JITCode::InterpreterThunk) {
2697         const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
2698         for (size_t i = 0; i < propertyAccessInstructions.size(); ++i) {
2699             Instruction* instruction = &instructions()[propertyAccessInstructions[i]];
2700             switch (interpreter->getOpcodeID(instruction[0].u.opcode)) {
2701             case op_put_by_id: {
2702                 StructureID oldStructureID = instruction[4].u.structureID;
2703                 StructureID newStructureID = instruction[6].u.structureID;
2704                 if (!oldStructureID || !newStructureID)
2705                     break;
2706                 Structure* oldStructure =
2707                     m_vm->heap.structureIDTable().get(oldStructureID);
2708                 Structure* newStructure =
2709                     m_vm->heap.structureIDTable().get(newStructureID);
2710                 if (Heap::isMarkedConcurrently(oldStructure))
2711                     visitor.appendUnbarrieredReadOnlyPointer(newStructure);
2712                 else
2713                     allAreMarkedSoFar = false;
2714                 break;
2715             }
2716             default:
2717                 break;
2718             }
2719         }
2720     }
2721
2722 #if ENABLE(JIT)
2723     if (JITCode::isJIT(jitType())) {
2724         for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter)
2725             allAreMarkedSoFar &= (*iter)->propagateTransitions(visitor);
2726     }
2727 #endif // ENABLE(JIT)
2728     
2729 #if ENABLE(DFG_JIT)
2730     if (JITCode::isOptimizingJIT(jitType())) {
2731         DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
2732         for (auto& weakReference : dfgCommon->weakStructureReferences)
2733             allAreMarkedSoFar &= weakReference->markIfCheap(visitor);
2734         
2735         for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
2736             if (shouldMarkTransition(dfgCommon->transitions[i])) {
2737                 // If the following three things are live, then the target of the
2738                 // transition is also live:
2739                 //
2740                 // - This code block. We know it's live already because otherwise
2741                 //   we wouldn't be scanning ourselves.
2742                 //
2743                 // - The code origin of the transition. Transitions may arise from
2744                 //   code that was inlined. They are not relevant if the user's
2745                 //   object that is required for the inlinee to run is no longer
2746                 //   live.
2747                 //
2748                 // - The source of the transition. The transition checks if some
2749                 //   heap location holds the source, and if so, stores the target.
2750                 //   Hence the source must be live for the transition to be live.
2751                 //
2752                 // We also short-circuit the liveness if the structure is harmless
2753                 // to mark (i.e. its global object and prototype are both already
2754                 // live).
2755                 
2756                 visitor.append(&dfgCommon->transitions[i].m_to);
2757             } else
2758                 allAreMarkedSoFar = false;
2759         }
2760     }
2761 #endif // ENABLE(DFG_JIT)
2762     
2763     if (allAreMarkedSoFar)
2764         m_allTransitionsHaveBeenMarked = true;
2765 }
2766
2767 void CodeBlock::determineLiveness(SlotVisitor& visitor)
2768 {
2769     UNUSED_PARAM(visitor);
2770     
2771 #if ENABLE(DFG_JIT)
2772     // Check if we have any remaining work to do.
2773     DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
2774     if (dfgCommon->livenessHasBeenProved)
2775         return;
2776     
2777     // Now check all of our weak references. If all of them are live, then we
2778     // have proved liveness and so we scan our strong references. If at end of
2779     // GC we still have not proved liveness, then this code block is toast.
2780     bool allAreLiveSoFar = true;
2781     for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) {
2782         if (!Heap::isMarkedConcurrently(dfgCommon->weakReferences[i].get())) {
2783             allAreLiveSoFar = false;
2784             break;
2785         }
2786     }
2787     if (allAreLiveSoFar) {
2788         for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i) {
2789             if (!Heap::isMarkedConcurrently(dfgCommon->weakStructureReferences[i].get())) {
2790                 allAreLiveSoFar = false;
2791                 break;
2792             }
2793         }
2794     }
2795     
2796     // If some weak references are dead, then this fixpoint iteration was
2797     // unsuccessful.
2798     if (!allAreLiveSoFar)
2799         return;
2800     
2801     // All weak references are live. Record this information so we don't
2802     // come back here again, and scan the strong references.
2803     dfgCommon->livenessHasBeenProved = true;
2804     visitor.appendUnbarrieredReadOnlyPointer(this);
2805 #endif // ENABLE(DFG_JIT)
2806 }
2807
2808 void CodeBlock::WeakReferenceHarvester::visitWeakReferences(SlotVisitor& visitor)
2809 {
2810     CodeBlock* codeBlock =
2811         bitwise_cast<CodeBlock*>(
2812             bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_weakReferenceHarvester));
2813
2814     codeBlock->propagateTransitions(visitor);
2815     codeBlock->determineLiveness(visitor);
2816 }
2817
2818 void CodeBlock::clearLLIntGetByIdCache(Instruction* instruction)
2819 {
2820     instruction[0].u.opcode = LLInt::getOpcode(op_get_by_id);
2821     instruction[4].u.pointer = nullptr;
2822     instruction[5].u.pointer = nullptr;
2823     instruction[6].u.pointer = nullptr;
2824 }
2825
2826 void CodeBlock::finalizeLLIntInlineCaches()
2827 {
2828 #if ENABLE(WEBASSEMBLY)
2829     if (m_ownerExecutable->isWebAssemblyExecutable())
2830         return;
2831 #endif
2832
2833     Interpreter* interpreter = m_vm->interpreter;
2834     const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
2835     for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
2836         Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]];
2837         switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
2838         case op_get_by_id:
2839         case op_get_by_id_proto_load:
2840         case op_get_by_id_unset: {
2841             StructureID oldStructureID = curInstruction[4].u.structureID;
2842             if (!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID)))
2843                 break;
2844             if (Options::verboseOSR())
2845                 dataLogF("Clearing LLInt property access.\n");
2846             clearLLIntGetByIdCache(curInstruction);
2847             break;
2848         }
2849         case op_put_by_id: {
2850             StructureID oldStructureID = curInstruction[4].u.structureID;
2851             StructureID newStructureID = curInstruction[6].u.structureID;
2852             StructureChain* chain = curInstruction[7].u.structureChain.get();
2853             if ((!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID))) &&
2854                 (!newStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(newStructureID))) &&
2855                 (!chain || Heap::isMarked(chain)))
2856                 break;
2857             if (Options::verboseOSR())
2858                 dataLogF("Clearing LLInt put transition.\n");
2859             curInstruction[4].u.structureID = 0;
2860             curInstruction[5].u.operand = 0;
2861             curInstruction[6].u.structureID = 0;
2862             curInstruction[7].u.structureChain.clear();
2863             break;
2864         }
2865         case op_get_array_length:
2866             break;
2867         case op_to_this:
2868             if (!curInstruction[2].u.structure || Heap::isMarked(curInstruction[2].u.structure.get()))
2869                 break;
2870             if (Options::verboseOSR())
2871                 dataLogF("Clearing LLInt to_this with structure %p.\n", curInstruction[2].u.structure.get());
2872             curInstruction[2].u.structure.clear();
2873             curInstruction[3].u.toThisStatus = merge(
2874                 curInstruction[3].u.toThisStatus, ToThisClearedByGC);
2875             break;
2876         case op_create_this: {
2877             auto& cacheWriteBarrier = curInstruction[4].u.jsCell;
2878             if (!cacheWriteBarrier || cacheWriteBarrier.unvalidatedGet() == JSCell::seenMultipleCalleeObjects())
2879                 break;
2880             JSCell* cachedFunction = cacheWriteBarrier.get();
2881             if (Heap::isMarked(cachedFunction))
2882                 break;
2883             if (Options::verboseOSR())
2884                 dataLogF("Clearing LLInt create_this with cached callee %p.\n", cachedFunction);
2885             cacheWriteBarrier.clear();
2886             break;
2887         }
2888         case op_resolve_scope: {
2889             // Right now this isn't strictly necessary. Any symbol tables that this will refer to
2890             // are for outer functions, and we refer to those functions strongly, and they refer
2891             // to the symbol table strongly. But it's nice to be on the safe side.
2892             WriteBarrierBase<SymbolTable>& symbolTable = curInstruction[6].u.symbolTable;
2893             if (!symbolTable || Heap::isMarked(symbolTable.get()))
2894                 break;
2895             if (Options::verboseOSR())
2896                 dataLogF("Clearing dead symbolTable %p.\n", symbolTable.get());
2897             symbolTable.clear();
2898             break;
2899         }
2900         case op_get_from_scope:
2901         case op_put_to_scope: {
2902             GetPutInfo getPutInfo = GetPutInfo(curInstruction[4].u.operand);
2903             if (getPutInfo.resolveType() == GlobalVar || getPutInfo.resolveType() == GlobalVarWithVarInjectionChecks 
2904                 || getPutInfo.resolveType() == LocalClosureVar || getPutInfo.resolveType() == GlobalLexicalVar || getPutInfo.resolveType() == GlobalLexicalVarWithVarInjectionChecks)
2905                 continue;
2906             WriteBarrierBase<Structure>& structure = curInstruction[5].u.structure;
2907             if (!structure || Heap::isMarked(structure.get()))
2908                 break;
2909             if (Options::verboseOSR())
2910                 dataLogF("Clearing scope access with structure %p.\n", structure.get());
2911             structure.clear();
2912             break;
2913         }
2914         default:
2915             OpcodeID opcodeID = interpreter->getOpcodeID(curInstruction[0].u.opcode);
2916             ASSERT_WITH_MESSAGE_UNUSED(opcodeID, false, "Unhandled opcode in CodeBlock::finalizeUnconditionally, %s(%d) at bc %u", opcodeNames[opcodeID], opcodeID, propertyAccessInstructions[i]);
2917         }
2918     }
2919
2920     // We can't just remove all the sets when we clear the caches since we might have created a watchpoint set
2921     // then cleared the cache without GCing in between.
2922     m_llintGetByIdWatchpointMap.removeIf([](const StructureWatchpointMap::KeyValuePairType& pair) -> bool {
2923         return !Heap::isMarked(pair.key);
2924     });
2925
2926     for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
2927         if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
2928             if (Options::verboseOSR())
2929                 dataLog("Clearing LLInt call from ", *this, "\n");
2930             m_llintCallLinkInfos[i].unlink();
2931         }
2932         if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get()))
2933             m_llintCallLinkInfos[i].lastSeenCallee.clear();
2934     }
2935 }
2936
2937 void CodeBlock::finalizeBaselineJITInlineCaches()
2938 {
2939 #if ENABLE(JIT)
2940     for (auto iter = callLinkInfosBegin(); !!iter; ++iter)
2941         (*iter)->visitWeak(*vm());
2942
2943     for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
2944         StructureStubInfo& stubInfo = **iter;
2945         stubInfo.visitWeakReferences(this);
2946     }
2947 #endif
2948 }
2949
2950 void CodeBlock::UnconditionalFinalizer::finalizeUnconditionally()
2951 {
2952     CodeBlock* codeBlock = bitwise_cast<CodeBlock*>(
2953         bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_unconditionalFinalizer));
2954
2955 #if ENABLE(DFG_JIT)
2956     if (codeBlock->shouldJettisonDueToWeakReference()) {
2957         codeBlock->jettison(Profiler::JettisonDueToWeakReference);
2958         return;
2959     }
2960 #endif // ENABLE(DFG_JIT)
2961
2962     if (codeBlock->shouldJettisonDueToOldAge()) {
2963         codeBlock->jettison(Profiler::JettisonDueToOldAge);
2964         return;
2965     }
2966
2967     if (JITCode::couldBeInterpreted(codeBlock->jitType()))
2968         codeBlock->finalizeLLIntInlineCaches();
2969
2970 #if ENABLE(JIT)
2971     if (!!codeBlock->jitCode())
2972         codeBlock->finalizeBaselineJITInlineCaches();
2973 #endif
2974 }
2975
2976 void CodeBlock::getStubInfoMap(const ConcurrentJSLocker&, StubInfoMap& result)
2977 {
2978 #if ENABLE(JIT)
2979     if (JITCode::isJIT(jitType()))
2980         toHashMap(m_stubInfos, getStructureStubInfoCodeOrigin, result);
2981 #else
2982     UNUSED_PARAM(result);
2983 #endif
2984 }
2985
2986 void CodeBlock::getStubInfoMap(StubInfoMap& result)
2987 {
2988     ConcurrentJSLocker locker(m_lock);
2989     getStubInfoMap(locker, result);
2990 }
2991
2992 void CodeBlock::getCallLinkInfoMap(const ConcurrentJSLocker&, CallLinkInfoMap& result)
2993 {
2994 #if ENABLE(JIT)
2995     if (JITCode::isJIT(jitType()))
2996         toHashMap(m_callLinkInfos, getCallLinkInfoCodeOrigin, result);
2997 #else
2998     UNUSED_PARAM(result);
2999 #endif
3000 }
3001
3002 void CodeBlock::getCallLinkInfoMap(CallLinkInfoMap& result)
3003 {
3004     ConcurrentJSLocker locker(m_lock);
3005     getCallLinkInfoMap(locker, result);
3006 }
3007
3008 void CodeBlock::getByValInfoMap(const ConcurrentJSLocker&, ByValInfoMap& result)
3009 {
3010 #if ENABLE(JIT)
3011     if (JITCode::isJIT(jitType())) {
3012         for (auto* byValInfo : m_byValInfos)
3013             result.add(CodeOrigin(byValInfo->bytecodeIndex), byValInfo);
3014     }
3015 #else
3016     UNUSED_PARAM(result);
3017 #endif
3018 }
3019
3020 void CodeBlock::getByValInfoMap(ByValInfoMap& result)
3021 {
3022     ConcurrentJSLocker locker(m_lock);
3023     getByValInfoMap(locker, result);
3024 }
3025
3026 #if ENABLE(JIT)
3027 StructureStubInfo* CodeBlock::addStubInfo(AccessType accessType)
3028 {
3029     ConcurrentJSLocker locker(m_lock);
3030     return m_stubInfos.add(accessType);
3031 }
3032
3033 JITAddIC* CodeBlock::addJITAddIC(ArithProfile* arithProfile)
3034 {
3035     return m_addICs.add(arithProfile);
3036 }
3037
3038 JITMulIC* CodeBlock::addJITMulIC(ArithProfile* arithProfile)
3039 {
3040     return m_mulICs.add(arithProfile);
3041 }
3042
3043 JITSubIC* CodeBlock::addJITSubIC(ArithProfile* arithProfile)
3044 {
3045     return m_subICs.add(arithProfile);
3046 }
3047
3048 JITNegIC* CodeBlock::addJITNegIC(ArithProfile* arithProfile)
3049 {
3050     return m_negICs.add(arithProfile);
3051 }
3052
3053 StructureStubInfo* CodeBlock::findStubInfo(CodeOrigin codeOrigin)
3054 {
3055     for (StructureStubInfo* stubInfo : m_stubInfos) {
3056         if (stubInfo->codeOrigin == codeOrigin)
3057             return stubInfo;
3058     }
3059     return nullptr;
3060 }
3061
3062 ByValInfo* CodeBlock::addByValInfo()
3063 {
3064     ConcurrentJSLocker locker(m_lock);
3065     return m_byValInfos.add();
3066 }
3067
3068 CallLinkInfo* CodeBlock::addCallLinkInfo()
3069 {
3070     ConcurrentJSLocker locker(m_lock);
3071     return m_callLinkInfos.add();
3072 }
3073
3074 CallLinkInfo* CodeBlock::getCallLinkInfoForBytecodeIndex(unsigned index)
3075 {
3076     for (auto iter = m_callLinkInfos.begin(); !!iter; ++iter) {
3077         if ((*iter)->codeOrigin() == CodeOrigin(index))
3078             return *iter;
3079     }
3080     return nullptr;
3081 }
3082
3083 void CodeBlock::resetJITData()
3084 {
3085     RELEASE_ASSERT(!JITCode::isJIT(jitType()));
3086     ConcurrentJSLocker locker(m_lock);
3087     
3088     // We can clear these because no other thread will have references to any stub infos, call
3089     // link infos, or by val infos if we don't have JIT code. Attempts to query these data
3090     // structures using the concurrent API (getStubInfoMap and friends) will return nothing if we
3091     // don't have JIT code.
3092     m_stubInfos.clear();
3093     m_callLinkInfos.clear();
3094     m_byValInfos.clear();
3095     
3096     // We can clear this because the DFG's queries to these data structures are guarded by whether
3097     // there is JIT code.
3098     m_rareCaseProfiles.clear();
3099 }
3100 #endif
3101
3102 void CodeBlock::visitOSRExitTargets(SlotVisitor& visitor)
3103 {
3104     // We strongly visit OSR exits targets because we don't want to deal with
3105     // the complexity of generating an exit target CodeBlock on demand and
3106     // guaranteeing that it matches the details of the CodeBlock we compiled
3107     // the OSR exit against.
3108
3109     visitor.append(&m_alternative);
3110
3111 #if ENABLE(DFG_JIT)
3112     DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
3113     if (dfgCommon->inlineCallFrames) {
3114         for (auto* inlineCallFrame : *dfgCommon->inlineCallFrames) {
3115             ASSERT(inlineCallFrame->baselineCodeBlock);
3116             visitor.append(&inlineCallFrame->baselineCodeBlock);
3117         }
3118     }
3119 #endif
3120 }
3121
3122 void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
3123 {
3124     visitor.append(&m_globalObject);
3125     visitor.append(&m_ownerExecutable);
3126     visitor.append(&m_unlinkedCode);
3127     if (m_rareData)
3128         m_rareData->m_evalCodeCache.visitAggregate(visitor);
3129     visitor.appendValues(m_constantRegisters.data(), m_constantRegisters.size());
3130     for (size_t i = 0; i < m_functionExprs.size(); ++i)
3131         visitor.append(&m_functionExprs[i]);
3132     for (size_t i = 0; i < m_functionDecls.size(); ++i)
3133         visitor.append(&m_functionDecls[i]);
3134     for (unsigned i = 0; i < m_objectAllocationProfiles.size(); ++i)
3135         m_objectAllocationProfiles[i].visitAggregate(visitor);
3136
3137 #if ENABLE(JIT)
3138     for (ByValInfo* byValInfo : m_byValInfos)
3139         visitor.append(&byValInfo->cachedSymbol);
3140 #endif
3141
3142 #if ENABLE(DFG_JIT)
3143     if (JITCode::isOptimizingJIT(jitType()))
3144         visitOSRExitTargets(visitor);
3145 #endif
3146
3147     updateAllPredictions();
3148 }
3149
3150 void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor)
3151 {
3152     UNUSED_PARAM(visitor);
3153
3154 #if ENABLE(DFG_JIT)
3155     if (!JITCode::isOptimizingJIT(jitType()))
3156         return;
3157     
3158     DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
3159
3160     for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
3161         if (!!dfgCommon->transitions[i].m_codeOrigin)
3162             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.
3163         visitor.append(&dfgCommon->transitions[i].m_from);
3164         visitor.append(&dfgCommon->transitions[i].m_to);
3165     }
3166     
3167     for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i)
3168         visitor.append(&dfgCommon->weakReferences[i]);
3169
3170     for (unsigned i = 0; i < dfgCommon->weakStructureReferences.size(); ++i)
3171         visitor.append(&dfgCommon->weakStructureReferences[i]);
3172
3173     dfgCommon->livenessHasBeenProved = true;
3174 #endif    
3175 }
3176
3177 CodeBlock* CodeBlock::baselineAlternative()
3178 {
3179 #if ENABLE(JIT)
3180     CodeBlock* result = this;
3181     while (result->alternative())
3182         result = result->alternative();
3183     RELEASE_ASSERT(result);
3184     RELEASE_ASSERT(JITCode::isBaselineCode(result->jitType()) || result->jitType() == JITCode::None);
3185     return result;
3186 #else
3187     return this;
3188 #endif
3189 }
3190
3191 CodeBlock* CodeBlock::baselineVersion()
3192 {
3193 #if ENABLE(JIT)
3194     if (JITCode::isBaselineCode(jitType()))
3195         return this;
3196     CodeBlock* result = replacement();
3197     if (!result) {
3198         // This can happen if we're creating the original CodeBlock for an executable.
3199         // Assume that we're the baseline CodeBlock.
3200         RELEASE_ASSERT(jitType() == JITCode::None);
3201         return this;
3202     }
3203     result = result->baselineAlternative();
3204     return result;
3205 #else
3206     return this;
3207 #endif
3208 }
3209
3210 #if ENABLE(JIT)
3211 bool CodeBlock::hasOptimizedReplacement(JITCode::JITType typeToReplace)
3212 {
3213     return JITCode::isHigherTier(replacement()->jitType(), typeToReplace);
3214 }
3215
3216 bool CodeBlock::hasOptimizedReplacement()
3217 {
3218     return hasOptimizedReplacement(jitType());
3219 }
3220 #endif
3221
3222 HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler requiredHandler)
3223 {
3224     RELEASE_ASSERT(bytecodeOffset < instructions().size());
3225     return handlerForIndex(bytecodeOffset, requiredHandler);
3226 }
3227
3228 HandlerInfo* CodeBlock::handlerForIndex(unsigned index, RequiredHandler requiredHandler)
3229 {
3230     if (!m_rareData)
3231         return 0;
3232     return HandlerInfo::handlerForIndex(m_rareData->m_exceptionHandlers, index, requiredHandler);
3233 }
3234
3235 CallSiteIndex CodeBlock::newExceptionHandlingCallSiteIndex(CallSiteIndex originalCallSite)
3236 {
3237 #if ENABLE(DFG_JIT)
3238     RELEASE_ASSERT(JITCode::isOptimizingJIT(jitType()));
3239     RELEASE_ASSERT(canGetCodeOrigin(originalCallSite));
3240     ASSERT(!!handlerForIndex(originalCallSite.bits()));
3241     CodeOrigin originalOrigin = codeOrigin(originalCallSite);
3242     return m_jitCode->dfgCommon()->addUniqueCallSiteIndex(originalOrigin);
3243 #else
3244     // We never create new on-the-fly exception handling
3245     // call sites outside the DFG/FTL inline caches.
3246     UNUSED_PARAM(originalCallSite);
3247     RELEASE_ASSERT_NOT_REACHED();
3248     return CallSiteIndex(0u);
3249 #endif
3250 }
3251
3252 void CodeBlock::removeExceptionHandlerForCallSite(CallSiteIndex callSiteIndex)
3253 {
3254     RELEASE_ASSERT(m_rareData);
3255     Vector<HandlerInfo>& exceptionHandlers = m_rareData->m_exceptionHandlers;
3256     unsigned index = callSiteIndex.bits();
3257     for (size_t i = 0; i < exceptionHandlers.size(); ++i) {
3258         HandlerInfo& handler = exceptionHandlers[i];
3259         if (handler.start <= index && handler.end > index) {
3260             exceptionHandlers.remove(i);
3261             return;
3262         }
3263     }
3264
3265     RELEASE_ASSERT_NOT_REACHED();
3266 }
3267
3268 unsigned CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
3269 {
3270     RELEASE_ASSERT(bytecodeOffset < instructions().size());
3271     return ownerScriptExecutable()->firstLine() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset);
3272 }
3273
3274 unsigned CodeBlock::columnNumberForBytecodeOffset(unsigned bytecodeOffset)
3275 {
3276     int divot;
3277     int startOffset;
3278     int endOffset;
3279     unsigned line;
3280     unsigned column;
3281     expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
3282     return column;
3283 }
3284
3285 void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column) const
3286 {
3287     m_unlinkedCode->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset, line, column);
3288     divot += m_sourceOffset;
3289     column += line ? 1 : firstLineColumnOffset();
3290     line += ownerScriptExecutable()->firstLine();
3291 }
3292
3293 bool CodeBlock::hasOpDebugForLineAndColumn(unsigned line, unsigned column)
3294 {
3295     Interpreter* interpreter = vm()->interpreter;
3296     const Instruction* begin = instructions().begin();
3297     const Instruction* end = instructions().end();
3298     for (const Instruction* it = begin; it != end;) {
3299         OpcodeID opcodeID = interpreter->getOpcodeID(it->u.opcode);
3300         if (opcodeID == op_debug) {
3301             unsigned bytecodeOffset = it - begin;
3302             int unused;
3303             unsigned opDebugLine;
3304             unsigned opDebugColumn;
3305             expressionRangeForBytecodeOffset(bytecodeOffset, unused, unused, unused, opDebugLine, opDebugColumn);
3306             if (line == opDebugLine && (column == Breakpoint::unspecifiedColumn || column == opDebugColumn))
3307                 return true;
3308         }
3309         it += opcodeLengths[opcodeID];
3310     }
3311     return false;
3312 }
3313
3314 void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
3315 {
3316     ConcurrentJSLocker locker(m_lock);
3317
3318     m_rareCaseProfiles.shrinkToFit();
3319     
3320     if (shrinkMode == EarlyShrink) {
3321         m_constantRegisters.shrinkToFit();
3322         m_constantsSourceCodeRepresentation.shrinkToFit();
3323         
3324         if (m_rareData) {
3325             m_rareData->m_switchJumpTables.shrinkToFit();
3326             m_rareData->m_stringSwitchJumpTables.shrinkToFit();
3327         }
3328     } // else don't shrink these, because we would have already pointed pointers into these tables.
3329 }
3330
3331 #if ENABLE(JIT)
3332 void CodeBlock::linkIncomingCall(ExecState* callerFrame, CallLinkInfo* incoming)
3333 {
3334     noticeIncomingCall(callerFrame);
3335     m_incomingCalls.push(incoming);
3336 }
3337
3338 void CodeBlock::linkIncomingPolymorphicCall(ExecState* callerFrame, PolymorphicCallNode* incoming)
3339 {
3340     noticeIncomingCall(callerFrame);
3341     m_incomingPolymorphicCalls.push(incoming);
3342 }
3343 #endif // ENABLE(JIT)
3344
3345 void CodeBlock::unlinkIncomingCalls()
3346 {
3347     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
3348         m_incomingLLIntCalls.begin()->unlink();
3349 #if ENABLE(JIT)
3350     while (m_incomingCalls.begin() != m_incomingCalls.end())
3351         m_incomingCalls.begin()->unlink(*vm());
3352     while (m_incomingPolymorphicCalls.begin() != m_incomingPolymorphicCalls.end())
3353         m_incomingPolymorphicCalls.begin()->unlink(*vm());
3354 #endif // ENABLE(JIT)
3355 }
3356
3357 void CodeBlock::linkIncomingCall(ExecState* callerFrame, LLIntCallLinkInfo* incoming)
3358 {
3359     noticeIncomingCall(callerFrame);
3360     m_incomingLLIntCalls.push(incoming);
3361 }
3362
3363 CodeBlock* CodeBlock::newReplacement()
3364 {
3365     return ownerScriptExecutable()->newReplacementCodeBlockFor(specializationKind());
3366 }
3367
3368 #if ENABLE(JIT)
3369 CodeBlock* CodeBlock::replacement()
3370 {
3371     const ClassInfo* classInfo = this->classInfo();
3372
3373     if (classInfo == FunctionCodeBlock::info())
3374         return jsCast<FunctionExecutable*>(ownerExecutable())->codeBlockFor(m_isConstructor ? CodeForConstruct : CodeForCall);
3375
3376     if (classInfo == EvalCodeBlock::info())
3377         return jsCast<EvalExecutable*>(ownerExecutable())->codeBlock();
3378
3379     if (classInfo == ProgramCodeBlock::info())
3380         return jsCast<ProgramExecutable*>(ownerExecutable())->codeBlock();
3381
3382     if (classInfo == ModuleProgramCodeBlock::info())
3383         return jsCast<ModuleProgramExecutable*>(ownerExecutable())->codeBlock();
3384
3385 #if ENABLE(WEBASSEMBLY)
3386     if (classInfo == WebAssemblyCodeBlock::info())
3387         return nullptr;
3388 #endif
3389
3390     RELEASE_ASSERT_NOT_REACHED();
3391     return nullptr;
3392 }
3393
3394 DFG::CapabilityLevel CodeBlock::computeCapabilityLevel()
3395 {
3396     const ClassInfo* classInfo = this->classInfo();
3397
3398     if (classInfo == FunctionCodeBlock::info()) {
3399         if (m_isConstructor)
3400             return DFG::functionForConstructCapabilityLevel(this);
3401         return DFG::functionForCallCapabilityLevel(this);
3402     }
3403
3404     if (classInfo == EvalCodeBlock::info())
3405         return DFG::evalCapabilityLevel(this);
3406
3407     if (classInfo == ProgramCodeBlock::info())
3408         return DFG::programCapabilityLevel(this);
3409
3410     if (classInfo == ModuleProgramCodeBlock::info())
3411         return DFG::programCapabilityLevel(this);
3412
3413 #if ENABLE(WEBASSEMBLY)
3414     if (classInfo == WebAssemblyCodeBlock::info())
3415         return DFG::CannotCompile;
3416 #endif
3417
3418     RELEASE_ASSERT_NOT_REACHED();
3419     return DFG::CannotCompile;
3420 }
3421
3422 #endif // ENABLE(JIT)
3423
3424 void CodeBlock::jettison(Profiler::JettisonReason reason, ReoptimizationMode mode, const FireDetail* detail)
3425 {
3426 #if !ENABLE(DFG_JIT)
3427     UNUSED_PARAM(mode);
3428     UNUSED_PARAM(detail);
3429 #endif
3430     
3431     CODEBLOCK_LOG_EVENT(this, "jettison", ("due to ", reason, ", counting = ", mode == CountReoptimization, ", detail = ", pointerDump(detail)));
3432
3433     RELEASE_ASSERT(reason != Profiler::NotJettisoned);
3434     
3435 #if ENABLE(DFG_JIT)
3436     if (DFG::shouldDumpDisassembly()) {
3437         dataLog("Jettisoning ", *this);
3438         if (mode == CountReoptimization)
3439             dataLog(" and counting reoptimization");
3440         dataLog(" due to ", reason);
3441         if (detail)
3442             dataLog(", ", *detail);
3443         dataLog(".\n");
3444     }
3445     
3446     if (reason == Profiler::JettisonDueToWeakReference) {
3447         if (DFG::shouldDumpDisassembly()) {
3448             dataLog(*this, " will be jettisoned because of the following dead references:\n");
3449             DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();
3450             for (unsigned i = 0; i < dfgCommon->transitions.size(); ++i) {
3451                 DFG::WeakReferenceTransition& transition = dfgCommon->transitions[i];
3452                 JSCell* origin = transition.m_codeOrigin.get();
3453                 JSCell* from = transition.m_from.get();
3454                 JSCell* to = transition.m_to.get();
3455                 if ((!origin || Heap::isMarked(origin)) && Heap::isMarked(from))
3456                     continue;
3457                 dataLog("    Transition under ", RawPointer(origin), ", ", RawPointer(from), " -> ", RawPointer(to), ".\n");
3458             }
3459             for (unsigned i = 0; i < dfgCommon->weakReferences.size(); ++i) {
3460                 JSCell* weak = dfgCommon->weakReferences[i].get();
3461                 if (Heap::isMarked(weak))
3462                     continue;
3463                 dataLog("    Weak reference ", RawPointer(weak), ".\n");
3464             }
3465         }
3466     }
3467 #endif // ENABLE(DFG_JIT)
3468
3469     DeferGCForAWhile deferGC(*heap());
3470     
3471     // We want to accomplish two things here:
3472     // 1) Make sure that if this CodeBlock is on the stack right now, then if we return to it
3473     //    we should OSR exit at the top of the next bytecode instruction after the return.
3474     // 2) Make sure that if we call the owner executable, then we shouldn't call this CodeBlock.
3475
3476 #if ENABLE(DFG_JIT)
3477     if (reason != Profiler::JettisonDueToOldAge) {
3478         if (Profiler::Compilation* compilation = jitCode()->dfgCommon()->compilation.get())
3479             compilation->setJettisonReason(reason, detail);
3480         
3481         // This accomplishes (1), and does its own book-keeping about whether it has already happened.
3482         if (!jitCode()->dfgCommon()->invalidate()) {
3483             // We've already been invalidated.
3484             RELEASE_ASSERT(this != replacement() || (m_vm->heap.isCurrentThreadBusy() && !Heap::isMarked(ownerScriptExecutable())));
3485             return;
3486         }
3487     }
3488     
3489     if (DFG::shouldDumpDisassembly())
3490         dataLog("    Did invalidate ", *this, "\n");
3491     
3492     // Count the reoptimization if that's what the user wanted.
3493     if (mode == CountReoptimization) {
3494         // FIXME: Maybe this should call alternative().
3495         // https://bugs.webkit.org/show_bug.cgi?id=123677
3496         baselineAlternative()->countReoptimization();
3497         if (DFG::shouldDumpDisassembly())
3498             dataLog("    Did count reoptimization for ", *this, "\n");
3499     }
3500     
3501     if (this != replacement()) {
3502         // This means that we were never the entrypoint. This can happen for OSR entry code
3503         // blocks.
3504         return;
3505     }
3506
3507     if (alternative())
3508         alternative()->optimizeAfterWarmUp();
3509
3510     if (reason != Profiler::JettisonDueToOldAge)
3511         tallyFrequentExitSites();
3512 #endif // ENABLE(DFG_JIT)
3513
3514     // Jettison can happen during GC. We don't want to install code to a dead executable
3515     // because that would add a dead object to the remembered set.
3516     if (m_vm->heap.isCurrentThreadBusy() && !Heap::isMarked(ownerScriptExecutable()))
3517         return;
3518
3519     // This accomplishes (2).
3520     ownerScriptExecutable()->installCode(
3521         m_globalObject->vm(), alternative(), codeType(), specializationKind());
3522
3523 #if ENABLE(DFG_JIT)
3524     if (DFG::shouldDumpDisassembly())
3525         dataLog("    Did install baseline version of ", *this, "\n");
3526 #endif // ENABLE(DFG_JIT)
3527 }
3528
3529 JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin)
3530 {
3531     if (!codeOrigin.inlineCallFrame)
3532         return globalObject();
3533     return codeOrigin.inlineCallFrame->baselineCodeBlock->globalObject();
3534 }
3535
3536 class RecursionCheckFunctor {
3537 public:
3538     RecursionCheckFunctor(CallFrame* startCallFrame, CodeBlock* codeBlock, unsigned depthToCheck)
3539         : m_startCallFrame(startCallFrame)
3540         , m_codeBlock(codeBlock)
3541         , m_depthToCheck(depthToCheck)
3542         , m_foundStartCallFrame(false)
3543         , m_didRecurse(false)
3544     { }
3545
3546     StackVisitor::Status operator()(StackVisitor& visitor) const
3547     {
3548         CallFrame* currentCallFrame = visitor->callFrame();
3549
3550         if (currentCallFrame == m_startCallFrame)
3551             m_foundStartCallFrame = true;
3552
3553         if (m_foundStartCallFrame) {
3554             if (visitor->callFrame()->codeBlock() == m_codeBlock) {
3555                 m_didRecurse = true;
3556                 return StackVisitor::Done;
3557             }
3558
3559             if (!m_depthToCheck--)
3560                 return StackVisitor::Done;
3561         }
3562
3563         return StackVisitor::Continue;
3564     }
3565
3566     bool didRecurse() const { return m_didRecurse; }
3567
3568 private:
3569     CallFrame* m_startCallFrame;
3570     CodeBlock* m_codeBlock;
3571     mutable unsigned m_depthToCheck;
3572     mutable bool m_foundStartCallFrame;
3573     mutable bool m_didRecurse;
3574 };
3575
3576 void CodeBlock::noticeIncomingCall(ExecState* callerFrame)
3577 {
3578     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
3579     
3580     if (Options::verboseCallLink())
3581         dataLog("Noticing call link from ", pointerDump(callerCodeBlock), " to ", *this, "\n");
3582     
3583 #if ENABLE(DFG_JIT)
3584     if (!m_shouldAlwaysBeInlined)
3585         return;
3586     
3587     if (!callerCodeBlock) {
3588         m_shouldAlwaysBeInlined = false;
3589         if (Options::verboseCallLink())
3590             dataLog("    Clearing SABI because caller is native.\n");
3591         return;
3592     }
3593
3594     if (!hasBaselineJITProfiling())
3595         return;
3596
3597     if (!DFG::mightInlineFunction(this))
3598         return;
3599
3600     if (!canInline(capabilityLevelState()))
3601         return;
3602     
3603     if (!DFG::isSmallEnoughToInlineCodeInto(callerCodeBlock)) {
3604         m_shouldAlwaysBeInlined = false;
3605         if (Options::verboseCallLink())
3606             dataLog("    Clearing SABI because caller is too large.\n");
3607         return;
3608     }
3609
3610     if (callerCodeBlock->jitType() == JITCode::InterpreterThunk) {
3611         // If the caller is still in the interpreter, then we can't expect inlining to
3612         // happen anytime soon. Assume it's profitable to optimize it separately. This
3613         // ensures that a function is SABI only if it is called no more frequently than
3614         // any of its callers.
3615         m_shouldAlwaysBeInlined = false;
3616         if (Options::verboseCallLink())
3617             dataLog("    Clearing SABI because caller is in LLInt.\n");
3618         return;
3619     }
3620     
3621     if (JITCode::isOptimizingJIT(callerCodeBlock->jitType())) {
3622         m_shouldAlwaysBeInlined = false;
3623         if (Options::verboseCallLink())
3624             dataLog("    Clearing SABI bcause caller was already optimized.\n");
3625         return;
3626     }
3627     
3628     if (callerCodeBlock->codeType() != FunctionCode) {
3629         // If the caller is either eval or global code, assume that that won't be
3630         // optimized anytime soon. For eval code this is particularly true since we
3631         // delay eval optimization by a *lot*.
3632         m_shouldAlwaysBeInlined = false;
3633         if (Options::verboseCallLink())
3634             dataLog("    Clearing SABI because caller is not a function.\n");
3635         return;
3636     }
3637
3638     // Recursive calls won't be inlined.
3639     RecursionCheckFunctor functor(callerFrame, this, Options::maximumInliningDepth());
3640     vm()->topCallFrame->iterate(functor);
3641
3642     if (functor.didRecurse()) {
3643         if (Options::verboseCallLink())
3644             dataLog("    Clearing SABI because recursion was detected.\n");
3645         m_shouldAlwaysBeInlined = false;
3646         return;
3647     }
3648     
3649     if (callerCodeBlock->capabilityLevelState() == DFG::CapabilityLevelNotSet) {
3650         dataLog("In call from ", *callerCodeBlock, " ", callerFrame->codeOrigin(), " to ", *this, ": caller's DFG capability level is not set.\n");
3651         CRASH();
3652     }
3653     
3654     if (canCompile(callerCodeBlock->capabilityLevelState()))
3655         return;
3656     
3657     if (Options::verboseCallLink())
3658         dataLog("    Clearing SABI because the caller is not a DFG candidate.\n");
3659     
3660     m_shouldAlwaysBeInlined = false;
3661 #endif
3662 }
3663
3664 unsigned CodeBlock::reoptimizationRetryCounter() const
3665 {
3666 #if ENABLE(JIT)
3667     ASSERT(m_reoptimizationRetryCounter <= Options::reoptimizationRetryCounterMax());
3668     return m_reoptimizationRetryCounter;
3669 #else
3670     return 0;
3671 #endif // ENABLE(JIT)
3672 }
3673
3674 #if ENABLE(JIT)
3675 void CodeBlock::setCalleeSaveRegisters(RegisterSet calleeSaveRegisters)
3676 {
3677     m_calleeSaveRegisters = std::make_unique<RegisterAtOffsetList>(calleeSaveRegisters);
3678 }
3679
3680 void CodeBlock::setCalleeSaveRegisters(std::unique_ptr<RegisterAtOffsetList> registerAtOffsetList)
3681 {
3682     m_calleeSaveRegisters = WTFMove(registerAtOffsetList);
3683 }
3684     
3685 static size_t roundCalleeSaveSpaceAsVirtualRegisters(size_t calleeSaveRegisters)
3686 {
3687     static const unsigned cpuRegisterSize = sizeof(void*);
3688     return (WTF::roundUpToMultipleOf(sizeof(Register), calleeSaveRegisters * cpuRegisterSize) / sizeof(Register));
3689
3690 }
3691
3692 size_t CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters()
3693 {
3694     return roundCalleeSaveSpaceAsVirtualRegisters(numberOfLLIntBaselineCalleeSaveRegisters());
3695 }
3696
3697 size_t CodeBlock::calleeSaveSpaceAsVirtualRegisters()
3698 {
3699     return roundCalleeSaveSpaceAsVirtualRegisters(m_calleeSaveRegisters->size());
3700 }
3701
3702 void CodeBlock::countReoptimization()
3703 {
3704     m_reoptimizationRetryCounter++;
3705     if (m_reoptimizationRetryCounter > Options::reoptimizationRetryCounterMax())
3706         m_reoptimizationRetryCounter = Options::reoptimizationRetryCounterMax();
3707 }
3708
3709 unsigned CodeBlock::numberOfDFGCompiles()
3710 {
3711     ASSERT(JITCode::isBaselineCode(jitType()));
3712     if (Options::testTheFTL()) {
3713         if (m_didFailFTLCompilation)
3714             return 1000000;
3715         return (m_hasBeenCompiledWithFTL ? 1 : 0) + m_reoptimizationRetryCounter;
3716     }
3717     return (JITCode::isOptimizingJIT(replacement()->jitType()) ? 1 : 0) + m_reoptimizationRetryCounter;
3718 }
3719
3720 int32_t CodeBlock::codeTypeThresholdMultiplier() const
3721 {
3722     if (codeType() == EvalCode)
3723         return Options::evalThresholdMultiplier();
3724     
3725     return 1;
3726 }
3727
3728 double CodeBlock::optimizationThresholdScalingFactor()
3729 {
3730     // This expression arises from doing a least-squares fit of
3731     //
3732     // F[x_] =: a * Sqrt[x + b] + Abs[c * x] + d
3733     //
3734     // against the data points:
3735     //
3736     //    x       F[x_]
3737     //    10       0.9          (smallest reasonable code block)
3738     //   200       1.0          (typical small-ish code block)
3739     //   320       1.2          (something I saw in 3d-cube that I wanted to optimize)
3740     //  1268       5.0          (something I saw in 3d-cube that I didn't want to optimize)
3741     //  4000       5.5          (random large size, used to cause the function to converge to a shallow curve of some sort)
3742     // 10000       6.0          (similar to above)
3743     //
3744    &nbs