Revision: 19416
Author:   [email protected]
Date:     Mon Feb 17 15:24:39 2014 UTC
Log: Make a single HeapEntry per single JSArrayBuffer data in heap snapshot.

It turned out that JSArrayBuffer's may share their backing_store so
the backing_store should go through hash map registration just like
other heap objects, so they won't be reported twice.

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

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

Modified:
 /branches/bleeding_edge/src/heap-snapshot-generator.cc
 /branches/bleeding_edge/src/heap-snapshot-generator.h
 /branches/bleeding_edge/test/cctest/test-heap-profiler.cc

=======================================
--- /branches/bleeding_edge/src/heap-snapshot-generator.cc Mon Feb 17 12:39:01 2014 UTC +++ /branches/bleeding_edge/src/heap-snapshot-generator.cc Mon Feb 17 15:24:39 2014 UTC
@@ -1456,6 +1456,23 @@
 }


+class JSArrayBufferDataEntryAllocator : public HeapEntriesAllocator {
+ public:
+  JSArrayBufferDataEntryAllocator(int size, V8HeapExplorer* explorer)
+      : size_(size)
+      , explorer_(explorer) {
+  }
+  virtual HeapEntry* AllocateEntry(HeapThing ptr) {
+    return explorer_->AddEntry(
+        static_cast<Address>(ptr),
+        HeapEntry::kNative, "system / JSArrayBufferData", size_);
+  }
+ private:
+  int size_;
+  V8HeapExplorer* explorer_;
+};
+
+
 void V8HeapExplorer::ExtractJSArrayBufferReferences(
     int entry, JSArrayBuffer* buffer) {
   SetWeakReference(buffer, entry, "weak_next", buffer->weak_next(),
@@ -1468,10 +1485,9 @@
     return;
   size_t data_size = NumberToSize(heap_->isolate(), buffer->byte_length());
   CHECK(data_size <= static_cast<size_t>(kMaxInt));
-  HeapEntry* data_entry = AddEntry(
-      static_cast<Address>(buffer->backing_store()),
-      HeapEntry::kNative, "system / ArrayBufferData",
-      static_cast<int>(data_size));
+ JSArrayBufferDataEntryAllocator allocator(static_cast<int>(data_size), this);
+  HeapEntry* data_entry =
+      filler_->FindOrAddEntry(buffer->backing_store(), &allocator);
   filler_->SetNamedReference(HeapGraphEdge::kInternal,
                              entry, "backing_store", data_entry);
 }
=======================================
--- /branches/bleeding_edge/src/heap-snapshot-generator.h Thu Feb 13 15:31:39 2014 UTC +++ /branches/bleeding_edge/src/heap-snapshot-generator.h Mon Feb 17 15:24:39 2014 UTC
@@ -386,6 +386,10 @@
   void TagGlobalObjects();
   void TagCodeObject(Code* code);
   void TagBuiltinCodeObject(Code* code, const char* name);
+  HeapEntry* AddEntry(Address address,
+                      HeapEntry::Type type,
+                      const char* name,
+                      int size);

   static String* GetConstructorName(JSObject* object);

@@ -396,10 +400,6 @@
   HeapEntry* AddEntry(HeapObject* object,
                       HeapEntry::Type type,
                       const char* name);
-  HeapEntry* AddEntry(Address address,
-                      HeapEntry::Type type,
-                      const char* name,
-                      int size);

   const char* GetSystemEntryName(HeapObject* object);

=======================================
--- /branches/bleeding_edge/test/cctest/test-heap-profiler.cc Thu Feb 13 15:31:39 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-heap-profiler.cc Mon Feb 17 15:24:39 2014 UTC
@@ -2386,6 +2386,51 @@
   CHECK_NE(NULL, backing_store);
   CHECK_EQ(400, backing_store->GetSelfSize());
 }
+
+
+static int GetRetainersCount(const v8::HeapSnapshot* snapshot,
+                             const v8::HeapGraphNode* node) {
+  int count = 0;
+  for (int i = 0, l = snapshot->GetNodesCount(); i < l; ++i) {
+    const v8::HeapGraphNode* parent = snapshot->GetNode(i);
+    for (int j = 0, l2 = parent->GetChildrenCount(); j < l2; ++j) {
+      if (parent->GetChild(j)->GetToNode() == node) {
+        ++count;
+      }
+    }
+  }
+  return count;
+}
+
+
+TEST(ArrayBufferSharedBackingStore) {
+  LocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+  v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
+  CompileRun("sin1 = Math.sin(1);");
+  LocalContext env2;
+  CompileRun("sin2 = Math.sin(2);");
+  const v8::HeapSnapshot* snapshot =
+      heap_profiler->TakeHeapSnapshot(v8_str("snapshot"));
+  CHECK(ValidateSnapshot(snapshot));
+  // The 0th-child is (GC Roots), 1st is the user root.
+  const v8::HeapGraphNode* global =
+      snapshot->GetRoot()->GetChild(1)->GetToNode();
+  const v8::HeapGraphNode* builtins =
+      GetProperty(global, v8::HeapGraphEdge::kInternal, "builtins");
+  CHECK_NE(NULL, builtins);
+  const v8::HeapGraphNode* sin_table =
+      GetProperty(builtins, v8::HeapGraphEdge::kProperty, "kSinTable");
+  CHECK_NE(NULL, sin_table);
+  const v8::HeapGraphNode* buffer =
+      GetProperty(sin_table, v8::HeapGraphEdge::kInternal, "buffer");
+  CHECK_NE(NULL, buffer);
+  const v8::HeapGraphNode* backing_store =
+      GetProperty(buffer, v8::HeapGraphEdge::kInternal, "backing_store");
+  CHECK_NE(NULL, backing_store);
+  int retainers = GetRetainersCount(snapshot, backing_store);
+  CHECK_EQ(2, retainers);
+}


 TEST(BoxObject) {

--
--
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/groups/opt_out.

Reply via email to