Reviewers: Jakob,

Description:
Postpone counters triggered during GC, and use a HandleScope when calling back.

[email protected]
BUG=

Please review this at https://codereview.chromium.org/1125383007/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+64, -2 lines):
  M include/v8.h
  M src/heap/heap.h
  M src/heap/heap.cc
  M src/isolate.cc
  M test/cctest/test-heap.cc


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index 5227073759677071a8421544874c1b99eb931d40..fa33fb6fa3c5e62f4fc236738b76dbd491e20ab7 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -5107,6 +5107,7 @@ class V8_EXPORT Isolate {
     kStoreBufferOverflow = 4,
     kSlotsBufferOverflow = 5,
     kObjectObserve = 6,
+    kForcedGC = 7,
     kUseCounterFeatureCount  // This enum value must be last.
   };

Index: src/heap/heap.cc
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index 54a8915788237436b72762d6cb303ed9f189725b..d5c8360c06e1cd3f4231970603ca16ef11bcb47a 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -395,6 +395,20 @@ void Heap::ReportStatisticsAfterGC() {
 #else
   if (FLAG_log_gc) new_space_.ReportStatistics();
 #endif  // DEBUG
+ for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount);
+       ++i) {
+    int count = deferred_counters_[i];
+    deferred_counters_[i] = 0;
+    while (count != 0) {
+      count--;
+ isolate()->CountUsage(static_cast<v8::Isolate::UseCounterFeature>(i));
+    }
+  }
+}
+
+
+void Heap::IncrementDeferredCount(v8::Isolate::UseCounterFeature feature) {
+  deferred_counters_[feature]++;
 }


@@ -925,6 +939,11 @@ bool Heap::CollectGarbage(GarbageCollector collector, const char* gc_reason,
     tracer()->Stop(collector);
   }

+  if (collector == MARK_COMPACTOR &&
+      (gc_callback_flags & kGCCallbackFlagForced) != 0) {
+    isolate()->CountUsage(v8::Isolate::kForcedGC);
+  }
+
   // Start incremental marking for the next cycle. The heap snapshot
   // generator needs incremental marking to stay off after it aborted.
   if (!mark_compact_collector()->abort_incremental_marking() &&
@@ -5422,6 +5441,12 @@ bool Heap::SetUp() {
     }
   }

+ for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount);
+       i++) {
+    deferred_counters_[i] = 0;
+  }
+
+
   LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
   LOG(isolate_, IntPtrTEvent("heap-available", Available()));

Index: src/heap/heap.h
diff --git a/src/heap/heap.h b/src/heap/heap.h
index ff6a11ee68740c536713a21a0d13ef42649b3080..58be0a23f3eba311852d616b4fcee8ae4c74f8ad 100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -1311,6 +1311,8 @@ class Heap {
   // Returns minimal interval between two subsequent collections.
   double get_min_in_mutator() { return min_in_mutator_; }

+  void IncrementDeferredCount(v8::Isolate::UseCounterFeature feature);
+
   MarkCompactCollector* mark_compact_collector() {
     return &mark_compact_collector_;
   }
@@ -2047,6 +2049,8 @@ class Heap {
   // Total RegExp code ever generated
   double total_regexp_code_generated_;

+  int deferred_counters_[v8::Isolate::kUseCounterFeatureCount];
+
   GCTracer tracer_;

   // Creates and installs the full-sized number string cache.
Index: src/isolate.cc
diff --git a/src/isolate.cc b/src/isolate.cc
index d53d0d8d327829cd50abe69e6ae4213546008648..69a4f8d274d6cba4db56e5520f1b3505bc6bf8a3 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -2669,8 +2669,15 @@ void Isolate::SetUseCounterCallback(v8::Isolate::UseCounterCallback callback) {


 void Isolate::CountUsage(v8::Isolate::UseCounterFeature feature) {
-  if (use_counter_callback_) {
-    use_counter_callback_(reinterpret_cast<v8::Isolate*>(this), feature);
+ // The counter callback may cause the embedder to call into V8, which is not
+  // generally possible during GC.
+  if (heap_.gc_state() == Heap::NOT_IN_GC) {
+    if (use_counter_callback_) {
+      HandleScope handle_scope(this);
+      use_counter_callback_(reinterpret_cast<v8::Isolate*>(this), feature);
+    }
+  } else {
+    heap_.IncrementDeferredCount(feature);
   }
 }

Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index cb08fb4c04ee7841593c525589c918e7d5c8df25..d8c89aec1b4b242a9702c3a018681bdb9b2569bc 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -3203,6 +3203,31 @@ TEST(ReleaseOverReservedPages) {
   CHECK_EQ(1, old_space->CountTotalPages());
 }

+static int forced_gc_counter = 0;
+
+void MockUseCounterCallback(v8::Isolate* isolate,
+                            v8::Isolate::UseCounterFeature feature) {
+  isolate->GetCallingContext();
+  if (feature == v8::Isolate::kForcedGC) {
+    forced_gc_counter++;
+  }
+}
+
+
+TEST(CountForcedGC) {
+  i::FLAG_expose_gc = true;
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  isolate->SetUseCounterCallback(MockUseCounterCallback);
+
+  forced_gc_counter = 0;
+  const char* source = "gc();";
+  CompileRun(source);
+  CHECK_GT(forced_gc_counter, 0);
+}
+

 TEST(Regress2237) {
   i::FLAG_stress_compaction = false;


--
--
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/d/optout.

Reply via email to