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

Side by Side Diff: src/hydrogen-instructions.h

Issue 264973013: Don't add code dependencies eagerly for HCheckMaps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE Created 6 years, 7 months 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
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ 5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_
6 #define V8_HYDROGEN_INSTRUCTIONS_H_ 6 #define V8_HYDROGEN_INSTRUCTIONS_H_
7 7
8 #include "v8.h" 8 #include "v8.h"
9 9
10 #include "allocation.h" 10 #include "allocation.h"
(...skipping 2726 matching lines...) Expand 10 before | Expand all | Expand 10 after
2737 2737
2738 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 2738 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
2739 2739
2740 const Heap::RootListIndex index_; 2740 const Heap::RootListIndex index_;
2741 }; 2741 };
2742 2742
2743 2743
2744 class HCheckMaps V8_FINAL : public HTemplateInstruction<2> { 2744 class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
2745 public: 2745 public:
2746 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value, 2746 static HCheckMaps* New(Zone* zone, HValue* context, HValue* value,
2747 Handle<Map> map, CompilationInfo* info, 2747 Handle<Map> map, HValue* typecheck = NULL) {
2748 HValue* typecheck = NULL); 2748 return new(zone) HCheckMaps(value, new(zone) UniqueSet<Map>(
2749 Unique<Map>::CreateImmovable(map), zone), typecheck);
2750 }
2749 static HCheckMaps* New(Zone* zone, HValue* context, 2751 static HCheckMaps* New(Zone* zone, HValue* context,
2750 HValue* value, SmallMapList* map_list, 2752 HValue* value, SmallMapList* map_list,
2751 HValue* typecheck = NULL) { 2753 HValue* typecheck = NULL) {
2752 UniqueSet<Map>* maps = new(zone) UniqueSet<Map>(map_list->length(), zone); 2754 UniqueSet<Map>* maps = new(zone) UniqueSet<Map>(map_list->length(), zone);
2753 for (int i = 0; i < map_list->length(); ++i) { 2755 for (int i = 0; i < map_list->length(); ++i) {
2754 maps->Add(Unique<Map>::CreateImmovable(map_list->at(i)), zone); 2756 maps->Add(Unique<Map>::CreateImmovable(map_list->at(i)), zone);
2755 } 2757 }
2756 return new(zone) HCheckMaps(value, maps, typecheck); 2758 return new(zone) HCheckMaps(value, maps, typecheck);
2757 } 2759 }
2758 2760
2759 bool CanOmitMapChecks() { return omit_; } 2761 bool IsStabilityCheck() const { return is_stability_check_; }
2762 void MarkAsStabilityCheck() {
2763 has_migration_target_ = false;
2764 is_stability_check_ = true;
2765 ClearChangesFlag(kNewSpacePromotion);
2766 ClearDependsOnFlag(kElementsKind);
2767 ClearDependsOnFlag(kMaps);
2768 }
2760 2769
2761 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } 2770 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; }
2762 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { 2771 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
2763 return Representation::Tagged(); 2772 return Representation::Tagged();
2764 } 2773 }
2765 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; 2774 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
2766 2775
2767 HValue* value() { return OperandAt(0); } 2776 HValue* value() { return OperandAt(0); }
2768 HValue* typecheck() { return OperandAt(1); } 2777 HValue* typecheck() { return OperandAt(1); }
2769 2778
2770 const UniqueSet<Map>* maps() const { return maps_; } 2779 const UniqueSet<Map>* maps() const { return maps_; }
2771 void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; } 2780 void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; }
2772 2781
2773 bool has_migration_target() const { 2782 bool maps_are_stable() const { return maps_are_stable_; }
2774 return has_migration_target_; 2783
2775 } 2784 bool HasMigrationTarget() const { return has_migration_target_; }
2785
2786 virtual HValue* Canonicalize() V8_OVERRIDE;
2776 2787
2777 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) 2788 DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
2778 2789
2779 protected: 2790 protected:
2780 virtual bool DataEquals(HValue* other) V8_OVERRIDE { 2791 virtual bool DataEquals(HValue* other) V8_OVERRIDE {
2781 return this->maps()->Equals(HCheckMaps::cast(other)->maps()); 2792 return this->maps()->Equals(HCheckMaps::cast(other)->maps());
2782 } 2793 }
2783 2794
2784 virtual int RedefinedOperandIndex() { return 0; } 2795 virtual int RedefinedOperandIndex() { return 0; }
2785 2796
2786 private: 2797 private:
2787 // Clients should use one of the static New* methods above. 2798 // Clients should use one of the static New* methods above.
2788 HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck) 2799 HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck)
2789 : HTemplateInstruction<2>(value->type()), maps_(maps), 2800 : HTemplateInstruction<2>(value->type()), maps_(maps),
2790 omit_(false), has_migration_target_(false) { 2801 has_migration_target_(false), is_stability_check_(false),
2802 maps_are_stable_(true) {
2791 ASSERT_NE(0, maps->size()); 2803 ASSERT_NE(0, maps->size());
2792 SetOperandAt(0, value); 2804 SetOperandAt(0, value);
2793 // Use the object value for the dependency if NULL is passed. 2805 // Use the object value for the dependency if NULL is passed.
2794 SetOperandAt(1, typecheck ? typecheck : value); 2806 SetOperandAt(1, typecheck ? typecheck : value);
2795 set_representation(Representation::Tagged()); 2807 set_representation(Representation::Tagged());
2796 SetFlag(kUseGVN); 2808 SetFlag(kUseGVN);
2797 SetDependsOnFlag(kMaps); 2809 SetDependsOnFlag(kMaps);
2798 SetDependsOnFlag(kElementsKind); 2810 SetDependsOnFlag(kElementsKind);
2799 for (int i = 0; i < maps->size(); ++i) { 2811 for (int i = 0; i < maps->size(); ++i) {
2800 if (maps->at(i).handle()->is_migration_target()) { 2812 Handle<Map> map = maps->at(i).handle();
2801 SetChangesFlag(kNewSpacePromotion); 2813 if (map->is_migration_target()) has_migration_target_ = true;
2802 has_migration_target_ = true; 2814 if (!map->is_stable()) maps_are_stable_ = false;
2803 break;
2804 }
2805 } 2815 }
2816 if (has_migration_target_) SetChangesFlag(kNewSpacePromotion);
2806 } 2817 }
2807 2818
2808 const UniqueSet<Map>* maps_; 2819 const UniqueSet<Map>* maps_;
2809 bool omit_ : 1;
2810 bool has_migration_target_ : 1; 2820 bool has_migration_target_ : 1;
2821 bool is_stability_check_ : 1;
2822 bool maps_are_stable_ : 1;
2811 }; 2823 };
2812 2824
2813 2825
2814 class HCheckValue V8_FINAL : public HUnaryOperation { 2826 class HCheckValue V8_FINAL : public HUnaryOperation {
2815 public: 2827 public:
2816 static HCheckValue* New(Zone* zone, HValue* context, 2828 static HCheckValue* New(Zone* zone, HValue* context,
2817 HValue* value, Handle<JSFunction> func) { 2829 HValue* value, Handle<JSFunction> func) {
2818 bool in_new_space = zone->isolate()->heap()->InNewSpace(*func); 2830 bool in_new_space = zone->isolate()->heap()->InNewSpace(*func);
2819 // NOTE: We create an uninitialized Unique and initialize it later. 2831 // NOTE: We create an uninitialized Unique and initialize it later.
2820 // This is because a JSFunction can move due to GC during graph creation. 2832 // This is because a JSFunction can move due to GC during graph creation.
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
3452 3464
3453 static HConstant* CreateAndInsertBefore(Zone* zone, 3465 static HConstant* CreateAndInsertBefore(Zone* zone,
3454 Unique<Object> unique, 3466 Unique<Object> unique,
3455 bool is_not_in_new_space, 3467 bool is_not_in_new_space,
3456 HInstruction* instruction) { 3468 HInstruction* instruction) {
3457 return instruction->Prepend(new(zone) HConstant( 3469 return instruction->Prepend(new(zone) HConstant(
3458 unique, Representation::Tagged(), HType::Tagged(), 3470 unique, Representation::Tagged(), HType::Tagged(),
3459 is_not_in_new_space, false, false, kUnknownInstanceType)); 3471 is_not_in_new_space, false, false, kUnknownInstanceType));
3460 } 3472 }
3461 3473
3474 static HConstant* CreateAndInsertAfter(Zone* zone,
3475 Unique<Map> unique,
3476 HInstruction* instruction) {
3477 return instruction->Append(new(zone) HConstant(
3478 unique, Representation::Tagged(), HType::Tagged(),
3479 true, false, false, MAP_TYPE));
3480 }
3481
3462 Handle<Object> handle(Isolate* isolate) { 3482 Handle<Object> handle(Isolate* isolate) {
3463 if (object_.handle().is_null()) { 3483 if (object_.handle().is_null()) {
3464 // Default arguments to is_not_in_new_space depend on this heap number 3484 // Default arguments to is_not_in_new_space depend on this heap number
3465 // to be tenured so that it's guaranteed not to be located in new space. 3485 // to be tenured so that it's guaranteed not to be located in new space.
3466 object_ = Unique<Object>::CreateUninitialized( 3486 object_ = Unique<Object>::CreateUninitialized(
3467 isolate->factory()->NewNumber(double_value_, TENURED)); 3487 isolate->factory()->NewNumber(double_value_, TENURED));
3468 } 3488 }
3469 AllowDeferredHandleDereference smi_check; 3489 AllowDeferredHandleDereference smi_check;
3470 ASSERT(has_int32_value_ || !object_.handle()->IsSmi()); 3490 ASSERT(has_int32_value_ || !object_.handle()->IsSmi());
3471 return object_.handle(); 3491 return object_.handle();
3472 } 3492 }
3473 3493
3474 bool HasMap(Handle<Map> map) {
3475 Handle<Object> constant_object = handle(map->GetIsolate());
3476 return constant_object->IsHeapObject() &&
3477 Handle<HeapObject>::cast(constant_object)->map() == *map;
3478 }
3479
3480 bool IsSpecialDouble() const { 3494 bool IsSpecialDouble() const {
3481 return has_double_value_ && 3495 return has_double_value_ &&
3482 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || 3496 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) ||
3483 FixedDoubleArray::is_the_hole_nan(double_value_) || 3497 FixedDoubleArray::is_the_hole_nan(double_value_) ||
3484 std::isnan(double_value_)); 3498 std::isnan(double_value_));
3485 } 3499 }
3486 3500
3487 bool NotInNewSpace() const { 3501 bool NotInNewSpace() const {
3488 return is_not_in_new_space_; 3502 return is_not_in_new_space_;
3489 } 3503 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
3554 } 3568 }
3555 ExternalReference ExternalReferenceValue() const { 3569 ExternalReference ExternalReferenceValue() const {
3556 return external_reference_value_; 3570 return external_reference_value_;
3557 } 3571 }
3558 3572
3559 bool HasBooleanValue() const { return type_.IsBoolean(); } 3573 bool HasBooleanValue() const { return type_.IsBoolean(); }
3560 bool BooleanValue() const { return boolean_value_; } 3574 bool BooleanValue() const { return boolean_value_; }
3561 bool IsUndetectable() const { return is_undetectable_; } 3575 bool IsUndetectable() const { return is_undetectable_; }
3562 InstanceType GetInstanceType() const { return instance_type_; } 3576 InstanceType GetInstanceType() const { return instance_type_; }
3563 3577
3578 bool HasObjectMap() const { return !object_map_.IsNull(); }
3579 Unique<Map> ObjectMap() const {
3580 ASSERT(HasObjectMap());
3581 return object_map_;
3582 }
3583 bool ObjectMapIsStable() const {
3584 ASSERT(HasObjectMap());
3585 return object_map_is_stable_;
3586 }
3587
3564 virtual intptr_t Hashcode() V8_OVERRIDE { 3588 virtual intptr_t Hashcode() V8_OVERRIDE {
3565 if (has_int32_value_) { 3589 if (has_int32_value_) {
3566 return static_cast<intptr_t>(int32_value_); 3590 return static_cast<intptr_t>(int32_value_);
3567 } else if (has_double_value_) { 3591 } else if (has_double_value_) {
3568 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); 3592 return static_cast<intptr_t>(BitCast<int64_t>(double_value_));
3569 } else if (has_external_reference_value_) { 3593 } else if (has_external_reference_value_) {
3570 return reinterpret_cast<intptr_t>(external_reference_value_.address()); 3594 return reinterpret_cast<intptr_t>(external_reference_value_.address());
3571 } else { 3595 } else {
3572 ASSERT(!object_.handle().is_null()); 3596 ASSERT(!object_.handle().is_null());
3573 return object_.Hashcode(); 3597 return object_.Hashcode();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3646 void Initialize(Representation r); 3670 void Initialize(Representation r);
3647 3671
3648 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 3672 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
3649 3673
3650 // If this is a numerical constant, object_ either points to the 3674 // If this is a numerical constant, object_ either points to the
3651 // HeapObject the constant originated from or is null. If the 3675 // HeapObject the constant originated from or is null. If the
3652 // constant is non-numeric, object_ always points to a valid 3676 // constant is non-numeric, object_ always points to a valid
3653 // constant HeapObject. 3677 // constant HeapObject.
3654 Unique<Object> object_; 3678 Unique<Object> object_;
3655 3679
3680 // If this is a heap object, this points to the Map of the object.
3681 Unique<Map> object_map_;
3682 bool object_map_is_stable_ : 1;
3683
3656 // We store the HConstant in the most specific form safely possible. 3684 // We store the HConstant in the most specific form safely possible.
3657 // The two flags, has_int32_value_ and has_double_value_ tell us if 3685 // The two flags, has_int32_value_ and has_double_value_ tell us if
3658 // int32_value_ and double_value_ hold valid, safe representations 3686 // int32_value_ and double_value_ hold valid, safe representations
3659 // of the constant. has_int32_value_ implies has_double_value_ but 3687 // of the constant. has_int32_value_ implies has_double_value_ but
3660 // not the converse. 3688 // not the converse.
3661 bool has_smi_value_ : 1; 3689 bool has_smi_value_ : 1;
3662 bool has_int32_value_ : 1; 3690 bool has_int32_value_ : 1;
3663 bool has_double_value_ : 1; 3691 bool has_double_value_ : 1;
3664 bool has_external_reference_value_ : 1; 3692 bool has_external_reference_value_ : 1;
3665 bool is_not_in_new_space_ : 1; 3693 bool is_not_in_new_space_ : 1;
(...skipping 3890 matching lines...) Expand 10 before | Expand all | Expand 10 after
7556 virtual bool IsDeletable() const V8_OVERRIDE { return true; } 7584 virtual bool IsDeletable() const V8_OVERRIDE { return true; }
7557 }; 7585 };
7558 7586
7559 7587
7560 #undef DECLARE_INSTRUCTION 7588 #undef DECLARE_INSTRUCTION
7561 #undef DECLARE_CONCRETE_INSTRUCTION 7589 #undef DECLARE_CONCRETE_INSTRUCTION
7562 7590
7563 } } // namespace v8::internal 7591 } } // namespace v8::internal
7564 7592
7565 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 7593 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698