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

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 return IsInteger32() ? Integer32() : Tagged();
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 switch (index) {
2921 return index == 0 2987 // The arguments elements is considered tagged.
2922 ? Representation::Tagged() 2988 case 0: return Representation::Tagged();
2923 : Representation::Integer32(); 2989 // The checked index is a control flow dependency do avoid hoisting
2990 // and therefore it has no representation requirements.
2991 case 3: return Representation::None();
2992 default: return Representation::Integer32();
Sven Panne 2012/12/07 10:24:58 default is evil (a maintenance nightmare), please
2993 }
2924 } 2994 }
2925 2995
2926 HValue* arguments() { return OperandAt(0); } 2996 HValue* arguments() { return OperandAt(0); }
2927 HValue* length() { return OperandAt(1); } 2997 HValue* length() { return OperandAt(1); }
2928 HValue* index() { return OperandAt(2); } 2998 HValue* index() { return OperandAt(2); }
2999 HValue* checked_index() { return OperandAt(3); }
2929 3000
2930 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt) 3001 DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt)
2931 3002
2932 virtual bool DataEquals(HValue* other) { return true; } 3003 virtual bool DataEquals(HValue* other) { return true; }
2933 }; 3004 };
2934 3005
2935 3006
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 { 3007 class HBitwiseBinaryOperation: public HBinaryOperation {
2992 public: 3008 public:
2993 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) 3009 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
2994 : HBinaryOperation(context, left, right) { 3010 : HBinaryOperation(context, left, right) {
2995 SetFlag(kFlexibleRepresentation); 3011 SetFlag(kFlexibleRepresentation);
2996 SetFlag(kTruncatingToInt32); 3012 SetFlag(kTruncatingToInt32);
2997 SetAllSideEffects(); 3013 SetAllSideEffects();
2998 } 3014 }
2999 3015
3000 virtual Representation RequiredInputRepresentation(int index) { 3016 virtual Representation RequiredInputRepresentation(int index) {
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after
4335 virtual HValue* GetKey() = 0; 4351 virtual HValue* GetKey() = 0;
4336 virtual void SetKey(HValue* key) = 0; 4352 virtual void SetKey(HValue* key) = 0;
4337 virtual void SetIndexOffset(uint32_t index_offset) = 0; 4353 virtual void SetIndexOffset(uint32_t index_offset) = 0;
4338 virtual bool IsDehoisted() = 0; 4354 virtual bool IsDehoisted() = 0;
4339 virtual void SetDehoisted(bool is_dehoisted) = 0; 4355 virtual void SetDehoisted(bool is_dehoisted) = 0;
4340 virtual ~ArrayInstructionInterface() { }; 4356 virtual ~ArrayInstructionInterface() { };
4341 }; 4357 };
4342 4358
4343 4359
4344 class HLoadKeyed 4360 class HLoadKeyed
4345 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 4361 : public HTemplateInstruction<4>, public ArrayInstructionInterface {
4346 public: 4362 public:
4347 HLoadKeyed(HValue* obj, 4363 HLoadKeyed(HValue* obj,
4348 HValue* key, 4364 HValue* checked_key,
4349 HValue* dependency, 4365 HValue* dependency,
4350 ElementsKind elements_kind) 4366 ElementsKind elements_kind)
4351 : bit_field_(0) { 4367 : bit_field_(0) {
4352 bit_field_ = ElementsKindField::encode(elements_kind); 4368 bit_field_ = ElementsKindField::encode(elements_kind);
4353
4354 SetOperandAt(0, obj); 4369 SetOperandAt(0, obj);
4355 SetOperandAt(1, key); 4370 SetOperandAt(1, HBoundsCheck::ExtractUncheckedIndex(checked_key));
4356 SetOperandAt(2, dependency); 4371 SetOperandAt(2, dependency);
4372 SetOperandAt(3, checked_key);
4357 4373
4358 if (!is_external()) { 4374 if (!is_external()) {
4359 // I can detect the case between storing double (holey and fast) and 4375 // I can detect the case between storing double (holey and fast) and
4360 // smi/object by looking at elements_kind_. 4376 // smi/object by looking at elements_kind_.
4361 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) || 4377 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind) ||
4362 IsFastDoubleElementsKind(elements_kind)); 4378 IsFastDoubleElementsKind(elements_kind));
4363 4379
4364 if (IsFastSmiOrObjectElementsKind(elements_kind)) { 4380 if (IsFastSmiOrObjectElementsKind(elements_kind)) {
4365 if (IsFastSmiElementsKind(elements_kind) && 4381 if (IsFastSmiElementsKind(elements_kind) &&
4366 IsFastPackedElementsKind(elements_kind)) { 4382 IsFastPackedElementsKind(elements_kind)) {
(...skipping 21 matching lines...) Expand all
4388 4404
4389 SetFlag(kUseGVN); 4405 SetFlag(kUseGVN);
4390 } 4406 }
4391 4407
4392 bool is_external() const { 4408 bool is_external() const {
4393 return IsExternalArrayElementsKind(elements_kind()); 4409 return IsExternalArrayElementsKind(elements_kind());
4394 } 4410 }
4395 HValue* elements() { return OperandAt(0); } 4411 HValue* elements() { return OperandAt(0); }
4396 HValue* key() { return OperandAt(1); } 4412 HValue* key() { return OperandAt(1); }
4397 HValue* dependency() { return OperandAt(2); } 4413 HValue* dependency() { return OperandAt(2); }
4414 HValue* checked_key() { return OperandAt(3); }
4398 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); } 4415 uint32_t index_offset() { return IndexOffsetField::decode(bit_field_); }
4399 void SetIndexOffset(uint32_t index_offset) { 4416 void SetIndexOffset(uint32_t index_offset) {
4400 bit_field_ = IndexOffsetField::update(bit_field_, index_offset); 4417 bit_field_ = IndexOffsetField::update(bit_field_, index_offset);
4401 } 4418 }
4402 HValue* GetKey() { return key(); } 4419 HValue* GetKey() { return key(); }
4403 void SetKey(HValue* key) { SetOperandAt(1, key); } 4420 void SetKey(HValue* key) { SetOperandAt(1, key); }
4404 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); } 4421 bool IsDehoisted() { return IsDehoistedField::decode(bit_field_); }
4405 void SetDehoisted(bool is_dehoisted) { 4422 void SetDehoisted(bool is_dehoisted) {
4406 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted); 4423 bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
4407 } 4424 }
4408 ElementsKind elements_kind() const { 4425 ElementsKind elements_kind() const {
4409 return ElementsKindField::decode(bit_field_); 4426 return ElementsKindField::decode(bit_field_);
4410 } 4427 }
4411 4428
4412 virtual Representation RequiredInputRepresentation(int index) { 4429 virtual Representation RequiredInputRepresentation(int index) {
4413 // kind_fast: tagged[int32] (none) 4430 // kind_fast: tagged[int32] (none)
4414 // kind_double: tagged[int32] (none) 4431 // kind_double: tagged[int32] (none)
4415 // kind_external: external[int32] (none) 4432 // kind_external: external[int32] (none)
4416 if (index == 0) { 4433 if (index == 0) {
4417 return is_external() ? Representation::External() 4434 return is_external() ? Representation::External()
4418 : Representation::Tagged(); 4435 : Representation::Tagged();
4419 } 4436 }
4420 if (index == 1) return Representation::Integer32(); 4437 if (index == 1) {
4438 return OperandAt(1)->representation().KeyedAccessIndexRequirement();
4439 }
4421 return Representation::None(); 4440 return Representation::None();
4422 } 4441 }
4423 4442
4424 virtual Representation observed_input_representation(int index) { 4443 virtual Representation observed_input_representation(int index) {
4425 return RequiredInputRepresentation(index); 4444 return RequiredInputRepresentation(index);
4426 } 4445 }
4427 4446
4428 virtual void PrintDataTo(StringStream* stream); 4447 virtual void PrintDataTo(StringStream* stream);
4429 4448
4430 bool RequiresHoleCheck() const; 4449 bool RequiresHoleCheck() const;
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
4592 4611
4593 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric) 4612 DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric)
4594 4613
4595 private: 4614 private:
4596 Handle<String> name_; 4615 Handle<String> name_;
4597 StrictModeFlag strict_mode_flag_; 4616 StrictModeFlag strict_mode_flag_;
4598 }; 4617 };
4599 4618
4600 4619
4601 class HStoreKeyed 4620 class HStoreKeyed
4602 : public HTemplateInstruction<3>, public ArrayInstructionInterface { 4621 : public HTemplateInstruction<4>, public ArrayInstructionInterface {
4603 public: 4622 public:
4604 HStoreKeyed(HValue* obj, HValue* key, HValue* val, 4623 HStoreKeyed(HValue* obj, HValue* checked_key, HValue* val,
4605 ElementsKind elements_kind) 4624 ElementsKind elements_kind)
4606 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) { 4625 : elements_kind_(elements_kind), index_offset_(0), is_dehoisted_(false) {
4607 SetOperandAt(0, obj); 4626 SetOperandAt(0, obj);
4608 SetOperandAt(1, key); 4627 SetOperandAt(1, HBoundsCheck::ExtractUncheckedIndex(checked_key));
4609 SetOperandAt(2, val); 4628 SetOperandAt(2, val);
4629 SetOperandAt(3, checked_key);
4610 4630
4611 if (is_external()) { 4631 if (is_external()) {
4612 SetGVNFlag(kChangesSpecializedArrayElements); 4632 SetGVNFlag(kChangesSpecializedArrayElements);
4613 } else if (IsFastDoubleElementsKind(elements_kind)) { 4633 } else if (IsFastDoubleElementsKind(elements_kind)) {
4614 SetGVNFlag(kChangesDoubleArrayElements); 4634 SetGVNFlag(kChangesDoubleArrayElements);
4615 SetFlag(kDeoptimizeOnUndefined); 4635 SetFlag(kDeoptimizeOnUndefined);
4616 } else { 4636 } else {
4617 SetGVNFlag(kChangesArrayElements); 4637 SetGVNFlag(kChangesArrayElements);
4618 } 4638 }
4619 4639
4620 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. 4640 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
4621 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && 4641 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
4622 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { 4642 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
4623 SetFlag(kTruncatingToInt32); 4643 SetFlag(kTruncatingToInt32);
4624 } 4644 }
4625 } 4645 }
4626 4646
4627 virtual Representation RequiredInputRepresentation(int index) { 4647 virtual Representation RequiredInputRepresentation(int index) {
4628 // kind_fast: tagged[int32] = tagged 4648 // kind_fast: tagged[int32] = tagged
4629 // kind_double: tagged[int32] = double 4649 // kind_double: tagged[int32] = double
4630 // kind_external: external[int32] = (double | int32) 4650 // kind_external: external[int32] = (double | int32)
4631 if (index == 0) { 4651 if (index == 0) {
4632 return is_external() ? Representation::External() 4652 return is_external() ? Representation::External()
4633 : Representation::Tagged(); 4653 : Representation::Tagged();
4634 } else if (index == 1) { 4654 } else if (index == 1) {
4635 return Representation::Integer32(); 4655 return OperandAt(1)->representation().KeyedAccessIndexRequirement();
4656 } else if (index == 3) {
4657 return Representation::None();
4636 } 4658 }
4637 4659
4638 ASSERT_EQ(index, 2); 4660 ASSERT_EQ(index, 2);
4639 if (IsDoubleOrFloatElementsKind(elements_kind())) { 4661 if (IsDoubleOrFloatElementsKind(elements_kind())) {
4640 return Representation::Double(); 4662 return Representation::Double();
4641 } 4663 }
4642 4664
4643 return is_external() ? Representation::Integer32() 4665 return is_external() ? Representation::Integer32()
4644 : Representation::Tagged(); 4666 : Representation::Tagged();
4645 } 4667 }
(...skipping 10 matching lines...) Expand all
4656 if (is_external()) { 4678 if (is_external()) {
4657 return Representation::Integer32(); 4679 return Representation::Integer32();
4658 } 4680 }
4659 // For fast object elements kinds, don't assume anything. 4681 // For fast object elements kinds, don't assume anything.
4660 return Representation::None(); 4682 return Representation::None();
4661 } 4683 }
4662 4684
4663 HValue* elements() { return OperandAt(0); } 4685 HValue* elements() { return OperandAt(0); }
4664 HValue* key() { return OperandAt(1); } 4686 HValue* key() { return OperandAt(1); }
4665 HValue* value() { return OperandAt(2); } 4687 HValue* value() { return OperandAt(2); }
4688 HValue* checked_key() { return OperandAt(3); }
4666 bool value_is_smi() const { 4689 bool value_is_smi() const {
4667 return IsFastSmiElementsKind(elements_kind_); 4690 return IsFastSmiElementsKind(elements_kind_);
4668 } 4691 }
4669 ElementsKind elements_kind() const { return elements_kind_; } 4692 ElementsKind elements_kind() const { return elements_kind_; }
4670 uint32_t index_offset() { return index_offset_; } 4693 uint32_t index_offset() { return index_offset_; }
4671 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } 4694 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; }
4672 HValue* GetKey() { return key(); } 4695 HValue* GetKey() { return key(); }
4673 void SetKey(HValue* key) { SetOperandAt(1, key); } 4696 void SetKey(HValue* key) { SetOperandAt(1, key); }
4674 bool IsDehoisted() { return is_dehoisted_; } 4697 bool IsDehoisted() { return is_dehoisted_; }
4675 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; } 4698 void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
4798 4821
4799 protected: 4822 protected:
4800 virtual bool DataEquals(HValue* other) { return true; } 4823 virtual bool DataEquals(HValue* other) { return true; }
4801 4824
4802 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. 4825 // TODO(svenpanne) Might be safe, but leave it out until we know for sure.
4803 // private: 4826 // private:
4804 // virtual bool IsDeletable() const { return true; } 4827 // virtual bool IsDeletable() const { return true; }
4805 }; 4828 };
4806 4829
4807 4830
4808 class HStringCharCodeAt: public HTemplateInstruction<3> { 4831 class HStringCharCodeAt: public HTemplateInstruction<4> {
4809 public: 4832 public:
4810 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { 4833 HStringCharCodeAt(HValue* context, HValue* string, HValue* checked_index) {
4811 SetOperandAt(0, context); 4834 SetOperandAt(0, context);
4812 SetOperandAt(1, string); 4835 SetOperandAt(1, string);
4813 SetOperandAt(2, index); 4836 SetOperandAt(2, HBoundsCheck::ExtractUncheckedIndex(checked_index));
4837 SetOperandAt(3, checked_index);
4814 set_representation(Representation::Integer32()); 4838 set_representation(Representation::Integer32());
4815 SetFlag(kUseGVN); 4839 SetFlag(kUseGVN);
4816 SetGVNFlag(kDependsOnMaps); 4840 SetGVNFlag(kDependsOnMaps);
4817 SetGVNFlag(kChangesNewSpacePromotion); 4841 SetGVNFlag(kChangesNewSpacePromotion);
4818 } 4842 }
4819 4843
4820 virtual Representation RequiredInputRepresentation(int index) { 4844 virtual Representation RequiredInputRepresentation(int index) {
4821 // The index is supposed to be Integer32. 4845 switch (index) {
4822 return index == 2 4846 // The index is supposed to be Integer32.
4823 ? Representation::Integer32() 4847 case 2: return Representation::Integer32();
4824 : Representation::Tagged(); 4848 // The checked index is a control flow dependency do avoid hoisting
4849 // and therefore it has no representation requirements.
4850 case 3: return Representation::None();
4851 default: return Representation::Tagged();
Sven Panne 2012/12/07 10:24:58 see above
4852 }
4825 } 4853 }
4826 4854
4827 HValue* context() { return OperandAt(0); } 4855 HValue* context() { return OperandAt(0); }
4828 HValue* string() { return OperandAt(1); } 4856 HValue* string() { return OperandAt(1); }
4829 HValue* index() { return OperandAt(2); } 4857 HValue* index() { return OperandAt(2); }
4858 HValue* checked_index() { return OperandAt(3); }
4830 4859
4831 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) 4860 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
4832 4861
4833 protected: 4862 protected:
4834 virtual bool DataEquals(HValue* other) { return true; } 4863 virtual bool DataEquals(HValue* other) { return true; }
4835 4864
4836 virtual Range* InferRange(Zone* zone) { 4865 virtual Range* InferRange(Zone* zone) {
4837 return new(zone) Range(0, String::kMaxUtf16CodeUnit); 4866 return new(zone) Range(0, String::kMaxUtf16CodeUnit);
4838 } 4867 }
4839 4868
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after
5390 virtual bool IsDeletable() const { return true; } 5419 virtual bool IsDeletable() const { return true; }
5391 }; 5420 };
5392 5421
5393 5422
5394 #undef DECLARE_INSTRUCTION 5423 #undef DECLARE_INSTRUCTION
5395 #undef DECLARE_CONCRETE_INSTRUCTION 5424 #undef DECLARE_CONCRETE_INSTRUCTION
5396 5425
5397 } } // namespace v8::internal 5426 } } // namespace v8::internal
5398 5427
5399 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5428 #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