Chromium Code Reviews| 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 |