Line data Source code
1 : // Copyright 2018 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_HEAP_LOCAL_ALLOCATOR_INL_H_
6 : #define V8_HEAP_LOCAL_ALLOCATOR_INL_H_
7 :
8 : #include "src/heap/local-allocator.h"
9 :
10 : #include "src/heap/spaces-inl.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 175646186 : AllocationResult LocalAllocator::Allocate(AllocationSpace space,
16 : int object_size,
17 : AllocationAlignment alignment) {
18 175646186 : switch (space) {
19 : case NEW_SPACE:
20 90001070 : return AllocateInNewSpace(object_size, alignment);
21 : case OLD_SPACE:
22 : return compaction_spaces_.Get(OLD_SPACE)->AllocateRaw(object_size,
23 85643340 : alignment);
24 : case CODE_SPACE:
25 : return compaction_spaces_.Get(CODE_SPACE)
26 1776 : ->AllocateRaw(object_size, alignment);
27 : default:
28 0 : UNREACHABLE();
29 : break;
30 : }
31 : }
32 :
33 28876 : void LocalAllocator::FreeLast(AllocationSpace space, HeapObject object,
34 : int object_size) {
35 28876 : switch (space) {
36 : case NEW_SPACE:
37 80600 : FreeLastInNewSpace(object, object_size);
38 0 : return;
39 : case OLD_SPACE:
40 178387 : FreeLastInOldSpace(object, object_size);
41 28876 : return;
42 : default:
43 : // Only new and old space supported.
44 0 : UNREACHABLE();
45 : break;
46 : }
47 : }
48 :
49 80600 : void LocalAllocator::FreeLastInNewSpace(HeapObject object, int object_size) {
50 80600 : if (!new_space_lab_.TryFreeLast(object, object_size)) {
51 : // We couldn't free the last object so we have to write a proper filler.
52 9 : heap_->CreateFillerObjectAt(object->address(), object_size,
53 9 : ClearRecordedSlots::kNo);
54 : }
55 80600 : }
56 :
57 178341 : void LocalAllocator::FreeLastInOldSpace(HeapObject object, int object_size) {
58 178341 : if (!compaction_spaces_.Get(OLD_SPACE)->TryFreeLast(object, object_size)) {
59 : // We couldn't free the last object so we have to write a proper filler.
60 0 : heap_->CreateFillerObjectAt(object->address(), object_size,
61 0 : ClearRecordedSlots::kNo);
62 : }
63 178341 : }
64 :
65 89671936 : AllocationResult LocalAllocator::AllocateInLAB(int object_size,
66 : AllocationAlignment alignment) {
67 : AllocationResult allocation;
68 89671936 : if (!new_space_lab_.IsValid() && !NewLocalAllocationBuffer()) {
69 : return AllocationResult::Retry(OLD_SPACE);
70 : }
71 89668902 : allocation = new_space_lab_.AllocateRawAligned(object_size, alignment);
72 89546381 : if (allocation.IsRetry()) {
73 1842945 : if (!NewLocalAllocationBuffer()) {
74 : return AllocationResult::Retry(OLD_SPACE);
75 : } else {
76 123749 : allocation = new_space_lab_.AllocateRawAligned(object_size, alignment);
77 123747 : CHECK(!allocation.IsRetry());
78 : }
79 : }
80 87827183 : return allocation;
81 : }
82 :
83 1924669 : bool LocalAllocator::NewLocalAllocationBuffer() {
84 1924669 : if (lab_allocation_will_fail_) return false;
85 203736 : LocalAllocationBuffer saved_lab_ = new_space_lab_;
86 : AllocationResult result =
87 203723 : new_space_->AllocateRawSynchronized(kLabSize, kWordAligned);
88 407547 : new_space_lab_ = LocalAllocationBuffer::FromResult(heap_, result, kLabSize);
89 203766 : if (new_space_lab_.IsValid()) {
90 : new_space_lab_.TryMerge(&saved_lab_);
91 203447 : return true;
92 : }
93 319 : new_space_lab_ = saved_lab_;
94 319 : lab_allocation_will_fail_ = true;
95 319 : return false;
96 : }
97 :
98 89980474 : AllocationResult LocalAllocator::AllocateInNewSpace(
99 : int object_size, AllocationAlignment alignment) {
100 89980474 : if (object_size > kMaxLabObjectSize) {
101 300538 : return new_space_->AllocateRawSynchronized(object_size, alignment);
102 : }
103 89679936 : return AllocateInLAB(object_size, alignment);
104 : }
105 :
106 : } // namespace internal
107 : } // namespace v8
108 :
109 : #endif // V8_HEAP_LOCAL_ALLOCATOR_INL_H_
|