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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 bool IsNone() const { return kind_ == kNone; } | 340 bool IsNone() const { return kind_ == kNone; } |
| 341 bool IsTagged() const { return kind_ == kTagged; } | 341 bool IsTagged() const { return kind_ == kTagged; } |
| 342 bool IsInteger32() const { return kind_ == kInteger32; } | 342 bool IsInteger32() const { return kind_ == kInteger32; } |
| 343 bool IsDouble() const { return kind_ == kDouble; } | 343 bool IsDouble() const { return kind_ == kDouble; } |
| 344 bool IsExternal() const { return kind_ == kExternal; } | 344 bool IsExternal() const { return kind_ == kExternal; } |
| 345 bool IsSpecialization() const { | 345 bool IsSpecialization() const { |
| 346 return kind_ == kInteger32 || kind_ == kDouble; | 346 return kind_ == kInteger32 || kind_ == kDouble; |
| 347 } | 347 } |
| 348 const char* Mnemonic() const; | 348 const char* Mnemonic() const; |
| 349 | 349 |
| 350 Representation KeyedAccessIndexRequirement() { | |
| 351 return IsInteger32() ? Integer32() : Tagged(); | |
|
Sven Panne
2012/12/06 14:59:02
I think we should add an assertion here about the
Massi
2012/12/07 10:11:11
Well, this representation is meant to be used as r
Sven Panne
2012/12/07 10:24:58
Well, in general RequiredInputRepresentation doesn
| |
| 352 } | |
| 353 | |
| 350 private: | 354 private: |
| 351 explicit Representation(Kind k) : kind_(k) { } | 355 explicit Representation(Kind k) : kind_(k) { } |
| 352 | 356 |
| 353 // Make sure kind fits in int8. | 357 // Make sure kind fits in int8. |
| 354 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); | 358 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); |
| 355 | 359 |
| 356 int8_t kind_; | 360 int8_t kind_; |
| 357 }; | 361 }; |
| 358 | 362 |
| 359 | 363 |
| (...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2819 | 2823 |
| 2820 HValue* receiver() { return OperandAt(0); } | 2824 HValue* receiver() { return OperandAt(0); } |
| 2821 HValue* function() { return OperandAt(1); } | 2825 HValue* function() { return OperandAt(1); } |
| 2822 | 2826 |
| 2823 virtual HValue* Canonicalize(); | 2827 virtual HValue* Canonicalize(); |
| 2824 | 2828 |
| 2825 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) | 2829 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) |
| 2826 }; | 2830 }; |
| 2827 | 2831 |
| 2828 | 2832 |
| 2833 enum BoundsCheckKeyMode { | |
| 2834 DONT_ALLOW_SMI_KEY, | |
| 2835 ALLOW_SMI_KEY | |
| 2836 }; | |
| 2837 | |
| 2838 | |
| 2839 class HBoundsCheck: public HTemplateInstruction<2> { | |
| 2840 public: | |
| 2841 HBoundsCheck(HValue* index, HValue* length, | |
| 2842 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY) | |
| 2843 : key_mode_(key_mode) { | |
| 2844 SetOperandAt(0, index); | |
| 2845 SetOperandAt(1, length); | |
| 2846 set_representation(Representation::Integer32()); | |
| 2847 SetFlag(kUseGVN); | |
| 2848 } | |
| 2849 | |
| 2850 virtual Representation RequiredInputRepresentation(int arg_index) { | |
| 2851 if (key_mode_ == DONT_ALLOW_SMI_KEY || | |
| 2852 !length()->representation().IsTagged()) { | |
| 2853 return Representation::Integer32(); | |
| 2854 } | |
| 2855 // If the index is tagged and isn't constant, then allow the length | |
| 2856 // to be tagged, since it is usually already tagged from loading it out of | |
| 2857 // the length field of a JSArray. This allows for direct comparison without | |
| 2858 // untagging. | |
| 2859 if (index()->representation().IsTagged() && !index()->IsConstant()) { | |
| 2860 return Representation::Tagged(); | |
| 2861 } | |
| 2862 // Also allow the length to be tagged if the index is constant, because | |
| 2863 // it can be tagged to allow direct comparison. | |
| 2864 if (index()->IsConstant() && | |
| 2865 index()->representation().IsInteger32() && | |
| 2866 arg_index == 1) { | |
| 2867 return Representation::Tagged(); | |
| 2868 } | |
| 2869 return Representation::Integer32(); | |
| 2870 } | |
| 2871 virtual Representation observed_input_representation(int index) { | |
| 2872 return Representation::Integer32(); | |
| 2873 } | |
| 2874 | |
| 2875 virtual void PrintDataTo(StringStream* stream); | |
| 2876 | |
| 2877 HValue* index() { return OperandAt(0); } | |
| 2878 HValue* length() { return OperandAt(1); } | |
| 2879 | |
| 2880 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | |
| 2881 | |
| 2882 static HValue* ExtractUncheckedIndex(HValue* index) { | |
| 2883 return index->IsBoundsCheck() ? HBoundsCheck::cast(index)->index() : index; | |
| 2884 } | |
| 2885 | |
| 2886 protected: | |
| 2887 virtual bool DataEquals(HValue* other) { return true; } | |
| 2888 BoundsCheckKeyMode key_mode_; | |
| 2889 }; | |
| 2890 | |
| 2891 | |
| 2829 class HApplyArguments: public HTemplateInstruction<4> { | 2892 class HApplyArguments: public HTemplateInstruction<4> { |
| 2830 public: | 2893 public: |
| 2831 HApplyArguments(HValue* function, | 2894 HApplyArguments(HValue* function, |
| 2832 HValue* receiver, | 2895 HValue* receiver, |
| 2833 HValue* length, | 2896 HValue* length, |
| 2834 HValue* elements) { | 2897 HValue* elements) { |
| 2835 set_representation(Representation::Tagged()); | 2898 set_representation(Representation::Tagged()); |
| 2836 SetOperandAt(0, function); | 2899 SetOperandAt(0, function); |
| 2837 SetOperandAt(1, receiver); | 2900 SetOperandAt(1, receiver); |
| 2838 SetOperandAt(2, length); | 2901 SetOperandAt(2, length); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2897 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength) | 2960 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength) |
| 2898 | 2961 |
| 2899 protected: | 2962 protected: |
| 2900 virtual bool DataEquals(HValue* other) { return true; } | 2963 virtual bool DataEquals(HValue* other) { return true; } |
| 2901 | 2964 |
| 2902 private: | 2965 private: |
| 2903 virtual bool IsDeletable() const { return true; } | 2966 virtual bool IsDeletable() const { return true; } |
| 2904 }; | 2967 }; |
| 2905 | 2968 |
| 2906 | 2969 |
| 2907 class HAccessArgumentsAt: public HTemplateInstruction<3> { | 2970 class HAccessArgumentsAt: public HTemplateInstruction<4> { |
| 2908 public: | 2971 public: |
| 2909 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { | 2972 HAccessArgumentsAt(HValue* arguments, |
| 2973 HValue* length, | |
| 2974 HValue* checked_index) { | |
| 2910 set_representation(Representation::Tagged()); | 2975 set_representation(Representation::Tagged()); |
| 2911 SetFlag(kUseGVN); | 2976 SetFlag(kUseGVN); |
| 2912 SetOperandAt(0, arguments); | 2977 SetOperandAt(0, arguments); |
| 2913 SetOperandAt(1, length); | 2978 SetOperandAt(1, length); |
| 2914 SetOperandAt(2, index); | 2979 SetOperandAt(2, HBoundsCheck::ExtractUncheckedIndex(checked_index)); |
| 2980 SetOperandAt(3, checked_index); | |
| 2915 } | 2981 } |
| 2916 | 2982 |
| 2917 virtual void PrintDataTo(StringStream* stream); | 2983 virtual void PrintDataTo(StringStream* stream); |
| 2918 | 2984 |
| 2919 virtual Representation RequiredInputRepresentation(int index) { | 2985 virtual Representation RequiredInputRepresentation(int index) { |
| 2920 // The arguments elements is considered tagged. | 2986 // The arguments elements is considered tagged. |
| 2921 return index == 0 | 2987 return index == 0 |
| 2922 ? Representation::Tagged() | 2988 ? Representation::Tagged() : |
|
Sven Panne
2012/12/06 14:59:02
Formatting nit: Consistently indent the ternary op
Massi
2012/12/07 10:11:11
Done.
| |
| 2923 : Representation::Integer32(); | 2989 (index == 3 ? Representation::None() : |
|
Sven Panne
2012/12/06 14:59:02
Hmmm, I would have expected
checked_index()->rep
Massi
2012/12/07 10:11:11
Done.
| |
| 2990 Representation::Integer32()); | |
| 2924 } | 2991 } |
| 2925 | 2992 |
| 2926 HValue* arguments() { return OperandAt(0); } | 2993 HValue* arguments() { return OperandAt(0); } |
| 2927 HValue* length() { return OperandAt(1); } | 2994 HValue* length() { return OperandAt(1); } |
| 2928 HValue* index() { return OperandAt(2); } | 2995 HValue* index() { return OperandAt(2); } |
| 2996 HValue* checked_index() { return OperandAt(3); } | |
| 2929 | 2997 |
| 2930 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) | 2998 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) |
| 2931 | 2999 |
| 2932 virtual bool DataEquals(HValue* other) { return true; } | 3000 virtual bool DataEquals(HValue* other) { return true; } |
| 2933 }; | 3001 }; |
| 2934 | 3002 |
| 2935 | 3003 |
| 2936 enum BoundsCheckKeyMode { | |
| 2937 DONT_ALLOW_SMI_KEY, | |
| 2938 ALLOW_SMI_KEY | |
| 2939 }; | |
| 2940 | |
| 2941 | |
| 2942 class HBoundsCheck: public HTemplateInstruction<2> { | |
| 2943 public: | |
| 2944 HBoundsCheck(HValue* index, HValue* length, | |
| 2945 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY) | |
| 2946 : key_mode_(key_mode) { | |
| 2947 SetOperandAt(0, index); | |
| 2948 SetOperandAt(1, length); | |
| 2949 set_representation(Representation::Integer32()); | |
| 2950 SetFlag(kUseGVN); | |
| 2951 } | |
| 2952 | |
| 2953 virtual Representation RequiredInputRepresentation(int arg_index) { | |
| 2954 if (key_mode_ == DONT_ALLOW_SMI_KEY || | |
| 2955 !length()->representation().IsTagged()) { | |
| 2956 return Representation::Integer32(); | |
| 2957 } | |
| 2958 // If the index is tagged and isn't constant, then allow the length | |
| 2959 // to be tagged, since it is usually already tagged from loading it out of | |
| 2960 // the length field of a JSArray. This allows for direct comparison without | |
| 2961 // untagging. | |
| 2962 if (index()->representation().IsTagged() && !index()->IsConstant()) { | |
| 2963 return Representation::Tagged(); | |
| 2964 } | |
| 2965 // Also allow the length to be tagged if the index is constant, because | |
| 2966 // it can be tagged to allow direct comparison. | |
| 2967 if (index()->IsConstant() && | |
| 2968 index()->representation().IsInteger32() && | |
| 2969 arg_index == 1) { | |
| 2970 return Representation::Tagged(); | |
| 2971 } | |
| 2972 return Representation::Integer32(); | |
| 2973 } | |
| 2974 virtual Representation observed_input_representation(int index) { | |
| 2975 return Representation::Integer32(); | |
| 2976 } | |
| 2977 | |
| 2978 virtual void PrintDataTo(StringStream* stream); | |
| 2979 | |
| 2980 HValue* index() { return OperandAt(0); } | |
| 2981 HValue* length() { return OperandAt(1); } | |
| 2982 | |
| 2983 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | |
| 2984 | |
| 2985 protected: | |
| 2986 virtual bool DataEquals(HValue* other) { return true; } | |
| 2987 BoundsCheckKeyMode key_mode_; | |
| 2988 }; | |
| 2989 | |
| 2990 | |
| 2991 class HBitwiseBinaryOperation: public HBinaryOperation { | 3004 class HBitwiseBinaryOperation: public HBinaryOperation { |
| 2992 public: | 3005 public: |
| 2993 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) | 3006 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) |
| 2994 : HBinaryOperation(context, left, right) { | 3007 : HBinaryOperation(context, left, right) { |
| 2995 SetFlag(kFlexibleRepresentation); | 3008 SetFlag(kFlexibleRepresentation); |
| 2996 SetFlag(kTruncatingToInt32); | 3009 SetFlag(kTruncatingToInt32); |
| 2997 SetAllSideEffects(); | 3010 SetAllSideEffects(); |
| 2998 } | 3011 } |
| 2999 | 3012 |
| 3000 virtual Representation RequiredInputRepresentation(int index) { | 3013 virtual Representation RequiredInputRepresentation(int index) { |
| (...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4335 virtual HValue* GetKey() = 0; | 4348 virtual HValue* GetKey() = 0; |
| 4336 virtual void SetKey(HValue* key) = 0; | 4349 virtual void SetKey(HValue* key) = 0; |
| 4337 virtual void SetIndexOffset(uint32_t index_offset) = 0; | 4350 virtual void SetIndexOffset(uint32_t index_offset) = 0; |
| 4338 virtual bool IsDehoisted() = 0; | 4351 virtual bool IsDehoisted() = 0; |
| 4339 virtual void SetDehoisted(bool is_dehoisted) = 0; | 4352 virtual void SetDehoisted(bool is_dehoisted) = 0; |
| 4340 virtual ~ArrayInstructionInterface() { }; | 4353 virtual ~ArrayInstructionInterface() { }; |
| 4341 }; | 4354 }; |
| 4342 | 4355 |
| 4343 | 4356 |
| 4344 class HLoadKeyed | 4357 class HLoadKeyed |
| 4345 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4358 : public HTemplateInstruction<4>, public ArrayInstructionInterface { |
| 4346 public: | 4359 public: |
| 4347 HLoadKeyed(HValue* obj, | 4360 HLoadKeyed(HValue* obj, |
| 4348 HValue* key, | 4361 HValue* checked_key, |
| 4349 HValue* dependency, | 4362 HValue* dependency, |
| 4350 ElementsKind elements_kind) | 4363 ElementsKind elements_kind) |
| 4351 : bit_field_(0) { | 4364 : bit_field_(0) { |
| 4352 bit_field_ = ElementsKindField::encode(elements_kind); | 4365 bit_field_ = ElementsKindField::encode(elements_kind); |
| 4353 | |
| 4354 SetOperandAt(0, obj); | 4366 SetOperandAt(0, obj); |
| 4355 SetOperandAt(1, key); | 4367 SetOperandAt(1, HBoundsCheck::ExtractUncheckedIndex(checked_key)); |
| 4356 SetOperandAt(2, dependency); | 4368 SetOperandAt(2, dependency); |
| 4369 SetOperandAt(3, checked_key); | |
| 4357 | 4370 |
| 4358 if (!is_external()) { | 4371 if (!is_external()) { |
| 4359 // I can detect the case between storing double (holey and fast) and | 4372 // I can detect the case between storing double (holey and fast) and |
| 4360 // smi/object by looking at elements_kind_. | 4373 // smi/object by looking at elements_kind_. |
| 4361 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | 4374 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || |
| 4362 IsFastDoubleElementsKind(elements_kind)); | 4375 IsFastDoubleElementsKind(elements_kind)); |
| 4363 | 4376 |
| 4364 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 4377 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
| 4365 if (IsFastSmiElementsKind(elements_kind) && | 4378 if (IsFastSmiElementsKind(elements_kind) && |
| 4366 IsFastPackedElementsKind(elements_kind)) { | 4379 IsFastPackedElementsKind(elements_kind)) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 4388 | 4401 |
| 4389 SetFlag(kUseGVN); | 4402 SetFlag(kUseGVN); |
| 4390 } | 4403 } |
| 4391 | 4404 |
| 4392 bool is_external() const { | 4405 bool is_external() const { |
| 4393 return IsExternalArrayElementsKind(elements_kind()); | 4406 return IsExternalArrayElementsKind(elements_kind()); |
| 4394 } | 4407 } |
| 4395 HValue* elements() { return OperandAt(0); } | 4408 HValue* elements() { return OperandAt(0); } |
| 4396 HValue* key() { return OperandAt(1); } | 4409 HValue* key() { return OperandAt(1); } |
| 4397 HValue* dependency() { return OperandAt(2); } | 4410 HValue* dependency() { return OperandAt(2); } |
| 4411 HValue* checked_key() { return OperandAt(3); } | |
| 4398 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } | 4412 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } |
| 4399 void SetIndexOffset(uint32_t index_offset) { | 4413 void SetIndexOffset(uint32_t index_offset) { |
| 4400 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); | 4414 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); |
| 4401 } | 4415 } |
| 4402 HValue* GetKey() { return key(); } | 4416 HValue* GetKey() { return key(); } |
| 4403 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4417 void SetKey(HValue* key) { SetOperandAt(1, key); } |
| 4404 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } | 4418 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } |
| 4405 void SetDehoisted(bool is_dehoisted) { | 4419 void SetDehoisted(bool is_dehoisted) { |
| 4406 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); | 4420 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); |
| 4407 } | 4421 } |
| 4408 ElementsKind elements_kind() const { | 4422 ElementsKind elements_kind() const { |
| 4409 return ElementsKindField::decode(bit_field_); | 4423 return ElementsKindField::decode(bit_field_); |
| 4410 } | 4424 } |
| 4411 | 4425 |
| 4412 virtual Representation RequiredInputRepresentation(int index) { | 4426 virtual Representation RequiredInputRepresentation(int index) { |
| 4413 // kind_fast: tagged[int32] (none) | 4427 // kind_fast: tagged[int32] (none) |
| 4414 // kind_double: tagged[int32] (none) | 4428 // kind_double: tagged[int32] (none) |
| 4415 // kind_external: external[int32] (none) | 4429 // kind_external: external[int32] (none) |
| 4416 if (index == 0) { | 4430 if (index == 0) { |
| 4417 return is_external() ? Representation::External() | 4431 return is_external() ? Representation::External() |
| 4418 : Representation::Tagged(); | 4432 : Representation::Tagged(); |
| 4419 } | 4433 } |
| 4420 if (index == 1) return Representation::Integer32(); | 4434 if (index == 1) { |
| 4435 return OperandAt(1)->representation().KeyedAccessIndexRequirement(); | |
| 4436 } | |
| 4421 return Representation::None(); | 4437 return Representation::None(); |
| 4422 } | 4438 } |
| 4423 | 4439 |
| 4424 virtual Representation observed_input_representation(int index) { | 4440 virtual Representation observed_input_representation(int index) { |
| 4425 return RequiredInputRepresentation(index); | 4441 return RequiredInputRepresentation(index); |
| 4426 } | 4442 } |
| 4427 | 4443 |
| 4428 virtual void PrintDataTo(StringStream* stream); | 4444 virtual void PrintDataTo(StringStream* stream); |
| 4429 | 4445 |
| 4430 bool RequiresHoleCheck() const; | 4446 bool RequiresHoleCheck() const; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4592 | 4608 |
| 4593 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) | 4609 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) |
| 4594 | 4610 |
| 4595 private: | 4611 private: |
| 4596 Handle<String> name_; | 4612 Handle<String> name_; |
| 4597 StrictModeFlag strict_mode_flag_; | 4613 StrictModeFlag strict_mode_flag_; |
| 4598 }; | 4614 }; |
| 4599 | 4615 |
| 4600 | 4616 |
| 4601 class HStoreKeyed | 4617 class HStoreKeyed |
| 4602 : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 4618 : public HTemplateInstruction<4>, public ArrayInstructionInterface { |
| 4603 public: | 4619 public: |
| 4604 HStoreKeyed(HValue* obj, HValue* key, HValue* val, | 4620 HStoreKeyed(HValue* obj, HValue* checked_key, HValue* val, |
| 4605 ElementsKind elements_kind) | 4621 ElementsKind elements_kind) |
| 4606 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | 4622 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { |
| 4607 SetOperandAt(0, obj); | 4623 SetOperandAt(0, obj); |
| 4608 SetOperandAt(1, key); | 4624 SetOperandAt(1, HBoundsCheck::ExtractUncheckedIndex(checked_key)); |
| 4609 SetOperandAt(2, val); | 4625 SetOperandAt(2, val); |
| 4626 SetOperandAt(3, checked_key); | |
| 4610 | 4627 |
| 4611 if (is_external()) { | 4628 if (is_external()) { |
| 4612 SetGVNFlag(kChangesSpecializedArrayElements); | 4629 SetGVNFlag(kChangesSpecializedArrayElements); |
| 4613 } else if (IsFastDoubleElementsKind(elements_kind)) { | 4630 } else if (IsFastDoubleElementsKind(elements_kind)) { |
| 4614 SetGVNFlag(kChangesDoubleArrayElements); | 4631 SetGVNFlag(kChangesDoubleArrayElements); |
| 4615 SetFlag(kDeoptimizeOnUndefined); | 4632 SetFlag(kDeoptimizeOnUndefined); |
| 4616 } else { | 4633 } else { |
| 4617 SetGVNFlag(kChangesArrayElements); | 4634 SetGVNFlag(kChangesArrayElements); |
| 4618 } | 4635 } |
| 4619 | 4636 |
| 4620 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 4637 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
| 4621 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && | 4638 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && |
| 4622 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 4639 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
| 4623 SetFlag(kTruncatingToInt32); | 4640 SetFlag(kTruncatingToInt32); |
| 4624 } | 4641 } |
| 4625 } | 4642 } |
| 4626 | 4643 |
| 4627 virtual Representation RequiredInputRepresentation(int index) { | 4644 virtual Representation RequiredInputRepresentation(int index) { |
| 4628 // kind_fast: tagged[int32] = tagged | 4645 // kind_fast: tagged[int32] = tagged |
| 4629 // kind_double: tagged[int32] = double | 4646 // kind_double: tagged[int32] = double |
| 4630 // kind_external: external[int32] = (double | int32) | 4647 // kind_external: external[int32] = (double | int32) |
| 4631 if (index == 0) { | 4648 if (index == 0) { |
| 4632 return is_external() ? Representation::External() | 4649 return is_external() ? Representation::External() |
| 4633 : Representation::Tagged(); | 4650 : Representation::Tagged(); |
| 4634 } else if (index == 1) { | 4651 } else if (index == 1) { |
| 4635 return Representation::Integer32(); | 4652 return OperandAt(1)->representation().KeyedAccessIndexRequirement(); |
| 4653 } else if (index == 3) { | |
| 4654 return Representation::None(); | |
| 4636 } | 4655 } |
| 4637 | 4656 |
| 4638 ASSERT_EQ(index, 2); | 4657 ASSERT_EQ(index, 2); |
| 4639 if (IsDoubleOrFloatElementsKind(elements_kind())) { | 4658 if (IsDoubleOrFloatElementsKind(elements_kind())) { |
| 4640 return Representation::Double(); | 4659 return Representation::Double(); |
| 4641 } | 4660 } |
| 4642 | 4661 |
| 4643 return is_external() ? Representation::Integer32() | 4662 return is_external() ? Representation::Integer32() |
| 4644 : Representation::Tagged(); | 4663 : Representation::Tagged(); |
| 4645 } | 4664 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 4656 if (is_external()) { | 4675 if (is_external()) { |
| 4657 return Representation::Integer32(); | 4676 return Representation::Integer32(); |
| 4658 } | 4677 } |
| 4659 // For fast object elements kinds, don't assume anything. | 4678 // For fast object elements kinds, don't assume anything. |
| 4660 return Representation::None(); | 4679 return Representation::None(); |
| 4661 } | 4680 } |
| 4662 | 4681 |
| 4663 HValue* elements() { return OperandAt(0); } | 4682 HValue* elements() { return OperandAt(0); } |
| 4664 HValue* key() { return OperandAt(1); } | 4683 HValue* key() { return OperandAt(1); } |
| 4665 HValue* value() { return OperandAt(2); } | 4684 HValue* value() { return OperandAt(2); } |
| 4685 HValue* checked_key() { return OperandAt(3); } | |
| 4666 bool value_is_smi() const { | 4686 bool value_is_smi() const { |
| 4667 return IsFastSmiElementsKind(elements_kind_); | 4687 return IsFastSmiElementsKind(elements_kind_); |
| 4668 } | 4688 } |
| 4669 ElementsKind elements_kind() const { return elements_kind_; } | 4689 ElementsKind elements_kind() const { return elements_kind_; } |
| 4670 uint32_t index_offset() { return index_offset_; } | 4690 uint32_t index_offset() { return index_offset_; } |
| 4671 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 4691 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } |
| 4672 HValue* GetKey() { return key(); } | 4692 HValue* GetKey() { return key(); } |
| 4673 void SetKey(HValue* key) { SetOperandAt(1, key); } | 4693 void SetKey(HValue* key) { SetOperandAt(1, key); } |
| 4674 bool IsDehoisted() { return is_dehoisted_; } | 4694 bool IsDehoisted() { return is_dehoisted_; } |
| 4675 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 4695 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4798 | 4818 |
| 4799 protected: | 4819 protected: |
| 4800 virtual bool DataEquals(HValue* other) { return true; } | 4820 virtual bool DataEquals(HValue* other) { return true; } |
| 4801 | 4821 |
| 4802 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 4822 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. |
| 4803 // private: | 4823 // private: |
| 4804 // virtual bool IsDeletable() const { return true; } | 4824 // virtual bool IsDeletable() const { return true; } |
| 4805 }; | 4825 }; |
| 4806 | 4826 |
| 4807 | 4827 |
| 4808 class HStringCharCodeAt: public HTemplateInstruction<3> { | 4828 class HStringCharCodeAt: public HTemplateInstruction<4> { |
| 4809 public: | 4829 public: |
| 4810 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { | 4830 HStringCharCodeAt(HValue* context, HValue* string, HValue* checked_index) { |
| 4811 SetOperandAt(0, context); | 4831 SetOperandAt(0, context); |
| 4812 SetOperandAt(1, string); | 4832 SetOperandAt(1, string); |
| 4813 SetOperandAt(2, index); | 4833 SetOperandAt(2, HBoundsCheck::ExtractUncheckedIndex(checked_index)); |
| 4834 SetOperandAt(3, checked_index); | |
| 4814 set_representation(Representation::Integer32()); | 4835 set_representation(Representation::Integer32()); |
| 4815 SetFlag(kUseGVN); | 4836 SetFlag(kUseGVN); |
| 4816 SetGVNFlag(kDependsOnMaps); | 4837 SetGVNFlag(kDependsOnMaps); |
| 4817 SetGVNFlag(kChangesNewSpacePromotion); | 4838 SetGVNFlag(kChangesNewSpacePromotion); |
| 4818 } | 4839 } |
| 4819 | 4840 |
| 4820 virtual Representation RequiredInputRepresentation(int index) { | 4841 virtual Representation RequiredInputRepresentation(int index) { |
| 4821 // The index is supposed to be Integer32. | 4842 // The index is supposed to be Integer32. |
| 4822 return index == 2 | 4843 return index == 2 ? |
| 4823 ? Representation::Integer32() | 4844 Representation::Integer32() : |
| 4824 : Representation::Tagged(); | 4845 (index == 3 ? Representation::None() : Representation::Tagged()); |
|
Sven Panne
2012/12/06 14:59:02
See comments regarding indentation/adding a commen
Massi
2012/12/07 10:11:11
Done.
| |
| 4825 } | 4846 } |
| 4826 | 4847 |
| 4827 HValue* context() { return OperandAt(0); } | 4848 HValue* context() { return OperandAt(0); } |
| 4828 HValue* string() { return OperandAt(1); } | 4849 HValue* string() { return OperandAt(1); } |
| 4829 HValue* index() { return OperandAt(2); } | 4850 HValue* index() { return OperandAt(2); } |
| 4851 HValue* checked_index() { return OperandAt(3); } | |
| 4830 | 4852 |
| 4831 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) | 4853 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) |
| 4832 | 4854 |
| 4833 protected: | 4855 protected: |
| 4834 virtual bool DataEquals(HValue* other) { return true; } | 4856 virtual bool DataEquals(HValue* other) { return true; } |
| 4835 | 4857 |
| 4836 virtual Range* InferRange(Zone* zone) { | 4858 virtual Range* InferRange(Zone* zone) { |
| 4837 return new(zone) Range(0, String::kMaxUtf16CodeUnit); | 4859 return new(zone) Range(0, String::kMaxUtf16CodeUnit); |
| 4838 } | 4860 } |
| 4839 | 4861 |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5390 virtual bool IsDeletable() const { return true; } | 5412 virtual bool IsDeletable() const { return true; } |
| 5391 }; | 5413 }; |
| 5392 | 5414 |
| 5393 | 5415 |
| 5394 #undef DECLARE_INSTRUCTION | 5416 #undef DECLARE_INSTRUCTION |
| 5395 #undef DECLARE_CONCRETE_INSTRUCTION | 5417 #undef DECLARE_CONCRETE_INSTRUCTION |
| 5396 | 5418 |
| 5397 } } // namespace v8::internal | 5419 } } // namespace v8::internal |
| 5398 | 5420 |
| 5399 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5421 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |