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

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

Powered by Google App Engine
This is Rietveld 408576698