Commit be33ad31 authored by Dominik Inführ's avatar Dominik Inführ Committed by Commit Bot

[heap] Make Heap::AllocateRaw invoke Safepoint()

This will help reducing the time needed to reach a Safepoint() on the
main thread. During startup main_thread_local_isolate() is not
initialized when Heap::AllocateRaw() is invoked. Solve this by
only running Safepoint() after deserialization is completed.

Bug: v8:10315
Change-Id: I281fdbe5cebcd7946d687f56676c0d563792fde5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2835714
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarVictor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74181}
parent 923d3260
......@@ -3604,6 +3604,8 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
main_thread_local_isolate_.reset(new LocalIsolate(this, ThreadKind::kMain));
main_thread_local_heap()->Unpark();
heap_.InitializeMainThreadLocalHeap(main_thread_local_heap());
isolate_data_.external_reference_table()->Init(this);
#if V8_ENABLE_WEBASSEMBLY
......
......@@ -22,8 +22,7 @@ bool CollectionBarrier::CollectionRequested() {
}
LocalHeap::ThreadState CollectionBarrier::main_thread_state_relaxed() {
LocalHeap* main_thread_local_heap =
heap_->isolate()->main_thread_local_heap();
LocalHeap* main_thread_local_heap = heap_->main_thread_local_heap();
return main_thread_local_heap->state_relaxed();
}
......
......@@ -197,6 +197,10 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationType type,
IncrementObjectCounters();
#endif
if (CanSafepoint()) {
main_thread_local_heap()->Safepoint();
}
size_t large_object_threshold = MaxRegularHeapObjectSize(type);
bool large_object =
static_cast<size_t>(size_in_bytes) > large_object_threshold;
......
......@@ -1280,10 +1280,8 @@ void Heap::GarbageCollectionEpilogueInSafepoint(GarbageCollector collector) {
}
// Set main thread state back to Running from CollectionRequested.
LocalHeap* main_thread_local_heap = isolate()->main_thread_local_heap();
LocalHeap::ThreadState old_state =
main_thread_local_heap->state_.exchange(LocalHeap::kRunning);
main_thread_local_heap()->state_.exchange(LocalHeap::kRunning);
CHECK(old_state == LocalHeap::kRunning ||
old_state == LocalHeap::kCollectionRequested);
......@@ -5426,6 +5424,11 @@ void Heap::SetUpSpaces() {
write_protect_code_memory_ = FLAG_write_protect_code_memory;
}
void Heap::InitializeMainThreadLocalHeap(LocalHeap* main_thread_local_heap) {
DCHECK_NULL(main_thread_local_heap_);
main_thread_local_heap_ = main_thread_local_heap;
}
void Heap::InitializeHashSeed() {
DCHECK(!deserialization_complete_);
uint64_t new_hash_seed;
......
......@@ -763,6 +763,11 @@ class Heap {
inline bool CanAllocateInReadOnlySpace();
bool deserialization_complete() const { return deserialization_complete_; }
// We can only invoke Safepoint() on the main thread local heap after
// deserialization is complete. Before that, main_thread_local_heap_ might be
// null.
V8_INLINE bool CanSafepoint() const { return deserialization_complete(); }
bool HasLowAllocationRate();
bool HasHighFragmentation();
bool HasHighFragmentation(size_t used, size_t committed);
......@@ -805,6 +810,9 @@ class Heap {
// Sets up the heap memory without creating any objects.
void SetUpSpaces();
// Prepares the heap, setting up for deserialization.
void InitializeMainThreadLocalHeap(LocalHeap* main_thread_local_heap);
// (Re-)Initialize hash seed from flag or RNG.
void InitializeHashSeed();
......@@ -876,6 +884,8 @@ class Heap {
const base::AddressRegion& code_range();
LocalHeap* main_thread_local_heap() { return main_thread_local_heap_; }
// ===========================================================================
// Root set access. ==========================================================
// ===========================================================================
......@@ -2038,7 +2048,7 @@ class Heap {
AllocationAlignment alignment = kWordAligned);
// Allocates a heap object based on the map.
V8_WARN_UNUSED_RESULT AllocationResult Allocate(Map map,
V8_WARN_UNUSED_RESULT AllocationResult Allocate(Handle<Map> map,
AllocationType allocation);
// Allocates a partial map for bootstrapping.
......@@ -2136,9 +2146,12 @@ class Heap {
CodeLargeObjectSpace* code_lo_space_ = nullptr;
NewLargeObjectSpace* new_lo_space_ = nullptr;
ReadOnlySpace* read_only_space_ = nullptr;
// Map from the space id to the space.
Space* space_[LAST_SPACE + 1];
LocalHeap* main_thread_local_heap_ = nullptr;
// List for tracking ArrayBufferExtensions
ArrayBufferExtension* old_array_buffer_extensions_ = nullptr;
ArrayBufferExtension* young_array_buffer_extensions_ = nullptr;
......
......@@ -221,7 +221,7 @@ bool LocalHeap::TryPerformCollection() {
heap_->CollectGarbageForBackground(this);
return true;
} else {
LocalHeap* main_thread = heap_->isolate()->main_thread_local_heap();
LocalHeap* main_thread = heap_->main_thread_local_heap();
ThreadState current = main_thread->state_relaxed();
while (true) {
......
......@@ -195,9 +195,10 @@ void Heap::FinalizePartialMap(Map map) {
map.set_constructor_or_back_pointer(roots.null_value());
}
AllocationResult Heap::Allocate(Map map, AllocationType allocation_type) {
DCHECK(map.instance_type() != MAP_TYPE);
int size = map.instance_size();
AllocationResult Heap::Allocate(Handle<Map> map,
AllocationType allocation_type) {
DCHECK(map->instance_type() != MAP_TYPE);
int size = map->instance_size();
HeapObject result;
AllocationResult allocation = AllocateRaw(size, allocation_type);
if (!allocation.To(&result)) return allocation;
......@@ -205,7 +206,7 @@ AllocationResult Heap::Allocate(Map map, AllocationType allocation_type) {
WriteBarrierMode write_barrier_mode =
allocation_type == AllocationType::kYoung ? SKIP_WRITE_BARRIER
: UPDATE_WRITE_BARRIER;
result.set_map_after_allocation(map, write_barrier_mode);
result.set_map_after_allocation(*map, write_barrier_mode);
return result;
}
......@@ -281,7 +282,7 @@ bool Heap::CreateInitialMaps() {
{
AllocationResult allocation =
Allocate(roots.null_map(), AllocationType::kReadOnly);
Allocate(roots.null_map_handle(), AllocationType::kReadOnly);
if (!allocation.To(&obj)) return false;
}
set_null_value(Oddball::cast(obj));
......@@ -289,7 +290,7 @@ bool Heap::CreateInitialMaps() {
{
AllocationResult allocation =
Allocate(roots.undefined_map(), AllocationType::kReadOnly);
Allocate(roots.undefined_map_handle(), AllocationType::kReadOnly);
if (!allocation.To(&obj)) return false;
}
set_undefined_value(Oddball::cast(obj));
......@@ -297,7 +298,7 @@ bool Heap::CreateInitialMaps() {
DCHECK(!InYoungGeneration(roots.undefined_value()));
{
AllocationResult allocation =
Allocate(roots.the_hole_map(), AllocationType::kReadOnly);
Allocate(roots.the_hole_map_handle(), AllocationType::kReadOnly);
if (!allocation.To(&obj)) return false;
}
set_the_hole_value(Oddball::cast(obj));
......@@ -317,7 +318,7 @@ bool Heap::CreateInitialMaps() {
// Allocate the empty enum cache.
{
AllocationResult allocation =
Allocate(roots.enum_cache_map(), AllocationType::kReadOnly);
Allocate(roots.enum_cache_map_handle(), AllocationType::kReadOnly);
if (!allocation.To(&obj)) return false;
}
set_empty_enum_cache(EnumCache::cast(obj));
......@@ -551,8 +552,9 @@ bool Heap::CreateInitialMaps() {
{
// Empty array boilerplate description
AllocationResult alloc = Allocate(roots.array_boilerplate_description_map(),
AllocationType::kReadOnly);
AllocationResult alloc =
Allocate(roots.array_boilerplate_description_map_handle(),
AllocationType::kReadOnly);
if (!alloc.To(&obj)) return false;
ArrayBoilerplateDescription::cast(obj).set_constant_elements(
......@@ -565,7 +567,7 @@ bool Heap::CreateInitialMaps() {
{
AllocationResult allocation =
Allocate(roots.boolean_map(), AllocationType::kReadOnly);
Allocate(roots.boolean_map_handle(), AllocationType::kReadOnly);
if (!allocation.To(&obj)) return false;
}
set_true_value(Oddball::cast(obj));
......@@ -573,7 +575,7 @@ bool Heap::CreateInitialMaps() {
{
AllocationResult allocation =
Allocate(roots.boolean_map(), AllocationType::kReadOnly);
Allocate(roots.boolean_map_handle(), AllocationType::kReadOnly);
if (!allocation.To(&obj)) return false;
}
set_false_value(Oddball::cast(obj));
......
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