OLD | NEW |
---|---|
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 1490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1501 expected_input_types_(expected_input_types) { | 1501 expected_input_types_(expected_input_types) { |
1502 SetFlag(kAllowUndefinedAsNaN); | 1502 SetFlag(kAllowUndefinedAsNaN); |
1503 } | 1503 } |
1504 | 1504 |
1505 ToBooleanStub::Types expected_input_types_; | 1505 ToBooleanStub::Types expected_input_types_; |
1506 }; | 1506 }; |
1507 | 1507 |
1508 | 1508 |
1509 class HCompareMap V8_FINAL : public HUnaryControlInstruction { | 1509 class HCompareMap V8_FINAL : public HUnaryControlInstruction { |
1510 public: | 1510 public: |
1511 DECLARE_INSTRUCTION_FACTORY_P2(HCompareMap, HValue*, Handle<Map>); | 1511 DECLARE_INSTRUCTION_FACTORY_P3(HCompareMap, HValue*, Handle<Map>, |
1512 DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>, | 1512 CompilationInfo*); |
1513 DECLARE_INSTRUCTION_FACTORY_P5(HCompareMap, HValue*, Handle<Map>, | |
1514 CompilationInfo*, | |
1513 HBasicBlock*, HBasicBlock*); | 1515 HBasicBlock*, HBasicBlock*); |
1514 | 1516 |
1515 virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE { | 1517 virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE { |
1516 if (known_successor_index() != kNoKnownSuccessorIndex) { | 1518 if (known_successor_index() != kNoKnownSuccessorIndex) { |
1517 *block = SuccessorAt(known_successor_index()); | 1519 *block = SuccessorAt(known_successor_index()); |
1518 return true; | 1520 return true; |
1519 } | 1521 } |
1520 *block = NULL; | 1522 *block = NULL; |
1521 return false; | 1523 return false; |
1522 } | 1524 } |
1523 | 1525 |
1524 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 1526 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
1525 | 1527 |
1526 static const int kNoKnownSuccessorIndex = -1; | 1528 static const int kNoKnownSuccessorIndex = -1; |
1527 int known_successor_index() const { return known_successor_index_; } | 1529 int known_successor_index() const { return known_successor_index_; } |
1528 void set_known_successor_index(int known_successor_index) { | 1530 void set_known_successor_index(int known_successor_index) { |
1529 known_successor_index_ = known_successor_index; | 1531 known_successor_index_ = known_successor_index; |
1530 } | 1532 } |
1531 | 1533 |
1532 Unique<Map> map() const { return map_; } | 1534 Unique<Map> map() const { return map_; } |
1533 | 1535 |
1534 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 1536 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1535 return Representation::Tagged(); | 1537 return Representation::Tagged(); |
1536 } | 1538 } |
1537 | 1539 |
1540 bool is_stable() const { | |
1541 return is_stable_; | |
1542 } | |
1543 | |
1538 DECLARE_CONCRETE_INSTRUCTION(CompareMap) | 1544 DECLARE_CONCRETE_INSTRUCTION(CompareMap) |
1539 | 1545 |
1540 protected: | 1546 protected: |
1541 virtual int RedefinedOperandIndex() { return 0; } | 1547 virtual int RedefinedOperandIndex() { return 0; } |
1542 | 1548 |
1543 private: | 1549 private: |
1544 HCompareMap(HValue* value, | 1550 HCompareMap(HValue* value, |
1545 Handle<Map> map, | 1551 Handle<Map> map, |
1552 CompilationInfo* info, | |
1546 HBasicBlock* true_target = NULL, | 1553 HBasicBlock* true_target = NULL, |
1547 HBasicBlock* false_target = NULL) | 1554 HBasicBlock* false_target = NULL) |
1548 : HUnaryControlInstruction(value, true_target, false_target), | 1555 : HUnaryControlInstruction(value, true_target, false_target), |
1549 known_successor_index_(kNoKnownSuccessorIndex), map_(Unique<Map>(map)) { | 1556 known_successor_index_(kNoKnownSuccessorIndex), map_(Unique<Map>(map)) { |
1550 ASSERT(!map.is_null()); | 1557 ASSERT(!map.is_null()); |
1558 is_stable_ = map->is_stable(); | |
1559 | |
1560 if (is_stable_) { | |
1561 map->AddDependentCompilationInfo( | |
1562 DependentCode::kPrototypeCheckGroup, info); | |
1563 } | |
1551 } | 1564 } |
1552 | 1565 |
1553 int known_successor_index_; | 1566 int known_successor_index_; |
1567 bool is_stable_; | |
1554 Unique<Map> map_; | 1568 Unique<Map> map_; |
1555 }; | 1569 }; |
1556 | 1570 |
1557 | 1571 |
1558 class HContext V8_FINAL : public HTemplateInstruction<0> { | 1572 class HContext V8_FINAL : public HTemplateInstruction<0> { |
1559 public: | 1573 public: |
1560 static HContext* New(Zone* zone) { | 1574 static HContext* New(Zone* zone) { |
1561 return new(zone) HContext(); | 1575 return new(zone) HContext(); |
1562 } | 1576 } |
1563 | 1577 |
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2626 }; | 2640 }; |
2627 | 2641 |
2628 | 2642 |
2629 class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { | 2643 class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { |
2630 public: | 2644 public: |
2631 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, | 2645 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, |
2632 Handle<Map> map, CompilationInfo* info, | 2646 Handle<Map> map, CompilationInfo* info, |
2633 HValue* typecheck = NULL); | 2647 HValue* typecheck = NULL); |
2634 static HCheckMaps* New(Zone* zone, HValue* context, | 2648 static HCheckMaps* New(Zone* zone, HValue* context, |
2635 HValue* value, SmallMapList* maps, | 2649 HValue* value, SmallMapList* maps, |
2650 CompilationInfo* info, | |
2636 HValue* typecheck = NULL) { | 2651 HValue* typecheck = NULL) { |
2637 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); | 2652 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); |
2638 for (int i = 0; i < maps->length(); i++) { | 2653 for (int i = 0; i < maps->length(); i++) { |
2639 check_map->Add(maps->at(i), zone); | 2654 check_map->Add(maps->at(i), info, zone); |
2640 } | 2655 } |
2641 return check_map; | 2656 return check_map; |
2642 } | 2657 } |
2643 | 2658 |
2644 bool CanOmitMapChecks() { return omit_; } | 2659 bool CanOmitMapChecks() { return omit_; } |
2645 | 2660 |
2646 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } | 2661 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } |
2647 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2662 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
2648 return Representation::Tagged(); | 2663 return Representation::Tagged(); |
2649 } | 2664 } |
(...skipping 11 matching lines...) Expand all Loading... | |
2661 map_set_.Clear(); | 2676 map_set_.Clear(); |
2662 for (int i = 0; i < maps->size(); i++) { | 2677 for (int i = 0; i < maps->size(); i++) { |
2663 map_set_.Add(maps->at(i), zone); | 2678 map_set_.Add(maps->at(i), zone); |
2664 } | 2679 } |
2665 } | 2680 } |
2666 | 2681 |
2667 bool has_migration_target() const { | 2682 bool has_migration_target() const { |
2668 return has_migration_target_; | 2683 return has_migration_target_; |
2669 } | 2684 } |
2670 | 2685 |
2686 bool is_stable() const { | |
2687 return is_stable_; | |
2688 } | |
2689 | |
2671 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) | 2690 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
2672 | 2691 |
2673 protected: | 2692 protected: |
2674 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 2693 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
2675 return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_); | 2694 return this->map_set_.Equals(&HCheckMaps::cast(other)->map_set_); |
2676 } | 2695 } |
2677 | 2696 |
2678 virtual int RedefinedOperandIndex() { return 0; } | 2697 virtual int RedefinedOperandIndex() { return 0; } |
2679 | 2698 |
2680 private: | 2699 private: |
2681 void Add(Handle<Map> map, Zone* zone) { | 2700 void Add(Handle<Map> map, CompilationInfo* info, Zone* zone) { |
2682 map_set_.Add(Unique<Map>(map), zone); | 2701 map_set_.Add(Unique<Map>(map), zone); |
2702 is_stable_ = is_stable_ && map->is_stable(); | |
2703 | |
2704 if (is_stable_) { | |
2705 map->AddDependentCompilationInfo( | |
2706 DependentCode::kPrototypeCheckGroup, info); | |
2707 } | |
Igor Sheludko
2014/02/12 11:39:40
If all but the last map we are adding are stable t
Toon Verwaest
2014/02/12 14:53:34
I think it's a fine approximation for now. We can
| |
2708 | |
2683 if (!has_migration_target_ && map->is_migration_target()) { | 2709 if (!has_migration_target_ && map->is_migration_target()) { |
2684 has_migration_target_ = true; | 2710 has_migration_target_ = true; |
2685 SetChangesFlag(kNewSpacePromotion); | 2711 SetChangesFlag(kNewSpacePromotion); |
2686 } | 2712 } |
2687 } | 2713 } |
2688 | 2714 |
2689 // Clients should use one of the static New* methods above. | 2715 // Clients should use one of the static New* methods above. |
2690 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) | 2716 HCheckMaps(HValue* value, Zone *zone, HValue* typecheck) |
2691 : HTemplateInstruction<2>(value->type()), | 2717 : HTemplateInstruction<2>(value->type()), |
2692 omit_(false), has_migration_target_(false) { | 2718 omit_(false), has_migration_target_(false), is_stable_(true) { |
2693 SetOperandAt(0, value); | 2719 SetOperandAt(0, value); |
2694 // Use the object value for the dependency if NULL is passed. | 2720 // Use the object value for the dependency if NULL is passed. |
2695 SetOperandAt(1, typecheck != NULL ? typecheck : value); | 2721 SetOperandAt(1, typecheck != NULL ? typecheck : value); |
2696 set_representation(Representation::Tagged()); | 2722 set_representation(Representation::Tagged()); |
2697 SetFlag(kUseGVN); | 2723 SetFlag(kUseGVN); |
2698 SetFlag(kTrackSideEffectDominators); | 2724 SetFlag(kTrackSideEffectDominators); |
2699 SetDependsOnFlag(kMaps); | 2725 SetDependsOnFlag(kMaps); |
2700 SetDependsOnFlag(kElementsKind); | 2726 SetDependsOnFlag(kElementsKind); |
2701 } | 2727 } |
2702 | 2728 |
2703 bool omit_; | 2729 bool omit_; |
2704 bool has_migration_target_; | 2730 bool has_migration_target_; |
2731 bool is_stable_; | |
2705 UniqueSet<Map> map_set_; | 2732 UniqueSet<Map> map_set_; |
2706 }; | 2733 }; |
2707 | 2734 |
2708 | 2735 |
2709 class HCheckValue V8_FINAL : public HUnaryOperation { | 2736 class HCheckValue V8_FINAL : public HUnaryOperation { |
2710 public: | 2737 public: |
2711 static HCheckValue* New(Zone* zone, HValue* context, | 2738 static HCheckValue* New(Zone* zone, HValue* context, |
2712 HValue* value, Handle<JSFunction> func) { | 2739 HValue* value, Handle<JSFunction> func) { |
2713 bool in_new_space = zone->isolate()->heap()->InNewSpace(*func); | 2740 bool in_new_space = zone->isolate()->heap()->InNewSpace(*func); |
2714 // NOTE: We create an uninitialized Unique and initialize it later. | 2741 // NOTE: We create an uninitialized Unique and initialize it later. |
(...skipping 3755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6470 } | 6497 } |
6471 | 6498 |
6472 void SetTransition(HConstant* map_constant, CompilationInfo* info) { | 6499 void SetTransition(HConstant* map_constant, CompilationInfo* info) { |
6473 ASSERT(!has_transition()); // Only set once. | 6500 ASSERT(!has_transition()); // Only set once. |
6474 Handle<Map> map = Handle<Map>::cast(map_constant->handle(info->isolate())); | 6501 Handle<Map> map = Handle<Map>::cast(map_constant->handle(info->isolate())); |
6475 if (map->CanBeDeprecated()) { | 6502 if (map->CanBeDeprecated()) { |
6476 map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info); | 6503 map->AddDependentCompilationInfo(DependentCode::kTransitionGroup, info); |
6477 } | 6504 } |
6478 SetOperandAt(2, map_constant); | 6505 SetOperandAt(2, map_constant); |
6479 has_transition_ = true; | 6506 has_transition_ = true; |
6507 is_stable_ = map->is_stable(); | |
6508 if (is_stable_) { | |
6509 map->AddDependentCompilationInfo( | |
6510 DependentCode::kPrototypeCheckGroup, info); | |
6511 } | |
6512 } | |
6513 | |
6514 bool is_stable() const { | |
6515 return is_stable_; | |
6480 } | 6516 } |
6481 | 6517 |
6482 bool NeedsWriteBarrier() { | 6518 bool NeedsWriteBarrier() { |
6483 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || | 6519 ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) || |
6484 !has_transition()); | 6520 !has_transition()); |
6485 if (IsSkipWriteBarrier()) return false; | 6521 if (IsSkipWriteBarrier()) return false; |
6486 if (field_representation().IsDouble()) return false; | 6522 if (field_representation().IsDouble()) return false; |
6487 if (field_representation().IsSmi()) return false; | 6523 if (field_representation().IsSmi()) return false; |
6488 if (field_representation().IsInteger32()) return false; | 6524 if (field_representation().IsInteger32()) return false; |
6489 if (field_representation().IsExternal()) return false; | 6525 if (field_representation().IsExternal()) return false; |
(...skipping 18 matching lines...) Expand all Loading... | |
6508 | 6544 |
6509 private: | 6545 private: |
6510 HStoreNamedField(HValue* obj, | 6546 HStoreNamedField(HValue* obj, |
6511 HObjectAccess access, | 6547 HObjectAccess access, |
6512 HValue* val, | 6548 HValue* val, |
6513 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE) | 6549 StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE) |
6514 : access_(access), | 6550 : access_(access), |
6515 new_space_dominator_(NULL), | 6551 new_space_dominator_(NULL), |
6516 write_barrier_mode_(UPDATE_WRITE_BARRIER), | 6552 write_barrier_mode_(UPDATE_WRITE_BARRIER), |
6517 has_transition_(false), | 6553 has_transition_(false), |
6554 is_stable_(false), | |
6518 store_mode_(store_mode) { | 6555 store_mode_(store_mode) { |
6519 // Stores to a non existing in-object property are allowed only to the | 6556 // Stores to a non existing in-object property are allowed only to the |
6520 // newly allocated objects (via HAllocate or HInnerAllocatedObject). | 6557 // newly allocated objects (via HAllocate or HInnerAllocatedObject). |
6521 ASSERT(!access.IsInobject() || access.existing_inobject_property() || | 6558 ASSERT(!access.IsInobject() || access.existing_inobject_property() || |
6522 obj->IsAllocate() || obj->IsInnerAllocatedObject()); | 6559 obj->IsAllocate() || obj->IsInnerAllocatedObject()); |
6523 SetOperandAt(0, obj); | 6560 SetOperandAt(0, obj); |
6524 SetOperandAt(1, val); | 6561 SetOperandAt(1, val); |
6525 SetOperandAt(2, obj); | 6562 SetOperandAt(2, obj); |
6526 access.SetGVNFlags(this, STORE); | 6563 access.SetGVNFlags(this, STORE); |
6527 } | 6564 } |
6528 | 6565 |
6529 HObjectAccess access_; | 6566 HObjectAccess access_; |
6530 HValue* new_space_dominator_; | 6567 HValue* new_space_dominator_; |
6531 WriteBarrierMode write_barrier_mode_ : 1; | 6568 WriteBarrierMode write_barrier_mode_ : 1; |
6532 bool has_transition_ : 1; | 6569 bool has_transition_ : 1; |
6570 bool is_stable_ : 1; | |
6533 StoreFieldOrKeyedMode store_mode_ : 1; | 6571 StoreFieldOrKeyedMode store_mode_ : 1; |
6534 }; | 6572 }; |
6535 | 6573 |
6536 | 6574 |
6537 class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> { | 6575 class HStoreNamedGeneric V8_FINAL : public HTemplateInstruction<3> { |
6538 public: | 6576 public: |
6539 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreNamedGeneric, HValue*, | 6577 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P4(HStoreNamedGeneric, HValue*, |
6540 Handle<String>, HValue*, | 6578 Handle<String>, HValue*, |
6541 StrictModeFlag); | 6579 StrictModeFlag); |
6542 HValue* object() { return OperandAt(0); } | 6580 HValue* object() { return OperandAt(0); } |
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7416 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 7454 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
7417 }; | 7455 }; |
7418 | 7456 |
7419 | 7457 |
7420 #undef DECLARE_INSTRUCTION | 7458 #undef DECLARE_INSTRUCTION |
7421 #undef DECLARE_CONCRETE_INSTRUCTION | 7459 #undef DECLARE_CONCRETE_INSTRUCTION |
7422 | 7460 |
7423 } } // namespace v8::internal | 7461 } } // namespace v8::internal |
7424 | 7462 |
7425 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7463 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |