X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..f9bf01c6616d5ddcf65b13b33cedf9e387ff7a63:/bytecode/CodeBlock.cpp diff --git a/bytecode/CodeBlock.cpp b/bytecode/CodeBlock.cpp index be060d0..fd56ece 100644 --- a/bytecode/CodeBlock.cpp +++ b/bytecode/CodeBlock.cpp @@ -33,6 +33,8 @@ #include "JIT.h" #include "JSValue.h" #include "Interpreter.h" +#include "JSFunction.h" +#include "JSStaticScopeObject.h" #include "Debugger.h" #include "BytecodeGenerator.h" #include @@ -49,57 +51,61 @@ static UString escapeQuotes(const UString& str) UString result = str; int pos = 0; while ((pos = result.find('\"', pos)) >= 0) { - result = result.substr(0, pos) + "\"\\\"\"" + result.substr(pos + 1); + result = makeString(result.substr(0, pos), "\"\\\"\"", result.substr(pos + 1)); pos += 4; } return result; } -static UString valueToSourceString(ExecState* exec, JSValuePtr val) +static UString valueToSourceString(ExecState* exec, JSValue val) { - if (val.isString()) { - UString result("\""); - result += escapeQuotes(val.toString(exec)) + "\""; - return result; - } + if (!val) + return "0"; + + if (val.isString()) + return makeString("\"", escapeQuotes(val.toString(exec)), "\""); return val.toString(exec); } -static CString registerName(int r) +static CString constantName(ExecState* exec, int k, JSValue value) { - if (r == missingThisObjectMarker()) - return ""; - - return (UString("r") + UString::from(r)).UTF8String(); + return makeString(valueToSourceString(exec, value), "(@k", UString::from(k - FirstConstantRegisterIndex), ")").UTF8String(); } -static CString constantName(ExecState* exec, int k, JSValuePtr value) +static CString idName(int id0, const Identifier& ident) { - return (valueToSourceString(exec, value) + "(@k" + UString::from(k) + ")").UTF8String(); + return makeString(ident.ustring(), "(@id", UString::from(id0), ")").UTF8String(); } -static CString idName(int id0, const Identifier& ident) +CString CodeBlock::registerName(ExecState* exec, int r) const { - return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String(); + if (r == missingThisObjectMarker()) + return ""; + + if (isConstantRegisterIndex(r)) + return constantName(exec, r, getConstant(r)); + + return makeString("r", UString::from(r)).UTF8String(); } static UString regexpToSourceString(RegExp* regExp) { - UString pattern = UString("/") + regExp->pattern() + "/"; + char postfix[5] = { '/', 0, 0, 0, 0 }; + int index = 1; if (regExp->global()) - pattern += "g"; + postfix[index++] = 'g'; if (regExp->ignoreCase()) - pattern += "i"; + postfix[index++] = 'i'; if (regExp->multiline()) - pattern += "m"; + postfix[index] = 'm'; - return pattern; + return makeString("/", regExp->pattern(), postfix); } static CString regexpName(int re, RegExp* regexp) { - return (regexpToSourceString(regexp) + "(@re" + UString::from(re) + ")").UTF8String(); + return makeString(regexpToSourceString(regexp), "(@re", UString::from(re), ")").UTF8String(); } static UString pointerToSourceString(void* p) @@ -130,49 +136,44 @@ NEVER_INLINE static const char* debugHookName(int debugHookID) return ""; } -static int locationForOffset(const Vector::const_iterator& begin, Vector::const_iterator& it, int offset) -{ - return it - begin + offset; -} - -static void printUnaryOp(int location, Vector::const_iterator& it, const char* op) +void CodeBlock::printUnaryOp(ExecState* exec, int location, Vector::const_iterator& it, const char* op) const { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(r0).c_str(), registerName(r1).c_str()); + printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(exec, r0).c_str(), registerName(exec, r1).c_str()); } -static void printBinaryOp(int location, Vector::const_iterator& it, const char* op) +void CodeBlock::printBinaryOp(ExecState* exec, int location, Vector::const_iterator& it, const char* op) const { 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str()); + printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str()); } -static void printConditionalJump(const Vector::const_iterator& begin, Vector::const_iterator& it, int location, const char* op) +void CodeBlock::printConditionalJump(ExecState* exec, const Vector::const_iterator&, Vector::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(r0).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(exec, r0).c_str(), offset, location + offset); } -static void printGetByIdOp(int location, Vector::const_iterator& it, const Vector& m_identifiers, const char* op) +void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vector::const_iterator& it, const char* op) const { 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(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str()); + printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), idName(id0, m_identifiers[id0]).c_str()); it += 4; } -static void printPutByIdOp(int location, Vector::const_iterator& it, const Vector& m_identifiers, const char* op) +void CodeBlock::printPutByIdOp(ExecState* exec, int location, Vector::const_iterator& it, const char* op) const { 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(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str()); + printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str()); it += 4; } @@ -227,44 +228,44 @@ static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigne static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset) { - switch (stubInfo.opcodeID) { - case op_get_by_id_self: + switch (stubInfo.accessType) { + case access_get_by_id_self: printf(" [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).UTF8String().c_str()); return; - case op_get_by_id_proto: + case access_get_by_id_proto: printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).UTF8String().c_str()); return; - case op_get_by_id_chain: + case access_get_by_id_chain: printf(" [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdChain.chain).UTF8String().c_str()); return; - case op_get_by_id_self_list: + 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).UTF8String().c_str(), stubInfo.u.getByIdSelfList.listSize); return; - case op_get_by_id_proto_list: + 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).UTF8String().c_str(), stubInfo.u.getByIdProtoList.listSize); return; - case op_put_by_id_transition: + case access_put_by_id_transition: printf(" [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).UTF8String().c_str()); return; - case op_put_by_id_replace: + case access_put_by_id_replace: printf(" [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).UTF8String().c_str()); return; - case op_get_by_id: + case access_get_by_id: printf(" [%4d] %s\n", instructionOffset, "get_by_id"); return; - case op_put_by_id: + case access_put_by_id: printf(" [%4d] %s\n", instructionOffset, "put_by_id"); return; - case op_get_by_id_generic: + case access_get_by_id_generic: printf(" [%4d] %s\n", instructionOffset, "op_get_by_id_generic"); return; - case op_put_by_id_generic: + case access_put_by_id_generic: printf(" [%4d] %s\n", instructionOffset, "op_put_by_id_generic"); return; - case op_get_array_length: + case access_get_array_length: printf(" [%4d] %s\n", instructionOffset, "op_get_array_length"); return; - case op_get_string_length: + case access_get_string_length: printf(" [%4d] %s\n", instructionOffset, "op_get_string_length"); return; default: @@ -357,21 +358,12 @@ void CodeBlock::dump(ExecState* exec) const unsigned registerIndex = m_numVars; size_t i = 0; do { - printf(" r%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue(exec)).ascii()); + printf(" k%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue()).ascii()); ++i; ++registerIndex; } while (i < m_constantRegisters.size()); } - if (m_rareData && !m_rareData->m_unexpectedConstants.isEmpty()) { - printf("\nUnexpected Constants:\n"); - size_t i = 0; - do { - printf(" k%u = %s\n", static_cast(i), valueToSourceString(exec, m_rareData->m_unexpectedConstants[i]).ascii()); - ++i; - } while (i < m_rareData->m_unexpectedConstants.size()); - } - if (m_rareData && !m_rareData->m_regexps.isEmpty()) { printf("\nm_regexps:\n"); size_t i = 0; @@ -490,162 +482,161 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& } case op_enter_with_activation: { int r0 = (++it)->u.operand; - printf("[%4d] enter_with_activation %s\n", location, registerName(r0).c_str()); + printf("[%4d] enter_with_activation %s\n", location, registerName(exec, r0).c_str()); break; } case op_create_arguments: { printf("[%4d] create_arguments\n", location); break; } - case op_convert_this: { - int r0 = (++it)->u.operand; - printf("[%4d] convert_this %s\n", location, registerName(r0).c_str()); + case op_init_arguments: { + printf("[%4d] init_arguments\n", location); break; } - case op_unexpected_load: { + case op_convert_this: { int r0 = (++it)->u.operand; - int k0 = (++it)->u.operand; - printf("[%4d] unexpected_load\t %s, %s\n", location, registerName(r0).c_str(), constantName(exec, k0, unexpectedConstant(k0)).c_str()); + printf("[%4d] convert_this %s\n", location, registerName(exec, r0).c_str()); break; } case op_new_object: { int r0 = (++it)->u.operand; - printf("[%4d] new_object\t %s\n", location, registerName(r0).c_str()); + printf("[%4d] new_object\t %s\n", location, registerName(exec, r0).c_str()); 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(dst).c_str(), registerName(argv).c_str(), argc); + printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, argv).c_str(), argc); break; } case op_new_regexp: { int r0 = (++it)->u.operand; int re0 = (++it)->u.operand; - printf("[%4d] new_regexp\t %s, %s\n", location, registerName(r0).c_str(), regexpName(re0, regexp(re0)).c_str()); + printf("[%4d] new_regexp\t %s, %s\n", location, registerName(exec, r0).c_str(), regexpName(re0, regexp(re0)).c_str()); break; } case op_mov: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] mov\t\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str()); + printf("[%4d] mov\t\t %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str()); break; } case op_not: { - printUnaryOp(location, it, "not"); + printUnaryOp(exec, location, it, "not"); break; } case op_eq: { - printBinaryOp(location, it, "eq"); + printBinaryOp(exec, location, it, "eq"); break; } case op_eq_null: { - printUnaryOp(location, it, "eq_null"); + printUnaryOp(exec, location, it, "eq_null"); break; } case op_neq: { - printBinaryOp(location, it, "neq"); + printBinaryOp(exec, location, it, "neq"); break; } case op_neq_null: { - printUnaryOp(location, it, "neq_null"); + printUnaryOp(exec, location, it, "neq_null"); break; } case op_stricteq: { - printBinaryOp(location, it, "stricteq"); + printBinaryOp(exec, location, it, "stricteq"); break; } case op_nstricteq: { - printBinaryOp(location, it, "nstricteq"); + printBinaryOp(exec, location, it, "nstricteq"); break; } case op_less: { - printBinaryOp(location, it, "less"); + printBinaryOp(exec, location, it, "less"); break; } case op_lesseq: { - printBinaryOp(location, it, "lesseq"); + printBinaryOp(exec, location, it, "lesseq"); break; } case op_pre_inc: { int r0 = (++it)->u.operand; - printf("[%4d] pre_inc\t\t %s\n", location, registerName(r0).c_str()); + printf("[%4d] pre_inc\t\t %s\n", location, registerName(exec, r0).c_str()); break; } case op_pre_dec: { int r0 = (++it)->u.operand; - printf("[%4d] pre_dec\t\t %s\n", location, registerName(r0).c_str()); + printf("[%4d] pre_dec\t\t %s\n", location, registerName(exec, r0).c_str()); break; } case op_post_inc: { - printUnaryOp(location, it, "post_inc"); + printUnaryOp(exec, location, it, "post_inc"); break; } case op_post_dec: { - printUnaryOp(location, it, "post_dec"); + printUnaryOp(exec, location, it, "post_dec"); break; } case op_to_jsnumber: { - printUnaryOp(location, it, "to_jsnumber"); + printUnaryOp(exec, location, it, "to_jsnumber"); break; } case op_negate: { - printUnaryOp(location, it, "negate"); + printUnaryOp(exec, location, it, "negate"); break; } case op_add: { - printBinaryOp(location, it, "add"); + printBinaryOp(exec, location, it, "add"); ++it; break; } case op_mul: { - printBinaryOp(location, it, "mul"); + printBinaryOp(exec, location, it, "mul"); ++it; break; } case op_div: { - printBinaryOp(location, it, "div"); + printBinaryOp(exec, location, it, "div"); + ++it; break; } case op_mod: { - printBinaryOp(location, it, "mod"); + printBinaryOp(exec, location, it, "mod"); break; } case op_sub: { - printBinaryOp(location, it, "sub"); + printBinaryOp(exec, location, it, "sub"); ++it; break; } case op_lshift: { - printBinaryOp(location, it, "lshift"); + printBinaryOp(exec, location, it, "lshift"); break; } case op_rshift: { - printBinaryOp(location, it, "rshift"); + printBinaryOp(exec, location, it, "rshift"); break; } case op_urshift: { - printBinaryOp(location, it, "urshift"); + printBinaryOp(exec, location, it, "urshift"); break; } case op_bitand: { - printBinaryOp(location, it, "bitand"); + printBinaryOp(exec, location, it, "bitand"); ++it; break; } case op_bitxor: { - printBinaryOp(location, it, "bitxor"); + printBinaryOp(exec, location, it, "bitxor"); ++it; break; } case op_bitor: { - printBinaryOp(location, it, "bitor"); + printBinaryOp(exec, location, it, "bitor"); ++it; break; } case op_bitnot: { - printUnaryOp(location, it, "bitnot"); + printUnaryOp(exec, location, it, "bitnot"); break; } case op_instanceof: { @@ -653,59 +644,59 @@ void CodeBlock::dump(ExecState* exec, const Vector::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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str(), registerName(r3).c_str()); + printf("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str(), registerName(exec, r3).c_str()); break; } case op_typeof: { - printUnaryOp(location, it, "typeof"); + printUnaryOp(exec, location, it, "typeof"); break; } case op_is_undefined: { - printUnaryOp(location, it, "is_undefined"); + printUnaryOp(exec, location, it, "is_undefined"); break; } case op_is_boolean: { - printUnaryOp(location, it, "is_boolean"); + printUnaryOp(exec, location, it, "is_boolean"); break; } case op_is_number: { - printUnaryOp(location, it, "is_number"); + printUnaryOp(exec, location, it, "is_number"); break; } case op_is_string: { - printUnaryOp(location, it, "is_string"); + printUnaryOp(exec, location, it, "is_string"); break; } case op_is_object: { - printUnaryOp(location, it, "is_object"); + printUnaryOp(exec, location, it, "is_object"); break; } case op_is_function: { - printUnaryOp(location, it, "is_function"); + printUnaryOp(exec, location, it, "is_function"); break; } case op_in: { - printBinaryOp(location, it, "in"); + printBinaryOp(exec, location, it, "in"); break; } case op_resolve: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] resolve\t\t %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str()); + printf("[%4d] resolve\t\t %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str()); break; } case op_resolve_skip: { 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(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), skipLevels); + printf("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), skipLevels); break; } case op_resolve_global: { int r0 = (++it)->u.operand; - JSValuePtr scope = JSValuePtr((++it)->u.jsCell); + JSValue scope = JSValue((++it)->u.jsCell); int id0 = (++it)->u.operand; - printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).c_str()); + printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).c_str()); it += 2; break; } @@ -713,233 +704,265 @@ void CodeBlock::dump(ExecState* exec, const Vector::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(r0).c_str(), index, skipLevels); + printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(exec, r0).c_str(), index, skipLevels); break; } case op_put_scoped_var: { 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(r0).c_str()); + printf("[%4d] put_scoped_var\t %d, %d, %s\n", location, index, skipLevels, registerName(exec, r0).c_str()); break; } case op_get_global_var: { int r0 = (++it)->u.operand; - JSValuePtr scope = JSValuePtr((++it)->u.jsCell); + JSValue scope = JSValue((++it)->u.jsCell); int index = (++it)->u.operand; - printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), index); + printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(exec, r0).c_str(), valueToSourceString(exec, scope).ascii(), index); break; } case op_put_global_var: { - JSValuePtr scope = JSValuePtr((++it)->u.jsCell); + JSValue scope = JSValue((++it)->u.jsCell); int index = (++it)->u.operand; int r0 = (++it)->u.operand; - printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(r0).c_str()); + printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(exec, r0).c_str()); break; } case op_resolve_base: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] resolve_base\t %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str()); + printf("[%4d] resolve_base\t %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str()); 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(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str()); - break; - } - case op_resolve_func: { - int r0 = (++it)->u.operand; - int r1 = (++it)->u.operand; - int id0 = (++it)->u.operand; - printf("[%4d] resolve_func\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str()); + printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), idName(id0, m_identifiers[id0]).c_str()); break; } case op_get_by_id: { - printGetByIdOp(location, it, m_identifiers, "get_by_id"); + printGetByIdOp(exec, location, it, "get_by_id"); break; } case op_get_by_id_self: { - printGetByIdOp(location, it, m_identifiers, "get_by_id_self"); + printGetByIdOp(exec, location, it, "get_by_id_self"); break; } case op_get_by_id_self_list: { - printGetByIdOp(location, it, m_identifiers, "get_by_id_self_list"); + printGetByIdOp(exec, location, it, "get_by_id_self_list"); break; } case op_get_by_id_proto: { - printGetByIdOp(location, it, m_identifiers, "get_by_id_proto"); + printGetByIdOp(exec, location, it, "get_by_id_proto"); break; } case op_get_by_id_proto_list: { - printGetByIdOp(location, it, m_identifiers, "op_get_by_id_proto_list"); + printGetByIdOp(exec, location, it, "op_get_by_id_proto_list"); break; } case op_get_by_id_chain: { - printGetByIdOp(location, it, m_identifiers, "get_by_id_chain"); + printGetByIdOp(exec, location, it, "get_by_id_chain"); break; } case op_get_by_id_generic: { - printGetByIdOp(location, it, m_identifiers, "get_by_id_generic"); + printGetByIdOp(exec, location, it, "get_by_id_generic"); break; } case op_get_array_length: { - printGetByIdOp(location, it, m_identifiers, "get_array_length"); + printGetByIdOp(exec, location, it, "get_array_length"); break; } case op_get_string_length: { - printGetByIdOp(location, it, m_identifiers, "get_string_length"); + printGetByIdOp(exec, location, it, "get_string_length"); break; } case op_put_by_id: { - printPutByIdOp(location, it, m_identifiers, "put_by_id"); + printPutByIdOp(exec, location, it, "put_by_id"); break; } case op_put_by_id_replace: { - printPutByIdOp(location, it, m_identifiers, "put_by_id_replace"); + printPutByIdOp(exec, location, it, "put_by_id_replace"); break; } case op_put_by_id_transition: { - printPutByIdOp(location, it, m_identifiers, "put_by_id_transition"); + printPutByIdOp(exec, location, it, "put_by_id_transition"); break; } case op_put_by_id_generic: { - printPutByIdOp(location, it, m_identifiers, "put_by_id_generic"); + printPutByIdOp(exec, location, it, "put_by_id_generic"); break; } case op_put_getter: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] put_getter\t %s, %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str()); + printf("[%4d] put_getter\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str()); break; } case op_put_setter: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] put_setter\t %s, %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str()); + printf("[%4d] put_setter\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str()); + break; + } + case op_method_check: { + printf("[%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(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str()); + printf("[%4d] del_by_id\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), idName(id0, m_identifiers[id0]).c_str()); 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str()); + printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str()); + break; + } + case op_get_by_pname: { + int r0 = (++it)->u.operand; + int r1 = (++it)->u.operand; + int r2 = (++it)->u.operand; + 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).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str(), registerName(exec, r3).c_str(), registerName(exec, r4).c_str(), registerName(exec, r5).c_str()); 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str()); + printf("[%4d] put_by_val\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str()); 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(r0).c_str(), registerName(r1).c_str(), registerName(r2).c_str()); + printf("[%4d] del_by_val\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str()); 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(r0).c_str(), n0, registerName(r1).c_str()); + printf("[%4d] put_by_index\t %s, %u, %s\n", location, registerName(exec, r0).c_str(), n0, registerName(exec, r1).c_str()); break; } case op_jmp: { int offset = (++it)->u.operand; - printf("[%4d] jmp\t\t %d(->%d)\n", location, offset, locationForOffset(begin, it, offset)); + printf("[%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, locationForOffset(begin, it, offset)); + printf("[%4d] loop\t\t %d(->%d)\n", location, offset, location + offset); break; } case op_jtrue: { - printConditionalJump(begin, it, location, "jtrue"); + printConditionalJump(exec, begin, it, location, "jtrue"); break; } case op_loop_if_true: { - printConditionalJump(begin, it, location, "loop_if_true"); + printConditionalJump(exec, begin, it, location, "loop_if_true"); + break; + } + case op_loop_if_false: { + printConditionalJump(exec, begin, it, location, "loop_if_false"); break; } case op_jfalse: { - printConditionalJump(begin, it, location, "jfalse"); + printConditionalJump(exec, begin, it, location, "jfalse"); break; } case op_jeq_null: { - printConditionalJump(begin, it, location, "jeq_null"); + printConditionalJump(exec, begin, it, location, "jeq_null"); break; } case op_jneq_null: { - printConditionalJump(begin, it, location, "jneq_null"); + printConditionalJump(exec, begin, it, location, "jneq_null"); + break; + } + case op_jneq_ptr: { + 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).c_str(), registerName(exec, r1).c_str(), 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(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), 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).c_str(), registerName(exec, r1).c_str(), 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(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), 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).c_str(), registerName(exec, r1).c_str(), 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(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset); 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, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).c_str()); 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, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).c_str()); 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, locationForOffset(begin, it, defaultTarget), registerName(scrutineeRegister).c_str()); + printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).c_str()); break; } case op_new_func: { int r0 = (++it)->u.operand; int f0 = (++it)->u.operand; - printf("[%4d] new_func\t\t %s, f%d\n", location, registerName(r0).c_str(), f0); + printf("[%4d] new_func\t\t %s, f%d\n", location, registerName(exec, r0).c_str(), f0); 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(r0).c_str(), f0); + printf("[%4d] new_func_exp\t %s, f%d\n", location, registerName(exec, r0).c_str(), f0); break; } case op_call: { @@ -947,7 +970,7 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& int func = (++it)->u.operand; int argCount = (++it)->u.operand; int registerOffset = (++it)->u.operand; - printf("[%4d] call\t\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset); + printf("[%4d] call\t\t %s, %s, %d, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), argCount, registerOffset); break; } case op_call_eval: { @@ -955,12 +978,24 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& int func = (++it)->u.operand; int argCount = (++it)->u.operand; int registerOffset = (++it)->u.operand; - printf("[%4d] call_eval\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset); + printf("[%4d] call_eval\t %s, %s, %d, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), argCount, registerOffset); + break; + } + case op_call_varargs: { + int dst = (++it)->u.operand; + int func = (++it)->u.operand; + int argCount = (++it)->u.operand; + int registerOffset = (++it)->u.operand; + printf("[%4d] call_varargs\t %s, %s, %s, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), registerName(exec, argCount).c_str(), registerOffset); + break; + } + case op_load_varargs: { + printUnaryOp(exec, location, it, "load_varargs"); break; } case op_tear_off_activation: { int r0 = (++it)->u.operand; - printf("[%4d] tear_off_activation\t %s\n", location, registerName(r0).c_str()); + printf("[%4d] tear_off_activation\t %s\n", location, registerName(exec, r0).c_str()); break; } case op_tear_off_arguments: { @@ -969,7 +1004,7 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& } case op_ret: { int r0 = (++it)->u.operand; - printf("[%4d] ret\t\t %s\n", location, registerName(r0).c_str()); + printf("[%4d] ret\t\t %s\n", location, registerName(exec, r0).c_str()); break; } case op_construct: { @@ -979,31 +1014,49 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& int registerOffset = (++it)->u.operand; int proto = (++it)->u.operand; int thisRegister = (++it)->u.operand; - printf("[%4d] construct\t %s, %s, %d, %d, %s, %s\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset, registerName(proto).c_str(), registerName(thisRegister).c_str()); + printf("[%4d] construct\t %s, %s, %d, %d, %s, %s\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), argCount, registerOffset, registerName(exec, proto).c_str(), registerName(exec, thisRegister).c_str()); break; } case op_construct_verify: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] construct_verify\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str()); + printf("[%4d] construct_verify\t %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str()); break; } - case op_get_pnames: { + case op_strcat: { int r0 = (++it)->u.operand; int r1 = (++it)->u.operand; - printf("[%4d] get_pnames\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str()); + int count = (++it)->u.operand; + printf("[%4d] strcat\t\t %s, %s, %d\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), 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).c_str(), registerName(exec, r1).c_str()); + break; + } + case op_get_pnames: { + int r0 = it[1].u.operand; + int r1 = it[2].u.operand; + 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).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str(), registerName(exec, r3).c_str(), offset, location + offset); + it += OPCODE_LENGTH(op_get_pnames) - 1; break; } case op_next_pname: { - int dest = (++it)->u.operand; - int iter = (++it)->u.operand; - int offset = (++it)->u.operand; - printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(dest).c_str(), registerName(iter).c_str(), offset, locationForOffset(begin, it, offset)); + int dest = it[1].u.operand; + int iter = it[4].u.operand; + int offset = it[5].u.operand; + printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(exec, dest).c_str(), registerName(exec, iter).c_str(), 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(r0).c_str()); + printf("[%4d] push_scope\t %s\n", location, registerName(exec, r0).c_str()); break; } case op_pop_scope: { @@ -1014,41 +1067,41 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& 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(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str()); + printf("[%4d] push_new_scope \t%s, %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str()); 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, locationForOffset(begin, it, offset)); + printf("[%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(r0).c_str()); + printf("[%4d] catch\t\t %s\n", location, registerName(exec, r0).c_str()); break; } case op_throw: { int r0 = (++it)->u.operand; - printf("[%4d] throw\t\t %s\n", location, registerName(r0).c_str()); + printf("[%4d] throw\t\t %s\n", location, registerName(exec, r0).c_str()); break; } case op_new_error: { int r0 = (++it)->u.operand; int errorType = (++it)->u.operand; int k0 = (++it)->u.operand; - printf("[%4d] new_error\t %s, %d, %s\n", location, registerName(r0).c_str(), errorType, constantName(exec, k0, unexpectedConstant(k0)).c_str()); + printf("[%4d] new_error\t %s, %d, %s\n", location, registerName(exec, r0).c_str(), errorType, constantName(exec, k0, getConstant(k0)).c_str()); 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(retAddrDst).c_str(), offset, locationForOffset(begin, it, offset)); + printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(exec, retAddrDst).c_str(), offset, location + offset); break; } case op_sret: { int retAddrSrc = (++it)->u.operand; - printf("[%4d] sret\t\t %s\n", location, registerName(retAddrSrc).c_str()); + printf("[%4d] sret\t\t %s\n", location, registerName(exec, retAddrSrc).c_str()); break; } case op_debug: { @@ -1060,17 +1113,17 @@ void CodeBlock::dump(ExecState* exec, const Vector::const_iterator& } case op_profile_will_call: { int function = (++it)->u.operand; - printf("[%4d] profile_will_call %s\n", location, registerName(function).c_str()); + printf("[%4d] profile_will_call %s\n", location, registerName(exec, function).c_str()); break; } case op_profile_did_call: { int function = (++it)->u.operand; - printf("[%4d] profile_did_call\t %s\n", location, registerName(function).c_str()); + printf("[%4d] profile_did_call\t %s\n", location, registerName(exec, function).c_str()); break; } case op_end: { int r0 = (++it)->u.operand; - printf("[%4d] end\t\t %s\n", location, registerName(r0).c_str()); + printf("[%4d] end\t\t %s\n", location, registerName(exec, r0).c_str()); break; } } @@ -1095,7 +1148,6 @@ static HashSet liveCodeBlockSet; #define FOR_EACH_MEMBER_VECTOR_RARE_DATA(macro) \ macro(regexps) \ macro(functions) \ - macro(unexpectedConstants) \ macro(exceptionHandlers) \ macro(immediateSwitchJumpTables) \ macro(characterSwitchJumpTables) \ @@ -1218,23 +1270,22 @@ void CodeBlock::dumpStatistics() #endif } - -CodeBlock::CodeBlock(ScopeNode* ownerNode, CodeType codeType, PassRefPtr sourceProvider, unsigned sourceOffset) +CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, PassRefPtr sourceProvider, unsigned sourceOffset, SymbolTable* symTab) : m_numCalleeRegisters(0) - , m_numConstants(0) , m_numVars(0) , m_numParameters(0) - , m_ownerNode(ownerNode) + , m_ownerExecutable(ownerExecutable) , m_globalData(0) #ifndef NDEBUG , m_instructionCount(0) #endif - , m_needsFullScopeChain(ownerNode->needsActivation()) - , m_usesEval(ownerNode->usesEval()) + , m_needsFullScopeChain(ownerExecutable->needsActivation()) + , m_usesEval(ownerExecutable->usesEval()) , m_isNumericCompareFunction(false) , m_codeType(codeType) , m_source(sourceProvider) , m_sourceOffset(sourceOffset) + , m_symbolTable(symTab) , m_exceptionInfo(new ExceptionInfo) { ASSERT(m_source); @@ -1267,15 +1318,27 @@ CodeBlock::~CodeBlock() callLinkInfo->callee->removeCaller(callLinkInfo); } + for (size_t size = m_methodCallLinkInfos.size(), i = 0; i < size; ++i) { + if (Structure* structure = m_methodCallLinkInfos[i].cachedStructure) { + structure->deref(); + // Both members must be filled at the same time + ASSERT(!!m_methodCallLinkInfos[i].cachedPrototypeStructure); + m_methodCallLinkInfos[i].cachedPrototypeStructure->deref(); + } + } + +#if ENABLE(JIT_OPTIMIZE_CALL) unlinkCallers(); #endif +#endif // !ENABLE(JIT) + #if DUMP_CODE_BLOCK_STATISTICS liveCodeBlockSet.remove(this); #endif } -#if ENABLE(JIT) +#if ENABLE(JIT_OPTIMIZE_CALL) void CodeBlock::unlinkCallers() { size_t size = m_linkedCallerList.size(); @@ -1366,25 +1429,14 @@ void CodeBlock::refStructures(Instruction* vPC) const ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic)); } -void CodeBlock::mark() +void CodeBlock::markAggregate(MarkStack& markStack) { for (size_t i = 0; i < m_constantRegisters.size(); ++i) - if (!m_constantRegisters[i].marked()) - m_constantRegisters[i].mark(); - - for (size_t i = 0; i < m_functionExpressions.size(); ++i) - m_functionExpressions[i]->body()->mark(); - - if (m_rareData) { - for (size_t i = 0; i < m_rareData->m_functions.size(); ++i) - m_rareData->m_functions[i]->body()->mark(); - - for (size_t i = 0; i < m_rareData->m_unexpectedConstants.size(); ++i) { - if (!m_rareData->m_unexpectedConstants[i].marked()) - m_rareData->m_unexpectedConstants[i].mark(); - } - m_rareData->m_evalCodeCache.mark(); - } + markStack.append(m_constantRegisters[i].jsValue()); + for (size_t i = 0; i < m_functionExprs.size(); ++i) + m_functionExprs[i]->markAggregate(markStack); + for (size_t i = 0; i < m_functionDecls.size(); ++i) + m_functionDecls[i]->markAggregate(markStack); } void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame) @@ -1405,56 +1457,7 @@ void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame) scopeChain = scopeChain->next; } - switch (m_codeType) { - case FunctionCode: { - FunctionBodyNode* ownerFunctionBodyNode = static_cast(m_ownerNode); - RefPtr newFunctionBody = m_globalData->parser->reparse(m_globalData, ownerFunctionBodyNode); - ASSERT(newFunctionBody); - newFunctionBody->finishParsing(ownerFunctionBodyNode->copyParameters(), ownerFunctionBodyNode->parameterCount()); - - m_globalData->scopeNodeBeingReparsed = newFunctionBody.get(); - - CodeBlock& newCodeBlock = newFunctionBody->bytecodeForExceptionInfoReparse(scopeChain, this); - ASSERT(newCodeBlock.m_exceptionInfo); - ASSERT(newCodeBlock.m_instructionCount == m_instructionCount); - -#if ENABLE(JIT) - JIT::compile(m_globalData, &newCodeBlock); - ASSERT(newCodeBlock.m_jitCode.codeSize == m_jitCode.codeSize); -#endif - - m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release()); - - m_globalData->scopeNodeBeingReparsed = 0; - - break; - } - case EvalCode: { - EvalNode* ownerEvalNode = static_cast(m_ownerNode); - RefPtr newEvalBody = m_globalData->parser->reparse(m_globalData, ownerEvalNode); - - m_globalData->scopeNodeBeingReparsed = newEvalBody.get(); - - EvalCodeBlock& newCodeBlock = newEvalBody->bytecodeForExceptionInfoReparse(scopeChain, this); - ASSERT(newCodeBlock.m_exceptionInfo); - ASSERT(newCodeBlock.m_instructionCount == m_instructionCount); - -#if ENABLE(JIT) - JIT::compile(m_globalData, &newCodeBlock); - ASSERT(newCodeBlock.m_jitCode.codeSize == m_jitCode.codeSize); -#endif - - m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release()); - - m_globalData->scopeNodeBeingReparsed = 0; - - break; - } - default: - // CodeBlocks for Global code blocks are transient and therefore to not gain from - // from throwing out there exception information. - ASSERT_NOT_REACHED(); - } + m_exceptionInfo.set(m_ownerExecutable->reparseExceptionInfo(m_globalData, scopeChain, this)); } HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset) @@ -1483,7 +1486,7 @@ int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned byteco ASSERT(m_exceptionInfo); if (!m_exceptionInfo->m_lineInfo.size()) - return m_ownerNode->source().firstLine(); // Empty function + return m_ownerExecutable->source().firstLine(); // Empty function int low = 0; int high = m_exceptionInfo->m_lineInfo.size(); @@ -1496,7 +1499,7 @@ int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned byteco } if (!low) - return m_ownerNode->source().firstLine(); + return m_ownerExecutable->source().firstLine(); return m_exceptionInfo->m_lineInfo[low - 1].lineNumber; } @@ -1634,17 +1637,6 @@ bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset) } #endif -#if ENABLE(JIT) -void CodeBlock::setJITCode(JITCodeRef& jitCode) -{ - m_jitCode = jitCode; -#if !ENABLE(OPCODE_SAMPLING) - if (!BytecodeGenerator::dumpsGeneratedCode()) - m_instructions.clear(); -#endif -} -#endif - void CodeBlock::shrinkToFit() { m_instructions.shrinkToFit(); @@ -1660,7 +1652,8 @@ void CodeBlock::shrinkToFit() #endif m_identifiers.shrinkToFit(); - m_functionExpressions.shrinkToFit(); + m_functionDecls.shrinkToFit(); + m_functionExprs.shrinkToFit(); m_constantRegisters.shrinkToFit(); if (m_exceptionInfo) { @@ -1671,8 +1664,6 @@ void CodeBlock::shrinkToFit() if (m_rareData) { m_rareData->m_exceptionHandlers.shrinkToFit(); - m_rareData->m_functions.shrinkToFit(); - m_rareData->m_unexpectedConstants.shrinkToFit(); m_rareData->m_regexps.shrinkToFit(); m_rareData->m_immediateSwitchJumpTables.shrinkToFit(); m_rareData->m_characterSwitchJumpTables.shrinkToFit();