Do not leak message object beyond try-catch.
authoryangguo <yangguo@chromium.org>
Tue, 26 May 2015 08:00:04 +0000 (01:00 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 26 May 2015 08:00:17 +0000 (08:00 +0000)
R=mstarzinger@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#28612}

12 files changed:
src/arm/full-codegen-arm.cc
src/arm64/full-codegen-arm64.cc
src/compiler/ast-graph-builder.cc
src/full-codegen.cc
src/full-codegen.h
src/ia32/full-codegen-ia32.cc
src/mips/full-codegen-mips.cc
src/mips64/full-codegen-mips64.cc
src/ppc/full-codegen-ppc.cc
src/x64/full-codegen-x64.cc
src/x87/full-codegen-x87.cc
test/cctest/test-heap.cc

index 9d626a6..d3eb1d1 100644 (file)
@@ -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 __
 
 
index 632ec5f..171765d 100644 (file)
@@ -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 __
 
 
index a63744e..d3506e7 100644 (file)
@@ -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();
index 4ea455e..a256697 100644 (file)
@@ -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");
index 34e93ee..ff3faa8 100644 (file)
@@ -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_; }
index 7d575d8..2e6c417 100644 (file)
@@ -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 __
 
 
index 67ec571..fea797e 100644 (file)
@@ -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 __
 
 
index b253ed8..65c4689 100644 (file)
@@ -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 __
 
 
index 75415e1..f93e96b 100644 (file)
@@ -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 __
 
 
index 6e26e76..9878deb 100644 (file)
@@ -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 __
 
 
index 93878fe..fffb4b2 100644 (file)
@@ -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 __
 
 
index a37da26..e0665ce 100644 (file)
@@ -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);
+}