Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1882)

Side by Side Diff: src/hydrogen-instructions.h

Issue 11445016: Make keyed operations use the unchecked index but still depend on the checked one. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed review comments. Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 // This is intended to be used in RequiredInputRepresentation for keyed
352 // loads and stores to avoid inserting unneeded HChange instructions:
353 // keyed loads and stores can work on both int32 and tagged indexes.
354 return IsInteger32() ? Integer32() : Tagged();
355 }
356
350 private: 357 private:
351 explicit Representation(Kind k) : kind_(k) { } 358 explicit Representation(Kind k) : kind_(k) { }
352 359
353 // Make sure kind fits in int8. 360 // Make sure kind fits in int8.
354 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); 361 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
355 362
356 int8_t kind_; 363 int8_t kind_;
357 }; 364 };
358 365
359 366
(...skipping 2459 matching lines...) Expand 10 before | Expand all | Expand 10 after
2819 2826
2820 HValue* receiver() { return OperandAt(0); } 2827 HValue* receiver() { return OperandAt(0); }
2821 HValue* function() { return OperandAt(1); } 2828 HValue* function() { return OperandAt(1); }
2822 2829
2823 virtual HValue* Canonicalize(); 2830 virtual HValue* Canonicalize();
2824 2831
2825 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver) 2832 DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
2826 }; 2833 };
2827 2834
2828 2835
2836 enum BoundsCheckKeyMode {
2837 DONT_ALLOW_SMI_KEY,
2838 ALLOW_SMI_KEY
2839 };
2840
2841
2842 class HBoundsCheck: public HTemplateInstruction<2> {
2843 public:
2844 HBoundsCheck(HValue* index, HValue* length,
2845 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY)
2846 : key_mode_(key_mode) {
2847 SetOperandAt(0, index);
2848 SetOperandAt(1, length);
2849 set_representation(Representation::Integer32());
2850 SetFlag(kUseGVN);
2851 }
2852
2853 virtual Representation RequiredInputRepresentation(int arg_index) {
2854 if (key_mode_ == DONT_ALLOW_SMI_KEY ||
2855 !length()->representation().IsTagged()) {
2856 return Representation::Integer32();
2857 }
2858 // If the index is tagged and isn't constant, then allow the length
2859 // to be tagged, since it is usually already tagged from loading it out of
2860 // the length field of a JSArray. This allows for direct comparison without
2861 // untagging.
2862 if (index()->representation().IsTagged() && !index()->IsConstant()) {
2863 return Representation::Tagged();
2864 }
2865 // Also allow the length to be tagged if the index is constant, because
2866 // it can be tagged to allow direct comparison.
2867 if (index()->IsConstant() &&
2868 index()->representation().IsInteger32() &&
2869 arg_index == 1) {
2870 return Representation::Tagged();
2871 }
2872 return Representation::Integer32();
2873 }
2874 virtual Representation observed_input_representation(int index) {
2875 return Representation::Integer32();
2876 }
2877
2878 virtual void PrintDataTo(StringStream* stream);
2879
2880 HValue* index() { return OperandAt(0); }
2881 HValue* length() { return OperandAt(1); }
2882
2883 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
2884
2885 static HValue* ExtractUncheckedIndex(HValue* index) {
2886 return index->IsBoundsCheck() ? HBoundsCheck::cast(index)->index() : index;
2887 }
2888
2889 protected:
2890 virtual bool DataEquals(HValue* other) { return true; }
2891 BoundsCheckKeyMode key_mode_;
2892 };
2893
2894
2829 class HApplyArguments: public HTemplateInstruction<4> { 2895 class HApplyArguments: public HTemplateInstruction<4> {
2830 public: 2896 public:
2831 HApplyArguments(HValue* function, 2897 HApplyArguments(HValue* function,
2832 HValue* receiver, 2898 HValue* receiver,
2833 HValue* length, 2899 HValue* length,
2834 HValue* elements) { 2900 HValue* elements) {
2835 set_representation(Representation::Tagged()); 2901 set_representation(Representation::Tagged());
2836 SetOperandAt(0, function); 2902 SetOperandAt(0, function);
2837 SetOperandAt(1, receiver); 2903 SetOperandAt(1, receiver);
2838 SetOperandAt(2, length); 2904 SetOperandAt(2, length);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2897 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength) 2963 DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
2898 2964
2899 protected: 2965 protected:
2900 virtual bool DataEquals(HValue* other) { return true; } 2966 virtual bool DataEquals(HValue* other) { return true; }
2901 2967
2902 private: 2968 private:
2903 virtual bool IsDeletable() const { return true; } 2969 virtual bool IsDeletable() const { return true; }
2904 }; 2970 };
2905 2971
2906 2972
2907 class HAccessArgumentsAt: public HTemplateInstruction<3> { 2973 class HAccessArgumentsAt: public HTemplateInstruction<4> {
2908 public: 2974 public:
2909 HAccessArgumentsAt(HValue* arguments, HValue* length, HValue* index) { 2975 HAccessArgumentsAt(HValue* arguments,
2976 HValue* length,
2977 HValue* checked_index) {
2910 set_representation(Representation::Tagged()); 2978 set_representation(Representation::Tagged());
2911 SetFlag(kUseGVN); 2979 SetFlag(kUseGVN);
2912 SetOperandAt(0, arguments); 2980 SetOperandAt(0, arguments);
2913 SetOperandAt(1, length); 2981 SetOperandAt(1, length);
2914 SetOperandAt(2, index); 2982 SetOperandAt(2, HBoundsCheck::ExtractUncheckedIndex(checked_index));
2983 SetOperandAt(3, checked_index);
2915 } 2984 }
2916 2985
2917 virtual void PrintDataTo(StringStream* stream); 2986 virtual void PrintDataTo(StringStream* stream);
2918 2987
2919 virtual Representation RequiredInputRepresentation(int index) { 2988 virtual Representation RequiredInputRepresentation(int index) {
2920 // The arguments elements is considered tagged. 2989 switch (index) {
2921 return index == 0 2990 // The arguments elements is considered tagged.
2922 ? Representation::Tagged() 2991 case 0: return Representation::Tagged();
2923 : Representation::Integer32(); 2992 case 1: return Representation::Integer32();
2993 case 2: return Representation::Integer32();
2994 // The checked index is a control flow dependency to avoid hoisting
2995 // and therefore it has no representation requirements.
2996 case 3: return Representation::None();
2997 default: { UNREACHABLE(); return Representation::None(); }
2998 }
2924 } 2999 }
2925 3000
2926 HValue* arguments() { return OperandAt(0); } 3001 HValue* arguments() { return OperandAt(0); }
2927 HValue* length() { return OperandAt(1); } 3002 HValue* length() { return OperandAt(1); }
2928 HValue* index() { return OperandAt(2); } 3003 HValue* index() { return OperandAt(2); }
3004 HValue* checked_index() { return OperandAt(3); }
2929 3005
2930 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) 3006 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
2931 3007
2932 virtual bool DataEquals(HValue* other) { return true; } 3008 virtual bool DataEquals(HValue* other) { return true; }
2933 }; 3009 };
2934 3010
2935 3011
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 { 3012 class HBitwiseBinaryOperation: public HBinaryOperation {
2992 public: 3013 public:
2993 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) 3014 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2994 : HBinaryOperation(context, left, right) { 3015 : HBinaryOperation(context, left, right) {
2995 SetFlag(kFlexibleRepresentation); 3016 SetFlag(kFlexibleRepresentation);
2996 SetFlag(kTruncatingToInt32); 3017 SetFlag(kTruncatingToInt32);
2997 SetAllSideEffects(); 3018 SetAllSideEffects();
2998 } 3019 }
2999 3020
3000 virtual Representation RequiredInputRepresentation(int index) { 3021 virtual Representation RequiredInputRepresentation(int index) {
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after
4335 virtual HValue* GetKey() = 0; 4356 virtual HValue* GetKey() = 0;
4336 virtual void SetKey(HValue* key) = 0; 4357 virtual void SetKey(HValue* key) = 0;
4337 virtual void SetIndexOffset(uint32_t index_offset) = 0; 4358 virtual void SetIndexOffset(uint32_t index_offset) = 0;
4338 virtual bool IsDehoisted() = 0; 4359 virtual bool IsDehoisted() = 0;
4339 virtual void SetDehoisted(bool is_dehoisted) = 0; 4360 virtual void SetDehoisted(bool is_dehoisted) = 0;
4340 virtual ~ArrayInstructionInterface() { }; 4361 virtual ~ArrayInstructionInterface() { };
4341 }; 4362 };
4342 4363
4343 4364
4344 class HLoadKeyed 4365 class HLoadKeyed
4345 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 4366 : public HTemplateInstruction<4>, public ArrayInstructionInterface {
4346 public: 4367 public:
4347 HLoadKeyed(HValue* obj, 4368 HLoadKeyed(HValue* obj,
4348 HValue* key, 4369 HValue* checked_key,
4349 HValue* dependency, 4370 HValue* dependency,
4350 ElementsKind elements_kind) 4371 ElementsKind elements_kind)
4351 : bit_field_(0) { 4372 : bit_field_(0) {
4352 bit_field_ = ElementsKindField::encode(elements_kind); 4373 bit_field_ = ElementsKindField::encode(elements_kind);
4353
4354 SetOperandAt(0, obj); 4374 SetOperandAt(0, obj);
4355 SetOperandAt(1, key); 4375 SetOperandAt(1, HBoundsCheck::ExtractUncheckedIndex(checked_key));
4356 SetOperandAt(2, dependency); 4376 SetOperandAt(2, dependency);
4377 SetOperandAt(3, checked_key);
4357 4378
4358 if (!is_external()) { 4379 if (!is_external()) {
4359 // I can detect the case between storing double (holey and fast) and 4380 // I can detect the case between storing double (holey and fast) and
4360 // smi/object by looking at elements_kind_. 4381 // smi/object by looking at elements_kind_.
4361 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || 4382 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
4362 IsFastDoubleElementsKind(elements_kind)); 4383 IsFastDoubleElementsKind(elements_kind));
4363 4384
4364 if (IsFastSmiOrObjectElementsKind(elements_kind)) { 4385 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
4365 if (IsFastSmiElementsKind(elements_kind) && 4386 if (IsFastSmiElementsKind(elements_kind) &&
4366 IsFastPackedElementsKind(elements_kind)) { 4387 IsFastPackedElementsKind(elements_kind)) {
(...skipping 21 matching lines...) Expand all
4388 4409
4389 SetFlag(kUseGVN); 4410 SetFlag(kUseGVN);
4390 } 4411 }
4391 4412
4392 bool is_external() const { 4413 bool is_external() const {
4393 return IsExternalArrayElementsKind(elements_kind()); 4414 return IsExternalArrayElementsKind(elements_kind());
4394 } 4415 }
4395 HValue* elements() { return OperandAt(0); } 4416 HValue* elements() { return OperandAt(0); }
4396 HValue* key() { return OperandAt(1); } 4417 HValue* key() { return OperandAt(1); }
4397 HValue* dependency() { return OperandAt(2); } 4418 HValue* dependency() { return OperandAt(2); }
4419 HValue* checked_key() { return OperandAt(3); }
4398 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } 4420 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
4399 void SetIndexOffset(uint32_t index_offset) { 4421 void SetIndexOffset(uint32_t index_offset) {
4400 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); 4422 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
4401 } 4423 }
4402 HValue* GetKey() { return key(); } 4424 HValue* GetKey() { return key(); }
4403 void SetKey(HValue* key) { SetOperandAt(1, key); } 4425 void SetKey(HValue* key) { SetOperandAt(1, key); }
4404 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } 4426 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
4405 void SetDehoisted(bool is_dehoisted) { 4427 void SetDehoisted(bool is_dehoisted) {
4406 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); 4428 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
4407 } 4429 }
4408 ElementsKind elements_kind() const { 4430 ElementsKind elements_kind() const {
4409 return ElementsKindField::decode(bit_field_); 4431 return ElementsKindField::decode(bit_field_);
4410 } 4432 }
4411 4433
4412 virtual Representation RequiredInputRepresentation(int index) { 4434 virtual Representation RequiredInputRepresentation(int index) {
4413 // kind_fast: tagged[int32] (none) 4435 // kind_fast: tagged[int32] (none)
4414 // kind_double: tagged[int32] (none) 4436 // kind_double: tagged[int32] (none)
4415 // kind_external: external[int32] (none) 4437 // kind_external: external[int32] (none)
4416 if (index == 0) { 4438 if (index == 0) {
4417 return is_external() ? Representation::External() 4439 return is_external() ? Representation::External()
4418 : Representation::Tagged(); 4440 : Representation::Tagged();
4419 } 4441 }
4420 if (index == 1) return Representation::Integer32(); 4442 if (index == 1) {
4443 return OperandAt(1)->representation().KeyedAccessIndexRequirement();
4444 }
4421 return Representation::None(); 4445 return Representation::None();
4422 } 4446 }
4423 4447
4424 virtual Representation observed_input_representation(int index) { 4448 virtual Representation observed_input_representation(int index) {
4425 return RequiredInputRepresentation(index); 4449 return RequiredInputRepresentation(index);
4426 } 4450 }
4427 4451
4428 virtual void PrintDataTo(StringStream* stream); 4452 virtual void PrintDataTo(StringStream* stream);
4429 4453
4430 bool RequiresHoleCheck() const; 4454 bool RequiresHoleCheck() const;
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
4592 4616
4593 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) 4617 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
4594 4618
4595 private: 4619 private:
4596 Handle<String> name_; 4620 Handle<String> name_;
4597 StrictModeFlag strict_mode_flag_; 4621 StrictModeFlag strict_mode_flag_;
4598 }; 4622 };
4599 4623
4600 4624
4601 class HStoreKeyed 4625 class HStoreKeyed
4602 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 4626 : public HTemplateInstruction<4>, public ArrayInstructionInterface {
4603 public: 4627 public:
4604 HStoreKeyed(HValue* obj, HValue* key, HValue* val, 4628 HStoreKeyed(HValue* obj, HValue* checked_key, HValue* val,
4605 ElementsKind elements_kind) 4629 ElementsKind elements_kind)
4606 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { 4630 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) {
4607 SetOperandAt(0, obj); 4631 SetOperandAt(0, obj);
4608 SetOperandAt(1, key); 4632 SetOperandAt(1, HBoundsCheck::ExtractUncheckedIndex(checked_key));
4609 SetOperandAt(2, val); 4633 SetOperandAt(2, val);
4634 SetOperandAt(3, checked_key);
4610 4635
4611 if (is_external()) { 4636 if (is_external()) {
4612 SetGVNFlag(kChangesSpecializedArrayElements); 4637 SetGVNFlag(kChangesSpecializedArrayElements);
4613 } else if (IsFastDoubleElementsKind(elements_kind)) { 4638 } else if (IsFastDoubleElementsKind(elements_kind)) {
4614 SetGVNFlag(kChangesDoubleArrayElements); 4639 SetGVNFlag(kChangesDoubleArrayElements);
4615 SetFlag(kDeoptimizeOnUndefined); 4640 SetFlag(kDeoptimizeOnUndefined);
4616 } else { 4641 } else {
4617 SetGVNFlag(kChangesArrayElements); 4642 SetGVNFlag(kChangesArrayElements);
4618 } 4643 }
4619 4644
4620 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. 4645 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
4621 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && 4646 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
4622 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { 4647 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
4623 SetFlag(kTruncatingToInt32); 4648 SetFlag(kTruncatingToInt32);
4624 } 4649 }
4625 } 4650 }
4626 4651
4627 virtual Representation RequiredInputRepresentation(int index) { 4652 virtual Representation RequiredInputRepresentation(int index) {
4628 // kind_fast: tagged[int32] = tagged 4653 // kind_fast: tagged[int32] = tagged
4629 // kind_double: tagged[int32] = double 4654 // kind_double: tagged[int32] = double
4630 // kind_external: external[int32] = (double | int32) 4655 // kind_external: external[int32] = (double | int32)
4631 if (index == 0) { 4656 if (index == 0) {
4632 return is_external() ? Representation::External() 4657 return is_external() ? Representation::External()
4633 : Representation::Tagged(); 4658 : Representation::Tagged();
4634 } else if (index == 1) { 4659 } else if (index == 1) {
4635 return Representation::Integer32(); 4660 return OperandAt(1)->representation().KeyedAccessIndexRequirement();
4661 } else if (index == 3) {
4662 return Representation::None();
4636 } 4663 }
4637 4664
4638 ASSERT_EQ(index, 2); 4665 ASSERT_EQ(index, 2);
4639 if (IsDoubleOrFloatElementsKind(elements_kind())) { 4666 if (IsDoubleOrFloatElementsKind(elements_kind())) {
4640 return Representation::Double(); 4667 return Representation::Double();
4641 } 4668 }
4642 4669
4643 return is_external() ? Representation::Integer32() 4670 return is_external() ? Representation::Integer32()
4644 : Representation::Tagged(); 4671 : Representation::Tagged();
4645 } 4672 }
(...skipping 10 matching lines...) Expand all
4656 if (is_external()) { 4683 if (is_external()) {
4657 return Representation::Integer32(); 4684 return Representation::Integer32();
4658 } 4685 }
4659 // For fast object elements kinds, don't assume anything. 4686 // For fast object elements kinds, don't assume anything.
4660 return Representation::None(); 4687 return Representation::None();
4661 } 4688 }
4662 4689
4663 HValue* elements() { return OperandAt(0); } 4690 HValue* elements() { return OperandAt(0); }
4664 HValue* key() { return OperandAt(1); } 4691 HValue* key() { return OperandAt(1); }
4665 HValue* value() { return OperandAt(2); } 4692 HValue* value() { return OperandAt(2); }
4693 HValue* checked_key() { return OperandAt(3); }
4666 bool value_is_smi() const { 4694 bool value_is_smi() const {
4667 return IsFastSmiElementsKind(elements_kind_); 4695 return IsFastSmiElementsKind(elements_kind_);
4668 } 4696 }
4669 ElementsKind elements_kind() const { return elements_kind_; } 4697 ElementsKind elements_kind() const { return elements_kind_; }
4670 uint32_t index_offset() { return index_offset_; } 4698 uint32_t index_offset() { return index_offset_; }
4671 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } 4699 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4672 HValue* GetKey() { return key(); } 4700 HValue* GetKey() { return key(); }
4673 void SetKey(HValue* key) { SetOperandAt(1, key); } 4701 void SetKey(HValue* key) { SetOperandAt(1, key); }
4674 bool IsDehoisted() { return is_dehoisted_; } 4702 bool IsDehoisted() { return is_dehoisted_; }
4675 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 4703 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
4798 4826
4799 protected: 4827 protected:
4800 virtual bool DataEquals(HValue* other) { return true; } 4828 virtual bool DataEquals(HValue* other) { return true; }
4801 4829
4802 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. 4830 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
4803 // private: 4831 // private:
4804 // virtual bool IsDeletable() const { return true; } 4832 // virtual bool IsDeletable() const { return true; }
4805 }; 4833 };
4806 4834
4807 4835
4808 class HStringCharCodeAt: public HTemplateInstruction<3> { 4836 class HStringCharCodeAt: public HTemplateInstruction<4> {
4809 public: 4837 public:
4810 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { 4838 HStringCharCodeAt(HValue* context, HValue* string, HValue* checked_index) {
4811 SetOperandAt(0, context); 4839 SetOperandAt(0, context);
4812 SetOperandAt(1, string); 4840 SetOperandAt(1, string);
4813 SetOperandAt(2, index); 4841 SetOperandAt(2, HBoundsCheck::ExtractUncheckedIndex(checked_index));
4842 SetOperandAt(3, checked_index);
4814 set_representation(Representation::Integer32()); 4843 set_representation(Representation::Integer32());
4815 SetFlag(kUseGVN); 4844 SetFlag(kUseGVN);
4816 SetGVNFlag(kDependsOnMaps); 4845 SetGVNFlag(kDependsOnMaps);
4817 SetGVNFlag(kChangesNewSpacePromotion); 4846 SetGVNFlag(kChangesNewSpacePromotion);
4818 } 4847 }
4819 4848
4820 virtual Representation RequiredInputRepresentation(int index) { 4849 virtual Representation RequiredInputRepresentation(int index) {
4821 // The index is supposed to be Integer32. 4850 switch (index) {
4822 return index == 2 4851 case 0: return Representation::Tagged();
4823 ? Representation::Integer32() 4852 case 1: return Representation::Tagged();
4824 : Representation::Tagged(); 4853 // The index is supposed to be Integer32.
4854 case 2: return Representation::Integer32();
4855 // The checked index is a control flow dependency to avoid hoisting
4856 // and therefore it has no representation requirements.
4857 case 3: return Representation::None();
4858 default: { UNREACHABLE(); return Representation::None(); }
4859 }
4825 } 4860 }
4826 4861
4827 HValue* context() { return OperandAt(0); } 4862 HValue* context() { return OperandAt(0); }
4828 HValue* string() { return OperandAt(1); } 4863 HValue* string() { return OperandAt(1); }
4829 HValue* index() { return OperandAt(2); } 4864 HValue* index() { return OperandAt(2); }
4865 HValue* checked_index() { return OperandAt(3); }
4830 4866
4831 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) 4867 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
4832 4868
4833 protected: 4869 protected:
4834 virtual bool DataEquals(HValue* other) { return true; } 4870 virtual bool DataEquals(HValue* other) { return true; }
4835 4871
4836 virtual Range* InferRange(Zone* zone) { 4872 virtual Range* InferRange(Zone* zone) {
4837 return new(zone) Range(0, String::kMaxUtf16CodeUnit); 4873 return new(zone) Range(0, String::kMaxUtf16CodeUnit);
4838 } 4874 }
4839 4875
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
5390 virtual bool IsDeletable() const { return true; } 5426 virtual bool IsDeletable() const { return true; }
5391 }; 5427 };
5392 5428
5393 5429
5394 #undef DECLARE_INSTRUCTION 5430 #undef DECLARE_INSTRUCTION
5395 #undef DECLARE_CONCRETE_INSTRUCTION 5431 #undef DECLARE_CONCRETE_INSTRUCTION
5396 5432
5397 } } // namespace v8::internal 5433 } } // namespace v8::internal
5398 5434
5399 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5435 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698