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

Side by Side Diff: src/ic.cc

Issue 149133004: A64: Synchronize with r17807. (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 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 if (object->IsUndefined() || object->IsNull()) { 797 if (object->IsUndefined() || object->IsNull()) {
798 return TypeError("non_object_property_call", object, key); 798 return TypeError("non_object_property_call", object, key);
799 } 799 }
800 800
801 bool use_ic = MigrateDeprecated(object) 801 bool use_ic = MigrateDeprecated(object)
802 ? false : FLAG_use_ic && !object->IsAccessCheckNeeded(); 802 ? false : FLAG_use_ic && !object->IsAccessCheckNeeded();
803 803
804 if (use_ic && state() != MEGAMORPHIC) { 804 if (use_ic && state() != MEGAMORPHIC) {
805 ASSERT(!object->IsJSGlobalProxy()); 805 ASSERT(!object->IsJSGlobalProxy());
806 int argc = target()->arguments_count(); 806 int argc = target()->arguments_count();
807 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic( 807 Handle<Code> stub;
808 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); 808
809 if (object->IsJSObject()) { 809 // Use the KeyedArrayCallStub if the call is of the form array[smi](...),
810 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 810 // where array is an instance of one of the initial array maps (without
811 if (receiver->elements()->map() == 811 // extra named properties).
812 isolate()->heap()->non_strict_arguments_elements_map()) { 812 // TODO(verwaest): Also support keyed calls on instances of other maps.
813 stub = isolate()->stub_cache()->ComputeCallArguments(argc); 813 if (object->IsJSArray() && key->IsSmi()) {
814 Handle<JSArray> array = Handle<JSArray>::cast(object);
815 ElementsKind kind = array->map()->elements_kind();
816 if (IsFastObjectElementsKind(kind) &&
817 array->map() == isolate()->get_initial_js_array_map(kind)) {
818 KeyedArrayCallStub stub_gen(IsHoleyElementsKind(kind), argc);
819 stub = stub_gen.GetCode(isolate());
814 } 820 }
815 } 821 }
816 ASSERT(!stub.is_null()); 822
823 if (stub.is_null()) {
824 stub = isolate()->stub_cache()->ComputeCallMegamorphic(
825 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
826 if (object->IsJSObject()) {
827 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
828 if (receiver->elements()->map() ==
829 isolate()->heap()->non_strict_arguments_elements_map()) {
830 stub = isolate()->stub_cache()->ComputeCallArguments(argc);
831 }
832 }
833 ASSERT(!stub.is_null());
834 }
817 set_target(*stub); 835 set_target(*stub);
818 TRACE_IC("CallIC", key); 836 TRACE_IC("CallIC", key);
819 } 837 }
820 838
821 Handle<Object> result = GetProperty(isolate(), object, key); 839 Handle<Object> result = GetProperty(isolate(), object, key);
822 RETURN_IF_EMPTY_HANDLE(isolate(), result); 840 RETURN_IF_EMPTY_HANDLE(isolate(), result);
823 841
824 // Make receiver an object if the callee requires it. Strict mode or builtin 842 // Make receiver an object if the callee requires it. Strict mode or builtin
825 // functions do not wrap the receiver, non-strict functions and objects 843 // functions do not wrap the receiver, non-strict functions and objects
826 // called as functions do. 844 // called as functions do.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 if (!receiver_maps->at(current).is_null() && 960 if (!receiver_maps->at(current).is_null() &&
943 receiver_maps->at(current).is_identical_to(new_receiver_map)) { 961 receiver_maps->at(current).is_identical_to(new_receiver_map)) {
944 return false; 962 return false;
945 } 963 }
946 } 964 }
947 receiver_maps->Add(new_receiver_map); 965 receiver_maps->Add(new_receiver_map);
948 return true; 966 return true;
949 } 967 }
950 968
951 969
952 bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver, 970 bool IC::UpdatePolymorphicIC(Handle<Object> receiver,
953 Handle<String> name, 971 Handle<String> name,
954 Handle<Code> code) { 972 Handle<Code> code) {
955 if (!code->is_handler()) return false; 973 if (!code->is_handler()) return false;
956 MapHandleList receiver_maps; 974 MapHandleList receiver_maps;
957 CodeHandleList handlers; 975 CodeHandleList handlers;
958 976
959 int number_of_valid_maps; 977 int number_of_valid_maps;
960 int handler_to_overwrite = -1; 978 int handler_to_overwrite = -1;
961 Handle<Map> new_receiver_map(receiver->map()); 979 Handle<Map> new_receiver_map(receiver->GetMarkerMap(isolate()));
962 980
963 target()->FindAllMaps(&receiver_maps); 981 target()->FindAllMaps(&receiver_maps);
964 int number_of_maps = receiver_maps.length(); 982 int number_of_maps = receiver_maps.length();
965 number_of_valid_maps = number_of_maps; 983 number_of_valid_maps = number_of_maps;
966 984
967 for (int i = 0; i < number_of_maps; i++) { 985 for (int i = 0; i < number_of_maps; i++) {
968 Handle<Map> map = receiver_maps.at(i); 986 Handle<Map> map = receiver_maps.at(i);
969 // Filter out deprecated maps to ensure its instances get migrated. 987 // Filter out deprecated maps to ensure its instances get migrated.
970 if (map->is_deprecated()) { 988 if (map->is_deprecated()) {
971 number_of_valid_maps--; 989 number_of_valid_maps--;
(...skipping 21 matching lines...) Expand all
993 handlers.Add(code); 1011 handlers.Add(code);
994 } 1012 }
995 1013
996 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( 1014 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
997 &receiver_maps, &handlers, number_of_valid_maps, name, strict_mode()); 1015 &receiver_maps, &handlers, number_of_valid_maps, name, strict_mode());
998 set_target(*ic); 1016 set_target(*ic);
999 return true; 1017 return true;
1000 } 1018 }
1001 1019
1002 1020
1003 void IC::UpdateMonomorphicIC(Handle<HeapObject> receiver, 1021 void IC::UpdateMonomorphicIC(Handle<Object> receiver,
1004 Handle<Code> handler, 1022 Handle<Code> handler,
1005 Handle<String> name) { 1023 Handle<String> name) {
1006 if (!handler->is_handler()) return set_target(*handler); 1024 if (!handler->is_handler()) return set_target(*handler);
1007 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( 1025 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC(
1008 receiver, handler, name, strict_mode()); 1026 name, receiver, handler, strict_mode());
1009 set_target(*ic); 1027 set_target(*ic);
1010 } 1028 }
1011 1029
1012 1030
1013 void IC::CopyICToMegamorphicCache(Handle<String> name) { 1031 void IC::CopyICToMegamorphicCache(Handle<String> name) {
1014 MapHandleList receiver_maps; 1032 MapHandleList receiver_maps;
1015 CodeHandleList handlers; 1033 CodeHandleList handlers;
1016 target()->FindAllMaps(&receiver_maps); 1034 target()->FindAllMaps(&receiver_maps);
1017 if (!target()->FindHandlers(&handlers, receiver_maps.length())) return; 1035 if (!target()->FindHandlers(&handlers, receiver_maps.length())) return;
1018 for (int i = 0; i < receiver_maps.length(); i++) { 1036 for (int i = 0; i < receiver_maps.length(); i++) {
1019 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i)); 1037 UpdateMegamorphicCache(*receiver_maps.at(i), *name, *handlers.at(i));
1020 } 1038 }
1021 } 1039 }
1022 1040
1023 1041
1024 bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) { 1042 bool IC::IsTransitionedMapOfMonomorphicTarget(Map* receiver_map) {
1025 Map* current_map = target()->FindFirstMap(); 1043 Map* current_map = target()->FindFirstMap();
1026 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); 1044 ElementsKind receiver_elements_kind = receiver_map->elements_kind();
1027 bool more_general_transition = 1045 bool more_general_transition =
1028 IsMoreGeneralElementsKindTransition( 1046 IsMoreGeneralElementsKindTransition(
1029 current_map->elements_kind(), receiver_elements_kind); 1047 current_map->elements_kind(), receiver_elements_kind);
1030 Map* transitioned_map = more_general_transition 1048 Map* transitioned_map = more_general_transition
1031 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) 1049 ? current_map->LookupElementsTransitionMap(receiver_elements_kind)
1032 : NULL; 1050 : NULL;
1033 1051
1034 return transitioned_map == receiver_map; 1052 return transitioned_map == receiver_map;
1035 } 1053 }
1036 1054
1037 1055
1038 void IC::PatchCache(Handle<HeapObject> receiver, 1056 void IC::PatchCache(Handle<Object> object,
1039 Handle<String> name, 1057 Handle<String> name,
1040 Handle<Code> code) { 1058 Handle<Code> code) {
1041 switch (state()) { 1059 switch (state()) {
1042 case UNINITIALIZED: 1060 case UNINITIALIZED:
1043 case PREMONOMORPHIC: 1061 case PREMONOMORPHIC:
1044 case MONOMORPHIC_PROTOTYPE_FAILURE: 1062 case MONOMORPHIC_PROTOTYPE_FAILURE:
1045 UpdateMonomorphicIC(receiver, code, name); 1063 UpdateMonomorphicIC(object, code, name);
1046 break; 1064 break;
1047 case MONOMORPHIC: 1065 case MONOMORPHIC: {
1048 // For now, call stubs are allowed to rewrite to the same stub. This 1066 // For now, call stubs are allowed to rewrite to the same stub. This
1049 // happens e.g., when the field does not contain a function. 1067 // happens e.g., when the field does not contain a function.
1050 ASSERT(target()->is_call_stub() || 1068 ASSERT(target()->is_call_stub() ||
1051 target()->is_keyed_call_stub() || 1069 target()->is_keyed_call_stub() ||
1052 !target().is_identical_to(code)); 1070 !target().is_identical_to(code));
1053 if (!target()->is_keyed_stub()) { 1071 Code* old_handler = target()->FindFirstHandler();
1054 bool is_same_handler = false; 1072 if (old_handler == *code &&
1055 Code* old_handler = target()->FindFirstHandler(); 1073 IsTransitionedMapOfMonomorphicTarget(
1056 is_same_handler = old_handler == *code; 1074 object->GetMarkerMap(isolate()))) {
1057 1075 UpdateMonomorphicIC(object, code, name);
1058 if (is_same_handler && 1076 break;
1059 IsTransitionedMapOfMonomorphicTarget(receiver->map())) {
1060 UpdateMonomorphicIC(receiver, code, name);
1061 break;
1062 }
1063 } 1077 }
1064 // Fall through. 1078 // Fall through.
1079 }
1065 case POLYMORPHIC: 1080 case POLYMORPHIC:
1066 if (!target()->is_keyed_stub()) { 1081 if (!target()->is_keyed_stub()) {
1067 if (UpdatePolymorphicIC(receiver, name, code)) break; 1082 if (UpdatePolymorphicIC(object, name, code)) break;
1068 CopyICToMegamorphicCache(name); 1083 CopyICToMegamorphicCache(name);
1069 } 1084 }
1070 set_target(*megamorphic_stub()); 1085 set_target(*megamorphic_stub());
1071 // Fall through. 1086 // Fall through.
1072 case MEGAMORPHIC: 1087 case MEGAMORPHIC:
1073 UpdateMegamorphicCache(receiver->map(), *name, *code); 1088 UpdateMegamorphicCache(object->GetMarkerMap(isolate()), *name, *code);
1074 break; 1089 break;
1075 case DEBUG_STUB: 1090 case DEBUG_STUB:
1076 break; 1091 break;
1077 case GENERIC: 1092 case GENERIC:
1078 UNREACHABLE(); 1093 UNREACHABLE();
1079 break; 1094 break;
1080 } 1095 }
1081 } 1096 }
1082 1097
1083 1098
1084 Handle<Code> LoadIC::SimpleFieldLoad(int offset, 1099 Handle<Code> LoadIC::SimpleFieldLoad(int offset,
1085 bool inobject, 1100 bool inobject,
1086 Representation representation) { 1101 Representation representation) {
1087 if (kind() == Code::LOAD_IC) { 1102 if (kind() == Code::LOAD_IC) {
1088 LoadFieldStub stub(inobject, offset, representation); 1103 LoadFieldStub stub(inobject, offset, representation);
1089 return stub.GetCode(isolate()); 1104 return stub.GetCode(isolate());
1090 } else { 1105 } else {
1091 KeyedLoadFieldStub stub(inobject, offset, representation); 1106 KeyedLoadFieldStub stub(inobject, offset, representation);
1092 return stub.GetCode(isolate()); 1107 return stub.GetCode(isolate());
1093 } 1108 }
1094 } 1109 }
1095 1110
1096 1111
1097 void LoadIC::UpdateCaches(LookupResult* lookup, 1112 void LoadIC::UpdateCaches(LookupResult* lookup,
1098 Handle<Object> object, 1113 Handle<Object> object,
1099 Handle<String> name) { 1114 Handle<String> name) {
1100 // TODO(verwaest): It would be nice to support loading fields from smis as
1101 // well. For now just fail to update the cache.
1102 if (!object->IsHeapObject()) return;
1103
1104 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
1105
1106 Handle<Code> code;
1107 if (state() == UNINITIALIZED) { 1115 if (state() == UNINITIALIZED) {
1108 // This is the first time we execute this inline cache. 1116 // This is the first time we execute this inline cache.
1109 // Set the target to the pre monomorphic stub to delay 1117 // Set the target to the pre monomorphic stub to delay
1110 // setting the monomorphic state. 1118 // setting the monomorphic state.
1111 set_target(*pre_monomorphic_stub()); 1119 set_target(*pre_monomorphic_stub());
1112 TRACE_IC("LoadIC", name); 1120 TRACE_IC("LoadIC", name);
1113 return; 1121 return;
1114 } else if (!lookup->IsCacheable()) { 1122 }
1123
1124 Handle<Code> code;
1125 if (!lookup->IsCacheable()) {
1115 // Bail out if the result is not cacheable. 1126 // Bail out if the result is not cacheable.
1116 code = slow_stub(); 1127 code = slow_stub();
1117 } else if (object->IsString() &&
1118 name->Equals(isolate()->heap()->length_string())) {
1119 int length_index = String::kLengthOffset / kPointerSize;
1120 code = SimpleFieldLoad(length_index);
1121 } else if (!object->IsJSObject()) {
1122 // TODO(jkummerow): It would be nice to support non-JSObjects in
1123 // ComputeLoadHandler, then we wouldn't need to go generic here.
1124 code = slow_stub();
1125 } else if (!lookup->IsProperty()) { 1128 } else if (!lookup->IsProperty()) {
1126 code = kind() == Code::LOAD_IC 1129 if (kind() == Code::LOAD_IC) {
1127 ? isolate()->stub_cache()->ComputeLoadNonexistent( 1130 code = isolate()->stub_cache()->ComputeLoadNonexistent(name, object);
1128 name, Handle<JSObject>::cast(receiver)) 1131 } else {
1129 : slow_stub(); 1132 code = slow_stub();
1133 }
1130 } else { 1134 } else {
1131 code = ComputeHandler(lookup, Handle<JSObject>::cast(receiver), name); 1135 code = ComputeHandler(lookup, object, name);
1132 } 1136 }
1133 1137
1134 PatchCache(receiver, name, code); 1138 PatchCache(object, name, code);
1135 TRACE_IC("LoadIC", name); 1139 TRACE_IC("LoadIC", name);
1136 } 1140 }
1137 1141
1138 1142
1139 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { 1143 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) {
1140 // Cache code holding map should be consistent with 1144 // Cache code holding map should be consistent with
1141 // GenerateMonomorphicCacheProbe. 1145 // GenerateMonomorphicCacheProbe.
1142 isolate()->stub_cache()->Set(name, map, code); 1146 isolate()->stub_cache()->Set(name, map, code);
1143 } 1147 }
1144 1148
1145 1149
1146 Handle<Code> IC::ComputeHandler(LookupResult* lookup, 1150 Handle<Code> IC::ComputeHandler(LookupResult* lookup,
1147 Handle<JSObject> receiver, 1151 Handle<Object> object,
1148 Handle<String> name, 1152 Handle<String> name,
1149 Handle<Object> value) { 1153 Handle<Object> value) {
1154 InlineCacheHolderFlag cache_holder = GetCodeCacheForObject(*object);
1155 Handle<HeapObject> stub_holder(GetCodeCacheHolder(
1156 isolate(), *object, cache_holder));
1157
1150 Handle<Code> code = isolate()->stub_cache()->FindHandler( 1158 Handle<Code> code = isolate()->stub_cache()->FindHandler(
1151 name, receiver, kind()); 1159 name, stub_holder, kind(), cache_holder, strict_mode());
1152 if (!code.is_null()) return code; 1160 if (!code.is_null()) return code;
1153 1161
1154 code = CompileHandler(lookup, receiver, name, value); 1162 code = CompileHandler(lookup, object, name, value, cache_holder);
1155 ASSERT(code->is_handler()); 1163 ASSERT(code->is_handler());
1156 1164
1157 if (code->type() != Code::NORMAL) { 1165 if (code->type() != Code::NORMAL) {
1158 HeapObject::UpdateMapCodeCache(receiver, name, code); 1166 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
1159 } 1167 }
1160 1168
1161 return code; 1169 return code;
1162 } 1170 }
1163 1171
1164 1172
1165 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, 1173 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup,
1166 Handle<JSObject> receiver, 1174 Handle<Object> object,
1167 Handle<String> name, 1175 Handle<String> name,
1168 Handle<Object> unused) { 1176 Handle<Object> unused,
1177 InlineCacheHolderFlag cache_holder) {
1178 if (object->IsString() && name->Equals(isolate()->heap()->length_string())) {
1179 int length_index = String::kLengthOffset / kPointerSize;
1180 return SimpleFieldLoad(length_index);
1181 }
1182
1169 Handle<JSObject> holder(lookup->holder()); 1183 Handle<JSObject> holder(lookup->holder());
1170 LoadStubCompiler compiler(isolate(), kind()); 1184 LoadStubCompiler compiler(isolate(), cache_holder, kind());
1171 1185
1172 switch (lookup->type()) { 1186 switch (lookup->type()) {
1173 case FIELD: { 1187 case FIELD: {
1174 PropertyIndex field = lookup->GetFieldIndex(); 1188 PropertyIndex field = lookup->GetFieldIndex();
1175 if (receiver.is_identical_to(holder)) { 1189 if (object.is_identical_to(holder)) {
1176 return SimpleFieldLoad(field.translate(holder), 1190 return SimpleFieldLoad(field.translate(holder),
1177 field.is_inobject(holder), 1191 field.is_inobject(holder),
1178 lookup->representation()); 1192 lookup->representation());
1179 } 1193 }
1180 return compiler.CompileLoadField( 1194 return compiler.CompileLoadField(
1181 receiver, holder, name, field, lookup->representation()); 1195 object, holder, name, field, lookup->representation());
1182 } 1196 }
1183 case CONSTANT: { 1197 case CONSTANT: {
1184 Handle<Object> constant(lookup->GetConstant(), isolate()); 1198 Handle<Object> constant(lookup->GetConstant(), isolate());
1185 // TODO(2803): Don't compute a stub for cons strings because they cannot 1199 // TODO(2803): Don't compute a stub for cons strings because they cannot
1186 // be embedded into code. 1200 // be embedded into code.
1187 if (constant->IsConsString()) break; 1201 if (constant->IsConsString()) break;
1188 return compiler.CompileLoadConstant(receiver, holder, name, constant); 1202 return compiler.CompileLoadConstant(object, holder, name, constant);
1189 } 1203 }
1190 case NORMAL: 1204 case NORMAL:
1191 if (kind() != Code::LOAD_IC) break; 1205 if (kind() != Code::LOAD_IC) break;
1192 if (holder->IsGlobalObject()) { 1206 if (holder->IsGlobalObject()) {
1193 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); 1207 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
1194 Handle<PropertyCell> cell( 1208 Handle<PropertyCell> cell(
1195 global->GetPropertyCell(lookup), isolate()); 1209 global->GetPropertyCell(lookup), isolate());
1196 Handle<Code> code = compiler.CompileLoadGlobal( 1210 Handle<Code> code = compiler.CompileLoadGlobal(
1197 receiver, global, cell, name, lookup->IsDontDelete()); 1211 object, global, cell, name, lookup->IsDontDelete());
1198 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 1212 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1199 HeapObject::UpdateMapCodeCache(receiver, name, code); 1213 Handle<HeapObject> stub_holder(GetCodeCacheHolder(
1214 isolate(), *object, cache_holder));
1215 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
1200 return code; 1216 return code;
1201 } 1217 }
1202 // There is only one shared stub for loading normalized 1218 // There is only one shared stub for loading normalized
1203 // properties. It does not traverse the prototype chain, so the 1219 // properties. It does not traverse the prototype chain, so the
1204 // property must be found in the receiver for the stub to be 1220 // property must be found in the object for the stub to be
1205 // applicable. 1221 // applicable.
1206 if (!holder.is_identical_to(receiver)) break; 1222 if (!object.is_identical_to(holder)) break;
1207 return isolate()->builtins()->LoadIC_Normal(); 1223 return isolate()->builtins()->LoadIC_Normal();
1208 case CALLBACKS: { 1224 case CALLBACKS: {
1209 // Use simple field loads for some well-known callback properties. 1225 // Use simple field loads for some well-known callback properties.
1210 int object_offset; 1226 int object_offset;
1211 Handle<Map> map(receiver->map()); 1227 if (object->IsJSObject()) {
1212 if (Accessors::IsJSObjectFieldAccessor(map, name, &object_offset)) { 1228 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1213 PropertyIndex index = 1229 Handle<Map> map(receiver->map());
1214 PropertyIndex::NewHeaderIndex(object_offset / kPointerSize); 1230 if (Accessors::IsJSObjectFieldAccessor(map, name, &object_offset)) {
1215 return compiler.CompileLoadField( 1231 PropertyIndex index =
1216 receiver, receiver, name, index, Representation::Tagged()); 1232 PropertyIndex::NewHeaderIndex(object_offset / kPointerSize);
1233 return compiler.CompileLoadField(
1234 receiver, receiver, name, index, Representation::Tagged());
1235 }
1217 } 1236 }
1218 1237
1219 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); 1238 Handle<Object> callback(lookup->GetCallbackObject(), isolate());
1220 if (callback->IsExecutableAccessorInfo()) { 1239 if (callback->IsExecutableAccessorInfo()) {
1221 Handle<ExecutableAccessorInfo> info = 1240 Handle<ExecutableAccessorInfo> info =
1222 Handle<ExecutableAccessorInfo>::cast(callback); 1241 Handle<ExecutableAccessorInfo>::cast(callback);
1223 if (v8::ToCData<Address>(info->getter()) == 0) break; 1242 if (v8::ToCData<Address>(info->getter()) == 0) break;
1224 if (!info->IsCompatibleReceiver(*receiver)) break; 1243 if (!info->IsCompatibleReceiver(*object)) break;
1225 return compiler.CompileLoadCallback(receiver, holder, name, info); 1244 return compiler.CompileLoadCallback(object, holder, name, info);
1226 } else if (callback->IsAccessorPair()) { 1245 } else if (callback->IsAccessorPair()) {
1227 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(), 1246 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(),
1228 isolate()); 1247 isolate());
1229 if (!getter->IsJSFunction()) break; 1248 if (!getter->IsJSFunction()) break;
1230 if (holder->IsGlobalObject()) break; 1249 if (holder->IsGlobalObject()) break;
1231 if (!holder->HasFastProperties()) break; 1250 if (!holder->HasFastProperties()) break;
1232 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); 1251 Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
1252 if (!object->IsJSObject() &&
1253 !function->IsBuiltin() &&
1254 function->shared()->is_classic_mode()) {
1255 // Calling non-strict non-builtins with a value as the receiver
1256 // requires boxing.
1257 break;
1258 }
1233 CallOptimization call_optimization(function); 1259 CallOptimization call_optimization(function);
1234 if (call_optimization.is_simple_api_call() && 1260 if (call_optimization.is_simple_api_call() &&
1235 call_optimization.IsCompatibleReceiver(*receiver)) { 1261 call_optimization.IsCompatibleReceiver(*object)) {
1236 return compiler.CompileLoadCallback( 1262 return compiler.CompileLoadCallback(
1237 receiver, holder, name, call_optimization); 1263 object, holder, name, call_optimization);
1238 } 1264 }
1239 return compiler.CompileLoadViaGetter(receiver, holder, name, function); 1265 return compiler.CompileLoadViaGetter(object, holder, name, function);
1240 } 1266 }
1241 // TODO(dcarney): Handle correctly. 1267 // TODO(dcarney): Handle correctly.
1242 if (callback->IsDeclaredAccessorInfo()) break; 1268 if (callback->IsDeclaredAccessorInfo()) break;
1243 ASSERT(callback->IsForeign()); 1269 ASSERT(callback->IsForeign());
1244 // No IC support for old-style native accessors. 1270 // No IC support for old-style native accessors.
1245 break; 1271 break;
1246 } 1272 }
1247 case INTERCEPTOR: 1273 case INTERCEPTOR:
1248 ASSERT(HasInterceptorGetter(*holder)); 1274 ASSERT(HasInterceptorGetter(*holder));
1249 return compiler.CompileLoadInterceptor(receiver, holder, name); 1275 return compiler.CompileLoadInterceptor(object, holder, name);
1250 default: 1276 default:
1251 break; 1277 break;
1252 } 1278 }
1253 1279
1254 return slow_stub(); 1280 return slow_stub();
1255 } 1281 }
1256 1282
1257 1283
1258 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { 1284 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
1259 // This helper implements a few common fast cases for converting 1285 // This helper implements a few common fast cases for converting
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1357 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1332 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); 1358 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded");
1333 return generic_stub(); 1359 return generic_stub();
1334 } 1360 }
1335 1361
1336 return isolate()->stub_cache()->ComputeLoadElementPolymorphic( 1362 return isolate()->stub_cache()->ComputeLoadElementPolymorphic(
1337 &target_receiver_maps); 1363 &target_receiver_maps);
1338 } 1364 }
1339 1365
1340 1366
1341 MaybeObject* KeyedLoadIC::Load(Handle<Object> object, 1367 MaybeObject* KeyedLoadIC::LoadForceGeneric(Handle<Object> object,
1342 Handle<Object> key, 1368 Handle<Object> key) {
1343 ICMissMode miss_mode) { 1369 set_target(*generic_stub());
1370 return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
1371 }
1372
1373
1374 MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) {
1344 if (MigrateDeprecated(object)) { 1375 if (MigrateDeprecated(object)) {
1345 return Runtime::GetObjectPropertyOrFail(isolate(), object, key); 1376 return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
1346 } 1377 }
1347 1378
1348 MaybeObject* maybe_object = NULL; 1379 MaybeObject* maybe_object = NULL;
1349 Handle<Code> stub = generic_stub(); 1380 Handle<Code> stub = generic_stub();
1350 1381
1351 // Check for values that can be converted into an internalized string directly 1382 // Check for values that can be converted into an internalized string directly
1352 // or is representable as a smi. 1383 // or is representable as a smi.
1353 key = TryConvertKey(key, isolate()); 1384 key = TryConvertKey(key, isolate());
1354 1385
1355 if (key->IsInternalizedString()) { 1386 if (key->IsInternalizedString()) {
1356 maybe_object = LoadIC::Load(object, Handle<String>::cast(key)); 1387 maybe_object = LoadIC::Load(object, Handle<String>::cast(key));
1357 if (maybe_object->IsFailure()) return maybe_object; 1388 if (maybe_object->IsFailure()) return maybe_object;
1358 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { 1389 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
1359 ASSERT(!object->IsJSGlobalProxy()); 1390 ASSERT(!object->IsJSGlobalProxy());
1360 if (miss_mode != MISS_FORCE_GENERIC) { 1391 if (object->IsString() && key->IsNumber()) {
1361 if (object->IsString() && key->IsNumber()) { 1392 if (state() == UNINITIALIZED) stub = string_stub();
1362 if (state() == UNINITIALIZED) stub = string_stub(); 1393 } else if (object->IsJSObject()) {
1363 } else if (object->IsJSObject()) { 1394 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1364 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1395 if (receiver->elements()->map() ==
1365 if (receiver->elements()->map() == 1396 isolate()->heap()->non_strict_arguments_elements_map()) {
1366 isolate()->heap()->non_strict_arguments_elements_map()) { 1397 stub = non_strict_arguments_stub();
1367 stub = non_strict_arguments_stub(); 1398 } else if (receiver->HasIndexedInterceptor()) {
1368 } else if (receiver->HasIndexedInterceptor()) { 1399 stub = indexed_interceptor_stub();
1369 stub = indexed_interceptor_stub(); 1400 } else if (!key->ToSmi()->IsFailure() &&
1370 } else if (!key->ToSmi()->IsFailure() && 1401 (!target().is_identical_to(non_strict_arguments_stub()))) {
1371 (!target().is_identical_to(non_strict_arguments_stub()))) { 1402 stub = LoadElementStub(receiver);
1372 stub = LoadElementStub(receiver);
1373 }
1374 } 1403 }
1375 } 1404 }
1376 } 1405 }
1377 1406
1378 if (!is_target_set()) { 1407 if (!is_target_set()) {
1379 if (*stub == *generic_stub()) { 1408 if (*stub == *generic_stub()) {
1380 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic"); 1409 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
1381 } 1410 }
1382 ASSERT(!stub.is_null()); 1411 ASSERT(!stub.is_null());
1383 set_target(*stub); 1412 set_target(*stub);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 ASSERT(!lookup->IsHandler()); 1604 ASSERT(!lookup->IsHandler());
1576 1605
1577 Handle<Code> code = ComputeHandler(lookup, receiver, name, value); 1606 Handle<Code> code = ComputeHandler(lookup, receiver, name, value);
1578 1607
1579 PatchCache(receiver, name, code); 1608 PatchCache(receiver, name, code);
1580 TRACE_IC("StoreIC", name); 1609 TRACE_IC("StoreIC", name);
1581 } 1610 }
1582 1611
1583 1612
1584 Handle<Code> StoreIC::CompileHandler(LookupResult* lookup, 1613 Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
1585 Handle<JSObject> receiver, 1614 Handle<Object> object,
1586 Handle<String> name, 1615 Handle<String> name,
1587 Handle<Object> value) { 1616 Handle<Object> value,
1617 InlineCacheHolderFlag cache_holder) {
1618 ASSERT(cache_holder == OWN_MAP);
1619 // This is currently guaranteed by checks in StoreIC::Store.
1620 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1621
1588 Handle<JSObject> holder(lookup->holder()); 1622 Handle<JSObject> holder(lookup->holder());
1589 StoreStubCompiler compiler(isolate(), strict_mode(), kind()); 1623 StoreStubCompiler compiler(isolate(), strict_mode(), kind());
1590 switch (lookup->type()) { 1624 switch (lookup->type()) {
1591 case FIELD: 1625 case FIELD:
1592 return compiler.CompileStoreField(receiver, lookup, name); 1626 return compiler.CompileStoreField(receiver, lookup, name);
1593 case TRANSITION: { 1627 case TRANSITION: {
1594 // Explicitly pass in the receiver map since LookupForWrite may have 1628 // Explicitly pass in the receiver map since LookupForWrite may have
1595 // stored something else than the receiver in the holder. 1629 // stored something else than the receiver in the holder.
1596 Handle<Map> transition( 1630 Handle<Map> transition(
1597 lookup->GetTransitionTarget(receiver->map()), isolate()); 1631 lookup->GetTransitionTarget(receiver->map()), isolate());
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
1908 Heap* heap = receiver->GetHeap(); 1942 Heap* heap = receiver->GetHeap();
1909 if (receiver->elements()->map() == heap->fixed_cow_array_map()) { 1943 if (receiver->elements()->map() == heap->fixed_cow_array_map()) {
1910 return STORE_NO_TRANSITION_HANDLE_COW; 1944 return STORE_NO_TRANSITION_HANDLE_COW;
1911 } else { 1945 } else {
1912 return STANDARD_STORE; 1946 return STANDARD_STORE;
1913 } 1947 }
1914 } 1948 }
1915 } 1949 }
1916 1950
1917 1951
1952 MaybeObject* KeyedStoreIC::StoreForceGeneric(Handle<Object> object,
1953 Handle<Object> key,
1954 Handle<Object> value) {
1955 set_target(*generic_stub());
1956 Handle<Object> result = Runtime::SetObjectProperty(isolate(), object,
1957 key,
1958 value,
1959 NONE,
1960 strict_mode());
1961 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1962 return *result;
1963 }
1964
1965
1918 MaybeObject* KeyedStoreIC::Store(Handle<Object> object, 1966 MaybeObject* KeyedStoreIC::Store(Handle<Object> object,
1919 Handle<Object> key, 1967 Handle<Object> key,
1920 Handle<Object> value, 1968 Handle<Object> value) {
1921 ICMissMode miss_mode) {
1922 if (MigrateDeprecated(object)) { 1969 if (MigrateDeprecated(object)) {
1923 Handle<Object> result = Runtime::SetObjectProperty(isolate(), object, 1970 Handle<Object> result = Runtime::SetObjectProperty(isolate(), object,
1924 key, 1971 key,
1925 value, 1972 value,
1926 NONE, 1973 NONE,
1927 strict_mode()); 1974 strict_mode());
1928 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1975 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1929 return *result; 1976 return *result;
1930 } 1977 }
1931 1978
(...skipping 18 matching lines...) Expand all
1950 // Don't use ICs for maps of the objects in Array's prototype chain. We 1997 // Don't use ICs for maps of the objects in Array's prototype chain. We
1951 // expect to be able to trap element sets to objects with those maps in 1998 // expect to be able to trap element sets to objects with those maps in
1952 // the runtime to enable optimization of element hole access. 1999 // the runtime to enable optimization of element hole access.
1953 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); 2000 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
1954 if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false; 2001 if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false;
1955 } 2002 }
1956 2003
1957 if (use_ic) { 2004 if (use_ic) {
1958 ASSERT(!object->IsJSGlobalProxy()); 2005 ASSERT(!object->IsJSGlobalProxy());
1959 2006
1960 if (miss_mode != MISS_FORCE_GENERIC) { 2007 if (object->IsJSObject()) {
1961 if (object->IsJSObject()) { 2008 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1962 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 2009 bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure();
1963 bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure(); 2010 if (receiver->elements()->map() ==
1964 if (receiver->elements()->map() == 2011 isolate()->heap()->non_strict_arguments_elements_map()) {
1965 isolate()->heap()->non_strict_arguments_elements_map()) { 2012 stub = non_strict_arguments_stub();
1966 stub = non_strict_arguments_stub(); 2013 } else if (key_is_smi_like &&
1967 } else if (key_is_smi_like && 2014 !(target().is_identical_to(non_strict_arguments_stub()))) {
1968 !(target().is_identical_to(non_strict_arguments_stub()))) { 2015 // We should go generic if receiver isn't a dictionary, but our
1969 // We should go generic if receiver isn't a dictionary, but our 2016 // prototype chain does have dictionary elements. This ensures that
1970 // prototype chain does have dictionary elements. This ensures that 2017 // other non-dictionary receivers in the polymorphic case benefit
1971 // other non-dictionary receivers in the polymorphic case benefit 2018 // from fast path keyed stores.
1972 // from fast path keyed stores. 2019 if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) {
1973 if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) { 2020 KeyedAccessStoreMode store_mode =
1974 KeyedAccessStoreMode store_mode = 2021 GetStoreMode(receiver, key, value);
1975 GetStoreMode(receiver, key, value); 2022 stub = StoreElementStub(receiver, store_mode);
1976 stub = StoreElementStub(receiver, store_mode);
1977 }
1978 } 2023 }
1979 } 2024 }
1980 } 2025 }
1981 } 2026 }
1982 } 2027 }
1983 2028
1984 if (!is_target_set()) { 2029 if (!is_target_set()) {
1985 if (*stub == *generic_stub()) { 2030 if (*stub == *generic_stub()) {
1986 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); 2031 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
1987 } 2032 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 2111
2067 2112
2068 // Used from ic-<arch>.cc 2113 // Used from ic-<arch>.cc
2069 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { 2114 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) {
2070 HandleScope scope(isolate); 2115 HandleScope scope(isolate);
2071 ASSERT(args.length() == 2); 2116 ASSERT(args.length() == 2);
2072 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2117 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2073 Handle<Object> receiver = args.at<Object>(0); 2118 Handle<Object> receiver = args.at<Object>(0);
2074 Handle<Object> key = args.at<Object>(1); 2119 Handle<Object> key = args.at<Object>(1);
2075 ic.UpdateState(receiver, key); 2120 ic.UpdateState(receiver, key);
2076 return ic.Load(receiver, key, MISS); 2121 return ic.Load(receiver, key);
2077 } 2122 }
2078 2123
2079 2124
2080 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) { 2125 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) {
2081 HandleScope scope(isolate); 2126 HandleScope scope(isolate);
2082 ASSERT(args.length() == 2); 2127 ASSERT(args.length() == 2);
2083 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate); 2128 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
2084 Handle<Object> receiver = args.at<Object>(0); 2129 Handle<Object> receiver = args.at<Object>(0);
2085 Handle<Object> key = args.at<Object>(1); 2130 Handle<Object> key = args.at<Object>(1);
2086 ic.UpdateState(receiver, key); 2131 ic.UpdateState(receiver, key);
2087 return ic.Load(receiver, key, MISS); 2132 return ic.Load(receiver, key);
2088 } 2133 }
2089 2134
2090 2135
2091 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) { 2136 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) {
2092 HandleScope scope(isolate); 2137 HandleScope scope(isolate);
2093 ASSERT(args.length() == 2); 2138 ASSERT(args.length() == 2);
2094 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2139 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2095 Handle<Object> receiver = args.at<Object>(0); 2140 Handle<Object> receiver = args.at<Object>(0);
2096 Handle<Object> key = args.at<Object>(1); 2141 Handle<Object> key = args.at<Object>(1);
2097 ic.UpdateState(receiver, key); 2142 ic.UpdateState(receiver, key);
2098 return ic.Load(receiver, key, MISS_FORCE_GENERIC); 2143 return ic.LoadForceGeneric(receiver, key);
2099 } 2144 }
2100 2145
2101 2146
2102 // Used from ic-<arch>.cc. 2147 // Used from ic-<arch>.cc.
2103 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { 2148 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) {
2104 HandleScope scope(isolate); 2149 HandleScope scope(isolate);
2105 ASSERT(args.length() == 3); 2150 ASSERT(args.length() == 3);
2106 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2151 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2107 Handle<Object> receiver = args.at<Object>(0); 2152 Handle<Object> receiver = args.at<Object>(0);
2108 Handle<String> key = args.at<String>(1); 2153 Handle<String> key = args.at<String>(1);
2109 ic.UpdateState(receiver, key); 2154 ic.UpdateState(receiver, key);
2110 return ic.Store(receiver, key, args.at<Object>(2)); 2155 return ic.Store(receiver, key, args.at<Object>(2));
2111 } 2156 }
2112 2157
2113 2158
2114 RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { 2159 RUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) {
2115 HandleScope scope(isolate); 2160 HandleScope scope(isolate);
2116 ASSERT(args.length() == 3); 2161 ASSERT(args.length() == 3);
2117 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2162 StoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2118 Handle<Object> receiver = args.at<Object>(0); 2163 Handle<Object> receiver = args.at<Object>(0);
2119 Handle<String> key = args.at<String>(1); 2164 Handle<String> key = args.at<String>(1);
2120 ic.UpdateState(receiver, key); 2165 ic.UpdateState(receiver, key);
2121 return ic.Store(receiver, key, args.at<Object>(2)); 2166 return ic.Store(receiver, key, args.at<Object>(2));
2122 } 2167 }
2123 2168
2124 2169
2170 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure) {
2171 HandleScope scope(isolate);
2172 ASSERT(args.length() == 2);
2173 KeyedCallIC ic(isolate);
2174 Arguments* caller_args = reinterpret_cast<Arguments*>(args[0]);
2175 Handle<Object> key = args.at<Object>(1);
2176 Handle<Object> receiver((*caller_args)[0], isolate);
2177
2178 ic.UpdateState(receiver, key);
2179 MaybeObject* maybe_result = ic.LoadFunction(receiver, key);
2180 // Result could be a function or a failure.
2181 JSFunction* raw_function = NULL;
2182 if (!maybe_result->To(&raw_function)) return maybe_result;
2183
2184 if (raw_function->is_compiled()) return raw_function;
2185
2186 Handle<JSFunction> function(raw_function, isolate);
2187 JSFunction::CompileLazy(function, CLEAR_EXCEPTION);
2188 return *function;
2189 }
2190
2191
2125 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { 2192 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
2126 SealHandleScope shs(isolate); 2193 SealHandleScope shs(isolate);
2127 2194
2128 ASSERT(args.length() == 2); 2195 ASSERT(args.length() == 2);
2129 JSArray* receiver = JSArray::cast(args[0]); 2196 JSArray* receiver = JSArray::cast(args[0]);
2130 Object* len = args[1]; 2197 Object* len = args[1];
2131 2198
2132 // The generated code should filter out non-Smis before we get here. 2199 // The generated code should filter out non-Smis before we get here.
2133 ASSERT(len->IsSmi()); 2200 ASSERT(len->IsSmi());
2134 2201
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2197 2264
2198 2265
2199 // Used from ic-<arch>.cc. 2266 // Used from ic-<arch>.cc.
2200 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { 2267 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) {
2201 HandleScope scope(isolate); 2268 HandleScope scope(isolate);
2202 ASSERT(args.length() == 3); 2269 ASSERT(args.length() == 3);
2203 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2270 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2204 Handle<Object> receiver = args.at<Object>(0); 2271 Handle<Object> receiver = args.at<Object>(0);
2205 Handle<Object> key = args.at<Object>(1); 2272 Handle<Object> key = args.at<Object>(1);
2206 ic.UpdateState(receiver, key); 2273 ic.UpdateState(receiver, key);
2207 return ic.Store(receiver, key, args.at<Object>(2), MISS); 2274 return ic.Store(receiver, key, args.at<Object>(2));
2208 } 2275 }
2209 2276
2210 2277
2211 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) { 2278 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) {
2212 HandleScope scope(isolate); 2279 HandleScope scope(isolate);
2213 ASSERT(args.length() == 3); 2280 ASSERT(args.length() == 3);
2214 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2281 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2215 Handle<Object> receiver = args.at<Object>(0); 2282 Handle<Object> receiver = args.at<Object>(0);
2216 Handle<Object> key = args.at<Object>(1); 2283 Handle<Object> key = args.at<Object>(1);
2217 ic.UpdateState(receiver, key); 2284 ic.UpdateState(receiver, key);
2218 return ic.Store(receiver, key, args.at<Object>(2), MISS); 2285 return ic.Store(receiver, key, args.at<Object>(2));
2219 } 2286 }
2220 2287
2221 2288
2222 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) { 2289 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) {
2223 HandleScope scope(isolate); 2290 HandleScope scope(isolate);
2224 ASSERT(args.length() == 3); 2291 ASSERT(args.length() == 3);
2225 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2292 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2226 Handle<Object> object = args.at<Object>(0); 2293 Handle<Object> object = args.at<Object>(0);
2227 Handle<Object> key = args.at<Object>(1); 2294 Handle<Object> key = args.at<Object>(1);
2228 Handle<Object> value = args.at<Object>(2); 2295 Handle<Object> value = args.at<Object>(2);
(...skipping 24 matching lines...) Expand all
2253 } 2320 }
2254 2321
2255 2322
2256 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { 2323 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) {
2257 HandleScope scope(isolate); 2324 HandleScope scope(isolate);
2258 ASSERT(args.length() == 3); 2325 ASSERT(args.length() == 3);
2259 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2326 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2260 Handle<Object> receiver = args.at<Object>(0); 2327 Handle<Object> receiver = args.at<Object>(0);
2261 Handle<Object> key = args.at<Object>(1); 2328 Handle<Object> key = args.at<Object>(1);
2262 ic.UpdateState(receiver, key); 2329 ic.UpdateState(receiver, key);
2263 return ic.Store(receiver, key, args.at<Object>(2), MISS_FORCE_GENERIC); 2330 return ic.StoreForceGeneric(receiver, key, args.at<Object>(2));
2264 } 2331 }
2265 2332
2266 2333
2267 RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) { 2334 RUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) {
2268 HandleScope scope(isolate); 2335 HandleScope scope(isolate);
2269 ASSERT(args.length() == 4); 2336 ASSERT(args.length() == 4);
2270 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2337 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2271 Handle<Object> value = args.at<Object>(0); 2338 Handle<Object> value = args.at<Object>(0);
2272 Handle<Map> map = args.at<Map>(1); 2339 Handle<Map> map = args.at<Map>(1);
2273 Handle<Object> key = args.at<Object>(2); 2340 Handle<Object> key = args.at<Object>(2);
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
2540 case UNIQUE_NAME: 2607 case UNIQUE_NAME:
2541 case OBJECT: 2608 case OBJECT:
2542 case GENERIC: 2609 case GENERIC:
2543 return GENERIC; 2610 return GENERIC;
2544 } 2611 }
2545 UNREACHABLE(); 2612 UNREACHABLE();
2546 return GENERIC; // Make the compiler happy. 2613 return GENERIC; // Make the compiler happy.
2547 } 2614 }
2548 2615
2549 2616
2550 void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { 2617 Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
2551 HandleScope scope(isolate()); 2618 HandleScope scope(isolate());
2552 State previous_left, previous_right, previous_state; 2619 State previous_left, previous_right, previous_state;
2553 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, 2620 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left,
2554 &previous_right, &previous_state, NULL); 2621 &previous_right, &previous_state, NULL);
2555 State new_left = NewInputState(previous_left, x); 2622 State new_left = NewInputState(previous_left, x);
2556 State new_right = NewInputState(previous_right, y); 2623 State new_right = NewInputState(previous_right, y);
2557 State state = TargetState(previous_state, previous_left, previous_right, 2624 State state = TargetState(previous_state, previous_left, previous_right,
2558 HasInlinedSmiCode(address()), x, y); 2625 HasInlinedSmiCode(address()), x, y);
2559 ICCompareStub stub(op_, new_left, new_right, state); 2626 ICCompareStub stub(op_, new_left, new_right, state);
2560 if (state == KNOWN_OBJECT) { 2627 if (state == KNOWN_OBJECT) {
2561 stub.set_known_map( 2628 stub.set_known_map(
2562 Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate())); 2629 Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate()));
2563 } 2630 }
2564 set_target(*stub.GetCode(isolate())); 2631 Handle<Code> new_target = stub.GetCode(isolate());
2632 set_target(*new_target);
2565 2633
2566 #ifdef DEBUG 2634 #ifdef DEBUG
2567 if (FLAG_trace_ic) { 2635 if (FLAG_trace_ic) {
2568 PrintF("[CompareIC in "); 2636 PrintF("[CompareIC in ");
2569 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 2637 JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
2570 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", 2638 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n",
2571 GetStateName(previous_left), 2639 GetStateName(previous_left),
2572 GetStateName(previous_right), 2640 GetStateName(previous_right),
2573 GetStateName(previous_state), 2641 GetStateName(previous_state),
2574 GetStateName(new_left), 2642 GetStateName(new_left),
2575 GetStateName(new_right), 2643 GetStateName(new_right),
2576 GetStateName(state), 2644 GetStateName(state),
2577 Token::Name(op_), 2645 Token::Name(op_),
2578 static_cast<void*>(*stub.GetCode(isolate()))); 2646 static_cast<void*>(*stub.GetCode(isolate())));
2579 } 2647 }
2580 #endif 2648 #endif
2581 2649
2582 // Activate inlined smi code. 2650 // Activate inlined smi code.
2583 if (previous_state == UNINITIALIZED) { 2651 if (previous_state == UNINITIALIZED) {
2584 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); 2652 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
2585 } 2653 }
2654
2655 return *new_target;
2586 } 2656 }
2587 2657
2588 2658
2589 // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc. 2659 // Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc.
2590 RUNTIME_FUNCTION(Code*, CompareIC_Miss) { 2660 RUNTIME_FUNCTION(Code*, CompareIC_Miss) {
2591 HandleScope scope(isolate); 2661 HandleScope scope(isolate);
2592 ASSERT(args.length() == 3); 2662 ASSERT(args.length() == 3);
2593 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); 2663 CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2)));
2594 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); 2664 return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1));
2595 return ic.raw_target();
2596 } 2665 }
2597 2666
2598 2667
2599 void CompareNilIC::Clear(Address address, Code* target) { 2668 void CompareNilIC::Clear(Address address, Code* target) {
2600 if (IsCleared(target)) return; 2669 if (IsCleared(target)) return;
2601 Code::ExtraICState state = target->extended_extra_ic_state(); 2670 Code::ExtraICState state = target->extended_extra_ic_state();
2602 2671
2603 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); 2672 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED);
2604 stub.ClearState(); 2673 stub.ClearState();
2605 2674
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
2696 case Token::SHR: 2765 case Token::SHR:
2697 return Builtins::SHR; 2766 return Builtins::SHR;
2698 break; 2767 break;
2699 case Token::SHL: 2768 case Token::SHL:
2700 return Builtins::SHL; 2769 return Builtins::SHL;
2701 break; 2770 break;
2702 } 2771 }
2703 } 2772 }
2704 2773
2705 2774
2706 MaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object, 2775 MaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object) {
2707 Code::ExtraICState extra_ic_state) { 2776 ToBooleanStub stub(target()->extended_extra_ic_state());
2708 ToBooleanStub stub(extra_ic_state);
2709 bool to_boolean_value = stub.UpdateStatus(object); 2777 bool to_boolean_value = stub.UpdateStatus(object);
2710 Handle<Code> code = stub.GetCode(isolate()); 2778 Handle<Code> code = stub.GetCode(isolate());
2711 set_target(*code); 2779 set_target(*code);
2712 return Smi::FromInt(to_boolean_value ? 1 : 0); 2780 return Smi::FromInt(to_boolean_value ? 1 : 0);
2713 } 2781 }
2714 2782
2715 2783
2716 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { 2784 RUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) {
2717 ASSERT(args.length() == 1); 2785 ASSERT(args.length() == 1);
2718 HandleScope scope(isolate); 2786 HandleScope scope(isolate);
2719 Handle<Object> object = args.at<Object>(0); 2787 Handle<Object> object = args.at<Object>(0);
2720 ToBooleanIC ic(isolate); 2788 ToBooleanIC ic(isolate);
2721 Code::ExtraICState extra_ic_state = ic.target()->extended_extra_ic_state(); 2789 return ic.ToBoolean(object);
2722 return ic.ToBoolean(object, extra_ic_state);
2723 } 2790 }
2724 2791
2725 2792
2726 static const Address IC_utilities[] = { 2793 static const Address IC_utilities[] = {
2727 #define ADDR(name) FUNCTION_ADDR(name), 2794 #define ADDR(name) FUNCTION_ADDR(name),
2728 IC_UTIL_LIST(ADDR) 2795 IC_UTIL_LIST(ADDR)
2729 NULL 2796 NULL
2730 #undef ADDR 2797 #undef ADDR
2731 }; 2798 };
2732 2799
2733 2800
2734 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2801 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2735 return IC_utilities[id]; 2802 return IC_utilities[id];
2736 } 2803 }
2737 2804
2738 2805
2739 } } // namespace v8::internal 2806 } } // 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