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