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

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

Issue 878263002: Add MEGAMORPHIC state support for KeyedLoadIC (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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') | src/ic/x64/ic-x64.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 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 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 CompareICStub stub(target->stub_key(), isolate); 599 CompareICStub stub(target->stub_key(), isolate);
600 // Only clear CompareICs that can retain objects. 600 // Only clear CompareICs that can retain objects.
601 if (stub.state() != CompareICState::KNOWN_OBJECT) return; 601 if (stub.state() != CompareICState::KNOWN_OBJECT) return;
602 SetTargetAtAddress(address, GetRawUninitialized(isolate, stub.op()), 602 SetTargetAtAddress(address, GetRawUninitialized(isolate, stub.op()),
603 constant_pool); 603 constant_pool);
604 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); 604 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
605 } 605 }
606 606
607 607
608 // static 608 // static
609 Handle<Code> KeyedLoadIC::generic_stub(Isolate* isolate) { 609 Handle<Code> KeyedLoadIC::megamorphic_stub(Isolate* isolate) {
610 if (FLAG_compiled_keyed_generic_loads) { 610 if (FLAG_compiled_keyed_generic_loads) {
611 // TODO(dcarney): what do to here?
Jakob Kummerow 2015/01/29 15:58:55 Put in a TODO comment into the hydrogen-generated
611 return KeyedLoadGenericStub(isolate).GetCode(); 612 return KeyedLoadGenericStub(isolate).GetCode();
612 } else { 613 } else {
613 return isolate->builtins()->KeyedLoadIC_Generic(); 614 return isolate->builtins()->KeyedLoadIC_Megamorphic();
614 } 615 }
615 } 616 }
616 617
617 618
618 static bool MigrateDeprecated(Handle<Object> object) { 619 static bool MigrateDeprecated(Handle<Object> object) {
619 if (!object->IsJSObject()) return false; 620 if (!object->IsJSObject()) return false;
620 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 621 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
621 if (!receiver->map()->is_deprecated()) return false; 622 if (!receiver->map()->is_deprecated()) return false;
622 JSObject::MigrateInstance(Handle<JSObject>::cast(object)); 623 JSObject::MigrateInstance(Handle<JSObject>::cast(object));
623 return true; 624 return true;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 700
700 // Check if the name is trivially convertible to an index and get 701 // Check if the name is trivially convertible to an index and get
701 // the element or char if so. 702 // the element or char if so.
702 uint32_t index; 703 uint32_t index;
703 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { 704 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
704 // Rewrite to the generic keyed load stub. 705 // Rewrite to the generic keyed load stub.
705 if (FLAG_use_ic) { 706 if (FLAG_use_ic) {
706 if (UseVector()) { 707 if (UseVector()) {
707 ConfigureVectorState(GENERIC); 708 ConfigureVectorState(GENERIC);
708 } else { 709 } else {
709 set_target(*KeyedLoadIC::generic_stub(isolate())); 710 set_target(*KeyedLoadIC::megamorphic_stub(isolate()));
710 } 711 }
711 TRACE_IC("LoadIC", name); 712 TRACE_IC("LoadIC", name);
712 TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index"); 713 TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index");
713 } 714 }
714 Handle<Object> result; 715 Handle<Object> result;
715 ASSIGN_RETURN_ON_EXCEPTION( 716 ASSIGN_RETURN_ON_EXCEPTION(
716 isolate(), result, 717 isolate(), result,
717 Runtime::GetElementOrCharAt(isolate(), object, index), Object); 718 Runtime::GetElementOrCharAt(isolate(), object, index), Object);
718 return result; 719 return result;
719 } 720 }
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 vector_set_ = true; 965 vector_set_ = true;
965 } else { 966 } else {
966 target_set_ = true; 967 target_set_ = true;
967 } 968 }
968 break; 969 break;
969 case DEBUG_STUB: 970 case DEBUG_STUB:
970 break; 971 break;
971 case DEFAULT: 972 case DEFAULT:
972 UNREACHABLE(); 973 UNREACHABLE();
973 break; 974 break;
974 case GENERIC: 975 case GENERIC:
Jakob Kummerow 2015/01/29 15:58:55 nit: just combine it with the DEFAULT case.
975 // The generic keyed store stub re-uses store handlers, which can miss. 976 UNREACHABLE();
976 // That's ok, no reason to do anything.
977 DCHECK(target()->kind() == Code::KEYED_STORE_IC);
978 break; 977 break;
979 } 978 }
980 } 979 }
981 980
982 981
983 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, 982 Handle<Code> LoadIC::initialize_stub(Isolate* isolate,
984 ExtraICState extra_state) { 983 ExtraICState extra_state) {
985 if (FLAG_vector_ics) { 984 if (FLAG_vector_ics) {
986 return LoadICTrampolineStub(isolate, LoadICState(extra_state)).GetCode(); 985 return LoadICTrampolineStub(isolate, LoadICState(extra_state)).GetCode();
987 } 986 }
(...skipping 27 matching lines...) Expand all
1015 return initialize_stub(isolate); 1014 return initialize_stub(isolate);
1016 } 1015 }
1017 1016
1018 1017
1019 Handle<Code> LoadIC::megamorphic_stub() { 1018 Handle<Code> LoadIC::megamorphic_stub() {
1020 if (kind() == Code::LOAD_IC) { 1019 if (kind() == Code::LOAD_IC) {
1021 MegamorphicLoadStub stub(isolate(), LoadICState(extra_ic_state())); 1020 MegamorphicLoadStub stub(isolate(), LoadICState(extra_ic_state()));
1022 return stub.GetCode(); 1021 return stub.GetCode();
1023 } else { 1022 } else {
1024 DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); 1023 DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
1025 return KeyedLoadIC::generic_stub(isolate()); 1024 return KeyedLoadIC::megamorphic_stub(isolate());
1026 } 1025 }
1027 } 1026 }
1028 1027
1029 1028
1030 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate, 1029 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
1031 ExtraICState extra_state) { 1030 ExtraICState extra_state) {
1032 DCHECK(!FLAG_vector_ics); 1031 DCHECK(!FLAG_vector_ics);
1033 return PropertyICCompiler::ComputeLoad(isolate, PREMONOMORPHIC, extra_state); 1032 return PropertyICCompiler::ComputeLoad(isolate, PREMONOMORPHIC, extra_state);
1034 } 1033 }
1035 1034
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1084 } else { 1083 } else {
1085 code = ComputeHandler(lookup); 1084 code = ComputeHandler(lookup);
1086 } 1085 }
1087 1086
1088 PatchCache(lookup->name(), code); 1087 PatchCache(lookup->name(), code);
1089 TRACE_IC("LoadIC", lookup->name()); 1088 TRACE_IC("LoadIC", lookup->name());
1090 } 1089 }
1091 1090
1092 1091
1093 void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) { 1092 void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) {
1094 // Megamorphic state isn't implemented for keyed loads currently.
1095 if (kind() == Code::KEYED_LOAD_IC) return;
1096 Map* map = *TypeToMap(type, isolate()); 1093 Map* map = *TypeToMap(type, isolate());
1097 isolate()->stub_cache()->Set(name, map, code); 1094 isolate()->stub_cache()->Set(name, map, code);
1098 } 1095 }
1099 1096
1100 1097
1101 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { 1098 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) {
1102 bool receiver_is_holder = 1099 bool receiver_is_holder =
1103 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); 1100 lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>());
1104 CacheHolderFlag flag; 1101 CacheHolderFlag flag;
1105 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( 1102 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder(
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 } 1360 }
1364 1361
1365 DCHECK(state() != GENERIC); 1362 DCHECK(state() != GENERIC);
1366 1363
1367 // Determine the list of receiver maps that this call site has seen, 1364 // Determine the list of receiver maps that this call site has seen,
1368 // adding the map that was just encountered. 1365 // adding the map that was just encountered.
1369 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { 1366 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
1370 // If the miss wasn't due to an unseen map, a polymorphic stub 1367 // If the miss wasn't due to an unseen map, a polymorphic stub
1371 // won't help, use the generic stub. 1368 // won't help, use the generic stub.
1372 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice"); 1369 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice");
1373 return generic_stub(); 1370 return megamorphic_stub(isolate());
1374 } 1371 }
1375 1372
1376 // If the maximum number of receiver maps has been exceeded, use the generic 1373 // If the maximum number of receiver maps has been exceeded, use the generic
1377 // version of the IC. 1374 // version of the IC.
1378 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1375 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1379 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded"); 1376 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded");
1380 return generic_stub(); 1377 return megamorphic_stub(isolate());
1381 } 1378 }
1382 1379
1383 if (FLAG_vector_ics) { 1380 if (FLAG_vector_ics) {
1384 CodeHandleList handlers(target_receiver_maps.length()); 1381 CodeHandleList handlers(target_receiver_maps.length());
1385 ElementHandlerCompiler compiler(isolate()); 1382 ElementHandlerCompiler compiler(isolate());
1386 compiler.CompileElementHandlers(&target_receiver_maps, &handlers); 1383 compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
1387 TypeHandleList types(target_receiver_maps.length()); 1384 TypeHandleList types(target_receiver_maps.length());
1388 for (int i = 0; i < target_receiver_maps.length(); i++) { 1385 for (int i = 0; i < target_receiver_maps.length(); i++) {
1389 types.Add(HeapType::Class(target_receiver_maps.at(i), isolate())); 1386 types.Add(HeapType::Class(target_receiver_maps.at(i), isolate()));
1390 } 1387 }
1391 ConfigureVectorState(Handle<Name>::null(), &types, &handlers); 1388 ConfigureVectorState(Handle<Name>::null(), &types, &handlers);
1392 return null_handle; 1389 return null_handle;
1393 } 1390 }
1394 1391
1395 return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps); 1392 return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps);
1396 } 1393 }
1397 1394
1398 1395
1399 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, 1396 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
1400 Handle<Object> key) { 1397 Handle<Object> key) {
1401 if (MigrateDeprecated(object)) { 1398 if (MigrateDeprecated(object)) {
1402 Handle<Object> result; 1399 Handle<Object> result;
1403 ASSIGN_RETURN_ON_EXCEPTION( 1400 ASSIGN_RETURN_ON_EXCEPTION(
1404 isolate(), result, Runtime::GetObjectProperty(isolate(), object, key), 1401 isolate(), result, Runtime::GetObjectProperty(isolate(), object, key),
1405 Object); 1402 Object);
1406 return result; 1403 return result;
1407 } 1404 }
1408 1405
1409 Handle<Object> load_handle; 1406 Handle<Object> load_handle;
1410 Handle<Code> stub = generic_stub(); 1407 Handle<Code> stub = megamorphic_stub(isolate());
1411 1408
1412 // Check for non-string values that can be converted into an 1409 // Check for non-string values that can be converted into an
1413 // internalized string directly or is representable as a smi. 1410 // internalized string directly or is representable as a smi.
1414 key = TryConvertKey(key, isolate()); 1411 key = TryConvertKey(key, isolate());
1415 1412
1416 if (key->IsInternalizedString() || key->IsSymbol()) { 1413 if (key->IsInternalizedString() || key->IsSymbol()) {
1417 ASSIGN_RETURN_ON_EXCEPTION(isolate(), load_handle, 1414 ASSIGN_RETURN_ON_EXCEPTION(isolate(), load_handle,
1418 LoadIC::Load(object, Handle<Name>::cast(key)), 1415 LoadIC::Load(object, Handle<Name>::cast(key)),
1419 Object); 1416 Object);
1420 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { 1417 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
1421 if (object->IsJSObject() || (object->IsString() && key->IsNumber())) { 1418 if (object->IsJSObject() || (object->IsString() && key->IsNumber())) {
1422 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object); 1419 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
1423 if (object->IsString() || !Object::ToSmi(isolate(), key).is_null()) { 1420 if (object->IsString() || !Object::ToSmi(isolate(), key).is_null()) {
1424 stub = LoadElementStub(receiver); 1421 stub = LoadElementStub(receiver);
1425 } 1422 }
1426 } 1423 }
1427 } 1424 }
1428 1425
1429 if (!UseVector()) { 1426 if (!UseVector()) {
1430 if (!is_target_set()) { 1427 if (!is_target_set()) {
1431 Code* generic = *generic_stub(); 1428 Code* generic = *megamorphic_stub(isolate());
1432 if (*stub == generic) { 1429 if (*stub == generic) {
1433 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic"); 1430 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
1434 } 1431 }
1435 1432
1436 set_target(*stub); 1433 set_target(*stub);
1437 TRACE_IC("LoadIC", key); 1434 TRACE_IC("LoadIC", key);
1438 } 1435 }
1439 } else { 1436 } else {
1440 if (!is_vector_set() || stub.is_null()) { 1437 if (!is_vector_set() || stub.is_null()) {
1441 Code* generic = *generic_stub(); 1438 Code* generic = *megamorphic_stub(isolate());
1442 if (!stub.is_null() && *stub == generic) { 1439 if (!stub.is_null() && *stub == generic) {
1443 ConfigureVectorState(GENERIC); 1440 ConfigureVectorState(GENERIC);
Jakob Kummerow 2015/01/29 15:58:55 In a follow-up CL, please port the renaming change
1444 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic"); 1441 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
1445 } 1442 }
1446 1443
1447 TRACE_IC("LoadIC", key); 1444 TRACE_IC("LoadIC", key);
1448 } 1445 }
1449 } 1446 }
1450 1447
1451 if (!load_handle.is_null()) return load_handle; 1448 if (!load_handle.is_null()) return load_handle;
1452 Handle<Object> result; 1449 Handle<Object> result;
1453 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, 1450 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
(...skipping 1550 matching lines...) Expand 10 before | Expand all | Expand 10 after
3004 static const Address IC_utilities[] = { 3001 static const Address IC_utilities[] = {
3005 #define ADDR(name) FUNCTION_ADDR(name), 3002 #define ADDR(name) FUNCTION_ADDR(name),
3006 IC_UTIL_LIST(ADDR) NULL 3003 IC_UTIL_LIST(ADDR) NULL
3007 #undef ADDR 3004 #undef ADDR
3008 }; 3005 };
3009 3006
3010 3007
3011 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 3008 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
3012 } 3009 }
3013 } // namespace v8::internal 3010 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698