Skip to content

Commit ae1fa98

Browse files
danbevMylesBorins
authored andcommitted
deps: cherry-pick f4376ec801e1ded from V8 upstream
Original commit message: [heap] Make maximum regular code object size a runtime value. Executable V8 pages include 3 reserved OS pages: one for the writable header and two as guards. On systems with 64k OS pages, the amount of allocatable space left for objects can then be quite smaller than the page size, only 64k for each 256k page. This means regular code objects cannot be larger than 64k, while the maximum regular object size is fixed to 128k, half of the page size. As a result code object never reach this limit and we can end up filling regular pages with few large code objects. To fix this, we change the maximum code object size to be runtime value, set to half of the allocatable space per page. On systems with 64k OS pages, the limit will be 32k. Alternatively, we could increase the V8 page size to 512k on Arm64 linux so we wouldn't waste code space. However, systems with 4k OS pages are more common, and those with 64k pages tend to have more memory available so we should be able to live with it. Bug: v8:10808 Change-Id: I5d807e7a3df89f1e9c648899e9ba2f8e2648264c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2460809 Reviewed-by: Igor Sheludko <[email protected]> Reviewed-by: Georg Neis <[email protected]> Reviewed-by: Ulan Degenbaev <[email protected]> Commit-Queue: Pierre Langlois <[email protected]> Cr-Commit-Position: refs/heads/master@{#70569} PR-URL: #37225 Refs: nodejs/help#3202 Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Stewart X Addison <[email protected]> Reviewed-By: Juan José Arboleda <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 78680c1 commit ae1fa98

18 files changed

+143
-21
lines changed

deps/v8/src/base/build_config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@
205205
// PPC has large (64KB) physical pages.
206206
const int kPageSizeBits = 19;
207207
#else
208+
// Arm64 supports up to 64k OS pages on Linux, however 4k pages are more common
209+
// so we keep the V8 page size at 256k. Nonetheless, we need to make sure we
210+
// don't decrease it further in the future due to reserving 3 OS pages for every
211+
// executable V8 page.
208212
const int kPageSizeBits = 18;
209213
#endif
210214

deps/v8/src/compiler/allocation-builder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class AllocationBuilder final {
2727
// Primitive allocation of static size.
2828
void Allocate(int size, AllocationType allocation = AllocationType::kYoung,
2929
Type type = Type::Any()) {
30-
DCHECK_LE(size, kMaxRegularHeapObjectSize);
30+
DCHECK_LE(size, Heap::MaxRegularHeapObjectSize(allocation));
3131
effect_ = graph()->NewNode(
3232
common()->BeginRegion(RegionObservability::kNotObservable), effect_);
3333
allocation_ =

deps/v8/src/compiler/memory-lowering.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ Reduction MemoryLowering::ReduceAllocateRaw(
9898
DCHECK_EQ(IrOpcode::kAllocateRaw, node->opcode());
9999
DCHECK_IMPLIES(allocation_folding_ == AllocationFolding::kDoAllocationFolding,
100100
state_ptr != nullptr);
101+
// Code objects may have a maximum size smaller than kMaxHeapObjectSize due to
102+
// guard pages. If we need to support allocating code here we would need to
103+
// call MemoryChunkLayout::MaxRegularCodeObjectSize() at runtime.
104+
DCHECK_NE(allocation_type, AllocationType::kCode);
101105
Node* value;
102106
Node* size = node->InputAt(0);
103107
Node* effect = node->InputAt(1);

deps/v8/src/diagnostics/objects-debug.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,8 @@ void Code::CodeVerify(Isolate* isolate) {
955955
// everything is set up.
956956
// CHECK_EQ(ReadOnlyHeap::Contains(*this), !IsExecutable());
957957
relocation_info().ObjectVerify(isolate);
958-
CHECK(Code::SizeFor(body_size()) <= kMaxRegularHeapObjectSize ||
958+
CHECK(Code::SizeFor(body_size()) <=
959+
MemoryChunkLayout::MaxRegularCodeObjectSize() ||
959960
isolate->heap()->InSpace(*this, CODE_LO_SPACE));
960961
Address last_gc_pc = kNullAddress;
961962

deps/v8/src/heap/factory-base.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,8 @@ template <typename Impl>
721721
HeapObject FactoryBase<Impl>::AllocateRawArray(int size,
722722
AllocationType allocation) {
723723
HeapObject result = AllocateRaw(size, allocation);
724-
if (size > kMaxRegularHeapObjectSize && FLAG_use_marking_progress_bar) {
724+
if ((size > Heap::MaxRegularHeapObjectSize(allocation)) &&
725+
FLAG_use_marking_progress_bar) {
725726
MemoryChunk* chunk = MemoryChunk::FromHeapObject(result);
726727
chunk->SetFlag<AccessMode::ATOMIC>(MemoryChunk::HAS_PROGRESS_BAR);
727728
}

deps/v8/src/heap/factory.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,8 @@ MaybeHandle<FixedArray> Factory::TryNewFixedArray(
346346
AllocationResult allocation = heap->AllocateRaw(size, allocation_type);
347347
HeapObject result;
348348
if (!allocation.To(&result)) return MaybeHandle<FixedArray>();
349-
if (size > kMaxRegularHeapObjectSize && FLAG_use_marking_progress_bar) {
349+
if ((size > Heap::MaxRegularHeapObjectSize(allocation_type)) &&
350+
FLAG_use_marking_progress_bar) {
350351
MemoryChunk* chunk = MemoryChunk::FromHeapObject(result);
351352
chunk->SetFlag<AccessMode::ATOMIC>(MemoryChunk::HAS_PROGRESS_BAR);
352353
}

deps/v8/src/heap/heap-inl.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,9 @@ AllocationResult Heap::AllocateRaw(int size_in_bytes, AllocationType type,
192192
IncrementObjectCounters();
193193
#endif
194194

195-
bool large_object = size_in_bytes > kMaxRegularHeapObjectSize;
195+
size_t large_object_threshold = MaxRegularHeapObjectSize(type);
196+
bool large_object =
197+
static_cast<size_t>(size_in_bytes) > large_object_threshold;
196198

197199
HeapObject object;
198200
AllocationResult allocation;
@@ -279,7 +281,7 @@ HeapObject Heap::AllocateRawWith(int size, AllocationType allocation,
279281
Address* limit = heap->NewSpaceAllocationLimitAddress();
280282
if (allocation == AllocationType::kYoung &&
281283
alignment == AllocationAlignment::kWordAligned &&
282-
size <= kMaxRegularHeapObjectSize &&
284+
size <= MaxRegularHeapObjectSize(allocation) &&
283285
(*limit - *top >= static_cast<unsigned>(size)) &&
284286
V8_LIKELY(!FLAG_single_generation && FLAG_inline_new &&
285287
FLAG_gc_interval == 0)) {

deps/v8/src/heap/heap.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4963,6 +4963,14 @@ bool Heap::AllocationLimitOvershotByLargeMargin() {
49634963
return v8_overshoot >= v8_margin || global_overshoot >= global_margin;
49644964
}
49654965

4966+
// static
4967+
int Heap::MaxRegularHeapObjectSize(AllocationType allocation) {
4968+
if (allocation == AllocationType::kCode) {
4969+
return MemoryChunkLayout::MaxRegularCodeObjectSize();
4970+
}
4971+
return kMaxRegularHeapObjectSize;
4972+
}
4973+
49664974
bool Heap::ShouldOptimizeForLoadTime() {
49674975
return isolate()->rail_mode() == PERFORMANCE_LOAD &&
49684976
!AllocationLimitOvershotByLargeMargin() &&

deps/v8/src/heap/heap.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ class Heap {
481481

482482
bool IsImmovable(HeapObject object);
483483

484-
static bool IsLargeObject(HeapObject object);
484+
V8_EXPORT_PRIVATE static bool IsLargeObject(HeapObject object);
485485

486486
// This method supports the deserialization allocator. All allocations
487487
// are word-aligned. The method should never fail to allocate since the
@@ -1316,6 +1316,14 @@ class Heap {
13161316
// more eager to finalize incremental marking.
13171317
bool AllocationLimitOvershotByLargeMargin();
13181318

1319+
// Return the maximum size objects can be before having to allocate them as
1320+
// large objects. This takes into account allocating in the code space for
1321+
// which the size of the allocatable space per V8 page may depend on the OS
1322+
// page size at runtime. You may use kMaxRegularHeapObjectSize as a constant
1323+
// instead if you know the allocation isn't in the code spaces.
1324+
V8_EXPORT_PRIVATE static int MaxRegularHeapObjectSize(
1325+
AllocationType allocation);
1326+
13191327
// ===========================================================================
13201328
// Prologue/epilogue callback methods.========================================
13211329
// ===========================================================================
@@ -1404,8 +1412,10 @@ class Heap {
14041412
// Heap object allocation tracking. ==========================================
14051413
// ===========================================================================
14061414

1407-
void AddHeapObjectAllocationTracker(HeapObjectAllocationTracker* tracker);
1408-
void RemoveHeapObjectAllocationTracker(HeapObjectAllocationTracker* tracker);
1415+
V8_EXPORT_PRIVATE void AddHeapObjectAllocationTracker(
1416+
HeapObjectAllocationTracker* tracker);
1417+
V8_EXPORT_PRIVATE void RemoveHeapObjectAllocationTracker(
1418+
HeapObjectAllocationTracker* tracker);
14091419
bool has_heap_object_allocation_tracker() const {
14101420
return !allocation_trackers_.empty();
14111421
}

deps/v8/src/heap/memory-chunk.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ intptr_t MemoryChunkLayout::ObjectEndOffsetInCodePage() {
4747

4848
size_t MemoryChunkLayout::AllocatableMemoryInCodePage() {
4949
size_t memory = ObjectEndOffsetInCodePage() - ObjectStartOffsetInCodePage();
50-
DCHECK_LE(kMaxRegularHeapObjectSize, memory);
5150
return memory;
5251
}
5352

@@ -77,6 +76,12 @@ size_t MemoryChunkLayout::AllocatableMemoryInMemoryChunk(
7776
return AllocatableMemoryInDataPage();
7877
}
7978

79+
int MemoryChunkLayout::MaxRegularCodeObjectSize() {
80+
int size = static_cast<int>(AllocatableMemoryInCodePage() / 2);
81+
DCHECK_LE(size, kMaxRegularHeapObjectSize);
82+
return size;
83+
}
84+
8085
#ifdef THREAD_SANITIZER
8186
void MemoryChunk::SynchronizedHeapLoad() {
8287
CHECK(reinterpret_cast<Heap*>(base::Acquire_Load(

0 commit comments

Comments
 (0)