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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2436893003: [stubs] Cleanup CSA::BitFieldDecode() and friends. (Closed)
Patch Set: Addressing comments Created 4 years, 2 months 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
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/interpreter/interpreter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 #include "src/code-stub-assembler.h" 4 #include "src/code-stub-assembler.h"
5 #include "src/code-factory.h" 5 #include "src/code-factory.h"
6 #include "src/frames-inl.h" 6 #include "src/frames-inl.h"
7 #include "src/frames.h" 7 #include "src/frames.h"
8 #include "src/ic/handler-configuration.h" 8 #include "src/ic/handler-configuration.h"
9 #include "src/ic/stub-cache.h" 9 #include "src/ic/stub-cache.h"
10 10
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 Label* if_true, Label* if_false) { 651 Label* if_true, Label* if_false) {
652 // Bailout if receiver is a Smi. 652 // Bailout if receiver is a Smi.
653 GotoIf(TaggedIsSmi(object), if_false); 653 GotoIf(TaggedIsSmi(object), if_false);
654 654
655 Node* map = LoadMap(object); 655 Node* map = LoadMap(object);
656 656
657 // Bailout if instance type is not JS_ARRAY_TYPE. 657 // Bailout if instance type is not JS_ARRAY_TYPE.
658 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)), 658 GotoIf(WordNotEqual(LoadMapInstanceType(map), Int32Constant(JS_ARRAY_TYPE)),
659 if_false); 659 if_false);
660 660
661 Node* bit_field2 = LoadMapBitField2(map); 661 Node* elements_kind = LoadMapElementsKind(map);
662 Node* elements_kind = BitFieldDecode<Map::ElementsKindBits>(bit_field2);
663 662
664 // Bailout if receiver has slow elements. 663 // Bailout if receiver has slow elements.
665 GotoIf( 664 GotoIf(
666 Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)), 665 Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)),
667 if_false); 666 if_false);
668 667
669 // Check prototype chain if receiver does not have packed elements. 668 // Check prototype chain if receiver does not have packed elements.
670 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1)); 669 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1));
671 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1)); 670 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1));
672 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1)); 671 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1));
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 Node* CodeStubAssembler::LoadMapBitField3(Node* map) { 1017 Node* CodeStubAssembler::LoadMapBitField3(Node* map) {
1019 return LoadObjectField(map, Map::kBitField3Offset, MachineType::Uint32()); 1018 return LoadObjectField(map, Map::kBitField3Offset, MachineType::Uint32());
1020 } 1019 }
1021 1020
1022 Node* CodeStubAssembler::LoadMapInstanceType(Node* map) { 1021 Node* CodeStubAssembler::LoadMapInstanceType(Node* map) {
1023 return LoadObjectField(map, Map::kInstanceTypeOffset, MachineType::Uint8()); 1022 return LoadObjectField(map, Map::kInstanceTypeOffset, MachineType::Uint8());
1024 } 1023 }
1025 1024
1026 Node* CodeStubAssembler::LoadMapElementsKind(Node* map) { 1025 Node* CodeStubAssembler::LoadMapElementsKind(Node* map) {
1027 Node* bit_field2 = LoadMapBitField2(map); 1026 Node* bit_field2 = LoadMapBitField2(map);
1028 return BitFieldDecode<Map::ElementsKindBits>(bit_field2); 1027 return DecodeWord32<Map::ElementsKindBits>(bit_field2);
1029 } 1028 }
1030 1029
1031 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) { 1030 Node* CodeStubAssembler::LoadMapDescriptors(Node* map) {
1032 return LoadObjectField(map, Map::kDescriptorsOffset); 1031 return LoadObjectField(map, Map::kDescriptorsOffset);
1033 } 1032 }
1034 1033
1035 Node* CodeStubAssembler::LoadMapPrototype(Node* map) { 1034 Node* CodeStubAssembler::LoadMapPrototype(Node* map) {
1036 return LoadObjectField(map, Map::kPrototypeOffset); 1035 return LoadObjectField(map, Map::kPrototypeOffset);
1037 } 1036 }
1038 1037
(...skipping 2273 matching lines...) Expand 10 before | Expand all | Expand 10 after
3312 Label end(this); 3311 Label end(this);
3313 3312
3314 Variable var_result(this, MachineRepresentation::kTagged); 3313 Variable var_result(this, MachineRepresentation::kTagged);
3315 3314
3316 // Check if string has a cached array index. 3315 // Check if string has a cached array index.
3317 Node* hash = LoadNameHashField(input); 3316 Node* hash = LoadNameHashField(input);
3318 Node* bit = 3317 Node* bit =
3319 Word32And(hash, Int32Constant(String::kContainsCachedArrayIndexMask)); 3318 Word32And(hash, Int32Constant(String::kContainsCachedArrayIndexMask));
3320 GotoIf(Word32NotEqual(bit, Int32Constant(0)), &runtime); 3319 GotoIf(Word32NotEqual(bit, Int32Constant(0)), &runtime);
3321 3320
3322 var_result.Bind(SmiTag(BitFieldDecode<String::ArrayIndexValueBits>(hash))); 3321 var_result.Bind(
3322 SmiTag(DecodeWordFromWord32<String::ArrayIndexValueBits>(hash)));
3323 Goto(&end); 3323 Goto(&end);
3324 3324
3325 Bind(&runtime); 3325 Bind(&runtime);
3326 { 3326 {
3327 var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input)); 3327 var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input));
3328 Goto(&end); 3328 Goto(&end);
3329 } 3329 }
3330 3330
3331 Bind(&end); 3331 Bind(&end);
3332 return var_result.value(); 3332 return var_result.value();
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
3704 3704
3705 Bind(&return_zero); 3705 Bind(&return_zero);
3706 var_arg.Bind(SmiConstant(Smi::kZero)); 3706 var_arg.Bind(SmiConstant(Smi::kZero));
3707 Goto(&out); 3707 Goto(&out);
3708 } 3708 }
3709 3709
3710 Bind(&out); 3710 Bind(&out);
3711 return var_arg.value(); 3711 return var_arg.value();
3712 } 3712 }
3713 3713
3714 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, 3714 Node* CodeStubAssembler::DecodeWord32(Node* word32, uint32_t shift,
3715 uint32_t mask) { 3715 uint32_t mask) {
3716 return Word32Shr(Word32And(word32, Int32Constant(mask)), 3716 return Word32Shr(Word32And(word32, Int32Constant(mask)),
3717 static_cast<int>(shift)); 3717 static_cast<int>(shift));
3718 } 3718 }
3719 3719
3720 Node* CodeStubAssembler::DecodeWord(Node* word, uint32_t shift, uint32_t mask) {
3721 return WordShr(WordAnd(word, IntPtrConstant(mask)), static_cast<int>(shift));
3722 }
3723
3720 void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) { 3724 void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) {
3721 if (FLAG_native_code_counters && counter->Enabled()) { 3725 if (FLAG_native_code_counters && counter->Enabled()) {
3722 Node* counter_address = ExternalConstant(ExternalReference(counter)); 3726 Node* counter_address = ExternalConstant(ExternalReference(counter));
3723 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, 3727 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address,
3724 Int32Constant(value)); 3728 Int32Constant(value));
3725 } 3729 }
3726 } 3730 }
3727 3731
3728 void CodeStubAssembler::IncrementCounter(StatsCounter* counter, int delta) { 3732 void CodeStubAssembler::IncrementCounter(StatsCounter* counter, int delta) {
3729 DCHECK(delta > 0); 3733 DCHECK(delta > 0);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3779 Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask)); 3783 Word32And(hash, Int32Constant(Name::kIsNotArrayIndexMask));
3780 GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout); 3784 GotoIf(Word32Equal(not_an_index, Int32Constant(0)), if_bailout);
3781 // Finally, check if |key| is internalized. 3785 // Finally, check if |key| is internalized.
3782 STATIC_ASSERT(kNotInternalizedTag != 0); 3786 STATIC_ASSERT(kNotInternalizedTag != 0);
3783 Node* not_internalized = 3787 Node* not_internalized =
3784 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask)); 3788 Word32And(key_instance_type, Int32Constant(kIsNotInternalizedMask));
3785 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout); 3789 GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout);
3786 Goto(if_keyisunique); 3790 Goto(if_keyisunique);
3787 3791
3788 Bind(&if_hascachedindex); 3792 Bind(&if_hascachedindex);
3789 var_index->Bind(BitFieldDecodeWord<Name::ArrayIndexValueBits>(hash)); 3793 var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash));
3790 Goto(if_keyisindex); 3794 Goto(if_keyisindex);
3791 } 3795 }
3792 3796
3793 template <typename Dictionary> 3797 template <typename Dictionary>
3794 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) { 3798 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) {
3795 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize)); 3799 Node* entry_index = IntPtrMul(entry, IntPtrConstant(Dictionary::kEntrySize));
3796 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex + 3800 return IntPtrAdd(entry_index, IntPtrConstant(Dictionary::kElementsStartIndex +
3797 field_index)); 3801 field_index));
3798 } 3802 }
3799 3803
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
3992 GotoIf(Int32LessThanOrEqual(instance_type, 3996 GotoIf(Int32LessThanOrEqual(instance_type,
3993 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), 3997 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
3994 &if_objectisspecial); 3998 &if_objectisspecial);
3995 3999
3996 Node* bit_field = LoadMapBitField(map); 4000 Node* bit_field = LoadMapBitField(map);
3997 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor | 4001 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor |
3998 1 << Map::kIsAccessCheckNeeded); 4002 1 << Map::kIsAccessCheckNeeded);
3999 CSA_ASSERT(Word32Equal(Word32And(bit_field, mask), Int32Constant(0))); 4003 CSA_ASSERT(Word32Equal(Word32And(bit_field, mask), Int32Constant(0)));
4000 4004
4001 Node* bit_field3 = LoadMapBitField3(map); 4005 Node* bit_field3 = LoadMapBitField3(map);
4002 Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3);
4003 Label if_isfastmap(this), if_isslowmap(this); 4006 Label if_isfastmap(this), if_isslowmap(this);
4004 Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, &if_isslowmap); 4007 Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap,
4008 &if_isfastmap);
4005 Bind(&if_isfastmap); 4009 Bind(&if_isfastmap);
4006 { 4010 {
4007 Comment("DescriptorArrayLookup"); 4011 Comment("DescriptorArrayLookup");
4008 Node* nof = BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bit_field3); 4012 Node* nof =
4013 DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bit_field3);
4009 // Bail out to the runtime for large numbers of own descriptors. The stub 4014 // Bail out to the runtime for large numbers of own descriptors. The stub
4010 // only does linear search, which becomes too expensive in that case. 4015 // only does linear search, which becomes too expensive in that case.
4011 { 4016 {
4012 static const int32_t kMaxLinear = 210; 4017 static const int32_t kMaxLinear = 210;
4013 GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), if_bailout); 4018 GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), if_bailout);
4014 } 4019 }
4015 Node* descriptors = LoadMapDescriptors(map); 4020 Node* descriptors = LoadMapDescriptors(map);
4016 var_meta_storage->Bind(descriptors); 4021 var_meta_storage->Bind(descriptors);
4017 4022
4018 DescriptorLookupLinear(unique_name, descriptors, nof, if_found_fast, 4023 DescriptorLookupLinear(unique_name, descriptors, nof, if_found_fast,
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4086 (DescriptorArray::kDescriptorDetails - DescriptorArray::kDescriptorKey) * 4091 (DescriptorArray::kDescriptorDetails - DescriptorArray::kDescriptorKey) *
4087 kPointerSize; 4092 kPointerSize;
4088 const int name_to_value_offset = 4093 const int name_to_value_offset =
4089 (DescriptorArray::kDescriptorValue - DescriptorArray::kDescriptorKey) * 4094 (DescriptorArray::kDescriptorValue - DescriptorArray::kDescriptorKey) *
4090 kPointerSize; 4095 kPointerSize;
4091 4096
4092 Node* details = LoadAndUntagToWord32FixedArrayElement(descriptors, name_index, 4097 Node* details = LoadAndUntagToWord32FixedArrayElement(descriptors, name_index,
4093 name_to_details_offset); 4098 name_to_details_offset);
4094 var_details->Bind(details); 4099 var_details->Bind(details);
4095 4100
4096 Node* location = BitFieldDecode<PropertyDetails::LocationField>(details); 4101 Node* location = DecodeWord32<PropertyDetails::LocationField>(details);
4097 4102
4098 Label if_in_field(this), if_in_descriptor(this), done(this); 4103 Label if_in_field(this), if_in_descriptor(this), done(this);
4099 Branch(Word32Equal(location, Int32Constant(kField)), &if_in_field, 4104 Branch(Word32Equal(location, Int32Constant(kField)), &if_in_field,
4100 &if_in_descriptor); 4105 &if_in_descriptor);
4101 Bind(&if_in_field); 4106 Bind(&if_in_field);
4102 { 4107 {
4103 Node* field_index = 4108 Node* field_index =
4104 BitFieldDecodeWord<PropertyDetails::FieldIndexField>(details); 4109 DecodeWordFromWord32<PropertyDetails::FieldIndexField>(details);
4105 Node* representation = 4110 Node* representation =
4106 BitFieldDecode<PropertyDetails::RepresentationField>(details); 4111 DecodeWord32<PropertyDetails::RepresentationField>(details);
4107 4112
4108 Node* inobject_properties = LoadMapInobjectProperties(map); 4113 Node* inobject_properties = LoadMapInobjectProperties(map);
4109 4114
4110 Label if_inobject(this), if_backing_store(this); 4115 Label if_inobject(this), if_backing_store(this);
4111 Variable var_double_value(this, MachineRepresentation::kFloat64); 4116 Variable var_double_value(this, MachineRepresentation::kFloat64);
4112 Label rebox_double(this, &var_double_value); 4117 Label rebox_double(this, &var_double_value);
4113 Branch(UintPtrLessThan(field_index, inobject_properties), &if_inobject, 4118 Branch(UintPtrLessThan(field_index, inobject_properties), &if_inobject,
4114 &if_backing_store); 4119 &if_backing_store);
4115 Bind(&if_inobject); 4120 Bind(&if_inobject);
4116 { 4121 {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
4235 // |value| is the property backing store's contents, which is either a value 4240 // |value| is the property backing store's contents, which is either a value
4236 // or an accessor pair, as specified by |details|. 4241 // or an accessor pair, as specified by |details|.
4237 // Returns either the original value, or the result of the getter call. 4242 // Returns either the original value, or the result of the getter call.
4238 Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details, 4243 Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details,
4239 Node* context, Node* receiver, 4244 Node* context, Node* receiver,
4240 Label* if_bailout) { 4245 Label* if_bailout) {
4241 Variable var_value(this, MachineRepresentation::kTagged); 4246 Variable var_value(this, MachineRepresentation::kTagged);
4242 var_value.Bind(value); 4247 var_value.Bind(value);
4243 Label done(this); 4248 Label done(this);
4244 4249
4245 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details); 4250 Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
4246 GotoIf(Word32Equal(kind, Int32Constant(kData)), &done); 4251 GotoIf(Word32Equal(kind, Int32Constant(kData)), &done);
4247 4252
4248 // Accessor case. 4253 // Accessor case.
4249 { 4254 {
4250 Node* accessor_pair = value; 4255 Node* accessor_pair = value;
4251 GotoIf(Word32Equal(LoadInstanceType(accessor_pair), 4256 GotoIf(Word32Equal(LoadInstanceType(accessor_pair),
4252 Int32Constant(ACCESSOR_INFO_TYPE)), 4257 Int32Constant(ACCESSOR_INFO_TYPE)),
4253 if_bailout); 4258 if_bailout);
4254 AssertInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE); 4259 AssertInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE);
4255 Node* getter = LoadObjectField(accessor_pair, AccessorPair::kGetterOffset); 4260 Node* getter = LoadObjectField(accessor_pair, AccessorPair::kGetterOffset);
(...skipping 876 matching lines...) Expand 10 before | Expand all | Expand 10 after
5132 Variable var_entry(this, MachineType::PointerRepresentation()); 5137 Variable var_entry(this, MachineType::PointerRepresentation());
5133 Label if_found(this); 5138 Label if_found(this);
5134 NumberDictionaryLookup<SeededNumberDictionary>( 5139 NumberDictionaryLookup<SeededNumberDictionary>(
5135 elements, intptr_index, &if_found, &var_entry, if_hole); 5140 elements, intptr_index, &if_found, &var_entry, if_hole);
5136 Bind(&if_found); 5141 Bind(&if_found);
5137 // Check that the value is a data property. 5142 // Check that the value is a data property.
5138 Node* details_index = EntryToIndex<SeededNumberDictionary>( 5143 Node* details_index = EntryToIndex<SeededNumberDictionary>(
5139 var_entry.value(), SeededNumberDictionary::kEntryDetailsIndex); 5144 var_entry.value(), SeededNumberDictionary::kEntryDetailsIndex);
5140 Node* details = SmiToWord32( 5145 Node* details = SmiToWord32(
5141 LoadFixedArrayElement(elements, details_index, 0, INTPTR_PARAMETERS)); 5146 LoadFixedArrayElement(elements, details_index, 0, INTPTR_PARAMETERS));
5142 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details); 5147 Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
5143 // TODO(jkummerow): Support accessors without missing? 5148 // TODO(jkummerow): Support accessors without missing?
5144 GotoUnless(Word32Equal(kind, Int32Constant(kData)), miss); 5149 GotoUnless(Word32Equal(kind, Int32Constant(kData)), miss);
5145 // Finally, load the value. 5150 // Finally, load the value.
5146 Node* value_index = EntryToIndex<SeededNumberDictionary>( 5151 Node* value_index = EntryToIndex<SeededNumberDictionary>(
5147 var_entry.value(), SeededNumberDictionary::kEntryValueIndex); 5152 var_entry.value(), SeededNumberDictionary::kEntryValueIndex);
5148 Return(LoadFixedArrayElement(elements, value_index, 0, INTPTR_PARAMETERS)); 5153 Return(LoadFixedArrayElement(elements, value_index, 0, INTPTR_PARAMETERS));
5149 } 5154 }
5150 5155
5151 Bind(&if_typed_array); 5156 Bind(&if_typed_array);
5152 { 5157 {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
5262 5267
5263 // |handler| is a Smi, encoding what to do. See SmiHandler methods 5268 // |handler| is a Smi, encoding what to do. See SmiHandler methods
5264 // for the encoding format. 5269 // for the encoding format.
5265 Bind(&if_smi_handler); 5270 Bind(&if_smi_handler);
5266 { 5271 {
5267 Variable var_double_value(this, MachineRepresentation::kFloat64); 5272 Variable var_double_value(this, MachineRepresentation::kFloat64);
5268 Label rebox_double(this, &var_double_value); 5273 Label rebox_double(this, &var_double_value);
5269 5274
5270 Node* holder = var_holder.value(); 5275 Node* holder = var_holder.value();
5271 Node* handler_word = SmiUntag(var_smi_handler.value()); 5276 Node* handler_word = SmiUntag(var_smi_handler.value());
5272 Node* handler_type = 5277 Node* handler_type = DecodeWord<LoadHandlerTypeBits>(handler_word);
5273 WordAnd(handler_word, IntPtrConstant(LoadHandlerTypeBits::kMask));
5274 if (support_elements == kSupportElements) { 5278 if (support_elements == kSupportElements) {
5275 Label property(this); 5279 Label property(this);
5276 GotoUnless( 5280 GotoUnless(
5277 WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForElements)), 5281 WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForElements)),
5278 &property); 5282 &property);
5279 5283
5280 Comment("element_load"); 5284 Comment("element_load");
5281 Node* intptr_index = TryToIntptr(p->name, miss); 5285 Node* intptr_index = TryToIntptr(p->name, miss);
5282 Node* elements = LoadElements(holder); 5286 Node* elements = LoadElements(holder);
5283 Node* is_jsarray = 5287 Node* is_jsarray_condition = IsSetWord<KeyedLoadIsJsArray>(handler_word);
5284 WordAnd(handler_word, IntPtrConstant(KeyedLoadIsJsArray::kMask)); 5288 Node* elements_kind = DecodeWord<KeyedLoadElementsKind>(handler_word);
5285 Node* is_jsarray_condition = WordNotEqual(is_jsarray, IntPtrConstant(0));
5286 Node* elements_kind = BitFieldDecode<KeyedLoadElementsKind>(handler_word);
5287 Label if_hole(this), unimplemented_elements_kind(this); 5289 Label if_hole(this), unimplemented_elements_kind(this);
5288 Label* out_of_bounds = miss; 5290 Label* out_of_bounds = miss;
5289 EmitElementLoad(holder, elements, elements_kind, intptr_index, 5291 EmitElementLoad(holder, elements, elements_kind, intptr_index,
5290 is_jsarray_condition, &if_hole, &rebox_double, 5292 is_jsarray_condition, &if_hole, &rebox_double,
5291 &var_double_value, &unimplemented_elements_kind, 5293 &var_double_value, &unimplemented_elements_kind,
5292 out_of_bounds, miss); 5294 out_of_bounds, miss);
5293 5295
5294 Bind(&unimplemented_elements_kind); 5296 Bind(&unimplemented_elements_kind);
5295 { 5297 {
5296 // Smi handlers should only be installed for supported elements kinds. 5298 // Smi handlers should only be installed for supported elements kinds.
5297 // Crash if we get here. 5299 // Crash if we get here.
5298 DebugBreak(); 5300 DebugBreak();
5299 Goto(miss); 5301 Goto(miss);
5300 } 5302 }
5301 5303
5302 Bind(&if_hole); 5304 Bind(&if_hole);
5303 { 5305 {
5304 Comment("convert hole"); 5306 Comment("convert hole");
5305 Node* convert_hole = 5307 GotoUnless(IsSetWord<KeyedLoadConvertHole>(handler_word), miss);
5306 WordAnd(handler_word, IntPtrConstant(KeyedLoadConvertHole::kMask));
5307 GotoIf(WordEqual(convert_hole, IntPtrConstant(0)), miss);
5308 Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); 5308 Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex);
5309 DCHECK(isolate()->heap()->array_protector()->IsPropertyCell()); 5309 DCHECK(isolate()->heap()->array_protector()->IsPropertyCell());
5310 GotoUnless( 5310 GotoUnless(
5311 WordEqual( 5311 WordEqual(
5312 LoadObjectField(protector_cell, PropertyCell::kValueOffset), 5312 LoadObjectField(protector_cell, PropertyCell::kValueOffset),
5313 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))), 5313 SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))),
5314 miss); 5314 miss);
5315 Return(UndefinedConstant()); 5315 Return(UndefinedConstant());
5316 } 5316 }
5317 5317
5318 Bind(&property); 5318 Bind(&property);
5319 Comment("property_load"); 5319 Comment("property_load");
5320 } 5320 }
5321 5321
5322 Label constant(this), field(this); 5322 Label constant(this), field(this);
5323 Branch(WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForFields)), 5323 Branch(WordEqual(handler_type, IntPtrConstant(kLoadICHandlerForFields)),
5324 &field, &constant); 5324 &field, &constant);
5325 5325
5326 Bind(&field); 5326 Bind(&field);
5327 { 5327 {
5328 Comment("field_load"); 5328 Comment("field_load");
5329 Label inobject_double(this), out_of_object(this), 5329 Node* offset = DecodeWord<FieldOffsetOffset>(handler_word);
5330 out_of_object_double(this);
5331 Node* inobject_bit =
5332 WordAnd(handler_word, IntPtrConstant(FieldOffsetIsInobject::kMask));
5333 Node* double_bit =
5334 WordAnd(handler_word, IntPtrConstant(FieldOffsetIsDouble::kMask));
5335 Node* offset =
5336 WordSar(handler_word, IntPtrConstant(FieldOffsetOffset::kShift));
5337 5330
5338 GotoIf(WordEqual(inobject_bit, IntPtrConstant(0)), &out_of_object); 5331 Label inobject(this), out_of_object(this);
5332 Branch(IsSetWord<FieldOffsetIsInobject>(handler_word), &inobject,
5333 &out_of_object);
5339 5334
5340 GotoUnless(WordEqual(double_bit, IntPtrConstant(0)), &inobject_double); 5335 Bind(&inobject);
5341 Return(LoadObjectField(holder, offset)); 5336 {
5337 Label is_double(this);
5338 GotoIf(IsSetWord<FieldOffsetIsDouble>(handler_word), &is_double);
5339 Return(LoadObjectField(holder, offset));
5342 5340
5343 Bind(&inobject_double); 5341 Bind(&is_double);
5344 if (FLAG_unbox_double_fields) { 5342 if (FLAG_unbox_double_fields) {
5345 var_double_value.Bind( 5343 var_double_value.Bind(
5346 LoadObjectField(holder, offset, MachineType::Float64())); 5344 LoadObjectField(holder, offset, MachineType::Float64()));
5347 } else { 5345 } else {
5348 Node* mutable_heap_number = LoadObjectField(holder, offset); 5346 Node* mutable_heap_number = LoadObjectField(holder, offset);
5349 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); 5347 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number));
5348 }
5349 Goto(&rebox_double);
5350 } 5350 }
5351 Goto(&rebox_double);
5352 5351
5353 Bind(&out_of_object); 5352 Bind(&out_of_object);
5354 Node* properties = LoadProperties(holder); 5353 {
5355 Node* value = LoadObjectField(properties, offset); 5354 Label is_double(this);
5356 GotoUnless(WordEqual(double_bit, IntPtrConstant(0)), 5355 Node* properties = LoadProperties(holder);
5357 &out_of_object_double); 5356 Node* value = LoadObjectField(properties, offset);
5358 Return(value); 5357 GotoIf(IsSetWord<FieldOffsetIsDouble>(handler_word), &is_double);
5358 Return(value);
5359 5359
5360 Bind(&out_of_object_double); 5360 Bind(&is_double);
5361 var_double_value.Bind(LoadHeapNumberValue(value)); 5361 var_double_value.Bind(LoadHeapNumberValue(value));
5362 Goto(&rebox_double); 5362 Goto(&rebox_double);
5363 }
5363 5364
5364 Bind(&rebox_double); 5365 Bind(&rebox_double);
5365 Return(AllocateHeapNumberWithValue(var_double_value.value())); 5366 Return(AllocateHeapNumberWithValue(var_double_value.value()));
5366 } 5367 }
5367 5368
5368 Bind(&constant); 5369 Bind(&constant);
5369 { 5370 {
5370 Comment("constant_load"); 5371 Comment("constant_load");
5371 Node* descriptors = LoadMapDescriptors(LoadMap(holder)); 5372 Node* descriptors = LoadMapDescriptors(LoadMap(holder));
5372 Node* descriptor = WordSar( 5373 Node* descriptor = DecodeWord<ValueIndexInDescriptorArray>(handler_word);
5373 handler_word, IntPtrConstant(ValueIndexInDescriptorArray::kShift));
5374 #if defined(DEBUG) 5374 #if defined(DEBUG)
5375 Assert(UintPtrLessThan(descriptor, 5375 CSA_ASSERT(UintPtrLessThan(
5376 LoadAndUntagFixedArrayBaseLength(descriptors))); 5376 descriptor, LoadAndUntagFixedArrayBaseLength(descriptors)));
5377 #endif 5377 #endif
5378 Return( 5378 Return(
5379 LoadFixedArrayElement(descriptors, descriptor, 0, INTPTR_PARAMETERS)); 5379 LoadFixedArrayElement(descriptors, descriptor, 0, INTPTR_PARAMETERS));
5380 } 5380 }
5381 } 5381 }
5382 5382
5383 Bind(&try_proto_cell_handler); 5383 Bind(&try_proto_cell_handler);
5384 { 5384 {
5385 GotoIf(WordNotEqual(LoadMap(handler), LoadRoot(Heap::kTuple3MapRootIndex)), 5385 GotoIf(WordNotEqual(LoadMap(handler), LoadRoot(Heap::kTuple3MapRootIndex)),
5386 &call_handler); 5386 &call_handler);
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
5600 // Try looking up the property on the receiver; if unsuccessful, look 5600 // Try looking up the property on the receiver; if unsuccessful, look
5601 // for a handler in the stub cache. 5601 // for a handler in the stub cache.
5602 Comment("DescriptorArray lookup"); 5602 Comment("DescriptorArray lookup");
5603 5603
5604 // Skip linear search if there are too many descriptors. 5604 // Skip linear search if there are too many descriptors.
5605 // TODO(jkummerow): Consider implementing binary search. 5605 // TODO(jkummerow): Consider implementing binary search.
5606 // See also TryLookupProperty() which has the same limitation. 5606 // See also TryLookupProperty() which has the same limitation.
5607 const int32_t kMaxLinear = 210; 5607 const int32_t kMaxLinear = 210;
5608 Label stub_cache(this); 5608 Label stub_cache(this);
5609 Node* bitfield3 = LoadMapBitField3(receiver_map); 5609 Node* bitfield3 = LoadMapBitField3(receiver_map);
5610 Node* nof = BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bitfield3); 5610 Node* nof =
5611 DecodeWordFromWord32<Map::NumberOfOwnDescriptorsBits>(bitfield3);
5611 GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), &stub_cache); 5612 GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), &stub_cache);
5612 Node* descriptors = LoadMapDescriptors(receiver_map); 5613 Node* descriptors = LoadMapDescriptors(receiver_map);
5613 Variable var_name_index(this, MachineType::PointerRepresentation()); 5614 Variable var_name_index(this, MachineType::PointerRepresentation());
5614 Label if_descriptor_found(this); 5615 Label if_descriptor_found(this);
5615 DescriptorLookupLinear(key, descriptors, nof, &if_descriptor_found, 5616 DescriptorLookupLinear(key, descriptors, nof, &if_descriptor_found,
5616 &var_name_index, &stub_cache); 5617 &var_name_index, &stub_cache);
5617 5618
5618 Bind(&if_descriptor_found); 5619 Bind(&if_descriptor_found);
5619 { 5620 {
5620 LoadPropertyFromFastObject(receiver, receiver_map, descriptors, 5621 LoadPropertyFromFastObject(receiver, receiver_map, descriptors,
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
6407 Bind(&no_memento_found); 6408 Bind(&no_memento_found);
6408 Comment("] TrapAllocationMemento"); 6409 Comment("] TrapAllocationMemento");
6409 } 6410 }
6410 6411
6411 Node* CodeStubAssembler::PageFromAddress(Node* address) { 6412 Node* CodeStubAssembler::PageFromAddress(Node* address) {
6412 return WordAnd(address, IntPtrConstant(~Page::kPageAlignmentMask)); 6413 return WordAnd(address, IntPtrConstant(~Page::kPageAlignmentMask));
6413 } 6414 }
6414 6415
6415 Node* CodeStubAssembler::EnumLength(Node* map) { 6416 Node* CodeStubAssembler::EnumLength(Node* map) {
6416 Node* bitfield_3 = LoadMapBitField3(map); 6417 Node* bitfield_3 = LoadMapBitField3(map);
6417 Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3); 6418 Node* enum_length = DecodeWordFromWord32<Map::EnumLengthBits>(bitfield_3);
6418 return SmiTag(enum_length); 6419 return SmiTag(enum_length);
6419 } 6420 }
6420 6421
6421 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache, 6422 void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache,
6422 Label* use_runtime) { 6423 Label* use_runtime) {
6423 Variable current_js_object(this, MachineRepresentation::kTagged); 6424 Variable current_js_object(this, MachineRepresentation::kTagged);
6424 current_js_object.Bind(receiver); 6425 current_js_object.Bind(receiver);
6425 6426
6426 Variable current_map(this, MachineRepresentation::kTagged); 6427 Variable current_map(this, MachineRepresentation::kTagged);
6427 current_map.Bind(LoadMap(current_js_object.value())); 6428 current_map.Bind(LoadMap(current_js_object.value()));
(...skipping 1879 matching lines...) Expand 10 before | Expand all | Expand 10 after
8307 Node* buffer_bit_field = LoadObjectField( 8308 Node* buffer_bit_field = LoadObjectField(
8308 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32()); 8309 buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32());
8309 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask); 8310 Node* was_neutered_mask = Int32Constant(JSArrayBuffer::WasNeutered::kMask);
8310 8311
8311 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask), 8312 return Word32NotEqual(Word32And(buffer_bit_field, was_neutered_mask),
8312 Int32Constant(0)); 8313 Int32Constant(0));
8313 } 8314 }
8314 8315
8315 } // namespace internal 8316 } // namespace internal
8316 } // namespace v8 8317 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/interpreter/interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698