| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 #undef DEFINE_COMPILE | 53 #undef DEFINE_COMPILE |
| 54 | 54 |
| 55 | 55 |
| 56 const char* Representation::Mnemonic() const { | 56 const char* Representation::Mnemonic() const { |
| 57 switch (kind_) { | 57 switch (kind_) { |
| 58 case kNone: return "v"; | 58 case kNone: return "v"; |
| 59 case kTagged: return "t"; | 59 case kTagged: return "t"; |
| 60 case kDouble: return "d"; | 60 case kDouble: return "d"; |
| 61 case kInteger32: return "i"; | 61 case kInteger32: return "i"; |
| 62 case kExternal: return "x"; | 62 case kExternal: return "x"; |
| 63 case kNumRepresentations: | 63 default: |
| 64 UNREACHABLE(); | 64 UNREACHABLE(); |
| 65 return NULL; | 65 return NULL; |
| 66 } | 66 } |
| 67 UNREACHABLE(); | 67 } |
| 68 return NULL; | 68 |
| 69 |
| 70 void HValue::AssumeRepresentation(Representation r) { |
| 71 if (CheckFlag(kFlexibleRepresentation)) { |
| 72 ChangeRepresentation(r); |
| 73 // The representation of the value is dictated by type feedback and |
| 74 // will not be changed later. |
| 75 ClearFlag(kFlexibleRepresentation); |
| 76 } |
| 69 } | 77 } |
| 70 | 78 |
| 71 | 79 |
| 72 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { | 80 static int32_t ConvertAndSetOverflow(int64_t result, bool* overflow) { |
| 73 if (result > kMaxInt) { | 81 if (result > kMaxInt) { |
| 74 *overflow = true; | 82 *overflow = true; |
| 75 return kMaxInt; | 83 return kMaxInt; |
| 76 } | 84 } |
| 77 if (result < kMinInt) { | 85 if (result < kMinInt) { |
| 78 *overflow = true; | 86 *overflow = true; |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 #define MAKE_CASE(type) case k##type: return #type; | 359 #define MAKE_CASE(type) case k##type: return #type; |
| 352 HYDROGEN_CONCRETE_INSTRUCTION_LIST(MAKE_CASE) | 360 HYDROGEN_CONCRETE_INSTRUCTION_LIST(MAKE_CASE) |
| 353 #undef MAKE_CASE | 361 #undef MAKE_CASE |
| 354 case kPhi: return "Phi"; | 362 case kPhi: return "Phi"; |
| 355 default: return ""; | 363 default: return ""; |
| 356 } | 364 } |
| 357 } | 365 } |
| 358 | 366 |
| 359 | 367 |
| 360 void HValue::SetOperandAt(int index, HValue* value) { | 368 void HValue::SetOperandAt(int index, HValue* value) { |
| 361 ASSERT(value == NULL || !value->representation().IsNone()); | |
| 362 RegisterUse(index, value); | 369 RegisterUse(index, value); |
| 363 InternalSetOperandAt(index, value); | 370 InternalSetOperandAt(index, value); |
| 364 } | 371 } |
| 365 | 372 |
| 366 | 373 |
| 367 void HValue::DeleteAndReplaceWith(HValue* other) { | 374 void HValue::DeleteAndReplaceWith(HValue* other) { |
| 368 // We replace all uses first, so Delete can assert that there are none. | 375 // We replace all uses first, so Delete can assert that there are none. |
| 369 if (other != NULL) ReplaceAllUsesWith(other); | 376 if (other != NULL) ReplaceAllUsesWith(other); |
| 370 ASSERT(HasNoUses()); | 377 ASSERT(HasNoUses()); |
| 371 ClearOperands(); | 378 ClearOperands(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 395 | 402 |
| 396 void HValue::SetBlock(HBasicBlock* block) { | 403 void HValue::SetBlock(HBasicBlock* block) { |
| 397 ASSERT(block_ == NULL || block == NULL); | 404 ASSERT(block_ == NULL || block == NULL); |
| 398 block_ = block; | 405 block_ = block; |
| 399 if (id_ == kNoNumber && block != NULL) { | 406 if (id_ == kNoNumber && block != NULL) { |
| 400 id_ = block->graph()->GetNextValueID(this); | 407 id_ = block->graph()->GetNextValueID(this); |
| 401 } | 408 } |
| 402 } | 409 } |
| 403 | 410 |
| 404 | 411 |
| 405 void HValue::PrintTypeTo(HType type, StringStream* stream) { | 412 void HValue::PrintTypeTo(StringStream* stream) { |
| 406 stream->Add(type.ToShortString()); | 413 if (!representation().IsTagged() || type().Equals(HType::Tagged())) return; |
| 414 stream->Add(" type[%s]", type().ToString()); |
| 415 } |
| 416 |
| 417 |
| 418 void HValue::PrintRangeTo(StringStream* stream) { |
| 419 if (range() == NULL || range()->IsMostGeneric()) return; |
| 420 stream->Add(" range[%d,%d,m0=%d]", |
| 421 range()->lower(), |
| 422 range()->upper(), |
| 423 static_cast<int>(range()->CanBeMinusZero())); |
| 424 } |
| 425 |
| 426 |
| 427 void HValue::PrintChangesTo(StringStream* stream) { |
| 428 int changes_flags = (flags() & HValue::ChangesFlagsMask()); |
| 429 if (changes_flags == 0) return; |
| 430 stream->Add(" changes["); |
| 431 if (changes_flags == AllSideEffects()) { |
| 432 stream->Add("*"); |
| 433 } else { |
| 434 bool add_comma = false; |
| 435 #define PRINT_DO(type) \ |
| 436 if (changes_flags & (1 << kChanges##type)) { \ |
| 437 if (add_comma) stream->Add(","); \ |
| 438 add_comma = true; \ |
| 439 stream->Add(#type); \ |
| 440 } |
| 441 GVN_FLAG_LIST(PRINT_DO); |
| 442 #undef PRINT_DO |
| 443 } |
| 444 stream->Add("]"); |
| 407 } | 445 } |
| 408 | 446 |
| 409 | 447 |
| 410 void HValue::PrintNameTo(StringStream* stream) { | 448 void HValue::PrintNameTo(StringStream* stream) { |
| 411 stream->Add("%s%d", representation_.Mnemonic(), id()); | 449 stream->Add("%s%d", representation_.Mnemonic(), id()); |
| 412 } | 450 } |
| 413 | 451 |
| 414 | 452 |
| 415 bool HValue::UpdateInferredType() { | 453 bool HValue::UpdateInferredType() { |
| 416 HType type = CalculateInferredType(); | 454 HType type = CalculateInferredType(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 | 496 |
| 459 | 497 |
| 460 void HValue::ComputeInitialRange() { | 498 void HValue::ComputeInitialRange() { |
| 461 ASSERT(!HasRange()); | 499 ASSERT(!HasRange()); |
| 462 range_ = InferRange(); | 500 range_ = InferRange(); |
| 463 ASSERT(HasRange()); | 501 ASSERT(HasRange()); |
| 464 } | 502 } |
| 465 | 503 |
| 466 | 504 |
| 467 void HInstruction::PrintTo(StringStream* stream) { | 505 void HInstruction::PrintTo(StringStream* stream) { |
| 506 PrintMnemonicTo(stream); |
| 507 PrintDataTo(stream); |
| 508 PrintRangeTo(stream); |
| 509 PrintChangesTo(stream); |
| 510 PrintTypeTo(stream); |
| 511 } |
| 512 |
| 513 |
| 514 void HInstruction::PrintMnemonicTo(StringStream* stream) { |
| 468 stream->Add("%s", Mnemonic()); | 515 stream->Add("%s", Mnemonic()); |
| 469 if (HasSideEffects()) stream->Add("*"); | 516 if (HasSideEffects()) stream->Add("*"); |
| 470 stream->Add(" "); | 517 stream->Add(" "); |
| 471 PrintDataTo(stream); | |
| 472 | |
| 473 if (range() != NULL && | |
| 474 !range()->IsMostGeneric() && | |
| 475 !range()->CanBeMinusZero()) { | |
| 476 stream->Add(" range[%d,%d,m0=%d]", | |
| 477 range()->lower(), | |
| 478 range()->upper(), | |
| 479 static_cast<int>(range()->CanBeMinusZero())); | |
| 480 } | |
| 481 | |
| 482 int changes_flags = (flags() & HValue::ChangesFlagsMask()); | |
| 483 if (changes_flags != 0) { | |
| 484 stream->Add(" changes[0x%x]", changes_flags); | |
| 485 } | |
| 486 | |
| 487 if (representation().IsTagged() && !type().Equals(HType::Tagged())) { | |
| 488 stream->Add(" type[%s]", type().ToString()); | |
| 489 } | |
| 490 } | 518 } |
| 491 | 519 |
| 492 | 520 |
| 493 void HInstruction::Unlink() { | 521 void HInstruction::Unlink() { |
| 494 ASSERT(IsLinked()); | 522 ASSERT(IsLinked()); |
| 495 ASSERT(!IsControlInstruction()); // Must never move control instructions. | 523 ASSERT(!IsControlInstruction()); // Must never move control instructions. |
| 496 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these. | 524 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these. |
| 497 ASSERT(previous_ != NULL); | 525 ASSERT(previous_ != NULL); |
| 498 previous_->next_ = next_; | 526 previous_->next_ = next_; |
| 499 if (next_ == NULL) { | 527 if (next_ == NULL) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 HInstruction* cur = cur_block->first(); | 592 HInstruction* cur = cur_block->first(); |
| 565 while (cur != NULL) { | 593 while (cur != NULL) { |
| 566 ASSERT(cur != this); // We should reach other_operand before! | 594 ASSERT(cur != this); // We should reach other_operand before! |
| 567 if (cur == other_operand) break; | 595 if (cur == other_operand) break; |
| 568 cur = cur->next(); | 596 cur = cur->next(); |
| 569 } | 597 } |
| 570 // Must reach other operand in the same block! | 598 // Must reach other operand in the same block! |
| 571 ASSERT(cur == other_operand); | 599 ASSERT(cur == other_operand); |
| 572 } | 600 } |
| 573 } else { | 601 } else { |
| 602 // If the following assert fires, you may have forgotten an |
| 603 // AddInstruction. |
| 574 ASSERT(other_block->Dominates(cur_block)); | 604 ASSERT(other_block->Dominates(cur_block)); |
| 575 } | 605 } |
| 576 } | 606 } |
| 577 | 607 |
| 578 // Verify that instructions that may have side-effects are followed | 608 // Verify that instructions that may have side-effects are followed |
| 579 // by a simulate instruction. | 609 // by a simulate instruction. |
| 580 if (HasSideEffects() && !IsOsrEntry()) { | 610 if (HasSideEffects() && !IsOsrEntry()) { |
| 581 ASSERT(next()->IsSimulate()); | 611 ASSERT(next()->IsSimulate()); |
| 582 } | 612 } |
| 583 | 613 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 | 774 |
| 745 void HChange::PrintDataTo(StringStream* stream) { | 775 void HChange::PrintDataTo(StringStream* stream) { |
| 746 HUnaryOperation::PrintDataTo(stream); | 776 HUnaryOperation::PrintDataTo(stream); |
| 747 stream->Add(" %s to %s", from_.Mnemonic(), to().Mnemonic()); | 777 stream->Add(" %s to %s", from_.Mnemonic(), to().Mnemonic()); |
| 748 | 778 |
| 749 if (CanTruncateToInt32()) stream->Add(" truncating-int32"); | 779 if (CanTruncateToInt32()) stream->Add(" truncating-int32"); |
| 750 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 780 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
| 751 } | 781 } |
| 752 | 782 |
| 753 | 783 |
| 754 HCheckInstanceType* HCheckInstanceType::NewIsJSObjectOrJSFunction( | 784 void HCheckInstanceType::GetCheckInterval(InstanceType* first, |
| 755 HValue* value) { | 785 InstanceType* last) { |
| 756 STATIC_ASSERT((LAST_JS_OBJECT_TYPE + 1) == JS_FUNCTION_TYPE); | 786 ASSERT(is_interval_check()); |
| 757 return new HCheckInstanceType(value, FIRST_JS_OBJECT_TYPE, JS_FUNCTION_TYPE); | 787 switch (check_) { |
| 788 case IS_JS_OBJECT_OR_JS_FUNCTION: |
| 789 STATIC_ASSERT((LAST_JS_OBJECT_TYPE + 1) == JS_FUNCTION_TYPE); |
| 790 *first = FIRST_JS_OBJECT_TYPE; |
| 791 *last = JS_FUNCTION_TYPE; |
| 792 return; |
| 793 case IS_JS_ARRAY: |
| 794 *first = *last = JS_ARRAY_TYPE; |
| 795 return; |
| 796 default: |
| 797 UNREACHABLE(); |
| 798 } |
| 799 } |
| 800 |
| 801 |
| 802 void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) { |
| 803 ASSERT(!is_interval_check()); |
| 804 switch (check_) { |
| 805 case IS_STRING: |
| 806 *mask = kIsNotStringMask; |
| 807 *tag = kStringTag; |
| 808 return; |
| 809 case IS_SYMBOL: |
| 810 *mask = kIsSymbolMask; |
| 811 *tag = kSymbolTag; |
| 812 return; |
| 813 default: |
| 814 UNREACHABLE(); |
| 815 } |
| 758 } | 816 } |
| 759 | 817 |
| 760 | 818 |
| 761 void HCheckMap::PrintDataTo(StringStream* stream) { | 819 void HCheckMap::PrintDataTo(StringStream* stream) { |
| 762 value()->PrintNameTo(stream); | 820 value()->PrintNameTo(stream); |
| 763 stream->Add(" %p", *map()); | 821 stream->Add(" %p", *map()); |
| 764 } | 822 } |
| 765 | 823 |
| 766 | 824 |
| 767 void HCheckFunction::PrintDataTo(StringStream* stream) { | 825 void HCheckFunction::PrintDataTo(StringStream* stream) { |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 | 1314 |
| 1257 | 1315 |
| 1258 void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) { | 1316 void HLoadKeyedFastElement::PrintDataTo(StringStream* stream) { |
| 1259 object()->PrintNameTo(stream); | 1317 object()->PrintNameTo(stream); |
| 1260 stream->Add("["); | 1318 stream->Add("["); |
| 1261 key()->PrintNameTo(stream); | 1319 key()->PrintNameTo(stream); |
| 1262 stream->Add("]"); | 1320 stream->Add("]"); |
| 1263 } | 1321 } |
| 1264 | 1322 |
| 1265 | 1323 |
| 1324 bool HLoadKeyedFastElement::RequiresHoleCheck() const { |
| 1325 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
| 1326 HValue* use = it.value(); |
| 1327 if (!use->IsChange()) return true; |
| 1328 } |
| 1329 return false; |
| 1330 } |
| 1331 |
| 1332 |
| 1266 void HLoadKeyedGeneric::PrintDataTo(StringStream* stream) { | 1333 void HLoadKeyedGeneric::PrintDataTo(StringStream* stream) { |
| 1267 object()->PrintNameTo(stream); | 1334 object()->PrintNameTo(stream); |
| 1268 stream->Add("["); | 1335 stream->Add("["); |
| 1269 key()->PrintNameTo(stream); | 1336 key()->PrintNameTo(stream); |
| 1270 stream->Add("]"); | 1337 stream->Add("]"); |
| 1271 } | 1338 } |
| 1272 | 1339 |
| 1273 | 1340 |
| 1274 void HLoadKeyedSpecializedArrayElement::PrintDataTo( | 1341 void HLoadKeyedSpecializedArrayElement::PrintDataTo( |
| 1275 StringStream* stream) { | 1342 StringStream* stream) { |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1564 if (from().IsInteger32()) return NULL; | 1631 if (from().IsInteger32()) return NULL; |
| 1565 if (CanTruncateToInt32()) return NULL; | 1632 if (CanTruncateToInt32()) return NULL; |
| 1566 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { | 1633 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { |
| 1567 SetFlag(kBailoutOnMinusZero); | 1634 SetFlag(kBailoutOnMinusZero); |
| 1568 } | 1635 } |
| 1569 ASSERT(!from().IsInteger32() || !to().IsInteger32()); | 1636 ASSERT(!from().IsInteger32() || !to().IsInteger32()); |
| 1570 return NULL; | 1637 return NULL; |
| 1571 } | 1638 } |
| 1572 | 1639 |
| 1573 | 1640 |
| 1641 HValue* HForceRepresentation::EnsureAndPropagateNotMinusZero( |
| 1642 BitVector* visited) { |
| 1643 visited->Add(id()); |
| 1644 return value(); |
| 1645 } |
| 1646 |
| 1647 |
| 1574 HValue* HMod::EnsureAndPropagateNotMinusZero(BitVector* visited) { | 1648 HValue* HMod::EnsureAndPropagateNotMinusZero(BitVector* visited) { |
| 1575 visited->Add(id()); | 1649 visited->Add(id()); |
| 1576 if (range() == NULL || range()->CanBeMinusZero()) { | 1650 if (range() == NULL || range()->CanBeMinusZero()) { |
| 1577 SetFlag(kBailoutOnMinusZero); | 1651 SetFlag(kBailoutOnMinusZero); |
| 1578 return left(); | 1652 return left(); |
| 1579 } | 1653 } |
| 1580 return NULL; | 1654 return NULL; |
| 1581 } | 1655 } |
| 1582 | 1656 |
| 1583 | 1657 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1686 | 1760 |
| 1687 | 1761 |
| 1688 void HCheckPrototypeMaps::Verify() { | 1762 void HCheckPrototypeMaps::Verify() { |
| 1689 HInstruction::Verify(); | 1763 HInstruction::Verify(); |
| 1690 ASSERT(HasNoUses()); | 1764 ASSERT(HasNoUses()); |
| 1691 } | 1765 } |
| 1692 | 1766 |
| 1693 #endif | 1767 #endif |
| 1694 | 1768 |
| 1695 } } // namespace v8::internal | 1769 } } // namespace v8::internal |
| OLD | NEW |