Commit 14eba9b2 authored by yangguo's avatar yangguo Committed by Commit bot

Do not leak message object beyond try-catch.

R=mstarzinger@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#28612}
parent 9c5b2375
......@@ -5352,6 +5352,8 @@ void FullCodeGenerator::EnterFinallyBlock() {
__ mov(ip, Operand(pending_message_obj));
__ ldr(r1, MemOperand(ip));
__ push(r1);
ClearPendingMessage();
}
......@@ -5374,6 +5376,16 @@ void FullCodeGenerator::ExitFinallyBlock() {
}
void FullCodeGenerator::ClearPendingMessage() {
DCHECK(!result_register().is(r1));
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ LoadRoot(r1, Heap::kTheHoleValueRootIndex);
__ mov(ip, Operand(pending_message_obj));
__ str(r1, MemOperand(ip));
}
#undef __
......
......@@ -5363,6 +5363,8 @@ void FullCodeGenerator::EnterFinallyBlock() {
__ Mov(x10, pending_message_obj);
__ Ldr(x10, MemOperand(x10));
__ Push(x10);
ClearPendingMessage();
}
......@@ -5387,6 +5389,16 @@ void FullCodeGenerator::ExitFinallyBlock() {
}
void FullCodeGenerator::ClearPendingMessage() {
DCHECK(!result_register().is(x10));
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
__ Mov(x13, pending_message_obj);
__ Str(x10, MemOperand(x13));
}
#undef __
......
......@@ -1474,6 +1474,12 @@ void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
}
try_control.EndTry();
// Clear message object as we enter the catch block.
ExternalReference message_object =
ExternalReference::address_of_pending_message_obj(isolate());
Node* the_hole = jsgraph()->TheHoleConstant();
BuildStoreExternal(message_object, kMachAnyTagged, the_hole);
// Create a catch scope that binds the exception.
Node* exception = try_control.GetExceptionNode();
Unique<String> name = MakeUnique(stmt->variable()->name());
......@@ -1539,6 +1545,10 @@ void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
environment()->Push(result);
environment()->Push(message);
// Clear message object as we enter the finally block.
Node* the_hole = jsgraph()->TheHoleConstant();
BuildStoreExternal(message_object, kMachAnyTagged, the_hole);
// Evaluate the finally-block.
Visit(stmt->finally_block());
try_control.EndFinally();
......
......@@ -1182,6 +1182,8 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
Label try_entry, handler_entry, exit;
__ jmp(&try_entry);
__ bind(&handler_entry);
ClearPendingMessage();
// Exception handler code, the exception is in the result register.
// Extend the context before executing the catch block.
{ Comment cmnt(masm_, "[ Extend catch context");
......
......@@ -709,6 +709,7 @@ class FullCodeGenerator: public AstVisitor {
void ExitTryBlock(int handler_index);
void EnterFinallyBlock();
void ExitFinallyBlock();
void ClearPendingMessage();
// Loop nesting counter.
int loop_depth() { return loop_depth_; }
......
......@@ -5279,6 +5279,8 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference::address_of_pending_message_obj(isolate());
__ mov(edx, Operand::StaticVariable(pending_message_obj));
__ push(edx);
ClearPendingMessage();
}
......@@ -5301,6 +5303,15 @@ void FullCodeGenerator::ExitFinallyBlock() {
}
void FullCodeGenerator::ClearPendingMessage() {
DCHECK(!result_register().is(edx));
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
__ mov(Operand::StaticVariable(pending_message_obj), edx);
}
#undef __
......
......@@ -5353,6 +5353,8 @@ void FullCodeGenerator::EnterFinallyBlock() {
__ li(at, Operand(pending_message_obj));
__ lw(a1, MemOperand(at));
__ push(a1);
ClearPendingMessage();
}
......@@ -5377,6 +5379,16 @@ void FullCodeGenerator::ExitFinallyBlock() {
}
void FullCodeGenerator::ClearPendingMessage() {
DCHECK(!result_register().is(a1));
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
__ li(at, Operand(pending_message_obj));
__ sw(a1, MemOperand(at));
}
#undef __
......
......@@ -5356,6 +5356,8 @@ void FullCodeGenerator::EnterFinallyBlock() {
__ li(at, Operand(pending_message_obj));
__ ld(a1, MemOperand(at));
__ push(a1);
ClearPendingMessage();
}
......@@ -5380,6 +5382,16 @@ void FullCodeGenerator::ExitFinallyBlock() {
}
void FullCodeGenerator::ClearPendingMessage() {
DCHECK(!result_register().is(a1));
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
__ li(at, Operand(pending_message_obj));
__ sd(a1, MemOperand(at));
}
#undef __
......
......@@ -5362,6 +5362,8 @@ void FullCodeGenerator::EnterFinallyBlock() {
__ mov(ip, Operand(pending_message_obj));
__ LoadP(r4, MemOperand(ip));
__ push(r4);
ClearPendingMessage();
}
......@@ -5387,6 +5389,16 @@ void FullCodeGenerator::ExitFinallyBlock() {
}
void FullCodeGenerator::ClearPendingMessage() {
DCHECK(!result_register().is(r4));
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ LoadRoot(r4, Heap::kTheHoleValueRootIndex);
__ mov(ip, Operand(pending_message_obj));
__ StoreP(r4, MemOperand(ip));
}
#undef __
......
......@@ -5295,6 +5295,8 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference::address_of_pending_message_obj(isolate());
__ Load(rdx, pending_message_obj);
__ Push(rdx);
ClearPendingMessage();
}
......@@ -5319,6 +5321,15 @@ void FullCodeGenerator::ExitFinallyBlock() {
}
void FullCodeGenerator::ClearPendingMessage() {
DCHECK(!result_register().is(rdx));
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ LoadRoot(rdx, Heap::kTheHoleValueRootIndex);
__ Store(pending_message_obj, rdx);
}
#undef __
......
......@@ -5269,6 +5269,8 @@ void FullCodeGenerator::EnterFinallyBlock() {
ExternalReference::address_of_pending_message_obj(isolate());
__ mov(edx, Operand::StaticVariable(pending_message_obj));
__ push(edx);
ClearPendingMessage();
}
......@@ -5291,6 +5293,15 @@ void FullCodeGenerator::ExitFinallyBlock() {
}
void FullCodeGenerator::ClearPendingMessage() {
DCHECK(!result_register().is(edx));
ExternalReference pending_message_obj =
ExternalReference::address_of_pending_message_obj(isolate());
__ mov(edx, Immediate(isolate()->factory()->the_hole_value()));
__ mov(Operand::StaticVariable(pending_message_obj), edx);
}
#undef __
......
......@@ -5558,3 +5558,44 @@ TEST(NewSpaceAllocationThroughput2) {
bytes = tracer->NewSpaceAllocatedBytesInLast(100);
CHECK_EQ((counter3 - counter1) * 100 / (time3 - time1), bytes);
}
static void CheckLeak(const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = CcTest::i_isolate();
Object* message =
*reinterpret_cast<Object**>(isolate->pending_message_obj_address());
CHECK(message->IsTheHole());
}
TEST(MessageObjectLeak) {
CcTest::InitializeVM();
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
global->Set(v8::String::NewFromUtf8(isolate, "check"),
v8::FunctionTemplate::New(isolate, CheckLeak));
v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
v8::Context::Scope cscope(context);
const char* test =
"try {"
" throw 'message 1';"
"} catch (e) {"
"}"
"check();"
"L: try {"
" throw 'message 2';"
"} finally {"
" break L;"
"}"
"check();";
CompileRun(test);
const char* flag = "--turbo-filter=*";
FlagList::SetFlagsFromString(flag, StrLength(flag));
FLAG_always_opt = true;
FLAG_turbo_exceptions = true;
CompileRun(test);
}
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