| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ | 5 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_ |
| 6 #define V8_HYDROGEN_INSTRUCTIONS_H_ | 6 #define V8_HYDROGEN_INSTRUCTIONS_H_ |
| 7 | 7 |
| 8 #include "v8.h" | 8 #include "v8.h" |
| 9 | 9 |
| 10 #include "allocation.h" | 10 #include "allocation.h" |
| 11 #include "code-stubs.h" | 11 #include "code-stubs.h" |
| 12 #include "conversions.h" | 12 #include "conversions.h" |
| 13 #include "data-flow.h" | 13 #include "data-flow.h" |
| 14 #include "deoptimizer.h" | 14 #include "deoptimizer.h" |
| 15 #include "hydrogen-types.h" |
| 15 #include "small-pointer-list.h" | 16 #include "small-pointer-list.h" |
| 16 #include "string-stream.h" | 17 #include "string-stream.h" |
| 17 #include "unique.h" | 18 #include "unique.h" |
| 18 #include "utils.h" | 19 #include "utils.h" |
| 19 #include "zone.h" | 20 #include "zone.h" |
| 20 | 21 |
| 21 namespace v8 { | 22 namespace v8 { |
| 22 namespace internal { | 23 namespace internal { |
| 23 | 24 |
| 24 // Forward declarations. | 25 // Forward declarations. |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 bool MulAndCheckOverflow(const Representation& r, Range* other); | 276 bool MulAndCheckOverflow(const Representation& r, Range* other); |
| 276 | 277 |
| 277 private: | 278 private: |
| 278 int32_t lower_; | 279 int32_t lower_; |
| 279 int32_t upper_; | 280 int32_t upper_; |
| 280 Range* next_; | 281 Range* next_; |
| 281 bool can_be_minus_zero_; | 282 bool can_be_minus_zero_; |
| 282 }; | 283 }; |
| 283 | 284 |
| 284 | 285 |
| 285 class HType V8_FINAL { | |
| 286 public: | |
| 287 static HType None() { return HType(kNone); } | |
| 288 static HType Tagged() { return HType(kTagged); } | |
| 289 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } | |
| 290 static HType TaggedNumber() { return HType(kTaggedNumber); } | |
| 291 static HType Smi() { return HType(kSmi); } | |
| 292 static HType HeapNumber() { return HType(kHeapNumber); } | |
| 293 static HType String() { return HType(kString); } | |
| 294 static HType Boolean() { return HType(kBoolean); } | |
| 295 static HType NonPrimitive() { return HType(kNonPrimitive); } | |
| 296 static HType JSArray() { return HType(kJSArray); } | |
| 297 static HType JSObject() { return HType(kJSObject); } | |
| 298 | |
| 299 // Return the weakest (least precise) common type. | |
| 300 HType Combine(HType other) { | |
| 301 return HType(static_cast<Type>(type_ & other.type_)); | |
| 302 } | |
| 303 | |
| 304 bool Equals(const HType& other) const { | |
| 305 return type_ == other.type_; | |
| 306 } | |
| 307 | |
| 308 bool IsSubtypeOf(const HType& other) { | |
| 309 return Combine(other).Equals(other); | |
| 310 } | |
| 311 | |
| 312 bool IsTaggedPrimitive() const { | |
| 313 return ((type_ & kTaggedPrimitive) == kTaggedPrimitive); | |
| 314 } | |
| 315 | |
| 316 bool IsTaggedNumber() const { | |
| 317 return ((type_ & kTaggedNumber) == kTaggedNumber); | |
| 318 } | |
| 319 | |
| 320 bool IsSmi() const { | |
| 321 return ((type_ & kSmi) == kSmi); | |
| 322 } | |
| 323 | |
| 324 bool IsHeapNumber() const { | |
| 325 return ((type_ & kHeapNumber) == kHeapNumber); | |
| 326 } | |
| 327 | |
| 328 bool IsString() const { | |
| 329 return ((type_ & kString) == kString); | |
| 330 } | |
| 331 | |
| 332 bool IsNonString() const { | |
| 333 return IsTaggedPrimitive() || IsSmi() || IsHeapNumber() || | |
| 334 IsBoolean() || IsJSArray(); | |
| 335 } | |
| 336 | |
| 337 bool IsBoolean() const { | |
| 338 return ((type_ & kBoolean) == kBoolean); | |
| 339 } | |
| 340 | |
| 341 bool IsNonPrimitive() const { | |
| 342 return ((type_ & kNonPrimitive) == kNonPrimitive); | |
| 343 } | |
| 344 | |
| 345 bool IsJSArray() const { | |
| 346 return ((type_ & kJSArray) == kJSArray); | |
| 347 } | |
| 348 | |
| 349 bool IsJSObject() const { | |
| 350 return ((type_ & kJSObject) == kJSObject); | |
| 351 } | |
| 352 | |
| 353 bool IsHeapObject() const { | |
| 354 return IsHeapNumber() || IsString() || IsBoolean() || IsNonPrimitive(); | |
| 355 } | |
| 356 | |
| 357 bool ToStringOrToNumberCanBeObserved(Representation representation) { | |
| 358 switch (type_) { | |
| 359 case kTaggedPrimitive: // fallthru | |
| 360 case kTaggedNumber: // fallthru | |
| 361 case kSmi: // fallthru | |
| 362 case kHeapNumber: // fallthru | |
| 363 case kString: // fallthru | |
| 364 case kBoolean: | |
| 365 return false; | |
| 366 case kJSArray: // fallthru | |
| 367 case kJSObject: | |
| 368 return true; | |
| 369 case kTagged: | |
| 370 break; | |
| 371 } | |
| 372 return !representation.IsSmiOrInteger32() && !representation.IsDouble(); | |
| 373 } | |
| 374 | |
| 375 static HType TypeFromValue(Handle<Object> value); | |
| 376 | |
| 377 const char* ToString(); | |
| 378 | |
| 379 private: | |
| 380 enum Type { | |
| 381 kNone = 0x0, // 0000 0000 0000 0000 | |
| 382 kTagged = 0x1, // 0000 0000 0000 0001 | |
| 383 kTaggedPrimitive = 0x5, // 0000 0000 0000 0101 | |
| 384 kTaggedNumber = 0xd, // 0000 0000 0000 1101 | |
| 385 kSmi = 0x1d, // 0000 0000 0001 1101 | |
| 386 kHeapNumber = 0x2d, // 0000 0000 0010 1101 | |
| 387 kString = 0x45, // 0000 0000 0100 0101 | |
| 388 kBoolean = 0x85, // 0000 0000 1000 0101 | |
| 389 kNonPrimitive = 0x101, // 0000 0001 0000 0001 | |
| 390 kJSObject = 0x301, // 0000 0011 0000 0001 | |
| 391 kJSArray = 0x701 // 0000 0111 0000 0001 | |
| 392 }; | |
| 393 | |
| 394 // Make sure type fits in int16. | |
| 395 STATIC_ASSERT(kJSArray < (1 << (2 * kBitsPerByte))); | |
| 396 | |
| 397 explicit HType(Type t) : type_(t) { } | |
| 398 | |
| 399 int16_t type_; | |
| 400 }; | |
| 401 | |
| 402 | |
| 403 class HUseListNode: public ZoneObject { | 286 class HUseListNode: public ZoneObject { |
| 404 public: | 287 public: |
| 405 HUseListNode(HValue* value, int index, HUseListNode* tail) | 288 HUseListNode(HValue* value, int index, HUseListNode* tail) |
| 406 : tail_(tail), value_(value), index_(index) { | 289 : tail_(tail), value_(value), index_(index) { |
| 407 } | 290 } |
| 408 | 291 |
| 409 HUseListNode* tail(); | 292 HUseListNode* tail(); |
| 410 HValue* value() const { return value_; } | 293 HValue* value() const { return value_; } |
| 411 int index() const { return index_; } | 294 int index() const { return index_; } |
| 412 | 295 |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 } | 603 } |
| 721 return r; | 604 return r; |
| 722 } | 605 } |
| 723 | 606 |
| 724 HType type() const { return type_; } | 607 HType type() const { return type_; } |
| 725 void set_type(HType new_type) { | 608 void set_type(HType new_type) { |
| 726 ASSERT(new_type.IsSubtypeOf(type_)); | 609 ASSERT(new_type.IsSubtypeOf(type_)); |
| 727 type_ = new_type; | 610 type_ = new_type; |
| 728 } | 611 } |
| 729 | 612 |
| 730 bool IsHeapObject() { | |
| 731 return representation_.IsHeapObject() || type_.IsHeapObject(); | |
| 732 } | |
| 733 | |
| 734 // There are HInstructions that do not really change a value, they | 613 // There are HInstructions that do not really change a value, they |
| 735 // only add pieces of information to it (like bounds checks, map checks, | 614 // only add pieces of information to it (like bounds checks, map checks, |
| 736 // smi checks...). | 615 // smi checks...). |
| 737 // We call these instructions "informative definitions", or "iDef". | 616 // We call these instructions "informative definitions", or "iDef". |
| 738 // One of the iDef operands is special because it is the value that is | 617 // One of the iDef operands is special because it is the value that is |
| 739 // "transferred" to the output, we call it the "redefined operand". | 618 // "transferred" to the output, we call it the "redefined operand". |
| 740 // If an HValue is an iDef it must override RedefinedOperandIndex() so that | 619 // If an HValue is an iDef it must override RedefinedOperandIndex() so that |
| 741 // it does not return kNoRedefinedOperand; | 620 // it does not return kNoRedefinedOperand; |
| 742 static const int kNoRedefinedOperand = -1; | 621 static const int kNoRedefinedOperand = -1; |
| 743 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; } | 622 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; } |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 if (RedefinedOperand() != NULL) { | 805 if (RedefinedOperand() != NULL) { |
| 927 return RedefinedOperand()->TryDecompose(decomposition); | 806 return RedefinedOperand()->TryDecompose(decomposition); |
| 928 } else { | 807 } else { |
| 929 return false; | 808 return false; |
| 930 } | 809 } |
| 931 } | 810 } |
| 932 | 811 |
| 933 // Returns true conservatively if the program might be able to observe a | 812 // Returns true conservatively if the program might be able to observe a |
| 934 // ToString() operation on this value. | 813 // ToString() operation on this value. |
| 935 bool ToStringCanBeObserved() const { | 814 bool ToStringCanBeObserved() const { |
| 936 return type().ToStringOrToNumberCanBeObserved(representation()); | 815 return ToStringOrToNumberCanBeObserved(); |
| 937 } | 816 } |
| 938 | 817 |
| 939 // Returns true conservatively if the program might be able to observe a | 818 // Returns true conservatively if the program might be able to observe a |
| 940 // ToNumber() operation on this value. | 819 // ToNumber() operation on this value. |
| 941 bool ToNumberCanBeObserved() const { | 820 bool ToNumberCanBeObserved() const { |
| 942 return type().ToStringOrToNumberCanBeObserved(representation()); | 821 return ToStringOrToNumberCanBeObserved(); |
| 943 } | 822 } |
| 944 | 823 |
| 945 MinusZeroMode GetMinusZeroMode() { | 824 MinusZeroMode GetMinusZeroMode() { |
| 946 return CheckFlag(kBailoutOnMinusZero) | 825 return CheckFlag(kBailoutOnMinusZero) |
| 947 ? FAIL_ON_MINUS_ZERO : TREAT_MINUS_ZERO_AS_ZERO; | 826 ? FAIL_ON_MINUS_ZERO : TREAT_MINUS_ZERO_AS_ZERO; |
| 948 } | 827 } |
| 949 | 828 |
| 950 protected: | 829 protected: |
| 951 // This function must be overridden for instructions with flag kUseGVN, to | 830 // This function must be overridden for instructions with flag kUseGVN, to |
| 952 // compare the non-Operand parts of the instruction. | 831 // compare the non-Operand parts of the instruction. |
| 953 virtual bool DataEquals(HValue* other) { | 832 virtual bool DataEquals(HValue* other) { |
| 954 UNREACHABLE(); | 833 UNREACHABLE(); |
| 955 return false; | 834 return false; |
| 956 } | 835 } |
| 957 | 836 |
| 837 bool ToStringOrToNumberCanBeObserved() const { |
| 838 if (type().IsTaggedPrimitive()) return false; |
| 839 if (type().IsJSObject()) return true; |
| 840 return !representation().IsSmiOrInteger32() && !representation().IsDouble(); |
| 841 } |
| 842 |
| 958 virtual Representation RepresentationFromInputs() { | 843 virtual Representation RepresentationFromInputs() { |
| 959 return representation(); | 844 return representation(); |
| 960 } | 845 } |
| 961 virtual Representation RepresentationFromUses(); | 846 virtual Representation RepresentationFromUses(); |
| 962 Representation RepresentationFromUseRequirements(); | 847 Representation RepresentationFromUseRequirements(); |
| 963 bool HasNonSmiUse(); | 848 bool HasNonSmiUse(); |
| 964 virtual void UpdateRepresentation(Representation new_rep, | 849 virtual void UpdateRepresentation(Representation new_rep, |
| 965 HInferRepresentationPhase* h_infer, | 850 HInferRepresentationPhase* h_infer, |
| 966 const char* reason); | 851 const char* reason); |
| 967 void AddDependantsToWorklist(HInferRepresentationPhase* h_infer); | 852 void AddDependantsToWorklist(HInferRepresentationPhase* h_infer); |
| (...skipping 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2832 is_stability_check_ = true; | 2717 is_stability_check_ = true; |
| 2833 ClearChangesFlag(kNewSpacePromotion); | 2718 ClearChangesFlag(kNewSpacePromotion); |
| 2834 ClearDependsOnFlag(kElementsKind); | 2719 ClearDependsOnFlag(kElementsKind); |
| 2835 ClearDependsOnFlag(kMaps); | 2720 ClearDependsOnFlag(kMaps); |
| 2836 } | 2721 } |
| 2837 | 2722 |
| 2838 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } | 2723 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } |
| 2839 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2724 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 2840 return Representation::Tagged(); | 2725 return Representation::Tagged(); |
| 2841 } | 2726 } |
| 2727 |
| 2728 virtual HType CalculateInferredType() V8_OVERRIDE { |
| 2729 if (value()->type().IsHeapObject()) return value()->type(); |
| 2730 return HType::HeapObject(); |
| 2731 } |
| 2732 |
| 2842 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 2733 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 2843 | 2734 |
| 2844 HValue* value() { return OperandAt(0); } | 2735 HValue* value() const { return OperandAt(0); } |
| 2845 HValue* typecheck() { return OperandAt(1); } | 2736 HValue* typecheck() const { return OperandAt(1); } |
| 2846 | 2737 |
| 2847 const UniqueSet<Map>* maps() const { return maps_; } | 2738 const UniqueSet<Map>* maps() const { return maps_; } |
| 2848 void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; } | 2739 void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; } |
| 2849 | 2740 |
| 2850 bool maps_are_stable() const { return maps_are_stable_; } | 2741 bool maps_are_stable() const { return maps_are_stable_; } |
| 2851 | 2742 |
| 2852 bool HasMigrationTarget() const { return has_migration_target_; } | 2743 bool HasMigrationTarget() const { return has_migration_target_; } |
| 2853 | 2744 |
| 2854 virtual HValue* Canonicalize() V8_OVERRIDE; | 2745 virtual HValue* Canonicalize() V8_OVERRIDE; |
| 2855 | 2746 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2874 | 2765 |
| 2875 protected: | 2766 protected: |
| 2876 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 2767 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| 2877 return this->maps()->Equals(HCheckMaps::cast(other)->maps()); | 2768 return this->maps()->Equals(HCheckMaps::cast(other)->maps()); |
| 2878 } | 2769 } |
| 2879 | 2770 |
| 2880 virtual int RedefinedOperandIndex() { return 0; } | 2771 virtual int RedefinedOperandIndex() { return 0; } |
| 2881 | 2772 |
| 2882 private: | 2773 private: |
| 2883 HCheckMaps(HValue* value, const UniqueSet<Map>* maps, bool maps_are_stable) | 2774 HCheckMaps(HValue* value, const UniqueSet<Map>* maps, bool maps_are_stable) |
| 2884 : HTemplateInstruction<2>(value->type()), maps_(maps), | 2775 : HTemplateInstruction<2>(HType::HeapObject()), maps_(maps), |
| 2885 has_migration_target_(false), is_stability_check_(false), | 2776 has_migration_target_(false), is_stability_check_(false), |
| 2886 maps_are_stable_(maps_are_stable) { | 2777 maps_are_stable_(maps_are_stable) { |
| 2887 ASSERT_NE(0, maps->size()); | 2778 ASSERT_NE(0, maps->size()); |
| 2888 SetOperandAt(0, value); | 2779 SetOperandAt(0, value); |
| 2889 // Use the object value for the dependency. | 2780 // Use the object value for the dependency. |
| 2890 SetOperandAt(1, value); | 2781 SetOperandAt(1, value); |
| 2891 set_representation(Representation::Tagged()); | 2782 set_representation(Representation::Tagged()); |
| 2892 SetFlag(kUseGVN); | 2783 SetFlag(kUseGVN); |
| 2893 SetDependsOnFlag(kMaps); | 2784 SetDependsOnFlag(kMaps); |
| 2894 SetDependsOnFlag(kElementsKind); | 2785 SetDependsOnFlag(kElementsKind); |
| 2895 } | 2786 } |
| 2896 | 2787 |
| 2897 HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck) | 2788 HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck) |
| 2898 : HTemplateInstruction<2>(value->type()), maps_(maps), | 2789 : HTemplateInstruction<2>(HType::HeapObject()), maps_(maps), |
| 2899 has_migration_target_(false), is_stability_check_(false), | 2790 has_migration_target_(false), is_stability_check_(false), |
| 2900 maps_are_stable_(true) { | 2791 maps_are_stable_(true) { |
| 2901 ASSERT_NE(0, maps->size()); | 2792 ASSERT_NE(0, maps->size()); |
| 2902 SetOperandAt(0, value); | 2793 SetOperandAt(0, value); |
| 2903 // Use the object value for the dependency if NULL is passed. | 2794 // Use the object value for the dependency if NULL is passed. |
| 2904 SetOperandAt(1, typecheck ? typecheck : value); | 2795 SetOperandAt(1, typecheck ? typecheck : value); |
| 2905 set_representation(Representation::Tagged()); | 2796 set_representation(Representation::Tagged()); |
| 2906 SetFlag(kUseGVN); | 2797 SetFlag(kUseGVN); |
| 2907 SetDependsOnFlag(kMaps); | 2798 SetDependsOnFlag(kMaps); |
| 2908 SetDependsOnFlag(kElementsKind); | 2799 SetDependsOnFlag(kElementsKind); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2992 }; | 2883 }; |
| 2993 | 2884 |
| 2994 DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check); | 2885 DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check); |
| 2995 | 2886 |
| 2996 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 2887 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 2997 | 2888 |
| 2998 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2889 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 2999 return Representation::Tagged(); | 2890 return Representation::Tagged(); |
| 3000 } | 2891 } |
| 3001 | 2892 |
| 2893 virtual HType CalculateInferredType() V8_OVERRIDE { |
| 2894 switch (check_) { |
| 2895 case IS_SPEC_OBJECT: return HType::JSObject(); |
| 2896 case IS_JS_ARRAY: return HType::JSArray(); |
| 2897 case IS_STRING: return HType::String(); |
| 2898 case IS_INTERNALIZED_STRING: return HType::String(); |
| 2899 } |
| 2900 UNREACHABLE(); |
| 2901 return HType::Tagged(); |
| 2902 } |
| 2903 |
| 3002 virtual HValue* Canonicalize() V8_OVERRIDE; | 2904 virtual HValue* Canonicalize() V8_OVERRIDE; |
| 3003 | 2905 |
| 3004 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; } | 2906 bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; } |
| 3005 void GetCheckInterval(InstanceType* first, InstanceType* last); | 2907 void GetCheckInterval(InstanceType* first, InstanceType* last); |
| 3006 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag); | 2908 void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag); |
| 3007 | 2909 |
| 3008 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType) | 2910 DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType) |
| 3009 | 2911 |
| 3010 protected: | 2912 protected: |
| 3011 // TODO(ager): It could be nice to allow the ommision of instance | 2913 // TODO(ager): It could be nice to allow the ommision of instance |
| 3012 // type checks if we have already performed an instance type check | 2914 // type checks if we have already performed an instance type check |
| 3013 // with a larger range. | 2915 // with a larger range. |
| 3014 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 2916 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| 3015 HCheckInstanceType* b = HCheckInstanceType::cast(other); | 2917 HCheckInstanceType* b = HCheckInstanceType::cast(other); |
| 3016 return check_ == b->check_; | 2918 return check_ == b->check_; |
| 3017 } | 2919 } |
| 3018 | 2920 |
| 3019 virtual int RedefinedOperandIndex() { return 0; } | 2921 virtual int RedefinedOperandIndex() { return 0; } |
| 3020 | 2922 |
| 3021 private: | 2923 private: |
| 3022 const char* GetCheckName(); | 2924 const char* GetCheckName(); |
| 3023 | 2925 |
| 3024 HCheckInstanceType(HValue* value, Check check) | 2926 HCheckInstanceType(HValue* value, Check check) |
| 3025 : HUnaryOperation(value), check_(check) { | 2927 : HUnaryOperation(value, HType::HeapObject()), check_(check) { |
| 3026 set_representation(Representation::Tagged()); | 2928 set_representation(Representation::Tagged()); |
| 3027 SetFlag(kUseGVN); | 2929 SetFlag(kUseGVN); |
| 3028 } | 2930 } |
| 3029 | 2931 |
| 3030 const Check check_; | 2932 const Check check_; |
| 3031 }; | 2933 }; |
| 3032 | 2934 |
| 3033 | 2935 |
| 3034 class HCheckSmi V8_FINAL : public HUnaryOperation { | 2936 class HCheckSmi V8_FINAL : public HUnaryOperation { |
| 3035 public: | 2937 public: |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3062 | 2964 |
| 3063 class HCheckHeapObject V8_FINAL : public HUnaryOperation { | 2965 class HCheckHeapObject V8_FINAL : public HUnaryOperation { |
| 3064 public: | 2966 public: |
| 3065 DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); | 2967 DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); |
| 3066 | 2968 |
| 3067 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } | 2969 virtual bool HasEscapingOperandAt(int index) V8_OVERRIDE { return false; } |
| 3068 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2970 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 3069 return Representation::Tagged(); | 2971 return Representation::Tagged(); |
| 3070 } | 2972 } |
| 3071 | 2973 |
| 2974 virtual HType CalculateInferredType() V8_OVERRIDE { |
| 2975 if (value()->type().IsHeapObject()) return value()->type(); |
| 2976 return HType::HeapObject(); |
| 2977 } |
| 2978 |
| 3072 #ifdef DEBUG | 2979 #ifdef DEBUG |
| 3073 virtual void Verify() V8_OVERRIDE; | 2980 virtual void Verify() V8_OVERRIDE; |
| 3074 #endif | 2981 #endif |
| 3075 | 2982 |
| 3076 virtual HValue* Canonicalize() V8_OVERRIDE { | 2983 virtual HValue* Canonicalize() V8_OVERRIDE { |
| 3077 return value()->type().IsHeapObject() ? NULL : this; | 2984 return value()->type().IsHeapObject() ? NULL : this; |
| 3078 } | 2985 } |
| 3079 | 2986 |
| 3080 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) | 2987 DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject) |
| 3081 | 2988 |
| 3082 protected: | 2989 protected: |
| 3083 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } | 2990 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } |
| 3084 | 2991 |
| 3085 private: | 2992 private: |
| 3086 explicit HCheckHeapObject(HValue* value) | 2993 explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) { |
| 3087 : HUnaryOperation(value, HType::NonPrimitive()) { | |
| 3088 set_representation(Representation::Tagged()); | 2994 set_representation(Representation::Tagged()); |
| 3089 SetFlag(kUseGVN); | 2995 SetFlag(kUseGVN); |
| 3090 } | 2996 } |
| 3091 }; | 2997 }; |
| 3092 | 2998 |
| 3093 | 2999 |
| 3094 class InductionVariableData; | 3000 class InductionVariableData; |
| 3095 | 3001 |
| 3096 | 3002 |
| 3097 struct InductionVariableLimitUpdate { | 3003 struct InductionVariableLimitUpdate { |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3559 return instruction->Prepend(HConstant::New( | 3465 return instruction->Prepend(HConstant::New( |
| 3560 zone, context, value, representation)); | 3466 zone, context, value, representation)); |
| 3561 } | 3467 } |
| 3562 | 3468 |
| 3563 static HConstant* CreateAndInsertBefore(Zone* zone, | 3469 static HConstant* CreateAndInsertBefore(Zone* zone, |
| 3564 Unique<Map> map, | 3470 Unique<Map> map, |
| 3565 bool map_is_stable, | 3471 bool map_is_stable, |
| 3566 HInstruction* instruction) { | 3472 HInstruction* instruction) { |
| 3567 return instruction->Prepend(new(zone) HConstant( | 3473 return instruction->Prepend(new(zone) HConstant( |
| 3568 map, Unique<Map>(Handle<Map>::null()), map_is_stable, | 3474 map, Unique<Map>(Handle<Map>::null()), map_is_stable, |
| 3569 Representation::Tagged(), HType::Tagged(), true, | 3475 Representation::Tagged(), HType::HeapObject(), true, |
| 3570 false, false, MAP_TYPE)); | 3476 false, false, MAP_TYPE)); |
| 3571 } | 3477 } |
| 3572 | 3478 |
| 3573 static HConstant* CreateAndInsertAfter(Zone* zone, | 3479 static HConstant* CreateAndInsertAfter(Zone* zone, |
| 3574 Unique<Map> map, | 3480 Unique<Map> map, |
| 3575 bool map_is_stable, | 3481 bool map_is_stable, |
| 3576 HInstruction* instruction) { | 3482 HInstruction* instruction) { |
| 3577 return instruction->Append(new(zone) HConstant( | 3483 return instruction->Append(new(zone) HConstant( |
| 3578 map, Unique<Map>(Handle<Map>::null()), map_is_stable, | 3484 map, Unique<Map>(Handle<Map>::null()), map_is_stable, |
| 3579 Representation::Tagged(), HType::Tagged(), true, | 3485 Representation::Tagged(), HType::HeapObject(), true, |
| 3580 false, false, MAP_TYPE)); | 3486 false, false, MAP_TYPE)); |
| 3581 } | 3487 } |
| 3582 | 3488 |
| 3583 Handle<Object> handle(Isolate* isolate) { | 3489 Handle<Object> handle(Isolate* isolate) { |
| 3584 if (object_.handle().is_null()) { | 3490 if (object_.handle().is_null()) { |
| 3585 // Default arguments to is_not_in_new_space depend on this heap number | 3491 // Default arguments to is_not_in_new_space depend on this heap number |
| 3586 // to be tenured so that it's guaranteed not to be located in new space. | 3492 // to be tenured so that it's guaranteed not to be located in new space. |
| 3587 object_ = Unique<Object>::CreateUninitialized( | 3493 object_ = Unique<Object>::CreateUninitialized( |
| 3588 isolate->factory()->NewNumber(double_value_, TENURED)); | 3494 isolate->factory()->NewNumber(double_value_, TENURED)); |
| 3589 } | 3495 } |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4180 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 4086 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 4181 | 4087 |
| 4182 virtual int RedefinedOperandIndex() V8_OVERRIDE { return 0; } | 4088 virtual int RedefinedOperandIndex() V8_OVERRIDE { return 0; } |
| 4183 virtual bool IsPurelyInformativeDefinition() V8_OVERRIDE { return true; } | 4089 virtual bool IsPurelyInformativeDefinition() V8_OVERRIDE { return true; } |
| 4184 }; | 4090 }; |
| 4185 | 4091 |
| 4186 | 4092 |
| 4187 class HBitwiseBinaryOperation : public HBinaryOperation { | 4093 class HBitwiseBinaryOperation : public HBinaryOperation { |
| 4188 public: | 4094 public: |
| 4189 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right, | 4095 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right, |
| 4190 HType type = HType::Tagged()) | 4096 HType type = HType::TaggedNumber()) |
| 4191 : HBinaryOperation(context, left, right, type) { | 4097 : HBinaryOperation(context, left, right, type) { |
| 4192 SetFlag(kFlexibleRepresentation); | 4098 SetFlag(kFlexibleRepresentation); |
| 4193 SetFlag(kTruncatingToInt32); | 4099 SetFlag(kTruncatingToInt32); |
| 4194 SetFlag(kAllowUndefinedAsNaN); | 4100 SetFlag(kAllowUndefinedAsNaN); |
| 4195 SetAllSideEffects(); | 4101 SetAllSideEffects(); |
| 4196 } | 4102 } |
| 4197 | 4103 |
| 4198 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { | 4104 virtual void RepresentationChanged(Representation to) V8_OVERRIDE { |
| 4199 if (to.IsTagged() && | 4105 if (to.IsTagged() && |
| 4200 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) { | 4106 (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) { |
| (...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5133 return op() == HBitwise::cast(other)->op(); | 5039 return op() == HBitwise::cast(other)->op(); |
| 5134 } | 5040 } |
| 5135 | 5041 |
| 5136 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; | 5042 virtual Range* InferRange(Zone* zone) V8_OVERRIDE; |
| 5137 | 5043 |
| 5138 private: | 5044 private: |
| 5139 HBitwise(HValue* context, | 5045 HBitwise(HValue* context, |
| 5140 Token::Value op, | 5046 Token::Value op, |
| 5141 HValue* left, | 5047 HValue* left, |
| 5142 HValue* right) | 5048 HValue* right) |
| 5143 : HBitwiseBinaryOperation(context, left, right, HType::TaggedNumber()), | 5049 : HBitwiseBinaryOperation(context, left, right), |
| 5144 op_(op) { | 5050 op_(op) { |
| 5145 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); | 5051 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); |
| 5146 // BIT_AND with a smi-range positive value will always unset the | 5052 // BIT_AND with a smi-range positive value will always unset the |
| 5147 // entire sign-extension of the smi-sign. | 5053 // entire sign-extension of the smi-sign. |
| 5148 if (op == Token::BIT_AND && | 5054 if (op == Token::BIT_AND && |
| 5149 ((left->IsConstant() && | 5055 ((left->IsConstant() && |
| 5150 left->representation().IsSmi() && | 5056 left->representation().IsSmi() && |
| 5151 HConstant::cast(left)->Integer32Value() >= 0) || | 5057 HConstant::cast(left)->Integer32Value() >= 0) || |
| 5152 (right->IsConstant() && | 5058 (right->IsConstant() && |
| 5153 right->representation().IsSmi() && | 5059 right->representation().IsSmi() && |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5712 } | 5618 } |
| 5713 }; | 5619 }; |
| 5714 | 5620 |
| 5715 | 5621 |
| 5716 class HInnerAllocatedObject V8_FINAL : public HTemplateInstruction<2> { | 5622 class HInnerAllocatedObject V8_FINAL : public HTemplateInstruction<2> { |
| 5717 public: | 5623 public: |
| 5718 static HInnerAllocatedObject* New(Zone* zone, | 5624 static HInnerAllocatedObject* New(Zone* zone, |
| 5719 HValue* context, | 5625 HValue* context, |
| 5720 HValue* value, | 5626 HValue* value, |
| 5721 HValue* offset, | 5627 HValue* offset, |
| 5722 HType type = HType::Tagged()) { | 5628 HType type) { |
| 5723 return new(zone) HInnerAllocatedObject(value, offset, type); | 5629 return new(zone) HInnerAllocatedObject(value, offset, type); |
| 5724 } | 5630 } |
| 5725 | 5631 |
| 5726 HValue* base_object() { return OperandAt(0); } | 5632 HValue* base_object() { return OperandAt(0); } |
| 5727 HValue* offset() { return OperandAt(1); } | 5633 HValue* offset() { return OperandAt(1); } |
| 5728 | 5634 |
| 5729 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 5635 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 5730 return index == 0 ? Representation::Tagged() : Representation::Integer32(); | 5636 return index == 0 ? Representation::Tagged() : Representation::Integer32(); |
| 5731 } | 5637 } |
| 5732 | 5638 |
| 5733 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 5639 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 5734 | 5640 |
| 5735 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) | 5641 DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject) |
| 5736 | 5642 |
| 5737 private: | 5643 private: |
| 5738 HInnerAllocatedObject(HValue* value, | 5644 HInnerAllocatedObject(HValue* value, |
| 5739 HValue* offset, | 5645 HValue* offset, |
| 5740 HType type = HType::Tagged()) | 5646 HType type) : HTemplateInstruction<2>(type) { |
| 5741 : HTemplateInstruction<2>(type) { | |
| 5742 ASSERT(value->IsAllocate()); | 5647 ASSERT(value->IsAllocate()); |
| 5648 ASSERT(type.IsHeapObject()); |
| 5743 SetOperandAt(0, value); | 5649 SetOperandAt(0, value); |
| 5744 SetOperandAt(1, offset); | 5650 SetOperandAt(1, offset); |
| 5745 set_type(type); | |
| 5746 set_representation(Representation::Tagged()); | 5651 set_representation(Representation::Tagged()); |
| 5747 } | 5652 } |
| 5748 }; | 5653 }; |
| 5749 | 5654 |
| 5750 | 5655 |
| 5751 inline bool StoringValueNeedsWriteBarrier(HValue* value) { | 5656 inline bool StoringValueNeedsWriteBarrier(HValue* value) { |
| 5752 return !value->type().IsBoolean() | 5657 return !value->type().IsSmi() |
| 5753 && !value->type().IsSmi() | 5658 && !value->type().IsNull() |
| 5659 && !value->type().IsBoolean() |
| 5660 && !value->type().IsUndefined() |
| 5754 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); | 5661 && !(value->IsConstant() && HConstant::cast(value)->ImmortalImmovable()); |
| 5755 } | 5662 } |
| 5756 | 5663 |
| 5757 | 5664 |
| 5758 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, | 5665 inline bool ReceiverObjectNeedsWriteBarrier(HValue* object, |
| 5759 HValue* value, | 5666 HValue* value, |
| 5760 HValue* dominator) { | 5667 HValue* dominator) { |
| 5761 while (object->IsInnerAllocatedObject()) { | 5668 while (object->IsInnerAllocatedObject()) { |
| 5762 object = HInnerAllocatedObject::cast(object)->base_object(); | 5669 object = HInnerAllocatedObject::cast(object)->base_object(); |
| 5763 } | 5670 } |
| (...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6364 if (SmiValuesAre32Bits()) { | 6271 if (SmiValuesAre32Bits()) { |
| 6365 set_representation(Representation::Integer32()); | 6272 set_representation(Representation::Integer32()); |
| 6366 } else { | 6273 } else { |
| 6367 set_representation(representation); | 6274 set_representation(representation); |
| 6368 } | 6275 } |
| 6369 } else if (representation.IsDouble() || | 6276 } else if (representation.IsDouble() || |
| 6370 representation.IsExternal() || | 6277 representation.IsExternal() || |
| 6371 representation.IsInteger32()) { | 6278 representation.IsInteger32()) { |
| 6372 set_representation(representation); | 6279 set_representation(representation); |
| 6373 } else if (representation.IsHeapObject()) { | 6280 } else if (representation.IsHeapObject()) { |
| 6374 // TODO(bmeurer): This is probably broken. What we actually want to to | 6281 set_type(HType::HeapObject()); |
| 6375 // instead is set_representation(Representation::HeapObject()). | |
| 6376 set_type(HType::NonPrimitive()); | |
| 6377 set_representation(Representation::Tagged()); | 6282 set_representation(Representation::Tagged()); |
| 6378 } else { | 6283 } else { |
| 6379 set_representation(Representation::Tagged()); | 6284 set_representation(Representation::Tagged()); |
| 6380 } | 6285 } |
| 6381 access.SetGVNFlags(this, LOAD); | 6286 access.SetGVNFlags(this, LOAD); |
| 6382 } | 6287 } |
| 6383 | 6288 |
| 6384 HLoadNamedField(HValue* object, | 6289 HLoadNamedField(HValue* object, |
| 6385 HValue* dependency, | 6290 HValue* dependency, |
| 6386 HObjectAccess access, | 6291 HObjectAccess access, |
| 6387 const UniqueSet<Map>* maps, | 6292 const UniqueSet<Map>* maps, |
| 6388 HType type) | 6293 HType type) |
| 6389 : HTemplateInstruction<2>(type), access_(access), maps_(maps) { | 6294 : HTemplateInstruction<2>(type), access_(access), maps_(maps) { |
| 6390 ASSERT_NOT_NULL(maps); | 6295 ASSERT_NOT_NULL(maps); |
| 6391 ASSERT_NE(0, maps->size()); | 6296 ASSERT_NE(0, maps->size()); |
| 6392 | 6297 |
| 6393 ASSERT_NOT_NULL(object); | 6298 ASSERT_NOT_NULL(object); |
| 6394 SetOperandAt(0, object); | 6299 SetOperandAt(0, object); |
| 6395 SetOperandAt(1, dependency ? dependency : object); | 6300 SetOperandAt(1, dependency ? dependency : object); |
| 6396 | 6301 |
| 6397 ASSERT(access.representation().IsHeapObject()); | 6302 ASSERT(access.representation().IsHeapObject()); |
| 6398 // TODO(bmeurer): This is probably broken. What we actually want to to | 6303 ASSERT(type.IsHeapObject()); |
| 6399 // instead is set_representation(Representation::HeapObject()). | |
| 6400 if (!type.IsHeapObject()) set_type(HType::NonPrimitive()); | |
| 6401 set_representation(Representation::Tagged()); | 6304 set_representation(Representation::Tagged()); |
| 6402 | 6305 |
| 6403 access.SetGVNFlags(this, LOAD); | 6306 access.SetGVNFlags(this, LOAD); |
| 6404 } | 6307 } |
| 6405 | 6308 |
| 6406 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 6309 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 6407 | 6310 |
| 6408 HObjectAccess access_; | 6311 HObjectAccess access_; |
| 6409 const UniqueSet<Map>* maps_; | 6312 const UniqueSet<Map>* maps_; |
| 6410 }; | 6313 }; |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6806 new_space_dominator()); | 6709 new_space_dominator()); |
| 6807 } | 6710 } |
| 6808 | 6711 |
| 6809 bool NeedsWriteBarrierForMap() { | 6712 bool NeedsWriteBarrierForMap() { |
| 6810 return ReceiverObjectNeedsWriteBarrier(object(), transition(), | 6713 return ReceiverObjectNeedsWriteBarrier(object(), transition(), |
| 6811 new_space_dominator()); | 6714 new_space_dominator()); |
| 6812 } | 6715 } |
| 6813 | 6716 |
| 6814 SmiCheck SmiCheckForWriteBarrier() const { | 6717 SmiCheck SmiCheckForWriteBarrier() const { |
| 6815 if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK; | 6718 if (field_representation().IsHeapObject()) return OMIT_SMI_CHECK; |
| 6816 if (value()->IsHeapObject()) return OMIT_SMI_CHECK; | 6719 if (value()->type().IsHeapObject()) return OMIT_SMI_CHECK; |
| 6817 return INLINE_SMI_CHECK; | 6720 return INLINE_SMI_CHECK; |
| 6818 } | 6721 } |
| 6819 | 6722 |
| 6820 Representation field_representation() const { | 6723 Representation field_representation() const { |
| 6821 return access_.representation(); | 6724 return access_.representation(); |
| 6822 } | 6725 } |
| 6823 | 6726 |
| 6824 void UpdateValue(HValue* value) { | 6727 void UpdateValue(HValue* value) { |
| 6825 SetOperandAt(1, value); | 6728 SetOperandAt(1, value); |
| 6826 } | 6729 } |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7666 public: | 7569 public: |
| 7667 DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*); | 7570 DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*); |
| 7668 | 7571 |
| 7669 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 7572 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 7670 return Representation::Tagged(); | 7573 return Representation::Tagged(); |
| 7671 } | 7574 } |
| 7672 | 7575 |
| 7673 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 7576 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 7674 | 7577 |
| 7675 virtual HType CalculateInferredType() V8_OVERRIDE { | 7578 virtual HType CalculateInferredType() V8_OVERRIDE { |
| 7676 return HType::Tagged(); | 7579 if (value()->type().IsHeapObject()) return value()->type(); |
| 7580 return HType::HeapObject(); |
| 7677 } | 7581 } |
| 7678 | 7582 |
| 7679 HValue* value() { return OperandAt(0); } | 7583 HValue* value() const { return OperandAt(0); } |
| 7680 HValue* map() { return OperandAt(1); } | 7584 HValue* map() const { return OperandAt(1); } |
| 7681 | 7585 |
| 7682 virtual HValue* Canonicalize() V8_OVERRIDE; | 7586 virtual HValue* Canonicalize() V8_OVERRIDE; |
| 7683 | 7587 |
| 7684 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue) | 7588 DECLARE_CONCRETE_INSTRUCTION(CheckMapValue) |
| 7685 | 7589 |
| 7686 protected: | 7590 protected: |
| 7687 virtual int RedefinedOperandIndex() { return 0; } | 7591 virtual int RedefinedOperandIndex() { return 0; } |
| 7688 | 7592 |
| 7689 virtual bool DataEquals(HValue* other) V8_OVERRIDE { | 7593 virtual bool DataEquals(HValue* other) V8_OVERRIDE { |
| 7690 return true; | 7594 return true; |
| 7691 } | 7595 } |
| 7692 | 7596 |
| 7693 private: | 7597 private: |
| 7694 HCheckMapValue(HValue* value, | 7598 HCheckMapValue(HValue* value, HValue* map) |
| 7695 HValue* map) { | 7599 : HTemplateInstruction<2>(HType::HeapObject()) { |
| 7696 SetOperandAt(0, value); | 7600 SetOperandAt(0, value); |
| 7697 SetOperandAt(1, map); | 7601 SetOperandAt(1, map); |
| 7698 set_representation(Representation::Tagged()); | 7602 set_representation(Representation::Tagged()); |
| 7699 SetFlag(kUseGVN); | 7603 SetFlag(kUseGVN); |
| 7700 SetDependsOnFlag(kMaps); | 7604 SetDependsOnFlag(kMaps); |
| 7701 SetDependsOnFlag(kElementsKind); | 7605 SetDependsOnFlag(kElementsKind); |
| 7702 } | 7606 } |
| 7703 }; | 7607 }; |
| 7704 | 7608 |
| 7705 | 7609 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7810 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 7714 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 7811 }; | 7715 }; |
| 7812 | 7716 |
| 7813 | 7717 |
| 7814 #undef DECLARE_INSTRUCTION | 7718 #undef DECLARE_INSTRUCTION |
| 7815 #undef DECLARE_CONCRETE_INSTRUCTION | 7719 #undef DECLARE_CONCRETE_INSTRUCTION |
| 7816 | 7720 |
| 7817 } } // namespace v8::internal | 7721 } } // namespace v8::internal |
| 7818 | 7722 |
| 7819 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7723 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |