Revision: 21418
Author:   [email protected]
Date:     Thu May 22 05:36:27 2014 UTC
Log:      Introduce a separate event for CodeDeopt

The reuse of CodeCreateEvent for deopt events caused a CodeCreateEvent
fired twice for a code object. When the event was processed for the first
time it seized the no-fp-ranges from code object, so the second event
had no ranges info leaving code entry without them.
As a result when a cpu profile sample falls into the region it missed the
2nd stack frame.

LOG=N
BUG=
[email protected], [email protected]

Review URL: https://codereview.chromium.org/290093005
http://code.google.com/p/v8/source/detail?r=21418

Modified:
 /branches/bleeding_edge/src/cpu-profiler-inl.h
 /branches/bleeding_edge/src/cpu-profiler.cc
 /branches/bleeding_edge/src/cpu-profiler.h
 /branches/bleeding_edge/src/log.cc
 /branches/bleeding_edge/src/log.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/serialize.cc
 /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc

=======================================
--- /branches/bleeding_edge/src/cpu-profiler-inl.h Tue Apr 29 06:42:26 2014 UTC +++ /branches/bleeding_edge/src/cpu-profiler-inl.h Thu May 22 05:36:27 2014 UTC
@@ -26,6 +26,14 @@
 void CodeMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
   code_map->MoveCode(from, to);
 }
+
+
+void CodeDisableOptEventRecord::UpdateCodeMap(CodeMap* code_map) {
+  CodeEntry* entry = code_map->FindEntry(start);
+  if (entry != NULL) {
+    entry->set_bailout_reason(bailout_reason);
+  }
+}


 void SharedFunctionInfoMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.cc Tue May  6 08:18:09 2014 UTC
+++ /branches/bleeding_edge/src/cpu-profiler.cc Thu May 22 05:36:27 2014 UTC
@@ -302,6 +302,15 @@
   rec->to = to;
   processor_->Enqueue(evt_rec);
 }
+
+
+void CpuProfiler::CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) {
+  CodeEventsContainer evt_rec(CodeEventRecord::CODE_DISABLE_OPT);
+  CodeDisableOptEventRecord* rec = &evt_rec.CodeDisableOptEventRecord_;
+  rec->start = code->address();
+ rec->bailout_reason = GetBailoutReason(shared->DisableOptimizationReason());
+  processor_->Enqueue(evt_rec);
+}


 void CpuProfiler::CodeDeleteEvent(Address from) {
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.h  Tue Apr 29 06:42:26 2014 UTC
+++ /branches/bleeding_edge/src/cpu-profiler.h  Thu May 22 05:36:27 2014 UTC
@@ -26,6 +26,7 @@
 #define CODE_EVENTS_TYPE_LIST(V)                                   \
   V(CODE_CREATION,    CodeCreateEventRecord)                       \
   V(CODE_MOVE,        CodeMoveEventRecord)                         \
+  V(CODE_DISABLE_OPT, CodeDisableOptEventRecord)                   \
   V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord)           \
   V(REPORT_BUILTIN,   ReportBuiltinEventRecord)

@@ -65,6 +66,15 @@
 };


+class CodeDisableOptEventRecord : public CodeEventRecord {
+ public:
+  Address start;
+  const char* bailout_reason;
+
+  INLINE(void UpdateCodeMap(CodeMap* code_map));
+};
+
+
 class SharedFunctionInfoMoveEventRecord : public CodeEventRecord {
  public:
   Address from;
@@ -225,6 +235,7 @@
                                Code* code, int args_count);
   virtual void CodeMovingGCEvent() {}
   virtual void CodeMoveEvent(Address from, Address to);
+  virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared);
   virtual void CodeDeleteEvent(Address from);
   virtual void GetterCallbackEvent(Name* name, Address entry_point);
   virtual void RegExpCodeCreateEvent(Code* code, String* source);
=======================================
--- /branches/bleeding_edge/src/log.cc  Fri May  9 08:40:18 2014 UTC
+++ /branches/bleeding_edge/src/log.cc  Thu May 22 05:36:27 2014 UTC
@@ -230,6 +230,7 @@
   virtual ~PerfBasicLogger();

   virtual void CodeMoveEvent(Address from, Address to) { }
+ virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
   virtual void CodeDeleteEvent(Address from) { }

  private:
@@ -295,6 +296,7 @@
   virtual ~PerfJitLogger();

   virtual void CodeMoveEvent(Address from, Address to) { }
+ virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
   virtual void CodeDeleteEvent(Address from) { }

  private:
@@ -457,6 +459,7 @@
   virtual ~LowLevelLogger();

   virtual void CodeMoveEvent(Address from, Address to);
+ virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
   virtual void CodeDeleteEvent(Address from);
   virtual void SnapshotPositionEvent(Address addr, int pos);
   virtual void CodeMovingGCEvent();
@@ -623,6 +626,7 @@
   explicit JitLogger(JitCodeEventHandler code_event_handler);

   virtual void CodeMoveEvent(Address from, Address to);
+ virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) { }
   virtual void CodeDeleteEvent(Address from);
   virtual void AddCodeLinePosInfoEvent(
       void* jit_handler_data,
@@ -1444,6 +1448,24 @@
   msg.Append('\n');
   msg.WriteToLogFile();
 }
+
+
+void Logger::CodeDisableOptEvent(Code* code,
+                                 SharedFunctionInfo* shared) {
+  PROFILER_LOG(CodeDisableOptEvent(code, shared));
+
+  if (!is_logging_code_events()) return;
+  CALL_LISTENERS(CodeDisableOptEvent(code, shared));
+
+  if (!FLAG_log_code || !log_->IsEnabled()) return;
+  Log::MessageBuilder msg(log_);
+  msg.Append("%s,", kLogEventsNames[CODE_DISABLE_OPT_EVENT]);
+  SmartArrayPointer<char> name =
+ shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+  msg.Append("\"%s\",", name.get());
+ msg.Append("\"%s\"\n", GetBailoutReason(shared->DisableOptimizationReason()));
+  msg.WriteToLogFile();
+}


 void Logger::CodeMovingGCEvent() {
=======================================
--- /branches/bleeding_edge/src/log.h   Tue May  6 09:28:08 2014 UTC
+++ /branches/bleeding_edge/src/log.h   Thu May 22 05:36:27 2014 UTC
@@ -79,6 +79,7 @@

 #define LOG_EVENTS_AND_TAGS_LIST(V)                                     \
   V(CODE_CREATION_EVENT,            "code-creation")                    \
+  V(CODE_DISABLE_OPT_EVENT,         "code-disable-optimization")        \
   V(CODE_MOVE_EVENT,                "code-move")                        \
   V(CODE_DELETE_EVENT,              "code-delete")                      \
   V(CODE_MOVING_GC,                 "code-moving-gc")                   \
@@ -237,6 +238,8 @@
                        CompilationInfo* info,
                        Name* source, int line, int column);
   void CodeCreateEvent(LogEventsAndTags tag, Code* code, int args_count);
+  // Emits a code deoptimization event.
+  void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared);
   void CodeMovingGCEvent();
   // Emits a code create event for a RegExp.
   void RegExpCodeCreateEvent(Code* code, String* source);
@@ -470,6 +473,7 @@
   virtual void CodeDeleteEvent(Address from) = 0;
   virtual void SharedFunctionInfoMoveEvent(Address from, Address to) = 0;
   virtual void CodeMovingGCEvent() = 0;
+ virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) = 0;
 };


=======================================
--- /branches/bleeding_edge/src/objects.cc      Wed May 21 12:16:47 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Thu May 22 05:36:27 2014 UTC
@@ -10706,9 +10706,7 @@
   if (code()->kind() == Code::FUNCTION) {
     code()->set_optimizable(false);
   }
-  PROFILE(GetIsolate(),
-      LogExistingFunction(Handle<SharedFunctionInfo>(this),
-                          Handle<Code>(code())));
+  PROFILE(GetIsolate(), CodeDisableOptEvent(code(), this));
   if (FLAG_trace_opt) {
     PrintF("[disabled optimization for ");
     ShortPrint();
=======================================
--- /branches/bleeding_edge/src/serialize.cc    Mon May  5 07:10:38 2014 UTC
+++ /branches/bleeding_edge/src/serialize.cc    Thu May 22 05:36:27 2014 UTC
@@ -629,6 +629,9 @@
   virtual void CodeMoveEvent(Address from, Address to) {
     address_to_name_map_.Move(from, to);
   }
+
+ virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared) {
+  }

   virtual void CodeDeleteEvent(Address from) {
     address_to_name_map_.Remove(from);
=======================================
--- /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc Thu May 8 09:47:17 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc Thu May 22 05:36:27 2014 UTC
@@ -585,6 +585,72 @@

   profile->Delete();
 }
+
+
+static const char* hot_deopt_no_frame_entry_test_source =
+"function foo(a, b) {\n"
+"    try {\n"
+"      return a + b;\n"
+"    } catch (e) { }\n"
+"}\n"
+"function start(timeout) {\n"
+"  var start = Date.now();\n"
+"  do {\n"
+"    for (var i = 1; i < 1000; ++i) foo(1, i);\n"
+"    var duration = Date.now() - start;\n"
+"  } while (duration < timeout);\n"
+"  return duration;\n"
+"}\n";
+
+// Check that the profile tree for the script above will look like the
+// following:
+//
+// [Top down]:
+//  1062     0  (root) [-1]
+//  1054     0    start [-1]
+//  1054     1      foo [-1]
+//     2     2    (program) [-1]
+//     6     6    (garbage collector) [-1]
+//
+// The test checks no FP ranges are present in a deoptimized funcion.
+// If 'foo' has no ranges the samples falling into the prologue will miss the
+// 'start' function on the stack, so 'foo' will be attached to the (root).
+TEST(HotDeoptNoFrameEntry) {
+  LocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+
+  v8::Script::Compile(v8::String::NewFromUtf8(
+      env->GetIsolate(),
+      hot_deopt_no_frame_entry_test_source))->Run();
+  v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
+ env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "start")));
+
+  int32_t profiling_interval_ms = 200;
+  v8::Handle<v8::Value> args[] = {
+    v8::Integer::New(env->GetIsolate(), profiling_interval_ms)
+  };
+  v8::CpuProfile* profile =
+      RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200);
+  function->Call(env->Global(), ARRAY_SIZE(args), args);
+
+  const v8::CpuProfileNode* root = profile->GetTopDownRoot();
+
+  ScopedVector<v8::Handle<v8::String> > names(3);
+  names[0] = v8::String::NewFromUtf8(
+      env->GetIsolate(), ProfileGenerator::kGarbageCollectorEntryName);
+  names[1] = v8::String::NewFromUtf8(env->GetIsolate(),
+                                     ProfileGenerator::kProgramEntryName);
+  names[2] = v8::String::NewFromUtf8(env->GetIsolate(), "start");
+  CheckChildrenNames(root, names);
+
+  const v8::CpuProfileNode* startNode =
+      GetChild(env->GetIsolate(), root, "start");
+  CHECK_EQ(1, startNode->GetChildrenCount());
+
+  GetChild(env->GetIsolate(), startNode, "foo");
+
+  profile->Delete();
+}


 TEST(CollectCpuProfileSamples) {

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to