Skip to content
Permalink
Browse files
[JSC] Remove DeprecatedCallFrameForDebugger
https://bugs.webkit.org/show_bug.cgi?id=239045

Reviewed by Devin Rousso.

We should not enlarge sizeof(JSGlobalObject) by having DeprecatedCallFrameForDebugger which is only used for Debugger, and it is used
only when we have an error when evaluating top-level SyntaxError. This patch removes it: we introduce EmptyTopLevelCallFrameForDebugger
which can be constructed on stack and we use it instead of DeprecatedCallFrameForDebugger.

* Source/JavaScriptCore/debugger/Debugger.cpp:
(JSC::Debugger::updateCallFrame):
(JSC::EmptyTopLevelCallFrameForDebugger::EmptyTopLevelCallFrameForDebugger):
(JSC::EmptyTopLevelCallFrameForDebugger::asCallFrame):
(JSC::Debugger::exception):
* Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::create):
(JSC::DebuggerCallFrame::positionForCallFrame):
* Source/JavaScriptCore/interpreter/CallFrame.cpp:
(JSC::CallFrame::convertToStackOverflowFrame):
(JSC::CallFrame::initDeprecatedCallFrameForDebugger): Deleted.
* Source/JavaScriptCore/interpreter/CallFrame.h:
(JSC::CallFrame::isEmptyTopLevelCallFrameForDebugger const):
(JSC::CallFrame::isDeprecatedCallFrameForDebugger const): Deleted.
* Source/JavaScriptCore/interpreter/Interpreter.cpp:
(JSC::Interpreter::notifyDebuggerOfExceptionToBeThrown):
* Source/JavaScriptCore/runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::deprecatedCallFrameForDebugger): Deleted.
* Source/JavaScriptCore/runtime/JSGlobalObject.h:
* Source/JavaScriptCore/runtime/VM.cpp:
(JSC::VM::throwException):

Canonical link: https://commits.webkit.org/249603@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@292830 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Constellation committed Apr 13, 2022
1 parent d11ee60 commit 2aa55cf595edfef2ffd838a0f5079d6b2a1d603a
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 30 deletions.
@@ -1,3 +1,37 @@
2022-04-13 Yusuke Suzuki <ysuzuki@apple.com>

[JSC] Remove DeprecatedCallFrameForDebugger
https://bugs.webkit.org/show_bug.cgi?id=239045

Reviewed by Devin Rousso.

We should not enlarge sizeof(JSGlobalObject) by having DeprecatedCallFrameForDebugger which is only used for Debugger, and it is used
only when we have an error when evaluating top-level SyntaxError. This patch removes it: we introduce EmptyTopLevelCallFrameForDebugger
which can be constructed on stack and we use it instead of DeprecatedCallFrameForDebugger.

* debugger/Debugger.cpp:
(JSC::Debugger::updateCallFrame):
(JSC::EmptyTopLevelCallFrameForDebugger::EmptyTopLevelCallFrameForDebugger):
(JSC::EmptyTopLevelCallFrameForDebugger::asCallFrame):
(JSC::Debugger::exception):
* debugger/DebuggerCallFrame.cpp:
(JSC::DebuggerCallFrame::create):
(JSC::DebuggerCallFrame::positionForCallFrame):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::convertToStackOverflowFrame):
(JSC::CallFrame::initDeprecatedCallFrameForDebugger): Deleted.
* interpreter/CallFrame.h:
(JSC::CallFrame::isEmptyTopLevelCallFrameForDebugger const):
(JSC::CallFrame::isDeprecatedCallFrameForDebugger const): Deleted.
* interpreter/Interpreter.cpp:
(JSC::Interpreter::notifyDebuggerOfExceptionToBeThrown):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::deprecatedCallFrameForDebugger): Deleted.
* runtime/JSGlobalObject.h:
* runtime/VM.cpp:
(JSC::VM::throwException):

2022-04-13 Chris Dumez <cdumez@apple.com>

Replace AtomString(const char*) with AtomString::fromLatin1(const char*)
@@ -1035,6 +1035,26 @@ JSC::JSValue Debugger::exceptionOrCaughtValue(JSC::JSGlobalObject* globalObject)
return { };
}

class EmptyTopLevelCallFrameForDebugger {
public:
EmptyTopLevelCallFrameForDebugger(JSGlobalObject* globalObject)
{
CallFrame* callFrame = asCallFrame();
callFrame->setCodeBlock(nullptr);
callFrame->setCallerFrame(CallFrame::noCaller());
callFrame->setReturnPC(nullptr);
callFrame->setArgumentCountIncludingThis(1);
callFrame->setThisValue(globalObject->globalThis());
callFrame->setCallee(globalObject->globalCallee());
ASSERT(callFrame->isEmptyTopLevelCallFrameForDebugger());
}

CallFrame* asCallFrame() { return CallFrame::create(m_values); }

private:
Register m_values[CallFrame::headerSizeInRegisters + /* thisValue */ 1] { };
};

void Debugger::exception(JSGlobalObject* globalObject, CallFrame* callFrame, JSValue exception, bool hasCatchHandler)
{
if (m_isPaused)
@@ -1056,11 +1076,21 @@ void Debugger::exception(JSGlobalObject* globalObject, CallFrame* callFrame, JSV
setSteppingMode(SteppingModeEnabled);
}

// When callFrame is nullptr, we are throwing an error without JS call frames.
// This can happen when program throws SyntaxError without evaluation.
EmptyTopLevelCallFrameForDebugger emptyCallFrame(globalObject);
bool callFrameWasNull = !callFrame;
if (callFrameWasNull)
callFrame = emptyCallFrame.asCallFrame();

m_hasHandlerForExceptionCallback = true;
m_currentException = exception;
updateCallFrame(globalObject, callFrame, AttemptPause);
m_currentException = JSValue();
m_hasHandlerForExceptionCallback = false;

if (callFrameWasNull)
m_currentCallFrame = nullptr;
}

void Debugger::atStatement(CallFrame* callFrame)
@@ -66,7 +66,7 @@ Ref<DebuggerCallFrame> DebuggerCallFrame::create(VM& vm, CallFrame* callFrame)
return adoptRef(*new DebuggerCallFrame(vm, callFrame, emptyFrame));
}

if (callFrame->isDeprecatedCallFrameForDebugger()) {
if (callFrame->isEmptyTopLevelCallFrameForDebugger()) {
ShadowChicken::Frame emptyFrame;
RELEASE_ASSERT(!emptyFrame.isTailDeleted);
return adoptRef(*new DebuggerCallFrame(vm, callFrame, emptyFrame));
@@ -320,6 +320,8 @@ TextPosition DebuggerCallFrame::currentPosition(VM& vm)
TextPosition DebuggerCallFrame::positionForCallFrame(VM& vm, CallFrame* callFrame)
{
LineAndColumnFunctor functor;
if (!callFrame)
return TextPosition(OrdinalNumber::fromOneBasedInt(0), OrdinalNumber::fromOneBasedInt(0));
StackVisitor::visit(callFrame, vm, functor);
return TextPosition(OrdinalNumber::fromOneBasedInt(functor.line()), OrdinalNumber::fromOneBasedInt(functor.column()));
}
@@ -40,16 +40,6 @@

namespace JSC {

void CallFrame::initDeprecatedCallFrameForDebugger(CallFrame* globalExec, JSCallee* globalCallee)
{
globalExec->setCodeBlock(nullptr);
globalExec->setCallerFrame(noCaller());
globalExec->setReturnPC(nullptr);
globalExec->setArgumentCountIncludingThis(0);
globalExec->setCallee(globalCallee);
ASSERT(globalExec->isDeprecatedCallFrameForDebugger());
}

bool CallFrame::callSiteBitsAreBytecodeOffset() const
{
ASSERT(codeBlock());
@@ -338,7 +328,7 @@ const char* CallFrame::describeFrame()

void CallFrame::convertToStackOverflowFrame(VM& vm, CodeBlock* codeBlockToKeepAliveUntilFrameIsUnwound)
{
ASSERT(!isDeprecatedCallFrameForDebugger());
ASSERT(!isEmptyTopLevelCallFrameForDebugger());
ASSERT(codeBlockToKeepAliveUntilFrameIsUnwound->inherits<CodeBlock>(vm));

EntryFrame* entryFrame = vm.topEntryFrame;
@@ -240,8 +240,6 @@ namespace JSC {
void setCallerFrame(CallFrame* frame) { callerFrameAndPC().callerFrame = frame; }
inline void setScope(int scopeRegisterOffset, JSScope*);

static void initDeprecatedCallFrameForDebugger(CallFrame* globalExec, JSCallee* globalCallee);

// Read a register from the codeframe (or constant from the CodeBlock).
Register& r(VirtualRegister);
// Read a register for a known non-constant
@@ -301,7 +299,8 @@ namespace JSC {
static int offsetFor(size_t argumentCountIncludingThis) { return CallFrameSlot::thisArgument + argumentCountIncludingThis - 1; }

static CallFrame* noCaller() { return nullptr; }
bool isDeprecatedCallFrameForDebugger() const

bool isEmptyTopLevelCallFrameForDebugger() const
{
return callerFrameAndPC().callerFrame == noCaller() && callerFrameAndPC().returnPC == nullptr;
}
@@ -770,7 +770,8 @@ void Interpreter::notifyDebuggerOfExceptionToBeThrown(VM& vm, JSGlobalObject* gl
// https://bugs.webkit.org/show_bug.cgi?id=121754

GetCatchHandlerFunctor functor;
StackVisitor::visit(callFrame, vm, functor);
if (callFrame)
StackVisitor::visit(callFrame, vm, functor);
HandlerInfo* handler = functor.handler();
ASSERT(!handler || handler->isCatchHandler());
bool hasCatchHandler = !!handler;
@@ -743,8 +743,6 @@ void JSGlobalObject::init(VM& vm)
JSCallee* globalCallee = JSCallee::create(vm, this, globalScope());
m_globalCallee.set(vm, this, globalCallee);

CallFrame::initDeprecatedCallFrameForDebugger(JSGlobalObject::deprecatedCallFrameForDebugger(), globalCallee);

JSCallee* stackOverflowFrameCallee = JSCallee::create(vm, this, globalScope());
m_stackOverflowFrameCallee.set(vm, this, stackOverflowFrameCallee);

@@ -2358,11 +2356,6 @@ void JSGlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)

DEFINE_VISIT_CHILDREN_WITH_MODIFIER(JS_EXPORT_PRIVATE, JSGlobalObject);

CallFrame* JSGlobalObject::deprecatedCallFrameForDebugger()
{
return CallFrame::create(m_deprecatedCallFrameForDebugger);
}

SUPPRESS_ASAN void JSGlobalObject::exposeDollarVM(VM& vm)
{
RELEASE_ASSERT(g_jscConfig.restrictedOptionsEnabled && Options::useDollarVM());
@@ -298,8 +298,6 @@ class JSGlobalObject : public JSSegmentedVariableObject {
public:
template<typename T> using Initializer = typename LazyProperty<JSGlobalObject, T>::Initializer;

Register m_deprecatedCallFrameForDebugger[CallFrame::headerSizeInRegisters];

WriteBarrier<JSObject> m_globalThis;

WriteBarrier<JSGlobalLexicalEnvironment> m_globalLexicalEnvironment;
@@ -1096,8 +1094,6 @@ class JSGlobalObject : public JSSegmentedVariableObject {

const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; }

JS_EXPORT_PRIVATE CallFrame* deprecatedCallFrameForDebugger();

static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; }

static JSGlobalObject* deriveShadowRealmGlobalObject(JSGlobalObject* globalObject)
@@ -898,9 +898,6 @@ Exception* VM::throwException(JSGlobalObject* globalObject, Exception* exception
}

CallFrame* throwOriginFrame = topJSCallFrame();
if (!throwOriginFrame)
throwOriginFrame = globalObject->deprecatedCallFrameForDebugger();

if (UNLIKELY(Options::breakOnThrow())) {
CodeBlock* codeBlock = throwOriginFrame ? throwOriginFrame->codeBlock() : nullptr;
dataLog("Throwing exception in call frame ", RawPointer(throwOriginFrame), " for code block ", codeBlock, "\n");

0 comments on commit 2aa55cf

Please sign in to comment.