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