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

Side by Side Diff: src/ic.cc

Issue 148343005: A64: Synchronize with r18147. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/ic-inl.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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 if (raw_frame->is_internal()) { 82 if (raw_frame->is_internal()) {
83 Code* apply_builtin = isolate()->builtins()->builtin( 83 Code* apply_builtin = isolate()->builtins()->builtin(
84 Builtins::kFunctionApply); 84 Builtins::kFunctionApply);
85 if (raw_frame->unchecked_code() == apply_builtin) { 85 if (raw_frame->unchecked_code() == apply_builtin) {
86 PrintF("apply from "); 86 PrintF("apply from ");
87 it.Advance(); 87 it.Advance();
88 raw_frame = it.frame(); 88 raw_frame = it.frame();
89 } 89 }
90 } 90 }
91 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 91 JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
92 Code::ExtraICState extra_state = new_target->extra_ic_state(); 92 ExtraICState extra_state = new_target->extra_ic_state();
93 const char* modifier = 93 const char* modifier =
94 GetTransitionMarkModifier(Code::GetKeyedAccessStoreMode(extra_state)); 94 GetTransitionMarkModifier(
95 KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
95 PrintF(" (%c->%c%s)", 96 PrintF(" (%c->%c%s)",
96 TransitionMarkFromState(state()), 97 TransitionMarkFromState(state()),
97 TransitionMarkFromState(new_state), 98 TransitionMarkFromState(new_state),
98 modifier); 99 modifier);
99 name->Print(); 100 name->Print();
100 PrintF("]\n"); 101 PrintF("]\n");
101 } 102 }
102 } 103 }
103 104
104 #define TRACE_GENERIC_IC(isolate, type, reason) \ 105 #define TRACE_GENERIC_IC(isolate, type, reason) \
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { 526 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) {
526 if (IsCleared(target)) return; 527 if (IsCleared(target)) return;
527 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); 528 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate));
528 } 529 }
529 530
530 531
531 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { 532 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) {
532 if (IsCleared(target)) return; 533 if (IsCleared(target)) return;
533 SetTargetAtAddress(address, 534 SetTargetAtAddress(address,
534 *pre_monomorphic_stub( 535 *pre_monomorphic_stub(
535 isolate, Code::GetStrictMode(target->extra_ic_state()))); 536 isolate, StoreIC::GetStrictMode(target->extra_ic_state())));
536 } 537 }
537 538
538 539
539 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { 540 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) {
540 if (IsCleared(target)) return; 541 if (IsCleared(target)) return;
541 SetTargetAtAddress(address, 542 SetTargetAtAddress(address,
542 *pre_monomorphic_stub( 543 *pre_monomorphic_stub(
543 isolate, Code::GetStrictMode(target->extra_ic_state()))); 544 isolate, StoreIC::GetStrictMode(target->extra_ic_state())));
544 } 545 }
545 546
546 547
547 void CompareIC::Clear(Isolate* isolate, Address address, Code* target) { 548 void CompareIC::Clear(Isolate* isolate, Address address, Code* target) {
548 ASSERT(target->major_key() == CodeStub::CompareIC); 549 ASSERT(target->major_key() == CodeStub::CompareIC);
549 CompareIC::State handler_state; 550 CompareIC::State handler_state;
550 Token::Value op; 551 Token::Value op;
551 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, 552 ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL,
552 &handler_state, &op); 553 &handler_state, &op);
553 // Only clear CompareICs that can retain objects. 554 // Only clear CompareICs that can retain objects.
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 ElementsKind kind = array->map()->elements_kind(); 816 ElementsKind kind = array->map()->elements_kind();
816 if (IsFastObjectElementsKind(kind) && 817 if (IsFastObjectElementsKind(kind) &&
817 array->map() == isolate()->get_initial_js_array_map(kind)) { 818 array->map() == isolate()->get_initial_js_array_map(kind)) {
818 KeyedArrayCallStub stub_gen(IsHoleyElementsKind(kind), argc); 819 KeyedArrayCallStub stub_gen(IsHoleyElementsKind(kind), argc);
819 stub = stub_gen.GetCode(isolate()); 820 stub = stub_gen.GetCode(isolate());
820 } 821 }
821 } 822 }
822 823
823 if (stub.is_null()) { 824 if (stub.is_null()) {
824 stub = isolate()->stub_cache()->ComputeCallMegamorphic( 825 stub = isolate()->stub_cache()->ComputeCallMegamorphic(
825 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); 826 argc, Code::KEYED_CALL_IC, kNoExtraICState);
826 if (object->IsJSObject()) { 827 if (object->IsJSObject()) {
827 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 828 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
828 if (receiver->elements()->map() == 829 if (receiver->elements()->map() ==
829 isolate()->heap()->non_strict_arguments_elements_map()) { 830 isolate()->heap()->non_strict_arguments_elements_map()) {
830 stub = isolate()->stub_cache()->ComputeCallArguments(argc); 831 stub = isolate()->stub_cache()->ComputeCallArguments(argc);
831 } 832 }
832 } 833 }
833 ASSERT(!stub.is_null()); 834 ASSERT(!stub.is_null());
834 } 835 }
835 set_target(*stub); 836 set_target(*stub);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 stub = pre_monomorphic_stub(); 873 stub = pre_monomorphic_stub();
873 } else if (state() == PREMONOMORPHIC || state() == MONOMORPHIC) { 874 } else if (state() == PREMONOMORPHIC || state() == MONOMORPHIC) {
874 StringLengthStub string_length_stub(kind()); 875 StringLengthStub string_length_stub(kind());
875 stub = string_length_stub.GetCode(isolate()); 876 stub = string_length_stub.GetCode(isolate());
876 } else if (state() != MEGAMORPHIC) { 877 } else if (state() != MEGAMORPHIC) {
877 ASSERT(state() != GENERIC); 878 ASSERT(state() != GENERIC);
878 stub = megamorphic_stub(); 879 stub = megamorphic_stub();
879 } 880 }
880 if (!stub.is_null()) { 881 if (!stub.is_null()) {
881 set_target(*stub); 882 set_target(*stub);
882 #ifdef DEBUG
883 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /stringwrapper]\n"); 883 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /stringwrapper]\n");
884 #endif
885 } 884 }
886 // Get the string if we have a string wrapper object. 885 // Get the string if we have a string wrapper object.
887 String* string = String::cast(JSValue::cast(*object)->value()); 886 String* string = String::cast(JSValue::cast(*object)->value());
888 return Smi::FromInt(string->length()); 887 return Smi::FromInt(string->length());
889 } 888 }
890 889
891 // Use specialized code for getting prototype of functions. 890 // Use specialized code for getting prototype of functions.
892 if (object->IsJSFunction() && 891 if (object->IsJSFunction() &&
893 name->Equals(isolate()->heap()->prototype_string()) && 892 name->Equals(isolate()->heap()->prototype_string()) &&
894 Handle<JSFunction>::cast(object)->should_have_prototype()) { 893 Handle<JSFunction>::cast(object)->should_have_prototype()) {
895 Handle<Code> stub; 894 Handle<Code> stub;
896 if (state() == UNINITIALIZED) { 895 if (state() == UNINITIALIZED) {
897 stub = pre_monomorphic_stub(); 896 stub = pre_monomorphic_stub();
898 } else if (state() == PREMONOMORPHIC) { 897 } else if (state() == PREMONOMORPHIC) {
899 FunctionPrototypeStub function_prototype_stub(kind()); 898 FunctionPrototypeStub function_prototype_stub(kind());
900 stub = function_prototype_stub.GetCode(isolate()); 899 stub = function_prototype_stub.GetCode(isolate());
901 } else if (state() != MEGAMORPHIC) { 900 } else if (state() != MEGAMORPHIC) {
902 ASSERT(state() != GENERIC); 901 ASSERT(state() != GENERIC);
903 stub = megamorphic_stub(); 902 stub = megamorphic_stub();
904 } 903 }
905 if (!stub.is_null()) { 904 if (!stub.is_null()) {
906 set_target(*stub); 905 set_target(*stub);
907 #ifdef DEBUG
908 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); 906 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
909 #endif
910 } 907 }
911 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object)); 908 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object));
912 } 909 }
913 } 910 }
914 911
915 // Check if the name is trivially convertible to an index and get 912 // Check if the name is trivially convertible to an index and get
916 // the element or char if so. 913 // the element or char if so.
917 uint32_t index; 914 uint32_t index;
918 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { 915 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
919 // Rewrite to the generic keyed load stub. 916 // Rewrite to the generic keyed load stub.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 999
1003 number_of_valid_types++; 1000 number_of_valid_types++;
1004 if (handler_to_overwrite >= 0) { 1001 if (handler_to_overwrite >= 0) {
1005 handlers.Set(handler_to_overwrite, code); 1002 handlers.Set(handler_to_overwrite, code);
1006 } else { 1003 } else {
1007 types.Add(type); 1004 types.Add(type);
1008 handlers.Add(code); 1005 handlers.Add(code);
1009 } 1006 }
1010 1007
1011 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( 1008 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
1012 &types, &handlers, number_of_valid_types, name, strict_mode()); 1009 &types, &handlers, number_of_valid_types, name, extra_ic_state());
1013 set_target(*ic); 1010 set_target(*ic);
1014 return true; 1011 return true;
1015 } 1012 }
1016 1013
1017 1014
1018 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { 1015 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) {
1019 Type* type = object->IsJSGlobalObject() 1016 Type* type = object->IsJSGlobalObject()
1020 ? Type::Constant(Handle<JSGlobalObject>::cast(object)) 1017 ? Type::Constant(Handle<JSGlobalObject>::cast(object))
1021 : Type::OfCurrently(object); 1018 : Type::OfCurrently(object);
1022 return handle(type, isolate); 1019 return handle(type, isolate);
(...skipping 17 matching lines...) Expand all
1040 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); 1037 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean();
1041 return Type::Class(map); 1038 return Type::Class(map);
1042 } 1039 }
1043 1040
1044 1041
1045 void IC::UpdateMonomorphicIC(Handle<Type> type, 1042 void IC::UpdateMonomorphicIC(Handle<Type> type,
1046 Handle<Code> handler, 1043 Handle<Code> handler,
1047 Handle<String> name) { 1044 Handle<String> name) {
1048 if (!handler->is_handler()) return set_target(*handler); 1045 if (!handler->is_handler()) return set_target(*handler);
1049 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( 1046 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC(
1050 name, type, handler, strict_mode()); 1047 name, type, handler, extra_ic_state());
1051 set_target(*ic); 1048 set_target(*ic);
1052 } 1049 }
1053 1050
1054 1051
1055 void IC::CopyICToMegamorphicCache(Handle<String> name) { 1052 void IC::CopyICToMegamorphicCache(Handle<String> name) {
1056 TypeHandleList types; 1053 TypeHandleList types;
1057 CodeHandleList handlers; 1054 CodeHandleList handlers;
1058 target()->FindAllTypes(&types); 1055 target()->FindAllTypes(&types);
1059 if (!target()->FindHandlers(&handlers, types.length())) return; 1056 if (!target()->FindHandlers(&handlers, types.length())) return;
1060 for (int i = 0; i < types.length(); i++) { 1057 for (int i = 0; i < types.length(); i++) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 1172
1176 Handle<Code> IC::ComputeHandler(LookupResult* lookup, 1173 Handle<Code> IC::ComputeHandler(LookupResult* lookup,
1177 Handle<Object> object, 1174 Handle<Object> object,
1178 Handle<String> name, 1175 Handle<String> name,
1179 Handle<Object> value) { 1176 Handle<Object> value) {
1180 InlineCacheHolderFlag cache_holder = GetCodeCacheForObject(*object); 1177 InlineCacheHolderFlag cache_holder = GetCodeCacheForObject(*object);
1181 Handle<HeapObject> stub_holder(GetCodeCacheHolder( 1178 Handle<HeapObject> stub_holder(GetCodeCacheHolder(
1182 isolate(), *object, cache_holder)); 1179 isolate(), *object, cache_holder));
1183 1180
1184 Handle<Code> code = isolate()->stub_cache()->FindHandler( 1181 Handle<Code> code = isolate()->stub_cache()->FindHandler(
1185 name, handle(stub_holder->map()), kind(), cache_holder, strict_mode()); 1182 name, handle(stub_holder->map()), kind(), cache_holder);
1186 if (!code.is_null()) return code; 1183 if (!code.is_null()) return code;
1187 1184
1188 code = CompileHandler(lookup, object, name, value, cache_holder); 1185 code = CompileHandler(lookup, object, name, value, cache_holder);
1189 ASSERT(code->is_handler()); 1186 ASSERT(code->is_handler());
1190 1187
1191 if (code->type() != Code::NORMAL) { 1188 if (code->type() != Code::NORMAL) {
1192 HeapObject::UpdateMapCodeCache(stub_holder, name, code); 1189 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
1193 } 1190 }
1194 1191
1195 return code; 1192 return code;
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
1630 Handle<Code> StoreIC::CompileHandler(LookupResult* lookup, 1627 Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
1631 Handle<Object> object, 1628 Handle<Object> object,
1632 Handle<String> name, 1629 Handle<String> name,
1633 Handle<Object> value, 1630 Handle<Object> value,
1634 InlineCacheHolderFlag cache_holder) { 1631 InlineCacheHolderFlag cache_holder) {
1635 ASSERT(cache_holder == OWN_MAP); 1632 ASSERT(cache_holder == OWN_MAP);
1636 // This is currently guaranteed by checks in StoreIC::Store. 1633 // This is currently guaranteed by checks in StoreIC::Store.
1637 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1634 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1638 1635
1639 Handle<JSObject> holder(lookup->holder()); 1636 Handle<JSObject> holder(lookup->holder());
1640 StoreStubCompiler compiler(isolate(), strict_mode(), kind()); 1637 // Handlers do not use strict mode.
1638 StoreStubCompiler compiler(isolate(), kNonStrictMode, kind());
1641 switch (lookup->type()) { 1639 switch (lookup->type()) {
1642 case FIELD: 1640 case FIELD:
1643 return compiler.CompileStoreField(receiver, lookup, name); 1641 return compiler.CompileStoreField(receiver, lookup, name);
1644 case TRANSITION: { 1642 case TRANSITION: {
1645 // Explicitly pass in the receiver map since LookupForWrite may have 1643 // Explicitly pass in the receiver map since LookupForWrite may have
1646 // stored something else than the receiver in the holder. 1644 // stored something else than the receiver in the holder.
1647 Handle<Map> transition( 1645 Handle<Map> transition(
1648 lookup->GetTransitionTarget(receiver->map()), isolate()); 1646 lookup->GetTransitionTarget(receiver->map()), isolate());
1649 int descriptor = transition->LastAdded(); 1647 int descriptor = transition->LastAdded();
1650 1648
1651 DescriptorArray* target_descriptors = transition->instance_descriptors(); 1649 DescriptorArray* target_descriptors = transition->instance_descriptors();
1652 PropertyDetails details = target_descriptors->GetDetails(descriptor); 1650 PropertyDetails details = target_descriptors->GetDetails(descriptor);
1653 1651
1654 if (details.type() == CALLBACKS || details.attributes() != NONE) break; 1652 if (details.type() == CALLBACKS || details.attributes() != NONE) break;
1655 1653
1656 return compiler.CompileStoreTransition( 1654 return compiler.CompileStoreTransition(
1657 receiver, lookup, transition, name); 1655 receiver, lookup, transition, name);
1658 } 1656 }
1659 case NORMAL: 1657 case NORMAL:
1660 if (kind() == Code::KEYED_STORE_IC) break; 1658 if (kind() == Code::KEYED_STORE_IC) break;
1661 if (receiver->IsGlobalObject()) { 1659 if (receiver->IsGlobalObject()) {
1662 // The stub generated for the global object picks the value directly 1660 // The stub generated for the global object picks the value directly
1663 // from the property cell. So the property must be directly on the 1661 // from the property cell. So the property must be directly on the
1664 // global object. 1662 // global object.
1665 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 1663 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
1666 Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate()); 1664 Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
1667 Handle<Type> union_type = PropertyCell::UpdatedType(cell, value); 1665 Handle<Type> union_type = PropertyCell::UpdatedType(cell, value);
1668 StoreGlobalStub stub(strict_mode(), union_type->IsConstant()); 1666 StoreGlobalStub stub(union_type->IsConstant());
1669 1667
1670 Handle<Code> code = stub.GetCodeCopyFromTemplate( 1668 Handle<Code> code = stub.GetCodeCopyFromTemplate(
1671 isolate(), receiver->map(), *cell); 1669 isolate(), receiver->map(), *cell);
1672 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 1670 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1673 HeapObject::UpdateMapCodeCache(receiver, name, code); 1671 HeapObject::UpdateMapCodeCache(receiver, name, code);
1674 return code; 1672 return code;
1675 } 1673 }
1676 ASSERT(holder.is_identical_to(receiver)); 1674 ASSERT(holder.is_identical_to(receiver));
1677 return strict_mode() == kStrictMode 1675 return isolate()->builtins()->StoreIC_Normal();
1678 ? isolate()->builtins()->StoreIC_Normal_Strict()
1679 : isolate()->builtins()->StoreIC_Normal();
1680 case CALLBACKS: { 1676 case CALLBACKS: {
1681 if (kind() == Code::KEYED_STORE_IC) break; 1677 if (kind() == Code::KEYED_STORE_IC) break;
1682 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); 1678 Handle<Object> callback(lookup->GetCallbackObject(), isolate());
1683 if (callback->IsExecutableAccessorInfo()) { 1679 if (callback->IsExecutableAccessorInfo()) {
1684 Handle<ExecutableAccessorInfo> info = 1680 Handle<ExecutableAccessorInfo> info =
1685 Handle<ExecutableAccessorInfo>::cast(callback); 1681 Handle<ExecutableAccessorInfo>::cast(callback);
1686 if (v8::ToCData<Address>(info->setter()) == 0) break; 1682 if (v8::ToCData<Address>(info->setter()) == 0) break;
1687 if (!holder->HasFastProperties()) break; 1683 if (!holder->HasFastProperties()) break;
1688 if (!info->IsCompatibleReceiver(*receiver)) break; 1684 if (!info->IsCompatibleReceiver(*receiver)) break;
1689 return compiler.CompileStoreCallback(receiver, holder, name, info); 1685 return compiler.CompileStoreCallback(receiver, holder, name, info);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 // stores into properties in dictionary mode), then there will be not 1747 // stores into properties in dictionary mode), then there will be not
1752 // receiver maps in the target. 1748 // receiver maps in the target.
1753 return generic_stub(); 1749 return generic_stub();
1754 } 1750 }
1755 1751
1756 // There are several special cases where an IC that is MONOMORPHIC can still 1752 // There are several special cases where an IC that is MONOMORPHIC can still
1757 // transition to a different GetNonTransitioningStoreMode IC that handles a 1753 // transition to a different GetNonTransitioningStoreMode IC that handles a
1758 // superset of the original IC. Handle those here if the receiver map hasn't 1754 // superset of the original IC. Handle those here if the receiver map hasn't
1759 // changed or it has transitioned to a more general kind. 1755 // changed or it has transitioned to a more general kind.
1760 KeyedAccessStoreMode old_store_mode = 1756 KeyedAccessStoreMode old_store_mode =
1761 Code::GetKeyedAccessStoreMode(target()->extra_ic_state()); 1757 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state());
1762 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); 1758 Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
1763 if (state() == MONOMORPHIC) { 1759 if (state() == MONOMORPHIC) {
1764 // If the "old" and "new" maps are in the same elements map family, stay 1760 // If the "old" and "new" maps are in the same elements map family, stay
1765 // MONOMORPHIC and use the map for the most generic ElementsKind. 1761 // MONOMORPHIC and use the map for the most generic ElementsKind.
1766 Handle<Map> transitioned_receiver_map = receiver_map; 1762 Handle<Map> transitioned_receiver_map = receiver_map;
1767 if (IsTransitionStoreMode(store_mode)) { 1763 if (IsTransitionStoreMode(store_mode)) {
1768 transitioned_receiver_map = 1764 transitioned_receiver_map =
1769 ComputeTransitionedMap(receiver, store_mode); 1765 ComputeTransitionedMap(receiver, store_mode);
1770 } 1766 }
1771 if (IsTransitionOfMonomorphicTarget(MapToType(transitioned_receiver_map))) { 1767 if (IsTransitionOfMonomorphicTarget(MapToType(transitioned_receiver_map))) {
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
2342 case NUMBER: return "Number"; 2338 case NUMBER: return "Number";
2343 case ODDBALL: return "Oddball"; 2339 case ODDBALL: return "Oddball";
2344 case STRING: return "String"; 2340 case STRING: return "String";
2345 case GENERIC: return "Generic"; 2341 case GENERIC: return "Generic";
2346 default: return "Invalid"; 2342 default: return "Invalid";
2347 } 2343 }
2348 } 2344 }
2349 2345
2350 2346
2351 MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) { 2347 MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) {
2352 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); 2348 ExtraICState extra_ic_state = target()->extended_extra_ic_state();
2353 BinaryOpStub stub(extra_ic_state); 2349 BinaryOpStub stub(extra_ic_state);
2354 2350
2355 Handle<Type> left_type = stub.GetLeftType(isolate()); 2351 Handle<Type> left_type = stub.GetLeftType(isolate());
2356 Handle<Type> right_type = stub.GetRightType(isolate()); 2352 Handle<Type> right_type = stub.GetRightType(isolate());
2357 bool smi_was_enabled = left_type->Maybe(Type::Smi()) && 2353 bool smi_was_enabled = left_type->Maybe(Type::Smi()) &&
2358 right_type->Maybe(Type::Smi()); 2354 right_type->Maybe(Type::Smi());
2359 2355
2360 Maybe<Handle<Object> > result = stub.Result(left, right, isolate()); 2356 Maybe<Handle<Object> > result = stub.Result(left, right, isolate());
2361 if (!result.has_value) return Failure::Exception(); 2357 if (!result.has_value) return Failure::Exception();
2362 2358
2363 #ifdef DEBUG
2364 if (FLAG_trace_ic) { 2359 if (FLAG_trace_ic) {
2365 char buffer[100]; 2360 char buffer[100];
2366 NoAllocationStringAllocator allocator(buffer, 2361 NoAllocationStringAllocator allocator(buffer,
2367 static_cast<unsigned>(sizeof(buffer))); 2362 static_cast<unsigned>(sizeof(buffer)));
2368 StringStream stream(&allocator); 2363 StringStream stream(&allocator);
2369 stream.Add("["); 2364 stream.Add("[");
2370 stub.PrintName(&stream); 2365 stub.PrintName(&stream);
2371 2366
2372 stub.UpdateStatus(left, right, result); 2367 stub.UpdateStatus(left, right, result);
2373 2368
2374 stream.Add(" => "); 2369 stream.Add(" => ");
2375 stub.PrintState(&stream); 2370 stub.PrintState(&stream);
2376 stream.Add(" "); 2371 stream.Add(" ");
2377 stream.OutputToStdOut(); 2372 stream.OutputToStdOut();
2378 PrintF(" @ %p <- ", static_cast<void*>(*stub.GetCode(isolate()))); 2373 PrintF(" @ %p <- ", static_cast<void*>(*stub.GetCode(isolate())));
2379 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 2374 JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
2380 PrintF("]\n"); 2375 PrintF("]\n");
2381 } else { 2376 } else {
2382 stub.UpdateStatus(left, right, result); 2377 stub.UpdateStatus(left, right, result);
2383 } 2378 }
2384 #else
2385 stub.UpdateStatus(left, right, result);
2386 #endif
2387 2379
2388 Handle<Code> code = stub.GetCode(isolate()); 2380 Handle<Code> code = stub.GetCode(isolate());
2389 set_target(*code); 2381 set_target(*code);
2390 2382
2391 left_type = stub.GetLeftType(isolate()); 2383 left_type = stub.GetLeftType(isolate());
2392 right_type = stub.GetRightType(isolate()); 2384 right_type = stub.GetRightType(isolate());
2393 bool enable_smi = left_type->Maybe(Type::Smi()) && 2385 bool enable_smi = left_type->Maybe(Type::Smi()) &&
2394 right_type->Maybe(Type::Smi()); 2386 right_type->Maybe(Type::Smi());
2395 2387
2396 if (!smi_was_enabled && enable_smi) { 2388 if (!smi_was_enabled && enable_smi) {
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 State state = TargetState(previous_state, previous_left, previous_right, 2597 State state = TargetState(previous_state, previous_left, previous_right,
2606 HasInlinedSmiCode(address()), x, y); 2598 HasInlinedSmiCode(address()), x, y);
2607 ICCompareStub stub(op_, new_left, new_right, state); 2599 ICCompareStub stub(op_, new_left, new_right, state);
2608 if (state == KNOWN_OBJECT) { 2600 if (state == KNOWN_OBJECT) {
2609 stub.set_known_map( 2601 stub.set_known_map(
2610 Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate())); 2602 Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate()));
2611 } 2603 }
2612 Handle<Code> new_target = stub.GetCode(isolate()); 2604 Handle<Code> new_target = stub.GetCode(isolate());
2613 set_target(*new_target); 2605 set_target(*new_target);
2614 2606
2615 #ifdef DEBUG
2616 if (FLAG_trace_ic) { 2607 if (FLAG_trace_ic) {
2617 PrintF("[CompareIC in "); 2608 PrintF("[CompareIC in ");
2618 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 2609 JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
2619 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", 2610 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n",
2620 GetStateName(previous_left), 2611 GetStateName(previous_left),
2621 GetStateName(previous_right), 2612 GetStateName(previous_right),
2622 GetStateName(previous_state), 2613 GetStateName(previous_state),
2623 GetStateName(new_left), 2614 GetStateName(new_left),
2624 GetStateName(new_right), 2615 GetStateName(new_right),
2625 GetStateName(state), 2616 GetStateName(state),
2626 Token::Name(op_), 2617 Token::Name(op_),
2627 static_cast<void*>(*stub.GetCode(isolate()))); 2618 static_cast<void*>(*stub.GetCode(isolate())));
2628 } 2619 }
2629 #endif
2630 2620
2631 // Activate inlined smi code. 2621 // Activate inlined smi code.
2632 if (previous_state == UNINITIALIZED) { 2622 if (previous_state == UNINITIALIZED) {
2633 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); 2623 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
2634 } 2624 }
2635 2625
2636 return *new_target; 2626 return *new_target;
2637 } 2627 }
2638 2628
2639 2629
2640 // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc. 2630 // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc.
2641 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { 2631 RUNTIME_FUNCTION(Code*, CompareIC_Miss) {
2642 HandleScope scope(isolate); 2632 HandleScope scope(isolate);
2643 ASSERT(args.length() == 3); 2633 ASSERT(args.length() == 3);
2644 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); 2634 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2)));
2645 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); 2635 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1));
2646 } 2636 }
2647 2637
2648 2638
2649 void CompareNilIC::Clear(Address address, Code* target) { 2639 void CompareNilIC::Clear(Address address, Code* target) {
2650 if (IsCleared(target)) return; 2640 if (IsCleared(target)) return;
2651 Code::ExtraICState state = target->extended_extra_ic_state(); 2641 ExtraICState state = target->extended_extra_ic_state();
2652 2642
2653 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); 2643 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED);
2654 stub.ClearState(); 2644 stub.ClearState();
2655 2645
2656 Code* code = NULL; 2646 Code* code = NULL;
2657 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); 2647 CHECK(stub.FindCodeInCache(&code, target->GetIsolate()));
2658 2648
2659 SetTargetAtAddress(address, code); 2649 SetTargetAtAddress(address, code);
2660 } 2650 }
2661 2651
2662 2652
2663 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil, 2653 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil,
2664 Handle<Object> object) { 2654 Handle<Object> object) {
2665 if (object->IsNull() || object->IsUndefined()) { 2655 if (object->IsNull() || object->IsUndefined()) {
2666 return Smi::FromInt(true); 2656 return Smi::FromInt(true);
2667 } 2657 }
2668 return Smi::FromInt(object->IsUndetectableObject()); 2658 return Smi::FromInt(object->IsUndetectableObject());
2669 } 2659 }
2670 2660
2671 2661
2672 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { 2662 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) {
2673 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); 2663 ExtraICState extra_ic_state = target()->extended_extra_ic_state();
2674 2664
2675 CompareNilICStub stub(extra_ic_state); 2665 CompareNilICStub stub(extra_ic_state);
2676 2666
2677 // Extract the current supported types from the patched IC and calculate what 2667 // Extract the current supported types from the patched IC and calculate what
2678 // types must be supported as a result of the miss. 2668 // types must be supported as a result of the miss.
2679 bool already_monomorphic = stub.IsMonomorphic(); 2669 bool already_monomorphic = stub.IsMonomorphic();
2680 2670
2681 stub.UpdateStatus(object); 2671 stub.UpdateStatus(object);
2682 2672
2683 NilValue nil = stub.GetNilValue(); 2673 NilValue nil = stub.GetNilValue();
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
2778 #undef ADDR 2768 #undef ADDR
2779 }; 2769 };
2780 2770
2781 2771
2782 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2772 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2783 return IC_utilities[id]; 2773 return IC_utilities[id];
2784 } 2774 }
2785 2775
2786 2776
2787 } } // namespace v8::internal 2777 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698