Handle captured objects in OptimizedFrame::Summarize.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 2 Dec 2013 12:11:02 +0000 (12:11 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 2 Dec 2013 12:11:02 +0000 (12:11 +0000)
R=yangguo@chromium.org
BUG=v8:3029
TEST=mjsunit/regress/regress-3029
LOG=N

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18187 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/frames.cc
src/isolate.cc
src/isolate.h
test/cctest/test-debug.cc
test/mjsunit/regress/regress-3029.js [new file with mode: 0644]

index 912c822..9549c2d 100644 (file)
@@ -984,14 +984,16 @@ void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
       // to construct a stack trace, the receiver is always in a stack slot.
       opcode = static_cast<Translation::Opcode>(it.Next());
       ASSERT(opcode == Translation::STACK_SLOT ||
-             opcode == Translation::LITERAL);
+             opcode == Translation::LITERAL ||
+             opcode == Translation::CAPTURED_OBJECT ||
+             opcode == Translation::DUPLICATED_OBJECT);
       int index = it.Next();
 
       // Get the correct receiver in the optimized frame.
       Object* receiver = NULL;
       if (opcode == Translation::LITERAL) {
         receiver = data->LiteralArray()->get(index);
-      } else {
+      } else if (opcode == Translation::STACK_SLOT) {
         // Positive index means the value is spilled to the locals
         // area. Negative means it is stored in the incoming parameter
         // area.
@@ -1007,6 +1009,12 @@ void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
               ? this->receiver()
               : this->GetParameter(parameter_index);
         }
+      } else {
+        // TODO(3029): Materializing a captured object (or duplicated
+        // object) is hard, we return undefined for now. This breaks the
+        // produced stack trace, as constructor frames aren't marked as
+        // such anymore.
+        receiver = isolate()->heap()->undefined_value();
       }
 
       Code* code = function->shared()->code();
index 941ac42..6495d25 100644 (file)
@@ -1323,11 +1323,6 @@ MessageLocation Isolate::GetMessageLocation() {
 }
 
 
-void Isolate::TraceException(bool flag) {
-  FLAG_trace_exception = flag;  // TODO(isolates): This is an unfortunate use.
-}
-
-
 bool Isolate::OptionalRescheduleException(bool is_bottom_call) {
   ASSERT(has_pending_exception());
   PropagatePendingExceptionToExternalTryCatch();
index e80cd45..7ba3088 100644 (file)
@@ -785,9 +785,6 @@ class Isolate {
   // result in the target out parameter.
   void ComputeLocation(MessageLocation* target);
 
-  // Override command line flag.
-  void TraceException(bool flag);
-
   // Out of resource exception helpers.
   Failure* StackOverflow();
   Failure* TerminateExecution();
index ff802e3..f42b82b 100644 (file)
@@ -3943,8 +3943,6 @@ TEST(BreakOnException) {
   v8::HandleScope scope(env->GetIsolate());
   env.ExposeDebug();
 
-  CcTest::i_isolate()->TraceException(false);
-
   // Create functions for testing break on exception.
   CompileFunction(&env, "function throws(){throw 1;}", "throws");
   v8::Local<v8::Function> caught =
@@ -4089,8 +4087,6 @@ TEST(BreakOnCompileException) {
   // For this test, we want to break on uncaught exceptions:
   ChangeBreakOnException(false, true);
 
-  CcTest::i_isolate()->TraceException(false);
-
   // Create a function for checking the function when hitting a break point.
   frame_count = CompileFunction(&env, frame_count_source, "frame_count");
 
diff --git a/test/mjsunit/regress/regress-3029.js b/test/mjsunit/regress/regress-3029.js
new file mode 100644 (file)
index 0000000..ae412df
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function c(x) {
+  undefined.boom();
+}
+
+function f() {
+  return new c();
+}
+
+function g() {
+  f();
+}
+
+assertThrows("g()", TypeError);
+assertThrows("g()", TypeError);
+%OptimizeFunctionOnNextCall(g);
+assertThrows("g()", TypeError);