OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 1387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1398 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, | 1398 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, |
1399 array_length, elements_length); | 1399 array_length, elements_length); |
1400 | 1400 |
1401 if_builder.End(); | 1401 if_builder.End(); |
1402 } | 1402 } |
1403 | 1403 |
1404 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); | 1404 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); |
1405 } | 1405 } |
1406 | 1406 |
1407 | 1407 |
| 1408 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoadHelper( |
| 1409 HValue* elements, |
| 1410 HValue* key, |
| 1411 HValue* hash, |
| 1412 HValue* mask, |
| 1413 int current_probe) { |
| 1414 if (current_probe == kNumberDictionaryProbes) { |
| 1415 return NULL; |
| 1416 } |
| 1417 |
| 1418 int32_t offset = SeededNumberDictionary::GetProbeOffset(current_probe); |
| 1419 HValue* raw_index = (current_probe == 0) |
| 1420 ? hash |
| 1421 : Add<HAdd>(hash, Add<HConstant>(offset)); |
| 1422 raw_index = Add<HBitwise>(Token::BIT_AND, raw_index, mask); |
| 1423 int32_t entry_size = SeededNumberDictionary::kEntrySize; |
| 1424 raw_index = Add<HMul>(raw_index, Add<HConstant>(entry_size)); |
| 1425 raw_index->ClearFlag(HValue::kCanOverflow); |
| 1426 |
| 1427 int32_t base_offset = SeededNumberDictionary::kElementsStartIndex; |
| 1428 HValue* key_index = Add<HAdd>(raw_index, Add<HConstant>(base_offset)); |
| 1429 key_index->ClearFlag(HValue::kCanOverflow); |
| 1430 |
| 1431 HValue* candidate_key = Add<HLoadKeyed>(elements, key_index, |
| 1432 static_cast<HValue*>(NULL), |
| 1433 FAST_SMI_ELEMENTS); |
| 1434 |
| 1435 IfBuilder key_compare(this); |
| 1436 key_compare.IfNot<HCompareObjectEqAndBranch>(key, candidate_key); |
| 1437 key_compare.Then(); |
| 1438 { |
| 1439 // Key at the current probe doesn't match, try at the next probe. |
| 1440 HValue* result = BuildUncheckedDictionaryElementLoadHelper( |
| 1441 elements, key, hash, mask, current_probe + 1); |
| 1442 if (result == NULL) { |
| 1443 key_compare.Deopt("probes exhausted in keyed load dictionary lookup"); |
| 1444 result = graph()->GetConstantUndefined(); |
| 1445 } else { |
| 1446 Push(result); |
| 1447 } |
| 1448 } |
| 1449 key_compare.Else(); |
| 1450 { |
| 1451 // Key at current probe matches. Details must be zero, otherwise the |
| 1452 // dictionary element requires special handling. |
| 1453 HValue* details_index = Add<HAdd>(raw_index, |
| 1454 Add<HConstant>(base_offset + 2)); |
| 1455 details_index->ClearFlag(HValue::kCanOverflow); |
| 1456 |
| 1457 HValue* details = Add<HLoadKeyed>(elements, details_index, |
| 1458 static_cast<HValue*>(NULL), |
| 1459 FAST_SMI_ELEMENTS); |
| 1460 IfBuilder details_compare(this); |
| 1461 details_compare.If<HCompareNumericAndBranch>(details, |
| 1462 graph()->GetConstant0(), |
| 1463 Token::NE); |
| 1464 details_compare.ThenDeopt("keyed load dictionary element not fast case"); |
| 1465 |
| 1466 details_compare.Else(); |
| 1467 { |
| 1468 // Key matches and details are zero --> fast case. Load and return the |
| 1469 // value. |
| 1470 HValue* result_index = Add<HAdd>(raw_index, |
| 1471 Add<HConstant>(base_offset + 1)); |
| 1472 result_index->ClearFlag(HValue::kCanOverflow); |
| 1473 |
| 1474 Push(Add<HLoadKeyed>(elements, result_index, |
| 1475 static_cast<HValue*>(NULL), |
| 1476 FAST_ELEMENTS)); |
| 1477 } |
| 1478 details_compare.End(); |
| 1479 } |
| 1480 key_compare.End(); |
| 1481 |
| 1482 return Pop(); |
| 1483 } |
| 1484 |
| 1485 |
| 1486 HValue* HGraphBuilder::BuildElementIndexHash(HValue* index) { |
| 1487 int32_t seed_value = static_cast<uint32_t>(isolate()->heap()->HashSeed()); |
| 1488 HValue* seed = Add<HConstant>(seed_value); |
| 1489 HValue* hash = Add<HBitwise>(Token::BIT_XOR, index, seed); |
| 1490 |
| 1491 // hash = ~hash + (hash << 15); |
| 1492 HValue* shifted_hash = Add<HShl>(hash, Add<HConstant>(15)); |
| 1493 HValue* not_hash = Add<HBitwise>(Token::BIT_XOR, hash, |
| 1494 graph()->GetConstantMinus1()); |
| 1495 hash = Add<HAdd>(shifted_hash, not_hash); |
| 1496 |
| 1497 // hash = hash ^ (hash >> 12); |
| 1498 shifted_hash = Add<HShr>(hash, Add<HConstant>(12)); |
| 1499 hash = Add<HBitwise>(Token::BIT_XOR, hash, shifted_hash); |
| 1500 |
| 1501 // hash = hash + (hash << 2); |
| 1502 shifted_hash = Add<HShl>(hash, Add<HConstant>(2)); |
| 1503 hash = Add<HAdd>(hash, shifted_hash); |
| 1504 |
| 1505 // hash = hash ^ (hash >> 4); |
| 1506 shifted_hash = Add<HShr>(hash, Add<HConstant>(4)); |
| 1507 hash = Add<HBitwise>(Token::BIT_XOR, hash, shifted_hash); |
| 1508 |
| 1509 // hash = hash * 2057; |
| 1510 hash = Add<HMul>(hash, Add<HConstant>(2057)); |
| 1511 hash->ClearFlag(HValue::kCanOverflow); |
| 1512 |
| 1513 // hash = hash ^ (hash >> 16); |
| 1514 shifted_hash = Add<HShr>(hash, Add<HConstant>(16)); |
| 1515 return Add<HBitwise>(Token::BIT_XOR, hash, shifted_hash); |
| 1516 } |
| 1517 |
| 1518 |
| 1519 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, |
| 1520 HValue* key) { |
| 1521 HValue* elements = AddLoadElements(receiver); |
| 1522 |
| 1523 HValue* hash = BuildElementIndexHash(key); |
| 1524 |
| 1525 HValue* capacity = Add<HLoadKeyed>( |
| 1526 elements, |
| 1527 Add<HConstant>(NameDictionary::kCapacityIndex), |
| 1528 static_cast<HValue*>(NULL), |
| 1529 FAST_SMI_ELEMENTS); |
| 1530 |
| 1531 HValue* mask = Add<HSub>(capacity, graph()->GetConstant1()); |
| 1532 mask->ChangeRepresentation(Representation::Integer32()); |
| 1533 mask->ClearFlag(HValue::kCanOverflow); |
| 1534 |
| 1535 return BuildUncheckedDictionaryElementLoadHelper(elements, key, |
| 1536 hash, mask, 0); |
| 1537 } |
| 1538 |
| 1539 |
1408 HValue* HGraphBuilder::BuildNumberToString(HValue* object, | 1540 HValue* HGraphBuilder::BuildNumberToString(HValue* object, |
1409 Handle<Type> type) { | 1541 Handle<Type> type) { |
1410 NoObservableSideEffectsScope scope(this); | 1542 NoObservableSideEffectsScope scope(this); |
1411 | 1543 |
1412 // Create a joinable continuation. | 1544 // Create a joinable continuation. |
1413 HIfContinuation found(graph()->CreateBasicBlock(), | 1545 HIfContinuation found(graph()->CreateBasicBlock(), |
1414 graph()->CreateBasicBlock()); | 1546 graph()->CreateBasicBlock()); |
1415 | 1547 |
1416 // Load the number string cache. | 1548 // Load the number string cache. |
1417 HValue* number_string_cache = | 1549 HValue* number_string_cache = |
(...skipping 9003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10421 if (ShouldProduceTraceOutput()) { | 10553 if (ShouldProduceTraceOutput()) { |
10422 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10554 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10423 } | 10555 } |
10424 | 10556 |
10425 #ifdef DEBUG | 10557 #ifdef DEBUG |
10426 graph_->Verify(false); // No full verify. | 10558 graph_->Verify(false); // No full verify. |
10427 #endif | 10559 #endif |
10428 } | 10560 } |
10429 | 10561 |
10430 } } // namespace v8::internal | 10562 } } // namespace v8::internal |
OLD | NEW |