Commit e8144576 authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[interpreter] Clear pending message object on handler entry.

This clears the currently pending message object whenever a try-block or
a finally-block is being entered in interpreted code. The intention is
to avoid memory leaks introduced by the message object. Also the message
object is being restored when a finally-block exits.

R=rmcilroy@chromium.org
TEST=cctest/test-heap/MessageObjectLeak
BUG=v8:4674
LOG=n

Review URL: https://codereview.chromium.org/1651993002

Cr-Commit-Position: refs/heads/master@{#33704}
parent ebac85c0
......@@ -1108,6 +1108,7 @@ void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
TryCatchBuilder try_control_builder(builder());
Register no_reg;
// Preserve the context in a dedicated register, so that it can be restored
// when the handler is entered by the stack-unwinding machinery.
......@@ -1123,11 +1124,15 @@ void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
}
try_control_builder.EndTry();
// Clear message object as we enter the catch block.
// TODO(mstarzinger): Implement this!
// Create a catch scope that binds the exception.
VisitNewLocalCatchContext(stmt->variable());
builder()->StoreAccumulatorInRegister(context);
// Clear message object as we enter the catch block.
builder()->CallRuntime(Runtime::kInterpreterClearPendingMessage, no_reg, 0);
// Load the catch context into the accumulator.
builder()->LoadAccumulatorWithRegister(context);
// Evaluate the catch-block.
VisitInScope(stmt->catch_block(), stmt->scope());
......@@ -1137,6 +1142,7 @@ void BytecodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
TryFinallyBuilder try_control_builder(builder());
Register no_reg;
// We keep a record of all paths that enter the finally-block to be able to
// dispatch to the correct continuation point after the statements in the
......@@ -1177,15 +1183,22 @@ void BytecodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
try_control_builder.BeginHandler();
commands.RecordHandlerReThrowPath();
// Pending message object is saved on entry.
try_control_builder.BeginFinally();
Register message = context; // Reuse register.
// Clear message object as we enter the finally block.
// TODO(mstarzinger): Implement this!
builder()
->CallRuntime(Runtime::kInterpreterClearPendingMessage, no_reg, 0)
.StoreAccumulatorInRegister(message);
// Evaluate the finally-block.
Visit(stmt->finally_block());
try_control_builder.EndFinally();
// Pending message object is restored on exit.
builder()->CallRuntime(Runtime::kInterpreterSetPendingMessage, message, 1);
// Dynamic dispatch after the finally-block.
commands.ApplyDeferredCommands();
}
......
......@@ -253,5 +253,21 @@ RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) {
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_InterpreterClearPendingMessage) {
SealHandleScope shs(isolate);
DCHECK_EQ(0, args.length());
Object* message = isolate->thread_local_top()->pending_message_obj_;
isolate->clear_pending_message();
return message;
}
RUNTIME_FUNCTION(Runtime_InterpreterSetPendingMessage) {
SealHandleScope shs(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, message, 0);
isolate->thread_local_top()->pending_message_obj_ = *message;
return isolate->heap()->undefined_value();
}
} // namespace internal
} // namespace v8
......@@ -221,7 +221,9 @@ namespace internal {
F(InterpreterTypeOf, 1, 1) \
F(InterpreterNewClosure, 2, 1) \
F(InterpreterTraceBytecodeEntry, 3, 1) \
F(InterpreterTraceBytecodeExit, 3, 1)
F(InterpreterTraceBytecodeExit, 3, 1) \
F(InterpreterClearPendingMessage, 0, 1) \
F(InterpreterSetPendingMessage, 1, 1)
#define FOR_EACH_INTRINSIC_FUNCTION(F) \
F(FunctionGetName, 1, 1) \
......
......@@ -513,11 +513,8 @@
'test-profile-generator/BailoutReason': [FAIL],
'test-api/Regress385349': [FAIL],
# TODO(mstarzinger,4674): Message object is not properly cleared.
'test-heap/MessageObjectLeak': [FAIL],
# TODO(mstarzinger,4674): Support exception handlers in BytecodeGraphBuilder.
'test-run-deopt/DeoptExceptionHandlerCatch': [FAIL],
'test-run-deopt/DeoptExceptionHandlerCatch': [PASS, FAIL],
# TODO(rmcilroy,4680): Check failed: toplevel_test_code_event_found.
'test-serialize/SerializeToplevelIsolates': [FAIL],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment