Add HeapProfiler::GetPersistentHandleCount to be able to track the number of persiste...
authorvegorov@chromium.org <vegorov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 7 Mar 2012 17:38:50 +0000 (17:38 +0000)
committervegorov@chromium.org <vegorov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 7 Mar 2012 17:38:50 +0000 (17:38 +0000)
It turns out that an increasing number of persistent handles is a good signal for bugs in the bindings layer

BUG=none
TEST=cctest/test-heap-profiler/PersistentHandleCount

Review URL: https://chromiumcodereview.appspot.com/9620007
Patch from Jochen Eisinger <jochen@chromium.org>.

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

include/v8-profiler.h
src/api.cc
src/global-handles.cc
src/global-handles.h
test/cctest/test-heap-profiler.cc

index fc3ee78837136a97bee4f212298835a9b00ce1e8..2499bbf050efa6ae794ac8c09422c17cb5093686 100644 (file)
@@ -430,6 +430,9 @@ class V8EXPORT HeapProfiler {
    * handle.
    */
   static const uint16_t kPersistentHandleNoClassId = 0;
+
+  /** Returns the number of currently existing persistent handles. */
+  static int GetPersistentHandleCount();
 };
 
 
index 4498286916238f6ea009c1a3a0ce9124eb5e6cc4..552fe006a442a43891c284e5dbcad0f85b8b4689 100644 (file)
@@ -6071,6 +6071,11 @@ void HeapProfiler::DefineWrapperClass(uint16_t class_id,
 }
 
 
+int HeapProfiler::GetPersistentHandleCount() {
+  i::Isolate* isolate = i::Isolate::Current();
+  return isolate->global_handles()->NumberOfGlobalHandles();
+}
+
 
 v8::Testing::StressType internal::Testing::stress_type_ =
     v8::Testing::kStressTypeOpt;
index 471f5a336c59aeaf07baf7c6f7afa68b1d4963b7..9c0ad45179dc538bc39aab0c08036dca229677b4 100644 (file)
@@ -384,6 +384,7 @@ GlobalHandles::GlobalHandles(Isolate* isolate)
     : isolate_(isolate),
       number_of_weak_handles_(0),
       number_of_global_object_weak_handles_(0),
+      number_of_global_handles_(0),
       first_block_(NULL),
       first_used_block_(NULL),
       first_free_(NULL),
@@ -403,6 +404,7 @@ GlobalHandles::~GlobalHandles() {
 
 Handle<Object> GlobalHandles::Create(Object* value) {
   isolate_->counters()->global_handles()->Increment();
+  number_of_global_handles_++;
   if (first_free_ == NULL) {
     first_block_ = new NodeBlock(first_block_);
     first_block_->PutNodesOnFreeList(&first_free_);
@@ -423,6 +425,7 @@ Handle<Object> GlobalHandles::Create(Object* value) {
 
 void GlobalHandles::Destroy(Object** location) {
   isolate_->counters()->global_handles()->Decrement();
+  number_of_global_handles_--;
   if (location == NULL) return;
   Node::FromLocation(location)->Release(this);
 }
index 153d4dac1a2b1e7617d82359e64bdfbe3d704347..ddf5fe29c383fcd87b5d9d8b7d576d662ae11e4b 100644 (file)
@@ -143,6 +143,11 @@ class GlobalHandles {
     return number_of_global_object_weak_handles_;
   }
 
+  // Returns the current number of handles to global objects.
+  int NumberOfGlobalHandles() {
+    return number_of_global_handles_;
+  }
+
   // Clear the weakness of a global handle.
   void ClearWeakness(Object** location);
 
@@ -248,6 +253,9 @@ class GlobalHandles {
   // number_of_weak_handles_.
   int number_of_global_object_weak_handles_;
 
+  // Field always containing the number of handles to global objects.
+  int number_of_global_handles_;
+
   // List of all allocated node blocks.
   NodeBlock* first_block_;
 
index f7078509408dd7fb6b21205ab6b322109b04485e..7a227cdf9b273acc8b026eccabc337dae7062230 100644 (file)
@@ -1279,3 +1279,37 @@ TEST(SfiAndJsFunctionWeakRefs) {
       GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared");
   CHECK(HasWeakEdge(shared));
 }
+
+
+TEST(PersistentHandleCount) {
+  v8::HandleScope scope;
+  LocalContext env;
+
+  // V8 also uses global handles internally, so we can't test for an absolute
+  // number.
+  int global_handle_count = v8::HeapProfiler::GetPersistentHandleCount();
+
+  // Create some persistent handles.
+  v8::Persistent<v8::String> p_AAA =
+      v8::Persistent<v8::String>::New(v8_str("AAA"));
+  CHECK_EQ(global_handle_count + 1,
+           v8::HeapProfiler::GetPersistentHandleCount());
+  v8::Persistent<v8::String> p_BBB =
+      v8::Persistent<v8::String>::New(v8_str("BBB"));
+  CHECK_EQ(global_handle_count + 2,
+           v8::HeapProfiler::GetPersistentHandleCount());
+  v8::Persistent<v8::String> p_CCC =
+      v8::Persistent<v8::String>::New(v8_str("CCC"));
+  CHECK_EQ(global_handle_count + 3,
+           v8::HeapProfiler::GetPersistentHandleCount());
+
+  // Dipose the persistent handles in a different order.
+  p_AAA.Dispose();
+  CHECK_EQ(global_handle_count + 2,
+           v8::HeapProfiler::GetPersistentHandleCount());
+  p_CCC.Dispose();
+  CHECK_EQ(global_handle_count + 1,
+           v8::HeapProfiler::GetPersistentHandleCount());
+  p_BBB.Dispose();
+  CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount());
+}