Revision: 24700
Author:   [email protected]
Date:     Fri Oct 17 15:44:02 2014 UTC
Log:      Tick processor: Print C++ entry points

[email protected], [email protected], [email protected]

Review URL: https://codereview.chromium.org/638633002
https://code.google.com/p/v8/source/detail?r=24700

Modified:
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/cpu-profiler.cc
 /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
 /branches/bleeding_edge/src/isolate.h
 /branches/bleeding_edge/src/sampler.cc
 /branches/bleeding_edge/src/sampler.h
 /branches/bleeding_edge/src/x64/macro-assembler-x64.cc
 /branches/bleeding_edge/test/cctest/trace-extension.cc
 /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default
 /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.func-info
 /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.gc-state
/branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown
 /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic
 /branches/bleeding_edge/tools/codemap.js
 /branches/bleeding_edge/tools/logreader.js
 /branches/bleeding_edge/tools/profile.js
 /branches/bleeding_edge/tools/tickprocessor.js

=======================================
--- /branches/bleeding_edge/src/api.cc  Fri Oct 17 09:04:58 2014 UTC
+++ /branches/bleeding_edge/src/api.cc  Fri Oct 17 15:44:02 2014 UTC
@@ -6657,8 +6657,8 @@
 void Isolate::GetStackSample(const RegisterState& state, void** frames,
size_t frames_limit, SampleInfo* sample_info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
-  i::TickSample::GetStackSample(isolate, state, frames, frames_limit,
-                                sample_info);
+ i::TickSample::GetStackSample(isolate, state, i::TickSample::kSkipCEntryFrame,
+                                frames, frames_limit, sample_info);
 }


=======================================
--- /branches/bleeding_edge/src/cpu-profiler.cc Tue Oct  7 14:45:17 2014 UTC
+++ /branches/bleeding_edge/src/cpu-profiler.cc Fri Oct 17 15:44:02 2014 UTC
@@ -48,7 +48,7 @@
     regs.fp = frame->fp();
     regs.pc = frame->pc();
   }
-  record.sample.Init(isolate, regs);
+  record.sample.Init(isolate, regs, TickSample::kSkipCEntryFrame);
   ticks_from_vm_buffer_.Enqueue(record);
 }

=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Mon Oct 13 14:41:33 2014 UTC +++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Fri Oct 17 15:44:02 2014 UTC
@@ -942,8 +942,10 @@
   // Save the frame pointer and the context in top.
ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate());
   ExternalReference context_address(Isolate::kContextAddress, isolate());
+ ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate());
   mov(Operand::StaticVariable(c_entry_fp_address), ebp);
   mov(Operand::StaticVariable(context_address), esi);
+  mov(Operand::StaticVariable(c_function_address), ebx);
 }


=======================================
--- /branches/bleeding_edge/src/isolate.h       Tue Oct 14 08:43:33 2014 UTC
+++ /branches/bleeding_edge/src/isolate.h       Fri Oct 17 15:44:02 2014 UTC
@@ -169,6 +169,7 @@
 #define FOR_EACH_ISOLATE_ADDRESS_NAME(C)                \
   C(Handler, handler)                                   \
   C(CEntryFP, c_entry_fp)                               \
+  C(CFunction, c_function)                              \
   C(Context, context)                                   \
   C(PendingException, pending_exception)                \
   C(ExternalCaughtException, external_caught_exception) \
@@ -288,6 +289,7 @@
   // Stack.
   Address c_entry_fp_;  // the frame pointer of the top c entry frame
   Address handler_;   // try-blocks are chained through the stack
+  Address c_function_;  // C function that was called at c entry.

   // Throwing an exception may cause a Promise rejection.  For this purpose
   // we keep track of a stack of nested promises and the corresponding
@@ -652,11 +654,15 @@
     return thread->c_entry_fp_;
   }
static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
+  Address c_function() { return thread_local_top_.c_function_; }

   inline Address* c_entry_fp_address() {
     return &thread_local_top_.c_entry_fp_;
   }
   inline Address* handler_address() { return &thread_local_top_.handler_; }
+  inline Address* c_function_address() {
+    return &thread_local_top_.c_function_;
+  }

   // Bottom JS entry.
   Address js_entry_sp() {
=======================================
--- /branches/bleeding_edge/src/sampler.cc      Wed Oct  8 11:51:57 2014 UTC
+++ /branches/bleeding_edge/src/sampler.cc      Fri Oct 17 15:44:02 2014 UTC
@@ -570,7 +570,8 @@
 // StackTracer implementation
 //
 DISABLE_ASAN void TickSample::Init(Isolate* isolate,
-                                   const v8::RegisterState& regs) {
+                                   const v8::RegisterState& regs,
+ RecordCEntryFrame record_c_entry_frame) {
   timestamp = base::TimeTicks::HighResolutionNow();
   pc = reinterpret_cast<Address>(regs.pc);
   state = isolate->current_vm_state();
@@ -601,13 +602,14 @@
   top_frame_type = it.top_frame_type();

   SampleInfo info;
-  GetStackSample(isolate, regs, reinterpret_cast<void**>(&stack[0]),
-                 kMaxFramesCount, &info);
+  GetStackSample(isolate, regs, record_c_entry_frame,
+ reinterpret_cast<void**>(&stack[0]), kMaxFramesCount, &info);
   frames_count = static_cast<unsigned>(info.frames_count);
 }


void TickSample::GetStackSample(Isolate* isolate, const v8::RegisterState& regs,
+                                RecordCEntryFrame record_c_entry_frame,
                                 void** frames, size_t frames_limit,
                                 v8::SampleInfo* sample_info) {
   sample_info->frames_count = 0;
@@ -620,6 +622,10 @@
   SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp),
reinterpret_cast<Address>(regs.sp), js_entry_sp);
   size_t i = 0;
+  if (record_c_entry_frame == kIncludeCEntryFrame && !it.done() &&
+      it.top_frame_type() == StackFrame::EXIT) {
+    frames[i++] = isolate->c_function();
+  }
   while (!it.done() && i < frames_limit) {
     frames[i++] = it.frame()->pc();
     it.Advance();
@@ -696,7 +702,7 @@
   TickSample* sample = isolate_->cpu_profiler()->StartTickSample();
   TickSample sample_obj;
   if (sample == NULL) sample = &sample_obj;
-  sample->Init(isolate_, state);
+  sample->Init(isolate_, state, TickSample::kIncludeCEntryFrame);
   if (is_counting_samples_) {
     if (sample->state == JS || sample->state == EXTERNAL) {
       ++js_and_external_sample_count_;
=======================================
--- /branches/bleeding_edge/src/sampler.h       Mon Sep 29 12:59:54 2014 UTC
+++ /branches/bleeding_edge/src/sampler.h       Fri Oct 17 15:44:02 2014 UTC
@@ -25,6 +25,11 @@

 // TickSample captures the information collected for each sample.
 struct TickSample {
+  // Internal profiling (with --prof + tools/$OS-tick-processor) wants to
+  // include the runtime function we're calling. Externally exposed tick
+  // samples don't care.
+  enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };
+
   TickSample()
       : state(OTHER),
         pc(NULL),
@@ -32,8 +37,10 @@
         frames_count(0),
         has_external_callback(false),
         top_frame_type(StackFrame::NONE) {}
-  void Init(Isolate* isolate, const v8::RegisterState& state);
+  void Init(Isolate* isolate, const v8::RegisterState& state,
+            RecordCEntryFrame record_c_entry_frame);
static void GetStackSample(Isolate* isolate, const v8::RegisterState& state,
+                             RecordCEntryFrame record_c_entry_frame,
                              void** frames, size_t frames_limit,
                              v8::SampleInfo* sample_info);
   StateTag state;  // The state of the VM.
=======================================
--- /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Fri Oct 17 04:18:38 2014 UTC +++ /branches/bleeding_edge/src/x64/macro-assembler-x64.cc Fri Oct 17 15:44:02 2014 UTC
@@ -4093,6 +4093,7 @@

   Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp);
   Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi);
+  Store(ExternalReference(Isolate::kCFunctionAddress, isolate()), rbx);
 }


=======================================
--- /branches/bleeding_edge/test/cctest/trace-extension.cc Tue Jun 3 08:12:43 2014 UTC +++ /branches/bleeding_edge/test/cctest/trace-extension.cc Fri Oct 17 15:44:02 2014 UTC
@@ -91,7 +91,8 @@
   // sp is only used to define stack high bound
   regs.sp =
       reinterpret_cast<Address>(trace_env.sample) - 10240;
-  trace_env.sample->Init(CcTest::i_isolate(), regs);
+  trace_env.sample->Init(CcTest::i_isolate(), regs,
+                         TickSample::kSkipCEntryFrame);
 }


=======================================
--- /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default Mon Aug 4 09:13:58 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.default Fri Oct 17 15:44:02 2014 UTC
@@ -24,6 +24,13 @@
       4   30.8%          Shared libraries
       2   15.4%          Unaccounted

+ [C++ entry points]:
+   ticks    cpp   total   name
+ 2 40.0% 15.4% v8::internal::Runtime_Math_exp(v8::internal::Arguments) + 1 20.0% 7.7% v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*) + 1 20.0% 7.7% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
+      1   20.0%    7.7%  exp
+
  [Bottom up (heavy) profile]:
   Note: percentage shows a share of a particular caller in the total
   amount of its parent calls.
=======================================
--- /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.func-info Mon Aug 4 09:13:58 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.func-info Fri Oct 17 15:44:02 2014 UTC
@@ -18,6 +18,9 @@
       0    0.0%    0.0%  GC
       0    0.0%          Shared libraries

+ [C++ entry points]:
+   ticks    cpp   total   name
+
  [Bottom up (heavy) profile]:
   Note: percentage shows a share of a particular caller in the total
   amount of its parent calls.
=======================================
--- /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.gc-state Mon Aug 4 09:13:58 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.gc-state Fri Oct 17 15:44:02 2014 UTC
@@ -16,6 +16,9 @@
       0    0.0%    0.0%  GC
       0    0.0%          Shared libraries

+ [C++ entry points]:
+   ticks    cpp   total   name
+
  [Bottom up (heavy) profile]:
   Note: percentage shows a share of a particular caller in the total
   amount of its parent calls.
=======================================
--- /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown Mon Aug 4 09:13:58 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.ignore-unknown Fri Oct 17 15:44:02 2014 UTC
@@ -23,6 +23,13 @@
       0    0.0%    0.0%  GC
       4   36.4%          Shared libraries

+ [C++ entry points]:
+   ticks    cpp   total   name
+ 2 40.0% 18.2% v8::internal::Runtime_Math_exp(v8::internal::Arguments) + 1 20.0% 9.1% v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*) + 1 20.0% 9.1% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
+      1   20.0%    9.1%  exp
+
  [Bottom up (heavy) profile]:
   Note: percentage shows a share of a particular caller in the total
   amount of its parent calls.
=======================================
--- /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic Mon Aug 4 09:13:58 2014 UTC +++ /branches/bleeding_edge/test/mjsunit/tools/tickprocessor-test.separate-ic Fri Oct 17 15:44:02 2014 UTC
@@ -26,6 +26,13 @@
       4   30.8%          Shared libraries
       2   15.4%          Unaccounted

+ [C++ entry points]:
+   ticks    cpp   total   name
+ 2 40.0% 15.4% v8::internal::Runtime_Math_exp(v8::internal::Arguments) + 1 20.0% 7.7% v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*) + 1 20.0% 7.7% v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
+      1   20.0%    7.7%  exp
+
  [Bottom up (heavy) profile]:
   Note: percentage shows a share of a particular caller in the total
   amount of its parent calls.
=======================================
--- /branches/bleeding_edge/tools/codemap.js    Wed Sep 14 11:47:03 2011 UTC
+++ /branches/bleeding_edge/tools/codemap.js    Fri Oct 17 15:44:02 2014 UTC
@@ -258,11 +258,13 @@
  *
  * @param {number} size Code entry size in bytes.
  * @param {string} opt_name Code entry name.
+ * @param {string} opt_type Code entry type, e.g. SHARED_LIB, CPP.
  * @constructor
  */
-CodeMap.CodeEntry = function(size, opt_name) {
+CodeMap.CodeEntry = function(size, opt_name, opt_type) {
   this.size = size;
   this.name = opt_name || '';
+  this.type = opt_type || '';
   this.nameUpdated_ = false;
 };

=======================================
--- /branches/bleeding_edge/tools/logreader.js  Thu Sep 15 13:20:42 2011 UTC
+++ /branches/bleeding_edge/tools/logreader.js  Fri Oct 17 15:44:02 2014 UTC
@@ -108,6 +108,8 @@
     // Filter out possible 'overflow' string.
     } else if (firstChar != 'o') {
       fullStack.push(parseInt(frame, 16));
+    } else {
+      print("dropping: " + frame);
     }
   }
   return fullStack;
=======================================
--- /branches/bleeding_edge/tools/profile.js    Mon Sep 12 10:50:40 2011 UTC
+++ /branches/bleeding_edge/tools/profile.js    Fri Oct 17 15:44:02 2014 UTC
@@ -36,6 +36,7 @@
   this.codeMap_ = new CodeMap();
   this.topDownTree_ = new CallTree();
   this.bottomUpTree_ = new CallTree();
+  this.c_entries_ = {};
 };


@@ -102,7 +103,7 @@
 Profile.prototype.addLibrary = function(
     name, startAddr, endAddr) {
   var entry = new CodeMap.CodeEntry(
-      endAddr - startAddr, name);
+      endAddr - startAddr, name, 'SHARED_LIB');
   this.codeMap_.addLibrary(startAddr, entry);
   return entry;
 };
@@ -118,7 +119,7 @@
 Profile.prototype.addStaticCode = function(
     name, startAddr, endAddr) {
   var entry = new CodeMap.CodeEntry(
-      endAddr - startAddr, name);
+      endAddr - startAddr, name, 'CPP');
   this.codeMap_.addStaticCode(startAddr, entry);
   return entry;
 };
@@ -250,10 +251,26 @@
  */
 Profile.prototype.resolveAndFilterFuncs_ = function(stack) {
   var result = [];
+  var last_seen_c_function = '';
+  var look_for_first_c_function = false;
   for (var i = 0; i < stack.length; ++i) {
     var entry = this.codeMap_.findEntry(stack[i]);
     if (entry) {
       var name = entry.getName();
+      if (i == 0 && (entry.type == 'CPP' || entry.type == 'SHARED_LIB')) {
+        look_for_first_c_function = true;
+      }
+      if (look_for_first_c_function) {
+        if (entry.type == 'CPP') {
+          last_seen_c_function = name;
+        } else if (i > 0 && last_seen_c_function != '') {
+          if (this.c_entries_[last_seen_c_function] === undefined) {
+            this.c_entries_[last_seen_c_function] = 0;
+          }
+          this.c_entries_[last_seen_c_function]++;
+          look_for_first_c_function = false;  // Found it, we're done.
+        }
+      }
       if (!this.skipThisFunction(name)) {
         result.push(name);
       }
@@ -381,6 +398,28 @@
 };


+Profile.CEntryNode = function(name, ticks) {
+  this.name = name;
+  this.ticks = ticks;
+}
+
+
+Profile.prototype.getCEntryProfile = function() {
+  var result = [new Profile.CEntryNode("TOTAL", 0)];
+  var total_ticks = 0;
+  for (var f in this.c_entries_) {
+    var ticks = this.c_entries_[f];
+    total_ticks += ticks;
+    result.push(new Profile.CEntryNode(f, ticks));
+  }
+  result[0].ticks = total_ticks;  // Sorting will keep this at index 0.
+  result.sort(function(n1, n2) {
+    return n2.ticks - n1.ticks || (n2.name < n1.name ? -1 : 1)
+  });
+  return result;
+}
+
+
 /**
  * Cleans up function entries that are not referenced by code entries.
  */
@@ -415,8 +454,7 @@
  * @constructor
  */
 Profile.DynamicCodeEntry = function(size, type, name) {
-  CodeMap.CodeEntry.call(this, size, name);
-  this.type = type;
+  CodeMap.CodeEntry.call(this, size, name, type);
 };


@@ -456,8 +494,7 @@
  * @constructor
  */
 Profile.DynamicFuncCodeEntry = function(size, type, func, state) {
-  CodeMap.CodeEntry.call(this, size);
-  this.type = type;
+  CodeMap.CodeEntry.call(this, size, '', type);
   this.func = func;
   this.state = state;
 };
=======================================
--- /branches/bleeding_edge/tools/tickprocessor.js Mon Aug 4 08:31:49 2014 UTC +++ /branches/bleeding_edge/tools/tickprocessor.js Fri Oct 17 15:44:02 2014 UTC
@@ -484,6 +484,15 @@
     this.printLine('Unaccounted', this.ticks_.unaccounted,
                    this.ticks_.total, null);
   }
+
+  print('\n [C++ entry points]:');
+  print('   ticks    cpp   total   name');
+  var c_entry_functions = this.profile_.getCEntryProfile();
+  var total_c_entry = c_entry_functions[0].ticks;
+  for (var i = 1; i < c_entry_functions.length; i++) {
+    c = c_entry_functions[i];
+    this.printLine(c.name, c.ticks, total_c_entry, totalTicks);
+  }

   this.printHeavyProfHeader();
   var heavyProfile = this.profile_.getBottomUpProfile();

--
--
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