Skip to content

Commit fe0e49d

Browse files
hannespayerCommit bot
authored andcommitted
Move double alignment logic into memory allocator.
BUG=chromium:436911 Review URL: https://codereview.chromium.org/1127993002 Cr-Commit-Position: refs/heads/master@{#28262}
1 parent 6618793 commit fe0e49d

5 files changed

Lines changed: 120 additions & 39 deletions

File tree

src/heap/heap.cc

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,24 +1941,19 @@ STATIC_ASSERT((ConstantPoolArray::kExtendedFirstOffset &
19411941
kDoubleAlignmentMask) == 0); // NOLINT
19421942

19431943

1944-
INLINE(static HeapObject* EnsureDoubleAligned(Heap* heap, HeapObject* object,
1945-
int size));
1946-
1947-
static HeapObject* EnsureDoubleAligned(Heap* heap, HeapObject* object,
1948-
int size) {
1944+
HeapObject* Heap::EnsureDoubleAligned(HeapObject* object, int size) {
19491945
if ((OffsetFrom(object->address()) & kDoubleAlignmentMask) != 0) {
1950-
heap->CreateFillerObjectAt(object->address(), kPointerSize);
1946+
CreateFillerObjectAt(object->address(), kPointerSize);
19511947
return HeapObject::FromAddress(object->address() + kPointerSize);
19521948
} else {
1953-
heap->CreateFillerObjectAt(object->address() + size - kPointerSize,
1954-
kPointerSize);
1949+
CreateFillerObjectAt(object->address() + size - kPointerSize, kPointerSize);
19551950
return object;
19561951
}
19571952
}
19581953

19591954

19601955
HeapObject* Heap::DoubleAlignForDeserialization(HeapObject* object, int size) {
1961-
return EnsureDoubleAligned(this, object, size);
1956+
return EnsureDoubleAligned(object, size);
19621957
}
19631958

19641959

@@ -2108,15 +2103,13 @@ class ScavengingVisitor : public StaticVisitorBase {
21082103
HeapObject* object, int object_size) {
21092104
Heap* heap = map->GetHeap();
21102105

2111-
int allocation_size = object_size;
2112-
if (alignment != kObjectAlignment) {
2113-
DCHECK(alignment == kDoubleAlignment);
2114-
allocation_size += kPointerSize;
2115-
}
2116-
21172106
DCHECK(heap->AllowedToBeMigrated(object, NEW_SPACE));
2118-
AllocationResult allocation =
2119-
heap->new_space()->AllocateRaw(allocation_size);
2107+
AllocationResult allocation;
2108+
if (alignment == kDoubleAlignment) {
2109+
allocation = heap->new_space()->AllocateRawDoubleAligned(object_size);
2110+
} else {
2111+
allocation = heap->new_space()->AllocateRaw(object_size);
2112+
}
21202113

21212114
HeapObject* target = NULL; // Initialization to please compiler.
21222115
if (allocation.To(&target)) {
@@ -2126,9 +2119,6 @@ class ScavengingVisitor : public StaticVisitorBase {
21262119
// object.
21272120
heap->promotion_queue()->SetNewLimit(heap->new_space()->top());
21282121

2129-
if (alignment != kObjectAlignment) {
2130-
target = EnsureDoubleAligned(heap, target, allocation_size);
2131-
}
21322122
MigrateObject(heap, object, target, object_size);
21332123

21342124
// Update slot to new target.
@@ -2146,20 +2136,15 @@ class ScavengingVisitor : public StaticVisitorBase {
21462136
HeapObject* object, int object_size) {
21472137
Heap* heap = map->GetHeap();
21482138

2149-
int allocation_size = object_size;
2150-
if (alignment != kObjectAlignment) {
2151-
DCHECK(alignment == kDoubleAlignment);
2152-
allocation_size += kPointerSize;
2153-
}
2154-
21552139
AllocationResult allocation;
2156-
allocation = heap->old_space()->AllocateRaw(allocation_size);
2140+
if (alignment == kDoubleAlignment) {
2141+
allocation = heap->old_space()->AllocateRawDoubleAligned(object_size);
2142+
} else {
2143+
allocation = heap->old_space()->AllocateRaw(object_size);
2144+
}
21572145

21582146
HeapObject* target = NULL; // Initialization to please compiler.
21592147
if (allocation.To(&target)) {
2160-
if (alignment != kObjectAlignment) {
2161-
target = EnsureDoubleAligned(heap, target, allocation_size);
2162-
}
21632148
MigrateObject(heap, object, target, object_size);
21642149

21652150
// Update slot to new target.
@@ -3678,7 +3663,7 @@ AllocationResult Heap::AllocateFixedTypedArray(int length,
36783663
if (!allocation.To(&object)) return allocation;
36793664

36803665
if (array_type == kExternalFloat64Array) {
3681-
object = EnsureDoubleAligned(this, object, size);
3666+
object = EnsureDoubleAligned(object, size);
36823667
}
36833668

36843669
object->set_map(MapForFixedTypedArray(array_type));
@@ -4409,7 +4394,7 @@ AllocationResult Heap::AllocateRawFixedDoubleArray(int length,
44094394
if (!allocation.To(&object)) return allocation;
44104395
}
44114396

4412-
return EnsureDoubleAligned(this, object, size);
4397+
return EnsureDoubleAligned(object, size);
44134398
}
44144399

44154400

@@ -4427,7 +4412,7 @@ AllocationResult Heap::AllocateConstantPoolArray(
44274412
AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE);
44284413
if (!allocation.To(&object)) return allocation;
44294414
}
4430-
object = EnsureDoubleAligned(this, object, size);
4415+
object = EnsureDoubleAligned(object, size);
44314416
object->set_map_no_write_barrier(constant_pool_array_map());
44324417

44334418
ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object);
@@ -4453,7 +4438,7 @@ AllocationResult Heap::AllocateExtendedConstantPoolArray(
44534438
AllocationResult allocation = AllocateRaw(size, space, OLD_SPACE);
44544439
if (!allocation.To(&object)) return allocation;
44554440
}
4456-
object = EnsureDoubleAligned(this, object, size);
4441+
object = EnsureDoubleAligned(object, size);
44574442
object->set_map_no_write_barrier(constant_pool_array_map());
44584443

44594444
ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object);

src/heap/heap.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,11 @@ class Heap {
714714
MUST_USE_RESULT AllocationResult
715715
CopyJSObject(JSObject* source, AllocationSite* site = NULL);
716716

717+
// This method assumes overallocation of one word. It will store a filler
718+
// before the object if the given object is not double aligned, otherwise
719+
// it will place the filler after the object.
720+
MUST_USE_RESULT HeapObject* EnsureDoubleAligned(HeapObject* object, int size);
721+
717722
// Clear the Instanceof cache (used when a prototype changes).
718723
inline void ClearInstanceofCache();
719724

src/heap/spaces-inl.h

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,25 @@ HeapObject* PagedSpace::AllocateLinearly(int size_in_bytes) {
250250
}
251251

252252

253+
HeapObject* PagedSpace::AllocateLinearlyDoubleAlign(int size_in_bytes) {
254+
Address current_top = allocation_info_.top();
255+
int alignment_size = 0;
256+
257+
if ((OffsetFrom(current_top) & kDoubleAlignmentMask) != 0) {
258+
alignment_size = kPointerSize;
259+
size_in_bytes += alignment_size;
260+
}
261+
Address new_top = current_top + size_in_bytes;
262+
if (new_top > allocation_info_.limit()) return NULL;
263+
264+
allocation_info_.set_top(new_top);
265+
if (alignment_size > 0)
266+
return heap()->EnsureDoubleAligned(HeapObject::FromAddress(current_top),
267+
size_in_bytes);
268+
return HeapObject::FromAddress(current_top);
269+
}
270+
271+
253272
// Raw allocation.
254273
AllocationResult PagedSpace::AllocateRaw(int size_in_bytes) {
255274
HeapObject* object = AllocateLinearly(size_in_bytes);
@@ -273,15 +292,69 @@ AllocationResult PagedSpace::AllocateRaw(int size_in_bytes) {
273292
}
274293

275294

295+
// Raw allocation.
296+
AllocationResult PagedSpace::AllocateRawDoubleAligned(int size_in_bytes) {
297+
DCHECK(identity() == OLD_SPACE);
298+
HeapObject* object = AllocateLinearlyDoubleAlign(size_in_bytes);
299+
int aligned_size_in_bytes = size_in_bytes + kPointerSize;
300+
301+
if (object == NULL) {
302+
object = free_list_.Allocate(aligned_size_in_bytes);
303+
if (object == NULL) {
304+
object = SlowAllocateRaw(aligned_size_in_bytes);
305+
}
306+
object = heap()->EnsureDoubleAligned(object, aligned_size_in_bytes);
307+
}
308+
309+
if (object != NULL) {
310+
MSAN_ALLOCATED_UNINITIALIZED_MEMORY(object->address(), size_in_bytes);
311+
return object;
312+
}
313+
314+
return AllocationResult::Retry(identity());
315+
}
316+
317+
276318
// -----------------------------------------------------------------------------
277319
// NewSpace
278320

279321

322+
AllocationResult NewSpace::AllocateRawDoubleAligned(int size_in_bytes) {
323+
Address old_top = allocation_info_.top();
324+
int alignment_size = 0;
325+
int aligned_size_in_bytes = 0;
326+
327+
// If double alignment is required and top pointer is not aligned, we allocate
328+
// additional memory to take care of the alignment.
329+
if ((OffsetFrom(old_top) & kDoubleAlignmentMask) != 0) {
330+
alignment_size += kPointerSize;
331+
}
332+
aligned_size_in_bytes = size_in_bytes + alignment_size;
333+
334+
if (allocation_info_.limit() - old_top < aligned_size_in_bytes) {
335+
return SlowAllocateRaw(size_in_bytes, true);
336+
}
337+
338+
HeapObject* obj = HeapObject::FromAddress(old_top);
339+
allocation_info_.set_top(allocation_info_.top() + aligned_size_in_bytes);
340+
DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
341+
342+
if (alignment_size > 0) {
343+
obj = heap()->EnsureDoubleAligned(obj, aligned_size_in_bytes);
344+
}
345+
346+
// The slow path above ultimately goes through AllocateRaw, so this suffices.
347+
MSAN_ALLOCATED_UNINITIALIZED_MEMORY(obj->address(), size_in_bytes);
348+
349+
return obj;
350+
}
351+
352+
280353
AllocationResult NewSpace::AllocateRaw(int size_in_bytes) {
281354
Address old_top = allocation_info_.top();
282355

283356
if (allocation_info_.limit() - old_top < size_in_bytes) {
284-
return SlowAllocateRaw(size_in_bytes);
357+
return SlowAllocateRaw(size_in_bytes, false);
285358
}
286359

287360
HeapObject* obj = HeapObject::FromAddress(old_top);

src/heap/spaces.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,26 +1458,31 @@ bool NewSpace::AddFreshPage() {
14581458
}
14591459

14601460

1461-
AllocationResult NewSpace::SlowAllocateRaw(int size_in_bytes) {
1461+
AllocationResult NewSpace::SlowAllocateRaw(int size_in_bytes,
1462+
bool double_aligned) {
14621463
Address old_top = allocation_info_.top();
14631464
Address high = to_space_.page_high();
14641465
if (allocation_info_.limit() < high) {
14651466
// Either the limit has been lowered because linear allocation was disabled
14661467
// or because incremental marking wants to get a chance to do a step. Set
14671468
// the new limit accordingly.
1468-
Address new_top = old_top + size_in_bytes;
1469+
int aligned_size = size_in_bytes;
1470+
aligned_size += (double_aligned ? kPointerSize : 0);
1471+
Address new_top = old_top + aligned_size;
14691472
int bytes_allocated = static_cast<int>(new_top - top_on_previous_step_);
14701473
heap()->incremental_marking()->Step(bytes_allocated,
14711474
IncrementalMarking::GC_VIA_STACK_GUARD);
1472-
UpdateInlineAllocationLimit(size_in_bytes);
1475+
UpdateInlineAllocationLimit(aligned_size);
14731476
top_on_previous_step_ = new_top;
1477+
if (double_aligned) return AllocateRawDoubleAligned(size_in_bytes);
14741478
return AllocateRaw(size_in_bytes);
14751479
} else if (AddFreshPage()) {
14761480
// Switched to new page. Try allocating again.
14771481
int bytes_allocated = static_cast<int>(old_top - top_on_previous_step_);
14781482
heap()->incremental_marking()->Step(bytes_allocated,
14791483
IncrementalMarking::GC_VIA_STACK_GUARD);
14801484
top_on_previous_step_ = to_space_.page_low();
1485+
if (double_aligned) return AllocateRawDoubleAligned(size_in_bytes);
14811486
return AllocateRaw(size_in_bytes);
14821487
} else {
14831488
return AllocationResult::Retry();

src/heap/spaces.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1759,6 +1759,11 @@ class PagedSpace : public Space {
17591759
// failure object if not.
17601760
MUST_USE_RESULT inline AllocationResult AllocateRaw(int size_in_bytes);
17611761

1762+
// Allocate the requested number of bytes in the space double aligned if
1763+
// possible, return a failure object if not.
1764+
MUST_USE_RESULT inline AllocationResult AllocateRawDoubleAligned(
1765+
int size_in_bytes);
1766+
17621767
// Give a block of memory to the space's free list. It might be added to
17631768
// the free list or accounted as waste.
17641769
// If add_to_freelist is false then just accounting stats are updated and
@@ -1919,6 +1924,10 @@ class PagedSpace : public Space {
19191924
// address denoted by top in allocation_info_.
19201925
inline HeapObject* AllocateLinearly(int size_in_bytes);
19211926

1927+
// Generic fast case allocation function that tries double aligned linear
1928+
// allocation at the address denoted by top in allocation_info_.
1929+
inline HeapObject* AllocateLinearlyDoubleAlign(int size_in_bytes);
1930+
19221931
// If sweeping is still in progress try to sweep unswept pages. If that is
19231932
// not successful, wait for the sweeper threads and re-try free-list
19241933
// allocation.
@@ -2484,6 +2493,9 @@ class NewSpace : public Space {
24842493
return allocation_info_.limit_address();
24852494
}
24862495

2496+
MUST_USE_RESULT INLINE(
2497+
AllocationResult AllocateRawDoubleAligned(int size_in_bytes));
2498+
24872499
MUST_USE_RESULT INLINE(AllocationResult AllocateRaw(int size_in_bytes));
24882500

24892501
// Reset the allocation pointer to the beginning of the active semispace.
@@ -2601,7 +2613,8 @@ class NewSpace : public Space {
26012613
HistogramInfo* allocated_histogram_;
26022614
HistogramInfo* promoted_histogram_;
26032615

2604-
MUST_USE_RESULT AllocationResult SlowAllocateRaw(int size_in_bytes);
2616+
MUST_USE_RESULT AllocationResult
2617+
SlowAllocateRaw(int size_in_bytes, bool double_aligned);
26052618

26062619
friend class SemiSpaceIterator;
26072620

0 commit comments

Comments
 (0)