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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 | 227 |
228 #define DECLARE_CONCRETE_INSTRUCTION(type) \ | 228 #define DECLARE_CONCRETE_INSTRUCTION(type) \ |
229 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \ | 229 virtual LInstruction* CompileToLithium(LChunkBuilder* builder); \ |
230 static H##type* cast(HValue* value) { \ | 230 static H##type* cast(HValue* value) { \ |
231 ASSERT(value->Is##type()); \ | 231 ASSERT(value->Is##type()); \ |
232 return reinterpret_cast<H##type*>(value); \ | 232 return reinterpret_cast<H##type*>(value); \ |
233 } \ | 233 } \ |
234 virtual Opcode opcode() const { return HValue::k##type; } | 234 virtual Opcode opcode() const { return HValue::k##type; } |
235 | 235 |
236 | 236 |
237 #ifdef DEBUG | |
238 #define ASSERT_ALLOCATION_DISABLED \ | |
239 ASSERT(isolate()->optimizing_compiler_thread()->IsOptimizerThread() || \ | |
240 !isolate()->heap()->IsAllocationAllowed()) | |
241 #else | |
242 #define ASSERT_ALLOCATION_DISABLED do {} while (0) | |
243 #endif | |
244 | |
245 class Range: public ZoneObject { | 237 class Range: public ZoneObject { |
246 public: | 238 public: |
247 Range() | 239 Range() |
248 : lower_(kMinInt), | 240 : lower_(kMinInt), |
249 upper_(kMaxInt), | 241 upper_(kMaxInt), |
250 next_(NULL), | 242 next_(NULL), |
251 can_be_minus_zero_(false) { } | 243 can_be_minus_zero_(false) { } |
252 | 244 |
253 Range(int32_t lower, int32_t upper) | 245 Range(int32_t lower, int32_t upper) |
254 : lower_(lower), | 246 : lower_(lower), |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
357 private: | 349 private: |
358 explicit Representation(Kind k) : kind_(k) { } | 350 explicit Representation(Kind k) : kind_(k) { } |
359 | 351 |
360 // Make sure kind fits in int8. | 352 // Make sure kind fits in int8. |
361 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); | 353 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); |
362 | 354 |
363 int8_t kind_; | 355 int8_t kind_; |
364 }; | 356 }; |
365 | 357 |
366 | 358 |
359 class UniqueValueId { | |
360 public: | |
361 UniqueValueId() : raw_address_(NULL) { } | |
362 | |
363 explicit UniqueValueId(Object* object) { | |
364 raw_address_ = reinterpret_cast<Address>(object); | |
365 ASSERT(!IsUninitialized()); | |
366 } | |
367 | |
368 explicit UniqueValueId(Handle<Object> handle) { | |
369 static const Address kEmptyHandleSentinel = reinterpret_cast<Address>(1); | |
370 if (handle.is_null()) { | |
371 raw_address_ = kEmptyHandleSentinel; | |
372 } else { | |
373 raw_address_ = reinterpret_cast<Address>(*handle); | |
374 ASSERT_NE(kEmptyHandleSentinel, raw_address_); | |
375 } | |
376 ASSERT(!IsUninitialized()); | |
377 } | |
378 | |
379 bool IsUninitialized() const { return raw_address_ == NULL; } | |
Sven Panne
2013/04/16 10:35:26
Almost all uses are negated, so let's negate the t
| |
380 | |
381 bool operator==(const UniqueValueId& other) const { | |
382 ASSERT(!IsUninitialized() && !other.IsUninitialized()); | |
383 return raw_address_ == other.raw_address_; | |
384 } | |
385 | |
386 bool operator!=(const UniqueValueId& other) const { | |
387 ASSERT(!IsUninitialized() && !other.IsUninitialized()); | |
388 return raw_address_ != other.raw_address_; | |
389 } | |
390 | |
391 intptr_t Hashcode() const { | |
392 ASSERT(!IsUninitialized()); | |
393 return reinterpret_cast<intptr_t>(raw_address_); | |
394 } | |
395 | |
396 private: | |
397 Address raw_address_; | |
398 }; | |
399 | |
400 | |
367 class HType { | 401 class HType { |
368 public: | 402 public: |
369 HType() : type_(kUninitialized) { } | 403 HType() : type_(kUninitialized) { } |
370 | 404 |
371 static HType Tagged() { return HType(kTagged); } | 405 static HType Tagged() { return HType(kTagged); } |
372 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } | 406 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } |
373 static HType TaggedNumber() { return HType(kTaggedNumber); } | 407 static HType TaggedNumber() { return HType(kTaggedNumber); } |
374 static HType Smi() { return HType(kSmi); } | 408 static HType Smi() { return HType(kSmi); } |
375 static HType HeapNumber() { return HType(kHeapNumber); } | 409 static HType HeapNumber() { return HType(kHeapNumber); } |
376 static HType String() { return HType(kString); } | 410 static HType String() { return HType(kString); } |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1050 | 1084 |
1051 // This gives the instruction an opportunity to replace itself with an | 1085 // This gives the instruction an opportunity to replace itself with an |
1052 // instruction that does the same in some better way. To replace an | 1086 // instruction that does the same in some better way. To replace an |
1053 // instruction with a new one, first add the new instruction to the graph, | 1087 // instruction with a new one, first add the new instruction to the graph, |
1054 // then return it. Return NULL to have the instruction deleted. | 1088 // then return it. Return NULL to have the instruction deleted. |
1055 virtual HValue* Canonicalize() { return this; } | 1089 virtual HValue* Canonicalize() { return this; } |
1056 | 1090 |
1057 bool Equals(HValue* other); | 1091 bool Equals(HValue* other); |
1058 virtual intptr_t Hashcode(); | 1092 virtual intptr_t Hashcode(); |
1059 | 1093 |
1094 // Compute unique ids upfront that is safe wrt GC and parallel recompilation. | |
1095 virtual void FinalizeUniqueValueId() { } | |
1096 | |
1060 // Printing support. | 1097 // Printing support. |
1061 virtual void PrintTo(StringStream* stream) = 0; | 1098 virtual void PrintTo(StringStream* stream) = 0; |
1062 void PrintNameTo(StringStream* stream); | 1099 void PrintNameTo(StringStream* stream); |
1063 void PrintTypeTo(StringStream* stream); | 1100 void PrintTypeTo(StringStream* stream); |
1064 void PrintRangeTo(StringStream* stream); | 1101 void PrintRangeTo(StringStream* stream); |
1065 void PrintChangesTo(StringStream* stream); | 1102 void PrintChangesTo(StringStream* stream); |
1066 | 1103 |
1067 const char* Mnemonic() const; | 1104 const char* Mnemonic() const; |
1068 | 1105 |
1069 // Type information helpers. | 1106 // Type information helpers. |
(...skipping 1566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2636 virtual bool DataEquals(HValue* other) { return true; } | 2673 virtual bool DataEquals(HValue* other) { return true; } |
2637 | 2674 |
2638 private: | 2675 private: |
2639 virtual bool IsDeletable() const { return true; } | 2676 virtual bool IsDeletable() const { return true; } |
2640 }; | 2677 }; |
2641 | 2678 |
2642 | 2679 |
2643 class HCheckMaps: public HTemplateInstruction<2> { | 2680 class HCheckMaps: public HTemplateInstruction<2> { |
2644 public: | 2681 public: |
2645 HCheckMaps(HValue* value, Handle<Map> map, Zone* zone, | 2682 HCheckMaps(HValue* value, Handle<Map> map, Zone* zone, |
2646 HValue* typecheck = NULL) { | 2683 HValue* typecheck = NULL) |
2684 : map_unique_ids_(0, zone) { | |
2647 SetOperandAt(0, value); | 2685 SetOperandAt(0, value); |
2648 // If callers don't depend on a typecheck, they can pass in NULL. In that | 2686 // If callers don't depend on a typecheck, they can pass in NULL. In that |
2649 // case we use a copy of the |value| argument as a dummy value. | 2687 // case we use a copy of the |value| argument as a dummy value. |
2650 SetOperandAt(1, typecheck != NULL ? typecheck : value); | 2688 SetOperandAt(1, typecheck != NULL ? typecheck : value); |
2651 set_representation(Representation::Tagged()); | 2689 set_representation(Representation::Tagged()); |
2652 SetFlag(kUseGVN); | 2690 SetFlag(kUseGVN); |
2653 SetFlag(kTrackSideEffectDominators); | 2691 SetFlag(kTrackSideEffectDominators); |
2654 SetGVNFlag(kDependsOnMaps); | 2692 SetGVNFlag(kDependsOnMaps); |
2655 SetGVNFlag(kDependsOnElementsKind); | 2693 SetGVNFlag(kDependsOnElementsKind); |
2656 map_set()->Add(map, zone); | 2694 map_set()->Add(map, zone); |
2657 } | 2695 } |
2658 HCheckMaps(HValue* value, SmallMapList* maps, Zone* zone) { | 2696 HCheckMaps(HValue* value, SmallMapList* maps, Zone* zone) |
2697 : map_unique_ids_(0, zone) { | |
2659 SetOperandAt(0, value); | 2698 SetOperandAt(0, value); |
2660 SetOperandAt(1, value); | 2699 SetOperandAt(1, value); |
2661 set_representation(Representation::Tagged()); | 2700 set_representation(Representation::Tagged()); |
2662 SetFlag(kUseGVN); | 2701 SetFlag(kUseGVN); |
2663 SetFlag(kTrackSideEffectDominators); | 2702 SetFlag(kTrackSideEffectDominators); |
2664 SetGVNFlag(kDependsOnMaps); | 2703 SetGVNFlag(kDependsOnMaps); |
2665 SetGVNFlag(kDependsOnElementsKind); | 2704 SetGVNFlag(kDependsOnElementsKind); |
2666 for (int i = 0; i < maps->length(); i++) { | 2705 for (int i = 0; i < maps->length(); i++) { |
2667 map_set()->Add(maps->at(i), zone); | 2706 map_set()->Add(maps->at(i), zone); |
2668 } | 2707 } |
(...skipping 26 matching lines...) Expand all Loading... | |
2695 virtual Representation RequiredInputRepresentation(int index) { | 2734 virtual Representation RequiredInputRepresentation(int index) { |
2696 return Representation::Tagged(); | 2735 return Representation::Tagged(); |
2697 } | 2736 } |
2698 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator); | 2737 virtual void SetSideEffectDominator(GVNFlag side_effect, HValue* dominator); |
2699 virtual void PrintDataTo(StringStream* stream); | 2738 virtual void PrintDataTo(StringStream* stream); |
2700 virtual HType CalculateInferredType(); | 2739 virtual HType CalculateInferredType(); |
2701 | 2740 |
2702 HValue* value() { return OperandAt(0); } | 2741 HValue* value() { return OperandAt(0); } |
2703 SmallMapList* map_set() { return &map_set_; } | 2742 SmallMapList* map_set() { return &map_set_; } |
2704 | 2743 |
2744 virtual void FinalizeUniqueValueId(); | |
2745 | |
2705 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) | 2746 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
2706 | 2747 |
2707 protected: | 2748 protected: |
2708 virtual bool DataEquals(HValue* other) { | 2749 virtual bool DataEquals(HValue* other) { |
2750 ASSERT_EQ(map_set_.length(), map_unique_ids_.length()); | |
2709 HCheckMaps* b = HCheckMaps::cast(other); | 2751 HCheckMaps* b = HCheckMaps::cast(other); |
2710 // Relies on the fact that map_set has been sorted before. | 2752 // Relies on the fact that map_set has been sorted before. |
2711 if (map_set()->length() != b->map_set()->length()) return false; | 2753 if (map_unique_ids_.length() != b->map_unique_ids_.length()) { |
2712 for (int i = 0; i < map_set()->length(); i++) { | 2754 return false; |
2713 if (!map_set()->at(i).is_identical_to(b->map_set()->at(i))) return false; | 2755 } |
2756 for (int i = 0; i < map_unique_ids_.length(); i++) { | |
2757 if (map_unique_ids_.at(i) != b->map_unique_ids_.at(i)) { | |
2758 return false; | |
2759 } | |
2714 } | 2760 } |
2715 return true; | 2761 return true; |
2716 } | 2762 } |
2717 | 2763 |
2718 private: | 2764 private: |
2719 SmallMapList map_set_; | 2765 SmallMapList map_set_; |
2766 ZoneList<UniqueValueId> map_unique_ids_; | |
2720 }; | 2767 }; |
2721 | 2768 |
2722 | 2769 |
2723 class HCheckFunction: public HUnaryOperation { | 2770 class HCheckFunction: public HUnaryOperation { |
2724 public: | 2771 public: |
2725 HCheckFunction(HValue* value, Handle<JSFunction> function) | 2772 HCheckFunction(HValue* value, Handle<JSFunction> function) |
2726 : HUnaryOperation(value), target_(function) { | 2773 : HUnaryOperation(value), target_(function), target_unique_id_() { |
2727 set_representation(Representation::Tagged()); | 2774 set_representation(Representation::Tagged()); |
2728 SetFlag(kUseGVN); | 2775 SetFlag(kUseGVN); |
2729 target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function); | 2776 target_in_new_space_ = Isolate::Current()->heap()->InNewSpace(*function); |
2730 } | 2777 } |
2731 | 2778 |
2732 virtual Representation RequiredInputRepresentation(int index) { | 2779 virtual Representation RequiredInputRepresentation(int index) { |
2733 return Representation::Tagged(); | 2780 return Representation::Tagged(); |
2734 } | 2781 } |
2735 virtual void PrintDataTo(StringStream* stream); | 2782 virtual void PrintDataTo(StringStream* stream); |
2736 virtual HType CalculateInferredType(); | 2783 virtual HType CalculateInferredType(); |
2737 | 2784 |
2738 #ifdef DEBUG | 2785 #ifdef DEBUG |
2739 virtual void Verify(); | 2786 virtual void Verify(); |
2740 #endif | 2787 #endif |
2741 | 2788 |
2789 virtual void FinalizeUniqueValueId() { | |
2790 target_unique_id_ = UniqueValueId(target_); | |
2791 } | |
2792 | |
2742 Handle<JSFunction> target() const { return target_; } | 2793 Handle<JSFunction> target() const { return target_; } |
2743 bool target_in_new_space() const { return target_in_new_space_; } | 2794 bool target_in_new_space() const { return target_in_new_space_; } |
2744 | 2795 |
2745 DECLARE_CONCRETE_INSTRUCTION(CheckFunction) | 2796 DECLARE_CONCRETE_INSTRUCTION(CheckFunction) |
2746 | 2797 |
2747 protected: | 2798 protected: |
2748 virtual bool DataEquals(HValue* other) { | 2799 virtual bool DataEquals(HValue* other) { |
2749 HCheckFunction* b = HCheckFunction::cast(other); | 2800 HCheckFunction* b = HCheckFunction::cast(other); |
2750 return target_.is_identical_to(b->target()); | 2801 return target_unique_id_ == b->target_unique_id_; |
2751 } | 2802 } |
2752 | 2803 |
2753 private: | 2804 private: |
2754 Handle<JSFunction> target_; | 2805 Handle<JSFunction> target_; |
2806 UniqueValueId target_unique_id_; | |
2755 bool target_in_new_space_; | 2807 bool target_in_new_space_; |
2756 }; | 2808 }; |
2757 | 2809 |
2758 | 2810 |
2759 class HCheckInstanceType: public HUnaryOperation { | 2811 class HCheckInstanceType: public HUnaryOperation { |
2760 public: | 2812 public: |
2761 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { | 2813 static HCheckInstanceType* NewIsSpecObject(HValue* value, Zone* zone) { |
2762 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); | 2814 return new(zone) HCheckInstanceType(value, IS_SPEC_OBJECT); |
2763 } | 2815 } |
2764 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) { | 2816 static HCheckInstanceType* NewIsJSArray(HValue* value, Zone* zone) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2849 | 2901 |
2850 protected: | 2902 protected: |
2851 virtual bool DataEquals(HValue* other) { return true; } | 2903 virtual bool DataEquals(HValue* other) { return true; } |
2852 }; | 2904 }; |
2853 | 2905 |
2854 | 2906 |
2855 class HCheckPrototypeMaps: public HTemplateInstruction<0> { | 2907 class HCheckPrototypeMaps: public HTemplateInstruction<0> { |
2856 public: | 2908 public: |
2857 HCheckPrototypeMaps(Handle<JSObject> prototype, | 2909 HCheckPrototypeMaps(Handle<JSObject> prototype, |
2858 Handle<JSObject> holder, | 2910 Handle<JSObject> holder, |
2859 Zone* zone) : prototypes_(2, zone), maps_(2, zone) { | 2911 Zone* zone) |
2912 : prototypes_(2, zone), | |
2913 maps_(2, zone), | |
2914 first_prototype_unique_id_(), | |
2915 last_prototype_unique_id_() { | |
2860 SetFlag(kUseGVN); | 2916 SetFlag(kUseGVN); |
2861 SetGVNFlag(kDependsOnMaps); | 2917 SetGVNFlag(kDependsOnMaps); |
2862 // Keep a list of all objects on the prototype chain up to the holder | 2918 // Keep a list of all objects on the prototype chain up to the holder |
2863 // and the expected maps. | 2919 // and the expected maps. |
2864 while (true) { | 2920 while (true) { |
2865 prototypes_.Add(prototype, zone); | 2921 prototypes_.Add(prototype, zone); |
2866 maps_.Add(Handle<Map>(prototype->map()), zone); | 2922 maps_.Add(Handle<Map>(prototype->map()), zone); |
2867 if (prototype.is_identical_to(holder)) break; | 2923 if (prototype.is_identical_to(holder)) break; |
2868 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype())); | 2924 prototype = Handle<JSObject>(JSObject::cast(prototype->GetPrototype())); |
2869 } | 2925 } |
2870 } | 2926 } |
2871 | 2927 |
2872 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; } | 2928 ZoneList<Handle<JSObject> >* prototypes() { return &prototypes_; } |
2873 | 2929 |
2874 ZoneList<Handle<Map> >* maps() { return &maps_; } | 2930 ZoneList<Handle<Map> >* maps() { return &maps_; } |
2875 | 2931 |
2876 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps) | 2932 DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps) |
2877 | 2933 |
2878 virtual Representation RequiredInputRepresentation(int index) { | 2934 virtual Representation RequiredInputRepresentation(int index) { |
2879 return Representation::None(); | 2935 return Representation::None(); |
2880 } | 2936 } |
2881 | 2937 |
2882 virtual void PrintDataTo(StringStream* stream); | 2938 virtual void PrintDataTo(StringStream* stream); |
2883 | 2939 |
2884 virtual intptr_t Hashcode() { | 2940 virtual intptr_t Hashcode() { |
2885 ASSERT_ALLOCATION_DISABLED; | 2941 return first_prototype_unique_id_.Hashcode() * 17 + |
2886 // Dereferencing to use the object's raw address for hashing is safe. | 2942 last_prototype_unique_id_.Hashcode(); |
2887 HandleDereferenceGuard allow_handle_deref(isolate(), | 2943 } |
2888 HandleDereferenceGuard::ALLOW); | 2944 |
2889 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || | 2945 virtual void FinalizeUniqueValueId() { |
2890 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); | 2946 first_prototype_unique_id_ = UniqueValueId(prototypes_.first()); |
2891 intptr_t hash = 0; | 2947 last_prototype_unique_id_ = UniqueValueId(prototypes_.last()); |
2892 for (int i = 0; i < prototypes_.length(); i++) { | |
2893 hash = 17 * hash + reinterpret_cast<intptr_t>(*prototypes_[i]); | |
2894 hash = 17 * hash + reinterpret_cast<intptr_t>(*maps_[i]); | |
2895 } | |
2896 return hash; | |
2897 } | 2948 } |
2898 | 2949 |
2899 bool CanOmitPrototypeChecks() { | 2950 bool CanOmitPrototypeChecks() { |
2900 for (int i = 0; i < maps()->length(); i++) { | 2951 for (int i = 0; i < maps()->length(); i++) { |
2901 if (!maps()->at(i)->CanOmitPrototypeChecks()) return false; | 2952 if (!maps()->at(i)->CanOmitPrototypeChecks()) return false; |
2902 } | 2953 } |
2903 return true; | 2954 return true; |
2904 } | 2955 } |
2905 | 2956 |
2906 protected: | 2957 protected: |
2907 virtual bool DataEquals(HValue* other) { | 2958 virtual bool DataEquals(HValue* other) { |
2908 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other); | 2959 HCheckPrototypeMaps* b = HCheckPrototypeMaps::cast(other); |
2909 #ifdef DEBUG | 2960 return first_prototype_unique_id_ == b->first_prototype_unique_id_ && |
2910 if (prototypes_.length() != b->prototypes()->length()) return false; | 2961 last_prototype_unique_id_ == b->last_prototype_unique_id_; |
2911 for (int i = 0; i < prototypes_.length(); i++) { | |
2912 if (!prototypes_[i].is_identical_to(b->prototypes()->at(i))) return false; | |
2913 if (!maps_[i].is_identical_to(b->maps()->at(i))) return false; | |
2914 } | |
2915 return true; | |
2916 #else | |
2917 return prototypes_.first().is_identical_to(b->prototypes()->first()) && | |
2918 prototypes_.last().is_identical_to(b->prototypes()->last()); | |
2919 #endif // DEBUG | |
2920 } | 2962 } |
2921 | 2963 |
2922 private: | 2964 private: |
2923 ZoneList<Handle<JSObject> > prototypes_; | 2965 ZoneList<Handle<JSObject> > prototypes_; |
2924 ZoneList<Handle<Map> > maps_; | 2966 ZoneList<Handle<Map> > maps_; |
2967 UniqueValueId first_prototype_unique_id_; | |
2968 UniqueValueId last_prototype_unique_id_; | |
2925 }; | 2969 }; |
2926 | 2970 |
2927 | 2971 |
2928 class HCheckSmi: public HUnaryOperation { | 2972 class HCheckSmi: public HUnaryOperation { |
2929 public: | 2973 public: |
2930 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { | 2974 explicit HCheckSmi(HValue* value) : HUnaryOperation(value) { |
2931 set_representation(Representation::Tagged()); | 2975 set_representation(Representation::Tagged()); |
2932 SetFlag(kUseGVN); | 2976 SetFlag(kUseGVN); |
2933 } | 2977 } |
2934 | 2978 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3169 class HConstant: public HTemplateInstruction<0> { | 3213 class HConstant: public HTemplateInstruction<0> { |
3170 public: | 3214 public: |
3171 HConstant(Handle<Object> handle, Representation r); | 3215 HConstant(Handle<Object> handle, Representation r); |
3172 HConstant(int32_t value, | 3216 HConstant(int32_t value, |
3173 Representation r, | 3217 Representation r, |
3174 Handle<Object> optional_handle = Handle<Object>::null()); | 3218 Handle<Object> optional_handle = Handle<Object>::null()); |
3175 HConstant(double value, | 3219 HConstant(double value, |
3176 Representation r, | 3220 Representation r, |
3177 Handle<Object> optional_handle = Handle<Object>::null()); | 3221 Handle<Object> optional_handle = Handle<Object>::null()); |
3178 HConstant(Handle<Object> handle, | 3222 HConstant(Handle<Object> handle, |
3223 UniqueValueId unique_id, | |
3179 Representation r, | 3224 Representation r, |
3180 HType type, | 3225 HType type, |
3181 bool is_internalized_string, | 3226 bool is_internalized_string, |
3182 bool boolean_value); | 3227 bool boolean_value); |
3183 | 3228 |
3184 Handle<Object> handle() { | 3229 Handle<Object> handle() { |
3185 if (handle_.is_null()) { | 3230 if (handle_.is_null()) { |
3186 handle_ = FACTORY->NewNumber(double_value_, TENURED); | 3231 handle_ = FACTORY->NewNumber(double_value_, TENURED); |
3187 } | 3232 } |
3188 ASSERT(has_int32_value_ || !handle_->IsSmi()); | 3233 ASSERT(has_int32_value_ || !handle_->IsSmi()); |
3189 return handle_; | 3234 return handle_; |
3190 } | 3235 } |
3191 | 3236 |
3192 bool InOldSpace() const { return !HEAP->InNewSpace(*handle_); } | |
3193 | |
3194 bool IsSpecialDouble() const { | 3237 bool IsSpecialDouble() const { |
3195 return has_double_value_ && | 3238 return has_double_value_ && |
3196 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || | 3239 (BitCast<int64_t>(double_value_) == BitCast<int64_t>(-0.0) || |
3197 FixedDoubleArray::is_the_hole_nan(double_value_) || | 3240 FixedDoubleArray::is_the_hole_nan(double_value_) || |
3198 isnan(double_value_)); | 3241 isnan(double_value_)); |
3199 } | 3242 } |
3200 | 3243 |
3201 bool ImmortalImmovable() const { | 3244 bool ImmortalImmovable() const { |
3202 if (has_int32_value_) { | 3245 if (has_int32_value_) { |
3203 return false; | 3246 return false; |
3204 } | 3247 } |
3205 if (has_double_value_) { | 3248 if (has_double_value_) { |
3206 if (IsSpecialDouble()) { | 3249 if (IsSpecialDouble()) { |
3207 return true; | 3250 return true; |
3208 } | 3251 } |
3209 return false; | 3252 return false; |
3210 } | 3253 } |
3211 | 3254 |
3212 ASSERT(!handle_.is_null()); | 3255 ASSERT(!handle_.is_null()); |
3256 HandleDereferenceGuard allow_dereference_for_immovable_check( | |
3257 isolate(), HandleDereferenceGuard::ALLOW); | |
3213 Heap* heap = isolate()->heap(); | 3258 Heap* heap = isolate()->heap(); |
3214 // We should have handled minus_zero_value and nan_value in the | 3259 ASSERT(unique_id_ != UniqueValueId(heap->minus_zero_value())); |
3215 // has_double_value_ clause above. | 3260 ASSERT(unique_id_ != UniqueValueId(heap->nan_value())); |
3216 // Dereferencing is safe to compare against immovable singletons. | 3261 return unique_id_ == UniqueValueId(heap->undefined_value()) || |
3217 HandleDereferenceGuard allow_handle_deref(isolate(), | 3262 unique_id_ == UniqueValueId(heap->null_value()) || |
3218 HandleDereferenceGuard::ALLOW); | 3263 unique_id_ == UniqueValueId(heap->true_value()) || |
3219 ASSERT(*handle_ != heap->minus_zero_value()); | 3264 unique_id_ == UniqueValueId(heap->false_value()) || |
3220 ASSERT(*handle_ != heap->nan_value()); | 3265 unique_id_ == UniqueValueId(heap->the_hole_value()) || |
3221 return *handle_ == heap->undefined_value() || | 3266 unique_id_ == UniqueValueId(heap->empty_string()); |
3222 *handle_ == heap->null_value() || | |
3223 *handle_ == heap->true_value() || | |
3224 *handle_ == heap->false_value() || | |
3225 *handle_ == heap->the_hole_value() || | |
3226 *handle_ == heap->empty_string(); | |
3227 } | 3267 } |
3228 | 3268 |
3229 virtual Representation RequiredInputRepresentation(int index) { | 3269 virtual Representation RequiredInputRepresentation(int index) { |
3230 return Representation::None(); | 3270 return Representation::None(); |
3231 } | 3271 } |
3232 | 3272 |
3233 virtual bool IsConvertibleToInteger() const { | 3273 virtual bool IsConvertibleToInteger() const { |
3234 return has_int32_value_; | 3274 return has_int32_value_; |
3235 } | 3275 } |
3236 | 3276 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3286 return HasStringValue() && is_internalized_string_; | 3326 return HasStringValue() && is_internalized_string_; |
3287 } | 3327 } |
3288 | 3328 |
3289 bool BooleanValue() const { return boolean_value_; } | 3329 bool BooleanValue() const { return boolean_value_; } |
3290 | 3330 |
3291 bool IsUint32() { | 3331 bool IsUint32() { |
3292 return HasInteger32Value() && (Integer32Value() >= 0); | 3332 return HasInteger32Value() && (Integer32Value() >= 0); |
3293 } | 3333 } |
3294 | 3334 |
3295 virtual intptr_t Hashcode() { | 3335 virtual intptr_t Hashcode() { |
3296 ASSERT_ALLOCATION_DISABLED; | |
3297 intptr_t hash; | |
3298 | |
3299 if (has_int32_value_) { | 3336 if (has_int32_value_) { |
3300 hash = static_cast<intptr_t>(int32_value_); | 3337 return static_cast<intptr_t>(int32_value_); |
3301 } else if (has_double_value_) { | 3338 } else if (has_double_value_) { |
3302 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_)); | 3339 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); |
3303 } else { | 3340 } else { |
3304 ASSERT(!handle_.is_null()); | 3341 ASSERT(!handle_.is_null()); |
3305 // Dereferencing to use the object's raw address for hashing is safe. | 3342 return unique_id_.Hashcode(); |
3306 HandleDereferenceGuard allow_handle_deref(isolate(), | |
3307 HandleDereferenceGuard::ALLOW); | |
3308 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || | |
3309 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); | |
3310 hash = reinterpret_cast<intptr_t>(*handle_); | |
3311 } | 3343 } |
3344 } | |
3312 | 3345 |
3313 return hash; | 3346 virtual void FinalizeUniqueValueId() { |
3347 if (!has_double_value_) { | |
3348 ASSERT(!handle_.is_null()); | |
3349 unique_id_ = UniqueValueId(handle_); | |
3350 } | |
3314 } | 3351 } |
3315 | 3352 |
3316 #ifdef DEBUG | 3353 #ifdef DEBUG |
3317 virtual void Verify() { } | 3354 virtual void Verify() { } |
3318 #endif | 3355 #endif |
3319 | 3356 |
3320 DECLARE_CONCRETE_INSTRUCTION(Constant) | 3357 DECLARE_CONCRETE_INSTRUCTION(Constant) |
3321 | 3358 |
3322 protected: | 3359 protected: |
3323 virtual Range* InferRange(Zone* zone); | 3360 virtual Range* InferRange(Zone* zone); |
3324 | 3361 |
3325 virtual bool DataEquals(HValue* other) { | 3362 virtual bool DataEquals(HValue* other) { |
3326 HConstant* other_constant = HConstant::cast(other); | 3363 HConstant* other_constant = HConstant::cast(other); |
3327 if (has_int32_value_) { | 3364 if (has_int32_value_) { |
3328 return other_constant->has_int32_value_ && | 3365 return other_constant->has_int32_value_ && |
3329 int32_value_ == other_constant->int32_value_; | 3366 int32_value_ == other_constant->int32_value_; |
3330 } else if (has_double_value_) { | 3367 } else if (has_double_value_) { |
3331 return other_constant->has_double_value_ && | 3368 return other_constant->has_double_value_ && |
3332 BitCast<int64_t>(double_value_) == | 3369 BitCast<int64_t>(double_value_) == |
3333 BitCast<int64_t>(other_constant->double_value_); | 3370 BitCast<int64_t>(other_constant->double_value_); |
3334 } else { | 3371 } else { |
3335 ASSERT(!handle_.is_null()); | 3372 ASSERT(!handle_.is_null()); |
3336 return !other_constant->handle_.is_null() && | 3373 return !other_constant->handle_.is_null() && |
3337 handle_.is_identical_to(other_constant->handle_); | 3374 unique_id_ == other_constant->unique_id_; |
3338 } | 3375 } |
3339 } | 3376 } |
3340 | 3377 |
3341 private: | 3378 private: |
3342 void Initialize(Representation r); | 3379 void Initialize(Representation r); |
3343 | 3380 |
3344 virtual bool IsDeletable() const { return true; } | 3381 virtual bool IsDeletable() const { return true; } |
3345 | 3382 |
3346 // If this is a numerical constant, handle_ either points to to the | 3383 // If this is a numerical constant, handle_ either points to to the |
3347 // HeapObject the constant originated from or is null. If the | 3384 // HeapObject the constant originated from or is null. If the |
3348 // constant is non-numeric, handle_ always points to a valid | 3385 // constant is non-numeric, handle_ always points to a valid |
3349 // constant HeapObject. | 3386 // constant HeapObject. |
3350 Handle<Object> handle_; | 3387 Handle<Object> handle_; |
3388 UniqueValueId unique_id_; | |
3351 | 3389 |
3352 // We store the HConstant in the most specific form safely possible. | 3390 // We store the HConstant in the most specific form safely possible. |
3353 // The two flags, has_int32_value_ and has_double_value_ tell us if | 3391 // The two flags, has_int32_value_ and has_double_value_ tell us if |
3354 // int32_value_ and double_value_ hold valid, safe representations | 3392 // int32_value_ and double_value_ hold valid, safe representations |
3355 // of the constant. has_int32_value_ implies has_double_value_ but | 3393 // of the constant. has_int32_value_ implies has_double_value_ but |
3356 // not the converse. | 3394 // not the converse. |
3357 bool has_int32_value_ : 1; | 3395 bool has_int32_value_ : 1; |
3358 bool has_double_value_ : 1; | 3396 bool has_double_value_ : 1; |
3359 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. | 3397 bool is_internalized_string_ : 1; // TODO(yangguo): make this part of HType. |
3360 bool boolean_value_ : 1; | 3398 bool boolean_value_ : 1; |
(...skipping 1391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4752 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) | 4790 DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue) |
4753 | 4791 |
4754 private: | 4792 private: |
4755 HPhi* incoming_value_; | 4793 HPhi* incoming_value_; |
4756 }; | 4794 }; |
4757 | 4795 |
4758 | 4796 |
4759 class HLoadGlobalCell: public HTemplateInstruction<0> { | 4797 class HLoadGlobalCell: public HTemplateInstruction<0> { |
4760 public: | 4798 public: |
4761 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details) | 4799 HLoadGlobalCell(Handle<JSGlobalPropertyCell> cell, PropertyDetails details) |
4762 : cell_(cell), details_(details) { | 4800 : cell_(cell), details_(details), unique_id_() { |
4763 set_representation(Representation::Tagged()); | 4801 set_representation(Representation::Tagged()); |
4764 SetFlag(kUseGVN); | 4802 SetFlag(kUseGVN); |
4765 SetGVNFlag(kDependsOnGlobalVars); | 4803 SetGVNFlag(kDependsOnGlobalVars); |
4766 } | 4804 } |
4767 | 4805 |
4768 Handle<JSGlobalPropertyCell> cell() const { return cell_; } | 4806 Handle<JSGlobalPropertyCell> cell() const { return cell_; } |
4769 bool RequiresHoleCheck() const; | 4807 bool RequiresHoleCheck() const; |
4770 | 4808 |
4771 virtual void PrintDataTo(StringStream* stream); | 4809 virtual void PrintDataTo(StringStream* stream); |
4772 | 4810 |
4773 virtual intptr_t Hashcode() { | 4811 virtual intptr_t Hashcode() { |
4774 ASSERT_ALLOCATION_DISABLED; | 4812 return unique_id_.Hashcode(); |
4775 // Dereferencing to use the object's raw address for hashing is safe. | 4813 } |
4776 HandleDereferenceGuard allow_handle_deref(isolate(), | 4814 |
4777 HandleDereferenceGuard::ALLOW); | 4815 virtual void FinalizeUniqueValueId() { |
4778 SLOW_ASSERT(Heap::RelocationLock::IsLocked(isolate()->heap()) || | 4816 unique_id_ = UniqueValueId(cell_); |
4779 !isolate()->optimizing_compiler_thread()->IsOptimizerThread()); | |
4780 return reinterpret_cast<intptr_t>(*cell_); | |
4781 } | 4817 } |
4782 | 4818 |
4783 virtual Representation RequiredInputRepresentation(int index) { | 4819 virtual Representation RequiredInputRepresentation(int index) { |
4784 return Representation::None(); | 4820 return Representation::None(); |
4785 } | 4821 } |
4786 | 4822 |
4787 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell) | 4823 DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell) |
4788 | 4824 |
4789 protected: | 4825 protected: |
4790 virtual bool DataEquals(HValue* other) { | 4826 virtual bool DataEquals(HValue* other) { |
4791 HLoadGlobalCell* b = HLoadGlobalCell::cast(other); | 4827 HLoadGlobalCell* b = HLoadGlobalCell::cast(other); |
4792 return cell_.is_identical_to(b->cell()); | 4828 return unique_id_ == b->unique_id_; |
4793 } | 4829 } |
4794 | 4830 |
4795 private: | 4831 private: |
4796 virtual bool IsDeletable() const { return !RequiresHoleCheck(); } | 4832 virtual bool IsDeletable() const { return !RequiresHoleCheck(); } |
4797 | 4833 |
4798 Handle<JSGlobalPropertyCell> cell_; | 4834 Handle<JSGlobalPropertyCell> cell_; |
4799 PropertyDetails details_; | 4835 PropertyDetails details_; |
4836 UniqueValueId unique_id_; | |
4800 }; | 4837 }; |
4801 | 4838 |
4802 | 4839 |
4803 class HLoadGlobalGeneric: public HTemplateInstruction<2> { | 4840 class HLoadGlobalGeneric: public HTemplateInstruction<2> { |
4804 public: | 4841 public: |
4805 HLoadGlobalGeneric(HValue* context, | 4842 HLoadGlobalGeneric(HValue* context, |
4806 HValue* global_object, | 4843 HValue* global_object, |
4807 Handle<Object> name, | 4844 Handle<Object> name, |
4808 bool for_typeof) | 4845 bool for_typeof) |
4809 : name_(name), | 4846 : name_(name), |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5249 virtual Representation RequiredInputRepresentation(int index) { | 5286 virtual Representation RequiredInputRepresentation(int index) { |
5250 return Representation::Tagged(); | 5287 return Representation::Tagged(); |
5251 } | 5288 } |
5252 | 5289 |
5253 virtual void PrintDataTo(StringStream* stream); | 5290 virtual void PrintDataTo(StringStream* stream); |
5254 | 5291 |
5255 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic) | 5292 DECLARE_CONCRETE_INSTRUCTION(LoadNamedFieldPolymorphic) |
5256 | 5293 |
5257 static const int kMaxLoadPolymorphism = 4; | 5294 static const int kMaxLoadPolymorphism = 4; |
5258 | 5295 |
5296 virtual void FinalizeUniqueValueId(); | |
5297 | |
5259 protected: | 5298 protected: |
5260 virtual bool DataEquals(HValue* value); | 5299 virtual bool DataEquals(HValue* value); |
5261 | 5300 |
5262 private: | 5301 private: |
5263 SmallMapList types_; | 5302 SmallMapList types_; |
5264 Handle<String> name_; | 5303 Handle<String> name_; |
5304 ZoneList<UniqueValueId> types_unique_ids_; | |
5305 UniqueValueId name_unique_id_; | |
5265 bool need_generic_; | 5306 bool need_generic_; |
5266 }; | 5307 }; |
5267 | 5308 |
5268 | 5309 |
5269 | 5310 |
5270 class HLoadNamedGeneric: public HTemplateInstruction<2> { | 5311 class HLoadNamedGeneric: public HTemplateInstruction<2> { |
5271 public: | 5312 public: |
5272 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name) | 5313 HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name) |
5273 : name_(name) { | 5314 : name_(name) { |
5274 SetOperandAt(0, context); | 5315 SetOperandAt(0, context); |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5518 class HStoreNamedField: public HTemplateInstruction<2> { | 5559 class HStoreNamedField: public HTemplateInstruction<2> { |
5519 public: | 5560 public: |
5520 HStoreNamedField(HValue* obj, | 5561 HStoreNamedField(HValue* obj, |
5521 Handle<String> name, | 5562 Handle<String> name, |
5522 HValue* val, | 5563 HValue* val, |
5523 bool in_object, | 5564 bool in_object, |
5524 int offset) | 5565 int offset) |
5525 : name_(name), | 5566 : name_(name), |
5526 is_in_object_(in_object), | 5567 is_in_object_(in_object), |
5527 offset_(offset), | 5568 offset_(offset), |
5569 transition_unique_id_(), | |
5528 new_space_dominator_(NULL) { | 5570 new_space_dominator_(NULL) { |
5529 SetOperandAt(0, obj); | 5571 SetOperandAt(0, obj); |
5530 SetOperandAt(1, val); | 5572 SetOperandAt(1, val); |
5531 SetFlag(kTrackSideEffectDominators); | 5573 SetFlag(kTrackSideEffectDominators); |
5532 SetGVNFlag(kDependsOnNewSpacePromotion); | 5574 SetGVNFlag(kDependsOnNewSpacePromotion); |
5533 if (is_in_object_) { | 5575 if (is_in_object_) { |
5534 SetGVNFlag(kChangesInobjectFields); | 5576 SetGVNFlag(kChangesInobjectFields); |
5535 } else { | 5577 } else { |
5536 SetGVNFlag(kChangesBackingStoreFields); | 5578 SetGVNFlag(kChangesBackingStoreFields); |
5537 } | 5579 } |
(...skipping 10 matching lines...) Expand all Loading... | |
5548 } | 5590 } |
5549 virtual void PrintDataTo(StringStream* stream); | 5591 virtual void PrintDataTo(StringStream* stream); |
5550 | 5592 |
5551 HValue* object() { return OperandAt(0); } | 5593 HValue* object() { return OperandAt(0); } |
5552 HValue* value() { return OperandAt(1); } | 5594 HValue* value() { return OperandAt(1); } |
5553 | 5595 |
5554 Handle<String> name() const { return name_; } | 5596 Handle<String> name() const { return name_; } |
5555 bool is_in_object() const { return is_in_object_; } | 5597 bool is_in_object() const { return is_in_object_; } |
5556 int offset() const { return offset_; } | 5598 int offset() const { return offset_; } |
5557 Handle<Map> transition() const { return transition_; } | 5599 Handle<Map> transition() const { return transition_; } |
5600 UniqueValueId transition_unique_id() const { return transition_unique_id_; } | |
5558 void set_transition(Handle<Map> map) { transition_ = map; } | 5601 void set_transition(Handle<Map> map) { transition_ = map; } |
5559 HValue* new_space_dominator() const { return new_space_dominator_; } | 5602 HValue* new_space_dominator() const { return new_space_dominator_; } |
5560 | 5603 |
5561 bool NeedsWriteBarrier() { | 5604 bool NeedsWriteBarrier() { |
5562 return StoringValueNeedsWriteBarrier(value()) && | 5605 return StoringValueNeedsWriteBarrier(value()) && |
5563 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 5606 ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
5564 } | 5607 } |
5565 | 5608 |
5566 bool NeedsWriteBarrierForMap() { | 5609 bool NeedsWriteBarrierForMap() { |
5567 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); | 5610 return ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator()); |
5568 } | 5611 } |
5569 | 5612 |
5613 virtual void FinalizeUniqueValueId() { | |
5614 transition_unique_id_ = UniqueValueId(transition_); | |
5615 } | |
5616 | |
5570 private: | 5617 private: |
5571 Handle<String> name_; | 5618 Handle<String> name_; |
5572 bool is_in_object_; | 5619 bool is_in_object_; |
5573 int offset_; | 5620 int offset_; |
5574 Handle<Map> transition_; | 5621 Handle<Map> transition_; |
5622 UniqueValueId transition_unique_id_; | |
5575 HValue* new_space_dominator_; | 5623 HValue* new_space_dominator_; |
5576 }; | 5624 }; |
5577 | 5625 |
5578 | 5626 |
5579 class HStoreNamedGeneric: public HTemplateInstruction<3> { | 5627 class HStoreNamedGeneric: public HTemplateInstruction<3> { |
5580 public: | 5628 public: |
5581 HStoreNamedGeneric(HValue* context, | 5629 HStoreNamedGeneric(HValue* context, |
5582 HValue* object, | 5630 HValue* object, |
5583 Handle<String> name, | 5631 Handle<String> name, |
5584 HValue* value, | 5632 HValue* value, |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5765 | 5813 |
5766 | 5814 |
5767 class HTransitionElementsKind: public HTemplateInstruction<2> { | 5815 class HTransitionElementsKind: public HTemplateInstruction<2> { |
5768 public: | 5816 public: |
5769 HTransitionElementsKind(HValue* context, | 5817 HTransitionElementsKind(HValue* context, |
5770 HValue* object, | 5818 HValue* object, |
5771 Handle<Map> original_map, | 5819 Handle<Map> original_map, |
5772 Handle<Map> transitioned_map) | 5820 Handle<Map> transitioned_map) |
5773 : original_map_(original_map), | 5821 : original_map_(original_map), |
5774 transitioned_map_(transitioned_map), | 5822 transitioned_map_(transitioned_map), |
5823 original_map_unique_id_(), | |
5824 transitioned_map_unique_id_(), | |
5775 from_kind_(original_map->elements_kind()), | 5825 from_kind_(original_map->elements_kind()), |
5776 to_kind_(transitioned_map->elements_kind()) { | 5826 to_kind_(transitioned_map->elements_kind()) { |
5777 SetOperandAt(0, object); | 5827 SetOperandAt(0, object); |
5778 SetOperandAt(1, context); | 5828 SetOperandAt(1, context); |
5779 SetFlag(kUseGVN); | 5829 SetFlag(kUseGVN); |
5780 SetGVNFlag(kChangesElementsKind); | 5830 SetGVNFlag(kChangesElementsKind); |
5781 if (original_map->has_fast_double_elements()) { | 5831 if (original_map->has_fast_double_elements()) { |
5782 SetGVNFlag(kChangesElementsPointer); | 5832 SetGVNFlag(kChangesElementsPointer); |
5783 SetGVNFlag(kChangesNewSpacePromotion); | 5833 SetGVNFlag(kChangesNewSpacePromotion); |
5784 } | 5834 } |
(...skipping 10 matching lines...) Expand all Loading... | |
5795 | 5845 |
5796 HValue* object() { return OperandAt(0); } | 5846 HValue* object() { return OperandAt(0); } |
5797 HValue* context() { return OperandAt(1); } | 5847 HValue* context() { return OperandAt(1); } |
5798 Handle<Map> original_map() { return original_map_; } | 5848 Handle<Map> original_map() { return original_map_; } |
5799 Handle<Map> transitioned_map() { return transitioned_map_; } | 5849 Handle<Map> transitioned_map() { return transitioned_map_; } |
5800 ElementsKind from_kind() { return from_kind_; } | 5850 ElementsKind from_kind() { return from_kind_; } |
5801 ElementsKind to_kind() { return to_kind_; } | 5851 ElementsKind to_kind() { return to_kind_; } |
5802 | 5852 |
5803 virtual void PrintDataTo(StringStream* stream); | 5853 virtual void PrintDataTo(StringStream* stream); |
5804 | 5854 |
5855 virtual void FinalizeUniqueValueId() { | |
5856 original_map_unique_id_ = UniqueValueId(original_map_); | |
5857 transitioned_map_unique_id_ = UniqueValueId(transitioned_map_); | |
5858 } | |
5859 | |
5805 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) | 5860 DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind) |
5806 | 5861 |
5807 protected: | 5862 protected: |
5808 virtual bool DataEquals(HValue* other) { | 5863 virtual bool DataEquals(HValue* other) { |
5809 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other); | 5864 HTransitionElementsKind* instr = HTransitionElementsKind::cast(other); |
5810 return original_map_.is_identical_to(instr->original_map()) && | 5865 return original_map_unique_id_ == instr->original_map_unique_id_ && |
5811 transitioned_map_.is_identical_to(instr->transitioned_map()); | 5866 transitioned_map_unique_id_ == instr->transitioned_map_unique_id_; |
5812 } | 5867 } |
5813 | 5868 |
5814 private: | 5869 private: |
5815 Handle<Map> original_map_; | 5870 Handle<Map> original_map_; |
5816 Handle<Map> transitioned_map_; | 5871 Handle<Map> transitioned_map_; |
5872 UniqueValueId original_map_unique_id_; | |
5873 UniqueValueId transitioned_map_unique_id_; | |
5817 ElementsKind from_kind_; | 5874 ElementsKind from_kind_; |
5818 ElementsKind to_kind_; | 5875 ElementsKind to_kind_; |
5819 }; | 5876 }; |
5820 | 5877 |
5821 | 5878 |
5822 class HStringAdd: public HBinaryOperation { | 5879 class HStringAdd: public HBinaryOperation { |
5823 public: | 5880 public: |
5824 static HInstruction* New(Zone* zone, | 5881 static HInstruction* New(Zone* zone, |
5825 HValue* context, | 5882 HValue* context, |
5826 HValue* left, | 5883 HValue* left, |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6432 virtual bool IsDeletable() const { return true; } | 6489 virtual bool IsDeletable() const { return true; } |
6433 }; | 6490 }; |
6434 | 6491 |
6435 | 6492 |
6436 #undef DECLARE_INSTRUCTION | 6493 #undef DECLARE_INSTRUCTION |
6437 #undef DECLARE_CONCRETE_INSTRUCTION | 6494 #undef DECLARE_CONCRETE_INSTRUCTION |
6438 | 6495 |
6439 } } // namespace v8::internal | 6496 } } // namespace v8::internal |
6440 | 6497 |
6441 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6498 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |