Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 | 4 |
| 5 #include "src/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
| 6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
| 7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
| 8 #include "src/frames.h" | 8 #include "src/frames.h" |
| 9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
| 10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
| (...skipping 2855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2866 // See Dictionary::NextProbe(). | 2866 // See Dictionary::NextProbe(). |
| 2867 count = IntPtrAdd(count, IntPtrConstant(1)); | 2867 count = IntPtrAdd(count, IntPtrConstant(1)); |
| 2868 entry = WordAnd(IntPtrAdd(entry, count), mask); | 2868 entry = WordAnd(IntPtrAdd(entry, count), mask); |
| 2869 | 2869 |
| 2870 var_count.Bind(count); | 2870 var_count.Bind(count); |
| 2871 var_entry->Bind(entry); | 2871 var_entry->Bind(entry); |
| 2872 Goto(&loop); | 2872 Goto(&loop); |
| 2873 } | 2873 } |
| 2874 } | 2874 } |
| 2875 | 2875 |
| 2876 void CodeStubAssembler::DescriptorLookupLinear(Node* unique_name, | |
|
Jakob Kummerow
2016/09/22 22:28:55
This is pulled out from below, unchanged.
| |
| 2877 Node* descriptors, Node* nof, | |
| 2878 Label* if_found, | |
| 2879 Variable* var_name_index, | |
| 2880 Label* if_not_found) { | |
| 2881 Variable var_descriptor(this, MachineType::PointerRepresentation()); | |
| 2882 Label loop(this, &var_descriptor); | |
| 2883 var_descriptor.Bind(IntPtrConstant(0)); | |
| 2884 Goto(&loop); | |
| 2885 | |
| 2886 Bind(&loop); | |
| 2887 { | |
| 2888 Node* index = var_descriptor.value(); | |
| 2889 Node* name_offset = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); | |
| 2890 Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize); | |
| 2891 GotoIf(WordEqual(index, nof), if_not_found); | |
| 2892 Node* name_index = IntPtrAdd(name_offset, IntPtrMul(index, factor)); | |
| 2893 Node* candidate_name = | |
| 2894 LoadFixedArrayElement(descriptors, name_index, 0, INTPTR_PARAMETERS); | |
| 2895 var_name_index->Bind(name_index); | |
| 2896 GotoIf(WordEqual(candidate_name, unique_name), if_found); | |
| 2897 var_descriptor.Bind(IntPtrAdd(index, IntPtrConstant(1))); | |
| 2898 Goto(&loop); | |
| 2899 } | |
| 2900 } | |
| 2901 | |
| 2876 void CodeStubAssembler::TryLookupProperty( | 2902 void CodeStubAssembler::TryLookupProperty( |
| 2877 Node* object, Node* map, Node* instance_type, Node* unique_name, | 2903 Node* object, Node* map, Node* instance_type, Node* unique_name, |
| 2878 Label* if_found_fast, Label* if_found_dict, Label* if_found_global, | 2904 Label* if_found_fast, Label* if_found_dict, Label* if_found_global, |
| 2879 Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found, | 2905 Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found, |
| 2880 Label* if_bailout) { | 2906 Label* if_bailout) { |
| 2881 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); | 2907 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep()); |
| 2882 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); | 2908 DCHECK_EQ(MachineType::PointerRepresentation(), var_name_index->rep()); |
| 2883 | 2909 |
| 2884 Label if_objectisspecial(this); | 2910 Label if_objectisspecial(this); |
| 2885 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); | 2911 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 2902 Node* nof = BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bit_field3); | 2928 Node* nof = BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bit_field3); |
| 2903 // Bail out to the runtime for large numbers of own descriptors. The stub | 2929 // Bail out to the runtime for large numbers of own descriptors. The stub |
| 2904 // only does linear search, which becomes too expensive in that case. | 2930 // only does linear search, which becomes too expensive in that case. |
| 2905 { | 2931 { |
| 2906 static const int32_t kMaxLinear = 210; | 2932 static const int32_t kMaxLinear = 210; |
| 2907 GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), if_bailout); | 2933 GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), if_bailout); |
| 2908 } | 2934 } |
| 2909 Node* descriptors = LoadMapDescriptors(map); | 2935 Node* descriptors = LoadMapDescriptors(map); |
| 2910 var_meta_storage->Bind(descriptors); | 2936 var_meta_storage->Bind(descriptors); |
| 2911 | 2937 |
| 2912 Variable var_descriptor(this, MachineType::PointerRepresentation()); | 2938 DescriptorLookupLinear(unique_name, descriptors, nof, if_found_fast, |
| 2913 Label loop(this, &var_descriptor); | 2939 var_name_index, if_not_found); |
| 2914 var_descriptor.Bind(IntPtrConstant(0)); | |
| 2915 Goto(&loop); | |
| 2916 Bind(&loop); | |
| 2917 { | |
| 2918 Node* index = var_descriptor.value(); | |
| 2919 Node* name_offset = IntPtrConstant(DescriptorArray::ToKeyIndex(0)); | |
| 2920 Node* factor = IntPtrConstant(DescriptorArray::kDescriptorSize); | |
| 2921 GotoIf(WordEqual(index, nof), if_not_found); | |
| 2922 | |
| 2923 Node* name_index = IntPtrAdd(name_offset, IntPtrMul(index, factor)); | |
| 2924 Node* name = | |
| 2925 LoadFixedArrayElement(descriptors, name_index, 0, INTPTR_PARAMETERS); | |
| 2926 | |
| 2927 var_name_index->Bind(name_index); | |
| 2928 GotoIf(WordEqual(name, unique_name), if_found_fast); | |
| 2929 | |
| 2930 var_descriptor.Bind(IntPtrAdd(index, IntPtrConstant(1))); | |
| 2931 Goto(&loop); | |
| 2932 } | |
| 2933 } | 2940 } |
| 2934 Bind(&if_isslowmap); | 2941 Bind(&if_isslowmap); |
| 2935 { | 2942 { |
| 2936 Node* dictionary = LoadProperties(object); | 2943 Node* dictionary = LoadProperties(object); |
| 2937 var_meta_storage->Bind(dictionary); | 2944 var_meta_storage->Bind(dictionary); |
| 2938 | 2945 |
| 2939 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict, | 2946 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict, |
| 2940 var_name_index, if_not_found); | 2947 var_name_index, if_not_found); |
| 2941 } | 2948 } |
| 2942 Bind(&if_objectisspecial); | 2949 Bind(&if_objectisspecial); |
| (...skipping 1377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4320 Bind(&miss); | 4327 Bind(&miss); |
| 4321 { | 4328 { |
| 4322 Comment("KeyedLoadIC_miss"); | 4329 Comment("KeyedLoadIC_miss"); |
| 4323 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, | 4330 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, |
| 4324 p->name, p->slot, p->vector); | 4331 p->name, p->slot, p->vector); |
| 4325 } | 4332 } |
| 4326 } | 4333 } |
| 4327 | 4334 |
| 4328 void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { | 4335 void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| 4329 Variable var_index(this, MachineType::PointerRepresentation()); | 4336 Variable var_index(this, MachineType::PointerRepresentation()); |
| 4337 Variable var_details(this, MachineRepresentation::kWord32); | |
| 4338 Variable var_value(this, MachineRepresentation::kTagged); | |
| 4330 Label if_index(this), if_unique_name(this), if_element_hole(this), | 4339 Label if_index(this), if_unique_name(this), if_element_hole(this), |
| 4331 if_oob(this), slow(this), stub_cache_miss(this), | 4340 if_oob(this), slow(this), stub_cache_miss(this), |
| 4332 if_property_dictionary(this); | 4341 if_property_dictionary(this), if_found_on_receiver(this); |
| 4333 | 4342 |
| 4334 Node* receiver = p->receiver; | 4343 Node* receiver = p->receiver; |
| 4335 GotoIf(WordIsSmi(receiver), &slow); | 4344 GotoIf(WordIsSmi(receiver), &slow); |
| 4336 Node* receiver_map = LoadMap(receiver); | 4345 Node* receiver_map = LoadMap(receiver); |
| 4337 Node* instance_type = LoadMapInstanceType(receiver_map); | 4346 Node* instance_type = LoadMapInstanceType(receiver_map); |
| 4338 // Receivers requiring non-standard element accesses (interceptors, access | 4347 // Receivers requiring non-standard element accesses (interceptors, access |
| 4339 // checks, strings and string wrappers, proxies) are handled in the runtime. | 4348 // checks, strings and string wrappers, proxies) are handled in the runtime. |
| 4340 GotoIf(Int32LessThanOrEqual(instance_type, | 4349 GotoIf(Int32LessThanOrEqual(instance_type, |
| 4341 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), | 4350 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), |
| 4342 &slow); | 4351 &slow); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4391 Node* properties = nullptr; | 4400 Node* properties = nullptr; |
| 4392 Bind(&if_unique_name); | 4401 Bind(&if_unique_name); |
| 4393 { | 4402 { |
| 4394 Comment("key is unique name"); | 4403 Comment("key is unique name"); |
| 4395 // Check if the receiver has fast or slow properties. | 4404 // Check if the receiver has fast or slow properties. |
| 4396 properties = LoadProperties(receiver); | 4405 properties = LoadProperties(receiver); |
| 4397 Node* properties_map = LoadMap(properties); | 4406 Node* properties_map = LoadMap(properties); |
| 4398 GotoIf(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), | 4407 GotoIf(WordEqual(properties_map, LoadRoot(Heap::kHashTableMapRootIndex)), |
| 4399 &if_property_dictionary); | 4408 &if_property_dictionary); |
| 4400 | 4409 |
| 4401 Comment("stub cache probe for fast property load"); | 4410 // Try looking up the property on the receiver; if unsuccessful, look |
|
Jakob Kummerow
2016/09/22 22:28:55
All this has moved into the "Bind(&stub_cache)" bl
| |
| 4402 Variable var_handler(this, MachineRepresentation::kTagged); | 4411 // for a handler in the stub cache. |
| 4403 Label found_handler(this, &var_handler), stub_cache_miss(this); | 4412 Comment("DescriptorArray lookup"); |
| 4404 TryProbeStubCache(isolate()->load_stub_cache(), receiver, key, | |
| 4405 &found_handler, &var_handler, &stub_cache_miss); | |
| 4406 Bind(&found_handler); | |
| 4407 { HandleLoadICHandlerCase(p, var_handler.value(), &slow); } | |
| 4408 | 4413 |
| 4409 Bind(&stub_cache_miss); | 4414 // Skip linear search if there are too many descriptors. |
| 4415 // TODO(jkummerow): Consider implementing binary search. | |
| 4416 // See also TryLookupProperty() which has the same limitation. | |
| 4417 const int32_t kMaxLinear = 210; | |
| 4418 Label stub_cache(this); | |
| 4419 Node* bitfield3 = LoadMapBitField3(receiver_map); | |
| 4420 Node* nof = BitFieldDecodeWord<Map::NumberOfOwnDescriptorsBits>(bitfield3); | |
| 4421 GotoIf(UintPtrGreaterThan(nof, IntPtrConstant(kMaxLinear)), &stub_cache); | |
| 4422 Node* descriptors = LoadMapDescriptors(receiver_map); | |
| 4423 Variable var_name_index(this, MachineType::PointerRepresentation()); | |
| 4424 Label if_descriptor_found(this); | |
| 4425 DescriptorLookupLinear(key, descriptors, nof, &if_descriptor_found, | |
| 4426 &var_name_index, &slow); | |
| 4427 | |
| 4428 Bind(&if_descriptor_found); | |
| 4410 { | 4429 { |
| 4411 Comment("KeyedLoadGeneric_miss"); | 4430 LoadPropertyFromFastObject(receiver, receiver_map, descriptors, |
| 4412 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, | 4431 var_name_index.value(), &var_details, |
| 4413 p->name, p->slot, p->vector); | 4432 &var_value); |
| 4433 Goto(&if_found_on_receiver); | |
| 4434 } | |
| 4435 | |
| 4436 Bind(&stub_cache); | |
| 4437 { | |
| 4438 Comment("stub cache probe for fast property load"); | |
| 4439 Variable var_handler(this, MachineRepresentation::kTagged); | |
| 4440 Label found_handler(this, &var_handler), stub_cache_miss(this); | |
| 4441 TryProbeStubCache(isolate()->load_stub_cache(), receiver, key, | |
| 4442 &found_handler, &var_handler, &stub_cache_miss); | |
| 4443 Bind(&found_handler); | |
| 4444 { HandleLoadICHandlerCase(p, var_handler.value(), &slow); } | |
| 4445 | |
| 4446 Bind(&stub_cache_miss); | |
| 4447 { | |
| 4448 Comment("KeyedLoadGeneric_miss"); | |
| 4449 TailCallRuntime(Runtime::kKeyedLoadIC_Miss, p->context, p->receiver, | |
| 4450 p->name, p->slot, p->vector); | |
| 4451 } | |
| 4414 } | 4452 } |
| 4415 } | 4453 } |
| 4416 | 4454 |
| 4417 Bind(&if_property_dictionary); | 4455 Bind(&if_property_dictionary); |
| 4418 { | 4456 { |
| 4419 Comment("dictionary property load"); | 4457 Comment("dictionary property load"); |
| 4420 // We checked for LAST_CUSTOM_ELEMENTS_RECEIVER before, which rules out | 4458 // We checked for LAST_CUSTOM_ELEMENTS_RECEIVER before, which rules out |
| 4421 // seeing global objects here (which would need special handling). | 4459 // seeing global objects here (which would need special handling). |
| 4422 | 4460 |
| 4423 Variable var_name_index(this, MachineType::PointerRepresentation()); | 4461 Variable var_name_index(this, MachineType::PointerRepresentation()); |
| 4424 Label dictionary_found(this, &var_name_index); | 4462 Label dictionary_found(this, &var_name_index); |
| 4425 NameDictionaryLookup<NameDictionary>(properties, key, &dictionary_found, | 4463 NameDictionaryLookup<NameDictionary>(properties, key, &dictionary_found, |
| 4426 &var_name_index, &slow); | 4464 &var_name_index, &slow); |
| 4427 Bind(&dictionary_found); | 4465 Bind(&dictionary_found); |
| 4428 { | 4466 { |
| 4429 Variable var_details(this, MachineRepresentation::kWord32); | |
| 4430 Variable var_value(this, MachineRepresentation::kTagged); | |
| 4431 LoadPropertyFromNameDictionary(properties, var_name_index.value(), | 4467 LoadPropertyFromNameDictionary(properties, var_name_index.value(), |
| 4432 &var_details, &var_value); | 4468 &var_details, &var_value); |
| 4433 Node* kind = | 4469 Goto(&if_found_on_receiver); |
| 4434 BitFieldDecode<PropertyDetails::KindField>(var_details.value()); | |
| 4435 // TODO(jkummerow): Support accessors without missing? | |
| 4436 GotoUnless(Word32Equal(kind, Int32Constant(kData)), &slow); | |
| 4437 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), | |
| 4438 1); | |
| 4439 Return(var_value.value()); | |
| 4440 } | 4470 } |
| 4441 } | 4471 } |
| 4442 | 4472 |
| 4473 Bind(&if_found_on_receiver); | |
| 4474 { | |
| 4475 Node* kind = | |
| 4476 BitFieldDecode<PropertyDetails::KindField>(var_details.value()); | |
| 4477 // TODO(jkummerow): Support accessors without missing? | |
| 4478 GotoUnless(Word32Equal(kind, Int32Constant(kData)), &slow); | |
| 4479 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); | |
| 4480 Return(var_value.value()); | |
| 4481 } | |
| 4482 | |
| 4443 Bind(&slow); | 4483 Bind(&slow); |
| 4444 { | 4484 { |
| 4445 Comment("KeyedLoadGeneric_slow"); | 4485 Comment("KeyedLoadGeneric_slow"); |
| 4446 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); | 4486 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); |
| 4447 // TODO(jkummerow): Should we use the GetProperty TF stub instead? | 4487 // TODO(jkummerow): Should we use the GetProperty TF stub instead? |
| 4448 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, | 4488 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, |
| 4449 p->name); | 4489 p->name); |
| 4450 } | 4490 } |
| 4451 } | 4491 } |
| 4452 | 4492 |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5174 Heap::kTheHoleValueRootIndex); | 5214 Heap::kTheHoleValueRootIndex); |
| 5175 | 5215 |
| 5176 // Store the WeakCell in the feedback vector. | 5216 // Store the WeakCell in the feedback vector. |
| 5177 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, | 5217 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, |
| 5178 CodeStubAssembler::SMI_PARAMETERS); | 5218 CodeStubAssembler::SMI_PARAMETERS); |
| 5179 return cell; | 5219 return cell; |
| 5180 } | 5220 } |
| 5181 | 5221 |
| 5182 } // namespace internal | 5222 } // namespace internal |
| 5183 } // namespace v8 | 5223 } // namespace v8 |
| OLD | NEW |