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

Side by Side Diff: src/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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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/hydrogen.h" 5 #include "src/hydrogen.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 #include "src/allocation-site-scopes.h" 10 #include "src/allocation-site-scopes.h"
(...skipping 1212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 1223
1224 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { 1224 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() {
1225 HBasicBlock* header = graph()->CreateBasicBlock(); 1225 HBasicBlock* header = graph()->CreateBasicBlock();
1226 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); 1226 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header);
1227 header->SetInitialEnvironment(entry_env); 1227 header->SetInitialEnvironment(entry_env);
1228 header->AttachLoopInformation(); 1228 header->AttachLoopInformation();
1229 return header; 1229 return header;
1230 } 1230 }
1231 1231
1232 1232
1233 HValue* HGraphBuilder::BuildGetElementsKind(HValue* object) {
1234 HValue* map = Add<HLoadNamedField>(object, static_cast<HValue*>(NULL),
1235 HObjectAccess::ForMap());
1236
1237 HValue* bit_field2 = Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
1238 HObjectAccess::ForMapBitField2());
1239 return BuildDecodeField<Map::ElementsKindBits>(bit_field2);
1240 }
1241
1242
1233 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { 1243 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) {
1234 if (obj->type().IsHeapObject()) return obj; 1244 if (obj->type().IsHeapObject()) return obj;
1235 return Add<HCheckHeapObject>(obj); 1245 return Add<HCheckHeapObject>(obj);
1236 } 1246 }
1237 1247
1238 1248
1239 void HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) { 1249 void HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) {
1240 Add<HDeoptimize>(reason, Deoptimizer::EAGER); 1250 Add<HDeoptimize>(reason, Deoptimizer::EAGER);
1241 FinishExitCurrentBlock(New<HAbnormalExit>()); 1251 FinishExitCurrentBlock(New<HAbnormalExit>());
1242 } 1252 }
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, 1402 BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
1393 array_length, elements_length); 1403 array_length, elements_length);
1394 1404
1395 if_builder.End(); 1405 if_builder.End();
1396 } 1406 }
1397 1407
1398 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); 1408 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map);
1399 } 1409 }
1400 1410
1401 1411
1412 void HGraphBuilder::BuildJSObjectCheck(HValue* receiver,
1413 int bit_field_mask) {
1414 // Check that the object isn't a smi.
1415 Add<HCheckHeapObject>(receiver);
1416
1417 // Get the map of the receiver.
1418 HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
1419 HObjectAccess::ForMap());
1420
1421 // Check the instance type and if an access check is needed, this can be
1422 // done with a single load, since both bytes are adjacent in the map.
1423 HObjectAccess access(HObjectAccess::ForMapInstanceTypeAndBitField());
1424 HValue* instance_type_and_bit_field =
1425 Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), access);
1426
1427 HValue* mask = Add<HConstant>(0x00FF | (bit_field_mask << 8));
1428 HValue* and_result = AddUncasted<HBitwise>(Token::BIT_AND,
1429 instance_type_and_bit_field,
1430 mask);
1431 HValue* sub_result = AddUncasted<HSub>(and_result,
1432 Add<HConstant>(JS_OBJECT_TYPE));
1433 Add<HBoundsCheck>(sub_result, Add<HConstant>(0x100 - JS_OBJECT_TYPE));
1434 }
1435
1436
1437 void HGraphBuilder::BuildKeyedIndexCheck(HValue* key,
1438 HIfContinuation* join_continuation) {
1439 // The sometimes unintuitively backward ordering of the ifs below is
1440 // convoluted, but necessary. All of the paths must guarantee that the
1441 // if-true of the continuation returns a smi element index and the if-false of
1442 // the continuation returns either a symbol or a unique string key. All other
1443 // object types cause a deopt to fall back to the runtime.
1444
1445 IfBuilder key_smi_if(this);
1446 key_smi_if.If<HIsSmiAndBranch>(key);
1447 key_smi_if.Then();
1448 {
1449 Push(key); // Nothing to do, just continue to true of continuation.
1450 }
1451 key_smi_if.Else();
1452 {
1453 HValue* map = Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
1454 HObjectAccess::ForMap());
1455 HValue* instance_type =
1456 Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
1457 HObjectAccess::ForMapInstanceType());
1458
1459 // Non-unique string, check for a string with a hash code that is actually
1460 // an index.
1461 STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE);
1462 IfBuilder not_string_or_name_if(this);
1463 not_string_or_name_if.If<HCompareNumericAndBranch>(
1464 instance_type,
1465 Add<HConstant>(LAST_UNIQUE_NAME_TYPE),
1466 Token::GT);
1467
1468 not_string_or_name_if.Then();
1469 {
1470 // Non-smi, non-Name, non-String: Try to convert to smi in case of
1471 // HeapNumber.
1472 // TODO(danno): This could call some variant of ToString
1473 Push(AddUncasted<HForceRepresentation>(key, Representation::Smi()));
1474 }
1475 not_string_or_name_if.Else();
1476 {
1477 // String or Name: check explicitly for Name, they can short-circuit
1478 // directly to unique non-index key path.
1479 IfBuilder not_symbol_if(this);
1480 not_symbol_if.If<HCompareNumericAndBranch>(
1481 instance_type,
1482 Add<HConstant>(SYMBOL_TYPE),
1483 Token::NE);
1484
1485 not_symbol_if.Then();
1486 {
1487 // String: check whether the String is a String of an index. If it is,
1488 // extract the index value from the hash.
1489 HValue* hash =
1490 Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
1491 HObjectAccess::ForNameHashField());
1492 HValue* not_index_mask = Add<HConstant>(static_cast<int>(
1493 String::kContainsCachedArrayIndexMask));
1494
1495 HValue* not_index_test = AddUncasted<HBitwise>(
1496 Token::BIT_AND, hash, not_index_mask);
1497
1498 IfBuilder string_index_if(this);
1499 string_index_if.If<HCompareNumericAndBranch>(not_index_test,
1500 graph()->GetConstant0(),
1501 Token::EQ);
1502 string_index_if.Then();
1503 {
1504 // String with index in hash: extract string and merge to index path.
1505 Push(BuildDecodeField<String::ArrayIndexValueBits>(hash));
1506 }
1507 string_index_if.Else();
1508 {
1509 // Key is a non-index String, check for uniqueness/internalization. If
1510 // it's not, deopt.
1511 HValue* not_internalized_bit = AddUncasted<HBitwise>(
1512 Token::BIT_AND,
1513 instance_type,
1514 Add<HConstant>(static_cast<int>(kIsNotInternalizedMask)));
1515 DeoptimizeIf<HCompareNumericAndBranch>(
1516 not_internalized_bit,
1517 graph()->GetConstant0(),
1518 Token::NE,
1519 "BuildKeyedIndexCheck: string isn't internalized");
1520 // Key guaranteed to be a unqiue string
1521 Push(key);
1522 }
1523 string_index_if.JoinContinuation(join_continuation);
1524 }
1525 not_symbol_if.Else();
1526 {
1527 Push(key); // Key is symbol
1528 }
1529 not_symbol_if.JoinContinuation(join_continuation);
1530 }
1531 not_string_or_name_if.JoinContinuation(join_continuation);
1532 }
1533 key_smi_if.JoinContinuation(join_continuation);
1534 }
1535
1536
1537 void HGraphBuilder::BuildNonGlobalObjectCheck(HValue* receiver) {
1538 // Get the the instance type of the receiver, and make sure that it is
1539 // not one of the global object types.
1540 HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
1541 HObjectAccess::ForMap());
1542 HValue* instance_type =
1543 Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
1544 HObjectAccess::ForMapInstanceType());
1545 STATIC_ASSERT(JS_BUILTINS_OBJECT_TYPE == JS_GLOBAL_OBJECT_TYPE + 1);
1546 HValue* min_global_type = Add<HConstant>(JS_GLOBAL_OBJECT_TYPE);
1547 HValue* max_global_type = Add<HConstant>(JS_BUILTINS_OBJECT_TYPE);
1548
1549 IfBuilder if_global_object(this);
1550 if_global_object.If<HCompareNumericAndBranch>(instance_type,
1551 max_global_type,
1552 Token::LTE);
1553 if_global_object.And();
1554 if_global_object.If<HCompareNumericAndBranch>(instance_type,
1555 min_global_type,
1556 Token::GTE);
1557 if_global_object.ThenDeopt("receiver was a global object");
1558 if_global_object.End();
1559 }
1560
1561
1562 void HGraphBuilder::BuildTestForDictionaryProperties(
1563 HValue* object,
1564 HIfContinuation* continuation) {
1565 HValue* properties = Add<HLoadNamedField>(
1566 object, static_cast<HValue*>(NULL),
1567 HObjectAccess::ForPropertiesPointer());
1568 HValue* properties_map =
1569 Add<HLoadNamedField>(properties, static_cast<HValue*>(NULL),
1570 HObjectAccess::ForMap());
1571 HValue* hash_map = Add<HLoadRoot>(Heap::kHashTableMapRootIndex);
1572 IfBuilder builder(this);
1573 builder.If<HCompareObjectEqAndBranch>(properties_map, hash_map);
1574 builder.CaptureContinuation(continuation);
1575 }
1576
1577
1578 HValue* HGraphBuilder::BuildKeyedLookupCacheHash(HValue* object,
1579 HValue* key) {
1580 // Load the map of the receiver, compute the keyed lookup cache hash
1581 // based on 32 bits of the map pointer and the string hash.
1582 HValue* object_map =
1583 Add<HLoadNamedField>(object, static_cast<HValue*>(NULL),
1584 HObjectAccess::ForMapAsInteger32());
1585 HValue* shifted_map = AddUncasted<HShr>(
1586 object_map, Add<HConstant>(KeyedLookupCache::kMapHashShift));
1587 HValue* string_hash =
1588 Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
1589 HObjectAccess::ForStringHashField());
1590 HValue* shifted_hash = AddUncasted<HShr>(
1591 string_hash, Add<HConstant>(String::kHashShift));
1592 HValue* xor_result = AddUncasted<HBitwise>(Token::BIT_XOR, shifted_map,
1593 shifted_hash);
1594 int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
1595 return AddUncasted<HBitwise>(Token::BIT_AND, xor_result,
1596 Add<HConstant>(mask));
1597 }
1598
1599
1402 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoadHelper( 1600 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoadHelper(
1403 HValue* elements, 1601 HValue* elements,
1404 HValue* key, 1602 HValue* key,
1405 HValue* hash, 1603 HValue* hash,
1406 HValue* mask, 1604 HValue* mask,
1407 int current_probe) { 1605 int current_probe) {
1408 if (current_probe == kNumberDictionaryProbes) { 1606 if (current_probe == kNumberDictionaryProbes) {
1409 return NULL; 1607 return NULL;
1410 } 1608 }
1411 1609
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 hash = AddUncasted<HMul>(hash, Add<HConstant>(2057)); 1702 hash = AddUncasted<HMul>(hash, Add<HConstant>(2057));
1505 hash->ClearFlag(HValue::kCanOverflow); 1703 hash->ClearFlag(HValue::kCanOverflow);
1506 1704
1507 // hash = hash ^ (hash >> 16); 1705 // hash = hash ^ (hash >> 16);
1508 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); 1706 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16));
1509 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1707 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash);
1510 } 1708 }
1511 1709
1512 1710
1513 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, 1711 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver,
1514 HValue* key) { 1712 HValue* elements,
1515 HValue* elements = AddLoadElements(receiver); 1713 HValue* key,
1516 1714 HValue* hash) {
1517 HValue* hash = BuildElementIndexHash(key);
1518
1519 HValue* capacity = Add<HLoadKeyed>( 1715 HValue* capacity = Add<HLoadKeyed>(
1520 elements, 1716 elements,
1521 Add<HConstant>(NameDictionary::kCapacityIndex), 1717 Add<HConstant>(NameDictionary::kCapacityIndex),
1522 static_cast<HValue*>(NULL), 1718 static_cast<HValue*>(NULL),
1523 FAST_ELEMENTS); 1719 FAST_ELEMENTS);
1524 1720
1525 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); 1721 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1());
1526 mask->ChangeRepresentation(Representation::Integer32()); 1722 mask->ChangeRepresentation(Representation::Integer32());
1527 mask->ClearFlag(HValue::kCanOverflow); 1723 mask->ClearFlag(HValue::kCanOverflow);
1528 1724
(...skipping 10619 matching lines...) Expand 10 before | Expand all | Expand 10 after
12148 if (ShouldProduceTraceOutput()) { 12344 if (ShouldProduceTraceOutput()) {
12149 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12345 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12150 } 12346 }
12151 12347
12152 #ifdef DEBUG 12348 #ifdef DEBUG
12153 graph_->Verify(false); // No full verify. 12349 graph_->Verify(false); // No full verify.
12154 #endif 12350 #endif
12155 } 12351 }
12156 12352
12157 } } // namespace v8::internal 12353 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698