Skip to content

Commit

Permalink
Update TCO debug mode
Browse files Browse the repository at this point in the history
Signed-off-by: HyukWoo Park <[email protected]>
  • Loading branch information
clover2123 authored and ksh8281 committed Jun 5, 2024
1 parent 25fe6b8 commit 1050ee4
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 5 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/es-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -367,10 +367,10 @@ jobs:
env:
BUILD_OPTIONS: -DESCARGOT_HOST=linux -DESCARGOT_THREADING=ON -DESCARGOT_TEMPORAL=ON -DESCARGOT_TCO=ON -DESCARGOT_TEST=ON -DESCARGOT_OUTPUT=shell -GNinja
run: |
LDFLAGS=" -L/usr/icu32/lib/ -Wl,-rpath=/usr/icu32/lib/" PKG_CONFIG_PATH="/usr/icu32/lib/pkgconfig/" cmake -H./ -Bbuild/out_linux -DESCARGOT_ARCH=x86 -DESCARGOT_MODE=debug $BUILD_OPTIONS
LDFLAGS=" -L/usr/icu32/lib/ -Wl,-rpath=/usr/icu32/lib/" PKG_CONFIG_PATH="/usr/icu32/lib/pkgconfig/" cmake -H./ -Bbuild/out_linux -DESCARGOT_ARCH=x86 -DESCARGOT_MODE=debug -DESCARGOT_TCO_DEBUG=ON $BUILD_OPTIONS
LDFLAGS=" -L/usr/icu32/lib/ -Wl,-rpath=/usr/icu32/lib/" PKG_CONFIG_PATH="/usr/icu32/lib/pkgconfig/" cmake -H./ -Bbuild/out_linux_release -DESCARGOT_ARCH=x86 $BUILD_OPTIONS
gcc -shared -m32 -fPIC -o backtrace-hooking-32.so tools/test/test262/backtrace-hooking.c
LDFLAGS=" -L/usr/icu64/lib/ -Wl,-rpath=/usr/icu64/lib/" PKG_CONFIG_PATH="/usr/icu64/lib/pkgconfig/" cmake -H./ -Bbuild/out_linux64 -DESCARGOT_ARCH=x64 -DESCARGOT_MODE=debug $BUILD_OPTIONS
LDFLAGS=" -L/usr/icu64/lib/ -Wl,-rpath=/usr/icu64/lib/" PKG_CONFIG_PATH="/usr/icu64/lib/pkgconfig/" cmake -H./ -Bbuild/out_linux64 -DESCARGOT_ARCH=x64 -DESCARGOT_MODE=debug -DESCARGOT_TCO_DEBUG=ON $BUILD_OPTIONS
LDFLAGS=" -L/usr/icu64/lib/ -Wl,-rpath=/usr/icu64/lib/" PKG_CONFIG_PATH="/usr/icu64/lib/pkgconfig/" cmake -H./ -Bbuild/out_linux64_release -DESCARGOT_ARCH=x64 -DESCARGOT_MODE=release $BUILD_OPTIONS
cmake --build build/out_linux/
cmake --build build/out_linux64/
Expand Down
6 changes: 6 additions & 0 deletions build/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ ENDIF()

IF (ESCARGOT_TCO)
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DENABLE_TCO)
IF (ESCARGOT_TCO_DEBUG)
IF (NOT ${ESCARGOT_MODE} STREQUAL "debug")
MESSAGE (FATAL_ERROR "ESCARGOT_TCO_DEBUG is enabled only for debug mode")
ENDIF()
SET (ESCARGOT_DEFINITIONS ${ESCARGOT_DEFINITIONS} -DENABLE_TCO_DEBUG)
ENDIF()
ENDIF()

IF (ESCARGOT_TEMPORAL)
Expand Down
54 changes: 51 additions & 3 deletions src/interpreter/ByteCodeInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,11 @@ class InterpreterSlowPath {

#if defined(ENABLE_TCO)
static Value tailRecursionSlowCase(ExecutionState& state, TailRecursion* code, ByteCodeBlock* byteCodeBlock, const Value& callee, Value* registerFile);
static Value prepareTailCallOptimization(ExecutionState* state, TailCall* code, ScriptFunctionObject* callee, ByteCodeBlock*& callerBlock, size_t& programCounter, const Value* registerFile);
static Value prepareTailCallOptimization(ExecutionState*& state, TailCall* code, ScriptFunctionObject* callee, ByteCodeBlock*& callerBlock, size_t& programCounter, const Value* registerFile);
static Value tailCallSlowCase(ExecutionState& state, TailCall* code, const Value& callee, Value* registerFile);
#if defined(ENABLE_TCO_DEBUG)
static ExecutionState* createExecutionStateForTailCall(ExecutionState* state, ScriptFunctionObject* callee, ByteCodeBlock* callerByteBlock);
#endif
#endif

private:
Expand Down Expand Up @@ -1556,6 +1559,14 @@ Value Interpreter::interpret(ExecutionState* state, ByteCodeBlock* byteCodeBlock
}

if (UNLIKELY(!state->inTCO())) {
#if defined(ENABLE_TCO_DEBUG)
ExecutionState* newState = InterpreterSlowPath::createExecutionStateForTailCall(state, callee.asPointerValue()->asScriptFunctionObject(), byteCodeBlock);
// copy the current programCounter info
state->m_programCounter = (size_t*)GC_MALLOC(sizeof(size_t));
*state->m_programCounter = programCounter;
newState->m_programCounter = &programCounter;
state = newState;
#endif
// At the start of tail call, we need to allocate a buffer for arguments
// because recursive tail call reuses this buffer
state->initTCOWithBuffer(Interpreter::tcoBuffer);
Expand Down Expand Up @@ -5035,7 +5046,7 @@ NEVER_INLINE Value InterpreterSlowPath::tailRecursionSlowCase(ExecutionState& st
return callee.asPointerValue()->call(state, receiver, code->m_argumentCount, &registerFile[code->m_argumentsStartIndex]);
}

NEVER_INLINE Value InterpreterSlowPath::prepareTailCallOptimization(ExecutionState* state, TailCall* code, ScriptFunctionObject* callee, ByteCodeBlock*& callerByteBlock, size_t& programCounter, const Value* registerFile)
NEVER_INLINE Value InterpreterSlowPath::prepareTailCallOptimization(ExecutionState*& state, TailCall* code, ScriptFunctionObject* callee, ByteCodeBlock*& callerByteBlock, size_t& programCounter, const Value* registerFile)
{
ASSERT(!callee->isScriptArrowFunctionObject() && !!callerByteBlock);
ASSERT(state->m_programCounter == &programCounter);
Expand All @@ -5057,6 +5068,21 @@ NEVER_INLINE Value InterpreterSlowPath::prepareTailCallOptimization(ExecutionSta
bool isStrict = calleeBlock->isStrict();
bool isTailRecursion = (calleeByteBlock == callerByteBlock) && (!callerByteBlock->codeBlock()->isTailRecursionDisabled());

#if defined(ENABLE_TCO_DEBUG)
// allocate a new ExecutionState for debugging purpose
ExecutionState* newState = createExecutionStateForTailCall(state, callee, callerByteBlock);

// copy the current programCounter info
state->m_programCounter = (size_t*)GC_MALLOC(sizeof(size_t));
*state->m_programCounter = programCounter;
newState->m_programCounter = &programCounter;
state = newState;

if (isTailRecursion) {
// convert to fast tail recursion
code->changeOpcode(Opcode::TailRecursionOpcode);
}
#else
// tail recursion reuses environment structures
if (isTailRecursion) {
// convert to fast tail recursion
Expand Down Expand Up @@ -5088,7 +5114,7 @@ NEVER_INLINE Value InterpreterSlowPath::prepareTailCallOptimization(ExecutionSta
newState->m_programCounter = &programCounter;
ASSERT(state == newState);
}

#endif

if (!state->inTCO()) {
// At the start of tail call, we need to set a buffer for arguments
Expand Down Expand Up @@ -5138,5 +5164,27 @@ NEVER_INLINE Value InterpreterSlowPath::tailCallSlowCase(ExecutionState& state,
const Value& receiver = (code->m_receiverIndex == REGISTER_LIMIT) ? Value() : registerFile[code->m_receiverIndex];
return callee.asPointerValue()->call(state, receiver, code->m_argumentCount, &registerFile[code->m_argumentsStartIndex]);
}

#if defined(ENABLE_TCO_DEBUG)
ExecutionState* InterpreterSlowPath::createExecutionStateForTailCall(ExecutionState* state, ScriptFunctionObject* callee, ByteCodeBlock* callerByteBlock)
{
ASSERT(!callee->isScriptArrowFunctionObject());

InterpretedCodeBlock* calleeBlock = callee->interpretedCodeBlock();
FunctionEnvironmentRecord* record = nullptr;
LexicalEnvironment* lexEnv = nullptr;
if (!calleeBlock->canAllocateEnvironmentOnStack()) {
ASSERT(!callee->isScriptSimpleFunctionObject());
record = FunctionObjectProcessCallGenerator::createFunctionEnvironmentRecord<ScriptFunctionObject, false, false>(*state, callee, calleeBlock);
lexEnv = new LexicalEnvironment(record, callee->outerEnvironment());
} else if (callerByteBlock->codeBlock()->canAllocateEnvironmentOnStack()) {
ASSERT(state->lexicalEnvironment()->record()->asDeclarativeEnvironmentRecord()->asFunctionEnvironmentRecord()->isFunctionEnvironmentRecordOnStack());
record = new FunctionEnvironmentRecordOnStack<false, false>(callee);
lexEnv = new LexicalEnvironment(record, callee->outerEnvironment(), false);
}

return new ExecutionState(calleeBlock->context(), state, lexEnv, 0, nullptr, calleeBlock->isStrict());
}
#endif
#endif
} // namespace Escargot

0 comments on commit 1050ee4

Please sign in to comment.