Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 331633002: Revert "Revert "Reland 21774: Generate KeyedLoadGeneric with Hydrogen"" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/field-index.h" 8 #include "src/field-index.h"
9 #include "src/hydrogen.h" 9 #include "src/hydrogen.h"
10 #include "src/lithium.h" 10 #include "src/lithium.h"
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 } 1383 }
1384 1384
1385 1385
1386 template<> 1386 template<>
1387 HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() { 1387 HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() {
1388 HValue* receiver = GetParameter(0); 1388 HValue* receiver = GetParameter(0);
1389 HValue* key = GetParameter(1); 1389 HValue* key = GetParameter(1);
1390 1390
1391 Add<HCheckSmi>(key); 1391 Add<HCheckSmi>(key);
1392 1392
1393 return BuildUncheckedDictionaryElementLoad(receiver, key); 1393 HValue* elements = AddLoadElements(receiver);
1394
1395 HValue* hash = BuildElementIndexHash(key);
1396
1397 return BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash);
1394 } 1398 }
1395 1399
1396 1400
1397 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode() { 1401 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode() {
1398 return DoGenerateCode(this); 1402 return DoGenerateCode(this);
1399 } 1403 }
1400 1404
1401 1405
1402 template<> 1406 template<>
1403 HValue* CodeStubGraphBuilder<RegExpConstructResultStub>::BuildCodeStub() { 1407 HValue* CodeStubGraphBuilder<RegExpConstructResultStub>::BuildCodeStub() {
1404 // Determine the parameters. 1408 // Determine the parameters.
1405 HValue* length = GetParameter(RegExpConstructResultStub::kLength); 1409 HValue* length = GetParameter(RegExpConstructResultStub::kLength);
1406 HValue* index = GetParameter(RegExpConstructResultStub::kIndex); 1410 HValue* index = GetParameter(RegExpConstructResultStub::kIndex);
1407 HValue* input = GetParameter(RegExpConstructResultStub::kInput); 1411 HValue* input = GetParameter(RegExpConstructResultStub::kInput);
1408 1412
1409 info()->MarkMustNotHaveEagerFrame(); 1413 info()->MarkMustNotHaveEagerFrame();
1410 1414
1411 return BuildRegExpConstructResult(length, index, input); 1415 return BuildRegExpConstructResult(length, index, input);
1412 } 1416 }
1413 1417
1414 1418
1415 Handle<Code> RegExpConstructResultStub::GenerateCode() { 1419 Handle<Code> RegExpConstructResultStub::GenerateCode() {
1416 return DoGenerateCode(this); 1420 return DoGenerateCode(this);
1417 } 1421 }
1418 1422
1419 1423
1424 template <>
1425 class CodeStubGraphBuilder<KeyedLoadGenericElementStub>
1426 : public CodeStubGraphBuilderBase {
1427 public:
1428 CodeStubGraphBuilder(Isolate* isolate,
1429 KeyedLoadGenericElementStub* stub)
1430 : CodeStubGraphBuilderBase(isolate, stub) {}
1431
1432 protected:
1433 virtual HValue* BuildCodeStub();
1434
1435 void BuildElementsKindLimitCheck(HGraphBuilder::IfBuilder* if_builder,
1436 HValue* bit_field2,
1437 ElementsKind kind);
1438
1439 void BuildFastElementLoad(HGraphBuilder::IfBuilder* if_builder,
1440 HValue* receiver,
1441 HValue* key,
1442 HValue* instance_type,
1443 HValue* bit_field2,
1444 ElementsKind kind);
1445
1446 void BuildExternalElementLoad(HGraphBuilder::IfBuilder* if_builder,
1447 HValue* receiver,
1448 HValue* key,
1449 HValue* instance_type,
1450 HValue* bit_field2,
1451 ElementsKind kind);
1452
1453 KeyedLoadGenericElementStub* casted_stub() {
1454 return static_cast<KeyedLoadGenericElementStub*>(stub());
1455 }
1456 };
1457
1458
1459 void CodeStubGraphBuilder<
1460 KeyedLoadGenericElementStub>::BuildElementsKindLimitCheck(
1461 HGraphBuilder::IfBuilder* if_builder,
1462 HValue* bit_field2,
1463 ElementsKind kind) {
1464 ElementsKind next_kind = static_cast<ElementsKind>(kind + 1);
1465 HValue* kind_limit = Add<HConstant>(
1466 static_cast<int>(Map::ElementsKindBits::encode(next_kind)));
1467
1468 if_builder->If<HCompareNumericAndBranch>(bit_field2, kind_limit, Token::LT);
1469 if_builder->Then();
1470 }
1471
1472
1473 void CodeStubGraphBuilder<KeyedLoadGenericElementStub>::BuildFastElementLoad(
1474 HGraphBuilder::IfBuilder* if_builder,
1475 HValue* receiver,
1476 HValue* key,
1477 HValue* instance_type,
1478 HValue* bit_field2,
1479 ElementsKind kind) {
1480 ASSERT(!IsExternalArrayElementsKind(kind));
1481
1482 BuildElementsKindLimitCheck(if_builder, bit_field2, kind);
1483
1484 IfBuilder js_array_check(this);
1485 js_array_check.If<HCompareNumericAndBranch>(
1486 instance_type, Add<HConstant>(JS_ARRAY_TYPE), Token::EQ);
1487 js_array_check.Then();
1488 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL,
1489 true, kind,
1490 LOAD, NEVER_RETURN_HOLE,
1491 STANDARD_STORE));
1492 js_array_check.Else();
1493 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL,
1494 false, kind,
1495 LOAD, NEVER_RETURN_HOLE,
1496 STANDARD_STORE));
1497 js_array_check.End();
1498 }
1499
1500
1501 void CodeStubGraphBuilder<
1502 KeyedLoadGenericElementStub>::BuildExternalElementLoad(
1503 HGraphBuilder::IfBuilder* if_builder,
1504 HValue* receiver,
1505 HValue* key,
1506 HValue* instance_type,
1507 HValue* bit_field2,
1508 ElementsKind kind) {
1509 ASSERT(IsExternalArrayElementsKind(kind));
1510
1511 BuildElementsKindLimitCheck(if_builder, bit_field2, kind);
1512
1513 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL,
1514 false, kind,
1515 LOAD, NEVER_RETURN_HOLE,
1516 STANDARD_STORE));
1517 }
1518
1519
1520 HValue* CodeStubGraphBuilder<KeyedLoadGenericElementStub>::BuildCodeStub() {
1521 HValue* receiver = GetParameter(0);
1522 HValue* key = GetParameter(1);
1523
1524 // Split into a smi/integer case and unique string case.
1525 HIfContinuation index_name_split_continuation(graph()->CreateBasicBlock(),
1526 graph()->CreateBasicBlock());
1527
1528 BuildKeyedIndexCheck(key, &index_name_split_continuation);
1529
1530 IfBuilder index_name_split(this, &index_name_split_continuation);
1531 index_name_split.Then();
1532 {
1533 // Key is an index (number)
1534 key = Pop();
1535
1536 int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) |
1537 (1 << Map::kHasIndexedInterceptor);
1538 BuildJSObjectCheck(receiver, bit_field_mask);
1539
1540 HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
1541 HObjectAccess::ForMap());
1542
1543 HValue* instance_type =
1544 Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
1545 HObjectAccess::ForMapInstanceType());
1546
1547 HValue* bit_field2 = Add<HLoadNamedField>(map,
1548 static_cast<HValue*>(NULL),
1549 HObjectAccess::ForMapBitField2());
1550
1551 IfBuilder kind_if(this);
1552 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1553 FAST_HOLEY_ELEMENTS);
1554
1555 kind_if.Else();
1556 {
1557 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1558 FAST_HOLEY_DOUBLE_ELEMENTS);
1559 }
1560 kind_if.Else();
1561
1562 // The DICTIONARY_ELEMENTS check generates a "kind_if.Then"
1563 BuildElementsKindLimitCheck(&kind_if, bit_field2, DICTIONARY_ELEMENTS);
1564 {
1565 HValue* elements = AddLoadElements(receiver);
1566
1567 HValue* hash = BuildElementIndexHash(key);
1568
1569 Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash));
1570 }
1571 kind_if.Else();
1572
1573 // The SLOPPY_ARGUMENTS_ELEMENTS check generates a "kind_if.Then"
1574 BuildElementsKindLimitCheck(&kind_if, bit_field2,
1575 SLOPPY_ARGUMENTS_ELEMENTS);
1576 // Non-strict elements are not handled.
1577 Add<HDeoptimize>("non-strict elements in KeyedLoadGenericElementStub",
1578 Deoptimizer::EAGER);
1579 Push(graph()->GetConstant0());
1580
1581 kind_if.Else();
1582 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1583 EXTERNAL_INT8_ELEMENTS);
1584
1585 kind_if.Else();
1586 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1587 EXTERNAL_UINT8_ELEMENTS);
1588
1589 kind_if.Else();
1590 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1591 EXTERNAL_INT16_ELEMENTS);
1592
1593 kind_if.Else();
1594 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1595 EXTERNAL_UINT16_ELEMENTS);
1596
1597 kind_if.Else();
1598 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1599 EXTERNAL_INT32_ELEMENTS);
1600
1601 kind_if.Else();
1602 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1603 EXTERNAL_UINT32_ELEMENTS);
1604
1605 kind_if.Else();
1606 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1607 EXTERNAL_FLOAT32_ELEMENTS);
1608
1609 kind_if.Else();
1610 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1611 EXTERNAL_FLOAT64_ELEMENTS);
1612
1613 kind_if.Else();
1614 BuildExternalElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1615 EXTERNAL_UINT8_CLAMPED_ELEMENTS);
1616
1617 kind_if.ElseDeopt("ElementsKind unhandled in KeyedLoadGenericElementStub");
1618
1619 kind_if.End();
1620 }
1621 index_name_split.Else();
1622 {
1623 // Key is a unique string.
1624 key = Pop();
1625
1626 int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) |
1627 (1 << Map::kHasNamedInterceptor);
1628 BuildJSObjectCheck(receiver, bit_field_mask);
1629
1630 HIfContinuation continuation;
1631 BuildTestForDictionaryProperties(receiver, &continuation);
1632 IfBuilder if_dict_properties(this, &continuation);
1633 if_dict_properties.Then();
1634 {
1635 // Key is string, properties are dictionary mode
1636 BuildNonGlobalObjectCheck(receiver);
1637
1638 HValue* properties = Add<HLoadNamedField>(
1639 receiver, static_cast<HValue*>(NULL),
1640 HObjectAccess::ForPropertiesPointer());
1641
1642 HValue* hash =
1643 Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
1644 HObjectAccess::ForNameHashField());
1645
1646 HValue* value = BuildUncheckedDictionaryElementLoad(receiver,
1647 properties,
1648 key,
1649 hash);
1650 Push(value);
1651 }
1652 if_dict_properties.Else();
1653 {
1654 // Key is string, properties are fast mode
1655 HValue* hash = BuildKeyedLookupCacheHash(receiver, key);
1656
1657 ExternalReference cache_keys_ref =
1658 ExternalReference::keyed_lookup_cache_keys(isolate());
1659 HValue* cache_keys = Add<HConstant>(cache_keys_ref);
1660
1661 HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
1662 HObjectAccess::ForMap());
1663 HValue* base_index = AddUncasted<HMul>(hash, Add<HConstant>(2));
1664 base_index->ClearFlag(HValue::kCanOverflow);
1665
1666 IfBuilder lookup_if(this);
1667 for (int probe = 0; probe < KeyedLookupCache::kEntriesPerBucket;
1668 ++probe) {
1669 int probe_base = probe * KeyedLookupCache::kEntryLength;
1670 HValue* map_index = AddUncasted<HAdd>(base_index,
1671 Add<HConstant>(probe_base + KeyedLookupCache::kMapIndex));
1672 map_index->ClearFlag(HValue::kCanOverflow);
1673 HValue* key_index = AddUncasted<HAdd>(base_index,
1674 Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex));
1675 key_index->ClearFlag(HValue::kCanOverflow);
1676 HValue* map_to_check = Add<HLoadKeyed>(cache_keys,
1677 map_index,
1678 static_cast<HValue*>(NULL),
1679 FAST_ELEMENTS,
1680 NEVER_RETURN_HOLE, 0);
1681 lookup_if.If<HCompareObjectEqAndBranch>(map_to_check, map);
1682 lookup_if.And();
1683 HValue* key_to_check = Add<HLoadKeyed>(cache_keys,
1684 key_index,
1685 static_cast<HValue*>(NULL),
1686 FAST_ELEMENTS,
1687 NEVER_RETURN_HOLE, 0);
1688 lookup_if.If<HCompareObjectEqAndBranch>(key_to_check, key);
1689 lookup_if.Then();
1690 {
1691 ExternalReference cache_field_offsets_ref =
1692 ExternalReference::keyed_lookup_cache_field_offsets(isolate());
1693 HValue* cache_field_offsets = Add<HConstant>(cache_field_offsets_ref);
1694 HValue* index = AddUncasted<HAdd>(hash,
1695 Add<HConstant>(probe));
1696 index->ClearFlag(HValue::kCanOverflow);
1697 HValue* property_index = Add<HLoadKeyed>(cache_field_offsets,
1698 index,
1699 static_cast<HValue*>(NULL),
1700 EXTERNAL_INT32_ELEMENTS,
1701 NEVER_RETURN_HOLE, 0);
1702 Push(property_index);
1703 }
1704 lookup_if.Else();
1705 }
1706 Add<HDeoptimize>("KeyedLoad fall-back", Deoptimizer::EAGER);
1707 Push(graph()->GetConstant0());
1708 lookup_if.End();
1709 Push(Add<HLoadFieldByIndex>(receiver, Pop()));
1710 }
1711 if_dict_properties.End();
1712 }
1713 index_name_split.End();
1714
1715 return Pop();
1716 }
1717
1718
1719 Handle<Code> KeyedLoadGenericElementStub::GenerateCode() {
1720 return DoGenerateCode(this);
1721 }
1722
1723
1420 } } // namespace v8::internal 1724 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/elements-kind.cc » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698