Refactored deopt tracing and FindOptimizedCode. Fixed a bug when printing stubs.
authorsvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 21 Dec 2012 07:18:56 +0000 (07:18 +0000)
committersvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 21 Dec 2012 07:18:56 +0000 (07:18 +0000)
Review URL: https://codereview.chromium.org/11636046

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

src/deoptimizer.cc
src/deoptimizer.h
src/objects.cc
src/objects.h

index d79b022..a0b50ed 100644 (file)
@@ -477,37 +477,32 @@ void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) {
 }
 
 
-static Code* FindOptimizedCode(Isolate* isolate,
-                               JSFunction* function,
-                               Deoptimizer::BailoutType type,
-                               Address from,
-                               Code* optimized_code) {
+bool Deoptimizer::TraceEnabledFor(BailoutType type) {
   switch (type) {
-    case Deoptimizer::EAGER:
-      ASSERT(from == NULL);
-      return function->code();
-    case Deoptimizer::LAZY: {
-      Code* compiled_code =
-          isolate->deoptimizer_data()->FindDeoptimizingCode(from);
-      return (compiled_code == NULL)
-          ? static_cast<Code*>(isolate->heap()->FindCodeObject(from))
-          : compiled_code;
-    }
-    case Deoptimizer::OSR: {
-      // The function has already been optimized and we're transitioning
-      // from the unoptimized shared version to the optimized one in the
-      // function. The return address (from) points to unoptimized code.
-      Code* compiled_code = function->code();
-      ASSERT(compiled_code->kind() == Code::OPTIMIZED_FUNCTION);
-      ASSERT(!compiled_code->contains(from));
-      return compiled_code;
-    }
-    case Deoptimizer::DEBUGGER:
-      ASSERT(optimized_code->contains(from));
-      return optimized_code;
+    case EAGER:
+    case LAZY:
+    case DEBUGGER:
+      return FLAG_trace_deopt;
+    case OSR:
+      return FLAG_trace_osr;
   }
   UNREACHABLE();
-  return NULL;
+  return false;
+}
+
+
+const char* Deoptimizer::MessageFor(BailoutType type) {
+  switch (type) {
+    case EAGER:
+    case LAZY:
+      return "DEOPT";
+    case DEBUGGER:
+      return "DEOPT FOR DEBUGGER";
+    case OSR:
+      return "OSR";
+  }
+  UNREACHABLE();
+  return false;
 }
 
 
@@ -532,38 +527,16 @@ Deoptimizer::Deoptimizer(Isolate* isolate,
       deferred_arguments_objects_values_(0),
       deferred_arguments_objects_(0),
       deferred_heap_numbers_(0) {
-  if (FLAG_trace_deopt && type != OSR) {
-    if (type == DEBUGGER) {
-      PrintF("**** DEOPT FOR DEBUGGER: ");
-    } else {
-      PrintF("**** DEOPT: ");
-    }
-    function->PrintName();
-    PrintF(" at bailout #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
-           bailout_id,
-           reinterpret_cast<intptr_t>(from),
-           fp_to_sp_delta - (2 * kPointerSize));
-  } else if (FLAG_trace_osr && type == OSR) {
-    PrintF("**** OSR: ");
-    function->PrintName();
-    PrintF(" at ast id #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
-           bailout_id,
-           reinterpret_cast<intptr_t>(from),
-           fp_to_sp_delta - (2 * kPointerSize));
-  }
-  // For COMPILED_STUBs called from builtins, the function pointer
-  // is a SMI indicating an internal frame.
+  // For COMPILED_STUBs called from builtins, the function pointer is a SMI
+  // indicating an internal frame.
   if (function->IsSmi()) {
     function = NULL;
   }
   if (function != NULL && function->IsOptimized()) {
     function->shared()->increment_deopt_count();
   }
-  compiled_code_ =
-      FindOptimizedCode(isolate, function, type, from, optimized_code);
-  if (FLAG_trace_deopt && type == EAGER) {
-    compiled_code_->PrintDeoptLocation(bailout_id);
-  }
+  compiled_code_ = FindOptimizedCode(function, optimized_code);
+  if (TraceEnabledFor(type)) Trace();
   ASSERT(HEAP->allow_allocation(false));
   unsigned size = ComputeInputFrameSize();
   input_ = new(size) FrameDescription(size, function);
@@ -571,6 +544,57 @@ Deoptimizer::Deoptimizer(Isolate* isolate,
 }
 
 
+Code* Deoptimizer::FindOptimizedCode(JSFunction* function,
+                                     Code* optimized_code) {
+  switch (bailout_type_) {
+    case Deoptimizer::EAGER:
+      ASSERT(from_ == NULL);
+      return function->code();
+    case Deoptimizer::LAZY: {
+      Code* compiled_code =
+          isolate_->deoptimizer_data()->FindDeoptimizingCode(from_);
+      return (compiled_code == NULL)
+          ? static_cast<Code*>(isolate_->heap()->FindCodeObject(from_))
+          : compiled_code;
+    }
+    case Deoptimizer::OSR: {
+      // The function has already been optimized and we're transitioning
+      // from the unoptimized shared version to the optimized one in the
+      // function. The return address (from_) points to unoptimized code.
+      Code* compiled_code = function->code();
+      ASSERT(compiled_code->kind() == Code::OPTIMIZED_FUNCTION);
+      ASSERT(!compiled_code->contains(from_));
+      return compiled_code;
+    }
+    case Deoptimizer::DEBUGGER:
+      ASSERT(optimized_code->contains(from_));
+      return optimized_code;
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
+void Deoptimizer::Trace() {
+  PrintF("**** %s: ", Deoptimizer::MessageFor(bailout_type_));
+  PrintFunctionName();
+  PrintF(" at id #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
+         bailout_id_,
+         reinterpret_cast<intptr_t>(from_),
+         fp_to_sp_delta_ - (2 * kPointerSize));
+  if (bailout_type_ == EAGER) compiled_code_->PrintDeoptLocation(bailout_id_);
+}
+
+
+void Deoptimizer::PrintFunctionName() {
+  if (function_->IsJSFunction()) {
+    function_->PrintName();
+  } else {
+    PrintF("%s", Code::Kind2String(compiled_code_->kind()));
+  }
+}
+
+
 Deoptimizer::~Deoptimizer() {
   ASSERT(input_ == NULL && output_ == NULL);
 }
@@ -681,7 +705,7 @@ void Deoptimizer::DoComputeOutputFrames() {
     PrintF("[deoptimizing%s: begin 0x%08" V8PRIxPTR " ",
            (bailout_type_ == LAZY ? " (lazy)" : ""),
            reinterpret_cast<intptr_t>(function_));
-    function_->PrintName();
+    PrintFunctionName();
     PrintF(" @%d]\n", bailout_id_);
   }
 
@@ -761,7 +785,7 @@ void Deoptimizer::DoComputeOutputFrames() {
     JSFunction* function = output_[index]->GetFunction();
     PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ",
            reinterpret_cast<intptr_t>(function));
-    function->PrintName();
+    if (function != NULL) function->PrintName();
     PrintF(" => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
            " took %0.3f ms]\n",
            node_id.ToInt(),
index 2c0fb93..870fdb2 100644 (file)
@@ -144,6 +144,9 @@ class Deoptimizer : public Malloced {
     DEBUGGER
   };
 
+  static bool TraceEnabledFor(BailoutType type);
+  static const char* MessageFor(BailoutType type);
+
   int output_count() const { return output_count_; }
 
   Code::Kind compiled_code_kind() const { return compiled_code_->kind(); }
@@ -326,6 +329,9 @@ class Deoptimizer : public Malloced {
               Address from,
               int fp_to_sp_delta,
               Code* optimized_code);
+  Code* FindOptimizedCode(JSFunction* function, Code* optimized_code);
+  void Trace();
+  void PrintFunctionName();
   void DeleteFrameDescriptions();
 
   void DoComputeOutputFrames();
index e43a94a..e1d6da6 100644 (file)
@@ -9157,6 +9157,30 @@ void Code::PrintDeoptLocation(int bailout_id) {
 }
 
 
+// Identify kind of code.
+const char* Code::Kind2String(Kind kind) {
+  switch (kind) {
+    case FUNCTION: return "FUNCTION";
+    case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION";
+    case COMPILED_STUB: return "COMPILED_STUB";
+    case STUB: return "STUB";
+    case BUILTIN: return "BUILTIN";
+    case LOAD_IC: return "LOAD_IC";
+    case KEYED_LOAD_IC: return "KEYED_LOAD_IC";
+    case STORE_IC: return "STORE_IC";
+    case KEYED_STORE_IC: return "KEYED_STORE_IC";
+    case CALL_IC: return "CALL_IC";
+    case KEYED_CALL_IC: return "KEYED_CALL_IC";
+    case UNARY_OP_IC: return "UNARY_OP_IC";
+    case BINARY_OP_IC: return "BINARY_OP_IC";
+    case COMPARE_IC: return "COMPARE_IC";
+    case TO_BOOLEAN_IC: return "TO_BOOLEAN_IC";
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
 #ifdef ENABLE_DISASSEMBLER
 
 void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) {
@@ -9335,30 +9359,6 @@ void DeoptimizationOutputData::DeoptimizationOutputDataPrint(FILE* out) {
 }
 
 
-// Identify kind of code.
-const char* Code::Kind2String(Kind kind) {
-  switch (kind) {
-    case FUNCTION: return "FUNCTION";
-    case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION";
-    case COMPILED_STUB: return "COMPILED_STUB";
-    case STUB: return "STUB";
-    case BUILTIN: return "BUILTIN";
-    case LOAD_IC: return "LOAD_IC";
-    case KEYED_LOAD_IC: return "KEYED_LOAD_IC";
-    case STORE_IC: return "STORE_IC";
-    case KEYED_STORE_IC: return "KEYED_STORE_IC";
-    case CALL_IC: return "CALL_IC";
-    case KEYED_CALL_IC: return "KEYED_CALL_IC";
-    case UNARY_OP_IC: return "UNARY_OP_IC";
-    case BINARY_OP_IC: return "BINARY_OP_IC";
-    case COMPARE_IC: return "COMPARE_IC";
-    case TO_BOOLEAN_IC: return "TO_BOOLEAN_IC";
-  }
-  UNREACHABLE();
-  return NULL;
-}
-
-
 const char* Code::ICState2String(InlineCacheState state) {
   switch (state) {
     case UNINITIALIZED: return "UNINITIALIZED";
index 8fe7fa7..88194c4 100644 (file)
@@ -4211,6 +4211,8 @@ class Code: public HeapObject {
   // Flags.
   STATIC_ASSERT(LAST_CODE_KIND < 16);
 
+  static const char* Kind2String(Kind kind);
+
   // Types of stubs.
   enum StubType {
     NORMAL,
@@ -4232,7 +4234,6 @@ class Code: public HeapObject {
 
 #ifdef ENABLE_DISASSEMBLER
   // Printing
-  static const char* Kind2String(Kind kind);
   static const char* ICState2String(InlineCacheState state);
   static const char* StubType2String(StubType type);
   static void PrintExtraICState(FILE* out, Kind kind, ExtraICState extra);