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

Side by Side Diff: src/ic.cc

Issue 424743002: Clean up name distinction between Keyed ICs and Element Handlers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/isolate.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/codegen.h" 10 #include "src/codegen.h"
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 ConstantPoolArray* constant_pool) { 475 ConstantPoolArray* constant_pool) {
476 // Currently, CallIC doesn't have state changes. 476 // Currently, CallIC doesn't have state changes.
477 } 477 }
478 478
479 479
480 void LoadIC::Clear(Isolate* isolate, 480 void LoadIC::Clear(Isolate* isolate,
481 Address address, 481 Address address,
482 Code* target, 482 Code* target,
483 ConstantPoolArray* constant_pool) { 483 ConstantPoolArray* constant_pool) {
484 if (IsCleared(target)) return; 484 if (IsCleared(target)) return;
485 Code* code = PropertyICCompiler::FindPreMonomorphicIC( 485 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC,
486 isolate, Code::LOAD_IC, target->extra_ic_state()); 486 target->extra_ic_state());
487 SetTargetAtAddress(address, code, constant_pool); 487 SetTargetAtAddress(address, code, constant_pool);
488 } 488 }
489 489
490 490
491 void StoreIC::Clear(Isolate* isolate, 491 void StoreIC::Clear(Isolate* isolate,
492 Address address, 492 Address address,
493 Code* target, 493 Code* target,
494 ConstantPoolArray* constant_pool) { 494 ConstantPoolArray* constant_pool) {
495 if (IsCleared(target)) return; 495 if (IsCleared(target)) return;
496 Code* code = PropertyICCompiler::FindPreMonomorphicIC( 496 Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::STORE_IC,
497 isolate, Code::STORE_IC, target->extra_ic_state()); 497 target->extra_ic_state());
498 SetTargetAtAddress(address, code, constant_pool); 498 SetTargetAtAddress(address, code, constant_pool);
499 } 499 }
500 500
501 501
502 void KeyedStoreIC::Clear(Isolate* isolate, 502 void KeyedStoreIC::Clear(Isolate* isolate,
503 Address address, 503 Address address,
504 Code* target, 504 Code* target,
505 ConstantPoolArray* constant_pool) { 505 ConstantPoolArray* constant_pool) {
506 if (IsCleared(target)) return; 506 if (IsCleared(target)) return;
507 SetTargetAtAddress(address, 507 SetTargetAtAddress(address,
(...skipping 14 matching lines...) Expand all
522 // Only clear CompareICs that can retain objects. 522 // Only clear CompareICs that can retain objects.
523 if (handler_state != KNOWN_OBJECT) return; 523 if (handler_state != KNOWN_OBJECT) return;
524 SetTargetAtAddress(address, GetRawUninitialized(isolate, op), constant_pool); 524 SetTargetAtAddress(address, GetRawUninitialized(isolate, op), constant_pool);
525 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); 525 PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
526 } 526 }
527 527
528 528
529 // static 529 // static
530 Handle<Code> KeyedLoadIC::generic_stub(Isolate* isolate) { 530 Handle<Code> KeyedLoadIC::generic_stub(Isolate* isolate) {
531 if (FLAG_compiled_keyed_generic_loads) { 531 if (FLAG_compiled_keyed_generic_loads) {
532 return KeyedLoadGenericElementStub(isolate).GetCode(); 532 return KeyedLoadGenericStub(isolate).GetCode();
533 } else { 533 } else {
534 return isolate->builtins()->KeyedLoadIC_Generic(); 534 return isolate->builtins()->KeyedLoadIC_Generic();
535 } 535 }
536 } 536 }
537 537
538 538
539 static bool MigrateDeprecated(Handle<Object> object) { 539 static bool MigrateDeprecated(Handle<Object> object) {
540 if (!object->IsJSObject()) return false; 540 if (!object->IsJSObject()) return false;
541 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 541 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
542 if (!receiver->map()->is_deprecated()) return false; 542 if (!receiver->map()->is_deprecated()) return false;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 number_of_types - deprecated_types - (handler_to_overwrite != -1); 653 number_of_types - deprecated_types - (handler_to_overwrite != -1);
654 654
655 if (number_of_valid_types >= 4) return false; 655 if (number_of_valid_types >= 4) return false;
656 if (number_of_types == 0) return false; 656 if (number_of_types == 0) return false;
657 if (!target()->FindHandlers(&handlers, types.length())) return false; 657 if (!target()->FindHandlers(&handlers, types.length())) return false;
658 658
659 number_of_valid_types++; 659 number_of_valid_types++;
660 if (number_of_valid_types > 1 && target()->is_keyed_stub()) return false; 660 if (number_of_valid_types > 1 && target()->is_keyed_stub()) return false;
661 Handle<Code> ic; 661 Handle<Code> ic;
662 if (number_of_valid_types == 1) { 662 if (number_of_valid_types == 1) {
663 ic = PropertyICCompiler::ComputeMonomorphicIC(kind(), name, type, code, 663 ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, type, code,
664 extra_ic_state()); 664 extra_ic_state());
665 } else { 665 } else {
666 if (handler_to_overwrite >= 0) { 666 if (handler_to_overwrite >= 0) {
667 handlers.Set(handler_to_overwrite, code); 667 handlers.Set(handler_to_overwrite, code);
668 if (!type->NowIs(types.at(handler_to_overwrite))) { 668 if (!type->NowIs(types.at(handler_to_overwrite))) {
669 types.Set(handler_to_overwrite, type); 669 types.Set(handler_to_overwrite, type);
670 } 670 }
671 } else { 671 } else {
672 types.Add(type); 672 types.Add(type);
673 handlers.Add(code); 673 handlers.Add(code);
674 } 674 }
675 ic = PropertyICCompiler::ComputePolymorphicIC(kind(), &types, &handlers, 675 ic = PropertyICCompiler::ComputePolymorphic(kind(), &types, &handlers,
676 number_of_valid_types, name, 676 number_of_valid_types, name,
677 extra_ic_state()); 677 extra_ic_state());
678 } 678 }
679 set_target(*ic); 679 set_target(*ic);
680 return true; 680 return true;
681 } 681 }
682 682
683 683
684 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { 684 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) {
685 return object->IsJSGlobalObject() 685 return object->IsJSGlobalObject()
686 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate) 686 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate)
687 : HeapType::NowOf(object, isolate); 687 : HeapType::NowOf(object, isolate);
(...skipping 30 matching lines...) Expand all
718 template 718 template
719 Type* IC::MapToType<Type>(Handle<Map> map, Zone* zone); 719 Type* IC::MapToType<Type>(Handle<Map> map, Zone* zone);
720 720
721 721
722 template 722 template
723 Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map, Isolate* region); 723 Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map, Isolate* region);
724 724
725 725
726 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<String> name) { 726 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<String> name) {
727 if (!handler->is_handler()) return set_target(*handler); 727 if (!handler->is_handler()) return set_target(*handler);
728 Handle<Code> ic = PropertyICCompiler::ComputeMonomorphicIC( 728 Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic(
729 kind(), name, receiver_type(), handler, extra_ic_state()); 729 kind(), name, receiver_type(), handler, extra_ic_state());
730 set_target(*ic); 730 set_target(*ic);
731 } 731 }
732 732
733 733
734 void IC::CopyICToMegamorphicCache(Handle<String> name) { 734 void IC::CopyICToMegamorphicCache(Handle<String> name) {
735 TypeHandleList types; 735 TypeHandleList types;
736 CodeHandleList handlers; 736 CodeHandleList handlers;
737 TargetTypes(&types); 737 TargetTypes(&types);
738 if (!target()->FindHandlers(&handlers, types.length())) return; 738 if (!target()->FindHandlers(&handlers, types.length())) return;
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 } 1066 }
1067 1067
1068 Handle<Map> receiver_map(receiver->map(), isolate()); 1068 Handle<Map> receiver_map(receiver->map(), isolate());
1069 MapHandleList target_receiver_maps; 1069 MapHandleList target_receiver_maps;
1070 if (target().is_identical_to(string_stub())) { 1070 if (target().is_identical_to(string_stub())) {
1071 target_receiver_maps.Add(isolate()->factory()->string_map()); 1071 target_receiver_maps.Add(isolate()->factory()->string_map());
1072 } else { 1072 } else {
1073 TargetMaps(&target_receiver_maps); 1073 TargetMaps(&target_receiver_maps);
1074 } 1074 }
1075 if (target_receiver_maps.length() == 0) { 1075 if (target_receiver_maps.length() == 0) {
1076 return PropertyICCompiler::ComputeKeyedLoadElement(receiver_map); 1076 return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
1077 } 1077 }
1078 1078
1079 // The first time a receiver is seen that is a transitioned version of the 1079 // The first time a receiver is seen that is a transitioned version of the
1080 // previous monomorphic receiver type, assume the new ElementsKind is the 1080 // previous monomorphic receiver type, assume the new ElementsKind is the
1081 // monomorphic type. This benefits global arrays that only transition 1081 // monomorphic type. This benefits global arrays that only transition
1082 // once, and all call sites accessing them are faster if they remain 1082 // once, and all call sites accessing them are faster if they remain
1083 // monomorphic. If this optimistic assumption is not true, the IC will 1083 // monomorphic. If this optimistic assumption is not true, the IC will
1084 // miss again and it will become polymorphic and support both the 1084 // miss again and it will become polymorphic and support both the
1085 // untransitioned and transitioned maps. 1085 // untransitioned and transitioned maps.
1086 if (state() == MONOMORPHIC && 1086 if (state() == MONOMORPHIC &&
1087 IsMoreGeneralElementsKindTransition( 1087 IsMoreGeneralElementsKindTransition(
1088 target_receiver_maps.at(0)->elements_kind(), 1088 target_receiver_maps.at(0)->elements_kind(),
1089 receiver->GetElementsKind())) { 1089 receiver->GetElementsKind())) {
1090 return PropertyICCompiler::ComputeKeyedLoadElement(receiver_map); 1090 return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
1091 } 1091 }
1092 1092
1093 ASSERT(state() != GENERIC); 1093 ASSERT(state() != GENERIC);
1094 1094
1095 // Determine the list of receiver maps that this call site has seen, 1095 // Determine the list of receiver maps that this call site has seen,
1096 // adding the map that was just encountered. 1096 // adding the map that was just encountered.
1097 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { 1097 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
1098 // If the miss wasn't due to an unseen map, a polymorphic stub 1098 // If the miss wasn't due to an unseen map, a polymorphic stub
1099 // won't help, use the generic stub. 1099 // won't help, use the generic stub.
1100 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); 1100 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice");
1101 return generic_stub(); 1101 return generic_stub();
1102 } 1102 }
1103 1103
1104 // If the maximum number of receiver maps has been exceeded, use the generic 1104 // If the maximum number of receiver maps has been exceeded, use the generic
1105 // version of the IC. 1105 // version of the IC.
1106 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1106 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1107 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); 1107 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded");
1108 return generic_stub(); 1108 return generic_stub();
1109 } 1109 }
1110 1110
1111 return PropertyICCompiler::ComputeLoadElementPolymorphic( 1111 return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps);
1112 &target_receiver_maps);
1113 } 1112 }
1114 1113
1115 1114
1116 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, 1115 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
1117 Handle<Object> key) { 1116 Handle<Object> key) {
1118 if (MigrateDeprecated(object)) { 1117 if (MigrateDeprecated(object)) {
1119 Handle<Object> result; 1118 Handle<Object> result;
1120 ASSIGN_RETURN_ON_EXCEPTION( 1119 ASSIGN_RETURN_ON_EXCEPTION(
1121 isolate(), 1120 isolate(),
1122 result, 1121 result,
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 return generic_stub(); 1486 return generic_stub();
1488 } 1487 }
1489 1488
1490 Handle<Map> receiver_map(receiver->map(), isolate()); 1489 Handle<Map> receiver_map(receiver->map(), isolate());
1491 MapHandleList target_receiver_maps; 1490 MapHandleList target_receiver_maps;
1492 TargetMaps(&target_receiver_maps); 1491 TargetMaps(&target_receiver_maps);
1493 if (target_receiver_maps.length() == 0) { 1492 if (target_receiver_maps.length() == 0) {
1494 Handle<Map> monomorphic_map = 1493 Handle<Map> monomorphic_map =
1495 ComputeTransitionedMap(receiver_map, store_mode); 1494 ComputeTransitionedMap(receiver_map, store_mode);
1496 store_mode = GetNonTransitioningStoreMode(store_mode); 1495 store_mode = GetNonTransitioningStoreMode(store_mode);
1497 return PropertyICCompiler::ComputeKeyedStoreElement( 1496 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1498 monomorphic_map, strict_mode(), store_mode); 1497 monomorphic_map, strict_mode(), store_mode);
1499 } 1498 }
1500 1499
1501 // There are several special cases where an IC that is MONOMORPHIC can still 1500 // There are several special cases where an IC that is MONOMORPHIC can still
1502 // transition to a different GetNonTransitioningStoreMode IC that handles a 1501 // transition to a different GetNonTransitioningStoreMode IC that handles a
1503 // superset of the original IC. Handle those here if the receiver map hasn't 1502 // superset of the original IC. Handle those here if the receiver map hasn't
1504 // changed or it has transitioned to a more general kind. 1503 // changed or it has transitioned to a more general kind.
1505 KeyedAccessStoreMode old_store_mode = 1504 KeyedAccessStoreMode old_store_mode =
1506 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); 1505 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state());
1507 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); 1506 Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
1508 if (state() == MONOMORPHIC) { 1507 if (state() == MONOMORPHIC) {
1509 Handle<Map> transitioned_receiver_map = receiver_map; 1508 Handle<Map> transitioned_receiver_map = receiver_map;
1510 if (IsTransitionStoreMode(store_mode)) { 1509 if (IsTransitionStoreMode(store_mode)) {
1511 transitioned_receiver_map = 1510 transitioned_receiver_map =
1512 ComputeTransitionedMap(receiver_map, store_mode); 1511 ComputeTransitionedMap(receiver_map, store_mode);
1513 } 1512 }
1514 if ((receiver_map.is_identical_to(previous_receiver_map) && 1513 if ((receiver_map.is_identical_to(previous_receiver_map) &&
1515 IsTransitionStoreMode(store_mode)) || 1514 IsTransitionStoreMode(store_mode)) ||
1516 IsTransitionOfMonomorphicTarget(*previous_receiver_map, 1515 IsTransitionOfMonomorphicTarget(*previous_receiver_map,
1517 *transitioned_receiver_map)) { 1516 *transitioned_receiver_map)) {
1518 // If the "old" and "new" maps are in the same elements map family, or 1517 // If the "old" and "new" maps are in the same elements map family, or
1519 // if they at least come from the same origin for a transitioning store, 1518 // if they at least come from the same origin for a transitioning store,
1520 // stay MONOMORPHIC and use the map for the most generic ElementsKind. 1519 // stay MONOMORPHIC and use the map for the most generic ElementsKind.
1521 store_mode = GetNonTransitioningStoreMode(store_mode); 1520 store_mode = GetNonTransitioningStoreMode(store_mode);
1522 return PropertyICCompiler::ComputeKeyedStoreElement( 1521 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1523 transitioned_receiver_map, strict_mode(), store_mode); 1522 transitioned_receiver_map, strict_mode(), store_mode);
1524 } else if (*previous_receiver_map == receiver->map() && 1523 } else if (*previous_receiver_map == receiver->map() &&
1525 old_store_mode == STANDARD_STORE && 1524 old_store_mode == STANDARD_STORE &&
1526 (store_mode == STORE_AND_GROW_NO_TRANSITION || 1525 (store_mode == STORE_AND_GROW_NO_TRANSITION ||
1527 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 1526 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
1528 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { 1527 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) {
1529 // A "normal" IC that handles stores can switch to a version that can 1528 // A "normal" IC that handles stores can switch to a version that can
1530 // grow at the end of the array, handle OOB accesses or copy COW arrays 1529 // grow at the end of the array, handle OOB accesses or copy COW arrays
1531 // and still stay MONOMORPHIC. 1530 // and still stay MONOMORPHIC.
1532 return PropertyICCompiler::ComputeKeyedStoreElement( 1531 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1533 receiver_map, strict_mode(), store_mode); 1532 receiver_map, strict_mode(), store_mode);
1534 } 1533 }
1535 } 1534 }
1536 1535
1537 ASSERT(state() != GENERIC); 1536 ASSERT(state() != GENERIC);
1538 1537
1539 bool map_added = 1538 bool map_added =
1540 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1539 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1541 1540
1542 if (IsTransitionStoreMode(store_mode)) { 1541 if (IsTransitionStoreMode(store_mode)) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 } 1583 }
1585 } 1584 }
1586 if (external_arrays != 0 && 1585 if (external_arrays != 0 &&
1587 external_arrays != target_receiver_maps.length()) { 1586 external_arrays != target_receiver_maps.length()) {
1588 TRACE_GENERIC_IC(isolate(), "KeyedIC", 1587 TRACE_GENERIC_IC(isolate(), "KeyedIC",
1589 "unsupported combination of external and normal arrays"); 1588 "unsupported combination of external and normal arrays");
1590 return generic_stub(); 1589 return generic_stub();
1591 } 1590 }
1592 } 1591 }
1593 1592
1594 return PropertyICCompiler::ComputeStoreElementPolymorphic( 1593 return PropertyICCompiler::ComputeKeyedStorePolymorphic(
1595 &target_receiver_maps, store_mode, strict_mode()); 1594 &target_receiver_maps, store_mode, strict_mode());
1596 } 1595 }
1597 1596
1598 1597
1599 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( 1598 Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
1600 Handle<Map> map, 1599 Handle<Map> map,
1601 KeyedAccessStoreMode store_mode) { 1600 KeyedAccessStoreMode store_mode) {
1602 switch (store_mode) { 1601 switch (store_mode) {
1603 case STORE_TRANSITION_SMI_TO_OBJECT: 1602 case STORE_TRANSITION_SMI_TO_OBJECT:
1604 case STORE_TRANSITION_DOUBLE_TO_OBJECT: 1603 case STORE_TRANSITION_DOUBLE_TO_OBJECT:
(...skipping 1431 matching lines...) Expand 10 before | Expand all | Expand 10 after
3036 #undef ADDR 3035 #undef ADDR
3037 }; 3036 };
3038 3037
3039 3038
3040 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3039 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3041 return IC_utilities[id]; 3040 return IC_utilities[id];
3042 } 3041 }
3043 3042
3044 3043
3045 } } // namespace v8::internal 3044 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/isolate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698