Ignore:
Timestamp:
Jan 7, 2009, 5:46:14 PM (16 years ago)
Author:
[email protected]
Message:

2009-01-07 Sam Weinig <[email protected]>

Reviewed by Geoffrey Garen.

<rdar://problem/6469060> Don't store exception information for a CodeBlock until first exception is thrown

Don't initially store exception information (lineNumber/expressionRange/getByIdExcecptionInfo)
in CodeBlocks blocks. Instead, re-parse for the data on demand and cache it then.

One important change that was needed to make this work was to pad op_get_global_var with nops to
be the same length as op_resolve_global, since one could be replaced for the other on re-parsing,
and we want to keep the offsets bytecode offsets the same.

1.3MB improvement on Membuster head.

  • bytecode/CodeBlock.cpp: (JSC::CodeBlock::dump): Update op_get_global_var to account for the padding. (JSC::CodeBlock::dumpStatistics): Add more statistic dumping. (JSC::CodeBlock::CodeBlock): Initialize m_exceptionInfo. (JSC::CodeBlock::reparseForExceptionInfoIfNecessary): Re-parses the CodeBlocks associated SourceCode and steals the ExceptionInfo from it. (JSC::CodeBlock::lineNumberForBytecodeOffset): Creates the exception info on demand. (JSC::CodeBlock::expressionRangeForBytecodeOffset): Ditto. (JSC::CodeBlock::getByIdExceptionInfoForBytecodeOffset): Ditto.
  • bytecode/CodeBlock.h: (JSC::CodeBlock::numberOfExceptionHandlers): Updated to account for m_exceptionInfo indirection. (JSC::CodeBlock::addExceptionHandler): Ditto. (JSC::CodeBlock::exceptionHandler): Ditto. (JSC::CodeBlock::clearExceptionInfo): Ditto. (JSC::CodeBlock::addExpressionInfo): Ditto. (JSC::CodeBlock::addGetByIdExceptionInfo): Ditto. (JSC::CodeBlock::numberOfLineInfos): Ditto. (JSC::CodeBlock::addLineInfo): Ditto. (JSC::CodeBlock::lastLineInfo): Ditto.
  • bytecode/Opcode.h: Change length of op_get_global_var to match op_resolve_global.
  • bytecode/SamplingTool.cpp: (JSC::SamplingTool::dump): Add comment indicating why it is okay not to pass a CallFrame.
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::generate): Clear the exception info after generation for Function and Eval Code when not in regenerate for exception info mode. (JSC::BytecodeGenerator::BytecodeGenerator): Initialize m_regeneratingForExceptionInfo to false. (JSC::BytecodeGenerator::emitGetScopedVar): Pad op_get_global_var with 2 nops.
  • bytecompiler/BytecodeGenerator.h: (JSC::BytecodeGenerator::setRegeneratingForExcpeptionInfo): Added.
  • interpreter/Interpreter.cpp: (JSC::Interpreter::throwException): Pass the CallFrame to exception info accessors. (JSC::Interpreter::privateExecute): Ditto. (JSC::Interpreter::retrieveLastCaller): Ditto. (JSC::Interpreter::cti_op_new_error): Ditto.
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): Pass the current bytecode offset instead of hard coding the line number, the stub will do the accessing if it gets called.
  • parser/Nodes.cpp: (JSC::ProgramNode::emitBytecode): Moved. (JSC::ProgramNode::generateBytecode): Moved. (JSC::EvalNode::create): Moved. (JSC::EvalNode::bytecodeForExceptionInfoReparse): Added. (JSC::FunctionBodyNode::generateBytecode): Rename reparse to reparseInPlace. (JSC::FunctionBodyNode::bytecodeForExceptionInfoReparse): Addded.
  • parser/Nodes.h: (JSC::ScopeNode::features): Added getter.
  • parser/Parser.cpp: (JSC::Parser::reparseInPlace): Renamed from reparse.
  • parser/Parser.h: (JSC::Parser::reparse): Added. Re-parses the passed in Node into a new Node.
  • runtime/ExceptionHelpers.cpp: (JSC::createUndefinedVariableError): Pass along CallFrame. (JSC::createInvalidParamError): Ditto. (JSC::createNotAConstructorError): Ditto. (JSC::createNotAFunctionError): Ditto. (JSC::createNotAnObjectError): Ditto.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/interpreter/Interpreter.cpp

    r39670 r39697  
    11/*
    2  * Copyright (C) 2008 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Cameron Zwarich <[email protected]>
    44 *
     
    798798                    int endOffset = 0;
    799799                    int divotPoint = 0;
    800                     int line = codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset);
     800                    int line = codeBlock->expressionRangeForBytecodeOffset(callFrame, bytecodeOffset, divotPoint, startOffset, endOffset);
    801801                    exception->putWithAttributes(callFrame, Identifier(callFrame, "line"), jsNumber(callFrame, line), ReadOnly | DontDelete);
    802802                   
     
    806806                    exception->putWithAttributes(callFrame, Identifier(callFrame, expressionEndOffsetPropertyName), jsNumber(callFrame, divotPoint + endOffset), ReadOnly | DontDelete);
    807807                } else
    808                     exception->putWithAttributes(callFrame, Identifier(callFrame, "line"), jsNumber(callFrame, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset)), ReadOnly | DontDelete);
     808                    exception->putWithAttributes(callFrame, Identifier(callFrame, "line"), jsNumber(callFrame, codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset)), ReadOnly | DontDelete);
    809809                exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerNode()->sourceID()), ReadOnly | DontDelete);
    810810                exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceURL"), jsOwnedString(callFrame, codeBlock->ownerNode()->sourceURL()), ReadOnly | DontDelete);
     
    822822    if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
    823823        DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
    824         debugger->exception(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset));
     824        debugger->exception(debuggerCallFrame, codeBlock->ownerNode()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset));
    825825    }
    826826
     
    23492349    }
    23502350    DEFINE_OPCODE(op_get_global_var) {
    2351         /* get_global_var dst(r) globalObject(c) index(n)
     2351        /* get_global_var dst(r) globalObject(c) index(n) nop(n) nop(n)
    23522352
    23532353           Gets the global var at global slot index and places it in register dst.
    23542354         */
    2355         int dst = (++vPC)->u.operand;
    2356         JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell);
     2355        int dst = vPC[1].u.operand;
     2356        JSGlobalObject* scope = static_cast<JSGlobalObject*>(vPC[2].u.jsCell);
    23572357        ASSERT(scope->isGlobalObject());
    2358         int index = (++vPC)->u.operand;
     2358        int index = vPC[3].u.operand;
    23592359
    23602360        callFrame[dst] = scope->registerAt(index);
    2361         ++vPC;
     2361
     2362        vPC += OPCODE_LENGTH(op_resolve_global);
    23622363        NEXT_INSTRUCTION();
    23632364    }
     
    38163817
    38173818        CodeBlock* codeBlock = callFrame->codeBlock();
    3818         callFrame[dst] = JSValuePtr(Error::create(callFrame, (ErrorType)type, codeBlock->unexpectedConstant(message)->toString(callFrame), codeBlock->lineNumberForBytecodeOffset(vPC - codeBlock->instructions().begin()), codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()));
     3819        callFrame[dst] = JSValuePtr(Error::create(callFrame, (ErrorType)type, codeBlock->unexpectedConstant(message)->toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()));
    38193820
    38203821        ++vPC;
     
    40334034
    40344035    unsigned bytecodeOffset = bytecodeOffsetForPC(callerCodeBlock, callFrame->returnPC());
    4035     lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
     4036    lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(callerFrame, bytecodeOffset - 1);
    40364037    sourceID = callerCodeBlock->ownerNode()->sourceID();
    40374038    sourceURL = callerCodeBlock->ownerNode()->sourceURL();
     
    60466047    unsigned type = ARG_int1;
    60476048    JSValuePtr message = ARG_src2;
    6048     unsigned lineNumber = ARG_int3;
    6049 
     6049    unsigned bytecodeOffset = ARG_int3;
     6050
     6051    unsigned lineNumber = codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset);
    60506052    return Error::create(callFrame, static_cast<ErrorType>(type), message->toString(callFrame), lineNumber, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
    60516053}
Note: See TracChangeset for help on using the changeset viewer.