OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
8 #include "src/frames.h" | 8 #include "src/frames.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 } | 39 } |
40 | 40 |
41 Node* CodeStubAssembler::BooleanMapConstant() { | 41 Node* CodeStubAssembler::BooleanMapConstant() { |
42 return HeapConstant(isolate()->factory()->boolean_map()); | 42 return HeapConstant(isolate()->factory()->boolean_map()); |
43 } | 43 } |
44 | 44 |
45 Node* CodeStubAssembler::EmptyStringConstant() { | 45 Node* CodeStubAssembler::EmptyStringConstant() { |
46 return LoadRoot(Heap::kempty_stringRootIndex); | 46 return LoadRoot(Heap::kempty_stringRootIndex); |
47 } | 47 } |
48 | 48 |
| 49 Node* CodeStubAssembler::FixedArrayMapConstant() { |
| 50 return LoadRoot(Heap::kFixedArrayMapRootIndex); |
| 51 } |
| 52 |
| 53 Node* CodeStubAssembler::FixedCowArrayMapConstant() { |
| 54 return LoadRoot(Heap::kFixedCOWArrayMapRootIndex); |
| 55 } |
| 56 |
| 57 Node* CodeStubAssembler::FixedDoubleArrayMapConstant() { |
| 58 return LoadRoot(Heap::kFixedDoubleArrayMapRootIndex); |
| 59 } |
| 60 |
49 Node* CodeStubAssembler::HeapNumberMapConstant() { | 61 Node* CodeStubAssembler::HeapNumberMapConstant() { |
50 return LoadRoot(Heap::kHeapNumberMapRootIndex); | 62 return LoadRoot(Heap::kHeapNumberMapRootIndex); |
51 } | 63 } |
52 | 64 |
53 Node* CodeStubAssembler::NoContextConstant() { | 65 Node* CodeStubAssembler::NoContextConstant() { |
54 return SmiConstant(Smi::FromInt(0)); | 66 return SmiConstant(Smi::FromInt(0)); |
55 } | 67 } |
56 | 68 |
57 Node* CodeStubAssembler::MinusZeroConstant() { | 69 Node* CodeStubAssembler::MinusZeroConstant() { |
58 return LoadRoot(Heap::kMinusZeroValueRootIndex); | 70 return LoadRoot(Heap::kMinusZeroValueRootIndex); |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 } | 1005 } |
994 | 1006 |
995 Node* CodeStubAssembler::LoadProperties(Node* object) { | 1007 Node* CodeStubAssembler::LoadProperties(Node* object) { |
996 return LoadObjectField(object, JSObject::kPropertiesOffset); | 1008 return LoadObjectField(object, JSObject::kPropertiesOffset); |
997 } | 1009 } |
998 | 1010 |
999 Node* CodeStubAssembler::LoadElements(Node* object) { | 1011 Node* CodeStubAssembler::LoadElements(Node* object) { |
1000 return LoadObjectField(object, JSObject::kElementsOffset); | 1012 return LoadObjectField(object, JSObject::kElementsOffset); |
1001 } | 1013 } |
1002 | 1014 |
| 1015 Node* CodeStubAssembler::LoadJSArrayLength(compiler::Node* array) { |
| 1016 return LoadObjectField(array, JSArray::kLengthOffset); |
| 1017 } |
| 1018 |
1003 Node* CodeStubAssembler::LoadFixedArrayBaseLength(compiler::Node* array) { | 1019 Node* CodeStubAssembler::LoadFixedArrayBaseLength(compiler::Node* array) { |
1004 return LoadObjectField(array, FixedArrayBase::kLengthOffset); | 1020 return LoadObjectField(array, FixedArrayBase::kLengthOffset); |
1005 } | 1021 } |
1006 | 1022 |
1007 Node* CodeStubAssembler::LoadAndUntagFixedArrayBaseLength(Node* array) { | 1023 Node* CodeStubAssembler::LoadAndUntagFixedArrayBaseLength(Node* array) { |
1008 return LoadAndUntagObjectField(array, FixedArrayBase::kLengthOffset); | 1024 return LoadAndUntagObjectField(array, FixedArrayBase::kLengthOffset); |
1009 } | 1025 } |
1010 | 1026 |
1011 Node* CodeStubAssembler::LoadMapBitField(Node* map) { | 1027 Node* CodeStubAssembler::LoadMapBitField(Node* map) { |
1012 return LoadObjectField(map, Map::kBitFieldOffset, MachineType::Uint8()); | 1028 return LoadObjectField(map, Map::kBitFieldOffset, MachineType::Uint8()); |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 Node* result = CallRuntime(Runtime::kAllocateSeqTwoByteString, context, | 1375 Node* result = CallRuntime(Runtime::kAllocateSeqTwoByteString, context, |
1360 SmiFromWord(length)); | 1376 SmiFromWord(length)); |
1361 var_result.Bind(result); | 1377 var_result.Bind(result); |
1362 Goto(&if_join); | 1378 Goto(&if_join); |
1363 } | 1379 } |
1364 | 1380 |
1365 Bind(&if_join); | 1381 Bind(&if_join); |
1366 return var_result.value(); | 1382 return var_result.value(); |
1367 } | 1383 } |
1368 | 1384 |
1369 Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind, Node* array_map, | 1385 Node* CodeStubAssembler::AllocateUninitializedJSArrayWithoutElements( |
1370 Node* capacity_node, Node* length_node, | 1386 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site) { |
1371 compiler::Node* allocation_site, | 1387 Comment("begin allocation of JSArray without elements"); |
1372 ParameterMode mode) { | 1388 int base_size = JSArray::kSize; |
1373 bool is_double = IsFastDoubleElementsKind(kind); | |
1374 int base_size = JSArray::kSize + FixedArray::kHeaderSize; | |
1375 int elements_offset = JSArray::kSize; | |
1376 | |
1377 Comment("begin allocation of JSArray"); | |
1378 | 1389 |
1379 if (allocation_site != nullptr) { | 1390 if (allocation_site != nullptr) { |
1380 base_size += AllocationMemento::kSize; | 1391 base_size += AllocationMemento::kSize; |
1381 elements_offset += AllocationMemento::kSize; | |
1382 } | 1392 } |
1383 | 1393 |
1384 Node* total_size = | 1394 Node* size = IntPtrConstant(base_size); |
1385 ElementOffsetFromIndex(capacity_node, kind, mode, base_size); | 1395 Node* array = AllocateUninitializedJSArray(kind, array_map, length, |
| 1396 allocation_site, size); |
| 1397 return array; |
| 1398 } |
1386 | 1399 |
1387 // Allocate both array and elements object, and initialize the JSArray. | 1400 std::pair<Node*, Node*> |
1388 Heap* heap = isolate()->heap(); | 1401 CodeStubAssembler::AllocateUninitializedJSArrayWithElements( |
1389 Node* array = Allocate(total_size); | 1402 ElementsKind kind, Node* array_map, Node* length, Node* allocation_site, |
| 1403 Node* capacity, ParameterMode capacity_mode) { |
| 1404 Comment("begin allocation of JSArray with elements"); |
| 1405 int base_size = JSArray::kSize; |
| 1406 |
| 1407 if (allocation_site != nullptr) { |
| 1408 base_size += AllocationMemento::kSize; |
| 1409 } |
| 1410 |
| 1411 int elements_offset = base_size; |
| 1412 |
| 1413 // Compute space for elements |
| 1414 base_size += FixedArray::kHeaderSize; |
| 1415 Node* size = ElementOffsetFromIndex(capacity, kind, capacity_mode, base_size); |
| 1416 |
| 1417 Node* array = AllocateUninitializedJSArray(kind, array_map, length, |
| 1418 allocation_site, size); |
| 1419 |
| 1420 Node* elements = InnerAllocate(array, elements_offset); |
| 1421 StoreObjectField(array, JSObject::kElementsOffset, elements); |
| 1422 |
| 1423 return {array, elements}; |
| 1424 } |
| 1425 |
| 1426 Node* CodeStubAssembler::AllocateUninitializedJSArray(ElementsKind kind, |
| 1427 Node* array_map, |
| 1428 Node* length, |
| 1429 Node* allocation_site, |
| 1430 Node* size_in_bytes) { |
| 1431 Node* array = Allocate(size_in_bytes); |
| 1432 |
| 1433 Comment("write JSArray headers"); |
1390 StoreMapNoWriteBarrier(array, array_map); | 1434 StoreMapNoWriteBarrier(array, array_map); |
1391 Node* empty_properties = LoadRoot(Heap::kEmptyFixedArrayRootIndex); | 1435 |
1392 StoreObjectFieldNoWriteBarrier(array, JSArray::kPropertiesOffset, | 1436 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); |
1393 empty_properties); | 1437 |
1394 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, | 1438 StoreObjectFieldRoot(array, JSArray::kPropertiesOffset, |
1395 TagParameter(length_node, mode)); | 1439 Heap::kEmptyFixedArrayRootIndex); |
1396 | 1440 |
1397 if (allocation_site != nullptr) { | 1441 if (allocation_site != nullptr) { |
1398 InitializeAllocationMemento(array, JSArray::kSize, allocation_site); | 1442 InitializeAllocationMemento(array, JSArray::kSize, allocation_site); |
1399 } | 1443 } |
| 1444 return array; |
| 1445 } |
1400 | 1446 |
| 1447 Node* CodeStubAssembler::AllocateJSArray(ElementsKind kind, Node* array_map, |
| 1448 Node* capacity, Node* length, |
| 1449 Node* allocation_site, |
| 1450 ParameterMode capacity_mode) { |
| 1451 bool is_double = IsFastDoubleElementsKind(kind); |
| 1452 |
| 1453 // Allocate both array and elements object, and initialize the JSArray. |
| 1454 Node *array, *elements; |
| 1455 std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( |
| 1456 kind, array_map, length, allocation_site, capacity, capacity_mode); |
1401 // Setup elements object. | 1457 // Setup elements object. |
1402 Node* elements = InnerAllocate(array, elements_offset); | 1458 Heap* heap = isolate()->heap(); |
1403 StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, elements); | |
1404 Handle<Map> elements_map(is_double ? heap->fixed_double_array_map() | 1459 Handle<Map> elements_map(is_double ? heap->fixed_double_array_map() |
1405 : heap->fixed_array_map()); | 1460 : heap->fixed_array_map()); |
1406 StoreMapNoWriteBarrier(elements, HeapConstant(elements_map)); | 1461 StoreMapNoWriteBarrier(elements, HeapConstant(elements_map)); |
1407 StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, | 1462 StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, |
1408 TagParameter(capacity_node, mode)); | 1463 TagParameter(capacity, capacity_mode)); |
1409 | 1464 |
1410 // Fill in the elements with holes. | 1465 // Fill in the elements with holes. |
1411 FillFixedArrayWithValue(kind, elements, IntPtrConstant(0), capacity_node, | 1466 FillFixedArrayWithValue(kind, elements, IntPtrConstant(0), capacity, |
1412 Heap::kTheHoleValueRootIndex, mode); | 1467 Heap::kTheHoleValueRootIndex, capacity_mode); |
1413 | 1468 |
1414 return array; | 1469 return array; |
1415 } | 1470 } |
1416 | 1471 |
1417 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, | 1472 Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind, |
1418 Node* capacity_node, | 1473 Node* capacity_node, |
1419 ParameterMode mode, | 1474 ParameterMode mode, |
1420 AllocationFlags flags) { | 1475 AllocationFlags flags) { |
1421 Node* total_size = GetFixedAarrayAllocationSize(capacity_node, kind, mode); | 1476 Node* total_size = GetFixedAarrayAllocationSize(capacity_node, kind, mode); |
1422 | 1477 |
(...skipping 2429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3852 Label* miss) { | 3907 Label* miss) { |
3853 Variable var_length(this, MachineType::PointerRepresentation()); | 3908 Variable var_length(this, MachineType::PointerRepresentation()); |
3854 Label if_array(this), length_loaded(this, &var_length); | 3909 Label if_array(this), length_loaded(this, &var_length); |
3855 GotoIf(is_jsarray_condition, &if_array); | 3910 GotoIf(is_jsarray_condition, &if_array); |
3856 { | 3911 { |
3857 var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements))); | 3912 var_length.Bind(SmiUntag(LoadFixedArrayBaseLength(elements))); |
3858 Goto(&length_loaded); | 3913 Goto(&length_loaded); |
3859 } | 3914 } |
3860 Bind(&if_array); | 3915 Bind(&if_array); |
3861 { | 3916 { |
3862 var_length.Bind(SmiUntag(LoadObjectField(object, JSArray::kLengthOffset))); | 3917 var_length.Bind(SmiUntag(LoadJSArrayLength(object))); |
3863 Goto(&length_loaded); | 3918 Goto(&length_loaded); |
3864 } | 3919 } |
3865 Bind(&length_loaded); | 3920 Bind(&length_loaded); |
3866 GotoUnless(UintPtrLessThan(intptr_index, var_length.value()), miss); | 3921 GotoUnless(UintPtrLessThan(intptr_index, var_length.value()), miss); |
3867 } | 3922 } |
3868 | 3923 |
3869 void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements, | 3924 void CodeStubAssembler::EmitElementLoad(Node* object, Node* elements, |
3870 Node* elements_kind, Node* intptr_index, | 3925 Node* elements_kind, Node* intptr_index, |
3871 Node* is_jsarray_condition, | 3926 Node* is_jsarray_condition, |
3872 Label* if_hole, Label* rebox_double, | 3927 Label* if_hole, Label* rebox_double, |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4194 &var_handler, &try_polymorphic); | 4249 &var_handler, &try_polymorphic); |
4195 Bind(&if_handler); | 4250 Bind(&if_handler); |
4196 { | 4251 { |
4197 HandleLoadICHandlerCase(p, var_handler.value(), &miss); | 4252 HandleLoadICHandlerCase(p, var_handler.value(), &miss); |
4198 } | 4253 } |
4199 | 4254 |
4200 Bind(&try_polymorphic); | 4255 Bind(&try_polymorphic); |
4201 { | 4256 { |
4202 // Check polymorphic case. | 4257 // Check polymorphic case. |
4203 Comment("LoadIC_try_polymorphic"); | 4258 Comment("LoadIC_try_polymorphic"); |
4204 GotoUnless( | 4259 GotoUnless(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), |
4205 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), | 4260 &try_megamorphic); |
4206 &try_megamorphic); | |
4207 HandlePolymorphicCase(p, receiver_map, feedback, &if_handler, &var_handler, | 4261 HandlePolymorphicCase(p, receiver_map, feedback, &if_handler, &var_handler, |
4208 &miss, 2); | 4262 &miss, 2); |
4209 } | 4263 } |
4210 | 4264 |
4211 Bind(&try_megamorphic); | 4265 Bind(&try_megamorphic); |
4212 { | 4266 { |
4213 // Check megamorphic case. | 4267 // Check megamorphic case. |
4214 GotoUnless( | 4268 GotoUnless( |
4215 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), | 4269 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), |
4216 &miss); | 4270 &miss); |
(...skipping 23 matching lines...) Expand all Loading... |
4240 &var_handler, &try_polymorphic); | 4294 &var_handler, &try_polymorphic); |
4241 Bind(&if_handler); | 4295 Bind(&if_handler); |
4242 { | 4296 { |
4243 HandleLoadICHandlerCase(p, var_handler.value(), &miss, kSupportElements); | 4297 HandleLoadICHandlerCase(p, var_handler.value(), &miss, kSupportElements); |
4244 } | 4298 } |
4245 | 4299 |
4246 Bind(&try_polymorphic); | 4300 Bind(&try_polymorphic); |
4247 { | 4301 { |
4248 // Check polymorphic case. | 4302 // Check polymorphic case. |
4249 Comment("KeyedLoadIC_try_polymorphic"); | 4303 Comment("KeyedLoadIC_try_polymorphic"); |
4250 GotoUnless( | 4304 GotoUnless(WordEqual(LoadMap(feedback), FixedArrayMapConstant()), |
4251 WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)), | 4305 &try_megamorphic); |
4252 &try_megamorphic); | |
4253 HandlePolymorphicCase(p, receiver_map, feedback, &if_handler, &var_handler, | 4306 HandlePolymorphicCase(p, receiver_map, feedback, &if_handler, &var_handler, |
4254 &miss, 2); | 4307 &miss, 2); |
4255 } | 4308 } |
4256 | 4309 |
4257 Bind(&try_megamorphic); | 4310 Bind(&try_megamorphic); |
4258 { | 4311 { |
4259 // Check megamorphic case. | 4312 // Check megamorphic case. |
4260 Comment("KeyedLoadIC_try_megamorphic"); | 4313 Comment("KeyedLoadIC_try_megamorphic"); |
4261 GotoUnless( | 4314 GotoUnless( |
4262 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), | 4315 WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)), |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4625 StoreFixedArrayElement(the_context, mapped_index, value, | 4678 StoreFixedArrayElement(the_context, mapped_index, value, |
4626 UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS); | 4679 UPDATE_WRITE_BARRIER, INTPTR_PARAMETERS); |
4627 } | 4680 } |
4628 Goto(&end); | 4681 Goto(&end); |
4629 } | 4682 } |
4630 | 4683 |
4631 Bind(&if_unmapped); | 4684 Bind(&if_unmapped); |
4632 { | 4685 { |
4633 Node* backing_store = LoadFixedArrayElement(elements, IntPtrConstant(1), 0, | 4686 Node* backing_store = LoadFixedArrayElement(elements, IntPtrConstant(1), 0, |
4634 INTPTR_PARAMETERS); | 4687 INTPTR_PARAMETERS); |
4635 GotoIf(WordNotEqual(LoadMap(backing_store), | 4688 GotoIf(WordNotEqual(LoadMap(backing_store), FixedArrayMapConstant()), |
4636 LoadRoot(Heap::kFixedArrayMapRootIndex)), | |
4637 bailout); | 4689 bailout); |
4638 | 4690 |
4639 Node* backing_store_length = | 4691 Node* backing_store_length = |
4640 LoadAndUntagFixedArrayBaseLength(backing_store); | 4692 LoadAndUntagFixedArrayBaseLength(backing_store); |
4641 GotoIf(UintPtrGreaterThanOrEqual(key, backing_store_length), bailout); | 4693 GotoIf(UintPtrGreaterThanOrEqual(key, backing_store_length), bailout); |
4642 | 4694 |
4643 // The key falls into unmapped range. | 4695 // The key falls into unmapped range. |
4644 if (is_load) { | 4696 if (is_load) { |
4645 Node* result = | 4697 Node* result = |
4646 LoadFixedArrayElement(backing_store, key, 0, INTPTR_PARAMETERS); | 4698 LoadFixedArrayElement(backing_store, key, 0, INTPTR_PARAMETERS); |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5137 Heap::kTheHoleValueRootIndex); | 5189 Heap::kTheHoleValueRootIndex); |
5138 | 5190 |
5139 // Store the WeakCell in the feedback vector. | 5191 // Store the WeakCell in the feedback vector. |
5140 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, | 5192 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
5141 CodeStubAssembler::SMI_PARAMETERS); | 5193 CodeStubAssembler::SMI_PARAMETERS); |
5142 return cell; | 5194 return cell; |
5143 } | 5195 } |
5144 | 5196 |
5145 } // namespace internal | 5197 } // namespace internal |
5146 } // namespace v8 | 5198 } // namespace v8 |
OLD | NEW |