diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-24 16:36:50 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-24 16:36:50 +0100 |
commit | ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (patch) | |
tree | b34b0daceb7c8e7fdde4b4ec43650ab7caadb0a9 /Source/JavaScriptCore/bytecode/CodeBlock.cpp | |
parent | 03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (diff) | |
download | qtwebkit-ad0d549d4cc13433f77c1ac8f0ab379c83d93f28.tar.gz |
Imported WebKit commit bb52bf3c0119e8a128cd93afe5572413a8617de9 (http://svn.webkit.org/repository/webkit/trunk@108790)
Diffstat (limited to 'Source/JavaScriptCore/bytecode/CodeBlock.cpp')
-rw-r--r-- | Source/JavaScriptCore/bytecode/CodeBlock.cpp | 518 |
1 files changed, 339 insertions, 179 deletions
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index 191fafd62..ab89ad965 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -42,6 +42,7 @@ #include "JSFunction.h" #include "JSStaticScopeObject.h" #include "JSValue.h" +#include "LowLevelInterpreter.h" #include "RepatchBuffer.h" #include "UStringConcatenate.h" #include <stdio.h> @@ -154,7 +155,7 @@ void CodeBlock::printUnaryOp(ExecState* exec, int location, Vector<Instruction>: int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] %s\t\t %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data()); } void CodeBlock::printBinaryOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const @@ -162,14 +163,14 @@ void CodeBlock::printBinaryOp(ExecState* exec, int location, Vector<Instruction> int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + dataLog("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); } void CodeBlock::printConditionalJump(ExecState* exec, const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator& it, int location, const char* op) const { int r0 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(exec, r0).data(), offset, location + offset); + dataLog("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(exec, r0).data(), offset, location + offset); } void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const @@ -177,7 +178,7 @@ void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vector<Instruction int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); it += 5; } @@ -186,7 +187,7 @@ void CodeBlock::printCallOp(ExecState* exec, int location, Vector<Instruction>:: int func = (++it)->u.operand; int argCount = (++it)->u.operand; int registerOffset = (++it)->u.operand; - printf("[%4d] %s\t %s, %d, %d\n", location, op, registerName(exec, func).data(), argCount, registerOffset); + dataLog("[%4d] %s\t %s, %d, %d\n", location, op, registerName(exec, func).data(), argCount, registerOffset); it += 2; } @@ -195,7 +196,7 @@ void CodeBlock::printPutByIdOp(ExecState* exec, int location, Vector<Instruction int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); + dataLog("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); it += 5; } @@ -243,48 +244,48 @@ static unsigned instructionOffsetForNth(ExecState* exec, const Vector<Instructio static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigned instructionOffset) { - printf(" [%4d] %s: %s\n", instructionOffset, "resolve_global", pointerToSourceString(resolveInfo.structure).utf8().data()); + dataLog(" [%4d] %s: %s\n", instructionOffset, "resolve_global", pointerToSourceString(resolveInfo.structure).utf8().data()); } static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset) { switch (stubInfo.accessType) { case access_get_by_id_self: - printf(" [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).utf8().data()); + dataLog(" [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).utf8().data()); return; case access_get_by_id_proto: - printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).utf8().data(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).utf8().data()); + dataLog(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).utf8().data(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).utf8().data()); return; case access_get_by_id_chain: - printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).utf8().data(), pointerToSourceString(stubInfo.u.getByIdChain.chain).utf8().data()); + dataLog(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).utf8().data(), pointerToSourceString(stubInfo.u.getByIdChain.chain).utf8().data()); return; case access_get_by_id_self_list: - printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).utf8().data(), stubInfo.u.getByIdSelfList.listSize); + dataLog(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).utf8().data(), stubInfo.u.getByIdSelfList.listSize); return; case access_get_by_id_proto_list: - printf(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).utf8().data(), stubInfo.u.getByIdProtoList.listSize); + dataLog(" [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).utf8().data(), stubInfo.u.getByIdProtoList.listSize); return; case access_put_by_id_transition_normal: case access_put_by_id_transition_direct: - printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).utf8().data(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).utf8().data(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).utf8().data()); + dataLog(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).utf8().data(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).utf8().data(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).utf8().data()); return; case access_put_by_id_replace: - printf(" [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).utf8().data()); + dataLog(" [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).utf8().data()); return; case access_unset: - printf(" [%4d] %s\n", instructionOffset, "unset"); + dataLog(" [%4d] %s\n", instructionOffset, "unset"); return; case access_get_by_id_generic: - printf(" [%4d] %s\n", instructionOffset, "op_get_by_id_generic"); + dataLog(" [%4d] %s\n", instructionOffset, "op_get_by_id_generic"); return; case access_put_by_id_generic: - printf(" [%4d] %s\n", instructionOffset, "op_put_by_id_generic"); + dataLog(" [%4d] %s\n", instructionOffset, "op_put_by_id_generic"); return; case access_get_array_length: - printf(" [%4d] %s\n", instructionOffset, "op_get_array_length"); + dataLog(" [%4d] %s\n", instructionOffset, "op_get_array_length"); return; case access_get_string_length: - printf(" [%4d] %s\n", instructionOffset, "op_get_string_length"); + dataLog(" [%4d] %s\n", instructionOffset, "op_get_string_length"); return; default: ASSERT_NOT_REACHED(); @@ -295,7 +296,7 @@ static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned i void CodeBlock::printStructure(const char* name, const Instruction* vPC, int operand) const { unsigned instructionOffset = vPC - instructions().begin(); - printf(" [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).utf8().data()); + dataLog(" [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).utf8().data()); } void CodeBlock::printStructures(const Instruction* vPC) const @@ -312,15 +313,15 @@ void CodeBlock::printStructures(const Instruction* vPC) const return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) { - 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()); + dataLog(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structure).utf8().data()); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) { - 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()); + dataLog(" [%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()); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) { - 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()); + dataLog(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).utf8().data(), pointerToSourceString(vPC[5].u.structureChain).utf8().data()); return; } if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id)) { @@ -347,7 +348,7 @@ void CodeBlock::printStructures(const Instruction* vPC) const void CodeBlock::dump(ExecState* exec) const { if (!m_instructions) { - printf("No instructions available.\n"); + dataLog("No instructions available.\n"); return; } @@ -356,10 +357,10 @@ void CodeBlock::dump(ExecState* exec) const for (size_t i = 0; i < instructions().size(); i += opcodeLengths[exec->interpreter()->getOpcodeID(instructions()[i].u.opcode)]) ++instructionCount; - printf("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s)\n\n", + dataLog("%lu m_instructions; %lu bytes at %p; %d parameter(s); %d callee register(s); %d variable(s)\n\n", static_cast<unsigned long>(instructionCount), static_cast<unsigned long>(instructions().size() * sizeof(Instruction)), - this, m_numParameters, m_numCalleeRegisters); + this, m_numParameters, m_numCalleeRegisters, m_numVars); Vector<Instruction>::const_iterator begin = instructions().begin(); Vector<Instruction>::const_iterator end = instructions().end(); @@ -367,35 +368,35 @@ void CodeBlock::dump(ExecState* exec) const dump(exec, begin, it); if (!m_identifiers.isEmpty()) { - printf("\nIdentifiers:\n"); + dataLog("\nIdentifiers:\n"); size_t i = 0; do { - printf(" id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].ustring().utf8().data()); + dataLog(" id%u = %s\n", static_cast<unsigned>(i), m_identifiers[i].ustring().utf8().data()); ++i; } while (i != m_identifiers.size()); } if (!m_constantRegisters.isEmpty()) { - printf("\nConstants:\n"); + dataLog("\nConstants:\n"); size_t i = 0; do { - printf(" k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, m_constantRegisters[i].get()).utf8().data()); + dataLog(" k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, m_constantRegisters[i].get()).utf8().data()); ++i; } while (i < m_constantRegisters.size()); } if (m_rareData && !m_rareData->m_regexps.isEmpty()) { - printf("\nm_regexps:\n"); + dataLog("\nm_regexps:\n"); size_t i = 0; do { - printf(" re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_rareData->m_regexps[i].get()).utf8().data()); + dataLog(" re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_rareData->m_regexps[i].get()).utf8().data()); ++i; } while (i < m_rareData->m_regexps.size()); } #if ENABLE(JIT) if (!m_globalResolveInfos.isEmpty() || !m_structureStubInfos.isEmpty()) - printf("\nStructures:\n"); + dataLog("\nStructures:\n"); if (!m_globalResolveInfos.isEmpty()) { size_t i = 0; @@ -412,9 +413,9 @@ void CodeBlock::dump(ExecState* exec) const } while (i < m_structureStubInfos.size()); } #endif -#if ENABLE(INTERPRETER) +#if ENABLE(CLASSIC_INTERPRETER) if (!m_globalResolveInstructions.isEmpty() || !m_propertyAccessInstructions.isEmpty()) - printf("\nStructures:\n"); + dataLog("\nStructures:\n"); if (!m_globalResolveInstructions.isEmpty()) { size_t i = 0; @@ -433,36 +434,36 @@ void CodeBlock::dump(ExecState* exec) const #endif if (m_rareData && !m_rareData->m_exceptionHandlers.isEmpty()) { - printf("\nException Handlers:\n"); + dataLog("\nException Handlers:\n"); unsigned i = 0; do { - printf("\t %d: { start: [%4d] end: [%4d] target: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target); + dataLog("\t %d: { start: [%4d] end: [%4d] target: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target); ++i; } while (i < m_rareData->m_exceptionHandlers.size()); } if (m_rareData && !m_rareData->m_immediateSwitchJumpTables.isEmpty()) { - printf("Immediate Switch Jump Tables:\n"); + dataLog("Immediate Switch Jump Tables:\n"); unsigned i = 0; do { - printf(" %1d = {\n", i); + dataLog(" %1d = {\n", i); int entry = 0; Vector<int32_t>::const_iterator end = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.end(); for (Vector<int32_t>::const_iterator iter = m_rareData->m_immediateSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) { if (!*iter) continue; - printf("\t\t%4d => %04d\n", entry + m_rareData->m_immediateSwitchJumpTables[i].min, *iter); + dataLog("\t\t%4d => %04d\n", entry + m_rareData->m_immediateSwitchJumpTables[i].min, *iter); } - printf(" }\n"); + dataLog(" }\n"); ++i; } while (i < m_rareData->m_immediateSwitchJumpTables.size()); } if (m_rareData && !m_rareData->m_characterSwitchJumpTables.isEmpty()) { - printf("\nCharacter Switch Jump Tables:\n"); + dataLog("\nCharacter Switch Jump Tables:\n"); unsigned i = 0; do { - printf(" %1d = {\n", i); + dataLog(" %1d = {\n", i); int entry = 0; Vector<int32_t>::const_iterator end = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.end(); for (Vector<int32_t>::const_iterator iter = m_rareData->m_characterSwitchJumpTables[i].branchOffsets.begin(); iter != end; ++iter, ++entry) { @@ -470,27 +471,27 @@ void CodeBlock::dump(ExecState* exec) const continue; ASSERT(!((i + m_rareData->m_characterSwitchJumpTables[i].min) & ~0xFFFF)); UChar ch = static_cast<UChar>(entry + m_rareData->m_characterSwitchJumpTables[i].min); - printf("\t\t\"%s\" => %04d\n", UString(&ch, 1).utf8().data(), *iter); + dataLog("\t\t\"%s\" => %04d\n", UString(&ch, 1).utf8().data(), *iter); } - printf(" }\n"); + dataLog(" }\n"); ++i; } while (i < m_rareData->m_characterSwitchJumpTables.size()); } if (m_rareData && !m_rareData->m_stringSwitchJumpTables.isEmpty()) { - printf("\nString Switch Jump Tables:\n"); + dataLog("\nString Switch Jump Tables:\n"); unsigned i = 0; do { - printf(" %1d = {\n", i); + dataLog(" %1d = {\n", i); StringJumpTable::StringOffsetTable::const_iterator end = m_rareData->m_stringSwitchJumpTables[i].offsetTable.end(); for (StringJumpTable::StringOffsetTable::const_iterator iter = m_rareData->m_stringSwitchJumpTables[i].offsetTable.begin(); iter != end; ++iter) - printf("\t\t\"%s\" => %04d\n", UString(iter->first).utf8().data(), iter->second.branchOffset); - printf(" }\n"); + dataLog("\t\t\"%s\" => %04d\n", UString(iter->first).utf8().data(), iter->second.branchOffset); + dataLog(" }\n"); ++i; } while (i < m_rareData->m_stringSwitchJumpTables.size()); } - printf("\n"); + dataLog("\n"); } void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator& it) const @@ -498,73 +499,73 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int location = it - begin; switch (exec->interpreter()->getOpcodeID(it->u.opcode)) { case op_enter: { - printf("[%4d] enter\n", location); + dataLog("[%4d] enter\n", location); break; } case op_create_activation: { int r0 = (++it)->u.operand; - printf("[%4d] create_activation %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] create_activation %s\n", location, registerName(exec, r0).data()); break; } case op_create_arguments: { int r0 = (++it)->u.operand; - printf("[%4d] create_arguments\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] create_arguments\t %s\n", location, registerName(exec, r0).data()); break; } case op_init_lazy_reg: { int r0 = (++it)->u.operand; - printf("[%4d] init_lazy_reg\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] init_lazy_reg\t %s\n", location, registerName(exec, r0).data()); break; } case op_get_callee: { int r0 = (++it)->u.operand; - printf("[%4d] op_get_callee %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] op_get_callee %s\n", location, registerName(exec, r0).data()); break; } case op_create_this: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] create_this %s %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] create_this %s %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); break; } case op_convert_this: { int r0 = (++it)->u.operand; - printf("[%4d] convert_this\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] convert_this\t %s\n", location, registerName(exec, r0).data()); break; } case op_new_object: { int r0 = (++it)->u.operand; - printf("[%4d] new_object\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] new_object\t %s\n", location, registerName(exec, r0).data()); break; } case op_new_array: { int dst = (++it)->u.operand; int argv = (++it)->u.operand; int argc = (++it)->u.operand; - printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc); + dataLog("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc); break; } case op_new_array_buffer: { int dst = (++it)->u.operand; int argv = (++it)->u.operand; int argc = (++it)->u.operand; - printf("[%4d] new_array_buffer %s, %d, %d\n", location, registerName(exec, dst).data(), argv, argc); + dataLog("[%4d] new_array_buffer %s, %d, %d\n", location, registerName(exec, dst).data(), argv, argc); break; } case op_new_regexp: { int r0 = (++it)->u.operand; int re0 = (++it)->u.operand; - printf("[%4d] new_regexp\t %s, ", location, registerName(exec, r0).data()); + dataLog("[%4d] new_regexp\t %s, ", location, registerName(exec, r0).data()); if (r0 >=0 && r0 < (int)numberOfRegExps()) - printf("%s\n", regexpName(re0, regexp(re0)).data()); + dataLog("%s\n", regexpName(re0, regexp(re0)).data()); else - printf("bad_regexp(%d)\n", re0); + dataLog("bad_regexp(%d)\n", re0); break; } case op_mov: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] mov\t\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] mov\t\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); break; } case op_not: { @@ -613,12 +614,12 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& } case op_pre_inc: { int r0 = (++it)->u.operand; - printf("[%4d] pre_inc\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] pre_inc\t\t %s\n", location, registerName(exec, r0).data()); break; } case op_pre_dec: { int r0 = (++it)->u.operand; - printf("[%4d] pre_dec\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] pre_dec\t\t %s\n", location, registerName(exec, r0).data()); break; } case op_post_inc: { @@ -694,7 +695,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& } case op_check_has_instance: { int base = (++it)->u.operand; - printf("[%4d] check_has_instance\t\t %s\n", location, registerName(exec, base).data()); + dataLog("[%4d] check_has_instance\t\t %s\n", location, registerName(exec, base).data()); break; } case op_instanceof: { @@ -702,7 +703,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; int r3 = (++it)->u.operand; - printf("[%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()); + 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()); break; } case op_typeof: { @@ -740,7 +741,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& case op_resolve: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] resolve\t\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] resolve\t\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); it++; break; } @@ -748,14 +749,14 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; int skipLevels = (++it)->u.operand; - printf("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), skipLevels); + dataLog("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), skipLevels); it++; break; } case op_resolve_global: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] resolve_global\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] resolve_global\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); it += 3; break; } @@ -765,7 +766,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& JSValue scope = JSValue((++it)->u.jsCell.get()); ++it; int depth = (++it)->u.operand; - printf("[%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); + 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); ++it; break; } @@ -773,7 +774,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; int index = (++it)->u.operand; int skipLevels = (++it)->u.operand; - printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(exec, r0).data(), index, skipLevels); + dataLog("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(exec, r0).data(), index, skipLevels); it++; break; } @@ -781,41 +782,41 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int index = (++it)->u.operand; int skipLevels = (++it)->u.operand; int r0 = (++it)->u.operand; - printf("[%4d] put_scoped_var\t %d, %d, %s\n", location, index, skipLevels, registerName(exec, r0).data()); + dataLog("[%4d] put_scoped_var\t %d, %d, %s\n", location, index, skipLevels, registerName(exec, r0).data()); break; } case op_get_global_var: { int r0 = (++it)->u.operand; int index = (++it)->u.operand; - printf("[%4d] get_global_var\t %s, %d\n", location, registerName(exec, r0).data(), index); + dataLog("[%4d] get_global_var\t %s, %d\n", location, registerName(exec, r0).data(), index); it++; break; } case op_put_global_var: { int index = (++it)->u.operand; int r0 = (++it)->u.operand; - printf("[%4d] put_global_var\t %d, %s\n", location, index, registerName(exec, r0).data()); + dataLog("[%4d] put_global_var\t %d, %s\n", location, index, registerName(exec, r0).data()); break; } case op_resolve_base: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; int isStrict = (++it)->u.operand; - printf("[%4d] resolve_base%s\t %s, %s\n", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] resolve_base%s\t %s, %s\n", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); it++; break; } case op_ensure_property_exists: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] ensure_property_exists\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] ensure_property_exists\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); break; } case op_resolve_with_base: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); it++; break; } @@ -823,7 +824,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] resolve_with_this %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); + dataLog("[%4d] resolve_with_this %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); it++; break; } @@ -896,6 +897,14 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& printPutByIdOp(exec, location, it, "put_by_id_transition"); break; } + case op_put_by_id_transition_direct: { + printPutByIdOp(exec, location, it, "put_by_id_transition_direct"); + break; + } + case op_put_by_id_transition_normal: { + printPutByIdOp(exec, location, it, "put_by_id_transition_normal"); + break; + } case op_put_by_id_generic: { printPutByIdOp(exec, location, it, "put_by_id_generic"); break; @@ -905,25 +914,25 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int id0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%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()); + 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()); break; } case op_method_check: { - printf("[%4d] method_check\n", location); + dataLog("[%4d] method_check\n", location); break; } case op_del_by_id: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] del_by_id\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data()); + 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()); break; } case op_get_by_val: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + dataLog("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); it++; break; } @@ -931,7 +940,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%4d] get_argument_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + dataLog("[%4d] get_argument_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); ++it; break; } @@ -942,38 +951,38 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r3 = (++it)->u.operand; int r4 = (++it)->u.operand; int r5 = (++it)->u.operand; - printf("[%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()); + 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()); break; } case op_put_by_val: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%4d] put_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + dataLog("[%4d] put_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); break; } case op_del_by_val: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int r2 = (++it)->u.operand; - printf("[%4d] del_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); + dataLog("[%4d] del_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data()); break; } case op_put_by_index: { int r0 = (++it)->u.operand; unsigned n0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] put_by_index\t %s, %u, %s\n", location, registerName(exec, r0).data(), n0, registerName(exec, r1).data()); + dataLog("[%4d] put_by_index\t %s, %u, %s\n", location, registerName(exec, r0).data(), n0, registerName(exec, r1).data()); break; } case op_jmp: { int offset = (++it)->u.operand; - printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, location + offset); + dataLog("[%4d] jmp\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_loop: { int offset = (++it)->u.operand; - printf("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset); + dataLog("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_jtrue: { @@ -1004,129 +1013,129 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_jless: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_jlesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_jgreater: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jgreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jgreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_jgreatereq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jgreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jgreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_jnless: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_jnlesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_jngreater: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jngreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jngreater\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_jngreatereq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jngreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] jngreatereq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_loop_if_less: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_loop_if_lesseq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_loop_if_greater: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_greater\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] loop_if_greater\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_loop_if_greatereq: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] loop_if_greatereq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); + dataLog("[%4d] loop_if_greatereq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset); break; } case op_loop_hint: { - printf("[%4d] loop_hint\n", location); + dataLog("[%4d] loop_hint\n", location); break; } case op_switch_imm: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); + dataLog("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); break; } case op_switch_char: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); + dataLog("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); break; } case op_switch_string: { int tableIndex = (++it)->u.operand; int defaultTarget = (++it)->u.operand; int scrutineeRegister = (++it)->u.operand; - printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); + dataLog("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data()); break; } case op_new_func: { int r0 = (++it)->u.operand; int f0 = (++it)->u.operand; int shouldCheck = (++it)->u.operand; - printf("[%4d] new_func\t\t %s, f%d, %s\n", location, registerName(exec, r0).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>"); + dataLog("[%4d] new_func\t\t %s, f%d, %s\n", location, registerName(exec, r0).data(), f0, shouldCheck ? "<Checked>" : "<Unchecked>"); break; } case op_new_func_exp: { int r0 = (++it)->u.operand; int f0 = (++it)->u.operand; - printf("[%4d] new_func_exp\t %s, f%d\n", location, registerName(exec, r0).data(), f0); + dataLog("[%4d] new_func_exp\t %s, f%d\n", location, registerName(exec, r0).data(), f0); break; } case op_call: { @@ -1142,35 +1151,35 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int thisValue = (++it)->u.operand; int arguments = (++it)->u.operand; int firstFreeRegister = (++it)->u.operand; - printf("[%4d] call_varargs\t %s, %s, %s, %d\n", location, registerName(exec, callee).data(), registerName(exec, thisValue).data(), registerName(exec, arguments).data(), firstFreeRegister); + dataLog("[%4d] call_varargs\t %s, %s, %s, %d\n", location, registerName(exec, callee).data(), registerName(exec, thisValue).data(), registerName(exec, arguments).data(), firstFreeRegister); break; } case op_tear_off_activation: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] tear_off_activation\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] tear_off_activation\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); break; } case op_tear_off_arguments: { int r0 = (++it)->u.operand; - printf("[%4d] tear_off_arguments %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] tear_off_arguments %s\n", location, registerName(exec, r0).data()); break; } case op_ret: { int r0 = (++it)->u.operand; - printf("[%4d] ret\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] ret\t\t %s\n", location, registerName(exec, r0).data()); break; } case op_call_put_result: { int r0 = (++it)->u.operand; - printf("[%4d] op_call_put_result\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] op_call_put_result\t\t %s\n", location, registerName(exec, r0).data()); it++; break; } case op_ret_object_or_this: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] constructor_ret\t\t %s %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] constructor_ret\t\t %s %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); break; } case op_construct: { @@ -1181,13 +1190,13 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; int count = (++it)->u.operand; - printf("[%4d] strcat\t\t %s, %s, %d\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), count); + dataLog("[%4d] strcat\t\t %s, %s, %d\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), count); break; } case op_to_primitive: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] to_primitive\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); + dataLog("[%4d] to_primitive\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data()); break; } case op_get_pnames: { @@ -1196,7 +1205,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int r2 = it[3].u.operand; int r3 = it[4].u.operand; int offset = it[5].u.operand; - printf("[%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); + 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); it += OPCODE_LENGTH(op_get_pnames) - 1; break; } @@ -1207,78 +1216,78 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int size = it[4].u.operand; int iter = it[5].u.operand; int offset = it[6].u.operand; - printf("[%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); + 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); it += OPCODE_LENGTH(op_next_pname) - 1; break; } case op_push_scope: { int r0 = (++it)->u.operand; - printf("[%4d] push_scope\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] push_scope\t %s\n", location, registerName(exec, r0).data()); break; } case op_pop_scope: { - printf("[%4d] pop_scope\n", location); + dataLog("[%4d] pop_scope\n", location); break; } case op_push_new_scope: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] push_new_scope \t%s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data()); + 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()); break; } case op_jmp_scopes: { int scopeDelta = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, location + offset); + dataLog("[%4d] jmp_scopes\t^%d, %d(->%d)\n", location, scopeDelta, offset, location + offset); break; } case op_catch: { int r0 = (++it)->u.operand; - printf("[%4d] catch\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] catch\t\t %s\n", location, registerName(exec, r0).data()); break; } case op_throw: { int r0 = (++it)->u.operand; - printf("[%4d] throw\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] throw\t\t %s\n", location, registerName(exec, r0).data()); break; } case op_throw_reference_error: { int k0 = (++it)->u.operand; - printf("[%4d] throw_reference_error\t %s\n", location, constantName(exec, k0, getConstant(k0)).data()); + dataLog("[%4d] throw_reference_error\t %s\n", location, constantName(exec, k0, getConstant(k0)).data()); break; } case op_jsr: { int retAddrDst = (++it)->u.operand; int offset = (++it)->u.operand; - printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(exec, retAddrDst).data(), offset, location + offset); + dataLog("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(exec, retAddrDst).data(), offset, location + offset); break; } case op_sret: { int retAddrSrc = (++it)->u.operand; - printf("[%4d] sret\t\t %s\n", location, registerName(exec, retAddrSrc).data()); + dataLog("[%4d] sret\t\t %s\n", location, registerName(exec, retAddrSrc).data()); break; } case op_debug: { int debugHookID = (++it)->u.operand; int firstLine = (++it)->u.operand; int lastLine = (++it)->u.operand; - printf("[%4d] debug\t\t %s, %d, %d\n", location, debugHookName(debugHookID), firstLine, lastLine); + dataLog("[%4d] debug\t\t %s, %d, %d\n", location, debugHookName(debugHookID), firstLine, lastLine); break; } case op_profile_will_call: { int function = (++it)->u.operand; - printf("[%4d] profile_will_call %s\n", location, registerName(exec, function).data()); + dataLog("[%4d] profile_will_call %s\n", location, registerName(exec, function).data()); break; } case op_profile_did_call: { int function = (++it)->u.operand; - printf("[%4d] profile_did_call\t %s\n", location, registerName(exec, function).data()); + dataLog("[%4d] profile_did_call\t %s\n", location, registerName(exec, function).data()); break; } case op_end: { int r0 = (++it)->u.operand; - printf("[%4d] end\t\t %s\n", location, registerName(exec, r0).data()); + dataLog("[%4d] end\t\t %s\n", location, registerName(exec, r0).data()); break; } } @@ -1382,29 +1391,29 @@ void CodeBlock::dumpStatistics() totalSize += symbolTableTotalSize; totalSize += (liveCodeBlockSet.size() * sizeof(CodeBlock)); - printf("Number of live CodeBlocks: %d\n", liveCodeBlockSet.size()); - printf("Size of a single CodeBlock [sizeof(CodeBlock)]: %zu\n", sizeof(CodeBlock)); - printf("Size of all CodeBlocks: %zu\n", totalSize); - printf("Average size of a CodeBlock: %zu\n", totalSize / liveCodeBlockSet.size()); + dataLog("Number of live CodeBlocks: %d\n", liveCodeBlockSet.size()); + dataLog("Size of a single CodeBlock [sizeof(CodeBlock)]: %zu\n", sizeof(CodeBlock)); + dataLog("Size of all CodeBlocks: %zu\n", totalSize); + dataLog("Average size of a CodeBlock: %zu\n", totalSize / liveCodeBlockSet.size()); - printf("Number of FunctionCode CodeBlocks: %zu (%.3f%%)\n", isFunctionCode, static_cast<double>(isFunctionCode) * 100.0 / liveCodeBlockSet.size()); - printf("Number of GlobalCode CodeBlocks: %zu (%.3f%%)\n", isGlobalCode, static_cast<double>(isGlobalCode) * 100.0 / liveCodeBlockSet.size()); - printf("Number of EvalCode CodeBlocks: %zu (%.3f%%)\n", isEvalCode, static_cast<double>(isEvalCode) * 100.0 / liveCodeBlockSet.size()); + dataLog("Number of FunctionCode CodeBlocks: %zu (%.3f%%)\n", isFunctionCode, static_cast<double>(isFunctionCode) * 100.0 / liveCodeBlockSet.size()); + dataLog("Number of GlobalCode CodeBlocks: %zu (%.3f%%)\n", isGlobalCode, static_cast<double>(isGlobalCode) * 100.0 / liveCodeBlockSet.size()); + dataLog("Number of EvalCode CodeBlocks: %zu (%.3f%%)\n", isEvalCode, static_cast<double>(isEvalCode) * 100.0 / liveCodeBlockSet.size()); - printf("Number of CodeBlocks with rare data: %zu (%.3f%%)\n", hasRareData, static_cast<double>(hasRareData) * 100.0 / liveCodeBlockSet.size()); + dataLog("Number of CodeBlocks with rare data: %zu (%.3f%%)\n", hasRareData, static_cast<double>(hasRareData) * 100.0 / liveCodeBlockSet.size()); - #define PRINT_STATS(name) printf("Number of CodeBlocks with " #name ": %zu\n", name##IsNotEmpty); printf("Size of all " #name ": %zu\n", name##TotalSize); + #define PRINT_STATS(name) dataLog("Number of CodeBlocks with " #name ": %zu\n", name##IsNotEmpty); dataLog("Size of all " #name ": %zu\n", name##TotalSize); FOR_EACH_MEMBER_VECTOR(PRINT_STATS) FOR_EACH_MEMBER_VECTOR_RARE_DATA(PRINT_STATS) #undef PRINT_STATS - printf("Number of CodeBlocks with evalCodeCache: %zu\n", evalCodeCacheIsNotEmpty); - printf("Number of CodeBlocks with symbolTable: %zu\n", symbolTableIsNotEmpty); + dataLog("Number of CodeBlocks with evalCodeCache: %zu\n", evalCodeCacheIsNotEmpty); + dataLog("Number of CodeBlocks with symbolTable: %zu\n", symbolTableIsNotEmpty); - printf("Size of all symbolTables: %zu\n", symbolTableTotalSize); + dataLog("Size of all symbolTables: %zu\n", symbolTableTotalSize); #else - printf("Dumping CodeBlock statistics is not enabled.\n"); + dataLog("Dumping CodeBlock statistics is not enabled.\n"); #endif } @@ -1453,6 +1462,7 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab) { setNumParameters(other.numParameters()); optimizeAfterWarmUp(); + jitAfterWarmUp(); if (other.m_rareData) { createRareDataIfNecessary(); @@ -1501,6 +1511,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlo ASSERT(m_source); optimizeAfterWarmUp(); + jitAfterWarmUp(); #if DUMP_CODE_BLOCK_STATISTICS liveCodeBlockSet.add(this); @@ -1518,7 +1529,11 @@ CodeBlock::~CodeBlock() #if ENABLE(VERBOSE_VALUE_PROFILE) dumpValueProfiles(); #endif - + +#if ENABLE(LLINT) + while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end()) + m_incomingLLIntCalls.begin()->remove(); +#endif // ENABLE(LLINT) #if ENABLE(JIT) // We may be destroyed before any CodeBlocks that refer to us are destroyed. // Consider that two CodeBlocks become unreachable at the same time. There @@ -1730,13 +1745,74 @@ void CodeBlock::finalizeUnconditionally() #else static const bool verboseUnlinking = false; #endif -#endif +#endif // ENABLE(JIT) +#if ENABLE(LLINT) + Interpreter* interpreter = m_globalData->interpreter; + // interpreter->classicEnabled() returns true if the old C++ interpreter is enabled. If that's enabled + // then we're not using LLInt. + if (!interpreter->classicEnabled()) { + for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) { + Instruction* curInstruction = &instructions()[m_propertyAccessInstructions[i]]; + switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) { + case op_get_by_id: + case op_put_by_id: + if (!curInstruction[4].u.structure || Heap::isMarked(curInstruction[4].u.structure.get())) + break; + if (verboseUnlinking) + dataLog("Clearing LLInt property access with structure %p.\n", curInstruction[4].u.structure.get()); + curInstruction[4].u.structure.clear(); + curInstruction[5].u.operand = 0; + break; + case op_put_by_id_transition_direct: + case op_put_by_id_transition_normal: + if (Heap::isMarked(curInstruction[4].u.structure.get()) + && Heap::isMarked(curInstruction[6].u.structure.get()) + && Heap::isMarked(curInstruction[7].u.structureChain.get())) + break; + if (verboseUnlinking) { + dataLog("Clearing LLInt put transition with structures %p -> %p, chain %p.\n", + curInstruction[4].u.structure.get(), + curInstruction[6].u.structure.get(), + curInstruction[7].u.structureChain.get()); + } + curInstruction[4].u.structure.clear(); + curInstruction[6].u.structure.clear(); + curInstruction[7].u.structureChain.clear(); + curInstruction[0].u.opcode = interpreter->getOpcode(op_put_by_id); + break; + default: + ASSERT_NOT_REACHED(); + } + } + for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) { + Instruction* curInstruction = &instructions()[m_globalResolveInstructions[i]]; + ASSERT(interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global + || interpreter->getOpcodeID(curInstruction[0].u.opcode) == op_resolve_global_dynamic); + if (!curInstruction[3].u.structure || Heap::isMarked(curInstruction[3].u.structure.get())) + continue; + if (verboseUnlinking) + dataLog("Clearing LLInt global resolve cache with structure %p.\n", curInstruction[3].u.structure.get()); + curInstruction[3].u.structure.clear(); + curInstruction[4].u.operand = 0; + } + for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) { + if (m_llintCallLinkInfos[i].isLinked() && !Heap::isMarked(m_llintCallLinkInfos[i].callee.get())) { + if (verboseUnlinking) + dataLog("Clearing LLInt call from %p.\n", this); + m_llintCallLinkInfos[i].unlink(); + } + if (!!m_llintCallLinkInfos[i].lastSeenCallee && !Heap::isMarked(m_llintCallLinkInfos[i].lastSeenCallee.get())) + m_llintCallLinkInfos[i].lastSeenCallee.clear(); + } + } +#endif // ENABLE(LLINT) + #if ENABLE(DFG_JIT) // Check if we're not live. If we are, then jettison. if (!(shouldImmediatelyAssumeLivenessDuringScan() || m_dfgData->livenessHasBeenProved)) { if (verboseUnlinking) - printf("Code block %p has dead weak references, jettisoning during GC.\n", this); + dataLog("Code block %p has dead weak references, jettisoning during GC.\n", this); // Make sure that the baseline JIT knows that it should re-warm-up before // optimizing. @@ -1754,7 +1830,7 @@ void CodeBlock::finalizeUnconditionally() for (unsigned i = 0; i < numberOfCallLinkInfos(); ++i) { if (callLinkInfo(i).isLinked() && !Heap::isMarked(callLinkInfo(i).callee.get())) { if (verboseUnlinking) - printf("Clearing call from %p.\n", this); + dataLog("Clearing call from %p to %p.\n", this, callLinkInfo(i).callee.get()); callLinkInfo(i).unlink(*m_globalData, repatchBuffer); } if (!!callLinkInfo(i).lastSeenCallee @@ -1764,7 +1840,7 @@ void CodeBlock::finalizeUnconditionally() for (size_t size = m_globalResolveInfos.size(), i = 0; i < size; ++i) { if (m_globalResolveInfos[i].structure && !Heap::isMarked(m_globalResolveInfos[i].structure.get())) { if (verboseUnlinking) - printf("Clearing resolve info in %p.\n", this); + dataLog("Clearing resolve info in %p.\n", this); m_globalResolveInfos[i].structure.clear(); } } @@ -1778,7 +1854,7 @@ void CodeBlock::finalizeUnconditionally() continue; if (verboseUnlinking) - printf("Clearing structure cache (kind %d) in %p.\n", stubInfo.accessType, this); + dataLog("Clearing structure cache (kind %d) in %p.\n", stubInfo.accessType, this); if (isGetByIdAccess(accessType)) { if (getJITCode().jitType() == JITCode::DFGJIT) @@ -1808,7 +1884,7 @@ void CodeBlock::finalizeUnconditionally() || !Heap::isMarked(m_methodCallLinkInfos[i].cachedFunction.get()) || !Heap::isMarked(m_methodCallLinkInfos[i].cachedPrototype.get())) { if (verboseUnlinking) - printf("Clearing method call in %p.\n", this); + dataLog("Clearing method call in %p.\n", this); m_methodCallLinkInfos[i].reset(repatchBuffer, getJITType()); StructureStubInfo& stubInfo = getStubInfo(m_methodCallLinkInfos[i].bytecodeIndex); @@ -1851,11 +1927,13 @@ void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor) visitor.append(&m_functionExprs[i]); for (size_t i = 0; i < m_functionDecls.size(); ++i) visitor.append(&m_functionDecls[i]); -#if ENABLE(INTERPRETER) - for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) - visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]); - for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) - visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]); +#if ENABLE(CLASSIC_INTERPRETER) + if (m_globalData->interpreter->classicEnabled()) { + for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) + visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]); + for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i) + visitStructures(visitor, &instructions()[m_globalResolveInstructions[i]]); + } #endif #if ENABLE(DFG_JIT) @@ -1863,10 +1941,13 @@ void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor) // Make sure that executables that we have inlined don't die. // FIXME: If they would have otherwise died, we should probably trigger recompilation. for (size_t i = 0; i < inlineCallFrames().size(); ++i) { - visitor.append(&inlineCallFrames()[i].executable); - visitor.append(&inlineCallFrames()[i].callee); + InlineCallFrame& inlineCallFrame = inlineCallFrames()[i]; + visitor.append(&inlineCallFrame.executable); + visitor.append(&inlineCallFrame.callee); } } + + m_lazyOperandValueProfiles.computeUpdatedPredictions(); #endif #if ENABLE(VALUE_PROFILER) @@ -1976,7 +2057,7 @@ void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& d return; } -#if ENABLE(INTERPRETER) +#if ENABLE(CLASSIC_INTERPRETER) bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset) { if (m_globalResolveInstructions.isEmpty()) @@ -2023,7 +2104,7 @@ void CodeBlock::shrinkToFit() { instructions().shrinkToFit(); -#if ENABLE(INTERPRETER) +#if ENABLE(CLASSIC_INTERPRETER) m_propertyAccessInstructions.shrinkToFit(); m_globalResolveInstructions.shrinkToFit(); #endif @@ -2068,12 +2149,18 @@ unsigned CodeBlock::addOrFindConstant(JSValue v) } return addConstant(v); } - + #if ENABLE(JIT) void CodeBlock::unlinkCalls() { if (!!m_alternative) m_alternative->unlinkCalls(); +#if ENABLE(LLINT) + for (size_t i = 0; i < m_llintCallLinkInfos.size(); ++i) { + if (m_llintCallLinkInfos[i].isLinked()) + m_llintCallLinkInfos[i].unlink(); + } +#endif if (!(m_callLinkInfos.size() || m_methodCallLinkInfos.size())) return; if (!m_globalData->canUseJIT()) @@ -2088,10 +2175,62 @@ void CodeBlock::unlinkCalls() void CodeBlock::unlinkIncomingCalls() { +#if ENABLE(LLINT) + while (m_incomingLLIntCalls.begin() != m_incomingLLIntCalls.end()) + m_incomingLLIntCalls.begin()->unlink(); +#endif + if (m_incomingCalls.isEmpty()) + return; RepatchBuffer repatchBuffer(this); while (m_incomingCalls.begin() != m_incomingCalls.end()) m_incomingCalls.begin()->unlink(*m_globalData, repatchBuffer); } + +unsigned CodeBlock::bytecodeOffset(ExecState* exec, ReturnAddressPtr returnAddress) +{ +#if ENABLE(LLINT) + if (returnAddress.value() >= bitwise_cast<void*>(&llint_begin) + && returnAddress.value() <= bitwise_cast<void*>(&llint_end)) { + ASSERT(exec->codeBlock()); + ASSERT(exec->codeBlock() == this); + ASSERT(JITCode::isBaselineCode(getJITType())); + Instruction* instruction = exec->currentVPC(); + ASSERT(instruction); + + // The LLInt stores the PC after the call instruction rather than the PC of + // the call instruction. This requires some correcting. We rely on the fact + // that the preceding instruction must be one of the call instructions, so + // either it's a call_varargs or it's a call, construct, or eval. + ASSERT(OPCODE_LENGTH(op_call_varargs) <= OPCODE_LENGTH(op_call)); + ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_construct)); + ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_eval)); + if (instruction[-OPCODE_LENGTH(op_call_varargs)].u.pointer == bitwise_cast<void*>(llint_op_call_varargs)) { + // We know that the preceding instruction must be op_call_varargs because there is no way that + // the pointer to the call_varargs could be an operand to the call. + instruction -= OPCODE_LENGTH(op_call_varargs); + ASSERT(instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast<void*>(llint_op_call) + && instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast<void*>(llint_op_construct) + && instruction[-OPCODE_LENGTH(op_call)].u.pointer != bitwise_cast<void*>(llint_op_call_eval)); + } else { + // Must be that the last instruction was some op_call. + ASSERT(instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast<void*>(llint_op_call) + || instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast<void*>(llint_op_construct) + || instruction[-OPCODE_LENGTH(op_call)].u.pointer == bitwise_cast<void*>(llint_op_call_eval)); + instruction -= OPCODE_LENGTH(op_call); + } + + return bytecodeOffset(instruction); + } +#else + UNUSED_PARAM(exec); +#endif + if (!m_rareData) + return 1; + Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector; + if (!callIndices.size()) + return 1; + return binarySearch<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset; +} #endif void CodeBlock::clearEvalCache() @@ -2187,31 +2326,52 @@ bool FunctionCodeBlock::canCompileWithDFGInternal() void ProgramCodeBlock::jettison() { - ASSERT(getJITType() != JITCode::BaselineJIT); + ASSERT(JITCode::isOptimizingJIT(getJITType())); ASSERT(this == replacement()); static_cast<ProgramExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData()); } void EvalCodeBlock::jettison() { - ASSERT(getJITType() != JITCode::BaselineJIT); + ASSERT(JITCode::isOptimizingJIT(getJITType())); ASSERT(this == replacement()); static_cast<EvalExecutable*>(ownerExecutable())->jettisonOptimizedCode(*globalData()); } void FunctionCodeBlock::jettison() { - ASSERT(getJITType() != JITCode::BaselineJIT); + ASSERT(JITCode::isOptimizingJIT(getJITType())); ASSERT(this == replacement()); static_cast<FunctionExecutable*>(ownerExecutable())->jettisonOptimizedCodeFor(*globalData(), m_isConstructor ? CodeForConstruct : CodeForCall); } + +void ProgramCodeBlock::jitCompileImpl(JSGlobalData& globalData) +{ + ASSERT(getJITType() == JITCode::InterpreterThunk); + ASSERT(this == replacement()); + return static_cast<ProgramExecutable*>(ownerExecutable())->jitCompile(globalData); +} + +void EvalCodeBlock::jitCompileImpl(JSGlobalData& globalData) +{ + ASSERT(getJITType() == JITCode::InterpreterThunk); + ASSERT(this == replacement()); + return static_cast<EvalExecutable*>(ownerExecutable())->jitCompile(globalData); +} + +void FunctionCodeBlock::jitCompileImpl(JSGlobalData& globalData) +{ + ASSERT(getJITType() == JITCode::InterpreterThunk); + ASSERT(this == replacement()); + return static_cast<FunctionExecutable*>(ownerExecutable())->jitCompileFor(globalData, m_isConstructor ? CodeForConstruct : CodeForCall); +} #endif #if ENABLE(VALUE_PROFILER) bool CodeBlock::shouldOptimizeNow() { #if ENABLE(JIT_VERBOSE_OSR) - printf("Considering optimizing %p...\n", this); + dataLog("Considering optimizing %p...\n", this); #endif #if ENABLE(VERBOSE_VALUE_PROFILE) @@ -2239,7 +2399,7 @@ bool CodeBlock::shouldOptimizeNow() } #if ENABLE(JIT_VERBOSE_OSR) - printf("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles()); + dataLog("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles()); #endif if ((!numberOfValueProfiles() || (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles() >= Options::desiredProfileLivenessRate) @@ -2270,7 +2430,7 @@ void CodeBlock::tallyFrequentExitSites() continue; #if DFG_ENABLE(DEBUG_VERBOSE) - fprintf(stderr, "OSR exit #%u (bc#%u, @%u, %s) for code block %p occurred frequently; counting as frequent exit site.\n", i, exit.m_codeOrigin.bytecodeIndex, exit.m_nodeIndex, DFG::exitKindToString(exit.m_kind), this); + dataLog("OSR exit #%u (bc#%u, @%u, %s) for code block %p occurred frequently; counting as frequent exit site.\n", i, exit.m_codeOrigin.bytecodeIndex, exit.m_nodeIndex, DFG::exitKindToString(exit.m_kind), this); #endif } } @@ -2279,30 +2439,30 @@ void CodeBlock::tallyFrequentExitSites() #if ENABLE(VERBOSE_VALUE_PROFILE) void CodeBlock::dumpValueProfiles() { - fprintf(stderr, "ValueProfile for %p:\n", this); + dataLog("ValueProfile for %p:\n", this); for (unsigned i = 0; i < totalNumberOfValueProfiles(); ++i) { ValueProfile* profile = getFromAllValueProfiles(i); if (profile->m_bytecodeOffset < 0) { ASSERT(profile->m_bytecodeOffset == -1); - fprintf(stderr, " arg = %u: ", i); + dataLog(" arg = %u: ", i); } else - fprintf(stderr, " bc = %d: ", profile->m_bytecodeOffset); + dataLog(" bc = %d: ", profile->m_bytecodeOffset); if (!profile->numberOfSamples() && profile->m_prediction == PredictNone) { - fprintf(stderr, "<empty>\n"); + dataLog("<empty>\n"); continue; } - profile->dump(stderr); - fprintf(stderr, "\n"); + profile->dump(WTF::dataFile()); + dataLog("\n"); } - fprintf(stderr, "RareCaseProfile for %p:\n", this); + dataLog("RareCaseProfile for %p:\n", this); for (unsigned i = 0; i < numberOfRareCaseProfiles(); ++i) { RareCaseProfile* profile = rareCaseProfile(i); - fprintf(stderr, " bc = %d: %u\n", profile->m_bytecodeOffset, profile->m_counter); + dataLog(" bc = %d: %u\n", profile->m_bytecodeOffset, profile->m_counter); } - fprintf(stderr, "SpecialFastCaseProfile for %p:\n", this); + dataLog("SpecialFastCaseProfile for %p:\n", this); for (unsigned i = 0; i < numberOfSpecialFastCaseProfiles(); ++i) { RareCaseProfile* profile = specialFastCaseProfile(i); - fprintf(stderr, " bc = %d: %u\n", profile->m_bytecodeOffset, profile->m_counter); + dataLog(" bc = %d: %u\n", profile->m_bytecodeOffset, profile->m_counter); } } #endif |