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

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: Relax the representation requirements for indexes in keyed accesses. 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
« src/hydrogen.cc ('K') | « 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 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
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
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
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
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
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
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
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
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_
OLDNEW
« src/hydrogen.cc ('K') | « src/hydrogen.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698