diff options
author | Ben Murdoch <benm@google.com> | 2009-08-18 15:36:45 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2009-08-18 19:20:06 +0100 |
commit | d227fc870c7a697500a3c900c31baf05fb9a8524 (patch) | |
tree | a3fa109aa5bf52fef562ac49d97a2f723889cc71 /JavaScriptCore/bytecode | |
parent | f2c627513266faa73f7669058d98c60769fb3524 (diff) | |
download | external_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.zip external_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.tar.gz external_webkit-d227fc870c7a697500a3c900c31baf05fb9a8524.tar.bz2 |
Merge WebKit r47420
Diffstat (limited to 'JavaScriptCore/bytecode')
-rw-r--r-- | JavaScriptCore/bytecode/CodeBlock.cpp | 98 | ||||
-rw-r--r-- | JavaScriptCore/bytecode/CodeBlock.h | 93 | ||||
-rw-r--r-- | JavaScriptCore/bytecode/EvalCodeCache.h | 36 | ||||
-rw-r--r-- | JavaScriptCore/bytecode/SamplingTool.cpp | 2 |
4 files changed, 91 insertions, 138 deletions
diff --git a/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp index e22f25a..b63e826 100644 --- a/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/JavaScriptCore/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 <stdio.h> @@ -1246,11 +1248,11 @@ void CodeBlock::dumpStatistics() #endif } -CodeBlock::CodeBlock(ScopeNode* ownerNode) +CodeBlock::CodeBlock(ExecutableBase* ownerExecutable) : m_numCalleeRegisters(0) , m_numVars(0) , m_numParameters(0) - , m_ownerNode(ownerNode) + , m_ownerExecutable(ownerExecutable) , m_globalData(0) #ifndef NDEBUG , m_instructionCount(0) @@ -1268,17 +1270,17 @@ CodeBlock::CodeBlock(ScopeNode* ownerNode) #endif } -CodeBlock::CodeBlock(ScopeNode* ownerNode, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset) +CodeBlock::CodeBlock(ExecutableBase* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset) : m_numCalleeRegisters(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) @@ -1435,15 +1437,10 @@ void CodeBlock::markAggregate(MarkStack& markStack) markStack.append(m_constantRegisters[i].jsValue()); } - for (size_t i = 0; i < m_functionExpressions.size(); ++i) - m_functionExpressions[i]->body()->markAggregate(markStack); - - if (m_rareData) { - for (size_t i = 0; i < m_rareData->m_functions.size(); ++i) - m_rareData->m_functions[i]->body()->markAggregate(markStack); - - m_rareData->m_evalCodeCache.markAggregate(markStack); - } + 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) @@ -1465,56 +1462,7 @@ void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame) scopeChain = scopeChain->next; } - switch (m_codeType) { - case FunctionCode: { - FunctionBodyNode* ownerFunctionBodyNode = static_cast<FunctionBodyNode*>(m_ownerNode); - RefPtr<FunctionBodyNode> newFunctionBody = m_globalData->parser->reparse<FunctionBodyNode>(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(newFunctionBody->generatedJITCode().size() == ownerNode()->generatedJITCode().size()); -#endif - - m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release()); - - m_globalData->scopeNodeBeingReparsed = 0; - - break; - } - case EvalCode: { - EvalNode* ownerEvalNode = static_cast<EvalNode*>(m_ownerNode); - RefPtr<EvalNode> newEvalBody = m_globalData->parser->reparse<EvalNode>(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(newEvalBody->generatedJITCode().size() == ownerNode()->generatedJITCode().size()); -#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) @@ -1545,7 +1493,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(); @@ -1558,7 +1506,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; } @@ -1701,18 +1649,6 @@ bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset) } #endif -#if ENABLE(JIT) -void CodeBlock::setJITCode(JITCode jitCode) -{ - ASSERT(m_codeType != NativeCode); - ownerNode()->setJITCode(jitCode); -#if !ENABLE(OPCODE_SAMPLING) - if (!BytecodeGenerator::dumpsGeneratedCode()) - m_instructions.clear(); -#endif -} -#endif - void CodeBlock::shrinkToFit() { m_instructions.shrinkToFit(); @@ -1728,7 +1664,8 @@ void CodeBlock::shrinkToFit() #endif m_identifiers.shrinkToFit(); - m_functionExpressions.shrinkToFit(); + m_functionDecls.shrinkToFit(); + m_functionExprs.shrinkToFit(); m_constantRegisters.shrinkToFit(); if (m_exceptionInfo) { @@ -1739,7 +1676,6 @@ void CodeBlock::shrinkToFit() if (m_rareData) { m_rareData->m_exceptionHandlers.shrinkToFit(); - m_rareData->m_functions.shrinkToFit(); m_rareData->m_regexps.shrinkToFit(); m_rareData->m_immediateSwitchJumpTables.shrinkToFit(); m_rareData->m_characterSwitchJumpTables.shrinkToFit(); diff --git a/JavaScriptCore/bytecode/CodeBlock.h b/JavaScriptCore/bytecode/CodeBlock.h index 39b1db3..fdeb4db 100644 --- a/JavaScriptCore/bytecode/CodeBlock.h +++ b/JavaScriptCore/bytecode/CodeBlock.h @@ -248,11 +248,22 @@ namespace JSC { } #endif + struct ExceptionInfo : FastAllocBase { + Vector<ExpressionRangeInfo> m_expressionInfo; + Vector<LineInfo> m_lineInfo; + Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo; + +#if ENABLE(JIT) + Vector<CallReturnOffsetToBytecodeIndex> m_callReturnIndexVector; +#endif + }; + class CodeBlock : public FastAllocBase { friend class JIT; + protected: + CodeBlock(ExecutableBase* ownerExecutable); + CodeBlock(ExecutableBase* ownerExecutable, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset); public: - CodeBlock(ScopeNode* ownerNode); - CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset); ~CodeBlock(); void markAggregate(MarkStack&); @@ -329,7 +340,7 @@ namespace JSC { unsigned getBytecodeIndex(CallFrame* callFrame, ReturnAddressPtr returnAddress) { reparseForExceptionInfoIfNecessary(callFrame); - return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(callReturnIndexVector().begin(), callReturnIndexVector().size(), ownerNode()->generatedJITCode().offsetOf(returnAddress.value()))->bytecodeIndex; + return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(callReturnIndexVector().begin(), callReturnIndexVector().size(), ownerExecutable()->generatedJITCode().offsetOf(returnAddress.value()))->bytecodeIndex; } bool functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex); @@ -339,17 +350,19 @@ namespace JSC { bool isNumericCompareFunction() { return m_isNumericCompareFunction; } Vector<Instruction>& instructions() { return m_instructions; } + void discardBytecode() { m_instructions.clear(); } + #ifndef NDEBUG + unsigned instructionCount() { return m_instructionCount; } void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; } #endif #if ENABLE(JIT) - JITCode& getJITCode() { return ownerNode()->generatedJITCode(); } - void setJITCode(JITCode); - ExecutablePool* executablePool() { return ownerNode()->getExecutablePool(); } + JITCode& getJITCode() { return ownerExecutable()->generatedJITCode(); } + ExecutablePool* executablePool() { return ownerExecutable()->getExecutablePool(); } #endif - ScopeNode* ownerNode() const { return m_ownerNode; } + ExecutableBase* ownerExecutable() const { return m_ownerExecutable; } void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; } @@ -404,6 +417,7 @@ namespace JSC { bool hasExceptionInfo() const { return m_exceptionInfo; } void clearExceptionInfo() { m_exceptionInfo.clear(); } + ExceptionInfo* extractExceptionInfo() { ASSERT(m_exceptionInfo); return m_exceptionInfo.release(); } void addExpressionInfo(const ExpressionRangeInfo& expressionInfo) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_expressionInfo.append(expressionInfo); } void addGetByIdExceptionInfo(const GetByIdExceptionInfo& info) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_getByIdExceptionInfo.append(info); } @@ -428,13 +442,11 @@ namespace JSC { ALWAYS_INLINE bool isConstantRegisterIndex(int index) { return index >= FirstConstantRegisterIndex; } ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].jsValue(); } - unsigned addFunctionExpression(FuncExprNode* n) { unsigned size = m_functionExpressions.size(); m_functionExpressions.append(n); return size; } - FuncExprNode* functionExpression(int index) const { return m_functionExpressions[index].get(); } - - unsigned addFunction(FuncDeclNode* n) { createRareDataIfNecessary(); unsigned size = m_rareData->m_functions.size(); m_rareData->m_functions.append(n); return size; } - FuncDeclNode* function(int index) const { ASSERT(m_rareData); return m_rareData->m_functions[index].get(); } - - bool hasFunctions() const { return m_functionExpressions.size() || (m_rareData && m_rareData->m_functions.size()); } + unsigned addFunctionDecl(PassRefPtr<FunctionExecutable> n) { unsigned size = m_functionDecls.size(); m_functionDecls.append(n); return size; } + FunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); } + int numberOfFunctionDecls() { return m_functionDecls.size(); } + unsigned addFunctionExpr(PassRefPtr<FunctionExecutable> n) { unsigned size = m_functionExprs.size(); m_functionExprs.append(n); return size; } + FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); } unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; } RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); } @@ -481,7 +493,7 @@ namespace JSC { m_rareData.set(new RareData); } - ScopeNode* m_ownerNode; + ExecutableBase* m_ownerExecutable; JSGlobalData* m_globalData; Vector<Instruction> m_instructions; @@ -517,26 +529,17 @@ namespace JSC { // Constant Pool Vector<Identifier> m_identifiers; Vector<Register> m_constantRegisters; - Vector<RefPtr<FuncExprNode> > m_functionExpressions; + Vector<RefPtr<FunctionExecutable> > m_functionDecls; + Vector<RefPtr<FunctionExecutable> > m_functionExprs; SymbolTable m_symbolTable; - struct ExceptionInfo : FastAllocBase { - Vector<ExpressionRangeInfo> m_expressionInfo; - Vector<LineInfo> m_lineInfo; - Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo; - -#if ENABLE(JIT) - Vector<CallReturnOffsetToBytecodeIndex> m_callReturnIndexVector; -#endif - }; OwnPtr<ExceptionInfo> m_exceptionInfo; struct RareData : FastAllocBase { Vector<HandlerInfo> m_exceptionHandlers; // Rare Constants - Vector<RefPtr<FuncDeclNode> > m_functions; Vector<RefPtr<RegExp> > m_regexps; // Jump Tables @@ -556,16 +559,16 @@ namespace JSC { // Program code is not marked by any function, so we make the global object // responsible for marking it. - class ProgramCodeBlock : public CodeBlock { + class GlobalCodeBlock : public CodeBlock { public: - ProgramCodeBlock(ScopeNode* ownerNode, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider) - : CodeBlock(ownerNode, codeType, sourceProvider, 0) + GlobalCodeBlock(ExecutableBase* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, JSGlobalObject* globalObject) + : CodeBlock(ownerExecutable, codeType, sourceProvider, sourceOffset) , m_globalObject(globalObject) { m_globalObject->codeBlocks().add(this); } - ~ProgramCodeBlock() + ~GlobalCodeBlock() { if (m_globalObject) m_globalObject->codeBlocks().remove(this); @@ -577,10 +580,18 @@ namespace JSC { JSGlobalObject* m_globalObject; // For program and eval nodes, the global object that marks the constant pool. }; - class EvalCodeBlock : public ProgramCodeBlock { + class ProgramCodeBlock : public GlobalCodeBlock { public: - EvalCodeBlock(ScopeNode* ownerNode, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth) - : ProgramCodeBlock(ownerNode, EvalCode, globalObject, sourceProvider) + ProgramCodeBlock(ProgramExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider) + : GlobalCodeBlock(ownerExecutable, codeType, sourceProvider, 0, globalObject) + { + } + }; + + class EvalCodeBlock : public GlobalCodeBlock { + public: + EvalCodeBlock(EvalExecutable* ownerExecutable, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth) + : GlobalCodeBlock(ownerExecutable, EvalCode, sourceProvider, 0, globalObject) , m_baseScopeDepth(baseScopeDepth) { } @@ -591,6 +602,22 @@ namespace JSC { int m_baseScopeDepth; }; + class FunctionCodeBlock : public CodeBlock { + public: + FunctionCodeBlock(FunctionExecutable* ownerExecutable, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset) + : CodeBlock(ownerExecutable, codeType, sourceProvider, sourceOffset) + { + } + }; + + class NativeCodeBlock : public CodeBlock { + public: + NativeCodeBlock(FunctionExecutable* ownerExecutable) + : CodeBlock(ownerExecutable) + { + } + }; + inline Register& ExecState::r(int index) { CodeBlock* codeBlock = this->codeBlock(); diff --git a/JavaScriptCore/bytecode/EvalCodeCache.h b/JavaScriptCore/bytecode/EvalCodeCache.h index 986525c..c486e42 100644 --- a/JavaScriptCore/bytecode/EvalCodeCache.h +++ b/JavaScriptCore/bytecode/EvalCodeCache.h @@ -29,6 +29,7 @@ #ifndef EvalCodeCache_h #define EvalCodeCache_h +#include "Executable.h" #include "JSGlobalObject.h" #include "Nodes.h" #include "Parser.h" @@ -41,44 +42,33 @@ namespace JSC { class EvalCodeCache { public: - PassRefPtr<EvalNode> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) + PassRefPtr<CacheableEvalExecutable> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) { - RefPtr<EvalNode> evalNode; + RefPtr<CacheableEvalExecutable> evalExecutable; if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject()) - evalNode = m_cacheMap.get(evalSource.rep()); + evalExecutable = m_cacheMap.get(evalSource.rep()); - if (!evalNode) { - int errorLine; - UString errorMessage; - - SourceCode source = makeSource(evalSource); - evalNode = exec->globalData().parser->parse<EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errorLine, &errorMessage); - if (evalNode) { - if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) - m_cacheMap.set(evalSource.rep(), evalNode); - } else { - exceptionValue = Error::create(exec, SyntaxError, errorMessage, errorLine, source.provider()->asID(), 0); + if (!evalExecutable) { + evalExecutable = CacheableEvalExecutable::create(makeSource(evalSource)); + exceptionValue = evalExecutable->parse(exec); + if (exceptionValue) return 0; - } + + if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) + m_cacheMap.set(evalSource.rep(), evalExecutable); } - return evalNode.release(); + return evalExecutable.release(); } bool isEmpty() const { return m_cacheMap.isEmpty(); } - void markAggregate(MarkStack& markStack) - { - EvalCacheMap::iterator end = m_cacheMap.end(); - for (EvalCacheMap::iterator ptr = m_cacheMap.begin(); ptr != end; ++ptr) - ptr->second->markAggregate(markStack); - } private: static const int maxCacheableSourceLength = 256; static const int maxCacheEntries = 64; - typedef HashMap<RefPtr<UString::Rep>, RefPtr<EvalNode> > EvalCacheMap; + typedef HashMap<RefPtr<UString::Rep>, RefPtr<CacheableEvalExecutable> > EvalCacheMap; EvalCacheMap m_cacheMap; }; diff --git a/JavaScriptCore/bytecode/SamplingTool.cpp b/JavaScriptCore/bytecode/SamplingTool.cpp index 8651723..8d0faa1 100644 --- a/JavaScriptCore/bytecode/SamplingTool.cpp +++ b/JavaScriptCore/bytecode/SamplingTool.cpp @@ -197,7 +197,7 @@ void SamplingTool::doRun() #if ENABLE(CODEBLOCK_SAMPLING) if (CodeBlock* codeBlock = sample.codeBlock()) { MutexLocker locker(m_scopeSampleMapMutex); - ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerNode()); + ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerExecutable()); ASSERT(record); record->sample(codeBlock, sample.vPC()); } |