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