Chromium Code Reviews| Index: src/code-stub-assembler.cc |
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc |
| index 833b4b20ead9bf58d4b0a06ee172b0a7356875bd..d1c0750a4b3dadceac68029cf71a856cefa6feef 100644 |
| --- a/src/code-stub-assembler.cc |
| +++ b/src/code-stub-assembler.cc |
| @@ -46,6 +46,21 @@ Node* CodeStubAssembler::EmptyStringConstant() { |
| return LoadRoot(Heap::kempty_stringRootIndex); |
| } |
| +Node* CodeStubAssembler::FixedArrayMapConstant() { |
| + return HeapConstant(isolate()->factory()->fixed_array_map()); |
| + // return LoadRoot(Heap::kFixedArrayMapRootIndex); |
| +} |
| + |
| +Node* CodeStubAssembler::FixedCowArrayMapConstant() { |
| + return HeapConstant(isolate()->factory()->fixed_cow_array_map()); |
| + // return LoadRoot(Heap::kFixedCOWArrayMapRootIndex); |
| +} |
| + |
| +Node* CodeStubAssembler::FixedDoubleArrayMapConstant() { |
| + return HeapConstant(isolate()->factory()->fixed_double_array_map()); |
| + // return LoadRoot(Heap::kFixedDoubleArrayMapRootIndex); |
| +} |
| + |
| Node* CodeStubAssembler::HeapNumberMapConstant() { |
| return LoadRoot(Heap::kHeapNumberMapRootIndex); |
| } |
| @@ -1000,6 +1015,10 @@ Node* CodeStubAssembler::LoadElements(Node* object) { |
| return LoadObjectField(object, JSObject::kElementsOffset); |
| } |
| +Node* CodeStubAssembler::LoadJSArrayLength(compiler::Node* array) { |
| + return LoadObjectField(array, JSArray::kLengthOffset); |
| +} |
| + |
| Node* CodeStubAssembler::LoadFixedArrayBaseLength(compiler::Node* array) { |
| return LoadObjectField(array, FixedArrayBase::kLengthOffset); |
| } |
| @@ -1366,49 +1385,81 @@ Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length) { |
| return var_result.value(); |
| } |
| -Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind, Node* array_map, |
| - Node* capacity_node, Node* length_node, |
| - compiler::Node* allocation_site, |
| - ParameterMode mode) { |
| - bool is_double = IsFastDoubleElementsKind(kind); |
| - int base_size = JSArray::kSize + FixedArray::kHeaderSize; |
| - int elements_offset = JSArray::kSize; |
| +Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( |
| + ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { |
| + return AllocateUninitializedJSArray(kind, array_map, length, allocation_site) |
| + .first; |
| +} |
| +std::pair<Node*, Node*> CodeStubAssembler::AllocateUninitializedJSArray( |
| + ElementsKind kind, Node* array_map, Node* length, Node* allocation_site, |
| + Node* capacity, ParameterMode capacity_mode) { |
| Comment("begin allocation of JSArray"); |
| + int base_size = JSArray::kSize; |
| + |
| if (allocation_site != nullptr) { |
| base_size += AllocationMemento::kSize; |
| - elements_offset += AllocationMemento::kSize; |
| } |
| - Node* total_size = |
| - ElementOffsetFromIndex(capacity_node, kind, mode, base_size); |
| + int elements_offset = base_size; |
| + Node* total_size; |
| + |
| + // Compute space for elements if capacity is not null. |
| + if (capacity != nullptr) { |
|
rmcilroy
2016/09/16 08:53:51
Not a great fan of this being an optional nullptr
klaasb
2016/09/19 12:17:59
Done.
|
| + base_size += FixedArray::kHeaderSize; |
| + total_size = |
| + ElementOffsetFromIndex(capacity, kind, capacity_mode, base_size); |
| + } else { |
| + total_size = IntPtrConstant(base_size); |
| + } |
| // Allocate both array and elements object, and initialize the JSArray. |
| - Heap* heap = isolate()->heap(); |
| Node* array = Allocate(total_size); |
| + |
| + Comment("write JSArray headers"); |
| StoreMapNoWriteBarrier(array, array_map); |
| - Node* empty_properties = LoadRoot(Heap::kEmptyFixedArrayRootIndex); |
| - StoreObjectFieldNoWriteBarrier(array, JSArray::kPropertiesOffset, |
| - empty_properties); |
| - StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, |
| - TagParameter(length_node, mode)); |
| + |
| + StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); |
| + |
| + StoreObjectFieldRoot(array, JSArray::kPropertiesOffset, |
| + Heap::kEmptyFixedArrayRootIndex); |
| if (allocation_site != nullptr) { |
| InitializeAllocationMemento(array, JSArray::kSize, allocation_site); |
| } |
| + if (capacity != nullptr) { |
| + Node* elements = InnerAllocate(array, elements_offset); |
| + StoreObjectField(array, JSObject::kElementsOffset, elements); |
| + return {array, elements}; |
| + } |
| + |
| + return {array, nullptr}; |
|
rmcilroy
2016/09/16 08:53:51
Also not keen on this maybe returning a nullptr. M
klaasb
2016/09/19 12:17:59
Done.
|
| +} |
| + |
| +Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind, Node* array_map, |
| + Node* capacity, Node* length, |
| + Node* allocation_site, |
| + ParameterMode mode) { |
| + bool is_double = IsFastDoubleElementsKind(kind); |
| + |
| + // Allocate both array and elements object, and initialize the JSArray. |
| + Node *array, *elements; |
| + std::tie(array, elements) = |
| + AllocateUninitializedJSArray(kind, array_map, TagParameter(length, mode), |
| + allocation_site, capacity, mode); |
| + |
| // Setup elements object. |
| - Node* elements = InnerAllocate(array, elements_offset); |
| - StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, elements); |
| + Heap* heap = isolate()->heap(); |
| Handle<Map> elements_map(is_double ? heap->fixed_double_array_map() |
| : heap->fixed_array_map()); |
| StoreMapNoWriteBarrier(elements, HeapConstant(elements_map)); |
| StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, |
| - TagParameter(capacity_node, mode)); |
| + TagParameter(capacity, mode)); |
| // Fill in the elements with holes. |
| - FillFixedArrayWithValue(kind, elements, IntPtrConstant(0), capacity_node, |
| + FillFixedArrayWithValue(kind, elements, IntPtrConstant(0), capacity, |
| Heap::kTheHoleValueRootIndex, mode); |
| return array; |
| @@ -3860,7 +3911,7 @@ void CodeStubAssembler::EmitFastElementsBoundsCheck(Node* object, |
| } |
| Bind(&if_array); |
| { |
| - var_length.Bind(SmiUntag(LoadObjectField(object, JSArray::kLengthOffset))); |
| + var_length.Bind(SmiUntag(LoadJSArrayLength(object))); |
| Goto(&length_loaded); |
| } |
| Bind(&length_loaded); |
| @@ -4202,9 +4253,8 @@ void CodeStubAssembler::LoadIC(const LoadICParameters* p) { |
| { |
| // Check polymorphic case. |
| Comment("LoadIC_try_polymorphic"); |
| - GotoUnless( |
| - WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), |
| - &try_megamorphic); |
| + GotoUnless(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), |
| + &try_megamorphic); |
| HandlePolymorphicCase(p, receiver_map, feedback, &if_handler, &var_handler, |
| &miss, 2); |
| } |
| @@ -4248,9 +4298,8 @@ void CodeStubAssembler::KeyedLoadIC(const LoadICParameters* p) { |
| { |
| // Check polymorphic case. |
| Comment("KeyedLoadIC_try_polymorphic"); |
| - GotoUnless( |
| - WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), |
| - &try_megamorphic); |
| + GotoUnless(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), |
| + &try_megamorphic); |
| HandlePolymorphicCase(p, receiver_map, feedback, &if_handler, &var_handler, |
| &miss, 2); |
| } |
| @@ -4601,8 +4650,7 @@ Node* CodeStubAssembler::EmitKeyedSloppyArguments(Node* receiver, Node* key, |
| { |
| Node* backing_store = LoadFixedArrayElement(elements, IntPtrConstant(1), 0, |
| INTPTR_PARAMETERS); |
| - GotoIf(WordNotEqual(LoadMap(backing_store), |
| - LoadRoot(Heap::kFixedArrayMapRootIndex)), |
| + GotoIf(WordNotEqual(LoadMap(backing_store), FixedArrayMapConstant()), |
| bailout); |
| Node* backing_store_length = |