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

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

Issue 1129853002: Removing FLAG_vector_ics. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Comment response. Created 5 years, 7 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/ic-compiler.h » ('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 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 488
489 void IC::Clear(Isolate* isolate, Address address, 489 void IC::Clear(Isolate* isolate, Address address,
490 ConstantPoolArray* constant_pool) { 490 ConstantPoolArray* constant_pool) {
491 Code* target = GetTargetAtAddress(address, constant_pool); 491 Code* target = GetTargetAtAddress(address, constant_pool);
492 492
493 // Don't clear debug break inline cache as it will remove the break point. 493 // Don't clear debug break inline cache as it will remove the break point.
494 if (target->is_debug_stub()) return; 494 if (target->is_debug_stub()) return;
495 495
496 switch (target->kind()) { 496 switch (target->kind()) {
497 case Code::LOAD_IC: 497 case Code::LOAD_IC:
498 if (FLAG_vector_ics) return;
499 return LoadIC::Clear(isolate, address, target, constant_pool);
500 case Code::KEYED_LOAD_IC: 498 case Code::KEYED_LOAD_IC:
501 if (FLAG_vector_ics) return; 499 return;
502 return KeyedLoadIC::Clear(isolate, address, target, constant_pool);
503 case Code::STORE_IC: 500 case Code::STORE_IC:
504 return StoreIC::Clear(isolate, address, target, constant_pool); 501 return StoreIC::Clear(isolate, address, target, constant_pool);
505 case Code::KEYED_STORE_IC: 502 case Code::KEYED_STORE_IC:
506 return KeyedStoreIC::Clear(isolate, address, target, constant_pool); 503 return KeyedStoreIC::Clear(isolate, address, target, constant_pool);
507 case Code::COMPARE_IC: 504 case Code::COMPARE_IC:
508 return CompareIC::Clear(isolate, address, target, constant_pool); 505 return CompareIC::Clear(isolate, address, target, constant_pool);
509 case Code::COMPARE_NIL_IC: 506 case Code::COMPARE_NIL_IC:
510 return CompareNilIC::Clear(address, target, constant_pool); 507 return CompareNilIC::Clear(address, target, constant_pool);
511 case Code::CALL_IC: // CallICs are vector-based and cleared differently. 508 case Code::CALL_IC: // CallICs are vector-based and cleared differently.
512 case Code::BINARY_OP_IC: 509 case Code::BINARY_OP_IC:
513 case Code::TO_BOOLEAN_IC: 510 case Code::TO_BOOLEAN_IC:
514 // Clearing these is tricky and does not 511 // Clearing these is tricky and does not
515 // make any performance difference. 512 // make any performance difference.
516 return; 513 return;
517 default: 514 default:
518 UNREACHABLE(); 515 UNREACHABLE();
519 } 516 }
520 } 517 }
521 518
522 519
523 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target,
524 ConstantPoolArray* constant_pool) {
525 DCHECK(!FLAG_vector_ics);
526 if (IsCleared(target)) return;
527
528 // Make sure to also clear the map used in inline fast cases. If we
529 // do not clear these maps, cached code can keep objects alive
530 // through the embedded maps.
531 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool);
532 }
533
534
535 void KeyedLoadIC::Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus) { 520 void KeyedLoadIC::Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus) {
536 if (IsCleared(nexus)) return; 521 if (IsCleared(nexus)) return;
537 // Make sure to also clear the map used in inline fast cases. If we 522 // Make sure to also clear the map used in inline fast cases. If we
538 // do not clear these maps, cached code can keep objects alive 523 // do not clear these maps, cached code can keep objects alive
539 // through the embedded maps. 524 // through the embedded maps.
540 State state = nexus->StateFromFeedback(); 525 State state = nexus->StateFromFeedback();
541 nexus->ConfigurePremonomorphic(); 526 nexus->ConfigurePremonomorphic();
542 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC); 527 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC);
543 } 528 }
544 529
545 530
546 void CallIC::Clear(Isolate* isolate, Code* host, CallICNexus* nexus) { 531 void CallIC::Clear(Isolate* isolate, Code* host, CallICNexus* nexus) {
547 // Determine our state. 532 // Determine our state.
548 Object* feedback = nexus->vector()->Get(nexus->slot()); 533 Object* feedback = nexus->vector()->Get(nexus->slot());
549 State state = nexus->StateFromFeedback(); 534 State state = nexus->StateFromFeedback();
550 535
551 if (state != UNINITIALIZED && !feedback->IsAllocationSite()) { 536 if (state != UNINITIALIZED && !feedback->IsAllocationSite()) {
552 nexus->ConfigureUninitialized(); 537 nexus->ConfigureUninitialized();
553 // The change in state must be processed. 538 // The change in state must be processed.
554 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, UNINITIALIZED); 539 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, UNINITIALIZED);
555 } 540 }
556 } 541 }
557 542
558 543
559 void LoadIC::Clear(Isolate* isolate, Address address, Code* target,
560 ConstantPoolArray* constant_pool) {
561 DCHECK(!FLAG_vector_ics);
562 if (IsCleared(target)) return;
563 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC,
564 target->extra_ic_state());
565 SetTargetAtAddress(address, code, constant_pool);
566 }
567
568
569 void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) { 544 void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) {
570 if (IsCleared(nexus)) return; 545 if (IsCleared(nexus)) return;
571 State state = nexus->StateFromFeedback(); 546 State state = nexus->StateFromFeedback();
572 nexus->ConfigurePremonomorphic(); 547 nexus->ConfigurePremonomorphic();
573 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC); 548 OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC);
574 } 549 }
575 550
576 551
577 void StoreIC::Clear(Isolate* isolate, Address address, Code* target, 552 void StoreIC::Clear(Isolate* isolate, Address address, Code* target,
578 ConstantPoolArray* constant_pool) { 553 ConstantPoolArray* constant_pool) {
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 case DEFAULT: 909 case DEFAULT:
935 case GENERIC: 910 case GENERIC:
936 UNREACHABLE(); 911 UNREACHABLE();
937 break; 912 break;
938 } 913 }
939 } 914 }
940 915
941 916
942 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, 917 Handle<Code> LoadIC::initialize_stub(Isolate* isolate,
943 ExtraICState extra_state) { 918 ExtraICState extra_state) {
944 if (FLAG_vector_ics) { 919 return LoadICTrampolineStub(isolate, LoadICState(extra_state)).GetCode();
945 return LoadICTrampolineStub(isolate, LoadICState(extra_state)).GetCode();
946 }
947
948 return PropertyICCompiler::ComputeLoad(isolate, UNINITIALIZED, extra_state);
949 }
950
951
952 Handle<Code> LoadIC::load_global(Isolate* isolate, Handle<GlobalObject> global,
953 Handle<String> name) {
954 // This special IC doesn't work with vector ics.
955 DCHECK(!FLAG_vector_ics);
956
957 Handle<ScriptContextTable> script_contexts(
958 global->native_context()->script_context_table());
959
960 ScriptContextTable::LookupResult lookup_result;
961 if (ScriptContextTable::Lookup(script_contexts, name, &lookup_result)) {
962 return initialize_stub(isolate, LoadICState(CONTEXTUAL).GetExtraICState());
963 }
964
965 Handle<Map> global_map(global->map());
966 Handle<Code> handler = PropertyHandlerCompiler::Find(
967 name, global_map, Code::LOAD_IC, kCacheOnReceiver, Code::NORMAL);
968 if (handler.is_null()) {
969 LookupIterator it(global, name);
970 if (!it.IsFound() || !it.GetHolder<JSObject>().is_identical_to(global) ||
971 it.state() != LookupIterator::DATA) {
972 return initialize_stub(isolate,
973 LoadICState(CONTEXTUAL).GetExtraICState());
974 }
975 NamedLoadHandlerCompiler compiler(isolate, global_map, global,
976 kCacheOnReceiver);
977 Handle<PropertyCell> cell = it.GetPropertyCell();
978 handler = compiler.CompileLoadGlobal(cell, name, it.IsConfigurable());
979 Map::UpdateCodeCache(global_map, name, handler);
980 }
981 return PropertyICCompiler::ComputeMonomorphic(
982 Code::LOAD_IC, name, handle(global->map()), handler,
983 LoadICState(CONTEXTUAL).GetExtraICState());
984 } 920 }
985 921
986 922
987 Handle<Code> LoadIC::initialize_stub_in_optimized_code( 923 Handle<Code> LoadIC::initialize_stub_in_optimized_code(
988 Isolate* isolate, ExtraICState extra_state, State initialization_state) { 924 Isolate* isolate, ExtraICState extra_state, State initialization_state) {
989 if (FLAG_vector_ics) { 925 return VectorRawLoadStub(isolate, LoadICState(extra_state)).GetCode();
990 return VectorRawLoadStub(isolate, LoadICState(extra_state)).GetCode();
991 }
992 return PropertyICCompiler::ComputeLoad(isolate, initialization_state,
993 extra_state);
994 } 926 }
995 927
996 928
997 Handle<Code> KeyedLoadIC::initialize_stub(Isolate* isolate) { 929 Handle<Code> KeyedLoadIC::initialize_stub(Isolate* isolate) {
998 if (FLAG_vector_ics) { 930 return KeyedLoadICTrampolineStub(isolate).GetCode();
999 return KeyedLoadICTrampolineStub(isolate).GetCode();
1000 }
1001
1002 return isolate->builtins()->KeyedLoadIC_Initialize();
1003 } 931 }
1004 932
1005 933
1006 Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code( 934 Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code(
1007 Isolate* isolate, State initialization_state) { 935 Isolate* isolate, State initialization_state) {
1008 if (FLAG_vector_ics && initialization_state != MEGAMORPHIC) { 936 if (initialization_state != MEGAMORPHIC) {
1009 return VectorRawKeyedLoadStub(isolate).GetCode(); 937 return VectorRawKeyedLoadStub(isolate).GetCode();
1010 } 938 }
1011 switch (initialization_state) { 939 switch (initialization_state) {
1012 case UNINITIALIZED: 940 case UNINITIALIZED:
1013 return isolate->builtins()->KeyedLoadIC_Initialize(); 941 return isolate->builtins()->KeyedLoadIC_Initialize();
1014 case PREMONOMORPHIC:
1015 return isolate->builtins()->KeyedLoadIC_PreMonomorphic();
1016 case MEGAMORPHIC: 942 case MEGAMORPHIC:
1017 return isolate->builtins()->KeyedLoadIC_Megamorphic(); 943 return isolate->builtins()->KeyedLoadIC_Megamorphic();
1018 default: 944 default:
1019 UNREACHABLE(); 945 UNREACHABLE();
1020 } 946 }
1021 return Handle<Code>(); 947 return Handle<Code>();
1022 } 948 }
1023 949
1024 950
1025 Handle<Code> KeyedStoreIC::initialize_stub(Isolate* isolate, 951 Handle<Code> KeyedStoreIC::initialize_stub(Isolate* isolate,
(...skipping 13 matching lines...) Expand all
1039 ? isolate->builtins()->KeyedStoreIC_Megamorphic_Strict() 965 ? isolate->builtins()->KeyedStoreIC_Megamorphic_Strict()
1040 : isolate->builtins()->KeyedStoreIC_Megamorphic(); 966 : isolate->builtins()->KeyedStoreIC_Megamorphic();
1041 default: 967 default:
1042 UNREACHABLE(); 968 UNREACHABLE();
1043 } 969 }
1044 return Handle<Code>(); 970 return Handle<Code>();
1045 } 971 }
1046 972
1047 973
1048 Handle<Code> LoadIC::megamorphic_stub() { 974 Handle<Code> LoadIC::megamorphic_stub() {
1049 if (kind() == Code::LOAD_IC) { 975 DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
1050 MegamorphicLoadStub stub(isolate(), LoadICState(extra_ic_state())); 976 return KeyedLoadIC::ChooseMegamorphicStub(isolate());
1051 return stub.GetCode();
1052 } else {
1053 DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
1054 return KeyedLoadIC::ChooseMegamorphicStub(isolate());
1055 }
1056 } 977 }
1057 978
1058 979
1059 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
1060 ExtraICState extra_state) {
1061 DCHECK(!FLAG_vector_ics);
1062 return PropertyICCompiler::ComputeLoad(isolate, PREMONOMORPHIC, extra_state);
1063 }
1064
1065
1066 Handle<Code> KeyedLoadIC::pre_monomorphic_stub(Isolate* isolate) {
1067 return isolate->builtins()->KeyedLoadIC_PreMonomorphic();
1068 }
1069
1070
1071 Handle<Code> LoadIC::pre_monomorphic_stub() const {
1072 if (kind() == Code::LOAD_IC) {
1073 return LoadIC::pre_monomorphic_stub(isolate(), extra_ic_state());
1074 } else {
1075 DCHECK_EQ(Code::KEYED_LOAD_IC, kind());
1076 return KeyedLoadIC::pre_monomorphic_stub(isolate());
1077 }
1078 }
1079
1080
1081 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { 980 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) {
1082 LoadFieldStub stub(isolate(), index); 981 LoadFieldStub stub(isolate(), index);
1083 return stub.GetCode(); 982 return stub.GetCode();
1084 } 983 }
1085 984
1086 985
1087 void LoadIC::UpdateCaches(LookupIterator* lookup) { 986 void LoadIC::UpdateCaches(LookupIterator* lookup) {
1088 if (state() == UNINITIALIZED) { 987 if (state() == UNINITIALIZED) {
1089 // This is the first time we execute this inline cache. Set the target to 988 // This is the first time we execute this inline cache. Set the target to
1090 // the pre monomorphic stub to delay setting the monomorphic state. 989 // the pre monomorphic stub to delay setting the monomorphic state.
1091 if (UseVector()) { 990 ConfigureVectorState(PREMONOMORPHIC);
1092 ConfigureVectorState(PREMONOMORPHIC);
1093 } else {
1094 set_target(*pre_monomorphic_stub());
1095 }
1096 TRACE_IC("LoadIC", lookup->name()); 991 TRACE_IC("LoadIC", lookup->name());
1097 return; 992 return;
1098 } 993 }
1099 994
1100 Handle<Code> code; 995 Handle<Code> code;
1101 if (lookup->state() == LookupIterator::JSPROXY || 996 if (lookup->state() == LookupIterator::JSPROXY ||
1102 lookup->state() == LookupIterator::ACCESS_CHECK) { 997 lookup->state() == LookupIterator::ACCESS_CHECK) {
1103 code = slow_stub(); 998 code = slow_stub();
1104 } else if (!lookup->IsFound()) { 999 } else if (!lookup->IsFound()) {
1105 if (kind() == Code::LOAD_IC) { 1000 if (kind() == Code::LOAD_IC) {
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 1248
1354 1249
1355 Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) { 1250 Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
1356 Handle<Code> null_handle; 1251 Handle<Code> null_handle;
1357 Handle<Map> receiver_map(receiver->map(), isolate()); 1252 Handle<Map> receiver_map(receiver->map(), isolate());
1358 MapHandleList target_receiver_maps; 1253 MapHandleList target_receiver_maps;
1359 TargetMaps(&target_receiver_maps); 1254 TargetMaps(&target_receiver_maps);
1360 1255
1361 1256
1362 if (target_receiver_maps.length() == 0) { 1257 if (target_receiver_maps.length() == 0) {
1363 if (FLAG_vector_ics) { 1258 Handle<Code> handler =
1364 Handle<Code> handler = 1259 PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
1365 PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map); 1260 ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
1366 ConfigureVectorState(Handle<Name>::null(), receiver_map, handler); 1261 return null_handle;
1367 return null_handle;
1368 }
1369 return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
1370 } 1262 }
1371 1263
1372 // The first time a receiver is seen that is a transitioned version of the 1264 // The first time a receiver is seen that is a transitioned version of the
1373 // previous monomorphic receiver type, assume the new ElementsKind is the 1265 // previous monomorphic receiver type, assume the new ElementsKind is the
1374 // monomorphic type. This benefits global arrays that only transition 1266 // monomorphic type. This benefits global arrays that only transition
1375 // once, and all call sites accessing them are faster if they remain 1267 // once, and all call sites accessing them are faster if they remain
1376 // monomorphic. If this optimistic assumption is not true, the IC will 1268 // monomorphic. If this optimistic assumption is not true, the IC will
1377 // miss again and it will become polymorphic and support both the 1269 // miss again and it will become polymorphic and support both the
1378 // untransitioned and transitioned maps. 1270 // untransitioned and transitioned maps.
1379 if (state() == MONOMORPHIC && !receiver->IsString() && 1271 if (state() == MONOMORPHIC && !receiver->IsString() &&
1380 IsMoreGeneralElementsKindTransition( 1272 IsMoreGeneralElementsKindTransition(
1381 target_receiver_maps.at(0)->elements_kind(), 1273 target_receiver_maps.at(0)->elements_kind(),
1382 Handle<JSObject>::cast(receiver)->GetElementsKind())) { 1274 Handle<JSObject>::cast(receiver)->GetElementsKind())) {
1383 if (FLAG_vector_ics) { 1275 Handle<Code> handler =
1384 Handle<Code> handler = 1276 PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
1385 PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map); 1277 ConfigureVectorState(Handle<Name>::null(), receiver_map, handler);
1386 ConfigureVectorState(Handle<Name>::null(), receiver_map, handler); 1278 return null_handle;
1387 return null_handle;
1388 }
1389 return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
1390 } 1279 }
1391 1280
1392 DCHECK(state() != GENERIC); 1281 DCHECK(state() != GENERIC);
1393 1282
1394 // Determine the list of receiver maps that this call site has seen, 1283 // Determine the list of receiver maps that this call site has seen,
1395 // adding the map that was just encountered. 1284 // adding the map that was just encountered.
1396 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { 1285 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
1397 // If the miss wasn't due to an unseen map, a polymorphic stub 1286 // If the miss wasn't due to an unseen map, a polymorphic stub
1398 // won't help, use the generic stub. 1287 // won't help, use the generic stub.
1399 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice"); 1288 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice");
1400 return megamorphic_stub(); 1289 return megamorphic_stub();
1401 } 1290 }
1402 1291
1403 // If the maximum number of receiver maps has been exceeded, use the generic 1292 // If the maximum number of receiver maps has been exceeded, use the generic
1404 // version of the IC. 1293 // version of the IC.
1405 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1294 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1406 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded"); 1295 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded");
1407 return megamorphic_stub(); 1296 return megamorphic_stub();
1408 } 1297 }
1409 1298
1410 if (FLAG_vector_ics) { 1299 CodeHandleList handlers(target_receiver_maps.length());
1411 CodeHandleList handlers(target_receiver_maps.length()); 1300 ElementHandlerCompiler compiler(isolate());
1412 ElementHandlerCompiler compiler(isolate()); 1301 compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
1413 compiler.CompileElementHandlers(&target_receiver_maps, &handlers); 1302 ConfigureVectorState(Handle<Name>::null(), &target_receiver_maps, &handlers);
1414 ConfigureVectorState(Handle<Name>::null(), &target_receiver_maps, 1303 return null_handle;
1415 &handlers);
1416 return null_handle;
1417 }
1418
1419 return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps);
1420 } 1304 }
1421 1305
1422 1306
1423 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, 1307 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
1424 Handle<Object> key) { 1308 Handle<Object> key) {
1425 if (MigrateDeprecated(object)) { 1309 if (MigrateDeprecated(object)) {
1426 Handle<Object> result; 1310 Handle<Object> result;
1427 ASSIGN_RETURN_ON_EXCEPTION( 1311 ASSIGN_RETURN_ON_EXCEPTION(
1428 isolate(), result, Runtime::GetObjectProperty(isolate(), object, key), 1312 isolate(), result, Runtime::GetObjectProperty(isolate(), object, key),
1429 Object); 1313 Object);
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after
2362 2246
2363 2247
2364 // Used from ic-<arch>.cc. 2248 // Used from ic-<arch>.cc.
2365 RUNTIME_FUNCTION(LoadIC_Miss) { 2249 RUNTIME_FUNCTION(LoadIC_Miss) {
2366 TimerEventScope<TimerEventIcMiss> timer(isolate); 2250 TimerEventScope<TimerEventIcMiss> timer(isolate);
2367 HandleScope scope(isolate); 2251 HandleScope scope(isolate);
2368 Handle<Object> receiver = args.at<Object>(0); 2252 Handle<Object> receiver = args.at<Object>(0);
2369 Handle<Name> key = args.at<Name>(1); 2253 Handle<Name> key = args.at<Name>(1);
2370 Handle<Object> result; 2254 Handle<Object> result;
2371 2255
2372 if (FLAG_vector_ics) { 2256 DCHECK(args.length() == 4);
2373 DCHECK(args.length() == 4); 2257 Handle<Smi> slot = args.at<Smi>(2);
2374 Handle<Smi> slot = args.at<Smi>(2); 2258 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
2375 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); 2259 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2376 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); 2260 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the
2377 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the 2261 // LoadIC miss handler if the handler misses. Since the vector Nexus is
2378 // LoadIC miss handler if the handler misses. Since the vector Nexus is 2262 // set up outside the IC, handle that here.
2379 // set up outside the IC, handle that here. 2263 if (vector->GetKind(vector_slot) == Code::LOAD_IC) {
2380 if (vector->GetKind(vector_slot) == Code::LOAD_IC) { 2264 LoadICNexus nexus(vector, vector_slot);
2381 LoadICNexus nexus(vector, vector_slot); 2265 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2382 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); 2266 ic.UpdateState(receiver, key);
2383 ic.UpdateState(receiver, key); 2267 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2384 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2385 ic.Load(receiver, key));
2386 } else {
2387 DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
2388 KeyedLoadICNexus nexus(vector, vector_slot);
2389 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2390 ic.UpdateState(receiver, key);
2391 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
2392 ic.Load(receiver, key));
2393 }
2394 } else { 2268 } else {
2395 DCHECK(args.length() == 2); 2269 DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
2396 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2270 KeyedLoadICNexus nexus(vector, vector_slot);
2271 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2397 ic.UpdateState(receiver, key); 2272 ic.UpdateState(receiver, key);
2398 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); 2273 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2399 } 2274 }
2400 return *result; 2275 return *result;
2401 } 2276 }
2402 2277
2403 2278
2404 // Used from ic-<arch>.cc 2279 // Used from ic-<arch>.cc
2405 RUNTIME_FUNCTION(KeyedLoadIC_Miss) { 2280 RUNTIME_FUNCTION(KeyedLoadIC_Miss) {
2406 TimerEventScope<TimerEventIcMiss> timer(isolate); 2281 TimerEventScope<TimerEventIcMiss> timer(isolate);
2407 HandleScope scope(isolate); 2282 HandleScope scope(isolate);
2408 Handle<Object> receiver = args.at<Object>(0); 2283 Handle<Object> receiver = args.at<Object>(0);
2409 Handle<Object> key = args.at<Object>(1); 2284 Handle<Object> key = args.at<Object>(1);
2410 Handle<Object> result; 2285 Handle<Object> result;
2411 2286
2412 if (FLAG_vector_ics) { 2287 DCHECK(args.length() == 4);
2413 DCHECK(args.length() == 4); 2288 Handle<Smi> slot = args.at<Smi>(2);
2414 Handle<Smi> slot = args.at<Smi>(2); 2289 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
2415 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); 2290 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2416 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); 2291 KeyedLoadICNexus nexus(vector, vector_slot);
2417 KeyedLoadICNexus nexus(vector, vector_slot); 2292 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
2418 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); 2293 ic.UpdateState(receiver, key);
2419 ic.UpdateState(receiver, key); 2294 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2420 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2421 } else {
2422 DCHECK(args.length() == 2);
2423 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2424 ic.UpdateState(receiver, key);
2425 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2426 }
2427
2428 return *result; 2295 return *result;
2429 } 2296 }
2430 2297
2431 2298
2432 RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure) { 2299 RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure) {
2433 TimerEventScope<TimerEventIcMiss> timer(isolate); 2300 TimerEventScope<TimerEventIcMiss> timer(isolate);
2434 HandleScope scope(isolate); 2301 HandleScope scope(isolate);
2435 Handle<Object> receiver = args.at<Object>(0); 2302 Handle<Object> receiver = args.at<Object>(0);
2436 Handle<Object> key = args.at<Object>(1); 2303 Handle<Object> key = args.at<Object>(1);
2437 Handle<Object> result; 2304 Handle<Object> result;
2438 2305
2439 if (FLAG_vector_ics) { 2306 DCHECK(args.length() == 4);
2440 DCHECK(args.length() == 4); 2307 Handle<Smi> slot = args.at<Smi>(2);
2441 Handle<Smi> slot = args.at<Smi>(2); 2308 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
2442 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); 2309 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
2443 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); 2310 KeyedLoadICNexus nexus(vector, vector_slot);
2444 KeyedLoadICNexus nexus(vector, vector_slot); 2311 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
2445 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); 2312 ic.UpdateState(receiver, key);
2446 ic.UpdateState(receiver, key); 2313 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2447 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2448 } else {
2449 DCHECK(args.length() == 2);
2450 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
2451 ic.UpdateState(receiver, key);
2452 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
2453 }
2454 2314
2455 return *result; 2315 return *result;
2456 } 2316 }
2457 2317
2458 2318
2459 // Used from ic-<arch>.cc. 2319 // Used from ic-<arch>.cc.
2460 RUNTIME_FUNCTION(StoreIC_Miss) { 2320 RUNTIME_FUNCTION(StoreIC_Miss) {
2461 TimerEventScope<TimerEventIcMiss> timer(isolate); 2321 TimerEventScope<TimerEventIcMiss> timer(isolate);
2462 HandleScope scope(isolate); 2322 HandleScope scope(isolate);
2463 DCHECK(args.length() == 3); 2323 DCHECK(args.length() == 3);
(...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after
3011 } 2871 }
3012 2872
3013 2873
3014 RUNTIME_FUNCTION(LoadIC_MissFromStubFailure) { 2874 RUNTIME_FUNCTION(LoadIC_MissFromStubFailure) {
3015 TimerEventScope<TimerEventIcMiss> timer(isolate); 2875 TimerEventScope<TimerEventIcMiss> timer(isolate);
3016 HandleScope scope(isolate); 2876 HandleScope scope(isolate);
3017 Handle<Object> receiver = args.at<Object>(0); 2877 Handle<Object> receiver = args.at<Object>(0);
3018 Handle<Name> key = args.at<Name>(1); 2878 Handle<Name> key = args.at<Name>(1);
3019 Handle<Object> result; 2879 Handle<Object> result;
3020 2880
3021 if (FLAG_vector_ics) { 2881 DCHECK(args.length() == 4);
3022 DCHECK(args.length() == 4); 2882 Handle<Smi> slot = args.at<Smi>(2);
3023 Handle<Smi> slot = args.at<Smi>(2); 2883 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
3024 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); 2884 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
3025 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); 2885 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the
3026 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the 2886 // LoadIC miss handler if the handler misses. Since the vector Nexus is
3027 // LoadIC miss handler if the handler misses. Since the vector Nexus is 2887 // set up outside the IC, handle that here.
3028 // set up outside the IC, handle that here. 2888 if (vector->GetKind(vector_slot) == Code::LOAD_IC) {
3029 if (vector->GetKind(vector_slot) == Code::LOAD_IC) { 2889 LoadICNexus nexus(vector, vector_slot);
3030 LoadICNexus nexus(vector, vector_slot); 2890 LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
3031 LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); 2891 ic.UpdateState(receiver, key);
3032 ic.UpdateState(receiver, key); 2892 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
3033 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
3034 ic.Load(receiver, key));
3035 } else {
3036 DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
3037 KeyedLoadICNexus nexus(vector, vector_slot);
3038 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
3039 ic.UpdateState(receiver, key);
3040 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
3041 ic.Load(receiver, key));
3042 }
3043 } else { 2893 } else {
3044 DCHECK(args.length() == 2); 2894 DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
3045 LoadIC ic(IC::EXTRA_CALL_FRAME, isolate); 2895 KeyedLoadICNexus nexus(vector, vector_slot);
2896 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
3046 ic.UpdateState(receiver, key); 2897 ic.UpdateState(receiver, key);
3047 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); 2898 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
3048 } 2899 }
3049 2900
3050 return *result; 2901 return *result;
3051 } 2902 }
3052 2903
3053 2904
3054 static const Address IC_utilities[] = { 2905 static const Address IC_utilities[] = {
3055 #define ADDR(name) FUNCTION_ADDR(name), 2906 #define ADDR(name) FUNCTION_ADDR(name),
3056 IC_UTIL_LIST(ADDR) NULL 2907 IC_UTIL_LIST(ADDR) NULL
3057 #undef ADDR 2908 #undef ADDR
3058 }; 2909 };
3059 2910
3060 2911
3061 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 2912 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
3062 } 2913 }
3063 } // namespace v8::internal 2914 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698