| 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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 341   bool IsNone() const { return kind_ == kNone; } | 341   bool IsNone() const { return kind_ == kNone; } | 
| 342   bool IsTagged() const { return kind_ == kTagged; } | 342   bool IsTagged() const { return kind_ == kTagged; } | 
| 343   bool IsInteger32() const { return kind_ == kInteger32; } | 343   bool IsInteger32() const { return kind_ == kInteger32; } | 
| 344   bool IsDouble() const { return kind_ == kDouble; } | 344   bool IsDouble() const { return kind_ == kDouble; } | 
| 345   bool IsExternal() const { return kind_ == kExternal; } | 345   bool IsExternal() const { return kind_ == kExternal; } | 
| 346   bool IsSpecialization() const { | 346   bool IsSpecialization() const { | 
| 347     return kind_ == kInteger32 || kind_ == kDouble; | 347     return kind_ == kInteger32 || kind_ == kDouble; | 
| 348   } | 348   } | 
| 349   const char* Mnemonic() const; | 349   const char* Mnemonic() const; | 
| 350 | 350 | 
| 351   Representation KeyedAccessIndexRequirement() { |  | 
| 352     // This is intended to be used in RequiredInputRepresentation for keyed |  | 
| 353     // loads and stores to avoid inserting unneeded HChange instructions: |  | 
| 354     // keyed loads and stores can work on both int32 and tagged indexes. |  | 
| 355     return IsInteger32() ? Integer32() : Tagged(); |  | 
| 356   } |  | 
| 357 |  | 
| 358  private: | 351  private: | 
| 359   explicit Representation(Kind k) : kind_(k) { } | 352   explicit Representation(Kind k) : kind_(k) { } | 
| 360 | 353 | 
| 361   // Make sure kind fits in int8. | 354   // Make sure kind fits in int8. | 
| 362   STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); | 355   STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); | 
| 363 | 356 | 
| 364   int8_t kind_; | 357   int8_t kind_; | 
| 365 }; | 358 }; | 
| 366 | 359 | 
| 367 | 360 | 
| (...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2827 | 2820 | 
| 2828   HValue* receiver() { return OperandAt(0); } | 2821   HValue* receiver() { return OperandAt(0); } | 
| 2829   HValue* function() { return OperandAt(1); } | 2822   HValue* function() { return OperandAt(1); } | 
| 2830 | 2823 | 
| 2831   virtual HValue* Canonicalize(); | 2824   virtual HValue* Canonicalize(); | 
| 2832 | 2825 | 
| 2833   DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) | 2826   DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) | 
| 2834 }; | 2827 }; | 
| 2835 | 2828 | 
| 2836 | 2829 | 
| 2837 enum BoundsCheckKeyMode { |  | 
| 2838   DONT_ALLOW_SMI_KEY, |  | 
| 2839   ALLOW_SMI_KEY |  | 
| 2840 }; |  | 
| 2841 |  | 
| 2842 |  | 
| 2843 class HBoundsCheck: public HTemplateInstruction<2> { |  | 
| 2844  public: |  | 
| 2845   HBoundsCheck(HValue* index, HValue* length, |  | 
| 2846                BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY) |  | 
| 2847       : key_mode_(key_mode) { |  | 
| 2848     SetOperandAt(0, index); |  | 
| 2849     SetOperandAt(1, length); |  | 
| 2850     set_representation(Representation::Integer32()); |  | 
| 2851     SetFlag(kUseGVN); |  | 
| 2852   } |  | 
| 2853 |  | 
| 2854   virtual Representation RequiredInputRepresentation(int arg_index) { |  | 
| 2855     if (key_mode_ == DONT_ALLOW_SMI_KEY || |  | 
| 2856         !length()->representation().IsTagged()) { |  | 
| 2857       return Representation::Integer32(); |  | 
| 2858     } |  | 
| 2859     // If the index is tagged and isn't constant, then allow the length |  | 
| 2860     // to be tagged, since it is usually already tagged from loading it out of |  | 
| 2861     // the length field of a JSArray. This allows for direct comparison without |  | 
| 2862     // untagging. |  | 
| 2863     if (index()->representation().IsTagged() && !index()->IsConstant()) { |  | 
| 2864       return Representation::Tagged(); |  | 
| 2865     } |  | 
| 2866     // Also allow the length to be tagged if the index is constant, because |  | 
| 2867     // it can be tagged to allow direct comparison. |  | 
| 2868     if (index()->IsConstant() && |  | 
| 2869         index()->representation().IsInteger32() && |  | 
| 2870         arg_index == 1) { |  | 
| 2871       return Representation::Tagged(); |  | 
| 2872     } |  | 
| 2873     return Representation::Integer32(); |  | 
| 2874   } |  | 
| 2875   virtual Representation observed_input_representation(int index) { |  | 
| 2876     return Representation::Integer32(); |  | 
| 2877   } |  | 
| 2878 |  | 
| 2879   virtual void PrintDataTo(StringStream* stream); |  | 
| 2880 |  | 
| 2881   HValue* index() { return OperandAt(0); } |  | 
| 2882   HValue* length() { return OperandAt(1); } |  | 
| 2883 |  | 
| 2884   DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) |  | 
| 2885 |  | 
| 2886   static HValue* ExtractUncheckedIndex(HValue* index) { |  | 
| 2887     return index->IsBoundsCheck() ? HBoundsCheck::cast(index)->index() : index; |  | 
| 2888   } |  | 
| 2889 |  | 
| 2890  protected: |  | 
| 2891   virtual bool DataEquals(HValue* other) { return true; } |  | 
| 2892   BoundsCheckKeyMode key_mode_; |  | 
| 2893 }; |  | 
| 2894 |  | 
| 2895 |  | 
| 2896 class HApplyArguments: public HTemplateInstruction<4> { | 2830 class HApplyArguments: public HTemplateInstruction<4> { | 
| 2897  public: | 2831  public: | 
| 2898   HApplyArguments(HValue* function, | 2832   HApplyArguments(HValue* function, | 
| 2899                   HValue* receiver, | 2833                   HValue* receiver, | 
| 2900                   HValue* length, | 2834                   HValue* length, | 
| 2901                   HValue* elements) { | 2835                   HValue* elements) { | 
| 2902     set_representation(Representation::Tagged()); | 2836     set_representation(Representation::Tagged()); | 
| 2903     SetOperandAt(0, function); | 2837     SetOperandAt(0, function); | 
| 2904     SetOperandAt(1, receiver); | 2838     SetOperandAt(1, receiver); | 
| 2905     SetOperandAt(2, length); | 2839     SetOperandAt(2, length); | 
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2964   DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength) | 2898   DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength) | 
| 2965 | 2899 | 
| 2966  protected: | 2900  protected: | 
| 2967   virtual bool DataEquals(HValue* other) { return true; } | 2901   virtual bool DataEquals(HValue* other) { return true; } | 
| 2968 | 2902 | 
| 2969  private: | 2903  private: | 
| 2970   virtual bool IsDeletable() const { return true; } | 2904   virtual bool IsDeletable() const { return true; } | 
| 2971 }; | 2905 }; | 
| 2972 | 2906 | 
| 2973 | 2907 | 
| 2974 class HAccessArgumentsAt: public HTemplateInstruction<4> { | 2908 class HAccessArgumentsAt: public HTemplateInstruction<3> { | 
| 2975  public: | 2909  public: | 
| 2976   HAccessArgumentsAt(HValue* arguments, | 2910   HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { | 
| 2977                      HValue* length, |  | 
| 2978                      HValue* checked_index) { |  | 
| 2979     set_representation(Representation::Tagged()); | 2911     set_representation(Representation::Tagged()); | 
| 2980     SetFlag(kUseGVN); | 2912     SetFlag(kUseGVN); | 
| 2981     SetOperandAt(0, arguments); | 2913     SetOperandAt(0, arguments); | 
| 2982     SetOperandAt(1, length); | 2914     SetOperandAt(1, length); | 
| 2983     SetOperandAt(2, HBoundsCheck::ExtractUncheckedIndex(checked_index)); | 2915     SetOperandAt(2, index); | 
| 2984     SetOperandAt(3, checked_index); |  | 
| 2985   } | 2916   } | 
| 2986 | 2917 | 
| 2987   virtual void PrintDataTo(StringStream* stream); | 2918   virtual void PrintDataTo(StringStream* stream); | 
| 2988 | 2919 | 
| 2989   virtual Representation RequiredInputRepresentation(int index) { | 2920   virtual Representation RequiredInputRepresentation(int index) { | 
| 2990     switch (index) { | 2921     // The arguments elements is considered tagged. | 
| 2991       // The arguments elements is considered tagged. | 2922     return index == 0 | 
| 2992       case 0: return Representation::Tagged(); | 2923         ? Representation::Tagged() | 
| 2993       case 1: return Representation::Integer32(); | 2924         : Representation::Integer32(); | 
| 2994       case 2: return Representation::Integer32(); |  | 
| 2995       // The checked index is a control flow dependency to avoid hoisting |  | 
| 2996       // and therefore it has no representation requirements. |  | 
| 2997       case 3: return Representation::None(); |  | 
| 2998       default: { |  | 
| 2999         UNREACHABLE(); |  | 
| 3000         return Representation::None(); |  | 
| 3001       } |  | 
| 3002     } |  | 
| 3003   } | 2925   } | 
| 3004 | 2926 | 
| 3005   HValue* arguments() { return OperandAt(0); } | 2927   HValue* arguments() { return OperandAt(0); } | 
| 3006   HValue* length() { return OperandAt(1); } | 2928   HValue* length() { return OperandAt(1); } | 
| 3007   HValue* index() { return OperandAt(2); } | 2929   HValue* index() { return OperandAt(2); } | 
| 3008   HValue* checked_index() { return OperandAt(3); } |  | 
| 3009 | 2930 | 
| 3010   DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) | 2931   DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) | 
| 3011 | 2932 | 
| 3012   virtual bool DataEquals(HValue* other) { return true; } | 2933   virtual bool DataEquals(HValue* other) { return true; } | 
| 3013 }; | 2934 }; | 
| 3014 | 2935 | 
| 3015 | 2936 | 
|  | 2937 enum BoundsCheckKeyMode { | 
|  | 2938   DONT_ALLOW_SMI_KEY, | 
|  | 2939   ALLOW_SMI_KEY | 
|  | 2940 }; | 
|  | 2941 | 
|  | 2942 | 
|  | 2943 class HBoundsCheck: public HTemplateInstruction<2> { | 
|  | 2944  public: | 
|  | 2945   HBoundsCheck(HValue* index, HValue* length, | 
|  | 2946                BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY) | 
|  | 2947       : key_mode_(key_mode) { | 
|  | 2948     SetOperandAt(0, index); | 
|  | 2949     SetOperandAt(1, length); | 
|  | 2950     set_representation(Representation::Integer32()); | 
|  | 2951     SetFlag(kUseGVN); | 
|  | 2952   } | 
|  | 2953 | 
|  | 2954   virtual Representation RequiredInputRepresentation(int arg_index) { | 
|  | 2955     if (key_mode_ == DONT_ALLOW_SMI_KEY || | 
|  | 2956         !length()->representation().IsTagged()) { | 
|  | 2957       return Representation::Integer32(); | 
|  | 2958     } | 
|  | 2959     // If the index is tagged and isn't constant, then allow the length | 
|  | 2960     // to be tagged, since it is usually already tagged from loading it out of | 
|  | 2961     // the length field of a JSArray. This allows for direct comparison without | 
|  | 2962     // untagging. | 
|  | 2963     if (index()->representation().IsTagged() && !index()->IsConstant()) { | 
|  | 2964       return Representation::Tagged(); | 
|  | 2965     } | 
|  | 2966     // Also allow the length to be tagged if the index is constant, because | 
|  | 2967     // it can be tagged to allow direct comparison. | 
|  | 2968     if (index()->IsConstant() && | 
|  | 2969         index()->representation().IsInteger32() && | 
|  | 2970         arg_index == 1) { | 
|  | 2971       return Representation::Tagged(); | 
|  | 2972     } | 
|  | 2973     return Representation::Integer32(); | 
|  | 2974   } | 
|  | 2975   virtual Representation observed_input_representation(int index) { | 
|  | 2976     return Representation::Integer32(); | 
|  | 2977   } | 
|  | 2978 | 
|  | 2979   virtual void PrintDataTo(StringStream* stream); | 
|  | 2980 | 
|  | 2981   HValue* index() { return OperandAt(0); } | 
|  | 2982   HValue* length() { return OperandAt(1); } | 
|  | 2983 | 
|  | 2984   DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | 
|  | 2985 | 
|  | 2986  protected: | 
|  | 2987   virtual bool DataEquals(HValue* other) { return true; } | 
|  | 2988   BoundsCheckKeyMode key_mode_; | 
|  | 2989 }; | 
|  | 2990 | 
|  | 2991 | 
| 3016 class HBitwiseBinaryOperation: public HBinaryOperation { | 2992 class HBitwiseBinaryOperation: public HBinaryOperation { | 
| 3017  public: | 2993  public: | 
| 3018   HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) | 2994   HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) | 
| 3019       : HBinaryOperation(context, left, right) { | 2995       : HBinaryOperation(context, left, right) { | 
| 3020     SetFlag(kFlexibleRepresentation); | 2996     SetFlag(kFlexibleRepresentation); | 
| 3021     SetFlag(kTruncatingToInt32); | 2997     SetFlag(kTruncatingToInt32); | 
| 3022     SetAllSideEffects(); | 2998     SetAllSideEffects(); | 
| 3023   } | 2999   } | 
| 3024 | 3000 | 
| 3025   virtual Representation RequiredInputRepresentation(int index) { | 3001   virtual Representation RequiredInputRepresentation(int index) { | 
| (...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4372   virtual HValue* GetKey() = 0; | 4348   virtual HValue* GetKey() = 0; | 
| 4373   virtual void SetKey(HValue* key) = 0; | 4349   virtual void SetKey(HValue* key) = 0; | 
| 4374   virtual void SetIndexOffset(uint32_t index_offset) = 0; | 4350   virtual void SetIndexOffset(uint32_t index_offset) = 0; | 
| 4375   virtual bool IsDehoisted() = 0; | 4351   virtual bool IsDehoisted() = 0; | 
| 4376   virtual void SetDehoisted(bool is_dehoisted) = 0; | 4352   virtual void SetDehoisted(bool is_dehoisted) = 0; | 
| 4377   virtual ~ArrayInstructionInterface() { }; | 4353   virtual ~ArrayInstructionInterface() { }; | 
| 4378 }; | 4354 }; | 
| 4379 | 4355 | 
| 4380 | 4356 | 
| 4381 class HLoadKeyed | 4357 class HLoadKeyed | 
| 4382     : public HTemplateInstruction<4>, public ArrayInstructionInterface { | 4358     : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 
| 4383  public: | 4359  public: | 
| 4384   HLoadKeyed(HValue* obj, | 4360   HLoadKeyed(HValue* obj, | 
| 4385              HValue* checked_key, | 4361              HValue* key, | 
| 4386              HValue* dependency, | 4362              HValue* dependency, | 
| 4387              ElementsKind elements_kind) | 4363              ElementsKind elements_kind) | 
| 4388       : bit_field_(0) { | 4364       : bit_field_(0) { | 
| 4389     bit_field_ = ElementsKindField::encode(elements_kind); | 4365     bit_field_ = ElementsKindField::encode(elements_kind); | 
|  | 4366 | 
| 4390     SetOperandAt(0, obj); | 4367     SetOperandAt(0, obj); | 
| 4391     SetOperandAt(1, HBoundsCheck::ExtractUncheckedIndex(checked_key)); | 4368     SetOperandAt(1, key); | 
| 4392     SetOperandAt(2, dependency); | 4369     SetOperandAt(2, dependency); | 
| 4393     SetOperandAt(3, checked_key); |  | 
| 4394 | 4370 | 
| 4395     if (!is_external()) { | 4371     if (!is_external()) { | 
| 4396       // 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 | 
| 4397       // smi/object by looking at elements_kind_. | 4373       // smi/object by looking at elements_kind_. | 
| 4398       ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | 4374       ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || | 
| 4399              IsFastDoubleElementsKind(elements_kind)); | 4375              IsFastDoubleElementsKind(elements_kind)); | 
| 4400 | 4376 | 
| 4401       if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 4377       if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 
| 4402         if (IsFastSmiElementsKind(elements_kind) && | 4378         if (IsFastSmiElementsKind(elements_kind) && | 
| 4403             IsFastPackedElementsKind(elements_kind)) { | 4379             IsFastPackedElementsKind(elements_kind)) { | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 4425 | 4401 | 
| 4426     SetFlag(kUseGVN); | 4402     SetFlag(kUseGVN); | 
| 4427   } | 4403   } | 
| 4428 | 4404 | 
| 4429   bool is_external() const { | 4405   bool is_external() const { | 
| 4430     return IsExternalArrayElementsKind(elements_kind()); | 4406     return IsExternalArrayElementsKind(elements_kind()); | 
| 4431   } | 4407   } | 
| 4432   HValue* elements() { return OperandAt(0); } | 4408   HValue* elements() { return OperandAt(0); } | 
| 4433   HValue* key() { return OperandAt(1); } | 4409   HValue* key() { return OperandAt(1); } | 
| 4434   HValue* dependency() { return OperandAt(2); } | 4410   HValue* dependency() { return OperandAt(2); } | 
| 4435   HValue* checked_key() { return OperandAt(3); } |  | 
| 4436   uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } | 4411   uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } | 
| 4437   void SetIndexOffset(uint32_t index_offset) { | 4412   void SetIndexOffset(uint32_t index_offset) { | 
| 4438     bit_field_ = IndexOffsetField::update(bit_field_, index_offset); | 4413     bit_field_ = IndexOffsetField::update(bit_field_, index_offset); | 
| 4439   } | 4414   } | 
| 4440   HValue* GetKey() { return key(); } | 4415   HValue* GetKey() { return key(); } | 
| 4441   void SetKey(HValue* key) { SetOperandAt(1, key); } | 4416   void SetKey(HValue* key) { SetOperandAt(1, key); } | 
| 4442   bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } | 4417   bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } | 
| 4443   void SetDehoisted(bool is_dehoisted) { | 4418   void SetDehoisted(bool is_dehoisted) { | 
| 4444     bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); | 4419     bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); | 
| 4445   } | 4420   } | 
| 4446   ElementsKind elements_kind() const { | 4421   ElementsKind elements_kind() const { | 
| 4447     return ElementsKindField::decode(bit_field_); | 4422     return ElementsKindField::decode(bit_field_); | 
| 4448   } | 4423   } | 
| 4449 | 4424 | 
| 4450   virtual Representation RequiredInputRepresentation(int index) { | 4425   virtual Representation RequiredInputRepresentation(int index) { | 
| 4451     // kind_fast:       tagged[int32] (none) | 4426     // kind_fast:       tagged[int32] (none) | 
| 4452     // kind_double:     tagged[int32] (none) | 4427     // kind_double:     tagged[int32] (none) | 
| 4453     // kind_external: external[int32] (none) | 4428     // kind_external: external[int32] (none) | 
| 4454     if (index == 0) { | 4429     if (index == 0) { | 
| 4455       return is_external() ? Representation::External() | 4430       return is_external() ? Representation::External() | 
| 4456           : Representation::Tagged(); | 4431           : Representation::Tagged(); | 
| 4457     } | 4432     } | 
| 4458     if (index == 1) { | 4433     if (index == 1) return Representation::Integer32(); | 
| 4459       return OperandAt(1)->representation().KeyedAccessIndexRequirement(); |  | 
| 4460     } |  | 
| 4461     return Representation::None(); | 4434     return Representation::None(); | 
| 4462   } | 4435   } | 
| 4463 | 4436 | 
| 4464   virtual Representation observed_input_representation(int index) { | 4437   virtual Representation observed_input_representation(int index) { | 
| 4465     return RequiredInputRepresentation(index); | 4438     return RequiredInputRepresentation(index); | 
| 4466   } | 4439   } | 
| 4467 | 4440 | 
| 4468   virtual void PrintDataTo(StringStream* stream); | 4441   virtual void PrintDataTo(StringStream* stream); | 
| 4469 | 4442 | 
| 4470   bool RequiresHoleCheck() const; | 4443   bool RequiresHoleCheck() const; | 
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4632 | 4605 | 
| 4633   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) | 4606   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) | 
| 4634 | 4607 | 
| 4635  private: | 4608  private: | 
| 4636   Handle<String> name_; | 4609   Handle<String> name_; | 
| 4637   StrictModeFlag strict_mode_flag_; | 4610   StrictModeFlag strict_mode_flag_; | 
| 4638 }; | 4611 }; | 
| 4639 | 4612 | 
| 4640 | 4613 | 
| 4641 class HStoreKeyed | 4614 class HStoreKeyed | 
| 4642     : public HTemplateInstruction<4>, public ArrayInstructionInterface { | 4615     : public HTemplateInstruction<3>, public ArrayInstructionInterface { | 
| 4643  public: | 4616  public: | 
| 4644   HStoreKeyed(HValue* obj, HValue* checked_key, HValue* val, | 4617   HStoreKeyed(HValue* obj, HValue* key, HValue* val, | 
| 4645               ElementsKind elements_kind) | 4618               ElementsKind elements_kind) | 
| 4646       : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | 4619       : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { | 
| 4647     SetOperandAt(0, obj); | 4620     SetOperandAt(0, obj); | 
| 4648     SetOperandAt(1, HBoundsCheck::ExtractUncheckedIndex(checked_key)); | 4621     SetOperandAt(1, key); | 
| 4649     SetOperandAt(2, val); | 4622     SetOperandAt(2, val); | 
| 4650     SetOperandAt(3, checked_key); |  | 
| 4651 | 4623 | 
| 4652     if (is_external()) { | 4624     if (is_external()) { | 
| 4653       SetGVNFlag(kChangesSpecializedArrayElements); | 4625       SetGVNFlag(kChangesSpecializedArrayElements); | 
| 4654     } else if (IsFastDoubleElementsKind(elements_kind)) { | 4626     } else if (IsFastDoubleElementsKind(elements_kind)) { | 
| 4655       SetGVNFlag(kChangesDoubleArrayElements); | 4627       SetGVNFlag(kChangesDoubleArrayElements); | 
| 4656       SetFlag(kDeoptimizeOnUndefined); | 4628       SetFlag(kDeoptimizeOnUndefined); | 
| 4657     } else { | 4629     } else { | 
| 4658       SetGVNFlag(kChangesArrayElements); | 4630       SetGVNFlag(kChangesArrayElements); | 
| 4659     } | 4631     } | 
| 4660 | 4632 | 
| 4661     // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 4633     // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 
| 4662     if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && | 4634     if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && | 
| 4663         elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 4635         elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 
| 4664       SetFlag(kTruncatingToInt32); | 4636       SetFlag(kTruncatingToInt32); | 
| 4665     } | 4637     } | 
| 4666   } | 4638   } | 
| 4667 | 4639 | 
| 4668   virtual Representation RequiredInputRepresentation(int index) { | 4640   virtual Representation RequiredInputRepresentation(int index) { | 
| 4669     // kind_fast:       tagged[int32] = tagged | 4641     // kind_fast:       tagged[int32] = tagged | 
| 4670     // kind_double:     tagged[int32] = double | 4642     // kind_double:     tagged[int32] = double | 
| 4671     // kind_external: external[int32] = (double | int32) | 4643     // kind_external: external[int32] = (double | int32) | 
| 4672     if (index == 0) { | 4644     if (index == 0) { | 
| 4673       return is_external() ? Representation::External() | 4645       return is_external() ? Representation::External() | 
| 4674                            : Representation::Tagged(); | 4646                            : Representation::Tagged(); | 
| 4675     } else if (index == 1) { | 4647     } else if (index == 1) { | 
| 4676       return OperandAt(1)->representation().KeyedAccessIndexRequirement(); | 4648       return Representation::Integer32(); | 
| 4677     } else if (index == 3) { |  | 
| 4678       return Representation::None(); |  | 
| 4679     } | 4649     } | 
| 4680 | 4650 | 
| 4681     ASSERT_EQ(index, 2); | 4651     ASSERT_EQ(index, 2); | 
| 4682     if (IsDoubleOrFloatElementsKind(elements_kind())) { | 4652     if (IsDoubleOrFloatElementsKind(elements_kind())) { | 
| 4683       return Representation::Double(); | 4653       return Representation::Double(); | 
| 4684     } | 4654     } | 
| 4685 | 4655 | 
| 4686     return is_external() ? Representation::Integer32() | 4656     return is_external() ? Representation::Integer32() | 
| 4687                          : Representation::Tagged(); | 4657                          : Representation::Tagged(); | 
| 4688   } | 4658   } | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 4699     if (is_external()) { | 4669     if (is_external()) { | 
| 4700       return Representation::Integer32(); | 4670       return Representation::Integer32(); | 
| 4701     } | 4671     } | 
| 4702     // For fast object elements kinds, don't assume anything. | 4672     // For fast object elements kinds, don't assume anything. | 
| 4703     return Representation::None(); | 4673     return Representation::None(); | 
| 4704   } | 4674   } | 
| 4705 | 4675 | 
| 4706   HValue* elements() { return OperandAt(0); } | 4676   HValue* elements() { return OperandAt(0); } | 
| 4707   HValue* key() { return OperandAt(1); } | 4677   HValue* key() { return OperandAt(1); } | 
| 4708   HValue* value() { return OperandAt(2); } | 4678   HValue* value() { return OperandAt(2); } | 
| 4709   HValue* checked_key() { return OperandAt(3); } |  | 
| 4710   bool value_is_smi() const { | 4679   bool value_is_smi() const { | 
| 4711     return IsFastSmiElementsKind(elements_kind_); | 4680     return IsFastSmiElementsKind(elements_kind_); | 
| 4712   } | 4681   } | 
| 4713   ElementsKind elements_kind() const { return elements_kind_; } | 4682   ElementsKind elements_kind() const { return elements_kind_; } | 
| 4714   uint32_t index_offset() { return index_offset_; } | 4683   uint32_t index_offset() { return index_offset_; } | 
| 4715   void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 4684   void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 
| 4716   HValue* GetKey() { return key(); } | 4685   HValue* GetKey() { return key(); } | 
| 4717   void SetKey(HValue* key) { SetOperandAt(1, key); } | 4686   void SetKey(HValue* key) { SetOperandAt(1, key); } | 
| 4718   bool IsDehoisted() { return is_dehoisted_; } | 4687   bool IsDehoisted() { return is_dehoisted_; } | 
| 4719   void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 4688   void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } | 
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4842 | 4811 | 
| 4843  protected: | 4812  protected: | 
| 4844   virtual bool DataEquals(HValue* other) { return true; } | 4813   virtual bool DataEquals(HValue* other) { return true; } | 
| 4845 | 4814 | 
| 4846   // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 4815   // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 
| 4847   // private: | 4816   // private: | 
| 4848   //  virtual bool IsDeletable() const { return true; } | 4817   //  virtual bool IsDeletable() const { return true; } | 
| 4849 }; | 4818 }; | 
| 4850 | 4819 | 
| 4851 | 4820 | 
| 4852 class HStringCharCodeAt: public HTemplateInstruction<4> { | 4821 class HStringCharCodeAt: public HTemplateInstruction<3> { | 
| 4853  public: | 4822  public: | 
| 4854   HStringCharCodeAt(HValue* context, HValue* string, HValue* checked_index) { | 4823   HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { | 
| 4855     SetOperandAt(0, context); | 4824     SetOperandAt(0, context); | 
| 4856     SetOperandAt(1, string); | 4825     SetOperandAt(1, string); | 
| 4857     SetOperandAt(2, HBoundsCheck::ExtractUncheckedIndex(checked_index)); | 4826     SetOperandAt(2, index); | 
| 4858     SetOperandAt(3, checked_index); |  | 
| 4859     set_representation(Representation::Integer32()); | 4827     set_representation(Representation::Integer32()); | 
| 4860     SetFlag(kUseGVN); | 4828     SetFlag(kUseGVN); | 
| 4861     SetGVNFlag(kDependsOnMaps); | 4829     SetGVNFlag(kDependsOnMaps); | 
| 4862     SetGVNFlag(kChangesNewSpacePromotion); | 4830     SetGVNFlag(kChangesNewSpacePromotion); | 
| 4863   } | 4831   } | 
| 4864 | 4832 | 
| 4865   virtual Representation RequiredInputRepresentation(int index) { | 4833   virtual Representation RequiredInputRepresentation(int index) { | 
| 4866     switch (index) { | 4834     // The index is supposed to be Integer32. | 
| 4867       case 0: return Representation::Tagged(); | 4835     return index == 2 | 
| 4868       case 1: return Representation::Tagged(); | 4836         ? Representation::Integer32() | 
| 4869       // The index is supposed to be Integer32. | 4837         : Representation::Tagged(); | 
| 4870       case 2: return Representation::Integer32(); |  | 
| 4871       // The checked index is a control flow dependency to avoid hoisting |  | 
| 4872       // and therefore it has no representation requirements. |  | 
| 4873       case 3: return Representation::None(); |  | 
| 4874       default: { |  | 
| 4875         UNREACHABLE(); |  | 
| 4876         return Representation::None(); |  | 
| 4877       } |  | 
| 4878     } |  | 
| 4879   } | 4838   } | 
| 4880 | 4839 | 
| 4881   HValue* context() { return OperandAt(0); } | 4840   HValue* context() { return OperandAt(0); } | 
| 4882   HValue* string() { return OperandAt(1); } | 4841   HValue* string() { return OperandAt(1); } | 
| 4883   HValue* index() { return OperandAt(2); } | 4842   HValue* index() { return OperandAt(2); } | 
| 4884   HValue* checked_index() { return OperandAt(3); } |  | 
| 4885 | 4843 | 
| 4886   DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) | 4844   DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) | 
| 4887 | 4845 | 
| 4888  protected: | 4846  protected: | 
| 4889   virtual bool DataEquals(HValue* other) { return true; } | 4847   virtual bool DataEquals(HValue* other) { return true; } | 
| 4890 | 4848 | 
| 4891   virtual Range* InferRange(Zone* zone) { | 4849   virtual Range* InferRange(Zone* zone) { | 
| 4892     return new(zone) Range(0, String::kMaxUtf16CodeUnit); | 4850     return new(zone) Range(0, String::kMaxUtf16CodeUnit); | 
| 4893   } | 4851   } | 
| 4894 | 4852 | 
| (...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5472   virtual bool IsDeletable() const { return true; } | 5430   virtual bool IsDeletable() const { return true; } | 
| 5473 }; | 5431 }; | 
| 5474 | 5432 | 
| 5475 | 5433 | 
| 5476 #undef DECLARE_INSTRUCTION | 5434 #undef DECLARE_INSTRUCTION | 
| 5477 #undef DECLARE_CONCRETE_INSTRUCTION | 5435 #undef DECLARE_CONCRETE_INSTRUCTION | 
| 5478 | 5436 | 
| 5479 } }  // namespace v8::internal | 5437 } }  // namespace v8::internal | 
| 5480 | 5438 | 
| 5481 #endif  // V8_HYDROGEN_INSTRUCTIONS_H_ | 5439 #endif  // V8_HYDROGEN_INSTRUCTIONS_H_ | 
| OLD | NEW | 
|---|