From 729b85ae8678ebd998a0e5f254817683198d0610 Mon Sep 17 00:00:00 2001 From: adamk Date: Tue, 31 Mar 2015 16:03:08 -0700 Subject: [PATCH] Add a UseCounter for Object.observe It triggers once per context that calls observe (or attempts to access any observation metadata, e.g. through Object.getNotifier). Review URL: https://codereview.chromium.org/1048213002 Cr-Commit-Position: refs/heads/master@{#27557} --- include/v8.h | 1 + src/runtime/runtime-observe.cc | 3 ++- test/cctest/test-object-observe.cc | 51 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/include/v8.h b/include/v8.h index 19ba8e7..fd281ae 100644 --- a/include/v8.h +++ b/include/v8.h @@ -5146,6 +5146,7 @@ class V8_EXPORT Isolate { kMarkDequeOverflow = 3, kStoreBufferOverflow = 4, kSlotsBufferOverflow = 5, + kObjectObserve = 6, kUseCounterFeatureCount // This enum value must be last. }; diff --git a/src/runtime/runtime-observe.cc b/src/runtime/runtime-observe.cc index 211922c..a942645 100644 --- a/src/runtime/runtime-observe.cc +++ b/src/runtime/runtime-observe.cc @@ -88,8 +88,9 @@ RUNTIME_FUNCTION(Runtime_DeliverObservationChangeRecords) { RUNTIME_FUNCTION(Runtime_GetObservationState) { - SealHandleScope shs(isolate); + HandleScope scope(isolate); DCHECK(args.length() == 0); + isolate->CountUsage(v8::Isolate::kObjectObserve); return isolate->heap()->observation_state(); } diff --git a/test/cctest/test-object-observe.cc b/test/cctest/test-object-observe.cc index 64634ad..50e2230 100644 --- a/test/cctest/test-object-observe.cc +++ b/test/cctest/test-object-observe.cc @@ -834,3 +834,54 @@ TEST(APIAccessorsShouldNotNotify) { CompileRun("Object.defineProperty(obj, 'accessor', { value: 44 });"); CHECK(CompileRun("records")->IsNull()); } + + +namespace { + +int* global_use_counts = NULL; + +void MockUseCounterCallback(v8::Isolate* isolate, + v8::Isolate::UseCounterFeature feature) { + ++global_use_counts[feature]; +} +} + + +TEST(UseCountObjectObserve) { + i::Isolate* isolate = CcTest::i_isolate(); + i::HandleScope scope(isolate); + LocalContext env; + int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; + global_use_counts = use_counts; + CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); + CompileRun( + "var obj = {};" + "Object.observe(obj, function(){})"); + CHECK_EQ(1, use_counts[v8::Isolate::kObjectObserve]); + CompileRun( + "var obj2 = {};" + "Object.observe(obj2, function(){})"); + // Only counts the first use of observe in a given context. + CHECK_EQ(1, use_counts[v8::Isolate::kObjectObserve]); + { + LocalContext env2; + CompileRun( + "var obj = {};" + "Object.observe(obj, function(){})"); + } + // Counts different contexts separately. + CHECK_EQ(2, use_counts[v8::Isolate::kObjectObserve]); +} + + +TEST(UseCountObjectGetNotifier) { + i::Isolate* isolate = CcTest::i_isolate(); + i::HandleScope scope(isolate); + LocalContext env; + int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; + global_use_counts = use_counts; + CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); + CompileRun("var obj = {}"); + CompileRun("Object.getNotifier(obj)"); + CHECK_EQ(1, use_counts[v8::Isolate::kObjectObserve]); +} -- 2.7.4