Ignore:
Timestamp:
Jun 28, 2012, 4:03:07 PM (13 years ago)
Author:
[email protected]
Message:

Adding a commenting utility to record BytecodeGenerator comments
with opcodes that are emitted. Presently, the comments can only
be constant strings. Adding comments for opcodes is optional.
If a comment is added, the comment will be printed following the
opcode when CodeBlock::dump() is called.

This utility is disabled by default, and is only meant for VM
development purposes. It should not be enabled for product builds.

To enable this utility, set ENABLE_BYTECODE_COMMENTS in CodeBlock.h
to 1.

https://bugs.webkit.org/show_bug.cgi?id=90095

Patch by Mark Lam <[email protected]> on 2012-06-28
Reviewed by Geoffrey Garen.

  • GNUmakefile.list.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecodeCommentAndNewLine): Dumps the comment.
(JSC):
(JSC::CodeBlock::printUnaryOp): Add comment dumps.
(JSC::CodeBlock::printBinaryOp): Add comment dumps.
(JSC::CodeBlock::printConditionalJump): Add comment dumps.
(JSC::CodeBlock::printCallOp): Add comment dumps.
(JSC::CodeBlock::printPutByIdOp): Add comment dumps.
(JSC::CodeBlock::dump): Add comment dumps.
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::commentForBytecodeOffset):

Finds the comment for an opcode if available.

(JSC::CodeBlock::dumpBytecodeComments):

For debugging whether comments are collected.
It is not being called anywhere.

  • bytecode/CodeBlock.h:

(CodeBlock):
(JSC::CodeBlock::bytecodeComments):

  • bytecode/Comment.h: Added.

(JSC):
(Comment):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitOpcode): Calls emitComment().
(JSC):
(JSC::BytecodeGenerator::emitComment): Adds comment to CodeBlock.
(JSC::BytecodeGenerator::prependComment):

Registers a comment for emitComemnt() to use later.

  • bytecompiler/BytecodeGenerator.h:

(BytecodeGenerator):
(JSC::BytecodeGenerator::emitComment):
(JSC::BytecodeGenerator::prependComment):

These are inlined versions of these functions that nullify them
when ENABLE_BYTECODE_COMMENTS is 0.

(JSC::BytecodeGenerator::comments):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r121215 r121480  
    4949#include <stdio.h>
    5050#include <wtf/StringExtras.h>
     51#include <wtf/UnusedParam.h>
    5152
    5253#if ENABLE(DFG_JIT)
     
    9293{
    9394    return makeUString(ident.ustring(), "(@id", UString::number(id0), ")").utf8();
     95}
     96
     97void CodeBlock::dumpBytecodeCommentAndNewLine(int location)
     98{
     99#if ENABLE(BYTECODE_COMMENTS)
     100    const char* comment = commentForBytecodeOffset(location);
     101    if (comment)
     102        dataLog("\t\t ; %s", comment);
     103#else
     104    UNUSED_PARAM(location);
     105#endif
     106    dataLog("\n");
    94107}
    95108
     
    157170    int r1 = (++it)->u.operand;
    158171
    159     dataLog("[%4d] %s\t\t %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data());
     172    dataLog("[%4d] %s\t\t %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data());
     173    dumpBytecodeCommentAndNewLine(location);
    160174}
    161175
     
    165179    int r1 = (++it)->u.operand;
    166180    int r2 = (++it)->u.operand;
    167     dataLog("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     181    dataLog("[%4d] %s\t\t %s, %s, %s", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     182    dumpBytecodeCommentAndNewLine(location);
    168183}
    169184
     
    172187    int r0 = (++it)->u.operand;
    173188    int offset = (++it)->u.operand;
    174     dataLog("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(exec, r0).data(), offset, location + offset);
     189    dataLog("[%4d] %s\t\t %s, %d(->%d)", location, op, registerName(exec, r0).data(), offset, location + offset);
     190    dumpBytecodeCommentAndNewLine(location);
    175191}
    176192
     
    403419#endif
    404420    }
    405     dataLog("\n");
     421    dumpBytecodeCommentAndNewLine(location);
    406422    it += 2;
    407423}
     
    412428    int id0 = (++it)->u.operand;
    413429    int r1 = (++it)->u.operand;
    414     dataLog("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
     430    dataLog("[%4d] %s\t %s, %s, %s", location, op, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
     431    dumpBytecodeCommentAndNewLine(location);
    415432    it += 5;
    416433}
     
    651668    switch (exec->interpreter()->getOpcodeID(it->u.opcode)) {
    652669        case op_enter: {
    653             dataLog("[%4d] enter\n", location);
     670            dataLog("[%4d] enter", location);
     671            dumpBytecodeCommentAndNewLine(location);
    654672            break;
    655673        }
    656674        case op_create_activation: {
    657675            int r0 = (++it)->u.operand;
    658             dataLog("[%4d] create_activation %s\n", location, registerName(exec, r0).data());
     676            dataLog("[%4d] create_activation %s", location, registerName(exec, r0).data());
     677            dumpBytecodeCommentAndNewLine(location);
    659678            break;
    660679        }
    661680        case op_create_arguments: {
    662681            int r0 = (++it)->u.operand;
    663             dataLog("[%4d] create_arguments\t %s\n", location, registerName(exec, r0).data());
     682            dataLog("[%4d] create_arguments\t %s", location, registerName(exec, r0).data());
     683            dumpBytecodeCommentAndNewLine(location);
    664684            break;
    665685        }
    666686        case op_init_lazy_reg: {
    667687            int r0 = (++it)->u.operand;
    668             dataLog("[%4d] init_lazy_reg\t %s\n", location, registerName(exec, r0).data());
     688            dataLog("[%4d] init_lazy_reg\t %s", location, registerName(exec, r0).data());
     689            dumpBytecodeCommentAndNewLine(location);
    669690            break;
    670691        }
    671692        case op_create_this: {
    672693            int r0 = (++it)->u.operand;
    673             dataLog("[%4d] create_this %s\n", location, registerName(exec, r0).data());
     694            dataLog("[%4d] create_this %s", location, registerName(exec, r0).data());
     695            dumpBytecodeCommentAndNewLine(location);
    674696            break;
    675697        }
    676698        case op_convert_this: {
    677699            int r0 = (++it)->u.operand;
    678             dataLog("[%4d] convert_this\t %s\n", location, registerName(exec, r0).data());
     700            dataLog("[%4d] convert_this\t %s", location, registerName(exec, r0).data());
     701            dumpBytecodeCommentAndNewLine(location);
    679702            ++it; // Skip value profile.
    680703            break;
     
    682705        case op_new_object: {
    683706            int r0 = (++it)->u.operand;
    684             dataLog("[%4d] new_object\t %s\n", location, registerName(exec, r0).data());
     707            dataLog("[%4d] new_object\t %s", location, registerName(exec, r0).data());
     708            dumpBytecodeCommentAndNewLine(location);
    685709            break;
    686710        }
     
    689713            int argv = (++it)->u.operand;
    690714            int argc = (++it)->u.operand;
    691             dataLog("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc);
     715            dataLog("[%4d] new_array\t %s, %s, %d", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc);
     716            dumpBytecodeCommentAndNewLine(location);
    692717            break;
    693718        }
     
    696721            int argv = (++it)->u.operand;
    697722            int argc = (++it)->u.operand;
    698             dataLog("[%4d] new_array_buffer %s, %d, %d\n", location, registerName(exec, dst).data(), argv, argc);
     723            dataLog("[%4d] new_array_buffer %s, %d, %d", location, registerName(exec, dst).data(), argv, argc);
     724            dumpBytecodeCommentAndNewLine(location);
    699725            break;
    700726        }
     
    704730            dataLog("[%4d] new_regexp\t %s, ", location, registerName(exec, r0).data());
    705731            if (r0 >=0 && r0 < (int)numberOfRegExps())
    706                 dataLog("%s\n", regexpName(re0, regexp(re0)).data());
     732                dataLog("%s", regexpName(re0, regexp(re0)).data());
    707733            else
    708                 dataLog("bad_regexp(%d)\n", re0);
     734                dataLog("bad_regexp(%d)", re0);
     735            dumpBytecodeCommentAndNewLine(location);
    709736            break;
    710737        }
     
    712739            int r0 = (++it)->u.operand;
    713740            int r1 = (++it)->u.operand;
    714             dataLog("[%4d] mov\t\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data());
     741            dataLog("[%4d] mov\t\t %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
     742            dumpBytecodeCommentAndNewLine(location);
    715743            break;
    716744        }
     
    761789        case op_pre_inc: {
    762790            int r0 = (++it)->u.operand;
    763             dataLog("[%4d] pre_inc\t\t %s\n", location, registerName(exec, r0).data());
     791            dataLog("[%4d] pre_inc\t\t %s", location, registerName(exec, r0).data());
     792            dumpBytecodeCommentAndNewLine(location);
    764793            break;
    765794        }
    766795        case op_pre_dec: {
    767796            int r0 = (++it)->u.operand;
    768             dataLog("[%4d] pre_dec\t\t %s\n", location, registerName(exec, r0).data());
     797            dataLog("[%4d] pre_dec\t\t %s", location, registerName(exec, r0).data());
     798            dumpBytecodeCommentAndNewLine(location);
    769799            break;
    770800        }
     
    838868        case op_check_has_instance: {
    839869            int base = (++it)->u.operand;
    840             dataLog("[%4d] check_has_instance\t\t %s\n", location, registerName(exec, base).data());
     870            dataLog("[%4d] check_has_instance\t\t %s", location, registerName(exec, base).data());
     871            dumpBytecodeCommentAndNewLine(location);
    841872            break;
    842873        }
     
    846877            int r2 = (++it)->u.operand;
    847878            int r3 = (++it)->u.operand;
    848             dataLog("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data());
     879            dataLog("[%4d] instanceof\t\t %s, %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data());
     880            dumpBytecodeCommentAndNewLine(location);
    849881            break;
    850882        }
     
    884916            int r0 = (++it)->u.operand;
    885917            int id0 = (++it)->u.operand;
    886             dataLog("[%4d] resolve\t\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
     918            dataLog("[%4d] resolve\t\t %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
     919            dumpBytecodeCommentAndNewLine(location);
    887920            it++;
    888921            break;
     
    892925            int id0 = (++it)->u.operand;
    893926            int skipLevels = (++it)->u.operand;
    894             dataLog("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), skipLevels);
     927            dataLog("[%4d] resolve_skip\t %s, %s, %d", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), skipLevels);
     928            dumpBytecodeCommentAndNewLine(location);
    895929            it++;
    896930            break;
     
    899933            int r0 = (++it)->u.operand;
    900934            int id0 = (++it)->u.operand;
    901             dataLog("[%4d] resolve_global\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
     935            dataLog("[%4d] resolve_global\t %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
     936            dumpBytecodeCommentAndNewLine(location);
    902937            it += 3;
    903938            break;
     
    909944            ++it;
    910945            int depth = (++it)->u.operand;
    911             dataLog("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth);
     946            dataLog("[%4d] resolve_global_dynamic\t %s, %s, %s, %d", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth);
     947            dumpBytecodeCommentAndNewLine(location);
    912948            ++it;
    913949            break;
     
    917953            int index = (++it)->u.operand;
    918954            int skipLevels = (++it)->u.operand;
    919             dataLog("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(exec, r0).data(), index, skipLevels);
     955            dataLog("[%4d] get_scoped_var\t %s, %d, %d", location, registerName(exec, r0).data(), index, skipLevels);
     956            dumpBytecodeCommentAndNewLine(location);
    920957            it++;
    921958            break;
     
    925962            int skipLevels = (++it)->u.operand;
    926963            int r0 = (++it)->u.operand;
    927             dataLog("[%4d] put_scoped_var\t %d, %d, %s\n", location, index, skipLevels, registerName(exec, r0).data());
     964            dataLog("[%4d] put_scoped_var\t %d, %d, %s", location, index, skipLevels, registerName(exec, r0).data());
     965            dumpBytecodeCommentAndNewLine(location);
    928966            break;
    929967        }
     
    931969            int r0 = (++it)->u.operand;
    932970            WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
    933             dataLog("[%4d] get_global_var\t %s, g%d(%p)\n", location, registerName(exec, r0).data(), m_globalObject->findRegisterIndex(registerPointer), registerPointer);
     971            dataLog("[%4d] get_global_var\t %s, g%d(%p)", location, registerName(exec, r0).data(), m_globalObject->findRegisterIndex(registerPointer), registerPointer);
     972            dumpBytecodeCommentAndNewLine(location);
    934973            it++;
    935974            break;
     
    938977            int r0 = (++it)->u.operand;
    939978            WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
    940             dataLog("[%4d] get_global_var_watchable\t %s, g%d(%p)\n", location, registerName(exec, r0).data(), m_globalObject->findRegisterIndex(registerPointer), registerPointer);
     979            dataLog("[%4d] get_global_var_watchable\t %s, g%d(%p)", location, registerName(exec, r0).data(), m_globalObject->findRegisterIndex(registerPointer), registerPointer);
     980            dumpBytecodeCommentAndNewLine(location);
    941981            it++;
    942982            it++;
     
    946986            WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
    947987            int r0 = (++it)->u.operand;
    948             dataLog("[%4d] put_global_var\t g%d(%p), %s\n", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
     988            dataLog("[%4d] put_global_var\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
     989            dumpBytecodeCommentAndNewLine(location);
    949990            break;
    950991        }
     
    952993            WriteBarrier<Unknown>* registerPointer = (++it)->u.registerPointer;
    953994            int r0 = (++it)->u.operand;
    954             dataLog("[%4d] put_global_var_check\t g%d(%p), %s\n", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
     995            dataLog("[%4d] put_global_var_check\t g%d(%p), %s", location, m_globalObject->findRegisterIndex(registerPointer), registerPointer, registerName(exec, r0).data());
     996            dumpBytecodeCommentAndNewLine(location);
    955997            it++;
    956998            it++;
     
    9611003            int id0 = (++it)->u.operand;
    9621004            int isStrict = (++it)->u.operand;
    963             dataLog("[%4d] resolve_base%s\t %s, %s\n", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
     1005            dataLog("[%4d] resolve_base%s\t %s, %s", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
     1006            dumpBytecodeCommentAndNewLine(location);
    9641007            it++;
    9651008            break;
     
    9681011            int r0 = (++it)->u.operand;
    9691012            int id0 = (++it)->u.operand;
    970             dataLog("[%4d] ensure_property_exists\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
     1013            dataLog("[%4d] ensure_property_exists\t %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
     1014            dumpBytecodeCommentAndNewLine(location);
    9711015            break;
    9721016        }
     
    9751019            int r1 = (++it)->u.operand;
    9761020            int id0 = (++it)->u.operand;
    977             dataLog("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
     1021            dataLog("[%4d] resolve_with_base %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
     1022            dumpBytecodeCommentAndNewLine(location);
    9781023            it++;
    9791024            break;
     
    9831028            int r1 = (++it)->u.operand;
    9841029            int id0 = (++it)->u.operand;
    985             dataLog("[%4d] resolve_with_this %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
     1030            dataLog("[%4d] resolve_with_this %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
     1031            dumpBytecodeCommentAndNewLine(location);
    9861032            it++;
    9871033            break;
     
    10021048            printGetByIdOp(exec, location, it);
    10031049            printGetByIdCacheStatus(exec, location);
    1004             dataLog("\n");
     1050            dumpBytecodeCommentAndNewLine(location);
    10051051            break;
    10061052        }
     
    10391085            int r1 = (++it)->u.operand;
    10401086            int r2 = (++it)->u.operand;
    1041             dataLog("[%4d] put_getter_setter\t %s, %s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     1087            dataLog("[%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());
     1088            dumpBytecodeCommentAndNewLine(location);
    10421089            break;
    10431090        }
     
    10711118            }
    10721119#endif
    1073             dataLog("\n");
     1120            dumpBytecodeCommentAndNewLine(location);
    10741121            ++it;
    10751122            printGetByIdOp(exec, location, it);
     
    10821129            int r1 = (++it)->u.operand;
    10831130            int id0 = (++it)->u.operand;
    1084             dataLog("[%4d] del_by_id\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
     1131            dataLog("[%4d] del_by_id\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
     1132            dumpBytecodeCommentAndNewLine(location);
    10851133            break;
    10861134        }
     
    10891137            int r1 = (++it)->u.operand;
    10901138            int r2 = (++it)->u.operand;
    1091             dataLog("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     1139            dataLog("[%4d] get_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     1140            dumpBytecodeCommentAndNewLine(location);
    10921141            it++;
    10931142            break;
     
    10971146            int r1 = (++it)->u.operand;
    10981147            int r2 = (++it)->u.operand;
    1099             dataLog("[%4d] get_argument_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     1148            dataLog("[%4d] get_argument_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     1149            dumpBytecodeCommentAndNewLine(location);
    11001150            ++it;
    11011151            break;
     
    11081158            int r4 = (++it)->u.operand;
    11091159            int r5 = (++it)->u.operand;
    1110             dataLog("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s\n", 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());
     1160            dataLog("[%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());
     1161            dumpBytecodeCommentAndNewLine(location);
    11111162            break;
    11121163        }
     
    11151166            int r1 = (++it)->u.operand;
    11161167            int r2 = (++it)->u.operand;
    1117             dataLog("[%4d] put_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     1168            dataLog("[%4d] put_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     1169            dumpBytecodeCommentAndNewLine(location);
    11181170            break;
    11191171        }
     
    11221174            int r1 = (++it)->u.operand;
    11231175            int r2 = (++it)->u.operand;
    1124             dataLog("[%4d] del_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     1176            dataLog("[%4d] del_by_val\t %s, %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
     1177            dumpBytecodeCommentAndNewLine(location);
    11251178            break;
    11261179        }
     
    11291182            unsigned n0 = (++it)->u.operand;
    11301183            int r1 = (++it)->u.operand;
    1131             dataLog("[%4d] put_by_index\t %s, %u, %s\n", location, registerName(exec, r0).data(), n0, registerName(exec, r1).data());
     1184            dataLog("[%4d] put_by_index\t %s, %u, %s", location, registerName(exec, r0).data(), n0, registerName(exec, r1).data());
     1185            dumpBytecodeCommentAndNewLine(location);
    11321186            break;
    11331187        }
    11341188        case op_jmp: {
    11351189            int offset = (++it)->u.operand;
    1136             dataLog("[%4d] jmp\t\t %d(->%d)\n", location, offset, location + offset);
     1190            dataLog("[%4d] jmp\t\t %d(->%d)", location, offset, location + offset);
     1191            dumpBytecodeCommentAndNewLine(location);
    11371192            break;
    11381193        }
    11391194        case op_loop: {
    11401195            int offset = (++it)->u.operand;
    1141             dataLog("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset);
     1196            dataLog("[%4d] loop\t\t %d(->%d)", location, offset, location + offset);
     1197            dumpBytecodeCommentAndNewLine(location);
    11421198            break;
    11431199        }
     
    11701226            void* pointer = (++it)->u.pointer;
    11711227            int offset = (++it)->u.operand;
    1172             dataLog("[%4d] jneq_ptr\t\t %s, %p, %d(->%d)\n", location, registerName(exec, r0).data(), pointer, offset, location + offset);
     1228            dataLog("[%4d] jneq_ptr\t\t %s, %p, %d(->%d)", location, registerName(exec, r0).data(), pointer, offset, location + offset);
     1229            dumpBytecodeCommentAndNewLine(location);
    11731230            break;
    11741231        }
     
    11771234            int r1 = (++it)->u.operand;
    11781235            int offset = (++it)->u.operand;
    1179             dataLog("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1236            dataLog("[%4d] jless\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1237            dumpBytecodeCommentAndNewLine(location);
    11801238            break;
    11811239        }
     
    11841242            int r1 = (++it)->u.operand;
    11851243            int offset = (++it)->u.operand;
    1186             dataLog("[%4d] jlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1244            dataLog("[%4d] jlesseq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1245            dumpBytecodeCommentAndNewLine(location);
    11871246            break;
    11881247        }
     
    11911250            int r1 = (++it)->u.operand;
    11921251            int offset = (++it)->u.operand;
    1193             dataLog("[%4d] jgreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1252            dataLog("[%4d] jgreater\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1253            dumpBytecodeCommentAndNewLine(location);
    11941254            break;
    11951255        }
     
    11981258            int r1 = (++it)->u.operand;
    11991259            int offset = (++it)->u.operand;
    1200             dataLog("[%4d] jgreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1260            dataLog("[%4d] jgreatereq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1261            dumpBytecodeCommentAndNewLine(location);
    12011262            break;
    12021263        }
     
    12051266            int r1 = (++it)->u.operand;
    12061267            int offset = (++it)->u.operand;
    1207             dataLog("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1268            dataLog("[%4d] jnless\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1269            dumpBytecodeCommentAndNewLine(location);
    12081270            break;
    12091271        }
     
    12121274            int r1 = (++it)->u.operand;
    12131275            int offset = (++it)->u.operand;
    1214             dataLog("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1276            dataLog("[%4d] jnlesseq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1277            dumpBytecodeCommentAndNewLine(location);
    12151278            break;
    12161279        }
     
    12191282            int r1 = (++it)->u.operand;
    12201283            int offset = (++it)->u.operand;
    1221             dataLog("[%4d] jngreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1284            dataLog("[%4d] jngreater\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1285            dumpBytecodeCommentAndNewLine(location);
    12221286            break;
    12231287        }
     
    12261290            int r1 = (++it)->u.operand;
    12271291            int offset = (++it)->u.operand;
    1228             dataLog("[%4d] jngreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1292            dataLog("[%4d] jngreatereq\t\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1293            dumpBytecodeCommentAndNewLine(location);
    12291294            break;
    12301295        }
     
    12331298            int r1 = (++it)->u.operand;
    12341299            int offset = (++it)->u.operand;
    1235             dataLog("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1300            dataLog("[%4d] loop_if_less\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1301            dumpBytecodeCommentAndNewLine(location);
    12361302            break;
    12371303        }
     
    12401306            int r1 = (++it)->u.operand;
    12411307            int offset = (++it)->u.operand;
    1242             dataLog("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1308            dataLog("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1309            dumpBytecodeCommentAndNewLine(location);
    12431310            break;
    12441311        }
     
    12471314            int r1 = (++it)->u.operand;
    12481315            int offset = (++it)->u.operand;
    1249             dataLog("[%4d] loop_if_greater\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1316            dataLog("[%4d] loop_if_greater\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1317            dumpBytecodeCommentAndNewLine(location);
    12501318            break;
    12511319        }
     
    12541322            int r1 = (++it)->u.operand;
    12551323            int offset = (++it)->u.operand;
    1256             dataLog("[%4d] loop_if_greatereq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1324            dataLog("[%4d] loop_if_greatereq\t %s, %s, %d(->%d)", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
     1325            dumpBytecodeCommentAndNewLine(location);
    12571326            break;
    12581327        }
    12591328        case op_loop_hint: {
    1260             dataLog("[%4d] loop_hint\n", location);
     1329            dataLog("[%4d] loop_hint", location);
     1330            dumpBytecodeCommentAndNewLine(location);
    12611331            break;
    12621332        }
     
    12651335            int defaultTarget = (++it)->u.operand;
    12661336            int scrutineeRegister = (++it)->u.operand;
    1267             dataLog("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
     1337            dataLog("[%4d] switch_imm\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
     1338            dumpBytecodeCommentAndNewLine(location);
    12681339            break;
    12691340        }
     
    12721343            int defaultTarget = (++it)->u.operand;
    12731344            int scrutineeRegister = (++it)->u.operand;
    1274             dataLog("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
     1345            dataLog("[%4d] switch_char\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
     1346            dumpBytecodeCommentAndNewLine(location);
    12751347            break;
    12761348        }
     
    12791351            int defaultTarget = (++it)->u.operand;
    12801352            int scrutineeRegister = (++it)->u.operand;
    1281             dataLog("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
     1353            dataLog("[%4d] switch_string\t %d, %d(->%d), %s", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
     1354            dumpBytecodeCommentAndNewLine(location);
    12821355            break;
    12831356        }
     
    12861359            int f0 = (++it)->u.operand;
    12871360            int shouldCheck = (++it)->u.operand;
    1288             dataLog("[%4d] new_func\t\t %s, f%d, %s\n", location, registerName(exec, r0).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>");
     1361            dataLog("[%4d] new_func\t\t %s, f%d, %s", location, registerName(exec, r0).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>");
     1362            dumpBytecodeCommentAndNewLine(location);
    12891363            break;
    12901364        }
     
    12921366            int r0 = (++it)->u.operand;
    12931367            int f0 = (++it)->u.operand;
    1294             dataLog("[%4d] new_func_exp\t %s, f%d\n", location, registerName(exec, r0).data(), f0);
     1368            dataLog("[%4d] new_func_exp\t %s, f%d", location, registerName(exec, r0).data(), f0);
     1369            dumpBytecodeCommentAndNewLine(location);
    12951370            break;
    12961371        }
     
    13081383            int arguments = (++it)->u.operand;
    13091384            int firstFreeRegister = (++it)->u.operand;
    1310             dataLog("[%4d] call_varargs\t %s, %s, %s, %d\n", location, registerName(exec, callee).data(), registerName(exec, thisValue).data(), registerName(exec, arguments).data(), firstFreeRegister);
     1385            dataLog("[%4d] call_varargs\t %s, %s, %s, %d", location, registerName(exec, callee).data(), registerName(exec, thisValue).data(), registerName(exec, arguments).data(), firstFreeRegister);
     1386            dumpBytecodeCommentAndNewLine(location);
    13111387            break;
    13121388        }
     
    13141390            int r0 = (++it)->u.operand;
    13151391            int r1 = (++it)->u.operand;
    1316             dataLog("[%4d] tear_off_activation\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data());
     1392            dataLog("[%4d] tear_off_activation\t %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
     1393            dumpBytecodeCommentAndNewLine(location);
    13171394            break;
    13181395        }
    13191396        case op_tear_off_arguments: {
    13201397            int r0 = (++it)->u.operand;
    1321             dataLog("[%4d] tear_off_arguments %s\n", location, registerName(exec, r0).data());
     1398            dataLog("[%4d] tear_off_arguments %s", location, registerName(exec, r0).data());
     1399            dumpBytecodeCommentAndNewLine(location);
    13221400            break;
    13231401        }
    13241402        case op_ret: {
    13251403            int r0 = (++it)->u.operand;
    1326             dataLog("[%4d] ret\t\t %s\n", location, registerName(exec, r0).data());
     1404            dataLog("[%4d] ret\t\t %s", location, registerName(exec, r0).data());
     1405            dumpBytecodeCommentAndNewLine(location);
    13271406            break;
    13281407        }
    13291408        case op_call_put_result: {
    13301409            int r0 = (++it)->u.operand;
    1331             dataLog("[%4d] call_put_result\t\t %s\n", location, registerName(exec, r0).data());
     1410            dataLog("[%4d] call_put_result\t\t %s", location, registerName(exec, r0).data());
     1411            dumpBytecodeCommentAndNewLine(location);
    13321412            it++;
    13331413            break;
     
    13361416            int r0 = (++it)->u.operand;
    13371417            int r1 = (++it)->u.operand;
    1338             dataLog("[%4d] constructor_ret\t\t %s %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data());
     1418            dataLog("[%4d] constructor_ret\t\t %s %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
     1419            dumpBytecodeCommentAndNewLine(location);
    13391420            break;
    13401421        }
     
    13471428            int r1 = (++it)->u.operand;
    13481429            int count = (++it)->u.operand;
    1349             dataLog("[%4d] strcat\t\t %s, %s, %d\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), count);
     1430            dataLog("[%4d] strcat\t\t %s, %s, %d", location, registerName(exec, r0).data(), registerName(exec, r1).data(), count);
     1431            dumpBytecodeCommentAndNewLine(location);
    13501432            break;
    13511433        }
     
    13531435            int r0 = (++it)->u.operand;
    13541436            int r1 = (++it)->u.operand;
    1355             dataLog("[%4d] to_primitive\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data());
     1437            dataLog("[%4d] to_primitive\t %s, %s", location, registerName(exec, r0).data(), registerName(exec, r1).data());
     1438            dumpBytecodeCommentAndNewLine(location);
    13561439            break;
    13571440        }
     
    13621445            int r3 = it[4].u.operand;
    13631446            int offset = it[5].u.operand;
    1364             dataLog("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), offset, location + offset);
     1447            dataLog("[%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);
     1448            dumpBytecodeCommentAndNewLine(location);
    13651449            it += OPCODE_LENGTH(op_get_pnames) - 1;
    13661450            break;
     
    13731457            int iter = it[5].u.operand;
    13741458            int offset = it[6].u.operand;
    1375             dataLog("[%4d] next_pname\t %s, %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, dest).data(), registerName(exec, base).data(), registerName(exec, i).data(), registerName(exec, size).data(), registerName(exec, iter).data(), offset, location + offset);
     1459            dataLog("[%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);
     1460            dumpBytecodeCommentAndNewLine(location);
    13761461            it += OPCODE_LENGTH(op_next_pname) - 1;
    13771462            break;
     
    13791464        case op_push_scope: {
    13801465            int r0 = (++it)->u.operand;
    1381             dataLog("[%4d] push_scope\t %s\n", location, registerName(exec, r0).data());
     1466            dataLog("[%4d] push_scope\t %s", location, registerName(exec, r0).data());
     1467            dumpBytecodeCommentAndNewLine(location);
    13821468            break;
    13831469        }
    13841470        case op_pop_scope: {
    1385             dataLog("[%4d] pop_scope\n", location);
     1471            dataLog("[%4d] pop_scope", location);
     1472            dumpBytecodeCommentAndNewLine(location);
    13861473            break;
    13871474        }
     
    13901477            int id0 = (++it)->u.operand;
    13911478            int r1 = (++it)->u.operand;
    1392             dataLog("[%4d] push_new_scope \t%s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
     1479            dataLog("[%4d] push_new_scope \t%s, %s, %s", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
     1480            dumpBytecodeCommentAndNewLine(location);
    13931481            break;
    13941482        }
     
    13961484            int scopeDelta = (++it)->u.operand;
    13971485            int offset = (++it)->u.operand;
    1398             dataLog("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, location + offset);
     1486            dataLog("[%4d] jmp_scopes\t^%d, %d(->%d)", location, scopeDelta, offset, location + offset);
     1487            dumpBytecodeCommentAndNewLine(location);
    13991488            break;
    14001489        }
    14011490        case op_catch: {
    14021491            int r0 = (++it)->u.operand;
    1403             dataLog("[%4d] catch\t\t %s\n", location, registerName(exec, r0).data());
     1492            dataLog("[%4d] catch\t\t %s", location, registerName(exec, r0).data());
     1493            dumpBytecodeCommentAndNewLine(location);
    14041494            break;
    14051495        }
    14061496        case op_throw: {
    14071497            int r0 = (++it)->u.operand;
    1408             dataLog("[%4d] throw\t\t %s\n", location, registerName(exec, r0).data());
     1498            dataLog("[%4d] throw\t\t %s", location, registerName(exec, r0).data());
     1499            dumpBytecodeCommentAndNewLine(location);
    14091500            break;
    14101501        }
    14111502        case op_throw_reference_error: {
    14121503            int k0 = (++it)->u.operand;
    1413             dataLog("[%4d] throw_reference_error\t %s\n", location, constantName(exec, k0, getConstant(k0)).data());
     1504            dataLog("[%4d] throw_reference_error\t %s", location, constantName(exec, k0, getConstant(k0)).data());
     1505            dumpBytecodeCommentAndNewLine(location);
    14141506            break;
    14151507        }
     
    14181510            int firstLine = (++it)->u.operand;
    14191511            int lastLine = (++it)->u.operand;
    1420             dataLog("[%4d] debug\t\t %s, %d, %d\n", location, debugHookName(debugHookID), firstLine, lastLine);
     1512            dataLog("[%4d] debug\t\t %s, %d, %d", location, debugHookName(debugHookID), firstLine, lastLine);
     1513            dumpBytecodeCommentAndNewLine(location);
    14211514            break;
    14221515        }
    14231516        case op_profile_will_call: {
    14241517            int function = (++it)->u.operand;
    1425             dataLog("[%4d] profile_will_call %s\n", location, registerName(exec, function).data());
     1518            dataLog("[%4d] profile_will_call %s", location, registerName(exec, function).data());
     1519            dumpBytecodeCommentAndNewLine(location);
    14261520            break;
    14271521        }
    14281522        case op_profile_did_call: {
    14291523            int function = (++it)->u.operand;
    1430             dataLog("[%4d] profile_did_call\t %s\n", location, registerName(exec, function).data());
     1524            dataLog("[%4d] profile_did_call\t %s", location, registerName(exec, function).data());
     1525            dumpBytecodeCommentAndNewLine(location);
    14311526            break;
    14321527        }
    14331528        case op_end: {
    14341529            int r0 = (++it)->u.operand;
    1435             dataLog("[%4d] end\t\t %s\n", location, registerName(exec, r0).data());
     1530            dataLog("[%4d] end\t\t %s", location, registerName(exec, r0).data());
     1531            dumpBytecodeCommentAndNewLine(location);
    14361532            break;
    14371533        }
     
    16021698    , m_reoptimizationRetryCounter(0)
    16031699    , m_lineInfo(other.m_lineInfo)
     1700#if ENABLE(BYTECODE_COMMENTS)
     1701    , m_bytecodeCommentIterator(0)
     1702#endif
    16041703#if ENABLE(JIT)
    16051704    , m_canCompileWithDFGState(DFG::CapabilityLevelNotSet)
     
    16541753    , m_optimizationDelayCounter(0)
    16551754    , m_reoptimizationRetryCounter(0)
     1755#if ENABLE(BYTECODE_COMMENTS)
     1756    , m_bytecodeCommentIterator(0)
     1757#endif
    16561758{
    16571759    ASSERT(m_source);
     
    21282230}
    21292231
     2232#if ENABLE(BYTECODE_COMMENTS)
     2233// Finds the comment string for the specified bytecode offset/PC is available.
     2234const char* CodeBlock::commentForBytecodeOffset(unsigned bytecodeOffset)
     2235{
     2236    ASSERT(bytecodeOffset < instructions().size());
     2237
     2238    Vector<Comment>& comments = m_bytecodeComments;
     2239    size_t numberOfComments = comments.size();
     2240    const char* result = 0;
     2241
     2242    if (!numberOfComments)
     2243        return 0; // No comments to match with.
     2244
     2245    // The next match is most likely the next comment in the list.
     2246    // Do a quick check to see if that is a match first.
     2247    // m_bytecodeCommentIterator should already be pointing to the
     2248    // next comment we should check.
     2249
     2250    ASSERT(m_bytecodeCommentIterator < comments.size());
     2251
     2252    size_t i = m_bytecodeCommentIterator;
     2253    size_t commentPC = comments[i].pc;
     2254    if (commentPC == bytecodeOffset) {
     2255        // We've got a match. All done!
     2256        m_bytecodeCommentIterator = i;
     2257        result = comments[i].string;
     2258    } else if (commentPC > bytecodeOffset) {
     2259        // The current comment is already greater than the requested PC.
     2260        // Start searching from the first comment.
     2261        i = 0;
     2262    } else {
     2263        // Otherwise, the current comment's PC is less than the requested PC.
     2264        // Hence, we can just start searching from the next comment in the
     2265        // list.
     2266        i++;
     2267    }
     2268
     2269    // If the result is still not found, do a linear search in the range
     2270    // that we've determined above.
     2271    if (!result) {
     2272        for (; i < comments.size(); ++i) {
     2273            commentPC = comments[i].pc;
     2274            if (commentPC == bytecodeOffset) {
     2275                result = comments[i].string;
     2276                break;
     2277            }
     2278            if (comments[i].pc > bytecodeOffset) {
     2279                // The current comment PC is already past the requested
     2280                // bytecodeOffset. Hence, there are no more possible
     2281                // matches. Just fail.
     2282                break;
     2283            }
     2284        }
     2285    }
     2286
     2287    // Update the iterator to point to the next comment.
     2288    if (++i >= numberOfComments) {
     2289        // At most point to the last comment entry. This ensures that the
     2290        // next time we call this function, the quick checks will at least
     2291        // have one entry to check and can fail fast if appropriate.
     2292        i = numberOfComments - 1;
     2293    }
     2294    m_bytecodeCommentIterator = i;
     2295    return result;
     2296}
     2297
     2298void CodeBlock::dumpBytecodeComments()
     2299{
     2300    Vector<Comment>& comments = m_bytecodeComments;
     2301    printf("Comments for codeblock %p: size %lu\n", this, comments.size());
     2302    for (size_t i = 0; i < comments.size(); ++i)
     2303        printf("     pc %lu : '%s'\n", comments[i].pc, comments[i].string);
     2304    printf("End of comments for codeblock %p\n", this);
     2305}
     2306#endif // ENABLE_BYTECODE_COMMENTS
     2307
    21302308HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
    21312309{
Note: See TracChangeset for help on using the changeset viewer.