static void VisitHandlesWithClassIds(PersistentHandleVisitor* visitor);
/**
+ * Iterates through all the persistent handles in the current isolate's heap
+ * that have class_ids and are candidates to be marked as partially dependent
+ * handles. This will visit handles to young objects created since the last
+ * garbage collection but is free to visit an arbitrary superset of these
+ * objects.
+ */
+ static void VisitHandlesForPartialDependence(
+ Isolate* isolate, PersistentHandleVisitor* visitor);
+
+ /**
* Optional notification that the embedder is idle.
* V8 uses the notification to reduce memory footprint.
* This call can be used repeatedly if the embedder remains idle.
}
+class VisitorAdapter : public i::ObjectVisitor {
+ public:
+ explicit VisitorAdapter(PersistentHandleVisitor* visitor)
+ : visitor_(visitor) {}
+ virtual void VisitPointers(i::Object** start, i::Object** end) {
+ UNREACHABLE();
+ }
+ virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
+ visitor_->VisitPersistentHandle(ToApi<Value>(i::Handle<i::Object>(p)),
+ class_id);
+ }
+ private:
+ PersistentHandleVisitor* visitor_;
+};
+
+
void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::V8::VisitHandlesWithClassId");
i::AssertNoAllocation no_allocation;
- class VisitorAdapter : public i::ObjectVisitor {
- public:
- explicit VisitorAdapter(PersistentHandleVisitor* visitor)
- : visitor_(visitor) {}
- virtual void VisitPointers(i::Object** start, i::Object** end) {
- UNREACHABLE();
- }
- virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
- visitor_->VisitPersistentHandle(ToApi<Value>(i::Handle<i::Object>(p)),
- class_id);
- }
- private:
- PersistentHandleVisitor* visitor_;
- } visitor_adapter(visitor);
+ VisitorAdapter visitor_adapter(visitor);
isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
}
+void v8::V8::VisitHandlesForPartialDependence(
+ Isolate* exported_isolate, PersistentHandleVisitor* visitor) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
+ ASSERT(isolate == i::Isolate::Current());
+ IsDeadCheck(isolate, "v8::V8::VisitHandlesForPartialDependence");
+
+ i::AssertNoAllocation no_allocation;
+
+ VisitorAdapter visitor_adapter(visitor);
+ isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
+ &visitor_adapter);
+}
+
+
bool v8::V8::IdleNotification(int hint) {
// Returning true tells the caller that it need not
// continue to call IdleNotification.
}
-void V8::AddObjectGroup(Isolate* exportedIsolate,
+void V8::AddObjectGroup(Isolate* exported_isolate,
Persistent<Value>* objects,
size_t length,
RetainedObjectInfo* info) {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exportedIsolate);
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
ASSERT(isolate == i::Isolate::Current());
if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
}
+void GlobalHandles::IterateAllRootsInNewSpaceWithClassIds(ObjectVisitor* v) {
+ for (int i = 0; i < new_space_nodes_.length(); ++i) {
+ Node* node = new_space_nodes_[i];
+ if (node->IsRetainer() && node->has_wrapper_class_id()) {
+ v->VisitEmbedderReference(node->location(),
+ node->wrapper_class_id());
+ }
+ }
+}
+
+
int GlobalHandles::NumberOfWeakHandles() {
int count = 0;
for (NodeIterator it(this); !it.done(); it.Advance()) {
}
+TEST(PersistentHandleInNewSpaceVisitor) {
+ v8::HandleScope scope;
+ LocalContext context;
+ v8::Persistent<v8::Object> object1 =
+ v8::Persistent<v8::Object>::New(v8::Object::New());
+ CHECK_EQ(0, object1.WrapperClassId());
+ object1.SetWrapperClassId(42);
+ CHECK_EQ(42, object1.WrapperClassId());
+
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+
+ v8::Persistent<v8::Object> object2 =
+ v8::Persistent<v8::Object>::New(v8::Object::New());
+ CHECK_EQ(0, object2.WrapperClassId());
+ object2.SetWrapperClassId(42);
+ CHECK_EQ(42, object2.WrapperClassId());
+
+ Visitor42 visitor(object2);
+ v8::V8::VisitHandlesForPartialDependence(v8::Isolate::GetCurrent(), &visitor);
+ CHECK_EQ(1, visitor.counter_);
+
+ object1.Dispose();
+ object2.Dispose();
+}
+
+
TEST(RegExp) {
v8::HandleScope scope;
LocalContext context;