Revision: 9275
Author:   [email protected]
Date:     Wed Sep 14 04:47:03 2011
Log:      Eliminate the need for code delete events in CPU profiler.

Events are still generated for tick processor on performance testing
server to work, as soon as scripts will be updated, it will be safe
to remove code delete events emitting code.

[email protected]
BUG=v8:1466
TEST=existing tests in test-profile-generator,test-cpu-profiler and mjsunit/tools

Review URL: http://codereview.chromium.org/7864017
http://code.google.com/p/v8/source/detail?r=9275

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/profile-generator-inl.h
 /branches/bleeding_edge/src/profile-generator.cc
 /branches/bleeding_edge/src/profile-generator.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/test/cctest/log-eq-of-logging-and-traversal.js
 /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc
 /branches/bleeding_edge/test/cctest/test-log.cc
 /branches/bleeding_edge/test/cctest/test-profile-generator.cc
 /branches/bleeding_edge/tools/codemap.js

=======================================
--- /branches/bleeding_edge/src/cpu-profiler-inl.h      Wed Jul 13 02:09:04 2011
+++ /branches/bleeding_edge/src/cpu-profiler-inl.h      Wed Sep 14 04:47:03 2011
@@ -49,11 +49,6 @@
 void CodeMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
   code_map->MoveCode(from, to);
 }
-
-
-void CodeDeleteEventRecord::UpdateCodeMap(CodeMap* code_map) {
-  code_map->DeleteCode(start);
-}


 void SharedFunctionInfoMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
=======================================
--- /branches/bleeding_edge/src/cpu-profiler.cc Wed Jul 13 02:09:04 2011
+++ /branches/bleeding_edge/src/cpu-profiler.cc Wed Sep 14 04:47:03 2011
@@ -135,16 +135,6 @@
   rec->to = to;
   events_buffer_.Enqueue(evt_rec);
 }
-
-
-void ProfilerEventsProcessor::CodeDeleteEvent(Address from) {
-  CodeEventsContainer evt_rec;
-  CodeDeleteEventRecord* rec = &evt_rec.CodeDeleteEventRecord_;
-  rec->type = CodeEventRecord::CODE_DELETE;
-  rec->order = ++enqueue_order_;
-  rec->start = from;
-  events_buffer_.Enqueue(evt_rec);
-}


 void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from,
@@ -425,7 +415,6 @@


 void CpuProfiler::CodeDeleteEvent(Address from) {
-  Isolate::Current()->cpu_profiler()->processor_->CodeDeleteEvent(from);
 }


=======================================
--- /branches/bleeding_edge/src/cpu-profiler.h  Wed Jul 13 02:09:04 2011
+++ /branches/bleeding_edge/src/cpu-profiler.h  Wed Sep 14 04:47:03 2011
@@ -48,7 +48,6 @@
 #define CODE_EVENTS_TYPE_LIST(V)                                   \
   V(CODE_CREATION,    CodeCreateEventRecord)                       \
   V(CODE_MOVE,        CodeMoveEventRecord)                         \
-  V(CODE_DELETE,      CodeDeleteEventRecord)                       \
   V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord)


@@ -87,14 +86,6 @@
 };


-class CodeDeleteEventRecord : public CodeEventRecord {
- public:
-  Address start;
-
-  INLINE(void UpdateCodeMap(CodeMap* code_map));
-};
-
-
 class SharedFunctionInfoMoveEventRecord : public CodeEventRecord {
  public:
   Address from;
=======================================
--- /branches/bleeding_edge/src/log.cc  Fri Sep  9 15:39:47 2011
+++ /branches/bleeding_edge/src/log.cc  Wed Sep 14 04:47:03 2011
@@ -1525,6 +1525,51 @@
     if (obj->IsCode()) LogCodeObject(obj);
   }
 }
+
+
+void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
+                                 Handle<Code> code) {
+  Handle<String> func_name(shared->DebugName());
+  if (shared->script()->IsScript()) {
+    Handle<Script> script(Script::cast(shared->script()));
+    if (script->name()->IsString()) {
+      Handle<String> script_name(String::cast(script->name()));
+      int line_num = GetScriptLineNumber(script, shared->start_position());
+      if (line_num > 0) {
+        PROFILE(ISOLATE,
+                CodeCreateEvent(
+ Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
+                    *code, *shared,
+                    *script_name, line_num + 1));
+      } else {
+        // Can't distinguish eval and script here, so always use Script.
+        PROFILE(ISOLATE,
+                CodeCreateEvent(
+                    Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
+                    *code, *shared, *script_name));
+      }
+    } else {
+      PROFILE(ISOLATE,
+              CodeCreateEvent(
+ Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
+                  *code, *shared, *func_name));
+    }
+  } else if (shared->IsApiFunction()) {
+    // API function.
+    FunctionTemplateInfo* fun_data = shared->get_api_func_data();
+    Object* raw_call_data = fun_data->call_code();
+    if (!raw_call_data->IsUndefined()) {
+      CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
+      Object* callback_obj = call_data->callback();
+      Address entry_point = v8::ToCData<Address>(callback_obj);
+      PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point));
+    }
+  } else {
+    PROFILE(ISOLATE,
+            CodeCreateEvent(
+                Logger::LAZY_COMPILE_TAG, *code, *shared, *func_name));
+  }
+}


 void Logger::LogCompiledFunctions() {
@@ -1540,48 +1585,7 @@
     if (*code_objects[i] == Isolate::Current()->builtins()->builtin(
         Builtins::kLazyCompile))
       continue;
-    Handle<SharedFunctionInfo> shared = sfis[i];
-    Handle<String> func_name(shared->DebugName());
-    if (shared->script()->IsScript()) {
-      Handle<Script> script(Script::cast(shared->script()));
-      if (script->name()->IsString()) {
-        Handle<String> script_name(String::cast(script->name()));
- int line_num = GetScriptLineNumber(script, shared->start_position());
-        if (line_num > 0) {
-          PROFILE(ISOLATE,
-                  CodeCreateEvent(
- Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
-                    *code_objects[i], *shared,
-                    *script_name, line_num + 1));
-        } else {
-          // Can't distinguish eval and script here, so always use Script.
-          PROFILE(ISOLATE,
-                  CodeCreateEvent(
- Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
-                      *code_objects[i], *shared, *script_name));
-        }
-      } else {
-        PROFILE(ISOLATE,
-                CodeCreateEvent(
- Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
-                    *code_objects[i], *shared, *func_name));
-      }
-    } else if (shared->IsApiFunction()) {
-      // API function.
-      FunctionTemplateInfo* fun_data = shared->get_api_func_data();
-      Object* raw_call_data = fun_data->call_code();
-      if (!raw_call_data->IsUndefined()) {
-        CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
-        Object* callback_obj = call_data->callback();
-        Address entry_point = v8::ToCData<Address>(callback_obj);
-        PROFILE(ISOLATE, CallbackEvent(*func_name, entry_point));
-      }
-    } else {
-      PROFILE(ISOLATE,
-              CodeCreateEvent(
-                  Logger::LAZY_COMPILE_TAG, *code_objects[i],
-                  *shared, *func_name));
-    }
+    LogExistingFunction(sfis[i], code_objects[i]);
   }
 }

=======================================
--- /branches/bleeding_edge/src/log.h   Wed Jul 13 04:31:22 2011
+++ /branches/bleeding_edge/src/log.h   Wed Sep 14 04:47:03 2011
@@ -281,6 +281,8 @@
   void ResumeProfiler();
   bool IsProfilerPaused();

+  void LogExistingFunction(Handle<SharedFunctionInfo> shared,
+                           Handle<Code> code);
   // Logs all compiled functions found in the heap.
   void LogCompiledFunctions();
   // Logs all accessor callbacks found in the heap.
=======================================
--- /branches/bleeding_edge/src/profile-generator-inl.h Wed Jul 13 02:09:04 2011 +++ /branches/bleeding_edge/src/profile-generator-inl.h Wed Sep 14 04:47:03 2011
@@ -76,22 +76,6 @@
       self_ticks_(0),
       children_(CodeEntriesMatch) {
 }
-
-
-void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) {
-  CodeTree::Locator locator;
-  tree_.Insert(addr, &locator);
-  locator.set_value(CodeEntryInfo(entry, size));
-}
-
-
-void CodeMap::MoveCode(Address from, Address to) {
-  tree_.Move(from, to);
-}
-
-void CodeMap::DeleteCode(Address addr) {
-  tree_.Remove(addr);
-}


 CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
=======================================
--- /branches/bleeding_edge/src/profile-generator.cc Mon Sep 5 00:37:52 2011 +++ /branches/bleeding_edge/src/profile-generator.cc Wed Sep 14 04:47:03 2011
@@ -492,6 +492,28 @@
     CodeMap::CodeEntryInfo(NULL, 0);


+void CodeMap::AddCode(Address addr, CodeEntry* entry, unsigned size) {
+  DeleteAllCoveredCode(addr, addr + size);
+  CodeTree::Locator locator;
+  tree_.Insert(addr, &locator);
+  locator.set_value(CodeEntryInfo(entry, size));
+}
+
+
+void CodeMap::DeleteAllCoveredCode(Address start, Address end) {
+  List<Address> to_delete;
+  Address addr = end - 1;
+  while (addr >= start) {
+    CodeTree::Locator locator;
+    if (!tree_.FindGreatestLessThan(addr, &locator)) break;
+    Address start2 = locator.key(), end2 = start2 + locator.value().size;
+    if (start2 < end && start < end2) to_delete.Add(start2);
+    addr = start2 - 1;
+  }
+  for (int i = 0; i < to_delete.length(); ++i) tree_.Remove(to_delete[i]);
+}
+
+
 CodeEntry* CodeMap::FindEntry(Address addr) {
   CodeTree::Locator locator;
   if (tree_.FindGreatestLessThan(addr, &locator)) {
@@ -518,6 +540,16 @@
     return id;
   }
 }
+
+
+void CodeMap::MoveCode(Address from, Address to) {
+  if (from == to) return;
+  CodeTree::Locator locator;
+  if (!tree_.Find(from, &locator)) return;
+  CodeEntryInfo entry = locator.value();
+  tree_.Remove(from);
+  AddCode(to, entry.entry, entry.size);
+}


 void CodeMap::CodeTreePrinter::Call(
=======================================
--- /branches/bleeding_edge/src/profile-generator.h     Mon Sep  5 00:37:52 2011
+++ /branches/bleeding_edge/src/profile-generator.h     Wed Sep 14 04:47:03 2011
@@ -238,9 +238,8 @@
 class CodeMap {
  public:
   CodeMap() : next_shared_id_(1) { }
-  INLINE(void AddCode(Address addr, CodeEntry* entry, unsigned size));
-  INLINE(void MoveCode(Address from, Address to));
-  INLINE(void DeleteCode(Address addr));
+  void AddCode(Address addr, CodeEntry* entry, unsigned size);
+  void MoveCode(Address from, Address to);
   CodeEntry* FindEntry(Address addr);
   int GetSharedId(Address addr);

@@ -270,6 +269,8 @@
     void Call(const Address& key, const CodeEntryInfo& value);
   };

+  void DeleteAllCoveredCode(Address start, Address end);
+
   // Fake CodeEntry pointer to distinguish shared function entries.
   static CodeEntry* const kSharedFunctionCodeEntry;

=======================================
--- /branches/bleeding_edge/src/runtime.cc      Wed Sep 14 04:20:31 2011
+++ /branches/bleeding_edge/src/runtime.cc      Wed Sep 14 04:47:03 2011
@@ -2243,6 +2243,11 @@
     // are guaranteed to be in old space.
     target->set_literals(*literals, SKIP_WRITE_BARRIER);
     target->set_next_function_link(isolate->heap()->undefined_value());
+
+ if (isolate->logger()->is_logging() || CpuProfiler::is_profiling(isolate)) {
+      isolate->logger()->LogExistingFunction(
+          shared, Handle<Code>(shared->code()));
+    }
   }

   target->set_context(*context);
=======================================
--- /branches/bleeding_edge/test/cctest/log-eq-of-logging-and-traversal.js Thu Jul 14 04:38:18 2011 +++ /branches/bleeding_edge/test/cctest/log-eq-of-logging-and-traversal.js Wed Sep 14 04:47:03 2011
@@ -43,8 +43,7 @@
           processor: this.processCodeCreation },
       'code-move': { parsers: [parseInt, parseInt],
           processor: this.processCodeMove },
-      'code-delete': { parsers: [parseInt],
-          processor: this.processCodeDelete },
+      'code-delete': null,
       'sfi-move': { parsers: [parseInt, parseInt],
           processor: this.processFunctionMove },
       'shared-library': null,
@@ -73,10 +72,6 @@
   this.profile.moveCode(from, to);
 };

-LogProcessor.prototype.processCodeDelete = function(start) {
-  this.profile.deleteCode(start);
-};
-
 LogProcessor.prototype.processFunctionMove = function(from, to) {
   this.profile.moveFunc(from, to);
 };
@@ -132,8 +127,8 @@
      "Script", "String", "RegExp", "Date", "Error"];

   function entitiesEqual(entityA, entityB) {
-    if (entityA === null && entityB !== null) return true;
-    if (entityA !== null && entityB === null) return false;
+    if ((entityA === null && entityB !== null) ||
+      (entityA !== null && entityB === null)) return true;
return entityA.size === entityB.size && entityNamesEqual(entityA, entityB);
   }

@@ -145,6 +140,8 @@
// find the same entries. We skip builtins during log parsing, but compiled // functions traversal may erroneously recognize them as functions, so we are
   // expecting more functions in traversal vs. logging.
+ // Since we don't track code deletions, logging can also report more entries
+  // than traversal.
   while (l_pos < l_len && t_pos < t_len) {
     var entryA = logging_entries[l_pos];
     var entryB = traversal_entries[t_pos];
@@ -166,11 +163,6 @@
     if (!entities_equal) equal = false;
     comparison.push([entities_equal, address, entityA, entityB]);
   }
-  if (l_pos < l_len) equal = false;
-  while (l_pos < l_len) {
-    var entryA = logging_entries[l_pos++];
-    comparison.push([false, entryA[0], entryA[1], null]);
-  }
   return [equal, comparison];
 }

=======================================
--- /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc Fri Aug 12 02:49:55 2011 +++ /branches/bleeding_edge/test/cctest/test-cpu-profiler.cc Wed Sep 14 04:47:03 2011
@@ -107,7 +107,7 @@
                             0x80);
   processor.CodeMoveEvent(ToAddress(0x1400), ToAddress(0x1500));
processor.CodeCreateEvent(i::Logger::STUB_TAG, 3, ToAddress(0x1600), 0x10);
-  processor.CodeDeleteEvent(ToAddress(0x1600));
+ processor.CodeCreateEvent(i::Logger::STUB_TAG, 4, ToAddress(0x1605), 0x10);
   // Enqueue a tick event to enable code events processing.
   EnqueueTickSampleEvent(&processor, ToAddress(0x1000));

=======================================
--- /branches/bleeding_edge/test/cctest/test-log.cc     Fri Aug 12 02:49:55 2011
+++ /branches/bleeding_edge/test/cctest/test-log.cc     Wed Sep 14 04:47:03 2011
@@ -25,6 +25,7 @@

 namespace {

+
 class ScopedLoggerInitializer {
  public:
   explicit ScopedLoggerInitializer(bool prof_lazy)
@@ -470,8 +471,9 @@

 typedef i::NativesCollection<i::TEST> TestSources;

-// Test that logging of code create / move / delete events
-// is equivalent to traversal of a resulting heap.
+
+// Test that logging of code create / move events is equivalent to traversal of
+// a resulting heap.
 TEST(EquivalenceOfLoggingAndTraversal) {
   // This test needs to be run on a "clean" V8 to ensure that snapshot log
// is loaded. This is always true when running using tools/test.py because
=======================================
--- /branches/bleeding_edge/test/cctest/test-profile-generator.cc Wed Sep 7 06:13:56 2011 +++ /branches/bleeding_edge/test/cctest/test-profile-generator.cc Wed Sep 14 04:47:03 2011
@@ -549,13 +549,14 @@
   code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
   CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));
   CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
-  code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1800));
+ code_map.MoveCode(ToAddress(0x1500), ToAddress(0x1700)); // Deprecate bbb.
   CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1500)));
-  CHECK_EQ(&entry2, code_map.FindEntry(ToAddress(0x1700)));
-  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1800)));
-  code_map.DeleteCode(ToAddress(0x1700));
+  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1700)));
+  CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0,
+                   TokenEnumerator::kNoSecurityToken);
+  code_map.AddCode(ToAddress(0x1750), &entry3, 0x100);
   CHECK_EQ(NULL, code_map.FindEntry(ToAddress(0x1700)));
-  CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1800)));
+  CHECK_EQ(&entry3, code_map.FindEntry(ToAddress(0x1750)));
 }


=======================================
--- /branches/bleeding_edge/tools/codemap.js    Mon Sep 12 03:50:40 2011
+++ /branches/bleeding_edge/tools/codemap.js    Wed Sep 14 04:47:03 2011
@@ -79,6 +79,7 @@
  * @param {CodeMap.CodeEntry} codeEntry Code entry object.
  */
 CodeMap.prototype.addCode = function(start, codeEntry) {
+ this.deleteAllCoveredNodes_(this.dynamics_, start, start + codeEntry.size);
   this.dynamics_.insert(start, codeEntry);
 };

@@ -92,6 +93,7 @@
  */
 CodeMap.prototype.moveCode = function(from, to) {
   var removedNode = this.dynamics_.remove(from);
+ this.deleteAllCoveredNodes_(this.dynamics_, to, to + removedNode.value.size);
   this.dynamics_.insert(to, removedNode.value);
 };

@@ -143,6 +145,23 @@
 };


+/**
+ * @private
+ */
+CodeMap.prototype.deleteAllCoveredNodes_ = function(tree, start, end) {
+  var to_delete = [];
+  var addr = end - 1;
+  while (addr >= start) {
+    var node = tree.findGreatestLessThan(addr);
+    if (!node) break;
+    var start2 = node.key, end2 = start2 + node.value.size;
+    if (start2 < end && start < end2) to_delete.push(start2);
+    addr = start2 - 1;
+  }
+ for (var i = 0, l = to_delete.length; i < l; ++i) tree.remove(to_delete[i]);
+};
+
+
 /**
  * @private
  */

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to