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