From: yangguo Date: Tue, 26 May 2015 08:00:04 +0000 (-0700) Subject: Do not leak message object beyond try-catch. X-Git-Tag: upstream/4.7.83~2428 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=14eba9b27531911f8466a5877fc66b64bc98bdb6;p=platform%2Fupstream%2Fv8.git 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} --- diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc index 9d626a6..d3eb1d1 100644 --- a/src/arm/full-codegen-arm.cc +++ b/src/arm/full-codegen-arm.cc @@ -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 __ diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc index 632ec5f..171765d 100644 --- a/src/arm64/full-codegen-arm64.cc +++ b/src/arm64/full-codegen-arm64.cc @@ -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 __ diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index a63744e..d3506e7 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -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 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(); diff --git a/src/full-codegen.cc b/src/full-codegen.cc index 4ea455e..a256697 100644 --- a/src/full-codegen.cc +++ b/src/full-codegen.cc @@ -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"); diff --git a/src/full-codegen.h b/src/full-codegen.h index 34e93ee..ff3faa8 100644 --- a/src/full-codegen.h +++ b/src/full-codegen.h @@ -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_; } diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc index 7d575d8..2e6c417 100644 --- a/src/ia32/full-codegen-ia32.cc +++ b/src/ia32/full-codegen-ia32.cc @@ -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 __ diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index 67ec571..fea797e 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -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 __ diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc index b253ed8..65c4689 100644 --- a/src/mips64/full-codegen-mips64.cc +++ b/src/mips64/full-codegen-mips64.cc @@ -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 __ diff --git a/src/ppc/full-codegen-ppc.cc b/src/ppc/full-codegen-ppc.cc index 75415e1..f93e96b 100644 --- a/src/ppc/full-codegen-ppc.cc +++ b/src/ppc/full-codegen-ppc.cc @@ -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 __ diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc index 6e26e76..9878deb 100644 --- a/src/x64/full-codegen-x64.cc +++ b/src/x64/full-codegen-x64.cc @@ -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 __ diff --git a/src/x87/full-codegen-x87.cc b/src/x87/full-codegen-x87.cc index 93878fe..fffb4b2 100644 --- a/src/x87/full-codegen-x87.cc +++ b/src/x87/full-codegen-x87.cc @@ -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 __ diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc index a37da26..e0665ce 100644 --- a/test/cctest/test-heap.cc +++ b/test/cctest/test-heap.cc @@ -5558,3 +5558,44 @@ TEST(NewSpaceAllocationThroughput2) { bytes = tracer->NewSpaceAllocatedBytesInLast(100); CHECK_EQ((counter3 - counter1) * 100 / (time3 - time1), bytes); } + + +static void CheckLeak(const v8::FunctionCallbackInfo& args) { + Isolate* isolate = CcTest::i_isolate(); + Object* message = + *reinterpret_cast(isolate->pending_message_obj_address()); + CHECK(message->IsTheHole()); +} + + +TEST(MessageObjectLeak) { + CcTest::InitializeVM(); + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + v8::Handle global = v8::ObjectTemplate::New(isolate); + global->Set(v8::String::NewFromUtf8(isolate, "check"), + v8::FunctionTemplate::New(isolate, CheckLeak)); + v8::Local 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); +}