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