[JSC] Shrink size of FunctionExecutable
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Feb 2019 21:02:27 +0000 (21:02 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 4 Feb 2019 21:02:27 +0000 (21:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=194191

Reviewed by Michael Saboff.

This patch reduces the size of FunctionExecutable. Since it is allocated in IsoSubspace, reducing the size directly
improves the allocation efficiency.

1. ScriptExecutable (base class of FunctionExecutable) has several members, but it is meaningful only in FunctionExecutable.
   We remove this from ScriptExecutable, and move it to FunctionExecutable.

2. FunctionExecutable has several data which are rarely used. One for FunctionOverrides functionality, which is typically
   used for JSC debugging purpose, and another is TypeSet and offsets for type profiler. We move them to RareData and reduce
   the size of FunctionExecutable in the common case.

This patch changes the size of FunctionExecutable from 176 to 144.

* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpSource):
(JSC::CodeBlock::finishCreation):
* dfg/DFGNode.h:
(JSC::DFG::Node::OpInfoWrapper::as const):
* interpreter/StackVisitor.cpp:
(JSC::StackVisitor::Frame::computeLineAndColumn const):
* runtime/ExecutableBase.h:
* runtime/FunctionExecutable.cpp:
(JSC::FunctionExecutable::FunctionExecutable):
(JSC::FunctionExecutable::ensureRareDataSlow):
* runtime/FunctionExecutable.h:
* runtime/Intrinsic.h:
* runtime/ModuleProgramExecutable.cpp:
(JSC::ModuleProgramExecutable::ModuleProgramExecutable):
* runtime/ProgramExecutable.cpp:
(JSC::ProgramExecutable::ProgramExecutable):
* runtime/ScriptExecutable.cpp:
(JSC::ScriptExecutable::ScriptExecutable):
(JSC::ScriptExecutable::overrideLineNumber const):
(JSC::ScriptExecutable::typeProfilingStartOffset const):
(JSC::ScriptExecutable::typeProfilingEndOffset const):
* runtime/ScriptExecutable.h:
(JSC::ScriptExecutable::firstLine const):
(JSC::ScriptExecutable::setOverrideLineNumber): Deleted.
(JSC::ScriptExecutable::hasOverrideLineNumber const): Deleted.
(JSC::ScriptExecutable::overrideLineNumber const): Deleted.
(JSC::ScriptExecutable::typeProfilingStartOffset const): Deleted.
(JSC::ScriptExecutable::typeProfilingEndOffset const): Deleted.
* runtime/StackFrame.cpp:
(JSC::StackFrame::computeLineAndColumn const):
* tools/JSDollarVM.cpp:
(JSC::functionReturnTypeFor):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@240938 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/CodeBlock.cpp
Source/JavaScriptCore/dfg/DFGNode.h
Source/JavaScriptCore/interpreter/StackVisitor.cpp
Source/JavaScriptCore/runtime/ExecutableBase.h
Source/JavaScriptCore/runtime/FunctionExecutable.cpp
Source/JavaScriptCore/runtime/FunctionExecutable.h
Source/JavaScriptCore/runtime/Intrinsic.h
Source/JavaScriptCore/runtime/ModuleProgramExecutable.cpp
Source/JavaScriptCore/runtime/ProgramExecutable.cpp
Source/JavaScriptCore/runtime/ScriptExecutable.cpp
Source/JavaScriptCore/runtime/ScriptExecutable.h
Source/JavaScriptCore/runtime/StackFrame.cpp
Source/JavaScriptCore/tools/JSDollarVM.cpp

index 5efd343..abd0975 100644 (file)
@@ -1,3 +1,56 @@
+2019-02-04  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Shrink size of FunctionExecutable
+        https://bugs.webkit.org/show_bug.cgi?id=194191
+
+        Reviewed by Michael Saboff.
+
+        This patch reduces the size of FunctionExecutable. Since it is allocated in IsoSubspace, reducing the size directly
+        improves the allocation efficiency.
+
+        1. ScriptExecutable (base class of FunctionExecutable) has several members, but it is meaningful only in FunctionExecutable.
+           We remove this from ScriptExecutable, and move it to FunctionExecutable.
+
+        2. FunctionExecutable has several data which are rarely used. One for FunctionOverrides functionality, which is typically
+           used for JSC debugging purpose, and another is TypeSet and offsets for type profiler. We move them to RareData and reduce
+           the size of FunctionExecutable in the common case.
+
+        This patch changes the size of FunctionExecutable from 176 to 144.
+
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpSource):
+        (JSC::CodeBlock::finishCreation):
+        * dfg/DFGNode.h:
+        (JSC::DFG::Node::OpInfoWrapper::as const):
+        * interpreter/StackVisitor.cpp:
+        (JSC::StackVisitor::Frame::computeLineAndColumn const):
+        * runtime/ExecutableBase.h:
+        * runtime/FunctionExecutable.cpp:
+        (JSC::FunctionExecutable::FunctionExecutable):
+        (JSC::FunctionExecutable::ensureRareDataSlow):
+        * runtime/FunctionExecutable.h:
+        * runtime/Intrinsic.h:
+        * runtime/ModuleProgramExecutable.cpp:
+        (JSC::ModuleProgramExecutable::ModuleProgramExecutable):
+        * runtime/ProgramExecutable.cpp:
+        (JSC::ProgramExecutable::ProgramExecutable):
+        * runtime/ScriptExecutable.cpp:
+        (JSC::ScriptExecutable::ScriptExecutable):
+        (JSC::ScriptExecutable::overrideLineNumber const):
+        (JSC::ScriptExecutable::typeProfilingStartOffset const):
+        (JSC::ScriptExecutable::typeProfilingEndOffset const):
+        * runtime/ScriptExecutable.h:
+        (JSC::ScriptExecutable::firstLine const):
+        (JSC::ScriptExecutable::setOverrideLineNumber): Deleted.
+        (JSC::ScriptExecutable::hasOverrideLineNumber const): Deleted.
+        (JSC::ScriptExecutable::overrideLineNumber const): Deleted.
+        (JSC::ScriptExecutable::typeProfilingStartOffset const): Deleted.
+        (JSC::ScriptExecutable::typeProfilingEndOffset const): Deleted.
+        * runtime/StackFrame.cpp:
+        (JSC::StackFrame::computeLineAndColumn const):
+        * tools/JSDollarVM.cpp:
+        (JSC::functionReturnTypeFor):
+
 2019-02-04  Mark Lam  <mark.lam@apple.com>
 
         DFG's doesGC() is incorrect about the SameValue node's behavior.
index 5340f91..0707789 100644 (file)
@@ -231,7 +231,7 @@ void CodeBlock::dumpSource(PrintStream& out)
         FunctionExecutable* functionExecutable = reinterpret_cast<FunctionExecutable*>(executable);
         StringView source = functionExecutable->source().provider()->getRange(
             functionExecutable->parametersStartOffset(),
-            functionExecutable->typeProfilingEndOffset() + 1); // Type profiling end offset is the character before the '}'.
+            functionExecutable->typeProfilingEndOffset(*vm()) + 1); // Type profiling end offset is the character before the '}'.
         
         out.print("function ", inferredName(), source);
         return;
@@ -411,7 +411,7 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink
     auto throwScope = DECLARE_THROW_SCOPE(vm);
 
     if (vm.typeProfiler() || vm.controlFlowProfiler())
-        vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(), ownerExecutable->typeProfilingEndOffset());
+        vm.functionHasExecutedCache()->removeUnexecutedRange(ownerExecutable->sourceID(), ownerExecutable->typeProfilingStartOffset(vm), ownerExecutable->typeProfilingEndOffset(vm));
 
     setConstantRegisters(unlinkedCodeBlock->constantRegisters(), unlinkedCodeBlock->constantsSourceCodeRepresentation());
     RETURN_IF_EXCEPTION(throwScope, false);
@@ -758,7 +758,7 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink
                     // the user's program, give the type profiler some range to identify these return statements.
                     // Currently, the text offset that is used as identification is "f" in the function keyword
                     // and is stored on TypeLocation's m_divotForFunctionOffsetIfReturnStatement member variable.
-                    divotStart = divotEnd = ownerExecutable->typeProfilingStartOffset();
+                    divotStart = divotEnd = ownerExecutable->typeProfilingStartOffset(vm);
                     shouldAnalyze = true;
                 }
                 break;
@@ -771,7 +771,7 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink
             bool isNewLocation = locationPair.second;
 
             if (bytecode.m_flag == ProfileTypeBytecodeFunctionReturnStatement)
-                location->m_divotForFunctionOffsetIfReturnStatement = ownerExecutable->typeProfilingStartOffset();
+                location->m_divotForFunctionOffsetIfReturnStatement = ownerExecutable->typeProfilingStartOffset(vm);
 
             if (shouldAnalyze && isNewLocation)
                 vm.typeProfiler()->insertNewLocation(location);
index 4c7deb6..fb3679a 100644 (file)
@@ -2987,7 +2987,7 @@ private:
             return static_cast<T>(u.constPointer);
         }
         template <typename T>
-        ALWAYS_INLINE auto as() const -> typename std::enable_if<(std::is_integral<T>::value || std::is_enum<T>::value) && sizeof(T) == 4, T>::type
+        ALWAYS_INLINE auto as() const -> typename std::enable_if<(std::is_integral<T>::value || std::is_enum<T>::value) && sizeof(T) <= 4, T>::type
         {
             return static_cast<T>(u.int32);
         }
index 2e110b7..2aa3f30 100644 (file)
@@ -406,8 +406,8 @@ void StackVisitor::Frame::computeLineAndColumn(unsigned& line, unsigned& column)
     line = divotLine + codeBlock->ownerScriptExecutable()->firstLine();
     column = divotColumn + (divotLine ? 1 : codeBlock->firstLineColumnOffset());
 
-    if (codeBlock->ownerScriptExecutable()->hasOverrideLineNumber())
-        line = codeBlock->ownerScriptExecutable()->overrideLineNumber();
+    if (Optional<int> overrideLineNumber = codeBlock->ownerScriptExecutable()->overrideLineNumber(*codeBlock->vm()))
+        line = overrideLineNumber.value();
 }
 
 void StackVisitor::Frame::retrieveExpressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column) const
index c719ffb..296da1b 100644 (file)
@@ -229,11 +229,11 @@ public:
     void dump(PrintStream&) const;
         
 protected:
-    Intrinsic m_intrinsic;
     RefPtr<JITCode> m_jitCodeForCall;
     RefPtr<JITCode> m_jitCodeForConstruct;
     MacroAssemblerCodePtr<JSEntryPtrTag> m_jitCodeForCallWithArityCheck;
     MacroAssemblerCodePtr<JSEntryPtrTag> m_jitCodeForConstructWithArityCheck;
+    Intrinsic m_intrinsic;
 };
 
 } // namespace JSC
index b39a8d1..4c91ca2 100644 (file)
@@ -50,9 +50,6 @@ FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, Unlinke
     m_lastLine = lastLine;
     ASSERT(endColumn != UINT_MAX);
     m_endColumn = endColumn;
-    m_parametersStartOffset = unlinkedExecutable->parametersStartOffset();
-    m_typeProfilingStartOffset = unlinkedExecutable->typeProfilingStartOffset();
-    m_typeProfilingEndOffset = unlinkedExecutable->typeProfilingEndOffset();
     if (VM::canUseJIT())
         new (&m_singletonFunction) WriteBarrier<InferredValue>();
     else
@@ -111,4 +108,14 @@ FunctionExecutable* FunctionExecutable::fromGlobalCode(
     return unlinkedExecutable->link(exec.vm(), source, overrideLineNumber);
 }
 
+FunctionExecutable::RareData& FunctionExecutable::ensureRareDataSlow()
+{
+    ASSERT(!m_rareData);
+    m_rareData = std::make_unique<RareData>();
+    m_rareData->m_parametersStartOffset = m_unlinkedExecutable->parametersStartOffset();
+    m_rareData->m_typeProfilingStartOffset = m_unlinkedExecutable->typeProfilingStartOffset();
+    m_rareData->m_typeProfilingEndOffset = m_unlinkedExecutable->typeProfilingEndOffset();
+    return *m_rareData;
+}
+
 } // namespace JSC
index 5b14e2b..013696a 100644 (file)
@@ -29,6 +29,7 @@
 #include "ScriptExecutable.h"
 #include "SourceCode.h"
 #include <wtf/Box.h>
+#include <wtf/Markable.h>
 
 namespace JSC {
 
@@ -122,10 +123,10 @@ public:
 
     RefPtr<TypeSet> returnStatementTypeSet() 
     {
-        if (!m_returnStatementTypeSet)
-            m_returnStatementTypeSet = TypeSet::create();
-
-        return m_returnStatementTypeSet;
+        RareData& rareData = ensureRareData();
+        if (!rareData.m_returnStatementTypeSet)
+            rareData.m_returnStatementTypeSet = TypeSet::create();
+        return rareData.m_returnStatementTypeSet;
     }
         
     FunctionMode functionMode() { return m_unlinkedExecutable->functionMode(); }
@@ -172,13 +173,50 @@ public:
         return Structure::create(vm, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), info());
     }
 
-    unsigned parametersStartOffset() const { return m_parametersStartOffset; }
+    void setOverrideLineNumber(int overrideLineNumber)
+    {
+        if (overrideLineNumber == -1) {
+            if (UNLIKELY(m_rareData))
+                m_rareData->m_overrideLineNumber = WTF::nullopt;
+            return;
+        }
+        ensureRareData().m_overrideLineNumber = overrideLineNumber;
+    }
+
+    Optional<int> overrideLineNumber() const
+    {
+        if (UNLIKELY(m_rareData))
+            return m_rareData->m_overrideLineNumber;
+        return WTF::nullopt;
+    }
+
+    unsigned typeProfilingStartOffset(VM&) const
+    {
+        if (UNLIKELY(m_rareData))
+            return m_rareData->m_typeProfilingStartOffset;
+        return m_unlinkedExecutable->typeProfilingStartOffset();
+    }
+
+    unsigned typeProfilingEndOffset(VM&) const
+    {
+        if (UNLIKELY(m_rareData))
+            return m_rareData->m_typeProfilingEndOffset;
+        return m_unlinkedExecutable->typeProfilingEndOffset();
+    }
+
+    unsigned parametersStartOffset() const
+    {
+        if (UNLIKELY(m_rareData))
+            return m_rareData->m_parametersStartOffset;
+        return m_unlinkedExecutable->parametersStartOffset();
+    }
 
     void overrideParameterAndTypeProfilingStartEndOffsets(unsigned parametersStartOffset, unsigned typeProfilingStartOffset, unsigned typeProfilingEndOffset)
     {
-        m_parametersStartOffset = parametersStartOffset;
-        m_typeProfilingStartOffset = typeProfilingStartOffset;
-        m_typeProfilingEndOffset = typeProfilingEndOffset;
+        auto& rareData = ensureRareData();
+        rareData.m_parametersStartOffset = parametersStartOffset;
+        rareData.m_typeProfilingStartOffset = typeProfilingStartOffset;
+        rareData.m_typeProfilingEndOffset = typeProfilingEndOffset;
     }
 
     DECLARE_INFO;
@@ -237,12 +275,28 @@ private:
     void finishCreation(VM&);
 
     friend class ScriptExecutable;
-    
-    unsigned m_parametersStartOffset;
+
+    struct RareData {
+        WTF_MAKE_STRUCT_FAST_ALLOCATED;
+        Markable<int, IntegralMarkableTraits<int, -1>> m_overrideLineNumber;
+        unsigned m_parametersStartOffset { 0 };
+        unsigned m_typeProfilingStartOffset { UINT_MAX };
+        unsigned m_typeProfilingEndOffset { UINT_MAX };
+        RefPtr<TypeSet> m_returnStatementTypeSet;
+    };
+
+    RareData& ensureRareData()
+    {
+        if (LIKELY(m_rareData))
+            return *m_rareData;
+        return ensureRareDataSlow();
+    }
+    RareData& ensureRareDataSlow();
+
+    std::unique_ptr<RareData> m_rareData;
     WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
     WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForCall;
     WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForConstruct;
-    RefPtr<TypeSet> m_returnStatementTypeSet;
     union {
         WriteBarrier<InferredValue> m_singletonFunction;
         WatchpointState m_singletonFunctionState;
index b47f46d..93d3643 100644 (file)
@@ -27,7 +27,7 @@
 
 namespace JSC {
 
-enum Intrinsic {
+enum Intrinsic : uint8_t {
     // Call intrinsics.
     NoIntrinsic,
     AbsIntrinsic,
index 25fd954..aef3fab 100644 (file)
@@ -46,10 +46,9 @@ ModuleProgramExecutable::ModuleProgramExecutable(ExecState* exec, const SourceCo
     : ScriptExecutable(exec->vm().moduleProgramExecutableStructure.get(), exec->vm(), source, false, DerivedContextType::None, false, EvalContextType::None, NoIntrinsic)
 {
     ASSERT(source.provider()->sourceType() == SourceProviderSourceType::Module);
-    m_typeProfilingStartOffset = 0;
-    m_typeProfilingEndOffset = source.length() - 1;
-    if (exec->vm().typeProfiler() || exec->vm().controlFlowProfiler())
-        exec->vm().functionHasExecutedCache()->insertUnexecutedRange(sourceID(), m_typeProfilingStartOffset, m_typeProfilingEndOffset);
+    VM& vm = exec->vm();
+    if (vm.typeProfiler() || vm.controlFlowProfiler())
+        vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), typeProfilingStartOffset(vm), typeProfilingEndOffset(vm));
 }
 
 ModuleProgramExecutable* ModuleProgramExecutable::create(ExecState* exec, const SourceCode& source)
index 1a3f092..5d72218 100644 (file)
@@ -47,10 +47,9 @@ ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
     : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec->vm(), source, false, DerivedContextType::None, false, EvalContextType::None, NoIntrinsic)
 {
     ASSERT(source.provider()->sourceType() == SourceProviderSourceType::Program);
-    m_typeProfilingStartOffset = 0;
-    m_typeProfilingEndOffset = source.length() - 1;
-    if (exec->vm().typeProfiler() || exec->vm().controlFlowProfiler())
-        exec->vm().functionHasExecutedCache()->insertUnexecutedRange(sourceID(), m_typeProfilingStartOffset, m_typeProfilingEndOffset);
+    VM& vm = exec->vm();
+    if (vm.typeProfiler() || vm.controlFlowProfiler())
+        vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), typeProfilingStartOffset(vm), typeProfilingEndOffset(vm));
 }
 
 void ProgramExecutable::destroy(JSCell* cell)
index 5236096..891c3a1 100644 (file)
@@ -48,7 +48,6 @@ const ClassInfo ScriptExecutable::s_info = { "ScriptExecutable", &ExecutableBase
 ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCode& source, bool isInStrictContext, DerivedContextType derivedContextType, bool isInArrowFunctionContext, EvalContextType evalContextType, Intrinsic intrinsic)
     : ExecutableBase(vm, structure, NUM_PARAMETERS_NOT_COMPILED, intrinsic)
     , m_features(isInStrictContext ? StrictModeFeature : 0)
-    , m_didTryToEnterInLoop(false)
     , m_hasCapturedVariables(false)
     , m_neverInline(false)
     , m_neverOptimize(false)
@@ -57,11 +56,6 @@ ScriptExecutable::ScriptExecutable(Structure* structure, VM& vm, const SourceCod
     , m_canUseOSRExitFuzzing(true)
     , m_derivedContextType(static_cast<unsigned>(derivedContextType))
     , m_evalContextType(static_cast<unsigned>(evalContextType))
-    , m_overrideLineNumber(-1)
-    , m_lastLine(-1)
-    , m_endColumn(UINT_MAX)
-    , m_typeProfilingStartOffset(UINT_MAX)
-    , m_typeProfilingEndOffset(UINT_MAX)
     , m_source(source)
 {
 }
@@ -372,4 +366,29 @@ CodeBlockHash ScriptExecutable::hashFor(CodeSpecializationKind kind) const
     return CodeBlockHash(source(), kind);
 }
 
+Optional<int> ScriptExecutable::overrideLineNumber(VM& vm) const
+{
+    if (inherits<FunctionExecutable>(vm))
+        return jsCast<const FunctionExecutable*>(this)->overrideLineNumber();
+    return WTF::nullopt;
+}
+
+unsigned ScriptExecutable::typeProfilingStartOffset(VM& vm) const
+{
+    if (inherits<FunctionExecutable>(vm))
+        return jsCast<const FunctionExecutable*>(this)->typeProfilingStartOffset(vm);
+    if (inherits<EvalExecutable>(vm))
+        return UINT_MAX;
+    return 0;
+}
+
+unsigned ScriptExecutable::typeProfilingEndOffset(VM& vm) const
+{
+    if (inherits<FunctionExecutable>(vm))
+        return jsCast<const FunctionExecutable*>(this)->typeProfilingEndOffset(vm);
+    if (inherits<EvalExecutable>(vm))
+        return UINT_MAX;
+    return m_source.length() - 1;
+}
+
 } // namespace JSC
index 8d891bd..5b85393 100644 (file)
@@ -45,14 +45,13 @@ public:
     const SourceOrigin& sourceOrigin() const { return m_source.provider()->sourceOrigin(); }
     const String& sourceURL() const { return m_source.provider()->url(); }
     int firstLine() const { return m_source.firstLine().oneBasedInt(); }
-    void setOverrideLineNumber(int overrideLineNumber) { m_overrideLineNumber = overrideLineNumber; }
-    bool hasOverrideLineNumber() const { return m_overrideLineNumber != -1; }
-    int overrideLineNumber() const { return m_overrideLineNumber; }
     int lastLine() const { return m_lastLine; }
     unsigned startColumn() const { return m_source.startColumn().oneBasedInt(); }
     unsigned endColumn() const { return m_endColumn; }
-    unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; }
-    unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; }
+
+    Optional<int> overrideLineNumber(VM&) const;
+    unsigned typeProfilingStartOffset(VM&) const;
+    unsigned typeProfilingEndOffset(VM&) const;
 
     bool usesEval() const { return m_features & EvalFeature; }
     bool usesArguments() const { return m_features & ArgumentsFeature; }
@@ -124,8 +123,8 @@ protected:
 #endif
     }
 
+    bool m_didTryToEnterInLoop { false };
     CodeFeatures m_features;
-    bool m_didTryToEnterInLoop;
     bool m_hasCapturedVariables : 1;
     bool m_neverInline : 1;
     bool m_neverOptimize : 1;
@@ -135,11 +134,8 @@ protected:
     unsigned m_derivedContextType : 2; // DerivedContextType
     unsigned m_evalContextType : 2; // EvalContextType
 
-    int m_overrideLineNumber;
-    int m_lastLine;
-    unsigned m_endColumn;
-    unsigned m_typeProfilingStartOffset;
-    unsigned m_typeProfilingEndOffset;
+    int m_lastLine { -1 };
+    unsigned m_endColumn { UINT_MAX };
     SourceCode m_source;
 };
 
index 01b85b9..dd29f2a 100644 (file)
@@ -114,8 +114,8 @@ void StackFrame::computeLineAndColumn(unsigned& line, unsigned& column) const
     m_codeBlock->expressionRangeForBytecodeOffset(m_bytecodeOffset, divot, unusedStartOffset, unusedEndOffset, line, column);
 
     ScriptExecutable* executable = m_codeBlock->ownerScriptExecutable();
-    if (executable->hasOverrideLineNumber())
-        line = executable->overrideLineNumber();
+    if (Optional<int> overrideLineNumber = executable->overrideLineNumber(*m_codeBlock->vm()))
+        line = overrideLineNumber.value();
 }
 
 String StackFrame::toString(VM& vm) const
index 747aa29..a2b56e6 100644 (file)
@@ -1985,7 +1985,7 @@ static EncodedJSValue JSC_HOST_CALL functionReturnTypeFor(ExecState* exec)
     RELEASE_ASSERT(functionValue.isFunction(vm));
     FunctionExecutable* executable = (jsDynamicCast<JSFunction*>(vm, functionValue.asCell()->getObject()))->jsExecutable();
 
-    unsigned offset = executable->typeProfilingStartOffset();
+    unsigned offset = executable->typeProfilingStartOffset(vm);
     String jsonString = vm.typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn, offset, executable->sourceID(), vm);
     return JSValue::encode(JSONParse(exec, jsonString));
 }