| 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));
|
|
|