Index: src/code-stub-assembler.cc |
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
index bf4ace8c88e44c30998398fe622a03c0d82e6792..6718704d807f507507616381feec5133c88c5c14 100644 |
--- a/src/code-stub-assembler.cc |
+++ b/src/code-stub-assembler.cc |
@@ -216,6 +216,14 @@ Node* CodeStubAssembler::SmiFromWord32(Node* value) { |
return WordShl(value, SmiShiftBitsConstant()); |
} |
+Node* CodeStubAssembler::SmiTag(Node* value) { |
+ return WordShl(value, SmiShiftBitsConstant()); |
+} |
+ |
+Node* CodeStubAssembler::SmiUntag(Node* value) { |
+ return WordSar(value, SmiShiftBitsConstant()); |
+} |
+ |
Node* CodeStubAssembler::SmiToWord32(Node* value) { |
Node* result = WordSar(value, SmiShiftBitsConstant()); |
if (Is64()) { |
@@ -278,6 +286,125 @@ Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { |
IntPtrConstant(0)); |
} |
+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. |
+ Variable result(this, MachineRepresentation::kTagged); |
+ Label runtime_call(this, Label::kDeferred), no_runtime_call(this); |
+ Label merge_runtime(this, &result); |
+ |
+ Branch(IntPtrLessThan(IntPtrSub(limit, top), size_in_bytes), &runtime_call, |
+ &no_runtime_call); |
+ |
+ 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); |
+ result.Bind(runtime_result); |
+ Goto(&merge_runtime); |
+ |
+ // When there is enough space, return `top' and bump it up. |
+ 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)); |
+ result.Bind(no_runtime_result); |
+ Goto(&merge_runtime); |
+ |
+ Bind(&merge_runtime); |
+ return result.value(); |
+} |
+ |
+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); |
+ Variable adjusted_size(this, MachineType::PointerRepresentation()); |
+ adjusted_size.Bind(size_in_bytes); |
+ if (flags & kDoubleAlignment) { |
+ // TODO(epertoso): Simd128 alignment. |
+ Label aligned(this), not_aligned(this), merge(this, &adjusted_size); |
+ Branch(WordAnd(top, IntPtrConstant(kDoubleAlignmentMask)), ¬_aligned, |
+ &aligned); |
+ |
+ Bind(¬_aligned); |
+ Node* not_aligned_size = |
+ IntPtrAdd(size_in_bytes, IntPtrConstant(kPointerSize)); |
+ adjusted_size.Bind(not_aligned_size); |
+ Goto(&merge); |
+ |
+ Bind(&aligned); |
+ Goto(&merge); |
+ } |
+ |
+ Variable address(this, MachineRepresentation::kTagged); |
+ address.Bind(AllocateRawUnaligned(adjusted_size.value(), kNone, top, limit)); |
+ |
+ Label needs_filler(this), doesnt_need_filler(this), |
+ merge_address(this, &address); |
+ Branch(IntPtrEqual(adjusted_size.value(), size_in_bytes), &doesnt_need_filler, |
+ &needs_filler); |
+ |
+ 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)); |
+ address.Bind(IntPtrAdd(address.value(), IntPtrConstant(kPointerSize))); |
+ Goto(&merge_address); |
+ |
+ Bind(&doesnt_need_filler); |
+ Goto(&merge_address); |
+ |
+ Bind(&merge_address); |
+ // Update the top. |
+ StoreNoWriteBarrier(MachineType::PointerRepresentation(), top_address, |
+ IntPtrAdd(top, adjusted_size.value())); |
+ return address.value(); |
+} |
+ |
+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::InnerAllocate(Node* previous, int offset) { |
+ return IntPtrAdd(previous, IntPtrConstant(offset)); |
+} |
+ |
Node* CodeStubAssembler::LoadBufferObject(Node* buffer, int offset, |
MachineType rep) { |
return Load(rep, buffer, IntPtrConstant(offset)); |