Revert of Changed scavenge GC to collect unmodified references (patchset #9 id:160001 of https://codereview.chromium.org/1358703003/ )
Reason for revert: [Sheriff] Speculative revert due to crbug.com/539814 Original issue's description: > Changed scavenge GC to collect unmodified references > > Added a scavenge GC pass that collects unmodified references instead of > processing object groups. This mode can be controlled by setting > FLAG_scavenge_remove_unmodified_objects. By default this is turned off. > Also, modified a test case to suit the handle the new GC pass. > > BUG=v8:4421 > LOG=N > > Committed: https://crrev.com/6254019238a853c9f3c09d615ba153043f6957c7 > Cr-Commit-Position: refs/heads/master@{#31102} TBR=jochen@chromium.org,rmcilroy@chromium.org,mythria@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=v8:4421,chromium:539814 Review URL: https://codereview.chromium.org/1388133002 Cr-Commit-Position: refs/heads/master@{#31130}
This commit is contained in:
parent
9af0174f03
commit
2e1dbae08b
@ -677,8 +677,6 @@ DEFINE_BOOL(verify_heap, false, "verify heap pointers before and after GC")
|
||||
#endif
|
||||
DEFINE_BOOL(move_object_start, false, "enable moving of object starts")
|
||||
DEFINE_BOOL(memory_reducer, true, "use memory reducer")
|
||||
DEFINE_BOOL(scavenge_reclaim_unmodified_objects, true,
|
||||
"remove unmodified and unreferenced objects")
|
||||
|
||||
// counters.cc
|
||||
DEFINE_INT(histogram_interval, 600000,
|
||||
|
@ -64,11 +64,7 @@ class GlobalHandles::Node {
|
||||
class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
|
||||
index_ = 0;
|
||||
set_independent(false);
|
||||
if (FLAG_scavenge_reclaim_unmodified_objects) {
|
||||
set_unmodified(false);
|
||||
} else {
|
||||
set_partially_dependent(false);
|
||||
}
|
||||
set_in_new_space_list(false);
|
||||
parameter_or_next_free_.next_free = NULL;
|
||||
weak_callback_ = NULL;
|
||||
@ -81,9 +77,6 @@ class GlobalHandles::Node {
|
||||
set_state(FREE);
|
||||
set_weakness_type(NORMAL_WEAK);
|
||||
set_in_new_space_list(false);
|
||||
if (FLAG_scavenge_reclaim_unmodified_objects) {
|
||||
set_unmodified(false);
|
||||
}
|
||||
parameter_or_next_free_.next_free = *first_free;
|
||||
*first_free = this;
|
||||
}
|
||||
@ -93,11 +86,7 @@ class GlobalHandles::Node {
|
||||
object_ = object;
|
||||
class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
|
||||
set_independent(false);
|
||||
if (FLAG_scavenge_reclaim_unmodified_objects) {
|
||||
set_unmodified(false);
|
||||
} else {
|
||||
set_partially_dependent(false);
|
||||
}
|
||||
set_state(NORMAL);
|
||||
parameter_or_next_free_.parameter = NULL;
|
||||
weak_callback_ = NULL;
|
||||
@ -117,11 +106,7 @@ class GlobalHandles::Node {
|
||||
object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
|
||||
class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
|
||||
set_independent(false);
|
||||
if (FLAG_scavenge_reclaim_unmodified_objects) {
|
||||
set_unmodified(false);
|
||||
} else {
|
||||
set_partially_dependent(false);
|
||||
}
|
||||
weak_callback_ = NULL;
|
||||
DecreaseBlockUses();
|
||||
}
|
||||
@ -155,23 +140,12 @@ class GlobalHandles::Node {
|
||||
}
|
||||
|
||||
bool is_partially_dependent() {
|
||||
CHECK(!FLAG_scavenge_reclaim_unmodified_objects);
|
||||
return IsPartiallyDependent::decode(flags_);
|
||||
}
|
||||
void set_partially_dependent(bool v) {
|
||||
CHECK(!FLAG_scavenge_reclaim_unmodified_objects);
|
||||
flags_ = IsPartiallyDependent::update(flags_, v);
|
||||
}
|
||||
|
||||
bool is_unmodified() {
|
||||
CHECK(FLAG_scavenge_reclaim_unmodified_objects);
|
||||
return IsUnmodified::decode(flags_);
|
||||
}
|
||||
void set_unmodified(bool v) {
|
||||
CHECK(FLAG_scavenge_reclaim_unmodified_objects);
|
||||
flags_ = IsUnmodified::update(flags_, v);
|
||||
}
|
||||
|
||||
bool is_in_new_space_list() {
|
||||
return IsInNewSpaceList::decode(flags_);
|
||||
}
|
||||
@ -375,8 +349,6 @@ class GlobalHandles::Node {
|
||||
// in_new_space_list) and a State.
|
||||
class NodeState : public BitField<State, 0, 3> {};
|
||||
class IsIndependent : public BitField<bool, 3, 1> {};
|
||||
// The following two fields are mutually exclusive
|
||||
class IsUnmodified : public BitField<bool, 4, 1> {};
|
||||
class IsPartiallyDependent : public BitField<bool, 4, 1> {};
|
||||
class IsInNewSpaceList : public BitField<bool, 5, 1> {};
|
||||
class NodeWeaknessType : public BitField<WeaknessType, 6, 2> {};
|
||||
@ -674,13 +646,6 @@ void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) {
|
||||
void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v) {
|
||||
for (int i = 0; i < new_space_nodes_.length(); ++i) {
|
||||
Node* node = new_space_nodes_[i];
|
||||
if (FLAG_scavenge_reclaim_unmodified_objects) {
|
||||
if (node->IsStrongRetainer() ||
|
||||
(node->IsWeakRetainer() && !node->is_independent() &&
|
||||
!node->is_unmodified())) {
|
||||
v->VisitPointer(node->location());
|
||||
}
|
||||
} else {
|
||||
if (node->IsStrongRetainer() ||
|
||||
(node->IsWeakRetainer() && !node->is_independent() &&
|
||||
!node->is_partially_dependent())) {
|
||||
@ -688,7 +653,6 @@ void GlobalHandles::IterateNewSpaceStrongAndDependentRoots(ObjectVisitor* v) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GlobalHandles::IdentifyNewSpaceWeakIndependentHandles(
|
||||
@ -723,49 +687,6 @@ void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
|
||||
}
|
||||
|
||||
|
||||
void GlobalHandles::IdentifyWeakUnmodifiedObjects(
|
||||
WeakSlotCallback is_unmodified) {
|
||||
for (int i = 0; i < new_space_nodes_.length(); ++i) {
|
||||
Node* node = new_space_nodes_[i];
|
||||
if (node->IsWeak() && is_unmodified(node->location())) {
|
||||
node->set_unmodified(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GlobalHandles::MarkNewSpaceWeakUnmodifiedObjectsPending(
|
||||
WeakSlotCallbackWithHeap is_unscavenged) {
|
||||
for (int i = 0; i < new_space_nodes_.length(); ++i) {
|
||||
Node* node = new_space_nodes_[i];
|
||||
DCHECK(node->is_in_new_space_list());
|
||||
if ((node->is_independent() || node->is_unmodified()) && node->IsWeak() &&
|
||||
is_unscavenged(isolate_->heap(), node->location())) {
|
||||
node->MarkPending();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GlobalHandles::IterateNewSpaceWeakUnmodifiedRoots(ObjectVisitor* v) {
|
||||
for (int i = 0; i < new_space_nodes_.length(); ++i) {
|
||||
Node* node = new_space_nodes_[i];
|
||||
DCHECK(node->is_in_new_space_list());
|
||||
if ((node->is_independent() || node->is_unmodified()) &&
|
||||
node->IsWeakRetainer()) {
|
||||
// Pending weak phantom handles die immediately. Everything else survives.
|
||||
if (node->state() == Node::PENDING &&
|
||||
node->weakness_type() != NORMAL_WEAK) {
|
||||
node->CollectPhantomCallbackData(isolate(),
|
||||
&pending_phantom_callbacks_);
|
||||
} else {
|
||||
v->VisitPointer(node->location());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
|
||||
WeakSlotCallbackWithHeap can_skip) {
|
||||
ComputeObjectGroupsAndImplicitReferences();
|
||||
@ -836,22 +757,13 @@ int GlobalHandles::PostScavengeProcessing(
|
||||
// the freed_nodes.
|
||||
continue;
|
||||
}
|
||||
// Skip dependent or unmodified handles. Their weak callbacks might expect
|
||||
// to be
|
||||
// Skip dependent handles. Their weak callbacks might expect to be
|
||||
// called between two global garbage collection callbacks which
|
||||
// are not called for minor collections.
|
||||
if (FLAG_scavenge_reclaim_unmodified_objects) {
|
||||
if (!node->is_independent() && !node->is_unmodified()) {
|
||||
continue;
|
||||
}
|
||||
node->set_unmodified(false);
|
||||
} else {
|
||||
if (!node->is_independent() && !node->is_partially_dependent()) {
|
||||
continue;
|
||||
}
|
||||
node->clear_partially_dependent();
|
||||
}
|
||||
|
||||
if (node->PostGarbageCollectionProcessing(isolate_)) {
|
||||
if (initial_post_gc_processing_count != post_gc_processing_count_) {
|
||||
// Weak callback triggered another GC and another round of
|
||||
@ -878,11 +790,7 @@ int GlobalHandles::PostMarkSweepProcessing(
|
||||
// the freed_nodes.
|
||||
continue;
|
||||
}
|
||||
if (FLAG_scavenge_reclaim_unmodified_objects) {
|
||||
it.node()->set_unmodified(false);
|
||||
} else {
|
||||
it.node()->clear_partially_dependent();
|
||||
}
|
||||
if (it.node()->PostGarbageCollectionProcessing(isolate_)) {
|
||||
if (initial_post_gc_processing_count != post_gc_processing_count_) {
|
||||
// See the comment above.
|
||||
|
@ -204,7 +204,7 @@ class GlobalHandles {
|
||||
// them as pending.
|
||||
void IdentifyWeakHandles(WeakSlotCallback f);
|
||||
|
||||
// NOTE: Five ...NewSpace... functions below are used during
|
||||
// NOTE: Three ...NewSpace... functions below are used during
|
||||
// scavenge collections and iterate over sets of handles that are
|
||||
// guaranteed to contain all handles holding new space objects (but
|
||||
// may also include old space objects).
|
||||
@ -220,19 +220,6 @@ class GlobalHandles {
|
||||
// See the note above.
|
||||
void IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v);
|
||||
|
||||
// Finds weak independent or unmodified handles satisfying
|
||||
// the callback predicate and marks them as pending. See the note above.
|
||||
void MarkNewSpaceWeakUnmodifiedObjectsPending(
|
||||
WeakSlotCallbackWithHeap is_unscavenged);
|
||||
|
||||
// Iterates over weak independent or unmodified handles.
|
||||
// See the note above.
|
||||
void IterateNewSpaceWeakUnmodifiedRoots(ObjectVisitor* v);
|
||||
|
||||
// Identify unmodified objects that are in weak state and marks them
|
||||
// unmodified
|
||||
void IdentifyWeakUnmodifiedObjects(WeakSlotCallback is_unmodified);
|
||||
|
||||
// Iterate over objects in object groups that have at least one object
|
||||
// which requires visiting. The callback has to return true if objects
|
||||
// can be skipped and false otherwise.
|
||||
|
@ -1255,12 +1255,9 @@ bool Heap::PerformGarbageCollection(
|
||||
GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
|
||||
VMState<EXTERNAL> state(isolate_);
|
||||
HandleScope handle_scope(isolate_);
|
||||
if (!(FLAG_scavenge_reclaim_unmodified_objects &&
|
||||
(gc_type == kGCTypeScavenge))) {
|
||||
CallGCPrologueCallbacks(gc_type, kNoGCCallbackFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EnsureFromSpaceIsCommitted();
|
||||
|
||||
@ -1343,12 +1340,9 @@ bool Heap::PerformGarbageCollection(
|
||||
GCTracer::Scope scope(tracer(), GCTracer::Scope::EXTERNAL);
|
||||
VMState<EXTERNAL> state(isolate_);
|
||||
HandleScope handle_scope(isolate_);
|
||||
if (!(FLAG_scavenge_reclaim_unmodified_objects &&
|
||||
(gc_type == kGCTypeScavenge))) {
|
||||
CallGCEpilogueCallbacks(gc_type, gc_callback_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VERIFY_HEAP
|
||||
if (FLAG_verify_heap) {
|
||||
@ -1506,22 +1500,6 @@ static bool IsUnscavengedHeapObject(Heap* heap, Object** p) {
|
||||
}
|
||||
|
||||
|
||||
static bool IsUnmodifiedHeapObject(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 != nullptr &&
|
||||
constructor->initial_map() == heap_object->map()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Heap::ScavengeStoreBufferCallback(Heap* heap, MemoryChunk* page,
|
||||
StoreBufferEvent event) {
|
||||
heap->store_buffer_rebuilder_.Callback(page, event);
|
||||
@ -1640,12 +1618,6 @@ void Heap::Scavenge() {
|
||||
promotion_queue_.Initialize();
|
||||
|
||||
ScavengeVisitor scavenge_visitor(this);
|
||||
|
||||
if (FLAG_scavenge_reclaim_unmodified_objects) {
|
||||
isolate()->global_handles()->IdentifyWeakUnmodifiedObjects(
|
||||
&IsUnmodifiedHeapObject);
|
||||
}
|
||||
|
||||
{
|
||||
// Copy roots.
|
||||
GCTracer::Scope gc_scope(tracer(), GCTracer::Scope::SCAVENGER_ROOTS);
|
||||
@ -1684,14 +1656,7 @@ void Heap::Scavenge() {
|
||||
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
|
||||
}
|
||||
|
||||
if (FLAG_scavenge_reclaim_unmodified_objects) {
|
||||
isolate()->global_handles()->MarkNewSpaceWeakUnmodifiedObjectsPending(
|
||||
&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(
|
||||
@ -1700,6 +1665,7 @@ void Heap::Scavenge() {
|
||||
}
|
||||
isolate()->global_handles()->RemoveObjectGroups();
|
||||
isolate()->global_handles()->RemoveImplicitRefGroups();
|
||||
}
|
||||
|
||||
isolate()->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
|
||||
&IsUnscavengedHeapObject);
|
||||
@ -1707,7 +1673,6 @@ void Heap::Scavenge() {
|
||||
isolate()->global_handles()->IterateNewSpaceWeakIndependentRoots(
|
||||
&scavenge_visitor);
|
||||
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
|
||||
}
|
||||
|
||||
UpdateNewSpaceReferencesInExternalStringTable(
|
||||
&UpdateNewSpaceReferenceInExternalStringTableEntry);
|
||||
|
@ -6536,8 +6536,7 @@ static void IndependentWeakHandle(bool global_gc, bool interlinked) {
|
||||
Local<Object> b(v8::Object::New(iso));
|
||||
object_a.handle.Reset(iso, a);
|
||||
object_b.handle.Reset(iso, b);
|
||||
if (interlinked &&
|
||||
!v8::internal::FLAG_scavenge_reclaim_unmodified_objects) {
|
||||
if (interlinked) {
|
||||
a->Set(v8_str("x"), b);
|
||||
b->Set(v8_str("x"), a);
|
||||
}
|
||||
@ -6549,7 +6548,6 @@ static void IndependentWeakHandle(bool global_gc, bool interlinked) {
|
||||
// We are relying on this creating a big flag array and reserving the space
|
||||
// up front.
|
||||
v8::Handle<Value> big_array = CompileRun("new Array(50000)");
|
||||
if (!v8::internal::FLAG_scavenge_reclaim_unmodified_objects)
|
||||
a->Set(v8_str("y"), big_array);
|
||||
big_heap_size = CcTest::heap()->SizeOfObjects();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user