| Index: src/heap/heap.cc
|
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
| index 31b93e71991e219b5c6050bd0f17bd890f6018ec..7089054d73e1e99034c159dcc6a0ceab96a606d2 100644
|
| --- a/src/heap/heap.cc
|
| +++ b/src/heap/heap.cc
|
| @@ -1206,7 +1206,10 @@ bool Heap::PerformGarbageCollection(
|
| GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
|
| VMState<EXTERNAL> state(isolate_);
|
| HandleScope handle_scope(isolate_);
|
| - CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags);
|
| + if (!(gc_type == kGCTypeScavenge &&
|
| + FLAG_scavenge_remove_unmodified_objects)) {
|
| + CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags);
|
| + }
|
| }
|
| }
|
|
|
| @@ -1291,7 +1294,10 @@ bool Heap::PerformGarbageCollection(
|
| GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
|
| VMState<EXTERNAL> state(isolate_);
|
| HandleScope handle_scope(isolate_);
|
| - CallGCEpilogueCallbacks(gc_type, gc_callback_flags);
|
| + if (!(gc_type == kGCTypeScavenge &&
|
| + FLAG_scavenge_remove_unmodified_objects)) {
|
| + CallGCEpilogueCallbacks(gc_type, gc_callback_flags);
|
| + }
|
| }
|
| }
|
|
|
| @@ -1445,6 +1451,22 @@ void Heap::CheckNewSpaceExpansionCriteria() {
|
| }
|
|
|
|
|
| +static bool IsUnModifiedNewSpaceObject(Object** p) {
|
| + Object* object = *p;
|
| + DCHECK(object->IsHeapObject());
|
| + HeapObject* heap_object = HeapObject::cast(object);
|
| + if (!object->IsJSObject()) {
|
| + return false;
|
| + }
|
| + Object* obj_constructor = (JSObject::cast(object))->map()->GetConstructor();
|
| + if (!obj_constructor->IsJSFunction()) return false;
|
| + JSFunction* constructor = JSFunction::cast(obj_constructor);
|
| + if (constructor == NULL) return false;
|
| + if (constructor->initial_map() == heap_object->map()) return true;
|
| + return false;
|
| +}
|
| +
|
| +
|
| static bool IsUnscavengedHeapObject(Heap* heap, Object** p) {
|
| return heap->InNewSpace(*p) &&
|
| !HeapObject::cast(*p)->map_word().IsForwardingAddress();
|
| @@ -1569,6 +1591,13 @@ void Heap::Scavenge() {
|
| promotion_queue_.Initialize();
|
|
|
| ScavengeVisitor scavenge_visitor(this);
|
| +
|
| + if (FLAG_scavenge_remove_unmodified_objects) {
|
| + isolate()->global_handles()->IdentifyWeakUnmodifiedObjects(
|
| + &IsUnModifiedNewSpaceObject);
|
| + }
|
| +
|
| +
|
| {
|
| // Copy roots.
|
| GCTracer::Scope gc_scope(tracer(), GCTracer::Scope::SCAVENGER_ROOTS);
|
| @@ -1607,7 +1636,14 @@ void Heap::Scavenge() {
|
| new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
|
| }
|
|
|
| - {
|
| + if (FLAG_scavenge_remove_unmodified_objects) {
|
| + isolate()->global_handles()->IdentifyNewSpaceWeakUnModifiedHandles(
|
| + &IsUnscavengedHeapObject);
|
| +
|
| + isolate()->global_handles()->IterateNewSpaceWeakUnModifiedRoots(
|
| + &scavenge_visitor);
|
| + new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
|
| + } else {
|
| GCTracer::Scope gc_scope(tracer(),
|
| GCTracer::Scope::SCAVENGER_OBJECT_GROUPS);
|
| while (isolate()->global_handles()->IterateObjectGroups(
|
| @@ -1616,14 +1652,14 @@ void Heap::Scavenge() {
|
| }
|
| isolate()->global_handles()->RemoveObjectGroups();
|
| isolate()->global_handles()->RemoveImplicitRefGroups();
|
| - }
|
|
|
| - isolate()->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
|
| - &IsUnscavengedHeapObject);
|
| + isolate()->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
|
| + &IsUnscavengedHeapObject);
|
|
|
| - isolate()->global_handles()->IterateNewSpaceWeakIndependentRoots(
|
| - &scavenge_visitor);
|
| - new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
|
| + isolate()->global_handles()->IterateNewSpaceWeakIndependentRoots(
|
| + &scavenge_visitor);
|
| + new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
|
| + }
|
|
|
| UpdateNewSpaceReferencesInExternalStringTable(
|
| &UpdateNewSpaceReferenceInExternalStringTableEntry);
|
|
|