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

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

Issue 2358373002: [stubs] KeyedLoadIC_Megamorphic: inline fast-property lookups (Closed)
Patch Set: rebase Created 4 years, 3 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/ic/ic.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 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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/ic/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698