Index: src/compiler/code-stub-assembler.cc |
diff --git a/src/compiler/code-stub-assembler.cc b/src/compiler/code-stub-assembler.cc |
index 558a09ea09c7764757fc04029b21852541c5715a..1521e49e62c89497fbeedb7e552f614385ef2c80 100644 |
--- a/src/compiler/code-stub-assembler.cc |
+++ b/src/compiler/code-stub-assembler.cc |
@@ -245,6 +245,122 @@ Node* CodeStubAssembler::LoadRoot(Heap::RootListIndex root_index) { |
return nullptr; |
} |
+Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes, |
+ AllocationFlags flags, |
+ Node* top_address, |
+ Node* limit_address) { |
+ Node* top = Load(MachineType::Pointer(), top_address); |
+ Node* limit = Load(MachineType::Pointer(), limit_address); |
+ |
+ // If there's not enough space, call the runtime. |
+ RawMachineLabel runtime_call, no_runtime_call, merge_runtime; |
+ raw_assembler_->Branch( |
+ raw_assembler_->IntPtrLessThan(IntPtrSub(limit, top), size_in_bytes), |
+ &runtime_call, &no_runtime_call); |
+ |
+ raw_assembler_->Bind(&runtime_call); |
+ // AllocateInTargetSpace does not use the context. |
+ Node* context = IntPtrConstant(0); |
+ Node* runtime_flags = SmiTag(Int32Constant( |
+ AllocateDoubleAlignFlag::encode(false) | |
+ AllocateTargetSpace::encode(flags & kPretenured |
+ ? AllocationSpace::OLD_SPACE |
+ : AllocationSpace::NEW_SPACE))); |
+ Node* runtime_result = CallRuntime(Runtime::kAllocateInTargetSpace, context, |
+ SmiTag(size_in_bytes), runtime_flags); |
+ raw_assembler_->Goto(&merge_runtime); |
+ |
+ // When there is enough space, return `top' and bump it up. |
+ raw_assembler_->Bind(&no_runtime_call); |
+ Node* no_runtime_result = top; |
+ StoreNoWriteBarrier(MachineType::PointerRepresentation(), top_address, |
+ IntPtrAdd(top, size_in_bytes)); |
+ no_runtime_result = |
+ IntPtrAdd(no_runtime_result, IntPtrConstant(kHeapObjectTag)); |
+ raw_assembler_->Goto(&merge_runtime); |
+ |
+ raw_assembler_->Bind(&merge_runtime); |
+ return raw_assembler_->Phi(MachineType::PointerRepresentation(), |
+ runtime_result, no_runtime_result); |
+} |
+ |
+Node* CodeStubAssembler::AllocateRawAligned(Node* size_in_bytes, |
+ AllocationFlags flags, |
+ Node* top_address, |
+ Node* limit_address) { |
+ Node* top = Load(MachineType::Pointer(), top_address); |
+ Node* limit = Load(MachineType::Pointer(), limit_address); |
+ Node* adjusted_size = size_in_bytes; |
+ if (flags & kDoubleAlignment) { |
+ // TODO(epertoso): Simd128 alignment. |
+ RawMachineLabel aligned, not_aligned, merge; |
+ raw_assembler_->Branch(WordAnd(top, IntPtrConstant(kDoubleAlignmentMask)), |
+ ¬_aligned, &aligned); |
+ |
+ raw_assembler_->Bind(¬_aligned); |
+ Node* not_aligned_size = |
+ IntPtrAdd(size_in_bytes, IntPtrConstant(kPointerSize)); |
+ raw_assembler_->Goto(&merge); |
+ |
+ raw_assembler_->Bind(&aligned); |
+ raw_assembler_->Goto(&merge); |
+ |
+ raw_assembler_->Bind(&merge); |
+ adjusted_size = raw_assembler_->Phi(MachineType::PointerRepresentation(), |
+ not_aligned_size, adjusted_size); |
+ } |
+ |
+ Node* address = AllocateRawUnaligned(adjusted_size, kNone, top, limit); |
+ |
+ RawMachineLabel needs_filler, doesnt_need_filler, merge_address; |
+ raw_assembler_->Branch( |
+ raw_assembler_->IntPtrEqual(adjusted_size, size_in_bytes), |
+ &doesnt_need_filler, &needs_filler); |
+ |
+ raw_assembler_->Bind(&needs_filler); |
+ // Store a filler and increase the address by kPointerSize. |
+ // TODO(epertoso): this code assumes that we only align to kDoubleSize. Change |
+ // it when Simd128 alignment is supported. |
+ StoreNoWriteBarrier(MachineType::PointerRepresentation(), top, |
+ LoadRoot(Heap::kOnePointerFillerMapRootIndex)); |
+ Node* address_with_filler = IntPtrAdd(address, IntPtrConstant(kPointerSize)); |
+ raw_assembler_->Goto(&merge_address); |
+ |
+ raw_assembler_->Bind(&doesnt_need_filler); |
+ Node* address_without_filler = address; |
+ raw_assembler_->Goto(&merge_address); |
+ |
+ raw_assembler_->Bind(&merge_address); |
+ address = raw_assembler_->Phi(MachineType::PointerRepresentation(), |
+ address_with_filler, address_without_filler); |
+ // Update the top. |
+ StoreNoWriteBarrier(MachineType::PointerRepresentation(), top_address, |
+ IntPtrAdd(top, adjusted_size)); |
+ return address; |
+} |
+ |
+Node* CodeStubAssembler::Allocate(int size_in_bytes, AllocationFlags flags) { |
+ bool const new_space = !(flags & kPretenured); |
+ Node* top_address = ExternalConstant( |
+ new_space |
+ ? ExternalReference::new_space_allocation_top_address(isolate()) |
+ : ExternalReference::old_space_allocation_top_address(isolate())); |
+ Node* limit_address = ExternalConstant( |
+ new_space |
+ ? ExternalReference::new_space_allocation_limit_address(isolate()) |
+ : ExternalReference::old_space_allocation_limit_address(isolate())); |
+ |
+#ifdef V8_HOST_ARCH_32_BIT |
+ if (flags & kDoubleAlignment) { |
+ return AllocateRawAligned(IntPtrConstant(size_in_bytes), flags, top_address, |
+ limit_address); |
+ } |
+#endif |
+ |
+ return AllocateRawUnaligned(IntPtrConstant(size_in_bytes), flags, top_address, |
+ limit_address); |
+} |
+ |
Node* CodeStubAssembler::Load(MachineType rep, Node* base) { |
return raw_assembler_->Load(rep, base); |
} |