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