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