• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Allocate(AllocationSpace space,int object_size,AllocationAlignment alignment)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 
FreeLast(AllocationSpace space,HeapObject * object,int object_size)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 
FreeLastInNewSpace(HeapObject * object,int object_size)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 
FreeLastInOldSpace(HeapObject * object,int object_size)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 
AllocateInLAB(int object_size,AllocationAlignment alignment)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 
NewLocalAllocationBuffer()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 
AllocateInNewSpace(int object_size,AllocationAlignment alignment)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_
110