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