[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
barraclough at apple.com
barraclough at apple.com
Wed Dec 22 16:09:32 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 87dbd5e0bf4b72c809ab8cb504b0f39874bcc7f0
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Nov 19 02:35:25 2010 +0000
Bug 49708 - Stop recompiling functions to regenerate exception info.
Reviewed by Oliver Hunt.
Instead only hold info as necessary – keep divot info is the inspector
is enabled, line number info is debugging or profiling, and handler
info for functions with try/catch.
JavaScriptCore:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpStatistics):
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::lineNumberForBytecodeOffset):
(JSC::CodeBlock::expressionRangeForBytecodeOffset):
(JSC::CodeBlock::shrinkToFit):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::bytecodeOffset):
(JSC::CodeBlock::addExpressionInfo):
(JSC::CodeBlock::addLineInfo):
(JSC::CodeBlock::hasExpressionInfo):
(JSC::CodeBlock::hasLineInfo):
(JSC::CodeBlock::needsCallReturnIndices):
(JSC::CodeBlock::callReturnIndexVector):
* bytecode/SamplingTool.cpp:
(JSC::SamplingTool::dump):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::BytecodeGenerator):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::emitNode):
(JSC::BytecodeGenerator::emitNodeInConditionContext):
(JSC::BytecodeGenerator::emitExpressionInfo):
(JSC::BytecodeGenerator::addLineInfo):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::unwindCallFrame):
(JSC::appendSourceToError):
(JSC::Interpreter::throwException):
(JSC::Interpreter::privateExecute):
(JSC::Interpreter::retrieveLastCaller):
* interpreter/Interpreter.h:
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITStubs.cpp:
(JSC::jitThrow):
(JSC::DEFINE_STUB_FUNCTION):
* runtime/Collector.cpp:
(JSC::Heap::markRoots):
* runtime/Executable.cpp:
(JSC::EvalExecutable::compileInternal):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):
* runtime/Executable.h:
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
* runtime/JSGlobalData.h:
(JSC::JSGlobalData::usingAPI):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::supportsRichSourceInfo):
(JSC::JSGlobalObject::globalData):
WebCore:
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::JSDOMWindowBase::supportsRichSourceInfo):
- report to JSC whether the inspector is enabled - in which
case we will generate better error messages on exceptions.
* bindings/js/JSDOMWindowBase.h:
WebKitTools:
* DumpRenderTree/mac/DumpRenderTree.mm:
(shouldEnableDeveloperExtras):
- always enable the developer tools from DRT, to ensure we
produce rich error messages on JavaScript exceptions.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@72360 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index b752aca..7644cd7 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,65 @@
+2010-11-18 Gavin Barraclough <barraclough at apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 49708 - Stop recompiling functions to regenerate exception info.
+
+ Instead only hold info as necessary – keep divot info is the inspector
+ is enabled, line number info is debugging or profiling, and handler
+ info for functions with try/catch.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dumpStatistics):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::lineNumberForBytecodeOffset):
+ (JSC::CodeBlock::expressionRangeForBytecodeOffset):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::bytecodeOffset):
+ (JSC::CodeBlock::addExpressionInfo):
+ (JSC::CodeBlock::addLineInfo):
+ (JSC::CodeBlock::hasExpressionInfo):
+ (JSC::CodeBlock::hasLineInfo):
+ (JSC::CodeBlock::needsCallReturnIndices):
+ (JSC::CodeBlock::callReturnIndexVector):
+ * bytecode/SamplingTool.cpp:
+ (JSC::SamplingTool::dump):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::generate):
+ (JSC::BytecodeGenerator::BytecodeGenerator):
+ * bytecompiler/BytecodeGenerator.h:
+ (JSC::BytecodeGenerator::emitNode):
+ (JSC::BytecodeGenerator::emitNodeInConditionContext):
+ (JSC::BytecodeGenerator::emitExpressionInfo):
+ (JSC::BytecodeGenerator::addLineInfo):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::appendSourceToError):
+ (JSC::Interpreter::throwException):
+ (JSC::Interpreter::privateExecute):
+ (JSC::Interpreter::retrieveLastCaller):
+ * interpreter/Interpreter.h:
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompile):
+ * jit/JITStubs.cpp:
+ (JSC::jitThrow):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/Collector.cpp:
+ (JSC::Heap::markRoots):
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::ProgramExecutable::compileInternal):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ * runtime/Executable.h:
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ (JSC::JSGlobalData::usingAPI):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::supportsRichSourceInfo):
+ (JSC::JSGlobalObject::globalData):
+
2010-11-18 Adam Roben <aroben at apple.com>
Add a script to delete manifest-related files when they are older than
diff --git a/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp
index 00ebde8..4576519 100644
--- a/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -1261,13 +1261,10 @@ static HashSet<CodeBlock*> liveCodeBlockSet;
macro(immediateSwitchJumpTables) \
macro(characterSwitchJumpTables) \
macro(stringSwitchJumpTables) \
- macro(functionRegisterInfos)
-
-#define FOR_EACH_MEMBER_VECTOR_EXCEPTION_INFO(macro) \
+ macro(evalCodeCache) \
macro(expressionInfo) \
macro(lineInfo) \
- macro(getByIdExceptionInfo) \
- macro(pcVector)
+ macro(callReturnIndexVector)
template<typename T>
static size_t sizeInBytes(const Vector<T>& vector)
@@ -1281,7 +1278,6 @@ void CodeBlock::dumpStatistics()
#define DEFINE_VARS(name) size_t name##IsNotEmpty = 0; size_t name##TotalSize = 0;
FOR_EACH_MEMBER_VECTOR(DEFINE_VARS)
FOR_EACH_MEMBER_VECTOR_RARE_DATA(DEFINE_VARS)
- FOR_EACH_MEMBER_VECTOR_EXCEPTION_INFO(DEFINE_VARS)
#undef DEFINE_VARS
// Non-vector data members
@@ -1290,7 +1286,6 @@ void CodeBlock::dumpStatistics()
size_t symbolTableIsNotEmpty = 0;
size_t symbolTableTotalSize = 0;
- size_t hasExceptionInfo = 0;
size_t hasRareData = 0;
size_t isFunctionCode = 0;
@@ -1310,13 +1305,6 @@ void CodeBlock::dumpStatistics()
symbolTableTotalSize += (codeBlock->m_symbolTable.capacity() * (sizeof(SymbolTable::KeyType) + sizeof(SymbolTable::MappedType)));
}
- if (codeBlock->m_exceptionInfo) {
- hasExceptionInfo++;
- #define GET_STATS(name) if (!codeBlock->m_exceptionInfo->m_##name.isEmpty()) { name##IsNotEmpty++; name##TotalSize += sizeInBytes(codeBlock->m_exceptionInfo->m_##name); }
- FOR_EACH_MEMBER_VECTOR_EXCEPTION_INFO(GET_STATS)
- #undef GET_STATS
- }
-
if (codeBlock->m_rareData) {
hasRareData++;
#define GET_STATS(name) if (!codeBlock->m_rareData->m_##name.isEmpty()) { name##IsNotEmpty++; name##TotalSize += sizeInBytes(codeBlock->m_rareData->m_##name); }
@@ -1345,7 +1333,6 @@ void CodeBlock::dumpStatistics()
#define GET_TOTAL_SIZE(name) totalSize += name##TotalSize;
FOR_EACH_MEMBER_VECTOR(GET_TOTAL_SIZE)
FOR_EACH_MEMBER_VECTOR_RARE_DATA(GET_TOTAL_SIZE)
- FOR_EACH_MEMBER_VECTOR_EXCEPTION_INFO(GET_TOTAL_SIZE)
#undef GET_TOTAL_SIZE
totalSize += symbolTableTotalSize;
@@ -1360,13 +1347,11 @@ void CodeBlock::dumpStatistics()
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());
- printf("Number of CodeBlocks with exception info: %zu (%.3f%%)\n", hasExceptionInfo, static_cast<double>(hasExceptionInfo) * 100.0 / liveCodeBlockSet.size());
printf("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);
FOR_EACH_MEMBER_VECTOR(PRINT_STATS)
FOR_EACH_MEMBER_VECTOR_RARE_DATA(PRINT_STATS)
- FOR_EACH_MEMBER_VECTOR_EXCEPTION_INFO(PRINT_STATS)
#undef PRINT_STATS
printf("Number of CodeBlocks with evalCodeCache: %zu\n", evalCodeCacheIsNotEmpty);
@@ -1399,7 +1384,6 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlo
, m_source(sourceProvider)
, m_sourceOffset(sourceOffset)
, m_symbolTable(symTab)
- , m_exceptionInfo(adoptPtr(new ExceptionInfo))
{
ASSERT(m_source);
@@ -1558,33 +1542,6 @@ void CodeBlock::markAggregate(MarkStack& markStack)
markStack.append(m_globalObject);
}
-bool CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
-{
- if (m_exceptionInfo)
- return true;
-
- ASSERT(!m_rareData || !m_rareData->m_exceptionHandlers.size());
- ScopeChainNode* scopeChain = callFrame->scopeChain();
- if (m_needsFullScopeChain) {
- if (codeType() == FunctionCode && !callFrame->r(activationRegister()).jsValue()) {
- createActivation(callFrame);
- scopeChain = callFrame->scopeChain();
- }
- ScopeChain sc(scopeChain);
- int scopeDelta = sc.localDepth();
- if (m_codeType == EvalCode)
- scopeDelta -= static_cast<EvalCodeBlock*>(this)->baseScopeDepth();
- else if (m_codeType == FunctionCode)
- scopeDelta++; // Compilation of function code assumes activation is not on the scope chain yet.
- ASSERT(scopeDelta >= 0);
- while (scopeDelta--)
- scopeChain = scopeChain->next;
- }
-
- m_exceptionInfo = m_ownerExecutable->reparseExceptionInfo(scopeChain, this);
- return m_exceptionInfo;
-}
-
HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
{
ASSERT(bytecodeOffset < m_instructionCount);
@@ -1603,46 +1560,48 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
return 0;
}
-int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset)
+int CodeBlock::lineNumberForBytecodeOffset(unsigned bytecodeOffset)
{
ASSERT(bytecodeOffset < m_instructionCount);
- if (!reparseForExceptionInfoIfNecessary(callFrame) || !m_exceptionInfo->m_lineInfo.size())
- return m_ownerExecutable->source().firstLine(); // Empty function or unable to reparse
+ if (!m_rareData)
+ return m_ownerExecutable->source().firstLine();
+
+ Vector<LineInfo>& lineInfo = m_rareData->m_lineInfo;
int low = 0;
- int high = m_exceptionInfo->m_lineInfo.size();
+ int high = lineInfo.size();
while (low < high) {
int mid = low + (high - low) / 2;
- if (m_exceptionInfo->m_lineInfo[mid].instructionOffset <= bytecodeOffset)
+ if (lineInfo[mid].instructionOffset <= bytecodeOffset)
low = mid + 1;
else
high = mid;
}
-
+
if (!low)
return m_ownerExecutable->source().firstLine();
- return m_exceptionInfo->m_lineInfo[low - 1].lineNumber;
+ return lineInfo[low - 1].lineNumber;
}
-void CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
+void CodeBlock::expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
{
ASSERT(bytecodeOffset < m_instructionCount);
- if (!reparseForExceptionInfoIfNecessary(callFrame) || !m_exceptionInfo->m_expressionInfo.size()) {
- // We didn't think anything could throw. Apparently we were wrong.
- // Alternatively something went wrong when trying to reparse
+ if (!m_rareData) {
startOffset = 0;
endOffset = 0;
divot = 0;
return;
}
+ Vector<ExpressionRangeInfo>& expressionInfo = m_rareData->m_expressionInfo;
+
int low = 0;
- int high = m_exceptionInfo->m_expressionInfo.size();
+ int high = expressionInfo.size();
while (low < high) {
int mid = low + (high - low) / 2;
- if (m_exceptionInfo->m_expressionInfo[mid].instructionOffset <= bytecodeOffset)
+ if (expressionInfo[mid].instructionOffset <= bytecodeOffset)
low = mid + 1;
else
high = mid;
@@ -1656,9 +1615,9 @@ void CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned
return;
}
- startOffset = m_exceptionInfo->m_expressionInfo[low - 1].startOffset;
- endOffset = m_exceptionInfo->m_expressionInfo[low - 1].endOffset;
- divot = m_exceptionInfo->m_expressionInfo[low - 1].divotPoint + m_sourceOffset;
+ startOffset = expressionInfo[low - 1].startOffset;
+ endOffset = expressionInfo[low - 1].endOffset;
+ divot = expressionInfo[low - 1].divotPoint + m_sourceOffset;
return;
}
@@ -1725,17 +1684,14 @@ void CodeBlock::shrinkToFit()
m_functionExprs.shrinkToFit();
m_constantRegisters.shrinkToFit();
- if (m_exceptionInfo) {
- m_exceptionInfo->m_expressionInfo.shrinkToFit();
- m_exceptionInfo->m_lineInfo.shrinkToFit();
- }
-
if (m_rareData) {
m_rareData->m_exceptionHandlers.shrinkToFit();
m_rareData->m_regexps.shrinkToFit();
m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
m_rareData->m_characterSwitchJumpTables.shrinkToFit();
m_rareData->m_stringSwitchJumpTables.shrinkToFit();
+ m_rareData->m_expressionInfo.shrinkToFit();
+ m_rareData->m_lineInfo.shrinkToFit();
}
}
diff --git a/JavaScriptCore/bytecode/CodeBlock.h b/JavaScriptCore/bytecode/CodeBlock.h
index 5298327..5b09b4a 100644
--- a/JavaScriptCore/bytecode/CodeBlock.h
+++ b/JavaScriptCore/bytecode/CodeBlock.h
@@ -102,7 +102,6 @@ namespace JSC {
{
}
- unsigned bytecodeOffset;
CodeLocationNearCall callReturnLocation;
CodeLocationDataLabelPtr hotPathBegin;
CodeLocationNearCall hotPathOther;
@@ -156,17 +155,6 @@ namespace JSC {
Structure* cachedPrototypeStructure;
};
- struct FunctionRegisterInfo {
- FunctionRegisterInfo(unsigned bytecodeOffset, int functionRegisterIndex)
- : bytecodeOffset(bytecodeOffset)
- , functionRegisterIndex(functionRegisterIndex)
- {
- }
-
- unsigned bytecodeOffset;
- int functionRegisterIndex;
- };
-
struct GlobalResolveInfo {
GlobalResolveInfo(unsigned bytecodeOffset)
: structure(0)
@@ -254,15 +242,6 @@ namespace JSC {
}
#endif
- struct ExceptionInfo : FastAllocBase {
- Vector<ExpressionRangeInfo> m_expressionInfo;
- Vector<LineInfo> m_lineInfo;
-
-#if ENABLE(JIT)
- Vector<CallReturnOffsetToBytecodeOffset> m_callReturnIndexVector;
-#endif
- };
-
class CodeBlock : public FastAllocBase {
friend class JIT;
protected:
@@ -307,8 +286,8 @@ namespace JSC {
}
HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset);
- int lineNumberForBytecodeOffset(CallFrame*, unsigned bytecodeOffset);
- void expressionRangeForBytecodeOffset(CallFrame*, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset);
+ int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
+ void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset);
#if ENABLE(JIT)
void addCaller(CallLinkInfo* caller)
@@ -345,11 +324,14 @@ namespace JSC {
return *(binaryChop<MethodCallLinkInfo, void*, getMethodCallLinkInfoReturnLocation>(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), returnAddress.value()));
}
- unsigned bytecodeOffset(CallFrame* callFrame, ReturnAddressPtr returnAddress)
+ unsigned bytecodeOffset(ReturnAddressPtr returnAddress)
{
- if (!reparseForExceptionInfoIfNecessary(callFrame))
+ if (!m_rareData)
+ return 1;
+ Vector<CallReturnOffsetToBytecodeOffset>& callIndices = m_rareData->m_callReturnIndexVector;
+ if (!callIndices.size())
return 1;
- return binaryChop<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callReturnIndexVector().begin(), callReturnIndexVector().size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
+ return binaryChop<CallReturnOffsetToBytecodeOffset, unsigned, getCallReturnOffset>(callIndices.begin(), callIndices.size(), getJITCode().offsetOf(returnAddress.value()))->bytecodeOffset;
}
#endif
#if ENABLE(INTERPRETER)
@@ -449,18 +431,36 @@ namespace JSC {
void addExceptionHandler(const HandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
HandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
- bool hasExceptionInfo() const { return m_exceptionInfo; }
- void clearExceptionInfo() { m_exceptionInfo.clear(); }
- PassOwnPtr<ExceptionInfo> extractExceptionInfo();
+ void addExpressionInfo(const ExpressionRangeInfo& expressionInfo)
+ {
+ createRareDataIfNecessary();
+ m_rareData->m_expressionInfo.append(expressionInfo);
+ }
- void addExpressionInfo(const ExpressionRangeInfo& expressionInfo) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_expressionInfo.append(expressionInfo); }
+ void addLineInfo(unsigned bytecodeOffset, int lineNo)
+ {
+ createRareDataIfNecessary();
+ Vector<LineInfo>& lineInfo = m_rareData->m_lineInfo;
+ if (!lineInfo.size() || lineInfo.last().lineNumber != lineNo) {
+ LineInfo info = { bytecodeOffset, lineNo };
+ lineInfo.append(info);
+ }
+ }
- size_t numberOfLineInfos() const { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_lineInfo.size(); }
- void addLineInfo(const LineInfo& lineInfo) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_lineInfo.append(lineInfo); }
- LineInfo& lastLineInfo() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_lineInfo.last(); }
+ bool hasExpressionInfo() { return m_rareData && m_rareData->m_expressionInfo.size(); }
+ bool hasLineInfo() { return m_rareData && m_rareData->m_lineInfo.size(); }
+ bool needsCallReturnIndices()
+ {
+ return m_rareData &&
+ (m_rareData->m_expressionInfo.size() || m_rareData->m_lineInfo.size() || m_rareData->m_exceptionHandlers.size());
+ }
#if ENABLE(JIT)
- Vector<CallReturnOffsetToBytecodeOffset>& callReturnIndexVector() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_callReturnIndexVector; }
+ Vector<CallReturnOffsetToBytecodeOffset>& callReturnIndexVector()
+ {
+ createRareDataIfNecessary();
+ return m_rareData->m_callReturnIndexVector;
+ }
#endif
// Constant Pool
@@ -528,8 +528,6 @@ namespace JSC {
void printPutByIdOp(ExecState*, int location, Vector<Instruction>::const_iterator&, const char* op) const;
#endif
- bool reparseForExceptionInfoIfNecessary(CallFrame*) WARN_UNUSED_RETURN;
-
void createRareDataIfNecessary()
{
if (!m_rareData)
@@ -580,8 +578,6 @@ namespace JSC {
SymbolTable* m_symbolTable;
- OwnPtr<ExceptionInfo> m_exceptionInfo;
-
struct RareData : FastAllocBase {
Vector<HandlerInfo> m_exceptionHandlers;
@@ -594,6 +590,14 @@ namespace JSC {
Vector<StringJumpTable> m_stringSwitchJumpTables;
EvalCodeCache m_evalCodeCache;
+
+ // Expression info - present if debugging.
+ Vector<ExpressionRangeInfo> m_expressionInfo;
+ // Line info - present if profiling or debugging.
+ Vector<LineInfo> m_lineInfo;
+#if ENABLE(JIT)
+ Vector<CallReturnOffsetToBytecodeOffset> m_callReturnIndexVector;
+#endif
};
OwnPtr<RareData> m_rareData;
};
@@ -668,12 +672,6 @@ namespace JSC {
}
};
- inline PassOwnPtr<ExceptionInfo> CodeBlock::extractExceptionInfo()
- {
- ASSERT(m_exceptionInfo);
- return m_exceptionInfo.release();
- }
-
inline Register& ExecState::r(int index)
{
CodeBlock* codeBlock = this->codeBlock();
diff --git a/JavaScriptCore/bytecode/SamplingTool.cpp b/JavaScriptCore/bytecode/SamplingTool.cpp
index 4614776..f47e698 100644
--- a/JavaScriptCore/bytecode/SamplingTool.cpp
+++ b/JavaScriptCore/bytecode/SamplingTool.cpp
@@ -337,7 +337,7 @@ void SamplingTool::dump(ExecState* exec)
if (blockPercent >= 1) {
//Instruction* code = codeBlock->instructions().begin();
- printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().utf8().data(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent);
+ printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().utf8().data(), codeBlock->lineNumberForBytecodeOffset(0), record->m_sampleCount, m_sampleCount, blockPercent);
if (i < 10) {
HashMap<unsigned,unsigned> lineCounts;
codeBlock->dump(exec);
@@ -347,7 +347,7 @@ void SamplingTool::dump(ExecState* exec)
int count = record->m_samples[op];
if (count) {
printf(" [% 4d] has sample count: % 4d\n", op, count);
- unsigned line = codeBlock->lineNumberForBytecodeOffset(exec, op);
+ unsigned line = codeBlock->lineNumberForBytecodeOffset(op);
lineCounts.set(line, (lineCounts.contains(line) ? lineCounts.get(line) : 0) + count);
}
}
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 0221cfa..26de0a1 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -153,11 +153,6 @@ void BytecodeGenerator::generate()
if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
symbolTable().clear();
-#if !ENABLE(OPCODE_SAMPLING)
- if (!m_regeneratingForExceptionInfo && !m_usesExceptions && (m_codeType == FunctionCode || m_codeType == EvalCode))
- m_codeBlock->clearExceptionInfo();
-#endif
-
m_codeBlock->shrinkToFit();
}
@@ -199,9 +194,10 @@ void BytecodeGenerator::preserveLastVar()
m_lastVar = &m_calleeRegisters.last();
}
-BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock)
- : m_shouldEmitDebugHooks(!!debugger)
+BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const ScopeChain& scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock)
+ : m_shouldEmitDebugHooks(scopeChain.globalObject()->debugger())
, m_shouldEmitProfileHooks(scopeChain.globalObject()->supportsProfiling())
+ , m_shouldEmitRichSourceInfo(scopeChain.globalObject()->supportsRichSourceInfo())
, m_scopeChain(&scopeChain)
, m_symbolTable(symbolTable)
, m_scopeNode(programNode)
@@ -217,7 +213,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d
, m_hasCreatedActivation(true)
, m_firstLazyFunction(0)
, m_lastLazyFunction(0)
- , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
+ , m_globalData(&scopeChain.globalObject()->globalData())
, m_lastOpcodeID(op_end)
#ifndef NDEBUG
, m_lastOpcodePosition(0)
@@ -293,9 +289,10 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d
codeBlock->m_numCapturedVars = codeBlock->m_numVars;
}
-BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock)
- : m_shouldEmitDebugHooks(!!debugger)
+BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const ScopeChain& scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock)
+ : m_shouldEmitDebugHooks(scopeChain.globalObject()->debugger())
, m_shouldEmitProfileHooks(scopeChain.globalObject()->supportsProfiling())
+ , m_shouldEmitRichSourceInfo(scopeChain.globalObject()->supportsRichSourceInfo())
, m_scopeChain(&scopeChain)
, m_symbolTable(symbolTable)
, m_scopeNode(functionBody)
@@ -310,7 +307,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
, m_hasCreatedActivation(false)
, m_firstLazyFunction(0)
, m_lastLazyFunction(0)
- , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
+ , m_globalData(&scopeChain.globalObject()->globalData())
, m_lastOpcodeID(op_end)
#ifndef NDEBUG
, m_lastOpcodePosition(0)
@@ -387,7 +384,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
}
}
- bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !debugger;
+ bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks;
if (!canLazilyCreateFunctions && !m_hasCreatedActivation) {
m_hasCreatedActivation = true;
emitOpcode(op_create_activation);
@@ -419,7 +416,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
}
- if (debugger)
+ if (m_shouldEmitDebugHooks)
codeBlock->m_numCapturedVars = codeBlock->m_numVars;
FunctionParameters& parameters = *functionBody->parameters();
@@ -457,9 +454,10 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
}
}
-BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock)
- : m_shouldEmitDebugHooks(!!debugger)
+BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const ScopeChain& scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock)
+ : m_shouldEmitDebugHooks(scopeChain.globalObject()->debugger())
, m_shouldEmitProfileHooks(scopeChain.globalObject()->supportsProfiling())
+ , m_shouldEmitRichSourceInfo(scopeChain.globalObject()->supportsRichSourceInfo())
, m_scopeChain(&scopeChain)
, m_symbolTable(symbolTable)
, m_scopeNode(evalNode)
@@ -474,7 +472,7 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge
, m_hasCreatedActivation(true)
, m_firstLazyFunction(0)
, m_lastLazyFunction(0)
- , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
+ , m_globalData(&scopeChain.globalObject()->globalData())
, m_lastOpcodeID(op_end)
#ifndef NDEBUG
, m_lastOpcodePosition(0)
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 499d232..a90f756 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -93,9 +93,9 @@ namespace JSC {
static void setDumpsGeneratedCode(bool dumpsGeneratedCode);
static bool dumpsGeneratedCode();
- BytecodeGenerator(ProgramNode*, const Debugger*, const ScopeChain&, SymbolTable*, ProgramCodeBlock*);
- BytecodeGenerator(FunctionBodyNode*, const Debugger*, const ScopeChain&, SymbolTable*, CodeBlock*);
- BytecodeGenerator(EvalNode*, const Debugger*, const ScopeChain&, SymbolTable*, EvalCodeBlock*);
+ BytecodeGenerator(ProgramNode*, const ScopeChain&, SymbolTable*, ProgramCodeBlock*);
+ BytecodeGenerator(FunctionBodyNode*, const ScopeChain&, SymbolTable*, CodeBlock*);
+ BytecodeGenerator(EvalNode*, const ScopeChain&, SymbolTable*, EvalCodeBlock*);
JSGlobalData* globalData() const { return m_globalData; }
const CommonIdentifiers& propertyNames() const { return *m_globalData->propertyNames; }
@@ -207,10 +207,8 @@ namespace JSC {
{
// Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
ASSERT(!dst || dst == ignoredResult() || !dst->isTemporary() || dst->refCount());
- if (!m_codeBlock->numberOfLineInfos() || m_codeBlock->lastLineInfo().lineNumber != n->lineNo()) {
- LineInfo info = { instructions().size(), n->lineNo() };
- m_codeBlock->addLineInfo(info);
- }
+ addLineInfo(n->lineNo());
+
if (m_emitNodeDepth >= s_maxEmitNodeDepth)
return emitThrowExpressionTooDeepException();
++m_emitNodeDepth;
@@ -226,10 +224,7 @@ namespace JSC {
void emitNodeInConditionContext(ExpressionNode* n, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
{
- if (!m_codeBlock->numberOfLineInfos() || m_codeBlock->lastLineInfo().lineNumber != n->lineNo()) {
- LineInfo info = { instructions().size(), n->lineNo() };
- m_codeBlock->addLineInfo(info);
- }
+ addLineInfo(n->lineNo());
if (m_emitNodeDepth >= s_maxEmitNodeDepth) {
emitThrowExpressionTooDeepException();
return;
@@ -240,7 +235,10 @@ namespace JSC {
}
void emitExpressionInfo(unsigned divot, unsigned startOffset, unsigned endOffset)
- {
+ {
+ if (!m_shouldEmitRichSourceInfo)
+ return;
+
divot -= m_codeBlock->sourceOffset();
if (divot > ExpressionRangeInfo::MaxDivot) {
// Overflow has occurred, we can only give line number info for errors for this region
@@ -504,6 +502,14 @@ namespace JSC {
return FunctionExecutable::create(globalData, body->ident(), body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
+ void addLineInfo(unsigned lineNo)
+ {
+#if !ENABLE(OPCODE_SAMPLING)
+ if (m_shouldEmitRichSourceInfo)
+#endif
+ m_codeBlock->addLineInfo(instructions().size(), lineNo);
+ }
+
RegisterID* emitInitLazyRegister(RegisterID*);
Vector<Instruction>& instructions() { return m_codeBlock->instructions(); }
@@ -520,6 +526,7 @@ namespace JSC {
bool m_shouldEmitDebugHooks;
bool m_shouldEmitProfileHooks;
+ bool m_shouldEmitRichSourceInfo;
const ScopeChain* m_scopeChain;
SymbolTable* m_symbolTable;
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index d75dca2..bdf54b9 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -587,13 +587,13 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
codeBlock = callerFrame->codeBlock();
#if ENABLE(JIT) && ENABLE(INTERPRETER)
if (callerFrame->globalData().canUseJIT())
- bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
+ bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC());
else
- bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnVPC());
+ bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC());
#elif ENABLE(JIT)
- bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
+ bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnPC());
#else
- bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnVPC());
+ bytecodeOffset = codeBlock->bytecodeOffset(callFrame->returnVPC());
#endif
callFrame = callerFrame;
@@ -604,12 +604,15 @@ static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception,
{
exception->clearAppendSourceToMessage();
+ if (!callFrame->codeBlock()->hasExpressionInfo())
+ return;
+
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
CodeBlock* codeBlock = callFrame->codeBlock();
- codeBlock->expressionRangeForBytecodeOffset(callFrame, bytecodeOffset, divotPoint, startOffset, endOffset);
+ codeBlock->expressionRangeForBytecodeOffset(bytecodeOffset, divotPoint, startOffset, endOffset);
int expressionStart = divotPoint - startOffset;
int expressionStop = divotPoint + endOffset;
@@ -648,7 +651,7 @@ static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception,
exception->putDirect(globalData->propertyNames->message, jsString(globalData, message));
}
-NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset, bool explicitThrow)
+NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset)
{
CodeBlock* codeBlock = callFrame->codeBlock();
bool isInterrupt = false;
@@ -656,13 +659,18 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
// Set up the exception object
if (exceptionValue.isObject()) {
JSObject* exception = asObject(exceptionValue);
- if (!explicitThrow && exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage())
+
+ if (exception->isErrorInstance() && static_cast<ErrorInstance*>(exception)->appendSourceToMessage())
appendSourceToError(callFrame, static_cast<ErrorInstance*>(exception), bytecodeOffset);
- // FIXME: should only really be adding these properties to VM generated exceptions,
- // but the inspector currently requires these for all thrown objects.
- if (!hasErrorInfo(callFrame, exception))
- addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset), codeBlock->ownerExecutable()->source());
+ // Using hasExpressionInfo to imply we are interested in rich exception info.
+ if (codeBlock->hasExpressionInfo() && !hasErrorInfo(callFrame, exception)) {
+ ASSERT(codeBlock->hasLineInfo());
+
+ // FIXME: should only really be adding these properties to VM generated exceptions,
+ // but the inspector currently requires these for all thrown objects.
+ addErrorInfo(callFrame, exception, codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), codeBlock->ownerExecutable()->source());
+ }
ComplType exceptionType = exception->exceptionType();
isInterrupt = exceptionType == Interrupted || exceptionType == Terminated;
@@ -671,7 +679,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
bool hasHandler = codeBlock->handlerForBytecodeOffset(bytecodeOffset);
- debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset), hasHandler);
+ debugger->exception(debuggerCallFrame, codeBlock->ownerExecutable()->sourceID(), codeBlock->lineNumberForBytecodeOffset(bytecodeOffset), hasHandler);
}
// Calculate an exception handler vPC, unwinding call frames as necessary.
@@ -4603,7 +4611,7 @@ skip_id_custom_self:
int ex = vPC[1].u.operand;
exceptionValue = callFrame->r(ex).jsValue();
- handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin(), true);
+ handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin());
if (!handler)
return throwError(callFrame, exceptionValue);
@@ -4774,7 +4782,7 @@ skip_id_custom_self:
// cannot fathom if we don't assign to the exceptionValue before branching)
exceptionValue = createInterruptedExecutionException(globalData);
}
- handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin(), false);
+ handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin());
if (!handler)
return throwError(callFrame, exceptionValue);
@@ -4849,15 +4857,15 @@ void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intp
unsigned bytecodeOffset = 0;
#if ENABLE(INTERPRETER)
if (!callerFrame->globalData().canUseJIT())
- bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnVPC());
+ bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnVPC());
#if ENABLE(JIT)
else
- bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
+ bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
#endif
#else
- bytecodeOffset = callerCodeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
+ bytecodeOffset = callerCodeBlock->bytecodeOffset(callFrame->returnPC());
#endif
- lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(callerFrame, bytecodeOffset - 1);
+ lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(bytecodeOffset - 1);
sourceID = callerCodeBlock->ownerExecutable()->sourceID();
sourceURL = callerCodeBlock->ownerExecutable()->sourceURL();
function = callerFrame->callee();
diff --git a/JavaScriptCore/interpreter/Interpreter.h b/JavaScriptCore/interpreter/Interpreter.h
index 2bc403e..47790cf 100644
--- a/JavaScriptCore/interpreter/Interpreter.h
+++ b/JavaScriptCore/interpreter/Interpreter.h
@@ -108,7 +108,7 @@ namespace JSC {
SamplingTool* sampler() { return m_sampler.get(); }
NEVER_INLINE JSValue callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset);
- NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset, bool);
+ NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset);
NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
void dumpSampleData(ExecState* exec);
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
index 3f2ec59..01401a7 100644
--- a/JavaScriptCore/jit/JIT.cpp
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -552,7 +552,7 @@ JITCode JIT::privateCompile(CodePtr* functionEntryArityCheck)
patchBuffer.link(iter->from, FunctionPtr(iter->to));
}
- if (m_codeBlock->hasExceptionInfo()) {
+ if (m_codeBlock->needsCallReturnIndices()) {
m_codeBlock->callReturnIndexVector().reserveCapacity(m_calls.size());
for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter)
m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeOffset(patchBuffer.returnAddressOffset(iter->from), iter->bytecodeOffset));
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index 36d36a2..0faff85 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -1067,13 +1067,13 @@ struct ExceptionHandler {
void* catchRoutine;
CallFrame* callFrame;
};
-static ExceptionHandler jitThrow(JSGlobalData* globalData, CallFrame* callFrame, JSValue exceptionValue, ReturnAddressPtr faultLocation, bool explicitThrow)
+static ExceptionHandler jitThrow(JSGlobalData* globalData, CallFrame* callFrame, JSValue exceptionValue, ReturnAddressPtr faultLocation)
{
ASSERT(exceptionValue);
- unsigned vPCIndex = callFrame->codeBlock()->bytecodeOffset(callFrame, faultLocation);
+ unsigned vPCIndex = callFrame->codeBlock()->bytecodeOffset(faultLocation);
globalData->exception = JSValue();
- HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, explicitThrow); // This may update callFrame & exceptionValue!
+ HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex); // This may update callFrame & exceptionValue!
globalData->exception = exceptionValue;
void* catchRoutine = handler ? handler->nativeCode.executableAddress() : FunctionPtr(ctiOpThrowNotCaught).value();
@@ -1384,7 +1384,7 @@ DEFINE_STUB_FUNCTION(void*, register_file_check)
// Rewind to the previous call frame because op_call already optimistically
// moved the call frame forward.
CallFrame* oldCallFrame = callFrame->callerFrame();
- ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), ReturnAddressPtr(oldCallFrame->returnPC()), false);
+ ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), ReturnAddressPtr(oldCallFrame->returnPC()));
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
callFrame = handler.callFrame;
}
@@ -2006,7 +2006,7 @@ DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
if (!stackFrame.registerFile->grow(newEnd)) {
// Rewind to the previous call frame because op_call already optimistically
// moved the call frame forward.
- ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false);
+ ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
}
@@ -2021,7 +2021,7 @@ DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
if (!stackFrame.registerFile->grow(newEnd)) {
// Rewind to the previous call frame because op_call already optimistically
// moved the call frame forward.
- ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false);
+ ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
}
@@ -2065,7 +2065,7 @@ DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
if (!stackFrame.registerFile->grow(newEnd)) {
// Rewind to the previous call frame because op_call already optimistically
// moved the call frame forward.
- ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false);
+ ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
}
@@ -2080,7 +2080,7 @@ DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
if (!stackFrame.registerFile->grow(newEnd)) {
// Rewind to the previous call frame because op_call already optimistically
// moved the call frame forward.
- ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc, false);
+ ExceptionHandler handler = jitThrow(stackFrame.globalData, oldCallFrame, createStackOverflowError(oldCallFrame), pc);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
}
@@ -3238,7 +3238,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
DEFINE_STUB_FUNCTION(void*, op_throw)
{
STUB_INIT_STACK_FRAME(stackFrame);
- ExceptionHandler handler = jitThrow(stackFrame.globalData, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS, true);
+ ExceptionHandler handler = jitThrow(stackFrame.globalData, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
}
@@ -3595,7 +3595,7 @@ DEFINE_STUB_FUNCTION(void*, vm_throw)
{
STUB_INIT_STACK_FRAME(stackFrame);
JSGlobalData* globalData = stackFrame.globalData;
- ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation, false);
+ ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation);
STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
return handler.callFrame;
}
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index f341646..3fbd278 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -1051,8 +1051,6 @@ void Heap::markRoots()
MarkedArgumentBuffer::markLists(markStack, *m_markListSet);
if (m_globalData->exception)
markStack.append(m_globalData->exception);
- if (m_globalData->functionCodeBlockBeingReparsed)
- m_globalData->functionCodeBlockBeingReparsed->markAggregate(markStack);
if (m_globalData->firstStringifierToMark)
JSONObject::markStringifiers(markStack, m_globalData->firstStringifierToMark);
diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp
index 2ad4b2d..f229f96 100644
--- a/JavaScriptCore/runtime/Executable.cpp
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -108,7 +108,7 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope
ASSERT(!m_evalCodeBlock);
m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), globalObject->debugger(), scopeChain, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get())));
+ OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChain, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get())));
generator->generate();
evalNode->destroyData();
@@ -156,7 +156,7 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc
JSGlobalObject* globalObject = scopeChain.globalObject();
m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock.get())));
+ OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock.get())));
generator->generate();
programNode->destroyData();
@@ -193,7 +193,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
ASSERT(!m_codeBlockForCall);
m_codeBlockForCall = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), false));
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlockForCall->symbolTable(), m_codeBlockForCall.get())));
+ OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scopeChain, m_codeBlockForCall->symbolTable(), m_codeBlockForCall.get())));
generator->generate();
m_numParametersForCall = m_codeBlockForCall->m_numParameters;
ASSERT(m_numParametersForCall);
@@ -234,7 +234,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
ASSERT(!m_codeBlockForConstruct);
m_codeBlockForConstruct = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), true));
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlockForConstruct->symbolTable(), m_codeBlockForConstruct.get())));
+ OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scopeChain, m_codeBlockForConstruct->symbolTable(), m_codeBlockForConstruct.get())));
generator->generate();
m_numParametersForConstruct = m_codeBlockForConstruct->m_numParameters;
ASSERT(m_numParametersForConstruct);
@@ -264,72 +264,6 @@ void FunctionExecutable::markAggregate(MarkStack& markStack)
m_codeBlockForConstruct->markAggregate(markStack);
}
-PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
-{
- JSObject* exception = 0;
- JSGlobalData* globalData = scopeChainNode->globalData;
- RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(scopeChainNode->globalObject, 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
- if (!newFunctionBody)
- return PassOwnPtr<ExceptionInfo>();
- ASSERT(newFunctionBody->isStrictMode() == isStrictMode());
- if (m_forceUsesArguments)
- newFunctionBody->setUsesArguments();
- newFunctionBody->finishParsing(m_parameters, m_name);
-
- ScopeChain scopeChain(scopeChainNode);
- JSGlobalObject* globalObject = scopeChain.globalObject();
-
- OwnPtr<CodeBlock> newCodeBlock(adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), codeBlock->m_isConstructor)));
- globalData->functionCodeBlockBeingReparsed = newCodeBlock.get();
-
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(newFunctionBody.get(), globalObject->debugger(), scopeChain, newCodeBlock->symbolTable(), newCodeBlock.get())));
- generator->setRegeneratingForExceptionInfo(static_cast<FunctionCodeBlock*>(codeBlock));
- generator->generate();
-
- ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
-
-#if ENABLE(JIT)
- if (globalData->canUseJIT()) {
- JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get(), 0, codeBlock->m_isConstructor ? generatedJITCodeForConstruct().start() : generatedJITCodeForCall().start());
- ASSERT(codeBlock->m_isConstructor ? newJITCode.size() == generatedJITCodeForConstruct().size() : newJITCode.size() == generatedJITCodeForCall().size());
- }
-#endif
-
- globalData->functionCodeBlockBeingReparsed = 0;
-
- return newCodeBlock->extractExceptionInfo();
-}
-
-PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
-{
- JSObject* exception = 0;
- JSGlobalData* globalData = scopeChainNode->globalData;
- RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(scopeChainNode->globalObject, 0, 0, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
- ASSERT(newEvalBody->isStrictMode() == isStrictMode());
- if (!newEvalBody)
- return PassOwnPtr<ExceptionInfo>();
-
- ScopeChain scopeChain(scopeChainNode);
- JSGlobalObject* globalObject = scopeChain.globalObject();
-
- OwnPtr<EvalCodeBlock> newCodeBlock(adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth())));
-
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(newEvalBody.get(), globalObject->debugger(), scopeChain, newCodeBlock->symbolTable(), newCodeBlock.get())));
- generator->setRegeneratingForExceptionInfo(static_cast<EvalCodeBlock*>(codeBlock));
- generator->generate();
-
- ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
-
-#if ENABLE(JIT)
- if (globalData->canUseJIT()) {
- JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get(), 0, generatedJITCodeForCall().start());
- ASSERT(newJITCode.size() == generatedJITCodeForCall().size());
- }
-#endif
-
- return newCodeBlock->extractExceptionInfo();
-}
-
void FunctionExecutable::recompile(ExecState*)
{
m_codeBlockForCall.clear();
@@ -376,10 +310,4 @@ UString FunctionExecutable::paramString() const
return builder.toUString();
}
-PassOwnPtr<ExceptionInfo> ProgramExecutable::reparseExceptionInfo(ScopeChainNode*, CodeBlock*)
-{
- // CodeBlocks for program code are transient and therefore do not gain from from throwing out their exception information.
- return PassOwnPtr<ExceptionInfo>();
-}
-
}
diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h
index 4c4ca56..14ed927 100644
--- a/JavaScriptCore/runtime/Executable.h
+++ b/JavaScriptCore/runtime/Executable.h
@@ -177,8 +177,6 @@ namespace JSC {
bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
bool isStrictMode() const { return m_features & StrictModeFeature; }
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*) = 0;
-
protected:
void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
{
@@ -229,8 +227,6 @@ namespace JSC {
JSObject* compileInternal(ExecState*, ScopeChainNode*);
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*);
-
OwnPtr<EvalCodeBlock> m_evalCodeBlock;
};
@@ -272,8 +268,6 @@ namespace JSC {
JSObject* compileInternal(ExecState*, ScopeChainNode*);
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*);
-
OwnPtr<ProgramCodeBlock> m_programCodeBlock;
};
@@ -365,8 +359,6 @@ namespace JSC {
JSObject* compileForCallInternal(ExecState*, ScopeChainNode*);
JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*);
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*);
-
unsigned m_numCapturedVariables : 31;
bool m_forceUsesArguments : 1;
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 58b844c..9948877 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -141,7 +141,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, heap(this)
, head(0)
, dynamicGlobalObject(0)
- , functionCodeBlockBeingReparsed(0)
, firstStringifierToMark(0)
, markStack(jsArrayVPtr)
, cachedUTCOffset(NaN)
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 153a4e5..6c3cf7e 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -116,6 +116,7 @@ namespace JSC {
};
bool isSharedInstance() { return globalDataType == APIShared; }
+ bool usingAPI() { return globalDataType != Default; }
static bool sharedInstanceExists();
static JSGlobalData& sharedInstance();
@@ -205,7 +206,6 @@ namespace JSC {
HashSet<JSObject*> arrayVisitedElements;
- CodeBlock* functionCodeBlockBeingReparsed;
Stringifier* firstStringifierToMark;
MarkStack markStack;
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index 93a1b88..714999f 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -254,9 +254,10 @@ namespace JSC {
Debugger* debugger() const { return d()->debugger; }
void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
-
+
virtual bool supportsProfiling() const { return false; }
-
+ virtual bool supportsRichSourceInfo() const { return true; }
+
ScopeChain& globalScopeChain() { return d()->globalScopeChain; }
virtual bool isGlobalObject() const { return true; }
@@ -276,7 +277,7 @@ namespace JSC {
void resetPrototype(JSValue prototype);
- JSGlobalData& globalData() { return *d()->globalData.get(); }
+ JSGlobalData& globalData() const { return *d()->globalData.get(); }
JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
static PassRefPtr<Structure> createStructure(JSValue prototype)
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index cf84a9a..5d1c3c3 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,19 @@
+2010-11-18 Gavin Barraclough <barraclough at apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 49708 - Stop recompiling functions to regenerate exception info.
+
+ Instead only hold info as necessary – keep divot info is the inspector
+ is enabled, line number info is debugging or profiling, and handler
+ info for functions with try/catch.
+
+ * bindings/js/JSDOMWindowBase.cpp:
+ (WebCore::JSDOMWindowBase::supportsRichSourceInfo):
+ - report to JSC whether the inspector is enabled - in which
+ case we will generate better error messages on exceptions.
+ * bindings/js/JSDOMWindowBase.h:
+
2010-11-18 Jian Li <jianli at chromium.org>
Reviewed by Kenneth Russell.
diff --git a/WebCore/bindings/js/JSDOMWindowBase.cpp b/WebCore/bindings/js/JSDOMWindowBase.cpp
index e2b50d0..a72ece6 100644
--- a/WebCore/bindings/js/JSDOMWindowBase.cpp
+++ b/WebCore/bindings/js/JSDOMWindowBase.cpp
@@ -118,6 +118,26 @@ bool JSDOMWindowBase::supportsProfiling() const
#endif
}
+bool JSDOMWindowBase::supportsRichSourceInfo() const
+{
+#if !ENABLE(JAVASCRIPT_DEBUGGER) || !ENABLE(INSPECTOR)
+ return false;
+#else
+ Frame* frame = impl()->frame();
+ if (!frame)
+ return false;
+
+ Page* page = frame->page();
+ if (!page)
+ return false;
+
+ bool enabled = page->inspectorController()->enabled();
+ ASSERT(enabled || !debugger());
+ ASSERT(enabled || !supportsProfiling());
+ return enabled;
+#endif
+}
+
bool JSDOMWindowBase::shouldInterruptScript() const
{
ASSERT(impl()->frame());
diff --git a/WebCore/bindings/js/JSDOMWindowBase.h b/WebCore/bindings/js/JSDOMWindowBase.h
index cafca73..fbef808 100644
--- a/WebCore/bindings/js/JSDOMWindowBase.h
+++ b/WebCore/bindings/js/JSDOMWindowBase.h
@@ -60,6 +60,7 @@ namespace WebCore {
virtual JSC::ExecState* globalExec();
virtual bool supportsProfiling() const;
+ virtual bool supportsRichSourceInfo() const;
virtual bool shouldInterruptScript() const;
bool allowsAccessFrom(JSC::ExecState*) const;
diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index 23f24a6..e278d36 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,18 @@
+2010-11-18 Gavin Barraclough <barraclough at apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 49708 - Stop recompiling functions to regenerate exception info.
+
+ Instead only hold info as necessary – keep divot info is the inspector
+ is enabled, line number info is debugging or profiling, and handler
+ info for functions with try/catch.
+
+ * DumpRenderTree/mac/DumpRenderTree.mm:
+ (shouldEnableDeveloperExtras):
+ - always enable the developer tools from DRT, to ensure we
+ produce rich error messages on JavaScript exceptions.
+
2010-11-18 Kinuko Yasuda <kinuko at chromium.org>
Reviewed by Ojan Vafai.
diff --git a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
index e280fab..68b4c2b 100644
--- a/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
+++ b/WebKitTools/DumpRenderTree/mac/DumpRenderTree.mm
@@ -989,7 +989,7 @@ static bool shouldOpenWebInspector(const char* pathOrURL)
static bool shouldEnableDeveloperExtras(const char* pathOrURL)
{
- return shouldOpenWebInspector(pathOrURL) || strstr(pathOrURL, "inspector-enabled/");
+ return true;
}
static void resetWebViewToConsistentStateBeforeTesting()
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list