Objective-C API: Rename JSValue.h/APIJSValue.h to JSCJSValue.h/JSValue.h
[WebKit-https.git] / Source / JavaScriptCore / bytecode / CodeBlock.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2010, 2012 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 Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "CodeBlock.h"
32
33 #include "BytecodeGenerator.h"
34 #include "CallLinkStatus.h"
35 #include "DFGCapabilities.h"
36 #include "DFGCommon.h"
37 #include "DFGNode.h"
38 #include "DFGRepatch.h"
39 #include "Debugger.h"
40 #include "Interpreter.h"
41 #include "JIT.h"
42 #include "JITStubs.h"
43 #include "JSActivation.h"
44 #include "JSCJSValue.h"
45 #include "JSFunction.h"
46 #include "JSNameScope.h"
47 #include "LowLevelInterpreter.h"
48 #include "Operations.h"
49 #include "ReduceWhitespace.h"
50 #include "RepatchBuffer.h"
51 #include "SlotVisitorInlines.h"
52 #include <stdio.h>
53 #include <wtf/CommaPrinter.h>
54 #include <wtf/StringExtras.h>
55 #include <wtf/StringPrintStream.h>
56 #include <wtf/UnusedParam.h>
57
58 #if ENABLE(DFG_JIT)
59 #include "DFGOperations.h"
60 #endif
61
62 #define DUMP_CODE_BLOCK_STATISTICS 0
63
64 namespace JSC {
65
66 #if ENABLE(DFG_JIT)
67 using namespace DFG;
68 #endif
69
70 String CodeBlock::inferredName() const
71 {
72     switch (codeType()) {
73     case GlobalCode:
74         return "<global>";
75     case EvalCode:
76         return "<eval>";
77     case FunctionCode:
78         return jsCast<FunctionExecutable*>(ownerExecutable())->inferredName().string();
79     default:
80         CRASH();
81         return String();
82     }
83 }
84
85 CodeBlockHash CodeBlock::hash() const
86 {
87     return CodeBlockHash(ownerExecutable()->source(), specializationKind());
88 }
89
90 String CodeBlock::sourceCodeForTools() const
91 {
92     if (codeType() != FunctionCode)
93         return ownerExecutable()->source().toString();
94     
95     SourceProvider* provider = source();
96     FunctionExecutable* executable = jsCast<FunctionExecutable*>(ownerExecutable());
97     UnlinkedFunctionExecutable* unlinked = executable->unlinkedExecutable();
98     unsigned unlinkedStartOffset = unlinked->startOffset();
99     unsigned linkedStartOffset = executable->source().startOffset();
100     int delta = linkedStartOffset - unlinkedStartOffset;
101     StringBuilder builder;
102     builder.append("function ");
103     builder.append(provider->getRange(
104         delta + unlinked->functionStartOffset(),
105         delta + unlinked->startOffset() + unlinked->sourceLength()));
106     return builder.toString();
107 }
108
109 String CodeBlock::sourceCodeOnOneLine() const
110 {
111     return reduceWhitespace(sourceCodeForTools());
112 }
113
114 void CodeBlock::dumpAssumingJITType(PrintStream& out, JITCode::JITType jitType) const
115 {
116     out.print(inferredName(), "#", hash(), ":[", RawPointer(this), "->", RawPointer(ownerExecutable()), ", ", jitType, codeType());
117     if (codeType() == FunctionCode)
118         out.print(specializationKind());
119     out.print("]");
120 }
121
122 void CodeBlock::dump(PrintStream& out) const
123 {
124     dumpAssumingJITType(out, getJITType());
125 }
126
127 static String escapeQuotes(const String& str)
128 {
129     String result = str;
130     size_t pos = 0;
131     while ((pos = result.find('\"', pos)) != notFound) {
132         result = makeString(result.substringSharingImpl(0, pos), "\"\\\"\"", result.substringSharingImpl(pos + 1));
133         pos += 4;
134     }
135     return result;
136 }
137
138 static String valueToSourceString(ExecState* exec, JSValue val)
139 {
140     if (!val)
141         return ASCIILiteral("0");
142
143     if (val.isString())
144         return makeString("\"", escapeQuotes(val.toString(exec)->value(exec)), "\"");
145
146     return toString(val);
147 }
148
149 static CString constantName(ExecState* exec, int k, JSValue value)
150 {
151     return makeString(valueToSourceString(exec, value), "(@k", String::number(k - FirstConstantRegisterIndex), ")").utf8();
152 }
153
154 static CString idName(int id0, const Identifier& ident)
155 {
156     return makeString(ident.string(), "(@id", String::number(id0), ")").utf8();
157 }
158
159 void CodeBlock::dumpBytecodeCommentAndNewLine(PrintStream& out, int location)
160 {
161 #if ENABLE(DFG_JIT)
162     Vector<FrequentExitSite> exitSites = exitProfile().exitSitesFor(location);
163     if (!exitSites.isEmpty()) {
164         out.print(" !! frequent exits: ");
165         CommaPrinter comma;
166         for (unsigned i = 0; i < exitSites.size(); ++i)
167             out.print(comma, exitSites[i].kind());
168     }
169 #endif // ENABLE(DFG_JIT)
170 #if ENABLE(BYTECODE_COMMENTS)
171     const char* comment = commentForBytecodeOffset(location);
172     if (comment)
173         out.printf("\t\t ; %s", comment);
174 #else
175     UNUSED_PARAM(location);
176 #endif
177     out.print("\n");
178 }
179
180 CString CodeBlock::registerName(ExecState* exec, int r) const
181 {
182     if (r == missingThisObjectMarker())
183         return "<null>";
184
185     if (isConstantRegisterIndex(r))
186         return constantName(exec, r, getConstant(r));
187
188     return makeString("r", String::number(r)).utf8();
189 }
190
191 static String regexpToSourceString(RegExp* regExp)
192 {
193     char postfix[5] = { '/', 0, 0, 0, 0 };
194     int index = 1;
195     if (regExp->global())
196         postfix[index++] = 'g';
197     if (regExp->ignoreCase())
198         postfix[index++] = 'i';
199     if (regExp->multiline())
200         postfix[index] = 'm';
201
202     return makeString("/", regExp->pattern(), postfix);
203 }
204
205 static CString regexpName(int re, RegExp* regexp)
206 {
207     return makeString(regexpToSourceString(regexp), "(@re", String::number(re), ")").utf8();
208 }
209
210 static String pointerToSourceString(void* p)
211 {
212     char buffer[2 + 2 * sizeof(void*) + 1]; // 0x [two characters per byte] \0
213     snprintf(buffer, sizeof(buffer), "%p", p);
214     return buffer;
215 }
216
217 NEVER_INLINE static const char* debugHookName(int debugHookID)
218 {
219     switch (static_cast<DebugHookID>(debugHookID)) {
220         case DidEnterCallFrame:
221             return "didEnterCallFrame";
222         case WillLeaveCallFrame:
223             return "willLeaveCallFrame";
224         case WillExecuteStatement:
225             return "willExecuteStatement";
226         case WillExecuteProgram:
227             return "willExecuteProgram";
228         case DidExecuteProgram:
229             return "didExecuteProgram";
230         case DidReachBreakpoint:
231             return "didReachBreakpoint";
232     }
233
234     RELEASE_ASSERT_NOT_REACHED();
235     return "";
236 }
237
238 void CodeBlock::printUnaryOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op)
239 {
240     int r0 = (++it)->u.operand;
241     int r1 = (++it)->u.operand;
242
243     out.printf("[%4d] %s\t\t %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data());
244 }
245
246 void CodeBlock::printBinaryOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op)
247 {
248     int r0 = (++it)->u.operand;
249     int r1 = (++it)->u.operand;
250     int r2 = (++it)->u.operand;
251     out.printf("[%4d] %s\t\t %s, %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
252 }
253
254 void CodeBlock::printConditionalJump(PrintStream& out, ExecState* exec, const Instruction*, const Instruction*& it, int location, const char* op)
255 {
256     int r0 = (++it)->u.operand;
257     int offset = (++it)->u.operand;
258     out.printf("[%4d] %s\t\t %s, %d(->%d)", location, op, registerName(exec, r0).data(), offset, location + offset);
259 }
260
261 void CodeBlock::printGetByIdOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it)
262 {
263     const char* op;
264     switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
265     case op_get_by_id:
266         op = "get_by_id";
267         break;
268     case op_get_by_id_out_of_line:
269         op = "get_by_id_out_of_line";
270         break;
271     case op_get_by_id_self:
272         op = "get_by_id_self";
273         break;
274     case op_get_by_id_proto:
275         op = "get_by_id_proto";
276         break;
277     case op_get_by_id_chain:
278         op = "get_by_id_chain";
279         break;
280     case op_get_by_id_getter_self:
281         op = "get_by_id_getter_self";
282         break;
283     case op_get_by_id_getter_proto:
284         op = "get_by_id_getter_proto";
285         break;
286     case op_get_by_id_getter_chain:
287         op = "get_by_id_getter_chain";
288         break;
289     case op_get_by_id_custom_self:
290         op = "get_by_id_custom_self";
291         break;
292     case op_get_by_id_custom_proto:
293         op = "get_by_id_custom_proto";
294         break;
295     case op_get_by_id_custom_chain:
296         op = "get_by_id_custom_chain";
297         break;
298     case op_get_by_id_generic:
299         op = "get_by_id_generic";
300         break;
301     case op_get_array_length:
302         op = "array_length";
303         break;
304     case op_get_string_length:
305         op = "string_length";
306         break;
307     default:
308         RELEASE_ASSERT_NOT_REACHED();
309         op = 0;
310     }
311     int r0 = (++it)->u.operand;
312     int r1 = (++it)->u.operand;
313     int id0 = (++it)->u.operand;
314     out.printf("[%4d] %s\t %s, %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
315     it += 4; // Increment up to the value profiler.
316 }
317
318 #if ENABLE(JIT) || ENABLE(LLINT) // unused in some configurations
319 static void dumpStructure(PrintStream& out, const char* name, ExecState* exec, Structure* structure, Identifier& ident)
320 {
321     if (!structure)
322         return;
323     
324     out.printf("%s = %p", name, structure);
325     
326     PropertyOffset offset = structure->get(exec->globalData(), ident);
327     if (offset != invalidOffset)
328         out.printf(" (offset = %d)", offset);
329 }
330 #endif
331
332 #if ENABLE(JIT) // unused when not ENABLE(JIT), leading to silly warnings
333 static void dumpChain(PrintStream& out, ExecState* exec, StructureChain* chain, Identifier& ident)
334 {
335     out.printf("chain = %p: [", chain);
336     bool first = true;
337     for (WriteBarrier<Structure>* currentStructure = chain->head();
338          *currentStructure;
339          ++currentStructure) {
340         if (first)
341             first = false;
342         else
343             out.printf(", ");
344         dumpStructure(out, "struct", exec, currentStructure->get(), ident);
345     }
346     out.printf("]");
347 }
348 #endif
349
350 void CodeBlock::printGetByIdCacheStatus(PrintStream& out, ExecState* exec, int location)
351 {
352     Instruction* instruction = instructions().begin() + location;
353
354     Identifier& ident = identifier(instruction[3].u.operand);
355     
356     UNUSED_PARAM(ident); // tell the compiler to shut up in certain platform configurations.
357     
358 #if ENABLE(LLINT)
359     if (exec->interpreter()->getOpcodeID(instruction[0].u.opcode) == op_get_array_length)
360         out.printf(" llint(array_length)");
361     else if (Structure* structure = instruction[4].u.structure.get()) {
362         out.printf(" llint(");
363         dumpStructure(out, "struct", exec, structure, ident);
364         out.printf(")");
365     }
366 #endif
367
368 #if ENABLE(JIT)
369     if (numberOfStructureStubInfos()) {
370         StructureStubInfo& stubInfo = getStubInfo(location);
371         if (stubInfo.seen) {
372             out.printf(" jit(");
373             
374             Structure* baseStructure = 0;
375             Structure* prototypeStructure = 0;
376             StructureChain* chain = 0;
377             PolymorphicAccessStructureList* structureList = 0;
378             int listSize = 0;
379             
380             switch (stubInfo.accessType) {
381             case access_get_by_id_self:
382                 out.printf("self");
383                 baseStructure = stubInfo.u.getByIdSelf.baseObjectStructure.get();
384                 break;
385             case access_get_by_id_proto:
386                 out.printf("proto");
387                 baseStructure = stubInfo.u.getByIdProto.baseObjectStructure.get();
388                 prototypeStructure = stubInfo.u.getByIdProto.prototypeStructure.get();
389                 break;
390             case access_get_by_id_chain:
391                 out.printf("chain");
392                 baseStructure = stubInfo.u.getByIdChain.baseObjectStructure.get();
393                 chain = stubInfo.u.getByIdChain.chain.get();
394                 break;
395             case access_get_by_id_self_list:
396                 out.printf("self_list");
397                 structureList = stubInfo.u.getByIdSelfList.structureList;
398                 listSize = stubInfo.u.getByIdSelfList.listSize;
399                 break;
400             case access_get_by_id_proto_list:
401                 out.printf("proto_list");
402                 structureList = stubInfo.u.getByIdProtoList.structureList;
403                 listSize = stubInfo.u.getByIdProtoList.listSize;
404                 break;
405             case access_unset:
406                 out.printf("unset");
407                 break;
408             case access_get_by_id_generic:
409                 out.printf("generic");
410                 break;
411             case access_get_array_length:
412                 out.printf("array_length");
413                 break;
414             case access_get_string_length:
415                 out.printf("string_length");
416                 break;
417             default:
418                 RELEASE_ASSERT_NOT_REACHED();
419                 break;
420             }
421             
422             if (baseStructure) {
423                 out.printf(", ");
424                 dumpStructure(out, "struct", exec, baseStructure, ident);
425             }
426             
427             if (prototypeStructure) {
428                 out.printf(", ");
429                 dumpStructure(out, "prototypeStruct", exec, baseStructure, ident);
430             }
431             
432             if (chain) {
433                 out.printf(", ");
434                 dumpChain(out, exec, chain, ident);
435             }
436             
437             if (structureList) {
438                 out.printf(", list = %p: [", structureList);
439                 for (int i = 0; i < listSize; ++i) {
440                     if (i)
441                         out.printf(", ");
442                     out.printf("(");
443                     dumpStructure(out, "base", exec, structureList->list[i].base.get(), ident);
444                     if (structureList->list[i].isChain) {
445                         if (structureList->list[i].u.chain.get()) {
446                             out.printf(", ");
447                             dumpChain(out, exec, structureList->list[i].u.chain.get(), ident);
448                         }
449                     } else {
450                         if (structureList->list[i].u.proto.get()) {
451                             out.printf(", ");
452                             dumpStructure(out, "proto", exec, structureList->list[i].u.proto.get(), ident);
453                         }
454                     }
455                     out.printf(")");
456                 }
457                 out.printf("]");
458             }
459             out.printf(")");
460         }
461     }
462 #endif
463 }
464
465 void CodeBlock::printCallOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op, CacheDumpMode cacheDumpMode)
466 {
467     int func = (++it)->u.operand;
468     int argCount = (++it)->u.operand;
469     int registerOffset = (++it)->u.operand;
470     out.printf("[%4d] %s\t %s, %d, %d", location, op, registerName(exec, func).data(), argCount, registerOffset);
471     if (cacheDumpMode == DumpCaches) {
472 #if ENABLE(LLINT)
473         LLIntCallLinkInfo* callLinkInfo = it[1].u.callLinkInfo;
474         if (callLinkInfo->lastSeenCallee) {
475             out.printf(
476                 " llint(%p, exec %p)",
477                 callLinkInfo->lastSeenCallee.get(),
478                 callLinkInfo->lastSeenCallee->executable());
479         }
480 #endif
481 #if ENABLE(JIT)
482         if (numberOfCallLinkInfos()) {
483             JSFunction* target = getCallLinkInfo(location).lastSeenCallee.get();
484             if (target)
485                 out.printf(" jit(%p, exec %p)", target, target->executable());
486         }
487 #endif
488         out.print(" status(", CallLinkStatus::computeFor(this, location), ")");
489     }
490     it += 2;
491 }
492
493 void CodeBlock::printPutByIdOp(PrintStream& out, ExecState* exec, int location, const Instruction*& it, const char* op)
494 {
495     int r0 = (++it)->u.operand;
496     int id0 = (++it)->u.operand;
497     int r1 = (++it)->u.operand;
498     out.printf("[%4d] %s\t %s, %s, %s", location, op, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
499     it += 5;
500 }
501
502 void CodeBlock::printStructure(PrintStream& out, const char* name, const Instruction* vPC, int operand)
503 {
504     unsigned instructionOffset = vPC - instructions().begin();
505     out.printf("  [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).utf8().data());
506 }
507
508 void CodeBlock::printStructures(PrintStream& out, const Instruction* vPC)
509 {
510     Interpreter* interpreter = m_globalData->interpreter;
511     unsigned instructionOffset = vPC - instructions().begin();
512
513     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id)) {
514         printStructure(out, "get_by_id", vPC, 4);
515         return;
516     }
517     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
518         printStructure(out, "get_by_id_self", vPC, 4);
519         return;
520     }
521     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
522         out.printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data());
523         return;
524     }
525     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
526         out.printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data(), pointerToSourceString(vPC[6].u.structureChain).utf8().data());
527         return;
528     }
529     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
530         out.printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structureChain).utf8().data());
531         return;
532     }
533     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id)) {
534         printStructure(out, "put_by_id", vPC, 4);
535         return;
536     }
537     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
538         printStructure(out, "put_by_id_replace", vPC, 4);
539         return;
540     }
541
542     // These m_instructions doesn't ref Structures.
543     ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_call) || vPC[0].u.opcode == interpreter->getOpcode(op_call_eval) || vPC[0].u.opcode == interpreter->getOpcode(op_construct));
544 }
545
546 void CodeBlock::dumpBytecode(PrintStream& out)
547 {
548     // We only use the ExecState* for things that don't actually lead to JS execution,
549     // like converting a JSString to a String. Hence the globalExec is appropriate.
550     ExecState* exec = m_globalObject->globalExec();
551     
552     size_t instructionCount = 0;
553
554     for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)])
555         ++instructionCount;
556
557     out.print(*this);
558     out.printf(
559         ": %lu m_instructions; %lu bytes; %d parameter(s); %d callee register(s); %d variable(s)",
560         static_cast<unsigned long>(instructions().size()),
561         static_cast<unsigned long>(instructions().size() * sizeof(Instruction)),
562         m_numParameters, m_numCalleeRegisters, m_numVars);
563     if (symbolTable() && symbolTable()->captureCount())
564         out.printf("; %d captured var(s)", symbolTable()->captureCount());
565     if (usesArguments()) {
566         out.printf(
567             "; uses arguments, in r%d, r%d",
568             argumentsRegister(),
569             unmodifiedArgumentsRegister(argumentsRegister()));
570     }
571     if (needsFullScopeChain() && codeType() == FunctionCode)
572         out.printf("; activation in r%d", activationRegister());
573     out.print("\n\nSource: ", sourceCodeOnOneLine(), "\n\n");
574
575     const Instruction* begin = instructions().begin();
576     const Instruction* end = instructions().end();
577     for (const Instruction* it = begin; it != end; ++it)
578         dumpBytecode(out, exec, begin, it);
579
580     if (!m_identifiers.isEmpty()) {
581         out.printf("\nIdentifiers:\n");
582         size_t i = 0;
583         do {
584             out.printf("  id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].string().utf8().data());
585             ++i;
586         } while (i != m_identifiers.size());
587     }
588
589     if (!m_constantRegisters.isEmpty()) {
590         out.printf("\nConstants:\n");
591         size_t i = 0;
592         do {
593             out.printf("   k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, m_constantRegisters[i].get()).utf8().data());
594             ++i;
595         } while (i < m_constantRegisters.size());
596     }
597
598     if (size_t count = m_unlinkedCode->numberOfRegExps()) {
599         out.printf("\nm_regexps:\n");
600         size_t i = 0;
601         do {
602             out.printf("  re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_unlinkedCode->regexp(i)).utf8().data());
603             ++i;
604         } while (i < count);
605     }
606
607 #if ENABLE(JIT)
608     if (!m_structureStubInfos.isEmpty())
609         out.printf("\nStructures:\n");
610 #endif
611
612     if (m_rareData && !m_rareData->m_exceptionHandlers.isEmpty()) {
613         out.printf("\nException Handlers:\n");
614         unsigned i = 0;
615         do {
616             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);
617             ++i;
618         } while (i < m_rareData->m_exceptionHandlers.size());
619     }
620     
621     if (m_rareData && !m_rareData->m_immediateSwitchJumpTables.isEmpty()) {
622         out.printf("Immediate Switch Jump Tables:\n");
623         unsigned i = 0;
624         do {
625             out.printf("  %1d = {\n", i);
626             int entry = 0;
627             Vector<int32_t>::const_iterator end = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.end();
628             for (Vector<int32_t>::const_iterator iter = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
629                 if (!*iter)
630                     continue;
631                 out.printf("\t\t%4d => %04d\n", entry + m_rareData->m_immediateSwitchJumpTables[i].min, *iter);
632             }
633             out.printf("      }\n");
634             ++i;
635         } while (i < m_rareData->m_immediateSwitchJumpTables.size());
636     }
637     
638     if (m_rareData && !m_rareData->m_characterSwitchJumpTables.isEmpty()) {
639         out.printf("\nCharacter Switch Jump Tables:\n");
640         unsigned i = 0;
641         do {
642             out.printf("  %1d = {\n", i);
643             int entry = 0;
644             Vector<int32_t>::const_iterator end = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.end();
645             for (Vector<int32_t>::const_iterator iter = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) {
646                 if (!*iter)
647                     continue;
648                 ASSERT(!((i + m_rareData->m_characterSwitchJumpTables[i].min) & ~0xFFFF));
649                 UChar ch = static_cast<UChar>(entry + m_rareData->m_characterSwitchJumpTables[i].min);
650                 out.printf("\t\t\"%s\" => %04d\n", String(&ch, 1).utf8().data(), *iter);
651             }
652             out.printf("      }\n");
653             ++i;
654         } while (i < m_rareData->m_characterSwitchJumpTables.size());
655     }
656     
657     if (m_rareData && !m_rareData->m_stringSwitchJumpTables.isEmpty()) {
658         out.printf("\nString Switch Jump Tables:\n");
659         unsigned i = 0;
660         do {
661             out.printf("  %1d = {\n", i);
662             StringJumpTable::StringOffsetTable::const_iterator end = m_rareData->m_stringSwitchJumpTables[i].offsetTable.end();
663             for (StringJumpTable::StringOffsetTable::const_iterator iter = m_rareData->m_stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter)
664                 out.printf("\t\t\"%s\" => %04d\n", String(iter->key).utf8().data(), iter->value.branchOffset);
665             out.printf("      }\n");
666             ++i;
667         } while (i < m_rareData->m_stringSwitchJumpTables.size());
668     }
669
670     out.printf("\n");
671 }
672
673 void CodeBlock::beginDumpProfiling(PrintStream& out, bool& hasPrintedProfiling)
674 {
675     if (hasPrintedProfiling) {
676         out.print("; ");
677         return;
678     }
679     
680     out.print("    ");
681     hasPrintedProfiling = true;
682 }
683
684 void CodeBlock::dumpValueProfiling(PrintStream& out, const Instruction*& it, bool& hasPrintedProfiling)
685 {
686     ++it;
687 #if ENABLE(VALUE_PROFILER)
688     CString description = it->u.profile->briefDescription();
689     if (!description.length())
690         return;
691     beginDumpProfiling(out, hasPrintedProfiling);
692     out.print(description);
693 #else
694     UNUSED_PARAM(out);
695     UNUSED_PARAM(hasPrintedProfiling);
696 #endif
697 }
698
699 void CodeBlock::dumpArrayProfiling(PrintStream& out, const Instruction*& it, bool& hasPrintedProfiling)
700 {
701     ++it;
702 #if ENABLE(VALUE_PROFILER)
703     CString description = it->u.arrayProfile->briefDescription(this);
704     if (!description.length())
705         return;
706     beginDumpProfiling(out, hasPrintedProfiling);
707     out.print(description);
708 #else
709     UNUSED_PARAM(out);
710     UNUSED_PARAM(hasPrintedProfiling);
711 #endif
712 }
713
714 #if ENABLE(VALUE_PROFILER)
715 void CodeBlock::dumpRareCaseProfile(PrintStream& out, const char* name, RareCaseProfile* profile, bool& hasPrintedProfiling)
716 {
717     if (!profile || !profile->m_counter)
718         return;
719
720     beginDumpProfiling(out, hasPrintedProfiling);
721     out.print(name, profile->m_counter);
722 }
723 #endif
724
725 void CodeBlock::dumpBytecode(PrintStream& out, ExecState* exec, const Instruction* begin, const Instruction*& it)
726 {
727     int location = it - begin;
728     bool hasPrintedProfiling = false;
729     switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
730         case op_enter: {
731             out.printf("[%4d] enter", location);
732             break;
733         }
734         case op_create_activation: {
735             int r0 = (++it)->u.operand;
736             out.printf("[%4d] create_activation %s", location, registerName(exec, r0).data());
737             break;
738         }
739         case op_create_arguments: {
740             int r0 = (++it)->u.operand;
741             out.printf("[%4d] create_arguments\t %s", location, registerName(exec, r0).data());
742             break;
743         }
744         case op_init_lazy_reg: {
745             int r0 = (++it)->u.operand;
746             out.printf("[%4d] init_lazy_reg\t %s", location, registerName(exec, r0).data());
747             break;
748         }
749         case op_get_callee: {
750             int r0 = (++it)->u.operand;
751             out.printf("[%4d] op_get_callee %s\n", location, registerName(exec, r0).data());
752             ++it;
753             break;
754         }
755         case op_create_this: {
756             int r0 = (++it)->u.operand;
757             int r1 = (++it)->u.operand;
758             out.printf("[%4d] create_this %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
759             break;
760         }
761         case op_convert_this: {
762             int r0 = (++it)->u.operand;
763             out.printf("[%4d] convert_this\t %s", location, registerName(exec, r0).data());
764             ++it; // Skip value profile.
765             break;
766         }
767         case op_new_object: {
768             int r0 = (++it)->u.operand;
769             out.printf("[%4d] new_object\t %s", location, registerName(exec, r0).data());
770             break;
771         }
772         case op_new_array: {
773             int dst = (++it)->u.operand;
774             int argv = (++it)->u.operand;
775             int argc = (++it)->u.operand;
776             out.printf("[%4d] new_array\t %s, %s, %d", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc);
777             ++it; // Skip array allocation profile.
778             break;
779         }
780         case op_new_array_with_size: {
781             int dst = (++it)->u.operand;
782             int length = (++it)->u.operand;
783             out.printf("[%4d] new_array_with_size\t %s, %s", location, registerName(exec, dst).data(), registerName(exec, length).data());
784             ++it; // Skip array allocation profile.
785             break;
786         }
787         case op_new_array_buffer: {
788             int dst = (++it)->u.operand;
789             int argv = (++it)->u.operand;
790             int argc = (++it)->u.operand;
791             out.printf("[%4d] new_array_buffer\t %s, %d, %d", location, registerName(exec, dst).data(), argv, argc);
792             ++it; // Skip array allocation profile.
793             break;
794         }
795         case op_new_regexp: {
796             int r0 = (++it)->u.operand;
797             int re0 = (++it)->u.operand;
798             out.printf("[%4d] new_regexp\t %s, ", location, registerName(exec, r0).data());
799             if (r0 >=0 && r0 < (int)m_unlinkedCode->numberOfRegExps())
800                 out.printf("%s", regexpName(re0, regexp(re0)).data());
801             else
802                 out.printf("bad_regexp(%d)", re0);
803             break;
804         }
805         case op_mov: {
806             int r0 = (++it)->u.operand;
807             int r1 = (++it)->u.operand;
808             out.printf("[%4d] mov\t\t %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
809             break;
810         }
811         case op_not: {
812             printUnaryOp(out, exec, location, it, "not");
813             break;
814         }
815         case op_eq: {
816             printBinaryOp(out, exec, location, it, "eq");
817             break;
818         }
819         case op_eq_null: {
820             printUnaryOp(out, exec, location, it, "eq_null");
821             break;
822         }
823         case op_neq: {
824             printBinaryOp(out, exec, location, it, "neq");
825             break;
826         }
827         case op_neq_null: {
828             printUnaryOp(out, exec, location, it, "neq_null");
829             break;
830         }
831         case op_stricteq: {
832             printBinaryOp(out, exec, location, it, "stricteq");
833             break;
834         }
835         case op_nstricteq: {
836             printBinaryOp(out, exec, location, it, "nstricteq");
837             break;
838         }
839         case op_less: {
840             printBinaryOp(out, exec, location, it, "less");
841             break;
842         }
843         case op_lesseq: {
844             printBinaryOp(out, exec, location, it, "lesseq");
845             break;
846         }
847         case op_greater: {
848             printBinaryOp(out, exec, location, it, "greater");
849             break;
850         }
851         case op_greatereq: {
852             printBinaryOp(out, exec, location, it, "greatereq");
853             break;
854         }
855         case op_pre_inc: {
856             int r0 = (++it)->u.operand;
857             out.printf("[%4d] pre_inc\t\t %s", location, registerName(exec, r0).data());
858             break;
859         }
860         case op_pre_dec: {
861             int r0 = (++it)->u.operand;
862             out.printf("[%4d] pre_dec\t\t %s", location, registerName(exec, r0).data());
863             break;
864         }
865         case op_post_inc: {
866             printUnaryOp(out, exec, location, it, "post_inc");
867             break;
868         }
869         case op_post_dec: {
870             printUnaryOp(out, exec, location, it, "post_dec");
871             break;
872         }
873         case op_to_jsnumber: {
874             printUnaryOp(out, exec, location, it, "to_jsnumber");
875             break;
876         }
877         case op_negate: {
878             printUnaryOp(out, exec, location, it, "negate");
879             break;
880         }
881         case op_add: {
882             printBinaryOp(out, exec, location, it, "add");
883             ++it;
884             break;
885         }
886         case op_mul: {
887             printBinaryOp(out, exec, location, it, "mul");
888             ++it;
889             break;
890         }
891         case op_div: {
892             printBinaryOp(out, exec, location, it, "div");
893             ++it;
894             break;
895         }
896         case op_mod: {
897             printBinaryOp(out, exec, location, it, "mod");
898             break;
899         }
900         case op_sub: {
901             printBinaryOp(out, exec, location, it, "sub");
902             ++it;
903             break;
904         }
905         case op_lshift: {
906             printBinaryOp(out, exec, location, it, "lshift");
907             break;            
908         }
909         case op_rshift: {
910             printBinaryOp(out, exec, location, it, "rshift");
911             break;
912         }
913         case op_urshift: {
914             printBinaryOp(out, exec, location, it, "urshift");
915             break;
916         }
917         case op_bitand: {
918             printBinaryOp(out, exec, location, it, "bitand");
919             ++it;
920             break;
921         }
922         case op_bitxor: {
923             printBinaryOp(out, exec, location, it, "bitxor");
924             ++it;
925             break;
926         }
927         case op_bitor: {
928             printBinaryOp(out, exec, location, it, "bitor");
929             ++it;
930             break;
931         }
932         case op_check_has_instance: {
933             int r0 = (++it)->u.operand;
934             int r1 = (++it)->u.operand;
935             int r2 = (++it)->u.operand;
936             int offset = (++it)->u.operand;
937             out.printf("[%4d] check_has_instance\t\t %s, %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), offset, location + offset);
938             break;
939         }
940         case op_instanceof: {
941             int r0 = (++it)->u.operand;
942             int r1 = (++it)->u.operand;
943             int r2 = (++it)->u.operand;
944             out.printf("[%4d] instanceof\t\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
945             break;
946         }
947         case op_typeof: {
948             printUnaryOp(out, exec, location, it, "typeof");
949             break;
950         }
951         case op_is_undefined: {
952             printUnaryOp(out, exec, location, it, "is_undefined");
953             break;
954         }
955         case op_is_boolean: {
956             printUnaryOp(out, exec, location, it, "is_boolean");
957             break;
958         }
959         case op_is_number: {
960             printUnaryOp(out, exec, location, it, "is_number");
961             break;
962         }
963         case op_is_string: {
964             printUnaryOp(out, exec, location, it, "is_string");
965             break;
966         }
967         case op_is_object: {
968             printUnaryOp(out, exec, location, it, "is_object");
969             break;
970         }
971         case op_is_function: {
972             printUnaryOp(out, exec, location, it, "is_function");
973             break;
974         }
975         case op_in: {
976             printBinaryOp(out, exec, location, it, "in");
977             break;
978         }
979         case op_put_to_base_variable:
980         case op_put_to_base: {
981             int base = (++it)->u.operand;
982             int id0 = (++it)->u.operand;
983             int value = (++it)->u.operand;
984             int resolveInfo = (++it)->u.operand;
985             out.printf("[%4d] put_to_base\t %s, %s, %s, %d", location, registerName(exec, base).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, value).data(), resolveInfo);
986             break;
987         }
988         case op_resolve:
989         case op_resolve_global_property:
990         case op_resolve_global_var:
991         case op_resolve_scoped_var:
992         case op_resolve_scoped_var_on_top_scope:
993         case op_resolve_scoped_var_with_top_scope_check: {
994             int r0 = (++it)->u.operand;
995             int id0 = (++it)->u.operand;
996             int resolveInfo = (++it)->u.operand;
997             out.printf("[%4d] resolve\t\t %s, %s, %d", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo);
998             dumpValueProfiling(out, it, hasPrintedProfiling);
999             break;
1000         }
1001         case op_init_global_const_nop: {
1002             out.printf("[%4d] init_global_const_nop\t", location);
1003             it++;
1004             it++;
1005             it++;
1006             it++;
1007             break;
1008         }
1009         case op_init_global_const: {
1010             WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
1011             int r0 = (++it)->u.operand;
1012             out.printf("[%4d] init_global_const\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
1013             it++;
1014             it++;
1015             break;
1016         }
1017         case op_init_global_const_check: {
1018             WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
1019             int r0 = (++it)->u.operand;
1020             out.printf("[%4d] init_global_const_check\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
1021             it++;
1022             it++;
1023             break;
1024         }
1025         case op_resolve_base_to_global:
1026         case op_resolve_base_to_global_dynamic:
1027         case op_resolve_base_to_scope:
1028         case op_resolve_base_to_scope_with_top_scope_check:
1029         case op_resolve_base: {
1030             int r0 = (++it)->u.operand;
1031             int id0 = (++it)->u.operand;
1032             int isStrict = (++it)->u.operand;
1033             int resolveInfo = (++it)->u.operand;
1034             int putToBaseInfo = (++it)->u.operand;
1035             out.printf("[%4d] resolve_base%s\t %s, %s, %d, %d", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo, putToBaseInfo);
1036             dumpValueProfiling(out, it, hasPrintedProfiling);
1037             break;
1038         }
1039         case op_ensure_property_exists: {
1040             int r0 = (++it)->u.operand;
1041             int id0 = (++it)->u.operand;
1042             out.printf("[%4d] ensure_property_exists\t %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
1043             break;
1044         }
1045         case op_resolve_with_base: {
1046             int r0 = (++it)->u.operand;
1047             int r1 = (++it)->u.operand;
1048             int id0 = (++it)->u.operand;
1049             int resolveInfo = (++it)->u.operand;
1050             int putToBaseInfo = (++it)->u.operand;
1051             out.printf("[%4d] resolve_with_base %s, %s, %s, %d, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo, putToBaseInfo);
1052             dumpValueProfiling(out, it, hasPrintedProfiling);
1053             break;
1054         }
1055         case op_resolve_with_this: {
1056             int r0 = (++it)->u.operand;
1057             int r1 = (++it)->u.operand;
1058             int id0 = (++it)->u.operand;
1059             int resolveInfo = (++it)->u.operand;
1060             out.printf("[%4d] resolve_with_this %s, %s, %s, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data(), resolveInfo);
1061             dumpValueProfiling(out, it, hasPrintedProfiling);
1062             break;
1063         }
1064         case op_get_by_id:
1065         case op_get_by_id_out_of_line:
1066         case op_get_by_id_self:
1067         case op_get_by_id_proto:
1068         case op_get_by_id_chain:
1069         case op_get_by_id_getter_self:
1070         case op_get_by_id_getter_proto:
1071         case op_get_by_id_getter_chain:
1072         case op_get_by_id_custom_self:
1073         case op_get_by_id_custom_proto:
1074         case op_get_by_id_custom_chain:
1075         case op_get_by_id_generic:
1076         case op_get_array_length:
1077         case op_get_string_length: {
1078             printGetByIdOp(out, exec, location, it);
1079             printGetByIdCacheStatus(out, exec, location);
1080             dumpValueProfiling(out, it, hasPrintedProfiling);
1081             break;
1082         }
1083         case op_get_arguments_length: {
1084             printUnaryOp(out, exec, location, it, "get_arguments_length");
1085             it++;
1086             break;
1087         }
1088         case op_put_by_id: {
1089             printPutByIdOp(out, exec, location, it, "put_by_id");
1090             break;
1091         }
1092         case op_put_by_id_out_of_line: {
1093             printPutByIdOp(out, exec, location, it, "put_by_id_out_of_line");
1094             break;
1095         }
1096         case op_put_by_id_replace: {
1097             printPutByIdOp(out, exec, location, it, "put_by_id_replace");
1098             break;
1099         }
1100         case op_put_by_id_transition: {
1101             printPutByIdOp(out, exec, location, it, "put_by_id_transition");
1102             break;
1103         }
1104         case op_put_by_id_transition_direct: {
1105             printPutByIdOp(out, exec, location, it, "put_by_id_transition_direct");
1106             break;
1107         }
1108         case op_put_by_id_transition_direct_out_of_line: {
1109             printPutByIdOp(out, exec, location, it, "put_by_id_transition_direct_out_of_line");
1110             break;
1111         }
1112         case op_put_by_id_transition_normal: {
1113             printPutByIdOp(out, exec, location, it, "put_by_id_transition_normal");
1114             break;
1115         }
1116         case op_put_by_id_transition_normal_out_of_line: {
1117             printPutByIdOp(out, exec, location, it, "put_by_id_transition_normal_out_of_line");
1118             break;
1119         }
1120         case op_put_by_id_generic: {
1121             printPutByIdOp(out, exec, location, it, "put_by_id_generic");
1122             break;
1123         }
1124         case op_put_getter_setter: {
1125             int r0 = (++it)->u.operand;
1126             int id0 = (++it)->u.operand;
1127             int r1 = (++it)->u.operand;
1128             int r2 = (++it)->u.operand;
1129             out.printf("[%4d] put_getter_setter\t %s, %s, %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
1130             break;
1131         }
1132         case op_del_by_id: {
1133             int r0 = (++it)->u.operand;
1134             int r1 = (++it)->u.operand;
1135             int id0 = (++it)->u.operand;
1136             out.printf("[%4d] del_by_id\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
1137             break;
1138         }
1139         case op_get_by_val: {
1140             int r0 = (++it)->u.operand;
1141             int r1 = (++it)->u.operand;
1142             int r2 = (++it)->u.operand;
1143             out.printf("[%4d] get_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
1144             dumpArrayProfiling(out, it, hasPrintedProfiling);
1145             dumpValueProfiling(out, it, hasPrintedProfiling);
1146             break;
1147         }
1148         case op_get_argument_by_val: {
1149             int r0 = (++it)->u.operand;
1150             int r1 = (++it)->u.operand;
1151             int r2 = (++it)->u.operand;
1152             out.printf("[%4d] get_argument_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
1153             ++it;
1154             dumpValueProfiling(out, it, hasPrintedProfiling);
1155             break;
1156         }
1157         case op_get_by_pname: {
1158             int r0 = (++it)->u.operand;
1159             int r1 = (++it)->u.operand;
1160             int r2 = (++it)->u.operand;
1161             int r3 = (++it)->u.operand;
1162             int r4 = (++it)->u.operand;
1163             int r5 = (++it)->u.operand;
1164             out.printf("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), registerName(exec, r4).data(), registerName(exec, r5).data());
1165             break;
1166         }
1167         case op_put_by_val: {
1168             int r0 = (++it)->u.operand;
1169             int r1 = (++it)->u.operand;
1170             int r2 = (++it)->u.operand;
1171             out.printf("[%4d] put_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
1172             dumpArrayProfiling(out, it, hasPrintedProfiling);
1173             break;
1174         }
1175         case op_del_by_val: {
1176             int r0 = (++it)->u.operand;
1177             int r1 = (++it)->u.operand;
1178             int r2 = (++it)->u.operand;
1179             out.printf("[%4d] del_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
1180             break;
1181         }
1182         case op_put_by_index: {
1183             int r0 = (++it)->u.operand;
1184             unsigned n0 = (++it)->u.operand;
1185             int r1 = (++it)->u.operand;
1186             out.printf("[%4d] put_by_index\t %s, %u, %s", location, registerName(exec, r0).data(), n0, registerName(exec, r1).data());
1187             break;
1188         }
1189         case op_jmp: {
1190             int offset = (++it)->u.operand;
1191             out.printf("[%4d] jmp\t\t %d(->%d)", location, offset, location + offset);
1192             break;
1193         }
1194         case op_loop: {
1195             int offset = (++it)->u.operand;
1196             out.printf("[%4d] loop\t\t %d(->%d)", location, offset, location + offset);
1197             break;
1198         }
1199         case op_jtrue: {
1200             printConditionalJump(out, exec, begin, it, location, "jtrue");
1201             break;
1202         }
1203         case op_loop_if_true: {
1204             printConditionalJump(out, exec, begin, it, location, "loop_if_true");
1205             break;
1206         }
1207         case op_loop_if_false: {
1208             printConditionalJump(out, exec, begin, it, location, "loop_if_false");
1209             break;
1210         }
1211         case op_jfalse: {
1212             printConditionalJump(out, exec, begin, it, location, "jfalse");
1213             break;
1214         }
1215         case op_jeq_null: {
1216             printConditionalJump(out, exec, begin, it, location, "jeq_null");
1217             break;
1218         }
1219         case op_jneq_null: {
1220             printConditionalJump(out, exec, begin, it, location, "jneq_null");
1221             break;
1222         }
1223         case op_jneq_ptr: {
1224             int r0 = (++it)->u.operand;
1225             Special::Pointer pointer = (++it)->u.specialPointer;
1226             int offset = (++it)->u.operand;
1227             out.printf("[%4d] jneq_ptr\t\t %s, %d (%p), %d(->%d)", location, registerName(exec, r0).data(), pointer, m_globalObject->actualPointerFor(pointer), offset, location + offset);
1228             break;
1229         }
1230         case op_jless: {
1231             int r0 = (++it)->u.operand;
1232             int r1 = (++it)->u.operand;
1233             int offset = (++it)->u.operand;
1234             out.printf("[%4d] jless\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1235             break;
1236         }
1237         case op_jlesseq: {
1238             int r0 = (++it)->u.operand;
1239             int r1 = (++it)->u.operand;
1240             int offset = (++it)->u.operand;
1241             out.printf("[%4d] jlesseq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1242             break;
1243         }
1244         case op_jgreater: {
1245             int r0 = (++it)->u.operand;
1246             int r1 = (++it)->u.operand;
1247             int offset = (++it)->u.operand;
1248             out.printf("[%4d] jgreater\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1249             break;
1250         }
1251         case op_jgreatereq: {
1252             int r0 = (++it)->u.operand;
1253             int r1 = (++it)->u.operand;
1254             int offset = (++it)->u.operand;
1255             out.printf("[%4d] jgreatereq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1256             break;
1257         }
1258         case op_jnless: {
1259             int r0 = (++it)->u.operand;
1260             int r1 = (++it)->u.operand;
1261             int offset = (++it)->u.operand;
1262             out.printf("[%4d] jnless\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1263             break;
1264         }
1265         case op_jnlesseq: {
1266             int r0 = (++it)->u.operand;
1267             int r1 = (++it)->u.operand;
1268             int offset = (++it)->u.operand;
1269             out.printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1270             break;
1271         }
1272         case op_jngreater: {
1273             int r0 = (++it)->u.operand;
1274             int r1 = (++it)->u.operand;
1275             int offset = (++it)->u.operand;
1276             out.printf("[%4d] jngreater\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1277             break;
1278         }
1279         case op_jngreatereq: {
1280             int r0 = (++it)->u.operand;
1281             int r1 = (++it)->u.operand;
1282             int offset = (++it)->u.operand;
1283             out.printf("[%4d] jngreatereq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1284             break;
1285         }
1286         case op_loop_if_less: {
1287             int r0 = (++it)->u.operand;
1288             int r1 = (++it)->u.operand;
1289             int offset = (++it)->u.operand;
1290             out.printf("[%4d] loop_if_less\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1291             break;
1292         }
1293         case op_loop_if_lesseq: {
1294             int r0 = (++it)->u.operand;
1295             int r1 = (++it)->u.operand;
1296             int offset = (++it)->u.operand;
1297             out.printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1298             break;
1299         }
1300         case op_loop_if_greater: {
1301             int r0 = (++it)->u.operand;
1302             int r1 = (++it)->u.operand;
1303             int offset = (++it)->u.operand;
1304             out.printf("[%4d] loop_if_greater\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1305             break;
1306         }
1307         case op_loop_if_greatereq: {
1308             int r0 = (++it)->u.operand;
1309             int r1 = (++it)->u.operand;
1310             int offset = (++it)->u.operand;
1311             out.printf("[%4d] loop_if_greatereq\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
1312             break;
1313         }
1314         case op_loop_hint: {
1315             out.printf("[%4d] loop_hint", location);
1316             break;
1317         }
1318         case op_switch_imm: {
1319             int tableIndex = (++it)->u.operand;
1320             int defaultTarget = (++it)->u.operand;
1321             int scrutineeRegister = (++it)->u.operand;
1322             out.printf("[%4d] switch_imm\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
1323             break;
1324         }
1325         case op_switch_char: {
1326             int tableIndex = (++it)->u.operand;
1327             int defaultTarget = (++it)->u.operand;
1328             int scrutineeRegister = (++it)->u.operand;
1329             out.printf("[%4d] switch_char\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
1330             break;
1331         }
1332         case op_switch_string: {
1333             int tableIndex = (++it)->u.operand;
1334             int defaultTarget = (++it)->u.operand;
1335             int scrutineeRegister = (++it)->u.operand;
1336             out.printf("[%4d] switch_string\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
1337             break;
1338         }
1339         case op_new_func: {
1340             int r0 = (++it)->u.operand;
1341             int f0 = (++it)->u.operand;
1342             int shouldCheck = (++it)->u.operand;
1343             out.printf("[%4d] new_func\t\t %s, f%d, %s", location, registerName(exec, r0).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>");
1344             break;
1345         }
1346         case op_new_func_exp: {
1347             int r0 = (++it)->u.operand;
1348             int f0 = (++it)->u.operand;
1349             out.printf("[%4d] new_func_exp\t %s, f%d", location, registerName(exec, r0).data(), f0);
1350             break;
1351         }
1352         case op_call: {
1353             printCallOp(out, exec, location, it, "call", DumpCaches);
1354             break;
1355         }
1356         case op_call_eval: {
1357             printCallOp(out, exec, location, it, "call_eval", DontDumpCaches);
1358             break;
1359         }
1360         case op_call_varargs: {
1361             int callee = (++it)->u.operand;
1362             int thisValue = (++it)->u.operand;
1363             int arguments = (++it)->u.operand;
1364             int firstFreeRegister = (++it)->u.operand;
1365             out.printf("[%4d] call_varargs\t %s, %s, %s, %d", location, registerName(exec, callee).data(), registerName(exec, thisValue).data(), registerName(exec, arguments).data(), firstFreeRegister);
1366             break;
1367         }
1368         case op_tear_off_activation: {
1369             int r0 = (++it)->u.operand;
1370             out.printf("[%4d] tear_off_activation\t %s", location, registerName(exec, r0).data());
1371             break;
1372         }
1373         case op_tear_off_arguments: {
1374             int r0 = (++it)->u.operand;
1375             int r1 = (++it)->u.operand;
1376             out.printf("[%4d] tear_off_arguments %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
1377             break;
1378         }
1379         case op_ret: {
1380             int r0 = (++it)->u.operand;
1381             out.printf("[%4d] ret\t\t %s", location, registerName(exec, r0).data());
1382             break;
1383         }
1384         case op_call_put_result: {
1385             int r0 = (++it)->u.operand;
1386             out.printf("[%4d] call_put_result\t\t %s", location, registerName(exec, r0).data());
1387             dumpValueProfiling(out, it, hasPrintedProfiling);
1388             break;
1389         }
1390         case op_ret_object_or_this: {
1391             int r0 = (++it)->u.operand;
1392             int r1 = (++it)->u.operand;
1393             out.printf("[%4d] constructor_ret\t\t %s %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
1394             break;
1395         }
1396         case op_construct: {
1397             printCallOp(out, exec, location, it, "construct", DumpCaches);
1398             break;
1399         }
1400         case op_strcat: {
1401             int r0 = (++it)->u.operand;
1402             int r1 = (++it)->u.operand;
1403             int count = (++it)->u.operand;
1404             out.printf("[%4d] strcat\t\t %s, %s, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), count);
1405             break;
1406         }
1407         case op_to_primitive: {
1408             int r0 = (++it)->u.operand;
1409             int r1 = (++it)->u.operand;
1410             out.printf("[%4d] to_primitive\t %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
1411             break;
1412         }
1413         case op_get_pnames: {
1414             int r0 = it[1].u.operand;
1415             int r1 = it[2].u.operand;
1416             int r2 = it[3].u.operand;
1417             int r3 = it[4].u.operand;
1418             int offset = it[5].u.operand;
1419             out.printf("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), offset, location + offset);
1420             it += OPCODE_LENGTH(op_get_pnames) - 1;
1421             break;
1422         }
1423         case op_next_pname: {
1424             int dest = it[1].u.operand;
1425             int base = it[2].u.operand;
1426             int i = it[3].u.operand;
1427             int size = it[4].u.operand;
1428             int iter = it[5].u.operand;
1429             int offset = it[6].u.operand;
1430             out.printf("[%4d] next_pname\t %s, %s, %s, %s, %s, %d(->%d)", location, registerName(exec, dest).data(), registerName(exec, base).data(), registerName(exec, i).data(), registerName(exec, size).data(), registerName(exec, iter).data(), offset, location + offset);
1431             it += OPCODE_LENGTH(op_next_pname) - 1;
1432             break;
1433         }
1434         case op_push_with_scope: {
1435             int r0 = (++it)->u.operand;
1436             out.printf("[%4d] push_with_scope\t %s", location, registerName(exec, r0).data());
1437             break;
1438         }
1439         case op_pop_scope: {
1440             out.printf("[%4d] pop_scope", location);
1441             break;
1442         }
1443         case op_push_name_scope: {
1444             int id0 = (++it)->u.operand;
1445             int r1 = (++it)->u.operand;
1446             unsigned attributes = (++it)->u.operand;
1447             out.printf("[%4d] push_name_scope \t%s, %s, %u", location, idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), attributes);
1448             break;
1449         }
1450         case op_jmp_scopes: {
1451             int scopeDelta = (++it)->u.operand;
1452             int offset = (++it)->u.operand;
1453             out.printf("[%4d] jmp_scopes\t^%d, %d(->%d)", location, scopeDelta, offset, location + offset);
1454             break;
1455         }
1456         case op_catch: {
1457             int r0 = (++it)->u.operand;
1458             out.printf("[%4d] catch\t\t %s", location, registerName(exec, r0).data());
1459             break;
1460         }
1461         case op_throw: {
1462             int r0 = (++it)->u.operand;
1463             out.printf("[%4d] throw\t\t %s", location, registerName(exec, r0).data());
1464             break;
1465         }
1466         case op_throw_static_error: {
1467             int k0 = (++it)->u.operand;
1468             int k1 = (++it)->u.operand;
1469             out.printf("[%4d] throw_static_error\t %s, %s", location, constantName(exec, k0, getConstant(k0)).data(), k1 ? "true" : "false");
1470             break;
1471         }
1472         case op_debug: {
1473             int debugHookID = (++it)->u.operand;
1474             int firstLine = (++it)->u.operand;
1475             int lastLine = (++it)->u.operand;
1476             int column = (++it)->u.operand;
1477             out.printf("[%4d] debug\t\t %s, %d, %d, %d", location, debugHookName(debugHookID), firstLine, lastLine, column);
1478             break;
1479         }
1480         case op_profile_will_call: {
1481             int function = (++it)->u.operand;
1482             out.printf("[%4d] profile_will_call %s", location, registerName(exec, function).data());
1483             break;
1484         }
1485         case op_profile_did_call: {
1486             int function = (++it)->u.operand;
1487             out.printf("[%4d] profile_did_call\t %s", location, registerName(exec, function).data());
1488             break;
1489         }
1490         case op_end: {
1491             int r0 = (++it)->u.operand;
1492             out.printf("[%4d] end\t\t %s", location, registerName(exec, r0).data());
1493             break;
1494         }
1495 #if ENABLE(LLINT_C_LOOP)
1496         default:
1497             RELEASE_ASSERT_NOT_REACHED();
1498 #endif
1499     }
1500
1501 #if ENABLE(VALUE_PROFILER)
1502     dumpRareCaseProfile(out, "rare case: ", rareCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
1503     dumpRareCaseProfile(out, "special fast case: ", specialFastCaseProfileForBytecodeOffset(location), hasPrintedProfiling);
1504 #endif
1505     
1506     dumpBytecodeCommentAndNewLine(out, location);
1507 }
1508
1509 void CodeBlock::dumpBytecode(PrintStream& out, unsigned bytecodeOffset)
1510 {
1511     ExecState* exec = m_globalObject->globalExec();
1512     const Instruction* it = instructions().begin() + bytecodeOffset;
1513     dumpBytecode(out, exec, instructions().begin(), it);
1514 }
1515
1516 #if DUMP_CODE_BLOCK_STATISTICS
1517 static HashSet<CodeBlock*> liveCodeBlockSet;
1518 #endif
1519
1520 #define FOR_EACH_MEMBER_VECTOR(macro) \
1521     macro(instructions) \
1522     macro(globalResolveInfos) \
1523     macro(structureStubInfos) \
1524     macro(callLinkInfos) \
1525     macro(linkedCallerList) \
1526     macro(identifiers) \
1527     macro(functionExpressions) \
1528     macro(constantRegisters)
1529
1530 #define FOR_EACH_MEMBER_VECTOR_RARE_DATA(macro) \
1531     macro(regexps) \
1532     macro(functions) \
1533     macro(exceptionHandlers) \
1534     macro(immediateSwitchJumpTables) \
1535     macro(characterSwitchJumpTables) \
1536     macro(stringSwitchJumpTables) \
1537     macro(evalCodeCache) \
1538     macro(expressionInfo) \
1539     macro(lineInfo) \
1540     macro(callReturnIndexVector)
1541
1542 template<typename T>
1543 static size_t sizeInBytes(const Vector<T>& vector)
1544 {
1545     return vector.capacity() * sizeof(T);
1546 }
1547
1548 void CodeBlock::dumpStatistics()
1549 {
1550 #if DUMP_CODE_BLOCK_STATISTICS
1551     #define DEFINE_VARS(name) size_t name##IsNotEmpty = 0; size_t name##TotalSize = 0;
1552         FOR_EACH_MEMBER_VECTOR(DEFINE_VARS)
1553         FOR_EACH_MEMBER_VECTOR_RARE_DATA(DEFINE_VARS)
1554     #undef DEFINE_VARS
1555
1556     // Non-vector data members
1557     size_t evalCodeCacheIsNotEmpty = 0;
1558
1559     size_t symbolTableIsNotEmpty = 0;
1560     size_t symbolTableTotalSize = 0;
1561
1562     size_t hasRareData = 0;
1563
1564     size_t isFunctionCode = 0;
1565     size_t isGlobalCode = 0;
1566     size_t isEvalCode = 0;
1567
1568     HashSet<CodeBlock*>::const_iterator end = liveCodeBlockSet.end();
1569     for (HashSet<CodeBlock*>::const_iterator it = liveCodeBlockSet.begin(); it != end; ++it) {
1570         CodeBlock* codeBlock = *it;
1571
1572         #define GET_STATS(name) if (!codeBlock->m_##name.isEmpty()) { name##IsNotEmpty++; name##TotalSize += sizeInBytes(codeBlock->m_##name); }
1573             FOR_EACH_MEMBER_VECTOR(GET_STATS)
1574         #undef GET_STATS
1575
1576         if (codeBlock->symbolTable() && !codeBlock->symbolTable()->isEmpty()) {
1577             symbolTableIsNotEmpty++;
1578             symbolTableTotalSize += (codeBlock->symbolTable()->capacity() * (sizeof(SymbolTable::KeyType) + sizeof(SymbolTable::MappedType)));
1579         }
1580
1581         if (codeBlock->m_rareData) {
1582             hasRareData++;
1583             #define GET_STATS(name) if (!codeBlock->m_rareData->m_##name.isEmpty()) { name##IsNotEmpty++; name##TotalSize += sizeInBytes(codeBlock->m_rareData->m_##name); }
1584                 FOR_EACH_MEMBER_VECTOR_RARE_DATA(GET_STATS)
1585             #undef GET_STATS
1586
1587             if (!codeBlock->m_rareData->m_evalCodeCache.isEmpty())
1588                 evalCodeCacheIsNotEmpty++;
1589         }
1590
1591         switch (codeBlock->codeType()) {
1592             case FunctionCode:
1593                 ++isFunctionCode;
1594                 break;
1595             case GlobalCode:
1596                 ++isGlobalCode;
1597                 break;
1598             case EvalCode:
1599                 ++isEvalCode;
1600                 break;
1601         }
1602     }
1603
1604     size_t totalSize = 0;
1605
1606     #define GET_TOTAL_SIZE(name) totalSize += name##TotalSize;
1607         FOR_EACH_MEMBER_VECTOR(GET_TOTAL_SIZE)
1608         FOR_EACH_MEMBER_VECTOR_RARE_DATA(GET_TOTAL_SIZE)
1609     #undef GET_TOTAL_SIZE
1610
1611     totalSize += symbolTableTotalSize;
1612     totalSize += (liveCodeBlockSet.size() * sizeof(CodeBlock));
1613
1614     dataLogF("Number of live CodeBlocks: %d\n", liveCodeBlockSet.size());
1615     dataLogF("Size of a single CodeBlock [sizeof(CodeBlock)]: %zu\n", sizeof(CodeBlock));
1616     dataLogF("Size of all CodeBlocks: %zu\n", totalSize);
1617     dataLogF("Average size of a CodeBlock: %zu\n", totalSize / liveCodeBlockSet.size());
1618
1619     dataLogF("Number of FunctionCode CodeBlocks: %zu (%.3f%%)\n", isFunctionCode, static_cast<double>(isFunctionCode) * 100.0 / liveCodeBlockSet.size());
1620     dataLogF("Number of GlobalCode CodeBlocks: %zu (%.3f%%)\n", isGlobalCode, static_cast<double>(isGlobalCode) * 100.0 / liveCodeBlockSet.size());
1621     dataLogF("Number of EvalCode CodeBlocks: %zu (%.3f%%)\n", isEvalCode, static_cast<double>(isEvalCode) * 100.0 / liveCodeBlockSet.size());
1622
1623     dataLogF("Number of CodeBlocks with rare data: %zu (%.3f%%)\n", hasRareData, static_cast<double>(hasRareData) * 100.0 / liveCodeBlockSet.size());
1624
1625     #define PRINT_STATS(name) dataLogF("Number of CodeBlocks with " #name ": %zu\n", name##IsNotEmpty); dataLogF("Size of all " #name ": %zu\n", name##TotalSize); 
1626         FOR_EACH_MEMBER_VECTOR(PRINT_STATS)
1627         FOR_EACH_MEMBER_VECTOR_RARE_DATA(PRINT_STATS)
1628     #undef PRINT_STATS
1629
1630     dataLogF("Number of CodeBlocks with evalCodeCache: %zu\n", evalCodeCacheIsNotEmpty);
1631     dataLogF("Number of CodeBlocks with symbolTable: %zu\n", symbolTableIsNotEmpty);
1632
1633     dataLogF("Size of all symbolTables: %zu\n", symbolTableTotalSize);
1634
1635 #else
1636     dataLogF("Dumping CodeBlock statistics is not enabled.\n");
1637 #endif
1638 }
1639
1640 CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other)
1641     : m_globalObject(other.m_globalObject)
1642     , m_heap(other.m_heap)
1643     , m_numCalleeRegisters(other.m_numCalleeRegisters)
1644     , m_numVars(other.m_numVars)
1645     , m_isConstructor(other.m_isConstructor)
1646     , m_unlinkedCode(*other.m_globalData, other.m_ownerExecutable.get(), other.m_unlinkedCode.get())
1647     , m_ownerExecutable(*other.m_globalData, other.m_ownerExecutable.get(), other.m_ownerExecutable.get())
1648     , m_globalData(other.m_globalData)
1649     , m_instructions(other.m_instructions)
1650     , m_thisRegister(other.m_thisRegister)
1651     , m_argumentsRegister(other.m_argumentsRegister)
1652     , m_activationRegister(other.m_activationRegister)
1653     , m_isStrictMode(other.m_isStrictMode)
1654     , m_source(other.m_source)
1655     , m_sourceOffset(other.m_sourceOffset)
1656     , m_identifiers(other.m_identifiers)
1657     , m_constantRegisters(other.m_constantRegisters)
1658     , m_functionDecls(other.m_functionDecls)
1659     , m_functionExprs(other.m_functionExprs)
1660     , m_osrExitCounter(0)
1661     , m_optimizationDelayCounter(0)
1662     , m_reoptimizationRetryCounter(0)
1663     , m_resolveOperations(other.m_resolveOperations)
1664     , m_putToBaseOperations(other.m_putToBaseOperations)
1665 #if ENABLE(BYTECODE_COMMENTS)
1666     , m_bytecodeCommentIterator(0)
1667 #endif
1668 #if ENABLE(JIT)
1669     , m_canCompileWithDFGState(DFG::CapabilityLevelNotSet)
1670 #endif
1671 {
1672     setNumParameters(other.numParameters());
1673     optimizeAfterWarmUp();
1674     jitAfterWarmUp();
1675
1676     if (other.m_rareData) {
1677         createRareDataIfNecessary();
1678         
1679         m_rareData->m_exceptionHandlers = other.m_rareData->m_exceptionHandlers;
1680         m_rareData->m_constantBuffers = other.m_rareData->m_constantBuffers;
1681         m_rareData->m_immediateSwitchJumpTables = other.m_rareData->m_immediateSwitchJumpTables;
1682         m_rareData->m_characterSwitchJumpTables = other.m_rareData->m_characterSwitchJumpTables;
1683         m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables;
1684     }
1685 }
1686
1687 CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlinkedCodeBlock, JSGlobalObject* globalObject, unsigned baseScopeDepth, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative)
1688     : m_globalObject(globalObject->globalData(), ownerExecutable, globalObject)
1689     , m_heap(&m_globalObject->globalData().heap)
1690     , m_numCalleeRegisters(unlinkedCodeBlock->m_numCalleeRegisters)
1691     , m_numVars(unlinkedCodeBlock->m_numVars)
1692     , m_isConstructor(unlinkedCodeBlock->isConstructor())
1693     , m_unlinkedCode(globalObject->globalData(), ownerExecutable, unlinkedCodeBlock)
1694     , m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable)
1695     , m_globalData(unlinkedCodeBlock->globalData())
1696     , m_thisRegister(unlinkedCodeBlock->thisRegister())
1697     , m_argumentsRegister(unlinkedCodeBlock->argumentsRegister())
1698     , m_activationRegister(unlinkedCodeBlock->activationRegister())
1699     , m_isStrictMode(unlinkedCodeBlock->isStrictMode())
1700     , m_source(sourceProvider)
1701     , m_sourceOffset(sourceOffset)
1702     , m_alternative(alternative)
1703     , m_osrExitCounter(0)
1704     , m_optimizationDelayCounter(0)
1705     , m_reoptimizationRetryCounter(0)
1706 #if ENABLE(BYTECODE_COMMENTS)
1707     , m_bytecodeCommentIterator(0)
1708 #endif
1709 {
1710     m_globalData->startedCompiling(this);
1711
1712     ASSERT(m_source);
1713     setNumParameters(unlinkedCodeBlock->numParameters());
1714
1715 #if DUMP_CODE_BLOCK_STATISTICS
1716     liveCodeBlockSet.add(this);
1717 #endif
1718     setIdentifiers(unlinkedCodeBlock->identifiers());
1719     setConstantRegisters(unlinkedCodeBlock->constantRegisters());
1720
1721     m_functionDecls.grow(unlinkedCodeBlock->numberOfFunctionDecls());
1722     for (size_t count = unlinkedCodeBlock->numberOfFunctionDecls(), i = 0; i < count; ++i) {
1723         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
1724         unsigned lineCount = unlinkedExecutable->lineCount();
1725         unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
1726         unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
1727         unsigned sourceLength = unlinkedExecutable->sourceLength();
1728         SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine);
1729         FunctionExecutable* executable = FunctionExecutable::create(*m_globalData, code, unlinkedExecutable, firstLine, firstLine + lineCount);
1730         m_functionDecls[i].set(*m_globalData, ownerExecutable, executable);
1731     }
1732
1733     m_functionExprs.grow(unlinkedCodeBlock->numberOfFunctionExprs());
1734     for (size_t count = unlinkedCodeBlock->numberOfFunctionExprs(), i = 0; i < count; ++i) {
1735         UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
1736         unsigned lineCount = unlinkedExecutable->lineCount();
1737         unsigned firstLine = ownerExecutable->lineNo() + unlinkedExecutable->firstLineOffset();
1738         unsigned startOffset = sourceOffset + unlinkedExecutable->startOffset();
1739         unsigned sourceLength = unlinkedExecutable->sourceLength();
1740         SourceCode code(m_source, startOffset, startOffset + sourceLength, firstLine);
1741         FunctionExecutable* executable = FunctionExecutable::create(*m_globalData, code, unlinkedExecutable, firstLine, firstLine + lineCount);
1742         m_functionExprs[i].set(*m_globalData, ownerExecutable, executable);
1743     }
1744
1745     if (unlinkedCodeBlock->hasRareData()) {
1746         createRareDataIfNecessary();
1747         if (size_t count = unlinkedCodeBlock->constantBufferCount()) {
1748             m_rareData->m_constantBuffers.grow(count);
1749             for (size_t i = 0; i < count; i++) {
1750                 const UnlinkedCodeBlock::ConstantBuffer& buffer = unlinkedCodeBlock->constantBuffer(i);
1751                 m_rareData->m_constantBuffers[i] = buffer;
1752             }
1753         }
1754         if (size_t count = unlinkedCodeBlock->numberOfExceptionHandlers()) {
1755             m_rareData->m_exceptionHandlers.grow(count);
1756             for (size_t i = 0; i < count; i++) {
1757                 const UnlinkedHandlerInfo& handler = unlinkedCodeBlock->exceptionHandler(i);
1758                 m_rareData->m_exceptionHandlers[i].start = handler.start;
1759                 m_rareData->m_exceptionHandlers[i].end = handler.end;
1760                 m_rareData->m_exceptionHandlers[i].target = handler.target;
1761                 m_rareData->m_exceptionHandlers[i].scopeDepth = handler.scopeDepth + baseScopeDepth;
1762 #if ENABLE(JIT) && ENABLE(LLINT)
1763                 m_rareData->m_exceptionHandlers[i].nativeCode = CodeLocationLabel(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(llint_op_catch)));
1764 #endif
1765             }
1766         }
1767
1768         if (size_t count = unlinkedCodeBlock->numberOfStringSwitchJumpTables()) {
1769             m_rareData->m_stringSwitchJumpTables.grow(count);
1770             for (size_t i = 0; i < count; i++) {
1771                 UnlinkedStringJumpTable::StringOffsetTable::iterator ptr = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.begin();
1772                 UnlinkedStringJumpTable::StringOffsetTable::iterator end = unlinkedCodeBlock->stringSwitchJumpTable(i).offsetTable.end();
1773                 for (; ptr != end; ++ptr) {
1774                     OffsetLocation offset;
1775                     offset.branchOffset = ptr->value;
1776                     m_rareData->m_stringSwitchJumpTables[i].offsetTable.add(ptr->key, offset);
1777                 }
1778             }
1779         }
1780
1781         if (size_t count = unlinkedCodeBlock->numberOfImmediateSwitchJumpTables()) {
1782             m_rareData->m_immediateSwitchJumpTables.grow(count);
1783             for (size_t i = 0; i < count; i++) {
1784                 UnlinkedSimpleJumpTable& sourceTable = unlinkedCodeBlock->immediateSwitchJumpTable(i);
1785                 SimpleJumpTable& destTable = m_rareData->m_immediateSwitchJumpTables[i];
1786                 destTable.branchOffsets = sourceTable.branchOffsets;
1787                 destTable.min = sourceTable.min;
1788             }
1789         }
1790
1791         if (size_t count = unlinkedCodeBlock->numberOfCharacterSwitchJumpTables()) {
1792             m_rareData->m_characterSwitchJumpTables.grow(count);
1793             for (size_t i = 0; i < count; i++) {
1794                 UnlinkedSimpleJumpTable& sourceTable = unlinkedCodeBlock->characterSwitchJumpTable(i);
1795                 SimpleJumpTable& destTable = m_rareData->m_characterSwitchJumpTables[i];
1796                 destTable.branchOffsets = sourceTable.branchOffsets;
1797                 destTable.min = sourceTable.min;
1798             }
1799         }
1800     }
1801
1802     // Allocate metadata buffers for the bytecode
1803 #if ENABLE(LLINT)
1804     if (size_t size = unlinkedCodeBlock->numberOfLLintCallLinkInfos())
1805         m_llintCallLinkInfos.grow(size);
1806 #endif
1807 #if ENABLE(DFG_JIT)
1808     if (size_t size = unlinkedCodeBlock->numberOfArrayProfiles())
1809         m_arrayProfiles.grow(size);
1810     if (size_t size = unlinkedCodeBlock->numberOfArrayAllocationProfiles())
1811         m_arrayAllocationProfiles.grow(size);
1812     if (size_t size = unlinkedCodeBlock->numberOfValueProfiles())
1813         m_valueProfiles.grow(size);
1814 #endif
1815     if (size_t size = unlinkedCodeBlock->numberOfResolveOperations())
1816         m_resolveOperations.grow(size);
1817     size_t putToBaseCount = unlinkedCodeBlock->numberOfPutToBaseOperations();
1818     m_putToBaseOperations.reserveCapacity(putToBaseCount);
1819     for (size_t i = 0; i < putToBaseCount; ++i)
1820         m_putToBaseOperations.append(PutToBaseOperation(isStrictMode()));
1821
1822     ASSERT(m_putToBaseOperations.capacity() == putToBaseCount);
1823
1824     // Copy and translate the UnlinkedInstructions
1825     size_t instructionCount = unlinkedCodeBlock->instructions().size();
1826     UnlinkedInstruction* pc = unlinkedCodeBlock->instructions().data();
1827     Vector<Instruction> instructions(instructionCount);
1828     for (size_t i = 0; i < unlinkedCodeBlock->instructions().size(); ) {
1829         unsigned opLength = opcodeLength(pc[i].u.opcode);
1830         instructions[i] = globalData()->interpreter->getOpcode(pc[i].u.opcode);
1831         for (size_t j = 1; j < opLength; ++j) {
1832             if (sizeof(int32_t) != sizeof(intptr_t))
1833                 instructions[i + j].u.pointer = 0;
1834             instructions[i + j].u.operand = pc[i + j].u.operand;
1835         }
1836         switch (pc[i].u.opcode) {
1837 #if ENABLE(DFG_JIT)
1838         case op_get_by_val:
1839         case op_get_argument_by_val: {
1840             int arrayProfileIndex = pc[i + opLength - 2].u.operand;
1841             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
1842
1843             instructions[i + opLength - 2] = &m_arrayProfiles[arrayProfileIndex];
1844             // fallthrough
1845         }
1846         case op_convert_this:
1847         case op_resolve:
1848         case op_resolve_base:
1849         case op_resolve_with_base:
1850         case op_resolve_with_this:
1851         case op_get_by_id:
1852         case op_call_put_result:
1853         case op_get_callee: {
1854             ValueProfile* profile = &m_valueProfiles[pc[i + opLength - 1].u.operand];
1855             ASSERT(profile->m_bytecodeOffset == -1);
1856             profile->m_bytecodeOffset = i;
1857             instructions[i + opLength - 1] = profile;
1858             break;
1859         }
1860         case op_put_by_val: {
1861             int arrayProfileIndex = pc[i + opLength - 1].u.operand;
1862             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
1863             instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex];
1864             break;
1865         }
1866
1867         case op_new_array:
1868         case op_new_array_buffer:
1869         case op_new_array_with_size: {
1870             int arrayAllocationProfileIndex = pc[i + opLength - 1].u.operand;
1871             instructions[i + opLength - 1] = &m_arrayAllocationProfiles[arrayAllocationProfileIndex];
1872             break;
1873         }
1874 #endif
1875
1876         case op_call:
1877         case op_call_eval: {
1878 #if ENABLE(DFG_JIT)
1879             int arrayProfileIndex = pc[i + opLength - 1].u.operand;
1880             m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i);
1881             instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex];
1882 #endif
1883 #if ENABLE(LLINT)
1884             instructions[i + 4] = &m_llintCallLinkInfos[pc[i + 4].u.operand];
1885 #endif
1886             break;
1887         }
1888         case op_construct:
1889 #if ENABLE(LLINT)
1890             instructions[i + 4] = &m_llintCallLinkInfos[pc[i + 4].u.operand];
1891 #endif
1892             break;
1893         case op_get_by_id_out_of_line:
1894         case op_get_by_id_self:
1895         case op_get_by_id_proto:
1896         case op_get_by_id_chain:
1897         case op_get_by_id_getter_self:
1898         case op_get_by_id_getter_proto:
1899         case op_get_by_id_getter_chain:
1900         case op_get_by_id_custom_self:
1901         case op_get_by_id_custom_proto:
1902         case op_get_by_id_custom_chain:
1903         case op_get_by_id_generic:
1904         case op_get_array_length:
1905         case op_get_string_length:
1906             CRASH();
1907
1908         case op_init_global_const_nop: {
1909             ASSERT(codeType() == GlobalCode);
1910             Identifier ident = identifier(pc[i + 4].u.operand);
1911             SymbolTableEntry entry = globalObject->symbolTable()->get(ident.impl());
1912             if (entry.isNull())
1913                 break;
1914
1915             if (entry.couldBeWatched()) {
1916                 instructions[i + 0] = globalData()->interpreter->getOpcode(op_init_global_const_check);
1917                 instructions[i + 1] = &globalObject->registerAt(entry.getIndex());
1918                 instructions[i + 3] = entry.addressOfIsWatched();
1919                 break;
1920             }
1921
1922             instructions[i + 0] = globalData()->interpreter->getOpcode(op_init_global_const);
1923             instructions[i + 1] = &globalObject->registerAt(entry.getIndex());
1924             break;
1925         }
1926         default:
1927             break;
1928         }
1929         i += opLength;
1930     }
1931     m_instructions = WTF::RefCountedArray<Instruction>(instructions);
1932
1933     // Set optimization thresholds only after m_instructions is initialized, since these
1934     // rely on the instruction count (and are in theory permitted to also inspect the
1935     // instruction stream to more accurate assess the cost of tier-up).
1936     optimizeAfterWarmUp();
1937     jitAfterWarmUp();
1938
1939     if (Options::dumpGeneratedBytecodes())
1940         dumpBytecode();
1941     m_globalData->finishedCompiling(this);
1942 }
1943
1944 CodeBlock::~CodeBlock()
1945 {
1946     if (m_globalData->m_perBytecodeProfiler)
1947         m_globalData->m_perBytecodeProfiler->notifyDestruction(this);
1948     
1949 #if ENABLE(DFG_JIT)
1950     // Remove myself from the set of DFG code blocks. Note that I may not be in this set
1951     // (because I'm not a DFG code block), in which case this is a no-op anyway.
1952     m_globalData->heap.m_dfgCodeBlocks.m_set.remove(this);
1953 #endif
1954     
1955 #if ENABLE(VERBOSE_VALUE_PROFILE)
1956     dumpValueProfiles();
1957 #endif
1958
1959 #if ENABLE(LLINT)    
1960     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
1961         m_incomingLLIntCalls.begin()->remove();
1962 #endif // ENABLE(LLINT)
1963 #if ENABLE(JIT)
1964     // We may be destroyed before any CodeBlocks that refer to us are destroyed.
1965     // Consider that two CodeBlocks become unreachable at the same time. There
1966     // is no guarantee about the order in which the CodeBlocks are destroyed.
1967     // So, if we don't remove incoming calls, and get destroyed before the
1968     // CodeBlock(s) that have calls into us, then the CallLinkInfo vector's
1969     // destructor will try to remove nodes from our (no longer valid) linked list.
1970     while (m_incomingCalls.begin() != m_incomingCalls.end())
1971         m_incomingCalls.begin()->remove();
1972     
1973     // Note that our outgoing calls will be removed from other CodeBlocks'
1974     // m_incomingCalls linked lists through the execution of the ~CallLinkInfo
1975     // destructors.
1976
1977     for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i)
1978         m_structureStubInfos[i].deref();
1979 #endif // ENABLE(JIT)
1980
1981 #if DUMP_CODE_BLOCK_STATISTICS
1982     liveCodeBlockSet.remove(this);
1983 #endif
1984 }
1985
1986 void CodeBlock::setNumParameters(int newValue)
1987 {
1988     m_numParameters = newValue;
1989
1990 #if ENABLE(VALUE_PROFILER)
1991     m_argumentValueProfiles.resize(newValue);
1992 #endif
1993 }
1994
1995 void CodeBlock::visitStructures(SlotVisitor& visitor, Instruction* vPC)
1996 {
1997     Interpreter* interpreter = m_globalData->interpreter;
1998
1999     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) && vPC[4].u.structure) {
2000         visitor.append(&vPC[4].u.structure);
2001         return;
2002     }
2003
2004     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_self) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_self)) {
2005         visitor.append(&vPC[4].u.structure);
2006         return;
2007     }
2008     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_proto) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_proto)) {
2009         visitor.append(&vPC[4].u.structure);
2010         visitor.append(&vPC[5].u.structure);
2011         return;
2012     }
2013     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain)) {
2014         visitor.append(&vPC[4].u.structure);
2015         if (vPC[5].u.structureChain)
2016             visitor.append(&vPC[5].u.structureChain);
2017         return;
2018     }
2019     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
2020         visitor.append(&vPC[4].u.structure);
2021         visitor.append(&vPC[5].u.structure);
2022         if (vPC[6].u.structureChain)
2023             visitor.append(&vPC[6].u.structureChain);
2024         return;
2025     }
2026     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) && vPC[4].u.structure) {
2027         visitor.append(&vPC[4].u.structure);
2028         return;
2029     }
2030     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_replace)) {
2031         visitor.append(&vPC[4].u.structure);
2032         return;
2033     }
2034
2035     // These instructions don't ref their Structures.
2036     ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_get_array_length) || vPC[0].u.opcode == interpreter->getOpcode(op_get_string_length));
2037 }
2038
2039 void EvalCodeCache::visitAggregate(SlotVisitor& visitor)
2040 {
2041     EvalCacheMap::iterator end = m_cacheMap.end();
2042     for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr)
2043         visitor.append(&ptr->value);
2044 }
2045
2046 void CodeBlock::visitAggregate(SlotVisitor& visitor)
2047 {
2048 #if ENABLE(PARALLEL_GC) && ENABLE(DFG_JIT)
2049     if (!!m_dfgData) {
2050         // I may be asked to scan myself more than once, and it may even happen concurrently.
2051         // To this end, use a CAS loop to check if I've been called already. Only one thread
2052         // may proceed past this point - whichever one wins the CAS race.
2053         unsigned oldValue;
2054         do {
2055             oldValue = m_dfgData->visitAggregateHasBeenCalled;
2056             if (oldValue) {
2057                 // Looks like someone else won! Return immediately to ensure that we don't
2058                 // trace the same CodeBlock concurrently. Doing so is hazardous since we will
2059                 // be mutating the state of ValueProfiles, which contain JSValues, which can
2060                 // have word-tearing on 32-bit, leading to awesome timing-dependent crashes
2061                 // that are nearly impossible to track down.
2062                 
2063                 // Also note that it must be safe to return early as soon as we see the
2064                 // value true (well, (unsigned)1), since once a GC thread is in this method
2065                 // and has won the CAS race (i.e. was responsible for setting the value true)
2066                 // it will definitely complete the rest of this method before declaring
2067                 // termination.
2068                 return;
2069             }
2070         } while (!WTF::weakCompareAndSwap(&m_dfgData->visitAggregateHasBeenCalled, 0, 1));
2071     }
2072 #endif // ENABLE(PARALLEL_GC) && ENABLE(DFG_JIT)
2073     
2074     if (!!m_alternative)
2075         m_alternative->visitAggregate(visitor);
2076
2077     visitor.append(&m_unlinkedCode);
2078
2079     // There are three things that may use unconditional finalizers: lazy bytecode freeing,
2080     // inline cache clearing, and jettisoning. The probability of us wanting to do at
2081     // least one of those things is probably quite close to 1. So we add one no matter what
2082     // and when it runs, it figures out whether it has any work to do.
2083     visitor.addUnconditionalFinalizer(this);
2084     
2085     if (shouldImmediatelyAssumeLivenessDuringScan()) {
2086         // This code block is live, so scan all references strongly and return.
2087         stronglyVisitStrongReferences(visitor);
2088         stronglyVisitWeakReferences(visitor);
2089         return;
2090     }
2091     
2092 #if ENABLE(DFG_JIT)
2093     // We get here if we're live in the sense that our owner executable is live,
2094     // but we're not yet live for sure in another sense: we may yet decide that this
2095     // code block should be jettisoned based on its outgoing weak references being
2096     // stale. Set a flag to indicate that we're still assuming that we're dead, and
2097     // perform one round of determining if we're live. The GC may determine, based on
2098     // either us marking additional objects, or by other objects being marked for
2099     // other reasons, that this iteration should run again; it will notify us of this
2100     // decision by calling harvestWeakReferences().
2101     
2102     m_dfgData->livenessHasBeenProved = false;
2103     m_dfgData->allTransitionsHaveBeenMarked = false;
2104     
2105     performTracingFixpointIteration(visitor);
2106
2107     // GC doesn't have enough information yet for us to decide whether to keep our DFG
2108     // data, so we need to register a handler to run again at the end of GC, when more
2109     // information is available.
2110     if (!(m_dfgData->livenessHasBeenProved && m_dfgData->allTransitionsHaveBeenMarked))
2111         visitor.addWeakReferenceHarvester(this);
2112     
2113 #else // ENABLE(DFG_JIT)
2114     RELEASE_ASSERT_NOT_REACHED();
2115 #endif // ENABLE(DFG_JIT)
2116 }
2117
2118 void CodeBlock::performTracingFixpointIteration(SlotVisitor& visitor)
2119 {
2120     UNUSED_PARAM(visitor);
2121     
2122 #if ENABLE(DFG_JIT)
2123     // Evaluate our weak reference transitions, if there are still some to evaluate.
2124     if (!m_dfgData->allTransitionsHaveBeenMarked) {
2125         bool allAreMarkedSoFar = true;
2126         for (unsigned i = 0; i < m_dfgData->transitions.size(); ++i) {
2127             if ((!m_dfgData->transitions[i].m_codeOrigin
2128                  || Heap::isMarked(m_dfgData->transitions[i].m_codeOrigin.get()))
2129                 && Heap::isMarked(m_dfgData->transitions[i].m_from.get())) {
2130                 // If the following three things are live, then the target of the
2131                 // transition is also live:
2132                 // - This code block. We know it's live already because otherwise
2133                 //   we wouldn't be scanning ourselves.
2134                 // - The code origin of the transition. Transitions may arise from
2135                 //   code that was inlined. They are not relevant if the user's
2136                 //   object that is required for the inlinee to run is no longer
2137                 //   live.
2138                 // - The source of the transition. The transition checks if some
2139                 //   heap location holds the source, and if so, stores the target.
2140                 //   Hence the source must be live for the transition to be live.
2141                 visitor.append(&m_dfgData->transitions[i].m_to);
2142             } else
2143                 allAreMarkedSoFar = false;
2144         }
2145         
2146         if (allAreMarkedSoFar)
2147             m_dfgData->allTransitionsHaveBeenMarked = true;
2148     }
2149     
2150     // Check if we have any remaining work to do.
2151     if (m_dfgData->livenessHasBeenProved)
2152         return;
2153     
2154     // Now check all of our weak references. If all of them are live, then we
2155     // have proved liveness and so we scan our strong references. If at end of
2156     // GC we still have not proved liveness, then this code block is toast.
2157     bool allAreLiveSoFar = true;
2158     for (unsigned i = 0; i < m_dfgData->weakReferences.size(); ++i) {
2159         if (!Heap::isMarked(m_dfgData->weakReferences[i].get())) {
2160             allAreLiveSoFar = false;
2161             break;
2162         }
2163     }
2164     
2165     // If some weak references are dead, then this fixpoint iteration was
2166     // unsuccessful.
2167     if (!allAreLiveSoFar)
2168         return;
2169     
2170     // All weak references are live. Record this information so we don't
2171     // come back here again, and scan the strong references.
2172     m_dfgData->livenessHasBeenProved = true;
2173     stronglyVisitStrongReferences(visitor);
2174 #endif // ENABLE(DFG_JIT)
2175 }
2176
2177 void CodeBlock::visitWeakReferences(SlotVisitor& visitor)
2178 {
2179     performTracingFixpointIteration(visitor);
2180 }
2181
2182 #if ENABLE(JIT_VERBOSE_OSR)
2183 static const bool verboseUnlinking = true;
2184 #else
2185 static const bool verboseUnlinking = false;
2186 #endif
2187
2188 void CodeBlock::finalizeUnconditionally()
2189 {
2190 #if ENABLE(LLINT)
2191     Interpreter* interpreter = m_globalData->interpreter;
2192     if (!!numberOfInstructions()) {
2193         const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
2194         for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
2195             Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]];
2196             switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
2197             case op_get_by_id:
2198             case op_get_by_id_out_of_line:
2199             case op_put_by_id:
2200             case op_put_by_id_out_of_line:
2201                 if (!curInstruction[4].u.structure || Heap::isMarked(curInstruction[4].u.structure.get()))
2202                     break;
2203                 if (verboseUnlinking)
2204                     dataLogF("Clearing LLInt property access with structure %p.\n", curInstruction[4].u.structure.get());
2205                 curInstruction[4].u.structure.clear();
2206                 curInstruction[5].u.operand = 0;
2207                 break;
2208             case op_put_by_id_transition_direct:
2209             case op_put_by_id_transition_normal:
2210             case op_put_by_id_transition_direct_out_of_line:
2211             case op_put_by_id_transition_normal_out_of_line:
2212                 if (Heap::isMarked(curInstruction[4].u.structure.get())
2213                     && Heap::isMarked(curInstruction[6].u.structure.get())
2214                     && Heap::isMarked(curInstruction[7].u.structureChain.get()))
2215                     break;
2216                 if (verboseUnlinking) {
2217                     dataLogF("Clearing LLInt put transition with structures %p -> %p, chain %p.\n",
2218                             curInstruction[4].u.structure.get(),
2219                             curInstruction[6].u.structure.get(),
2220                             curInstruction[7].u.structureChain.get());
2221                 }
2222                 curInstruction[4].u.structure.clear();
2223                 curInstruction[6].u.structure.clear();
2224                 curInstruction[7].u.structureChain.clear();
2225                 curInstruction[0].u.opcode = interpreter->getOpcode(op_put_by_id);
2226                 break;
2227             case op_get_array_length:
2228                 break;
2229             default:
2230                 RELEASE_ASSERT_NOT_REACHED();
2231             }
2232         }
2233
2234         for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) {
2235             if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) {
2236                 if (verboseUnlinking)
2237                     dataLog("Clearing LLInt call from ", *this, "\n");
2238                 m_llintCallLinkInfos[i].unlink();
2239             }
2240             if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get()))
2241                 m_llintCallLinkInfos[i].lastSeenCallee.clear();
2242         }
2243     }
2244 #endif // ENABLE(LLINT)
2245
2246 #if ENABLE(DFG_JIT)
2247     // Check if we're not live. If we are, then jettison.
2248     if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_dfgData->livenessHasBeenProved)) {
2249         if (verboseUnlinking)
2250             dataLog(*this, " has dead weak references, jettisoning during GC.\n");
2251
2252         // Make sure that the baseline JIT knows that it should re-warm-up before
2253         // optimizing.
2254         alternative()->optimizeAfterWarmUp();
2255         
2256         if (DFG::shouldShowDisassembly()) {
2257             dataLog(*this, "will be jettisoned because of the following dead references:\n");
2258             for (unsigned i = 0; i < m_dfgData->transitions.size(); ++i) {
2259                 WeakReferenceTransition& transition = m_dfgData->transitions[i];
2260                 JSCell* origin = transition.m_codeOrigin.get();
2261                 JSCell* from = transition.m_from.get();
2262                 JSCell* to = transition.m_to.get();
2263                 if ((!origin || Heap::isMarked(origin)) && Heap::isMarked(from))
2264                     continue;
2265                 dataLog("    Transition under ", JSValue(origin), ", ", JSValue(from), " -> ", JSValue(to), ".\n");
2266             }
2267             for (unsigned i = 0; i < m_dfgData->weakReferences.size(); ++i) {
2268                 JSCell* weak = m_dfgData->weakReferences[i].get();
2269                 if (Heap::isMarked(weak))
2270                     continue;
2271                 dataLog("    Weak reference ", JSValue(weak), ".\n");
2272             }
2273         }
2274         
2275         jettison();
2276         return;
2277     }
2278 #endif // ENABLE(DFG_JIT)
2279
2280     for (size_t size = m_putToBaseOperations.size(), i = 0; i < size; ++i) {
2281         if (m_putToBaseOperations[i].m_structure && !Heap::isMarked(m_putToBaseOperations[i].m_structure.get())) {
2282             if (verboseUnlinking)
2283                 dataLog("Clearing putToBase info in ", *this, "\n");
2284             m_putToBaseOperations[i].m_structure.clear();
2285         }
2286     }
2287     for (size_t size = m_resolveOperations.size(), i = 0; i < size; ++i) {
2288         if (m_resolveOperations[i].isEmpty())
2289             continue;
2290 #ifndef NDEBUG
2291         for (size_t insnSize = m_resolveOperations[i].size() - 1, k = 0; k < insnSize; ++k)
2292             ASSERT(!m_resolveOperations[i][k].m_structure);
2293 #endif
2294         m_resolveOperations[i].last().m_structure.clear();
2295         if (m_resolveOperations[i].last().m_structure && !Heap::isMarked(m_resolveOperations[i].last().m_structure.get())) {
2296             if (verboseUnlinking)
2297                 dataLog("Clearing resolve info in ", *this, "\n");
2298             m_resolveOperations[i].last().m_structure.clear();
2299         }
2300     }
2301
2302 #if ENABLE(JIT)
2303     // Handle inline caches.
2304     if (!!getJITCode()) {
2305         RepatchBuffer repatchBuffer(this);
2306         for (unsigned i = 0; i < numberOfCallLinkInfos(); ++i) {
2307             if (callLinkInfo(i).isLinked()) {
2308                 if (ClosureCallStubRoutine* stub = callLinkInfo(i).stub.get()) {
2309                     if (!Heap::isMarked(stub->structure())
2310                         || !Heap::isMarked(stub->executable())) {
2311                         if (verboseUnlinking) {
2312                             dataLog(
2313                                 "Clearing closure call from ", *this, " to ",
2314                                 stub->executable()->hashFor(callLinkInfo(i).specializationKind()),
2315                                 ", stub routine ", RawPointer(stub), ".\n");
2316                         }
2317                         callLinkInfo(i).unlink(*m_globalData, repatchBuffer);
2318                     }
2319                 } else if (!Heap::isMarked(callLinkInfo(i).callee.get())) {
2320                     if (verboseUnlinking) {
2321                         dataLog(
2322                             "Clearing call from ", *this, " to ",
2323                             RawPointer(callLinkInfo(i).callee.get()), " (",
2324                             callLinkInfo(i).callee.get()->executable()->hashFor(
2325                                 callLinkInfo(i).specializationKind()),
2326                             ").\n");
2327                     }
2328                     callLinkInfo(i).unlink(*m_globalData, repatchBuffer);
2329                 }
2330             }
2331             if (!!callLinkInfo(i).lastSeenCallee
2332                 && !Heap::isMarked(callLinkInfo(i).lastSeenCallee.get()))
2333                 callLinkInfo(i).lastSeenCallee.clear();
2334         }
2335         for (size_t size = m_structureStubInfos.size(), i = 0; i < size; ++i) {
2336             StructureStubInfo& stubInfo = m_structureStubInfos[i];
2337             
2338             if (stubInfo.visitWeakReferences())
2339                 continue;
2340             
2341             resetStubInternal(repatchBuffer, stubInfo);
2342         }
2343     }
2344 #endif
2345 }
2346
2347 #if ENABLE(JIT)
2348 void CodeBlock::resetStub(StructureStubInfo& stubInfo)
2349 {
2350     if (stubInfo.accessType == access_unset)
2351         return;
2352     
2353     RepatchBuffer repatchBuffer(this);
2354     resetStubInternal(repatchBuffer, stubInfo);
2355 }
2356
2357 void CodeBlock::resetStubInternal(RepatchBuffer& repatchBuffer, StructureStubInfo& stubInfo)
2358 {
2359     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
2360     
2361     if (verboseUnlinking)
2362         dataLog("Clearing structure cache (kind ", static_cast<int>(stubInfo.accessType), ") in ", *this, ".\n");
2363     
2364     if (isGetByIdAccess(accessType)) {
2365         if (getJITCode().jitType() == JITCode::DFGJIT)
2366             DFG::dfgResetGetByID(repatchBuffer, stubInfo);
2367         else
2368             JIT::resetPatchGetById(repatchBuffer, &stubInfo);
2369     } else {
2370         ASSERT(isPutByIdAccess(accessType));
2371         if (getJITCode().jitType() == JITCode::DFGJIT)
2372             DFG::dfgResetPutByID(repatchBuffer, stubInfo);
2373         else 
2374             JIT::resetPatchPutById(repatchBuffer, &stubInfo);
2375     }
2376     
2377     stubInfo.reset();
2378 }
2379 #endif
2380
2381 void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
2382 {
2383     visitor.append(&m_globalObject);
2384     visitor.append(&m_ownerExecutable);
2385     visitor.append(&m_unlinkedCode);
2386     if (m_rareData)
2387         m_rareData->m_evalCodeCache.visitAggregate(visitor);
2388     visitor.appendValues(m_constantRegisters.data(), m_constantRegisters.size());
2389     for (size_t i = 0; i < m_functionExprs.size(); ++i)
2390         visitor.append(&m_functionExprs[i]);
2391     for (size_t i = 0; i < m_functionDecls.size(); ++i)
2392         visitor.append(&m_functionDecls[i]);
2393
2394     updateAllPredictions(Collection);
2395 }
2396
2397 void CodeBlock::stronglyVisitWeakReferences(SlotVisitor& visitor)
2398 {
2399     UNUSED_PARAM(visitor);
2400
2401 #if ENABLE(DFG_JIT)
2402     if (!m_dfgData)
2403         return;
2404
2405     for (unsigned i = 0; i < m_dfgData->transitions.size(); ++i) {
2406         if (!!m_dfgData->transitions[i].m_codeOrigin)
2407             visitor.append(&m_dfgData->transitions[i].m_codeOrigin); // Almost certainly not necessary, since the code origin should also be a weak reference. Better to be safe, though.
2408         visitor.append(&m_dfgData->transitions[i].m_from);
2409         visitor.append(&m_dfgData->transitions[i].m_to);
2410     }
2411     
2412     for (unsigned i = 0; i < m_dfgData->weakReferences.size(); ++i)
2413         visitor.append(&m_dfgData->weakReferences[i]);
2414 #endif    
2415 }
2416
2417 #if ENABLE(BYTECODE_COMMENTS)
2418 // Finds the comment string for the specified bytecode offset/PC is available. 
2419 const char* CodeBlock::commentForBytecodeOffset(unsigned bytecodeOffset)
2420 {
2421     ASSERT(bytecodeOffset < instructions().size());
2422
2423     Vector<Comment>& comments = m_bytecodeComments;
2424     size_t numberOfComments = comments.size();
2425     const char* result = 0;
2426
2427     if (!numberOfComments)
2428         return 0; // No comments to match with.
2429
2430     // The next match is most likely the next comment in the list.
2431     // Do a quick check to see if that is a match first.
2432     // m_bytecodeCommentIterator should already be pointing to the
2433     // next comment we should check.
2434
2435     ASSERT(m_bytecodeCommentIterator < comments.size());
2436
2437     size_t i = m_bytecodeCommentIterator;
2438     size_t commentPC = comments[i].pc;
2439     if (commentPC == bytecodeOffset) {
2440         // We've got a match. All done!
2441         m_bytecodeCommentIterator = i;
2442         result = comments[i].string;
2443     } else if (commentPC > bytecodeOffset) {
2444         // The current comment is already greater than the requested PC.
2445         // Start searching from the first comment.
2446         i = 0;
2447     } else {
2448         // Otherwise, the current comment's PC is less than the requested PC.
2449         // Hence, we can just start searching from the next comment in the
2450         // list.
2451         i++;
2452     }
2453
2454     // If the result is still not found, do a linear search in the range
2455     // that we've determined above.
2456     if (!result) {
2457         for (; i < comments.size(); ++i) {
2458             commentPC = comments[i].pc;
2459             if (commentPC == bytecodeOffset) {
2460                 result = comments[i].string;
2461                 break;
2462             }
2463             if (comments[i].pc > bytecodeOffset) {
2464                 // The current comment PC is already past the requested
2465                 // bytecodeOffset. Hence, there are no more possible
2466                 // matches. Just fail.
2467                 break;
2468             }
2469         }
2470     }
2471
2472     // Update the iterator to point to the next comment.
2473     if (++i >= numberOfComments) {
2474         // At most point to the last comment entry. This ensures that the
2475         // next time we call this function, the quick checks will at least
2476         // have one entry to check and can fail fast if appropriate.
2477         i = numberOfComments - 1;
2478     }
2479     m_bytecodeCommentIterator = i;
2480     return result;
2481 }
2482
2483 void CodeBlock::dumpBytecodeComments()
2484 {
2485     Vector<Comment>& comments = m_bytecodeComments;
2486     printf("Comments for codeblock %p: size %lu\n", this, comments.size());
2487     for (size_t i = 0; i < comments.size(); ++i)
2488         printf("     pc %lu : '%s'\n", comments[i].pc, comments[i].string);
2489     printf("End of comments for codeblock %p\n", this);
2490 }
2491 #endif // ENABLE_BYTECODE_COMMENTS
2492
2493 HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
2494 {
2495     RELEASE_ASSERT(bytecodeOffset < instructions().size());
2496
2497     if (!m_rareData)
2498         return 0;
2499     
2500     Vector<HandlerInfo>& exceptionHandlers = m_rareData->m_exceptionHandlers;
2501     for (size_t i = 0; i < exceptionHandlers.size(); ++i) {
2502         // Handlers are ordered innermost first, so the first handler we encounter
2503         // that contains the source address is the correct handler to use.
2504         if (exceptionHandlers[i].start <= bytecodeOffset && exceptionHandlers[i].end > bytecodeOffset)
2505             return &exceptionHandlers[i];
2506     }
2507
2508     return 0;
2509 }
2510
2511 int CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
2512 {
2513     RELEASE_ASSERT(bytecodeOffset < instructions().size());
2514     return m_ownerExecutable->lineNo() + m_unlinkedCode->lineNumberForBytecodeOffset(bytecodeOffset);
2515 }
2516
2517 void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
2518 {
2519     m_unlinkedCode->expressionRangeForBytecodeOffset(bytecodeOffset, divot, startOffset, endOffset);
2520     divot += m_sourceOffset;
2521 }
2522
2523 void CodeBlock::shrinkToFit(ShrinkMode shrinkMode)
2524 {
2525 #if ENABLE(LLINT)
2526     m_llintCallLinkInfos.shrinkToFit();
2527 #endif
2528 #if ENABLE(JIT)
2529     m_structureStubInfos.shrinkToFit();
2530     m_callLinkInfos.shrinkToFit();
2531 #endif
2532 #if ENABLE(VALUE_PROFILER)
2533     if (shrinkMode == EarlyShrink)
2534         m_argumentValueProfiles.shrinkToFit();
2535     m_rareCaseProfiles.shrinkToFit();
2536     m_specialFastCaseProfiles.shrinkToFit();
2537 #endif
2538     
2539     if (shrinkMode == EarlyShrink) {
2540         m_identifiers.shrinkToFit();
2541         m_functionDecls.shrinkToFit();
2542         m_functionExprs.shrinkToFit();
2543         m_constantRegisters.shrinkToFit();
2544     } // else don't shrink these, because we would have already pointed pointers into these tables.
2545
2546     if (m_rareData) {
2547         m_rareData->m_exceptionHandlers.shrinkToFit();
2548         m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
2549         m_rareData->m_characterSwitchJumpTables.shrinkToFit();
2550         m_rareData->m_stringSwitchJumpTables.shrinkToFit();
2551 #if ENABLE(JIT)
2552         m_rareData->m_callReturnIndexVector.shrinkToFit();
2553 #endif
2554 #if ENABLE(DFG_JIT)
2555         m_rareData->m_inlineCallFrames.shrinkToFit();
2556         m_rareData->m_codeOrigins.shrinkToFit();
2557 #endif
2558     }
2559     
2560 #if ENABLE(DFG_JIT)
2561     if (m_dfgData) {
2562         m_dfgData->osrEntry.shrinkToFit();
2563         m_dfgData->osrExit.shrinkToFit();
2564         m_dfgData->speculationRecovery.shrinkToFit();
2565         m_dfgData->weakReferences.shrinkToFit();
2566         m_dfgData->transitions.shrinkToFit();
2567         m_dfgData->minifiedDFG.prepareAndShrink();
2568         m_dfgData->variableEventStream.shrinkToFit();
2569     }
2570 #endif
2571 }
2572
2573 void CodeBlock::createActivation(CallFrame* callFrame)
2574 {
2575     ASSERT(codeType() == FunctionCode);
2576     ASSERT(needsFullScopeChain());
2577     ASSERT(!callFrame->uncheckedR(activationRegister()).jsValue());
2578     JSActivation* activation = JSActivation::create(callFrame->globalData(), callFrame, this);
2579     callFrame->uncheckedR(activationRegister()) = JSValue(activation);
2580     callFrame->setScope(activation);
2581 }
2582
2583 unsigned CodeBlock::addOrFindConstant(JSValue v)
2584 {
2585     unsigned numberOfConstants = numberOfConstantRegisters();
2586     for (unsigned i = 0; i < numberOfConstants; ++i) {
2587         if (getConstant(FirstConstantRegisterIndex + i) == v)
2588             return i;
2589     }
2590     return addConstant(v);
2591 }
2592
2593 #if ENABLE(JIT)
2594 void CodeBlock::unlinkCalls()
2595 {
2596     if (!!m_alternative)
2597         m_alternative->unlinkCalls();
2598 #if ENABLE(LLINT)
2599     for (size_t i = 0; i < m_llintCallLinkInfos.size(); ++i) {
2600         if (m_llintCallLinkInfos[i].isLinked())
2601             m_llintCallLinkInfos[i].unlink();
2602     }
2603 #endif
2604     if (!m_callLinkInfos.size())
2605         return;
2606     if (!m_globalData->canUseJIT())
2607         return;
2608     RepatchBuffer repatchBuffer(this);
2609     for (size_t i = 0; i < m_callLinkInfos.size(); i++) {
2610         if (!m_callLinkInfos[i].isLinked())
2611             continue;
2612         m_callLinkInfos[i].unlink(*m_globalData, repatchBuffer);
2613     }
2614 }
2615
2616 void CodeBlock::unlinkIncomingCalls()
2617 {
2618 #if ENABLE(LLINT)
2619     while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end())
2620         m_incomingLLIntCalls.begin()->unlink();
2621 #endif
2622     if (m_incomingCalls.isEmpty())
2623         return;
2624     RepatchBuffer repatchBuffer(this);
2625     while (m_incomingCalls.begin() != m_incomingCalls.end())
2626         m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer);
2627 }
2628 #endif // ENABLE(JIT)
2629
2630 #if ENABLE(LLINT)
2631 Instruction* CodeBlock::adjustPCIfAtCallSite(Instruction* potentialReturnPC)
2632 {
2633     ASSERT(potentialReturnPC);
2634
2635     unsigned returnPCOffset = potentialReturnPC - instructions().begin();
2636     Instruction* adjustedPC;
2637     unsigned opcodeLength;
2638
2639     // If we are at a callsite, the LLInt stores the PC after the call
2640     // instruction rather than the PC of the call instruction. This requires
2641     // some correcting. If so, we can rely on the fact that the preceding
2642     // instruction must be one of the call instructions, so either it's a
2643     // call_varargs or it's a call, construct, or eval.
2644     //
2645     // If we are not at a call site, then we need to guard against the
2646     // possibility of peeking past the start of the bytecode range for this
2647     // codeBlock. Hence, we do a bounds check before we peek at the
2648     // potential "preceding" instruction.
2649     //     The bounds check is done by comparing the offset of the potential
2650     // returnPC with the length of the opcode. If there is room for a call
2651     // instruction before the returnPC, then the offset of the returnPC must
2652     // be greater than the size of the call opcode we're looking for.
2653
2654     // The determination of the call instruction present (if we are at a
2655     // callsite) depends on the following assumptions. So, assert that
2656     // they are still true:
2657     ASSERT(OPCODE_LENGTH(op_call_varargs) <= OPCODE_LENGTH(op_call));
2658     ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct));
2659     ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_eval));
2660
2661     // Check for the case of a preceeding op_call_varargs:
2662     opcodeLength = OPCODE_LENGTH(op_call_varargs);
2663     adjustedPC = potentialReturnPC - opcodeLength;
2664     if ((returnPCOffset >= opcodeLength)
2665         && (adjustedPC->u.pointer == LLInt::getCodePtr(llint_op_call_varargs))) {
2666         return adjustedPC;
2667     }
2668
2669     // Check for the case of the other 3 call instructions:
2670     opcodeLength = OPCODE_LENGTH(op_call);
2671     adjustedPC = potentialReturnPC - opcodeLength;
2672     if ((returnPCOffset >= opcodeLength)
2673         && (adjustedPC->u.pointer == LLInt::getCodePtr(llint_op_call)
2674             || adjustedPC->u.pointer == LLInt::getCodePtr(llint_op_construct)
2675             || adjustedPC->u.pointer == LLInt::getCodePtr(llint_op_call_eval))) {
2676         return adjustedPC;
2677     }
2678
2679     // Not a call site. No need to adjust PC. Just return the original.
2680     return potentialReturnPC;
2681 }
2682 #endif // ENABLE(LLINT)
2683
2684 #if ENABLE(JIT)
2685 ClosureCallStubRoutine* CodeBlock::findClosureCallForReturnPC(ReturnAddressPtr returnAddress)
2686 {
2687     for (unsigned i = m_callLinkInfos.size(); i--;) {
2688         CallLinkInfo& info = m_callLinkInfos[i];
2689         if (!info.stub)
2690             continue;
2691         if (!info.stub->code().executableMemory()->contains(returnAddress.value()))
2692             continue;
2693         
2694         return info.stub.get();
2695     }
2696     
2697     // The stub routine may have been jettisoned. This is rare, but we have to handle it.
2698     const JITStubRoutineSet& set = m_globalData->heap.jitStubRoutines();
2699     for (unsigned i = set.size(); i--;) {
2700         GCAwareJITStubRoutine* genericStub = set.at(i);
2701         if (!genericStub->isClosureCall())
2702             continue;
2703         ClosureCallStubRoutine* stub = static_cast<ClosureCallStubRoutine*>(genericStub);
2704         if (!stub->code().executableMemory()->contains(returnAddress.value()))
2705             continue;
2706         return stub;
2707     }
2708     
2709     return 0;
2710 }
2711 #endif
2712
2713 unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddress)
2714 {
2715     UNUSED_PARAM(exec);
2716     UNUSED_PARAM(returnAddress);
2717 #if ENABLE(LLINT)
2718 #if !ENABLE(LLINT_C_LOOP)
2719     // When using the JIT, we could have addresses that are not bytecode
2720     // addresses. We check if the return address is in the LLint glue and
2721     // opcode handlers range here to ensure that we are looking at bytecode
2722     // before attempting to convert the return address into a bytecode offset.
2723     //
2724     // In the case of the C Loop LLInt, the JIT is disabled, and the only
2725     // valid return addresses should be bytecode PCs. So, we can and need to
2726     // forego this check because when we do not ENABLE(COMPUTED_GOTO_OPCODES),
2727     // then the bytecode "PC"s are actually the opcodeIDs and are not bounded
2728     // by llint_begin and llint_end.
2729     if (returnAddress.value() >= LLInt::getCodePtr(llint_begin)
2730         && returnAddress.value() <= LLInt::getCodePtr(llint_end))
2731 #endif
2732     {
2733         RELEASE_ASSERT(exec->codeBlock());
2734         RELEASE_ASSERT(exec->codeBlock() == this);
2735         RELEASE_ASSERT(JITCode::isBaselineCode(getJITType()));
2736         Instruction* instruction = exec->currentVPC();
2737         RELEASE_ASSERT(instruction);
2738
2739         instruction = adjustPCIfAtCallSite(instruction);
2740         return bytecodeOffset(instruction);
2741     }
2742 #endif // !ENABLE(LLINT)
2743
2744 #if ENABLE(JIT)
2745     if (!m_rareData)
2746         return 1;
2747     Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
2748     if (!callIndices.size())
2749         return 1;
2750     
2751     if (getJITCode().getExecutableMemory()->contains(returnAddress.value())) {
2752         unsigned callReturnOffset = getJITCode().offsetOf(returnAddress.value());
2753         CallReturnOffsetToBytecodeOffset* result =
2754             binarySearch<CallReturnOffsetToBytecodeOffset, unsigned>(
2755                 callIndices, callIndices.size(), callReturnOffset, getCallReturnOffset);
2756         RELEASE_ASSERT(result->callReturnOffset == callReturnOffset);
2757         return result->bytecodeOffset;
2758     }
2759
2760     return findClosureCallForReturnPC(returnAddress)->codeOrigin().bytecodeIndex;
2761 #endif // ENABLE(JIT)
2762
2763 #if !ENABLE(LLINT) && !ENABLE(JIT)
2764     return 1;
2765 #endif
2766 }
2767
2768 #if ENABLE(DFG_JIT)
2769 bool CodeBlock::codeOriginForReturn(ReturnAddressPtr returnAddress, CodeOrigin& codeOrigin)
2770 {
2771     if (!hasCodeOrigins())
2772         return false;
2773
2774     if (!getJITCode().getExecutableMemory()->contains(returnAddress.value())) {
2775         codeOrigin = findClosureCallForReturnPC(returnAddress)->codeOrigin();
2776         return true;
2777     }
2778     
2779     unsigned offset = getJITCode().offsetOf(returnAddress.value());
2780     CodeOriginAtCallReturnOffset* entry =
2781         tryBinarySearch<CodeOriginAtCallReturnOffset, unsigned>(
2782             codeOrigins(), codeOrigins().size(), offset,
2783             getCallReturnOffsetForCodeOrigin);
2784     if (!entry)
2785         return false;
2786     codeOrigin = entry->codeOrigin;
2787     return true;
2788 }
2789 #endif // ENABLE(DFG_JIT)
2790
2791 void CodeBlock::clearEvalCache()
2792 {
2793     if (!!m_alternative)
2794         m_alternative->clearEvalCache();
2795     if (!m_rareData)
2796         return;
2797     m_rareData->m_evalCodeCache.clear();
2798 }
2799
2800 template<typename T>
2801 inline void replaceExistingEntries(Vector<T>& target, Vector<T>& source)
2802 {
2803     ASSERT(target.size() <= source.size());
2804     for (size_t i = 0; i < target.size(); ++i)
2805         target[i] = source[i];
2806 }
2807
2808 void CodeBlock::copyPostParseDataFrom(CodeBlock* alternative)
2809 {
2810     if (!alternative)
2811         return;
2812     
2813     replaceExistingEntries(m_constantRegisters, alternative->m_constantRegisters);
2814     replaceExistingEntries(m_functionDecls, alternative->m_functionDecls);
2815     replaceExistingEntries(m_functionExprs, alternative->m_functionExprs);
2816     if (!!m_rareData && !!alternative->m_rareData)
2817         replaceExistingEntries(m_rareData->m_constantBuffers, alternative->m_rareData->m_constantBuffers);
2818 }
2819
2820 void CodeBlock::copyPostParseDataFromAlternative()
2821 {
2822     copyPostParseDataFrom(m_alternative.get());
2823 }
2824
2825 #if ENABLE(JIT)
2826 void CodeBlock::reoptimize()
2827 {
2828     ASSERT(replacement() != this);
2829     ASSERT(replacement()->alternative() == this);
2830     replacement()->tallyFrequentExitSites();
2831     if (DFG::shouldShowDisassembly())
2832         dataLog(*replacement(), " will be jettisoned due to reoptimization of ", *this, ".\n");
2833     replacement()->jettison();
2834     countReoptimization();
2835     optimizeAfterWarmUp();
2836 }
2837
2838 CodeBlock* ProgramCodeBlock::replacement()
2839 {
2840     return &static_cast<ProgramExecutable*>(ownerExecutable())->generatedBytecode();
2841 }
2842
2843 CodeBlock* EvalCodeBlock::replacement()
2844 {
2845     return &static_cast<EvalExecutable*>(ownerExecutable())->generatedBytecode();
2846 }
2847
2848 CodeBlock* FunctionCodeBlock::replacement()
2849 {
2850     return &static_cast<FunctionExecutable*>(ownerExecutable())->generatedBytecodeFor(m_isConstructor ? CodeForConstruct : CodeForCall);
2851 }
2852
2853 JSObject* ProgramCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex)
2854 {
2855     if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType()))
2856         return 0;
2857     JSObject* error = static_cast<ProgramExecutable*>(ownerExecutable())->compileOptimized(exec, scope, bytecodeIndex);
2858     return error;
2859 }
2860
2861 JSObject* EvalCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex)
2862 {
2863     if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType()))
2864         return 0;
2865     JSObject* error = static_cast<EvalExecutable*>(ownerExecutable())->compileOptimized(exec, scope, bytecodeIndex);
2866     return error;
2867 }
2868
2869 JSObject* FunctionCodeBlock::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex)
2870 {
2871     if (replacement()->getJITType() == JITCode::nextTierJIT(getJITType()))
2872         return 0;
2873     JSObject* error = static_cast<FunctionExecutable*>(ownerExecutable())->compileOptimizedFor(exec, scope, bytecodeIndex, m_isConstructor ? CodeForConstruct : CodeForCall);
2874     return error;
2875 }
2876
2877 DFG::CapabilityLevel ProgramCodeBlock::canCompileWithDFGInternal()
2878 {
2879     return DFG::canCompileProgram(this);
2880 }
2881
2882 DFG::CapabilityLevel EvalCodeBlock::canCompileWithDFGInternal()
2883 {
2884     return DFG::canCompileEval(this);
2885 }
2886
2887 DFG::CapabilityLevel FunctionCodeBlock::canCompileWithDFGInternal()
2888 {
2889     if (m_isConstructor)
2890         return DFG::canCompileFunctionForConstruct(this);
2891     return DFG::canCompileFunctionForCall(this);
2892 }
2893
2894 void ProgramCodeBlock::jettison()
2895 {
2896     ASSERT(JITCode::isOptimizingJIT(getJITType()));
2897     ASSERT(this == replacement());
2898     if (DFG::shouldShowDisassembly())
2899         dataLog("Jettisoning ", *this, ".\n");
2900     static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
2901 }
2902
2903 void EvalCodeBlock::jettison()
2904 {
2905     ASSERT(JITCode::isOptimizingJIT(getJITType()));
2906     ASSERT(this == replacement());
2907     if (DFG::shouldShowDisassembly())
2908         dataLog("Jettisoning ", *this, ".\n");
2909     static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData());
2910 }
2911
2912 void FunctionCodeBlock::jettison()
2913 {
2914     ASSERT(JITCode::isOptimizingJIT(getJITType()));
2915     ASSERT(this == replacement());
2916     if (DFG::shouldShowDisassembly())
2917         dataLog("Jettisoning ", *this, ".\n");
2918     static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall);
2919 }
2920
2921 bool ProgramCodeBlock::jitCompileImpl(ExecState* exec)
2922 {
2923     ASSERT(getJITType() == JITCode::InterpreterThunk);
2924     ASSERT(this == replacement());
2925     return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(exec);
2926 }
2927
2928 bool EvalCodeBlock::jitCompileImpl(ExecState* exec)
2929 {
2930     ASSERT(getJITType() == JITCode::InterpreterThunk);
2931     ASSERT(this == replacement());
2932     return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(exec);
2933 }
2934
2935 bool FunctionCodeBlock::jitCompileImpl(ExecState* exec)
2936 {
2937     ASSERT(getJITType() == JITCode::InterpreterThunk);
2938     ASSERT(this == replacement());
2939     return static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(exec, m_isConstructor ? CodeForConstruct : CodeForCall);
2940 }
2941 #endif
2942
2943 JSGlobalObject* CodeBlock::globalObjectFor(CodeOrigin codeOrigin)
2944 {
2945     if (!codeOrigin.inlineCallFrame)
2946         return globalObject();
2947     return jsCast<FunctionExecutable*>(codeOrigin.inlineCallFrame->executable.get())->generatedBytecode().globalObject();
2948 }
2949
2950 unsigned CodeBlock::reoptimizationRetryCounter() const
2951 {
2952     ASSERT(m_reoptimizationRetryCounter <= Options::reoptimizationRetryCounterMax());
2953     return m_reoptimizationRetryCounter;
2954 }
2955
2956 void CodeBlock::countReoptimization()
2957 {
2958     m_reoptimizationRetryCounter++;
2959     if (m_reoptimizationRetryCounter > Options::reoptimizationRetryCounterMax())
2960         m_reoptimizationRetryCounter = Options::reoptimizationRetryCounterMax();
2961 }
2962
2963 int32_t CodeBlock::codeTypeThresholdMultiplier() const
2964 {
2965     if (codeType() == EvalCode)
2966         return Options::evalThresholdMultiplier();
2967     
2968     return 1;
2969 }
2970
2971 double CodeBlock::optimizationThresholdScalingFactor()
2972 {
2973     // This expression arises from doing a least-squares fit of
2974     //
2975     // F[x_] =: a * Sqrt[x + b] + Abs[c * x] + d
2976     //
2977     // against the data points:
2978     //
2979     //    x       F[x_]
2980     //    10       0.9          (smallest reasonable code block)
2981     //   200       1.0          (typical small-ish code block)
2982     //   320       1.2          (something I saw in 3d-cube that I wanted to optimize)
2983     //  1268       5.0          (something I saw in 3d-cube that I didn't want to optimize)
2984     //  4000       5.5          (random large size, used to cause the function to converge to a shallow curve of some sort)
2985     // 10000       6.0          (similar to above)
2986     //
2987     // I achieve the minimization using the following Mathematica code:
2988     //
2989     // MyFunctionTemplate[x_, a_, b_, c_, d_] := a*Sqrt[x + b] + Abs[c*x] + d
2990     //
2991     // samples = {{10, 0.9}, {200, 1}, {320, 1.2}, {1268, 5}, {4000, 5.5}, {10000, 6}}
2992     //
2993     // solution = 
2994     //     Minimize[Plus @@ ((MyFunctionTemplate[#[[1]], a, b, c, d] - #[[2]])^2 & /@ samples),
2995     //         {a, b, c, d}][[2]]
2996     //
2997     // And the code below (to initialize a, b, c, d) is generated by:
2998     //
2999     // Print["const double " <> ToString[#[[1]]] <> " = " <>
3000     //     If[#[[2]] < 0.00001, "0.0", ToString[#[[2]]]] <> ";"] & /@ solution
3001     //
3002     // We've long known the following to be true:
3003     // - Small code blocks are cheap to optimize and so we should do it sooner rather
3004     //   than later.
3005     // - Large code blocks are expensive to optimize and so we should postpone doing so,
3006     //   and sometimes have a large enough threshold that we never optimize them.
3007     // - The difference in cost is not totally linear because (a) just invoking the
3008     //   DFG incurs some base cost and (b) for large code blocks there is enough slop
3009     //   in the correlation between instruction count and the actual compilation cost
3010     //   that for those large blocks, the instruction count should not have a strong
3011     //   influence on our threshold.
3012     //
3013     // I knew the goals but I didn't know how to achieve them; so I picked an interesting
3014     // example where the heuristics were right (code block in 3d-cube with instruction
3015     // count 320, which got compiled early as it should have been) and one where they were
3016     // totally wrong (code block in 3d-cube with instruction count 1268, which was expensive
3017     // to compile and didn't run often enough to warrant compilation in my opinion), and
3018     // then threw in additional data points that represented my own guess of what our
3019     // heuristics should do for some round-numbered examples.
3020     //
3021     // The expression to which I decided to fit the data arose because I started with an
3022     // affine function, and then did two things: put the linear part in an Abs to ensure
3023     // that the fit didn't end up choosing a negative value of c (which would result in
3024     // the function turning over and going negative for large x) and I threw in a Sqrt
3025     // term because Sqrt represents my intution that the function should be more sensitive
3026     // to small changes in small values of x, but less sensitive when x gets large.
3027     
3028     // Note that the current fit essentially eliminates the linear portion of the
3029     // expression (c == 0.0).
3030     const double a = 0.061504;
3031     const double b = 1.02406;
3032     const double c = 0.0;
3033     const double d = 0.825914;
3034     
3035     double instructionCount = this->instructionCount();
3036     
3037     ASSERT(instructionCount); // Make sure this is called only after we have an instruction stream; otherwise it'll just return the value of d, which makes no sense.
3038     
3039     double result = d + a * sqrt(instructionCount + b) + c * instructionCount;
3040 #if ENABLE(JIT_VERBOSE_OSR)
3041     dataLog(*this, ": instruction count is ", instructionCount, ", scaling execution counter by ", result, " * ", codeTypeThresholdMultiplier(), "\n");
3042 #endif
3043     return result * codeTypeThresholdMultiplier();
3044 }
3045
3046 static int32_t clipThreshold(double threshold)
3047 {
3048     if (threshold < 1.0)
3049         return 1;
3050     
3051     if (threshold > static_cast<double>(std::numeric_limits<int32_t>::max()))
3052         return std::numeric_limits<int32_t>::max();
3053     
3054     return static_cast<int32_t>(threshold);
3055 }
3056
3057 int32_t CodeBlock::counterValueForOptimizeAfterWarmUp()
3058 {
3059     return clipThreshold(
3060         Options::thresholdForOptimizeAfterWarmUp() *
3061         optimizationThresholdScalingFactor() *
3062         (1 << reoptimizationRetryCounter()));
3063 }
3064
3065 int32_t CodeBlock::counterValueForOptimizeAfterLongWarmUp()
3066 {
3067     return clipThreshold(
3068         Options::thresholdForOptimizeAfterLongWarmUp() *
3069         optimizationThresholdScalingFactor() *
3070         (1 << reoptimizationRetryCounter()));
3071 }
3072
3073 int32_t CodeBlock::counterValueForOptimizeSoon()
3074 {
3075     return clipThreshold(
3076         Options::thresholdForOptimizeSoon() *
3077         optimizationThresholdScalingFactor() *
3078         (1 << reoptimizationRetryCounter()));
3079 }
3080
3081 bool CodeBlock::checkIfOptimizationThresholdReached()
3082 {
3083     return m_jitExecuteCounter.checkIfThresholdCrossedAndSet(this);
3084 }
3085
3086 void CodeBlock::optimizeNextInvocation()
3087 {
3088     m_jitExecuteCounter.setNewThreshold(0, this);
3089 }
3090
3091 void CodeBlock::dontOptimizeAnytimeSoon()
3092 {
3093     m_jitExecuteCounter.deferIndefinitely();
3094 }
3095
3096 void CodeBlock::optimizeAfterWarmUp()
3097 {
3098     m_jitExecuteCounter.setNewThreshold(counterValueForOptimizeAfterWarmUp(), this);
3099 }
3100
3101 void CodeBlock::optimizeAfterLongWarmUp()
3102 {
3103     m_jitExecuteCounter.setNewThreshold(counterValueForOptimizeAfterLongWarmUp(), this);
3104 }
3105
3106 void CodeBlock::optimizeSoon()
3107 {
3108     m_jitExecuteCounter.setNewThreshold(counterValueForOptimizeSoon(), this);
3109 }
3110
3111 #if ENABLE(JIT)
3112 uint32_t CodeBlock::adjustedExitCountThreshold(uint32_t desiredThreshold)
3113 {
3114     ASSERT(getJITType() == JITCode::DFGJIT);
3115     // Compute this the lame way so we don't saturate. This is called infrequently
3116     // enough that this loop won't hurt us.
3117     unsigned result = desiredThreshold;
3118     for (unsigned n = baselineVersion()->reoptimizationRetryCounter(); n--;) {
3119         unsigned newResult = result << 1;
3120         if (newResult < result)
3121             return std::numeric_limits<uint32_t>::max();
3122         result = newResult;
3123     }
3124     return result;
3125 }
3126
3127 uint32_t CodeBlock::exitCountThresholdForReoptimization()
3128 {
3129     return adjustedExitCountThreshold(Options::osrExitCountForReoptimization() * codeTypeThresholdMultiplier());
3130 }
3131
3132 uint32_t CodeBlock::exitCountThresholdForReoptimizationFromLoop()
3133 {
3134     return adjustedExitCountThreshold(Options::osrExitCountForReoptimizationFromLoop() * codeTypeThresholdMultiplier());
3135 }
3136
3137 bool CodeBlock::shouldReoptimizeNow()
3138 {
3139     return osrExitCounter() >= exitCountThresholdForReoptimization();
3140 }
3141
3142 bool CodeBlock::shouldReoptimizeFromLoopNow()
3143 {
3144     return osrExitCounter() >= exitCountThresholdForReoptimizationFromLoop();
3145 }
3146 #endif
3147
3148 #if ENABLE(VALUE_PROFILER)
3149 ArrayProfile* CodeBlock::getArrayProfile(unsigned bytecodeOffset)
3150 {
3151     for (unsigned i = 0; i < m_arrayProfiles.size(); ++i) {
3152         if (m_arrayProfiles[i].bytecodeOffset() == bytecodeOffset)
3153             return &m_arrayProfiles[i];
3154     }
3155     return 0;
3156 }
3157
3158 ArrayProfile* CodeBlock::getOrAddArrayProfile(unsigned bytecodeOffset)
3159 {
3160     ArrayProfile* result = getArrayProfile(bytecodeOffset);
3161     if (result)
3162         return result;
3163     return addArrayProfile(bytecodeOffset);
3164 }
3165
3166 void CodeBlock::updateAllPredictionsAndCountLiveness(
3167     OperationInProgress operation, unsigned& numberOfLiveNonArgumentValueProfiles, unsigned& numberOfSamplesInProfiles)
3168 {
3169     numberOfLiveNonArgumentValueProfiles = 0;
3170     numberOfSamplesInProfiles = 0; // If this divided by ValueProfile::numberOfBuckets equals numberOfValueProfiles() then value profiles are full.
3171     for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) {
3172         ValueProfile* profile = getFromAllValueProfiles(i);
3173         unsigned numSamples = profile->totalNumberOfSamples();
3174         if (numSamples > ValueProfile::numberOfBuckets)
3175             numSamples = ValueProfile::numberOfBuckets; // We don't want profiles that are extremely hot to be given more weight.
3176         numberOfSamplesInProfiles += numSamples;
3177         if (profile->m_bytecodeOffset < 0) {
3178             profile->computeUpdatedPrediction(operation);
3179             continue;
3180         }
3181         if (profile->numberOfSamples() || profile->m_prediction != SpecNone)
3182             numberOfLiveNonArgumentValueProfiles++;
3183         profile->computeUpdatedPrediction(operation);
3184     }
3185     
3186 #if ENABLE(DFG_JIT)
3187     m_lazyOperandValueProfiles.computeUpdatedPredictions(operation);
3188 #endif
3189 }
3190
3191 void CodeBlock::updateAllValueProfilePredictions(OperationInProgress operation)
3192 {
3193     unsigned ignoredValue1, ignoredValue2;
3194     updateAllPredictionsAndCountLiveness(operation, ignoredValue1, ignoredValue2);
3195 }
3196
3197 void CodeBlock::updateAllArrayPredictions(OperationInProgress operation)
3198 {
3199     for (unsigned i = m_arrayProfiles.size(); i--;)
3200         m_arrayProfiles[i].computeUpdatedPrediction(this, operation);
3201     
3202     // Don't count these either, for similar reasons.
3203     for (unsigned i = m_arrayAllocationProfiles.size(); i--;)
3204         m_arrayAllocationProfiles[i].updateIndexingType();
3205 }
3206
3207 void CodeBlock::updateAllPredictions(OperationInProgress operation)
3208 {
3209     updateAllValueProfilePredictions(operation);
3210     updateAllArrayPredictions(operation);
3211 }
3212
3213 bool CodeBlock::shouldOptimizeNow()
3214 {
3215 #if ENABLE(JIT_VERBOSE_OSR)
3216     dataLog("Considering optimizing ", *this, "...\n");
3217 #endif
3218
3219 #if ENABLE(VERBOSE_VALUE_PROFILE)
3220     dumpValueProfiles();
3221 #endif
3222
3223     if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay())
3224         return true;
3225     
3226     updateAllArrayPredictions();
3227     
3228     unsigned numberOfLiveNonArgumentValueProfiles;
3229     unsigned numberOfSamplesInProfiles;
3230     updateAllPredictionsAndCountLiveness(NoOperation, numberOfLiveNonArgumentValueProfiles, numberOfSamplesInProfiles);
3231
3232 #if ENABLE(JIT_VERBOSE_OSR)
3233     dataLogF("Profile hotness: %lf (%u / %u), %lf (%u / %u)\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), numberOfLiveNonArgumentValueProfiles, numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles(), numberOfSamplesInProfiles, ValueProfile::numberOfBuckets * numberOfValueProfiles());
3234 #endif
3235
3236     if ((!numberOfValueProfiles() || (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles() >= Options::desiredProfileLivenessRate())
3237         && (!totalNumberOfValueProfiles() || (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / totalNumberOfValueProfiles() >= Options::desiredProfileFullnessRate())
3238         && static_c