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

Side by Side Diff: src/ic/ic.cc

Issue 839893005: Vector-based KeyedLoadIC MISS logic needs improvement. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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/ic/ic.h ('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 // 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 } 135 }
136 136
137 137
138 #define TRACE_IC(type, name) TraceIC(type, name) 138 #define TRACE_IC(type, name) TraceIC(type, name)
139 139
140 140
141 IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus, 141 IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus,
142 bool for_queries_only) 142 bool for_queries_only)
143 : isolate_(isolate), 143 : isolate_(isolate),
144 target_set_(false), 144 target_set_(false),
145 vector_set_(false),
145 target_maps_set_(false), 146 target_maps_set_(false),
146 nexus_(nexus) { 147 nexus_(nexus) {
147 // To improve the performance of the (much used) IC code, we unfold a few 148 // To improve the performance of the (much used) IC code, we unfold a few
148 // levels of the stack frame iteration code. This yields a ~35% speedup when 149 // levels of the stack frame iteration code. This yields a ~35% speedup when
149 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. 150 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
150 const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); 151 const Address entry = Isolate::c_entry_fp(isolate->thread_local_top());
151 Address constant_pool = NULL; 152 Address constant_pool = NULL;
152 if (FLAG_enable_ool_constant_pool) { 153 if (FLAG_enable_ool_constant_pool) {
153 constant_pool = 154 constant_pool =
154 Memory::Address_at(entry + ExitFrameConstants::kConstantPoolOffset); 155 Memory::Address_at(entry + ExitFrameConstants::kConstantPoolOffset);
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 nexus->ConfigureGeneric(); 630 nexus->ConfigureGeneric();
630 } else if (new_state == PREMONOMORPHIC) { 631 } else if (new_state == PREMONOMORPHIC) {
631 nexus->ConfigurePremonomorphic(); 632 nexus->ConfigurePremonomorphic();
632 } else { 633 } else {
633 UNREACHABLE(); 634 UNREACHABLE();
634 } 635 }
635 } else { 636 } else {
636 UNREACHABLE(); 637 UNREACHABLE();
637 } 638 }
638 639
640 vector_set_ = true;
639 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), 641 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
640 new_state); 642 new_state);
641 } 643 }
642 644
643 645
644 void IC::ConfigureVectorState(Handle<Name> name, Handle<HeapType> type, 646 void IC::ConfigureVectorState(Handle<Name> name, Handle<HeapType> type,
645 Handle<Code> handler) { 647 Handle<Code> handler) {
646 DCHECK(UseVector()); 648 DCHECK(UseVector());
647 if (kind() == Code::LOAD_IC) { 649 if (kind() == Code::LOAD_IC) {
648 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 650 LoadICNexus* nexus = casted_nexus<LoadICNexus>();
649 nexus->ConfigureMonomorphic(type, handler); 651 nexus->ConfigureMonomorphic(type, handler);
650 } else { 652 } else {
651 DCHECK(kind() == Code::KEYED_LOAD_IC); 653 DCHECK(kind() == Code::KEYED_LOAD_IC);
652 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 654 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
653 nexus->ConfigureMonomorphic(name, type, handler); 655 nexus->ConfigureMonomorphic(name, type, handler);
654 } 656 }
655 657
658 vector_set_ = true;
656 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), 659 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
657 MONOMORPHIC); 660 MONOMORPHIC);
658 } 661 }
659 662
660 663
661 void IC::ConfigureVectorState(Handle<Name> name, TypeHandleList* types, 664 void IC::ConfigureVectorState(Handle<Name> name, TypeHandleList* types,
662 CodeHandleList* handlers) { 665 CodeHandleList* handlers) {
663 DCHECK(UseVector()); 666 DCHECK(UseVector());
664 if (kind() == Code::LOAD_IC) { 667 if (kind() == Code::LOAD_IC) {
665 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); 668 LoadICNexus* nexus = casted_nexus<LoadICNexus>();
666 nexus->ConfigurePolymorphic(types, handlers); 669 nexus->ConfigurePolymorphic(types, handlers);
667 } else { 670 } else {
668 DCHECK(kind() == Code::KEYED_LOAD_IC); 671 DCHECK(kind() == Code::KEYED_LOAD_IC);
669 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); 672 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
670 nexus->ConfigurePolymorphic(name, types, handlers); 673 nexus->ConfigurePolymorphic(name, types, handlers);
671 } 674 }
672 675
676 vector_set_ = true;
673 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), 677 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
674 POLYMORPHIC); 678 POLYMORPHIC);
675 } 679 }
676 680
677 681
678 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { 682 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
679 // If the object is undefined or null it's illegal to try to get any 683 // If the object is undefined or null it's illegal to try to get any
680 // of its properties; throw a TypeError in that case. 684 // of its properties; throw a TypeError in that case.
681 if (object->IsUndefined() || object->IsNull()) { 685 if (object->IsUndefined() || object->IsNull()) {
682 return TypeError("non_object_property_load", object, name); 686 return TypeError("non_object_property_load", object, name);
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 if (UseVector()) { 942 if (UseVector()) {
939 ConfigureVectorState(kind() == Code::KEYED_LOAD_IC ? GENERIC 943 ConfigureVectorState(kind() == Code::KEYED_LOAD_IC ? GENERIC
940 : MEGAMORPHIC); 944 : MEGAMORPHIC);
941 } else { 945 } else {
942 set_target(*megamorphic_stub()); 946 set_target(*megamorphic_stub());
943 } 947 }
944 // Fall through. 948 // Fall through.
945 case MEGAMORPHIC: 949 case MEGAMORPHIC:
946 UpdateMegamorphicCache(*receiver_type(), *name, *code); 950 UpdateMegamorphicCache(*receiver_type(), *name, *code);
947 // Indicate that we've handled this case. 951 // Indicate that we've handled this case.
948 target_set_ = true; 952 if (UseVector()) {
953 vector_set_ = true;
954 } else {
955 target_set_ = true;
956 }
949 break; 957 break;
950 case DEBUG_STUB: 958 case DEBUG_STUB:
951 break; 959 break;
952 case DEFAULT: 960 case DEFAULT:
953 UNREACHABLE(); 961 UNREACHABLE();
954 break; 962 break;
955 case GENERIC: 963 case GENERIC:
956 // The generic keyed store stub re-uses store handlers, which can miss. 964 // The generic keyed store stub re-uses store handlers, which can miss.
957 // That's ok, no reason to do anything. 965 // That's ok, no reason to do anything.
958 DCHECK(target()->kind() == Code::KEYED_STORE_IC); 966 DCHECK(target()->kind() == Code::KEYED_STORE_IC);
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 } 1350 }
1343 1351
1344 DCHECK(state() != GENERIC); 1352 DCHECK(state() != GENERIC);
1345 1353
1346 // Determine the list of receiver maps that this call site has seen, 1354 // Determine the list of receiver maps that this call site has seen,
1347 // adding the map that was just encountered. 1355 // adding the map that was just encountered.
1348 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { 1356 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
1349 // If the miss wasn't due to an unseen map, a polymorphic stub 1357 // If the miss wasn't due to an unseen map, a polymorphic stub
1350 // won't help, use the generic stub. 1358 // won't help, use the generic stub.
1351 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice"); 1359 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice");
1352 if (FLAG_vector_ics) {
1353 ConfigureVectorState(GENERIC);
1354 return null_handle;
1355 }
1356 return generic_stub(); 1360 return generic_stub();
1357 } 1361 }
1358 1362
1359 // If the maximum number of receiver maps has been exceeded, use the generic 1363 // If the maximum number of receiver maps has been exceeded, use the generic
1360 // version of the IC. 1364 // version of the IC.
1361 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1365 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1362 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded"); 1366 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded");
1363 if (FLAG_vector_ics) {
1364 ConfigureVectorState(GENERIC);
1365 return null_handle;
1366 }
1367 return generic_stub(); 1367 return generic_stub();
1368 } 1368 }
1369 1369
1370 if (FLAG_vector_ics) { 1370 if (FLAG_vector_ics) {
1371 CodeHandleList handlers(target_receiver_maps.length()); 1371 CodeHandleList handlers(target_receiver_maps.length());
1372 ElementHandlerCompiler compiler(isolate()); 1372 ElementHandlerCompiler compiler(isolate());
1373 compiler.CompileElementHandlers(&target_receiver_maps, &handlers); 1373 compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
1374 TypeHandleList types(target_receiver_maps.length()); 1374 TypeHandleList types(target_receiver_maps.length());
1375 for (int i = 0; i < target_receiver_maps.length(); i++) { 1375 for (int i = 0; i < target_receiver_maps.length(); i++) {
1376 types.Add(HeapType::Class(target_receiver_maps.at(i), isolate())); 1376 types.Add(HeapType::Class(target_receiver_maps.at(i), isolate()));
(...skipping 29 matching lines...) Expand all
1406 Object); 1406 Object);
1407 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { 1407 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
1408 if (object->IsJSObject() || (object->IsString() && key->IsNumber())) { 1408 if (object->IsJSObject() || (object->IsString() && key->IsNumber())) {
1409 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object); 1409 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
1410 if (object->IsString() || !Object::ToSmi(isolate(), key).is_null()) { 1410 if (object->IsString() || !Object::ToSmi(isolate(), key).is_null()) {
1411 stub = LoadElementStub(receiver); 1411 stub = LoadElementStub(receiver);
1412 } 1412 }
1413 } 1413 }
1414 } 1414 }
1415 1415
1416 if (!is_target_set()) { 1416 if (!UseVector()) {
1417 if (!FLAG_vector_ics) { 1417 if (!is_target_set()) {
1418 Code* generic = *generic_stub(); 1418 Code* generic = *generic_stub();
1419 if (*stub == generic) { 1419 if (*stub == generic) {
1420 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic"); 1420 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
1421 } 1421 }
1422 1422
1423 set_target(*stub); 1423 set_target(*stub);
1424 TRACE_IC("LoadIC", key);
1424 } 1425 }
1425 TRACE_IC("LoadIC", key); 1426 } else {
1427 if (!is_vector_set() || stub.is_null()) {
1428 Code* generic = *generic_stub();
1429 if (!stub.is_null() && *stub == generic) {
1430 ConfigureVectorState(GENERIC);
1431 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
1432 }
1433
1434 TRACE_IC("LoadIC", key);
1435 }
1426 } 1436 }
1427 1437
1428 if (!load_handle.is_null()) return load_handle; 1438 if (!load_handle.is_null()) return load_handle;
1429 Handle<Object> result; 1439 Handle<Object> result;
1430 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, 1440 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
1431 Runtime::GetObjectProperty(isolate(), object, key), 1441 Runtime::GetObjectProperty(isolate(), object, key),
1432 Object); 1442 Object);
1433 return result; 1443 return result;
1434 } 1444 }
1435 1445
(...skipping 1531 matching lines...) Expand 10 before | Expand all | Expand 10 after
2967 static const Address IC_utilities[] = { 2977 static const Address IC_utilities[] = {
2968 #define ADDR(name) FUNCTION_ADDR(name), 2978 #define ADDR(name) FUNCTION_ADDR(name),
2969 IC_UTIL_LIST(ADDR) NULL 2979 IC_UTIL_LIST(ADDR) NULL
2970 #undef ADDR 2980 #undef ADDR
2971 }; 2981 };
2972 2982
2973 2983
2974 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 2984 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
2975 } 2985 }
2976 } // namespace v8::internal 2986 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698