From: mstarzinger@chromium.org Date: Thu, 24 Jan 2013 15:53:16 +0000 (+0000) Subject: Implement VisitHandlesInNewSpaceWithClassIds() X-Git-Tag: upstream/4.7.83~15208 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c8cf5d90aa1b8bde03258ea2dec550d1163bd3e8;p=platform%2Fupstream%2Fv8.git Implement VisitHandlesInNewSpaceWithClassIds() BUG= TEST=test-api.cc::PersistentHandleInNewSpaceVisitor Review URL: https://codereview.chromium.org/11365131 Patch from Kentaro Hara . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13496 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/include/v8.h b/include/v8.h index 8d8a992..5f3e2ed 100644 --- a/include/v8.h +++ b/include/v8.h @@ -3489,6 +3489,16 @@ class V8EXPORT V8 { 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. diff --git a/src/api.cc b/src/api.cc index 54b233c..1561f24 100644 --- a/src/api.cc +++ b/src/api.cc @@ -4495,30 +4495,47 @@ void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) { } +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(i::Handle(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(i::Handle(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(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. @@ -5447,11 +5464,11 @@ void V8::AddObjectGroup(Persistent* objects, } -void V8::AddObjectGroup(Isolate* exportedIsolate, +void V8::AddObjectGroup(Isolate* exported_isolate, Persistent* objects, size_t length, RetainedObjectInfo* info) { - i::Isolate* isolate = reinterpret_cast(exportedIsolate); + i::Isolate* isolate = reinterpret_cast(exported_isolate); ASSERT(isolate == i::Isolate::Current()); if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return; STATIC_ASSERT(sizeof(Persistent) == sizeof(i::Object**)); diff --git a/src/global-handles.cc b/src/global-handles.cc index 427eae0..23b3918 100644 --- a/src/global-handles.cc +++ b/src/global-handles.cc @@ -682,6 +682,17 @@ void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) { } +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()) { diff --git a/src/global-handles.h b/src/global-handles.h index 8cfb34b..18bfc11 100644 --- a/src/global-handles.h +++ b/src/global-handles.h @@ -173,6 +173,10 @@ class GlobalHandles { // Iterates over all handles that have embedder-assigned class ID. void IterateAllRootsWithClassIds(ObjectVisitor* v); + // Iterates over all handles in the new space that have embedder-assigned + // class ID. + void IterateAllRootsInNewSpaceWithClassIds(ObjectVisitor* v); + // Iterates over all weak roots in heap. void IterateWeakRoots(ObjectVisitor* v); diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index d3b8824..ca027df 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -16699,6 +16699,32 @@ TEST(WrapperClassId) { } +TEST(PersistentHandleInNewSpaceVisitor) { + v8::HandleScope scope; + LocalContext context; + v8::Persistent object1 = + v8::Persistent::New(v8::Object::New()); + CHECK_EQ(0, object1.WrapperClassId()); + object1.SetWrapperClassId(42); + CHECK_EQ(42, object1.WrapperClassId()); + + HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); + + v8::Persistent object2 = + v8::Persistent::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;