[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