V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
local-allocator-inl.h
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 AllocationResult LocalAllocator::Allocate(AllocationSpace space,
16  int object_size,
17  AllocationAlignment alignment) {
18  switch (space) {
19  case NEW_SPACE:
20  return AllocateInNewSpace(object_size, alignment);
21  case OLD_SPACE:
22  return compaction_spaces_.Get(OLD_SPACE)->AllocateRaw(object_size,
23  alignment);
24  case CODE_SPACE:
25  return compaction_spaces_.Get(CODE_SPACE)
26  ->AllocateRaw(object_size, alignment);
27  default:
28  UNREACHABLE();
29  break;
30  }
31 }
32 
33 void LocalAllocator::FreeLast(AllocationSpace space, HeapObject* object,
34  int object_size) {
35  switch (space) {
36  case NEW_SPACE:
37  FreeLastInNewSpace(object, object_size);
38  return;
39  case OLD_SPACE:
40  FreeLastInOldSpace(object, object_size);
41  return;
42  default:
43  // Only new and old space supported.
44  UNREACHABLE();
45  break;
46  }
47 }
48 
49 void LocalAllocator::FreeLastInNewSpace(HeapObject* object, int object_size) {
50  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  heap_->CreateFillerObjectAt(object->address(), object_size,
53  ClearRecordedSlots::kNo);
54  }
55 }
56 
57 void LocalAllocator::FreeLastInOldSpace(HeapObject* object, int object_size) {
58  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  heap_->CreateFillerObjectAt(object->address(), object_size,
61  ClearRecordedSlots::kNo);
62  }
63 }
64 
65 AllocationResult LocalAllocator::AllocateInLAB(int object_size,
66  AllocationAlignment alignment) {
67  AllocationResult allocation;
68  if (!new_space_lab_.IsValid() && !NewLocalAllocationBuffer()) {
69  return AllocationResult::Retry(OLD_SPACE);
70  }
71  allocation = new_space_lab_.AllocateRawAligned(object_size, alignment);
72  if (allocation.IsRetry()) {
73  if (!NewLocalAllocationBuffer()) {
74  return AllocationResult::Retry(OLD_SPACE);
75  } else {
76  allocation = new_space_lab_.AllocateRawAligned(object_size, alignment);
77  CHECK(!allocation.IsRetry());
78  }
79  }
80  return allocation;
81 }
82 
83 bool LocalAllocator::NewLocalAllocationBuffer() {
84  if (lab_allocation_will_fail_) return false;
85  LocalAllocationBuffer saved_lab_ = new_space_lab_;
86  AllocationResult result =
87  new_space_->AllocateRawSynchronized(kLabSize, kWordAligned);
88  new_space_lab_ = LocalAllocationBuffer::FromResult(heap_, result, kLabSize);
89  if (new_space_lab_.IsValid()) {
90  new_space_lab_.TryMerge(&saved_lab_);
91  return true;
92  }
93  new_space_lab_ = saved_lab_;
94  lab_allocation_will_fail_ = true;
95  return false;
96 }
97 
98 AllocationResult LocalAllocator::AllocateInNewSpace(
99  int object_size, AllocationAlignment alignment) {
100  if (object_size > kMaxLabObjectSize) {
101  return new_space_->AllocateRawSynchronized(object_size, alignment);
102  }
103  return AllocateInLAB(object_size, alignment);
104 }
105 
106 } // namespace internal
107 } // namespace v8
108 
109 #endif // V8_HEAP_LOCAL_ALLOCATOR_INL_H_
Definition: libplatform.h:13