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/ic/accessor-assembler.h" | 5 #include "src/ic/accessor-assembler.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.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 1391 matching lines...) Loading... | |
1402 Variable var_details(this, MachineRepresentation::kWord32); | 1402 Variable var_details(this, MachineRepresentation::kWord32); |
1403 Variable var_value(this, MachineRepresentation::kTagged); | 1403 Variable var_value(this, MachineRepresentation::kTagged); |
1404 Label if_index(this), if_unique_name(this), if_element_hole(this), | 1404 Label if_index(this), if_unique_name(this), if_element_hole(this), |
1405 if_oob(this), slow(this), stub_cache_miss(this), | 1405 if_oob(this), slow(this), stub_cache_miss(this), |
1406 if_property_dictionary(this), if_found_on_receiver(this); | 1406 if_property_dictionary(this), if_found_on_receiver(this); |
1407 | 1407 |
1408 Node* receiver = p->receiver; | 1408 Node* receiver = p->receiver; |
1409 GotoIf(TaggedIsSmi(receiver), &slow); | 1409 GotoIf(TaggedIsSmi(receiver), &slow); |
1410 Node* receiver_map = LoadMap(receiver); | 1410 Node* receiver_map = LoadMap(receiver); |
1411 Node* instance_type = LoadMapInstanceType(receiver_map); | 1411 Node* instance_type = LoadMapInstanceType(receiver_map); |
1412 // Receivers requiring non-standard element accesses (interceptors, access | |
1413 // checks, strings and string wrappers, proxies) are handled in the runtime. | |
1414 GotoIf(Int32LessThanOrEqual(instance_type, | |
1415 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), | |
1416 &slow); | |
1417 | 1412 |
1418 TryToName(p->name, &if_index, &var_index, &if_unique_name, &var_unique, | 1413 TryToName(p->name, &if_index, &var_index, &if_unique_name, &var_unique, |
1419 &slow); | 1414 &slow); |
1420 | 1415 |
1421 Bind(&if_index); | 1416 Bind(&if_index); |
1422 { | 1417 { |
1423 Comment("integer index"); | 1418 Comment("integer index"); |
1419 // Receivers requiring non-standard element accesses (interceptors, access | |
1420 // checks, strings and string wrappers, proxies) are handled in the runtime. | |
1421 GotoIf(Int32LessThanOrEqual(instance_type, | |
1422 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), | |
1423 &slow); | |
1424 Node* index = var_index.value(); | 1424 Node* index = var_index.value(); |
1425 Node* elements = LoadElements(receiver); | 1425 Node* elements = LoadElements(receiver); |
1426 Node* elements_kind = LoadMapElementsKind(receiver_map); | 1426 Node* elements_kind = LoadMapElementsKind(receiver_map); |
1427 Node* is_jsarray_condition = | 1427 Node* is_jsarray_condition = |
1428 Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)); | 1428 Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)); |
1429 Variable var_double_value(this, MachineRepresentation::kFloat64); | 1429 Variable var_double_value(this, MachineRepresentation::kFloat64); |
1430 Label rebox_double(this, &var_double_value); | 1430 Label rebox_double(this, &var_double_value); |
1431 | 1431 |
1432 // Unimplemented elements kinds fall back to a runtime call. | 1432 // Unimplemented elements kinds fall back to a runtime call. |
1433 Label* unimplemented_elements_kind = &slow; | 1433 Label* unimplemented_elements_kind = &slow; |
(...skipping 24 matching lines...) Loading... | |
1458 BranchIfPrototypesHaveNoElements(receiver_map, &return_undefined, &slow); | 1458 BranchIfPrototypesHaveNoElements(receiver_map, &return_undefined, &slow); |
1459 | 1459 |
1460 Bind(&return_undefined); | 1460 Bind(&return_undefined); |
1461 Return(UndefinedConstant()); | 1461 Return(UndefinedConstant()); |
1462 } | 1462 } |
1463 | 1463 |
1464 Node* properties = nullptr; | 1464 Node* properties = nullptr; |
1465 Bind(&if_unique_name); | 1465 Bind(&if_unique_name); |
1466 { | 1466 { |
1467 Comment("key is unique name"); | 1467 Comment("key is unique name"); |
1468 | |
1469 // Receivers requiring non-standard accesses (interceptors, access | |
1470 // checks, string wrappers, proxies) are handled in the runtime. | |
1471 // We special-case strings here, to support loading <Symbol.split> etc. | |
1472 Variable var_receiver(this, MachineRepresentation::kTagged); | |
1473 Label normal_receiver(this, &var_receiver); | |
1474 var_receiver.Bind(receiver); | |
1475 GotoIf(Int32GreaterThan(instance_type, | |
1476 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), | |
1477 &normal_receiver); | |
1478 GotoIf(Int32GreaterThanOrEqual(instance_type, | |
1479 Int32Constant(FIRST_NONSTRING_TYPE)), | |
1480 &slow); | |
1481 CSA_ASSERT(this, WordEqual(LoadMapConstructorFunctionIndex(receiver_map), | |
1482 IntPtrConstant(Context::STRING_FUNCTION_INDEX))); | |
1483 Node* native_context = LoadNativeContext(p->context); | |
1484 Node* constructor_function = | |
1485 LoadContextElement(native_context, Context::STRING_FUNCTION_INDEX); | |
1486 Node* initial_map = LoadObjectField( | |
1487 constructor_function, JSFunction::kPrototypeOrInitialMapOffset); | |
1488 var_receiver.Bind(LoadMapPrototype(initial_map)); | |
1489 Goto(&normal_receiver); | |
1490 | |
1491 Bind(&normal_receiver); | |
1492 receiver = var_receiver.value(); | |
Igor Sheludko
2017/01/27 08:04:07
Here we are potentially changing the receiver but
Jakob Kummerow
2017/01/28 04:30:12
Oops, good point. Done.
| |
1468 Node* key = var_unique.value(); | 1493 Node* key = var_unique.value(); |
Igor Sheludko
2017/01/27 08:13:42
Moreover, we are lucky that the elements handling
Jakob Kummerow
2017/01/28 04:30:12
Done.
| |
1469 // Check if the receiver has fast or slow properties. | 1494 // Check if the receiver has fast or slow properties. |
1470 properties = LoadProperties(receiver); | 1495 properties = LoadProperties(receiver); |
1471 Node* properties_map = LoadMap(properties); | 1496 Node* properties_map = LoadMap(properties); |
1472 GotoIf(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), | 1497 GotoIf(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), |
1473 &if_property_dictionary); | 1498 &if_property_dictionary); |
1474 | 1499 |
1475 // Try looking up the property on the receiver; if unsuccessful, look | 1500 // Try looking up the property on the receiver; if unsuccessful, look |
1476 // for a handler in the stub cache. | 1501 // for a handler in the stub cache. |
1477 Comment("DescriptorArray lookup"); | 1502 Comment("DescriptorArray lookup"); |
1478 | 1503 |
(...skipping 25 matching lines...) Loading... | |
1504 Comment("stub cache probe for fast property load"); | 1529 Comment("stub cache probe for fast property load"); |
1505 Variable var_handler(this, MachineRepresentation::kTagged); | 1530 Variable var_handler(this, MachineRepresentation::kTagged); |
1506 Label found_handler(this, &var_handler), stub_cache_miss(this); | 1531 Label found_handler(this, &var_handler), stub_cache_miss(this); |
1507 TryProbeStubCache(isolate()->load_stub_cache(), receiver, key, | 1532 TryProbeStubCache(isolate()->load_stub_cache(), receiver, key, |
1508 &found_handler, &var_handler, &stub_cache_miss); | 1533 &found_handler, &var_handler, &stub_cache_miss); |
1509 Bind(&found_handler); | 1534 Bind(&found_handler); |
1510 { HandleLoadICHandlerCase(p, var_handler.value(), &slow); } | 1535 { HandleLoadICHandlerCase(p, var_handler.value(), &slow); } |
1511 | 1536 |
1512 Bind(&stub_cache_miss); | 1537 Bind(&stub_cache_miss); |
1513 { | 1538 { |
1539 // TODO(jkummerow): Check if the property exists on the prototype | |
1540 // chain. If it doesn't, then there's no point in missing. | |
1514 Comment("KeyedLoadGeneric_miss"); | 1541 Comment("KeyedLoadGeneric_miss"); |
1515 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, | 1542 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, |
1516 p->name, p->slot, p->vector); | 1543 p->name, p->slot, p->vector); |
1517 } | 1544 } |
1518 } | 1545 } |
1519 } | 1546 } |
1520 | 1547 |
1521 Bind(&if_property_dictionary); | 1548 Bind(&if_property_dictionary); |
1522 { | 1549 { |
1523 Comment("dictionary property load"); | 1550 Comment("dictionary property load"); |
(...skipping 359 matching lines...) Loading... | |
1883 Node* slot = Parameter(Descriptor::kSlot); | 1910 Node* slot = Parameter(Descriptor::kSlot); |
1884 Node* context = Parameter(Descriptor::kContext); | 1911 Node* context = Parameter(Descriptor::kContext); |
1885 Node* vector = LoadTypeFeedbackVectorForStub(); | 1912 Node* vector = LoadTypeFeedbackVectorForStub(); |
1886 | 1913 |
1887 StoreICParameters p(context, receiver, name, value, slot, vector); | 1914 StoreICParameters p(context, receiver, name, value, slot, vector); |
1888 KeyedStoreIC(&p, language_mode); | 1915 KeyedStoreIC(&p, language_mode); |
1889 } | 1916 } |
1890 | 1917 |
1891 } // namespace internal | 1918 } // namespace internal |
1892 } // namespace v8 | 1919 } // namespace v8 |
OLD | NEW |