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

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

Issue 57123002: Reland 21774: Generate KeyedLoadGeneric with Hydrogen (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Turn off by default Created 7 years 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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 } 1321 }
1322 1322
1323 1323
1324 template<> 1324 template<>
1325 HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() { 1325 HValue* CodeStubGraphBuilder<KeyedLoadDictionaryElementStub>::BuildCodeStub() {
1326 HValue* receiver = GetParameter(0); 1326 HValue* receiver = GetParameter(0);
1327 HValue* key = GetParameter(1); 1327 HValue* key = GetParameter(1);
1328 1328
1329 Add<HCheckSmi>(key); 1329 Add<HCheckSmi>(key);
1330 1330
1331 return BuildUncheckedDictionaryElementLoad(receiver, key); 1331 HValue* elements = AddLoadElements(receiver);
Toon Verwaest 2013/12/04 17:29:26 We need at least a BuildCheckHeapObject(receiver)
danno 2014/06/06 15:43:50 Why is that needed? We already did a map check in
1332
1333 HValue* hash = BuildElementIndexHash(key);
1334
1335 return BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash);
1332 } 1336 }
1333 1337
1334 1338
1335 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) { 1339 Handle<Code> KeyedLoadDictionaryElementStub::GenerateCode(Isolate* isolate) {
1336 return DoGenerateCode(isolate, this); 1340 return DoGenerateCode(isolate, this);
1337 } 1341 }
1338 1342
1339 1343
1344 template <>
1345 class CodeStubGraphBuilder<KeyedLoadGenericElementStub>
1346 : public CodeStubGraphBuilderBase {
1347 public:
1348 CodeStubGraphBuilder(Isolate* isolate,
1349 KeyedLoadGenericElementStub* stub)
Toon Verwaest 2013/12/04 17:29:26 nit: Weird indentation
danno 2014/06/06 15:43:50 Done.
1350 : CodeStubGraphBuilderBase(isolate, stub) {}
1351
1352 protected:
1353 virtual HValue* BuildCodeStub();
1354
1355 void BuildFastElementLoad(HGraphBuilder::IfBuilder* if_builder,
1356 HValue* receiver,
1357 HValue* key,
1358 HValue* instance_type,
1359 HValue* bit_field2,
1360 ElementsKind next_kind,
1361 ElementsKind handle_as_kind);
1362
1363 KeyedLoadGenericElementStub* casted_stub() {
1364 return static_cast<KeyedLoadGenericElementStub*>(stub());
1365 }
1366 };
1367
1368
1369 void CodeStubGraphBuilder<KeyedLoadGenericElementStub>::BuildFastElementLoad(
1370 HGraphBuilder::IfBuilder* if_builder,
1371 HValue* receiver,
1372 HValue* key,
1373 HValue* instance_type,
1374 HValue* bit_field2,
1375 ElementsKind next_kind,
1376 ElementsKind handle_as_kind) {
Toon Verwaest 2013/12/04 17:29:26 In isolation it's very hard to see what this metho
danno 2014/06/06 15:43:50 Done.
1377 HValue* next_kind_value =
1378 Add<HConstant>(next_kind << Map::kElementsKindShift);
1379 if_builder->If<HCompareNumericAndBranch>(bit_field2, next_kind_value,
1380 Token::LT);
1381 if_builder->Then();
1382
1383 IfBuilder js_array_check(this);
1384
1385 if (!IsExternalArrayElementsKind(handle_as_kind)) {
1386 js_array_check.If<HCompareNumericAndBranch>(
1387 instance_type, Add<HConstant>(JS_ARRAY_TYPE), Token::EQ);
1388 }
1389
1390 js_array_check.Then();
1391 if (!IsExternalArrayElementsKind(handle_as_kind)) {
Toon Verwaest 2013/12/04 17:29:26 It's hard to understand what kind of graph is crea
danno 2014/06/06 15:43:50 Done.
1392 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL,
1393 true, handle_as_kind,
1394 false, NEVER_RETURN_HOLE,
1395 STANDARD_STORE));
1396 } else {
1397 Push(graph()->GetConstant0());
1398 }
1399
1400 js_array_check.Else();
1401 Push(BuildUncheckedMonomorphicElementAccess(receiver, key, NULL,
1402 false, handle_as_kind,
1403 false, NEVER_RETURN_HOLE,
1404 STANDARD_STORE));
1405 }
1406
1407
1408 HValue* CodeStubGraphBuilder<KeyedLoadGenericElementStub>::BuildCodeStub() {
1409 HValue* receiver = GetParameter(0);
1410 HValue* key = GetParameter(1);
1411
1412 // Split into a smi/integer case and unique string case.
1413 HIfContinuation index_name_split_continuation(graph()->CreateBasicBlock(),
1414 graph()->CreateBasicBlock());
1415
1416 BuildKeyedIndexCheck(key, &index_name_split_continuation);
1417
1418 IfBuilder index_name_split(this, &index_name_split_continuation);
1419 index_name_split.Then();
1420 {
1421 // Key is an index (number)
1422 key = Pop();
1423
1424 int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) |
1425 (1 << Map::kHasIndexedInterceptor);
1426 BuildReceiverCheck(receiver, bit_field_mask);
Toon Verwaest 2013/12/04 17:29:26 Can we pull these 2 checks out of the continuation
danno 2014/06/06 15:43:50 No, these can't be moved since they are different
1427
1428 HValue* map = Add<HLoadNamedField>(receiver, HObjectAccess::ForMap());
1429
1430 HValue* instance_type =
1431 Add<HLoadNamedField>(map, HObjectAccess::ForMapInstanceType());
1432
1433 HValue* bit_field2 = Add<HLoadNamedField>(map,
1434 HObjectAccess::ForMapBitField2());
1435
1436 IfBuilder kind_if(this);
1437 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1438 FAST_DOUBLE_ELEMENTS, FAST_HOLEY_ELEMENTS);
1439
1440 kind_if.Else();
1441 {
1442 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1443 DICTIONARY_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS);
1444 }
1445 kind_if.Else();
1446 {
1447 int non_strict_elements_kind =
1448 NON_STRICT_ARGUMENTS_ELEMENTS << Map::kElementsKindShift;
1449 HValue* dictionary_limit = Add<HConstant>(non_strict_elements_kind);
1450 kind_if.If<HCompareNumericAndBranch>(bit_field2, dictionary_limit,
1451 Token::LT);
1452 }
1453 kind_if.Then();
1454 {
1455 HValue* elements = AddLoadElements(receiver);
1456
1457 HValue* hash = BuildElementIndexHash(key);
1458
1459 Push(BuildUncheckedDictionaryElementLoad(receiver, elements, key, hash));
1460 }
1461 // Non-strict elements are not handled.
1462 kind_if.Else();
1463
1464 HValue* non_strict_limit =
1465 Add<HConstant>(EXTERNAL_BYTE_ELEMENTS << Map::kElementsKindShift);
1466 DeoptimizeIf<HCompareNumericAndBranch>(
1467 bit_field2, non_strict_limit, Token::LT,
1468 "non-strict argument elements in KeyedLoadGenericElementStub");
1469
1470 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1471 EXTERNAL_UNSIGNED_BYTE_ELEMENTS,
1472 EXTERNAL_BYTE_ELEMENTS);
1473
1474 kind_if.Else();
1475 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1476 EXTERNAL_SHORT_ELEMENTS,
1477 EXTERNAL_UNSIGNED_BYTE_ELEMENTS);
1478
1479 kind_if.Else();
1480 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1481 EXTERNAL_UNSIGNED_SHORT_ELEMENTS,
1482 EXTERNAL_SHORT_ELEMENTS);
1483
1484 kind_if.Else();
1485 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1486 EXTERNAL_INT_ELEMENTS,
1487 EXTERNAL_UNSIGNED_SHORT_ELEMENTS);
1488
1489 kind_if.Else();
1490 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1491 EXTERNAL_UNSIGNED_INT_ELEMENTS,
1492 EXTERNAL_INT_ELEMENTS);
1493
1494 kind_if.Else();
1495 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1496 EXTERNAL_FLOAT_ELEMENTS,
1497 EXTERNAL_UNSIGNED_INT_ELEMENTS);
1498
1499 kind_if.Else();
1500 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1501 EXTERNAL_DOUBLE_ELEMENTS, EXTERNAL_FLOAT_ELEMENTS);
1502
1503 kind_if.Else();
1504 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1505 EXTERNAL_PIXEL_ELEMENTS, EXTERNAL_DOUBLE_ELEMENTS);
1506
1507 kind_if.Else();
1508 BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
1509 static_cast<ElementsKind>(EXTERNAL_PIXEL_ELEMENTS + 1),
1510 EXTERNAL_PIXEL_ELEMENTS);
1511
1512 kind_if.ElseDeopt("ElementsKind unhandled in KeyedLoadGenericElementStub");
1513
1514 kind_if.End();
1515 }
1516 index_name_split.Else();
1517 {
1518 // Key is a unique string.
1519 key = Pop();
1520
1521 int bit_field_mask = (1 << Map::kIsAccessCheckNeeded) |
1522 (1 << Map::kHasNamedInterceptor);
1523 BuildReceiverCheck(receiver, bit_field_mask);
1524
1525 HIfContinuation continuation;
1526 BuildCheckForDictionaryProperties(receiver, &continuation);
1527 IfBuilder if_dict_properties(this, &continuation);
1528 if_dict_properties.Then();
1529 {
1530 // Key is string, properties are dictionary mode
1531 BuildGlobalInstanceTypeCheck(receiver);
1532
1533 HValue* properties = Add<HLoadNamedField>(
1534 receiver, HObjectAccess::ForPropertiesPointer());
1535
1536 HValue* hash =
1537 Add<HLoadNamedField>(key, HObjectAccess::ForNameHashField());
1538
1539 HValue* value = BuildUncheckedDictionaryElementLoad(receiver,
1540 properties,
1541 key,
1542 hash);
1543 Push(value);
1544 }
1545 if_dict_properties.Else();
1546 {
1547 // Key is string, properties are fast mode
1548 HValue* hash = BuildKeyedLookupCacheHash(receiver, key);
1549
1550 ExternalReference cache_keys_ref =
1551 ExternalReference::keyed_lookup_cache_keys(isolate());
1552 HValue* cache_keys = Add<HConstant>(cache_keys_ref);
1553
1554 HValue* map = Add<HLoadNamedField>(receiver, HObjectAccess::ForMap());
1555 HValue* base_index = AddUncasted<HMul>(hash, Add<HConstant>(2));
1556 base_index->ClearFlag(HValue::kCanOverflow);
1557
1558 IfBuilder lookup_if(this);
1559 for (int probe = 0; probe < KeyedLookupCache::kEntriesPerBucket;
1560 ++probe) {
1561 HValue* map_index = AddUncasted<HAdd>(base_index,
1562 Add<HConstant>(probe * 2));
1563 map_index->ClearFlag(HValue::kCanOverflow);
1564 HValue* key_index = AddUncasted<HAdd>(base_index,
1565 Add<HConstant>(probe * 2 + 1));
1566 key_index->ClearFlag(HValue::kCanOverflow);
1567 HValue* map_to_check = Add<HLoadKeyed>(cache_keys,
1568 map_index,
1569 static_cast<HValue*>(NULL),
1570 FAST_ELEMENTS,
1571 NEVER_RETURN_HOLE, 0);
1572 lookup_if.If<HCompareObjectEqAndBranch>(map_to_check, map);
1573 lookup_if.And();
1574 HValue* key_to_check = Add<HLoadKeyed>(cache_keys,
1575 key_index,
1576 static_cast<HValue*>(NULL),
1577 FAST_ELEMENTS,
1578 NEVER_RETURN_HOLE, 0);
1579 lookup_if.If<HCompareObjectEqAndBranch>(key_to_check, key);
1580 lookup_if.Then();
1581 {
1582 ExternalReference cache_field_offsets_ref =
1583 ExternalReference::keyed_lookup_cache_field_offsets(isolate());
1584 HValue* cache_field_offsets = Add<HConstant>(cache_field_offsets_ref);
1585 HValue* index = AddUncasted<HAdd>(hash,
1586 Add<HConstant>(probe));
1587 index->ClearFlag(HValue::kCanOverflow);
1588 HValue* property_index = Add<HLoadKeyed>(cache_field_offsets,
1589 index,
1590 static_cast<HValue*>(NULL),
1591 EXTERNAL_INT_ELEMENTS,
1592 NEVER_RETURN_HOLE, 0);
1593 Push(property_index);
1594 }
1595 lookup_if.Else();
1596 }
1597 Add<HDeoptimize>("KeyedLoad fall-back", Deoptimizer::EAGER);
1598 Push(graph()->GetConstant0());
1599 lookup_if.End();
1600 Push(Add<HLoadFieldByIndex>(receiver, Pop()));
1601 }
1602 if_dict_properties.End();
1603 }
1604 index_name_split.End();
1605
1606 return Pop();
1607 }
1608
1609
1610 Handle<Code> KeyedLoadGenericElementStub::GenerateCode(Isolate* isolate) {
1611 return DoGenerateCode(isolate, this);
1612 }
1613
1614
1340 } } // namespace v8::internal 1615 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698