Commit df625be0 authored by Dan Elphick's avatar Dan Elphick Committed by Commit Bot

[heap] Skip marking of read-only roots

Adds new VisitModes VISIT_ALL_BUT_READ_ONLY and
VISIT_STRONG_FOR_SERIALIZATION.

GC-related methods like MarkReachableObjects now now use
VISIT_ALL_BUT_READ_ONLY instead of VISIT_ALL. All GC-related VisitModes
skip iterating over the read-only roots.

All Serializer methods should always use a _FOR_SERIALIZATION value to
ensure they do visit the read-only roots.

Also adds RootsTable::read_only_roots_begin and end methods.

Bug: v8:7464
Change-Id: I468d7ae9f345d9fc0e10837f01dc5b92bd996412
Reviewed-on: https://chromium-review.googlesource.com/c/1256245Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Commit-Queue: Dan Elphick <delphick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56368}
parent 469c7ee9
......@@ -623,11 +623,13 @@ enum Movability { kMovable, kImmovable };
enum VisitMode {
VISIT_ALL,
VISIT_ALL_BUT_READ_ONLY,
VISIT_ALL_IN_MINOR_MC_MARK,
VISIT_ALL_IN_MINOR_MC_UPDATE,
VISIT_ALL_IN_SCAVENGE,
VISIT_ALL_IN_SWEEP_NEWSPACE,
VISIT_ONLY_STRONG,
VISIT_ONLY_STRONG_FOR_SERIALIZATION,
VISIT_FOR_SERIALIZATION,
};
......
......@@ -3788,8 +3788,13 @@ void Heap::IterateStrongRoots(RootVisitor* v, VisitMode mode) {
const bool isMinorGC = mode == VISIT_ALL_IN_SCAVENGE ||
mode == VISIT_ALL_IN_MINOR_MC_MARK ||
mode == VISIT_ALL_IN_MINOR_MC_UPDATE;
v->VisitRootPointers(Root::kStrongRootList, nullptr,
roots_.strong_roots_begin(), roots_.strong_roots_end());
// Garbage collection can skip over the read-only roots.
const bool isGC = mode != VISIT_ALL && mode != VISIT_FOR_SERIALIZATION &&
mode != VISIT_ONLY_STRONG_FOR_SERIALIZATION;
Object** start =
isGC ? roots_.read_only_roots_end() : roots_.strong_roots_begin();
v->VisitRootPointers(Root::kStrongRootList, nullptr, start,
roots_.strong_roots_end());
v->Synchronize(VisitorSynchronization::kStrongRootList);
isolate_->bootstrapper()->Iterate(v);
......@@ -3828,17 +3833,19 @@ void Heap::IterateStrongRoots(RootVisitor* v, VisitMode mode) {
// global handles need to be added manually.
break;
case VISIT_ONLY_STRONG:
case VISIT_ONLY_STRONG_FOR_SERIALIZATION:
isolate_->global_handles()->IterateStrongRoots(v);
break;
case VISIT_ALL_IN_SCAVENGE:
isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v);
break;
case VISIT_ALL_IN_MINOR_MC_MARK:
// Global handles are processed manually be the minor MC.
// Global handles are processed manually by the minor MC.
break;
case VISIT_ALL_IN_MINOR_MC_UPDATE:
// Global handles are processed manually be the minor MC.
// Global handles are processed manually by the minor MC.
break;
case VISIT_ALL_BUT_READ_ONLY:
case VISIT_ALL_IN_SWEEP_NEWSPACE:
case VISIT_ALL:
isolate_->global_handles()->IterateAllRoots(v);
......@@ -5062,7 +5069,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
void MarkReachableObjects() {
MarkingVisitor visitor(this);
heap_->IterateRoots(&visitor, VISIT_ALL);
heap_->IterateRoots(&visitor, VISIT_ALL_BUT_READ_ONLY);
visitor.TransitiveClosure();
}
......
......@@ -1586,7 +1586,7 @@ bool V8HeapExplorer::IterateAndExtractReferences(SnapshotFiller* filler) {
// first. Otherwise a particular JSFunction object could set
// its custom name to a generic builtin.
RootsReferencesExtractor extractor(this);
heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG);
heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG_FOR_SERIALIZATION);
extractor.SetVisitingWeakRoots();
heap_->IterateWeakGlobalHandles(&extractor);
......
......@@ -56,6 +56,25 @@ FixedTypedArrayBase* ReadOnlyRoots::EmptyFixedTypedArrayForMap(const Map* map) {
return FixedTypedArrayBase::cast(roots_table_[root_index]);
}
Object** RootsTable::read_only_roots_end() {
// Enumerate the read-only roots into an expression of the form:
// (root_1, root_2, root_3, ..., root_n)
// This evaluates to root_n, but Clang warns that the other values in the list
// are unused so suppress that warning.
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value"
#endif
#define ROOT(type, name, CamelName) , RootIndex::k##CamelName
constexpr RootIndex kLastReadOnlyRoot =
(RootIndex::kFirstRoot READ_ONLY_ROOT_LIST(ROOT));
#undef ROOT
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
return &roots_[static_cast<size_t>(kLastReadOnlyRoot) + 1];
}
} // namespace internal
} // namespace v8
......
......@@ -387,6 +387,11 @@ class RootsTable {
static RootIndex RootIndexForEmptyFixedTypedArray(ElementsKind elements_kind);
private:
Object** read_only_roots_begin() {
return &roots_[static_cast<size_t>(RootIndex::kFirstStrongRoot)];
}
inline Object** read_only_roots_end();
Object** strong_roots_begin() {
return &roots_[static_cast<size_t>(RootIndex::kFirstStrongRoot)];
}
......
......@@ -37,7 +37,8 @@ void StartupDeserializer::DeserializeInto(Isolate* isolate) {
{
DisallowHeapAllocation no_gc;
isolate->heap()->IterateSmiRoots(this);
isolate->heap()->IterateStrongRoots(this, VISIT_ONLY_STRONG);
isolate->heap()->IterateStrongRoots(this,
VISIT_ONLY_STRONG_FOR_SERIALIZATION);
isolate->heap()->RepairFreeListsAfterDeserialization();
isolate->heap()->IterateWeakRoots(this, VISIT_FOR_SERIALIZATION);
DeserializeDeferredObjects();
......
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