Implement VisitHandlesInNewSpaceWithClassIds()

BUG=
TEST=test-api.cc::PersistentHandleInNewSpaceVisitor

Review URL: https://codereview.chromium.org/11365131
Patch from Kentaro Hara <haraken@chromium.org>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13496 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 63ec79a4
...@@ -3488,6 +3488,16 @@ class V8EXPORT V8 { ...@@ -3488,6 +3488,16 @@ class V8EXPORT V8 {
*/ */
static void VisitHandlesWithClassIds(PersistentHandleVisitor* visitor); 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. * Optional notification that the embedder is idle.
* V8 uses the notification to reduce memory footprint. * V8 uses the notification to reduce memory footprint.
......
...@@ -4495,30 +4495,47 @@ void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) { ...@@ -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<Value>(i::Handle<i::Object>(p)),
class_id);
}
private:
PersistentHandleVisitor* visitor_;
};
void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) { void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
i::Isolate* isolate = i::Isolate::Current(); i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::V8::VisitHandlesWithClassId"); IsDeadCheck(isolate, "v8::V8::VisitHandlesWithClassId");
i::AssertNoAllocation no_allocation; i::AssertNoAllocation no_allocation;
class VisitorAdapter : public i::ObjectVisitor { VisitorAdapter visitor_adapter(visitor);
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);
isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter); 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) { bool v8::V8::IdleNotification(int hint) {
// Returning true tells the caller that it need not // Returning true tells the caller that it need not
// continue to call IdleNotification. // continue to call IdleNotification.
...@@ -5447,11 +5464,11 @@ void V8::AddObjectGroup(Persistent<Value>* objects, ...@@ -5447,11 +5464,11 @@ void V8::AddObjectGroup(Persistent<Value>* objects,
} }
void V8::AddObjectGroup(Isolate* exportedIsolate, void V8::AddObjectGroup(Isolate* exported_isolate,
Persistent<Value>* objects, Persistent<Value>* objects,
size_t length, size_t length,
RetainedObjectInfo* info) { RetainedObjectInfo* info) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exportedIsolate); i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
ASSERT(isolate == i::Isolate::Current()); ASSERT(isolate == i::Isolate::Current());
if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return; if (IsDeadCheck(isolate, "v8::V8::AddObjectGroup()")) return;
STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**)); STATIC_ASSERT(sizeof(Persistent<Value>) == sizeof(i::Object**));
......
...@@ -682,6 +682,17 @@ void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) { ...@@ -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 GlobalHandles::NumberOfWeakHandles() {
int count = 0; int count = 0;
for (NodeIterator it(this); !it.done(); it.Advance()) { for (NodeIterator it(this); !it.done(); it.Advance()) {
......
...@@ -173,6 +173,10 @@ class GlobalHandles { ...@@ -173,6 +173,10 @@ class GlobalHandles {
// Iterates over all handles that have embedder-assigned class ID. // Iterates over all handles that have embedder-assigned class ID.
void IterateAllRootsWithClassIds(ObjectVisitor* v); 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. // Iterates over all weak roots in heap.
void IterateWeakRoots(ObjectVisitor* v); void IterateWeakRoots(ObjectVisitor* v);
......
...@@ -16699,6 +16699,32 @@ TEST(WrapperClassId) { ...@@ -16699,6 +16699,32 @@ TEST(WrapperClassId) {
} }
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) { TEST(RegExp) {
v8::HandleScope scope; v8::HandleScope scope;
LocalContext context; LocalContext context;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment