Add HeapProfiler::GetPersistentHandleCount to be able to track the number of persistent handles

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
This commit is contained in:
vegorov@chromium.org 2012-03-07 17:38:50 +00:00
parent 1a768b1143
commit 47b6027c37
5 changed files with 53 additions and 0 deletions

View 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();
};

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

View 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);
}

View 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_;

View 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());
}