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 = |