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

Side by Side Diff: src/ic.cc

Issue 143633007: A64: Synchronize with r18764. (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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 if (proto->IsNull()) { 224 if (proto->IsNull()) {
225 ASSERT(!lookup->IsFound()); 225 ASSERT(!lookup->IsFound());
226 return; 226 return;
227 } 227 }
228 228
229 object = proto; 229 object = proto;
230 } 230 }
231 } 231 }
232 232
233 233
234 bool CallIC::TryUpdateExtraICState(LookupResult* lookup,
235 Handle<Object> object) {
236 if (!lookup->IsConstantFunction()) return false;
237 JSFunction* function = lookup->GetConstantFunction();
238 if (!function->shared()->HasBuiltinFunctionId()) return false;
239
240 // Fetch the arguments passed to the called function.
241 const int argc = target()->arguments_count();
242 Address entry = isolate()->c_entry_fp(isolate()->thread_local_top());
243 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
244 Arguments args(argc + 1,
245 &Memory::Object_at(fp +
246 StandardFrameConstants::kCallerSPOffset +
247 argc * kPointerSize));
248 switch (function->shared()->builtin_function_id()) {
249 case kStringCharCodeAt:
250 case kStringCharAt:
251 if (object->IsString()) {
252 String* string = String::cast(*object);
253 // Check there's the right string value or wrapper in the receiver slot.
254 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value());
255 // If we're in the default (fastest) state and the index is
256 // out of bounds, update the state to record this fact.
257 if (StringStubState::decode(extra_ic_state()) == DEFAULT_STRING_STUB &&
258 argc >= 1 && args[1]->IsNumber()) {
259 double index = DoubleToInteger(args.number_at(1));
260 if (index < 0 || index >= string->length()) {
261 set_extra_ic_state(StringStubState::update(extra_ic_state(),
262 STRING_INDEX_OUT_OF_BOUNDS));
263 return true;
264 }
265 }
266 }
267 break;
268 default:
269 return false;
270 }
271 return false;
272 }
273
274
275 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 234 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
276 Handle<String> name) { 235 Handle<String> name) {
277 if (target()->is_call_stub()) {
278 LookupResult lookup(isolate());
279 LookupForRead(receiver, name, &lookup);
280 if (static_cast<CallIC*>(this)->TryUpdateExtraICState(&lookup, receiver)) {
281 return true;
282 }
283 }
284
285 if (target()->is_keyed_stub()) { 236 if (target()->is_keyed_stub()) {
286 // Determine whether the failure is due to a name failure. 237 // Determine whether the failure is due to a name failure.
287 if (!name->IsName()) return false; 238 if (!name->IsName()) return false;
288 Name* stub_name = target()->FindFirstName(); 239 Name* stub_name = target()->FindFirstName();
289 if (*name != stub_name) return false; 240 if (*name != stub_name) return false;
290 } 241 }
291 242
292 InlineCacheHolderFlag cache_holder = 243 InlineCacheHolderFlag cache_holder =
293 Code::ExtractCacheHolderFromFlags(target()->flags()); 244 Code::ExtractCacheHolderFromFlags(target()->flags());
294 245
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 // Otherwise, it will fail in the lookup step. 570 // Otherwise, it will fail in the lookup step.
620 } 571 }
621 572
622 // Lookup the property in the object. 573 // Lookup the property in the object.
623 LookupResult lookup(isolate()); 574 LookupResult lookup(isolate());
624 LookupForRead(object, name, &lookup); 575 LookupForRead(object, name, &lookup);
625 576
626 if (!lookup.IsFound()) { 577 if (!lookup.IsFound()) {
627 // If the object does not have the requested property, check which 578 // If the object does not have the requested property, check which
628 // exception we need to throw. 579 // exception we need to throw.
629 return IsUndeclaredGlobal(object) 580 return object->IsGlobalObject()
630 ? ReferenceError("not_defined", name) 581 ? ReferenceError("not_defined", name)
631 : TypeError("undefined_method", object, name); 582 : TypeError("undefined_method", object, name);
632 } 583 }
633 584
634 // Lookup is valid: Update inline cache and stub cache. 585 // Lookup is valid: Update inline cache and stub cache.
635 if (use_ic) UpdateCaches(&lookup, object, name); 586 if (use_ic) UpdateCaches(&lookup, object, name);
636 587
637 // Get the property. 588 // Get the property.
638 PropertyAttributes attr; 589 PropertyAttributes attr;
639 Handle<Object> result = 590 Handle<Object> result =
640 Object::GetProperty(object, object, &lookup, name, &attr); 591 Object::GetProperty(object, object, &lookup, name, &attr);
641 RETURN_IF_EMPTY_HANDLE(isolate(), result); 592 RETURN_IF_EMPTY_HANDLE(isolate(), result);
642 593
643 if (lookup.IsInterceptor() && attr == ABSENT) { 594 if (lookup.IsInterceptor() && attr == ABSENT) {
644 // If the object does not have the requested property, check which 595 // If the object does not have the requested property, check which
645 // exception we need to throw. 596 // exception we need to throw.
646 return IsUndeclaredGlobal(object) 597 return object->IsGlobalObject()
647 ? ReferenceError("not_defined", name) 598 ? ReferenceError("not_defined", name)
648 : TypeError("undefined_method", object, name); 599 : TypeError("undefined_method", object, name);
649 } 600 }
650 601
651 ASSERT(!result->IsTheHole()); 602 ASSERT(!result->IsTheHole());
652 603
653 // Make receiver an object if the callee requires it. Strict mode or builtin 604 // Make receiver an object if the callee requires it. Strict mode or builtin
654 // functions do not wrap the receiver, non-strict functions and objects 605 // functions do not wrap the receiver, non-strict functions and objects
655 // called as functions do. 606 // called as functions do.
656 ReceiverToObjectIfRequired(result, object); 607 ReceiverToObjectIfRequired(result, object);
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 if (!receiver_maps->at(current).is_null() && 891 if (!receiver_maps->at(current).is_null() &&
941 receiver_maps->at(current).is_identical_to(new_receiver_map)) { 892 receiver_maps->at(current).is_identical_to(new_receiver_map)) {
942 return false; 893 return false;
943 } 894 }
944 } 895 }
945 receiver_maps->Add(new_receiver_map); 896 receiver_maps->Add(new_receiver_map);
946 return true; 897 return true;
947 } 898 }
948 899
949 900
950 bool IC::UpdatePolymorphicIC(Handle<Type> type, 901 bool IC::UpdatePolymorphicIC(Handle<HeapType> type,
951 Handle<String> name, 902 Handle<String> name,
952 Handle<Code> code) { 903 Handle<Code> code) {
953 if (!code->is_handler()) return false; 904 if (!code->is_handler()) return false;
954 TypeHandleList types; 905 TypeHandleList types;
955 CodeHandleList handlers; 906 CodeHandleList handlers;
956 907
957 int number_of_valid_types; 908 int number_of_valid_types;
958 int handler_to_overwrite = -1; 909 int handler_to_overwrite = -1;
959 910
960 target()->FindAllTypes(&types); 911 target()->FindAllTypes(&types);
961 int number_of_types = types.length(); 912 int number_of_types = types.length();
962 number_of_valid_types = number_of_types; 913 number_of_valid_types = number_of_types;
963 914
964 for (int i = 0; i < number_of_types; i++) { 915 for (int i = 0; i < number_of_types; i++) {
965 Handle<Type> current_type = types.at(i); 916 Handle<HeapType> current_type = types.at(i);
966 // Filter out deprecated maps to ensure their instances get migrated. 917 // Filter out deprecated maps to ensure their instances get migrated.
967 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { 918 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) {
968 number_of_valid_types--; 919 number_of_valid_types--;
969 // If the receiver type is already in the polymorphic IC, this indicates 920 // If the receiver type is already in the polymorphic IC, this indicates
970 // there was a prototoype chain failure. In that case, just overwrite the 921 // there was a prototoype chain failure. In that case, just overwrite the
971 // handler. 922 // handler.
972 } else if (type->IsCurrently(current_type)) { 923 } else if (type->IsCurrently(current_type)) {
973 ASSERT(handler_to_overwrite == -1); 924 ASSERT(handler_to_overwrite == -1);
974 number_of_valid_types--; 925 number_of_valid_types--;
975 handler_to_overwrite = i; 926 handler_to_overwrite = i;
(...skipping 12 matching lines...) Expand all
988 handlers.Add(code); 939 handlers.Add(code);
989 } 940 }
990 941
991 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( 942 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
992 &types, &handlers, number_of_valid_types, name, extra_ic_state()); 943 &types, &handlers, number_of_valid_types, name, extra_ic_state());
993 set_target(*ic); 944 set_target(*ic);
994 return true; 945 return true;
995 } 946 }
996 947
997 948
998 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { 949 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) {
999 return object->IsJSGlobalObject() 950 return object->IsJSGlobalObject()
1000 ? Type::Constant(Handle<JSGlobalObject>::cast(object), isolate) 951 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate)
1001 : Type::OfCurrently(object, isolate); 952 : HeapType::OfCurrently(object, isolate);
1002 } 953 }
1003 954
1004 955
1005 Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) { 956 Handle<Map> IC::TypeToMap(HeapType* type, Isolate* isolate) {
1006 if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); 957 if (type->Is(HeapType::Number()))
1007 if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); 958 return isolate->factory()->heap_number_map();
959 if (type->Is(HeapType::Boolean())) return isolate->factory()->oddball_map();
1008 if (type->IsConstant()) { 960 if (type->IsConstant()) {
1009 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map()); 961 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map());
1010 } 962 }
1011 ASSERT(type->IsClass()); 963 ASSERT(type->IsClass());
1012 return type->AsClass(); 964 return type->AsClass();
1013 } 965 }
1014 966
1015 967
1016 Handle<Type> IC::MapToType(Handle<Map> map) { 968 Handle<HeapType> IC::MapToType(Handle<Map> map) {
1017 Isolate* isolate = map->GetIsolate(); 969 Isolate* isolate = map->GetIsolate();
1018 if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(isolate); 970 if (map->instance_type() == HEAP_NUMBER_TYPE) {
1019 // The only oddballs that can be recorded in ICs are booleans. 971 return HeapType::Number(isolate);
1020 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(isolate); 972 } else if (map->instance_type() == ODDBALL_TYPE) {
1021 return Type::Class(map, isolate); 973 // The only oddballs that can be recorded in ICs are booleans.
974 return HeapType::Boolean(isolate);
975 } else {
976 return HeapType::Class(map, isolate);
977 }
1022 } 978 }
1023 979
1024 980
1025 void IC::UpdateMonomorphicIC(Handle<Type> type, 981 void IC::UpdateMonomorphicIC(Handle<HeapType> type,
1026 Handle<Code> handler, 982 Handle<Code> handler,
1027 Handle<String> name) { 983 Handle<String> name) {
1028 if (!handler->is_handler()) return set_target(*handler); 984 if (!handler->is_handler()) return set_target(*handler);
1029 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( 985 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC(
1030 name, type, handler, extra_ic_state()); 986 name, type, handler, extra_ic_state());
1031 set_target(*ic); 987 set_target(*ic);
1032 } 988 }
1033 989
1034 990
1035 void IC::CopyICToMegamorphicCache(Handle<String> name) { 991 void IC::CopyICToMegamorphicCache(Handle<String> name) {
1036 TypeHandleList types; 992 TypeHandleList types;
1037 CodeHandleList handlers; 993 CodeHandleList handlers;
1038 target()->FindAllTypes(&types); 994 target()->FindAllTypes(&types);
1039 if (!target()->FindHandlers(&handlers, types.length())) return; 995 if (!target()->FindHandlers(&handlers, types.length())) return;
1040 for (int i = 0; i < types.length(); i++) { 996 for (int i = 0; i < types.length(); i++) {
1041 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); 997 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i));
1042 } 998 }
1043 } 999 }
1044 1000
1045 1001
1046 bool IC::IsTransitionOfMonomorphicTarget(Handle<Type> type) { 1002 bool IC::IsTransitionOfMonomorphicTarget(Handle<HeapType> type) {
1047 if (!type->IsClass()) return false; 1003 if (!type->IsClass()) return false;
1048 Map* receiver_map = *type->AsClass(); 1004 Map* receiver_map = *type->AsClass();
1049 Map* current_map = target()->FindFirstMap(); 1005 Map* current_map = target()->FindFirstMap();
1050 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); 1006 ElementsKind receiver_elements_kind = receiver_map->elements_kind();
1051 bool more_general_transition = 1007 bool more_general_transition =
1052 IsMoreGeneralElementsKindTransition( 1008 IsMoreGeneralElementsKindTransition(
1053 current_map->elements_kind(), receiver_elements_kind); 1009 current_map->elements_kind(), receiver_elements_kind);
1054 Map* transitioned_map = more_general_transition 1010 Map* transitioned_map = more_general_transition
1055 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) 1011 ? current_map->LookupElementsTransitionMap(receiver_elements_kind)
1056 : NULL; 1012 : NULL;
1057 1013
1058 return transitioned_map == receiver_map; 1014 return transitioned_map == receiver_map;
1059 } 1015 }
1060 1016
1061 1017
1062 void IC::PatchCache(Handle<Type> type, 1018 void IC::PatchCache(Handle<HeapType> type,
1063 Handle<String> name, 1019 Handle<String> name,
1064 Handle<Code> code) { 1020 Handle<Code> code) {
1065 switch (state()) { 1021 switch (state()) {
1066 case UNINITIALIZED: 1022 case UNINITIALIZED:
1067 case PREMONOMORPHIC: 1023 case PREMONOMORPHIC:
1068 case MONOMORPHIC_PROTOTYPE_FAILURE: 1024 case MONOMORPHIC_PROTOTYPE_FAILURE:
1069 UpdateMonomorphicIC(type, code, name); 1025 UpdateMonomorphicIC(type, code, name);
1070 break; 1026 break;
1071 case MONOMORPHIC: { 1027 case MONOMORPHIC: {
1072 // For now, call stubs are allowed to rewrite to the same stub. This 1028 // For now, call stubs are allowed to rewrite to the same stub. This
(...skipping 22 matching lines...) Expand all
1095 break; 1051 break;
1096 case GENERIC: 1052 case GENERIC:
1097 UNREACHABLE(); 1053 UNREACHABLE();
1098 break; 1054 break;
1099 } 1055 }
1100 } 1056 }
1101 1057
1102 1058
1103 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) { 1059 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) {
1104 Handle<Code> ic = isolate->stub_cache()->ComputeLoad( 1060 Handle<Code> ic = isolate->stub_cache()->ComputeLoad(
1105 UNINITIALIZED, IC::ComputeExtraICState(mode)); 1061 UNINITIALIZED, ComputeExtraICState(mode));
1106 return ic; 1062 return ic;
1107 } 1063 }
1108 1064
1109 1065
1110 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate, 1066 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
1111 ContextualMode mode) { 1067 ContextualMode mode) {
1112 return isolate->stub_cache()->ComputeLoad( 1068 return isolate->stub_cache()->ComputeLoad(
1113 PREMONOMORPHIC, IC::ComputeExtraICState(mode)); 1069 PREMONOMORPHIC, ComputeExtraICState(mode));
1114 } 1070 }
1115 1071
1116 1072
1117 Handle<Code> LoadIC::megamorphic_stub() { 1073 Handle<Code> LoadIC::megamorphic_stub() {
1118 return isolate()->stub_cache()->ComputeLoad( 1074 return isolate()->stub_cache()->ComputeLoad(
1119 MEGAMORPHIC, extra_ic_state()); 1075 MEGAMORPHIC, extra_ic_state());
1120 } 1076 }
1121 1077
1122 1078
1123 Handle<Code> LoadIC::SimpleFieldLoad(int offset, 1079 Handle<Code> LoadIC::SimpleFieldLoad(int offset,
(...skipping 14 matching lines...) Expand all
1138 Handle<String> name) { 1094 Handle<String> name) {
1139 if (state() == UNINITIALIZED) { 1095 if (state() == UNINITIALIZED) {
1140 // This is the first time we execute this inline cache. 1096 // This is the first time we execute this inline cache.
1141 // Set the target to the pre monomorphic stub to delay 1097 // Set the target to the pre monomorphic stub to delay
1142 // setting the monomorphic state. 1098 // setting the monomorphic state.
1143 set_target(*pre_monomorphic_stub()); 1099 set_target(*pre_monomorphic_stub());
1144 TRACE_IC("LoadIC", name); 1100 TRACE_IC("LoadIC", name);
1145 return; 1101 return;
1146 } 1102 }
1147 1103
1148 Handle<Type> type = CurrentTypeOf(object, isolate()); 1104 Handle<HeapType> type = CurrentTypeOf(object, isolate());
1149 Handle<Code> code; 1105 Handle<Code> code;
1150 if (!lookup->IsCacheable()) { 1106 if (!lookup->IsCacheable()) {
1151 // Bail out if the result is not cacheable. 1107 // Bail out if the result is not cacheable.
1152 code = slow_stub(); 1108 code = slow_stub();
1153 } else if (!lookup->IsProperty()) { 1109 } else if (!lookup->IsProperty()) {
1154 if (kind() == Code::LOAD_IC) { 1110 if (kind() == Code::LOAD_IC) {
1155 code = isolate()->stub_cache()->ComputeLoadNonexistent(name, type); 1111 code = isolate()->stub_cache()->ComputeLoadNonexistent(name, type);
1156 } else { 1112 } else {
1157 code = slow_stub(); 1113 code = slow_stub();
1158 } 1114 }
1159 } else { 1115 } else {
1160 code = ComputeHandler(lookup, object, name); 1116 code = ComputeHandler(lookup, object, name);
1161 } 1117 }
1162 1118
1163 PatchCache(type, name, code); 1119 PatchCache(type, name, code);
1164 TRACE_IC("LoadIC", name); 1120 TRACE_IC("LoadIC", name);
1165 } 1121 }
1166 1122
1167 1123
1168 void IC::UpdateMegamorphicCache(Type* type, Name* name, Code* code) { 1124 void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) {
1169 // Cache code holding map should be consistent with 1125 // Cache code holding map should be consistent with
1170 // GenerateMonomorphicCacheProbe. 1126 // GenerateMonomorphicCacheProbe.
1171 Map* map = *TypeToMap(type, isolate()); 1127 Map* map = *TypeToMap(type, isolate());
1172 isolate()->stub_cache()->Set(name, map, code); 1128 isolate()->stub_cache()->Set(name, map, code);
1173 } 1129 }
1174 1130
1175 1131
1176 Handle<Code> IC::ComputeHandler(LookupResult* lookup, 1132 Handle<Code> IC::ComputeHandler(LookupResult* lookup,
1177 Handle<Object> object, 1133 Handle<Object> object,
1178 Handle<String> name, 1134 Handle<String> name,
(...skipping 20 matching lines...) Expand all
1199 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, 1155 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup,
1200 Handle<Object> object, 1156 Handle<Object> object,
1201 Handle<String> name, 1157 Handle<String> name,
1202 Handle<Object> unused, 1158 Handle<Object> unused,
1203 InlineCacheHolderFlag cache_holder) { 1159 InlineCacheHolderFlag cache_holder) {
1204 if (object->IsString() && name->Equals(isolate()->heap()->length_string())) { 1160 if (object->IsString() && name->Equals(isolate()->heap()->length_string())) {
1205 int length_index = String::kLengthOffset / kPointerSize; 1161 int length_index = String::kLengthOffset / kPointerSize;
1206 return SimpleFieldLoad(length_index); 1162 return SimpleFieldLoad(length_index);
1207 } 1163 }
1208 1164
1209 Handle<Type> type = CurrentTypeOf(object, isolate()); 1165 Handle<HeapType> type = CurrentTypeOf(object, isolate());
1210 Handle<JSObject> holder(lookup->holder()); 1166 Handle<JSObject> holder(lookup->holder());
1211 LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind()); 1167 LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind());
1212 1168
1213 switch (lookup->type()) { 1169 switch (lookup->type()) {
1214 case FIELD: { 1170 case FIELD: {
1215 PropertyIndex field = lookup->GetFieldIndex(); 1171 PropertyIndex field = lookup->GetFieldIndex();
1216 if (object.is_identical_to(holder)) { 1172 if (object.is_identical_to(holder)) {
1217 return SimpleFieldLoad(field.translate(holder), 1173 return SimpleFieldLoad(field.translate(holder),
1218 field.is_inobject(holder), 1174 field.is_inobject(holder),
1219 lookup->representation()); 1175 lookup->representation());
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 receiver, name, value, NONE, strict_mode(), store_mode); 1519 receiver, name, value, NONE, strict_mode(), store_mode);
1564 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1520 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1565 return *result; 1521 return *result;
1566 } 1522 }
1567 1523
1568 LookupResult lookup(isolate()); 1524 LookupResult lookup(isolate());
1569 bool can_store = LookupForWrite(receiver, name, value, &lookup, this); 1525 bool can_store = LookupForWrite(receiver, name, value, &lookup, this);
1570 if (!can_store && 1526 if (!can_store &&
1571 strict_mode() == kStrictMode && 1527 strict_mode() == kStrictMode &&
1572 !(lookup.IsProperty() && lookup.IsReadOnly()) && 1528 !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1573 IsUndeclaredGlobal(object)) { 1529 object->IsGlobalObject()) {
1574 // Strict mode doesn't allow setting non-existent global property. 1530 // Strict mode doesn't allow setting non-existent global property.
1575 return ReferenceError("not_defined", name); 1531 return ReferenceError("not_defined", name);
1576 } 1532 }
1577 if (FLAG_use_ic) { 1533 if (FLAG_use_ic) {
1578 if (state() == UNINITIALIZED) { 1534 if (state() == UNINITIALIZED) {
1579 Handle<Code> stub = pre_monomorphic_stub(); 1535 Handle<Code> stub = pre_monomorphic_stub();
1580 set_target(*stub); 1536 set_target(*stub);
1581 TRACE_IC("StoreIC", name); 1537 TRACE_IC("StoreIC", name);
1582 } else if (can_store) { 1538 } else if (can_store) {
1583 UpdateCaches(&lookup, receiver, name, value); 1539 UpdateCaches(&lookup, receiver, name, value);
1584 } else if (!name->IsCacheable(isolate()) || 1540 } else if (!name->IsCacheable(isolate()) ||
1585 lookup.IsNormal() || 1541 lookup.IsNormal() ||
1586 (lookup.IsField() && lookup.CanHoldValue(value))) { 1542 (lookup.IsField() && lookup.CanHoldValue(value))) {
1587 Handle<Code> stub = generic_stub(); 1543 Handle<Code> stub = generic_stub();
1588 set_target(*stub); 1544 set_target(*stub);
1589 } 1545 }
1590 } 1546 }
1591 1547
1592 // Set the property. 1548 // Set the property.
1593 Handle<Object> result = JSReceiver::SetProperty( 1549 Handle<Object> result = JSReceiver::SetProperty(
1594 receiver, name, value, NONE, strict_mode(), store_mode); 1550 receiver, name, value, NONE, strict_mode(), store_mode);
1595 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1551 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1596 return *result; 1552 return *result;
1597 } 1553 }
1598 1554
1599 1555
1600 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, 1556 Handle<Code> StoreIC::initialize_stub(Isolate* isolate,
1601 StrictModeFlag strict_mode, 1557 StrictModeFlag strict_mode) {
1602 ContextualMode mode) { 1558 ExtraICState extra_state = ComputeExtraICState(strict_mode);
1603 ExtraICState extra_state = ComputeExtraICState(strict_mode, mode);
1604 Handle<Code> ic = isolate->stub_cache()->ComputeStore( 1559 Handle<Code> ic = isolate->stub_cache()->ComputeStore(
1605 UNINITIALIZED, extra_state); 1560 UNINITIALIZED, extra_state);
1606 return ic; 1561 return ic;
1607 } 1562 }
1608 1563
1609 1564
1610 Handle<Code> StoreIC::megamorphic_stub() { 1565 Handle<Code> StoreIC::megamorphic_stub() {
1611 return isolate()->stub_cache()->ComputeStore(MEGAMORPHIC, extra_ic_state()); 1566 return isolate()->stub_cache()->ComputeStore(MEGAMORPHIC, extra_ic_state());
1612 } 1567 }
1613 1568
1614 1569
1615 Handle<Code> StoreIC::generic_stub() const { 1570 Handle<Code> StoreIC::generic_stub() const {
1616 return isolate()->stub_cache()->ComputeStore(GENERIC, extra_ic_state()); 1571 return isolate()->stub_cache()->ComputeStore(GENERIC, extra_ic_state());
1617 } 1572 }
1618 1573
1619 1574
1620 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate, 1575 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate,
1621 StrictModeFlag strict_mode, 1576 StrictModeFlag strict_mode) {
1622 ContextualMode contextual_mode) { 1577 ExtraICState state = ComputeExtraICState(strict_mode);
1623 ExtraICState state = StoreIC::ComputeExtraICState(strict_mode,
1624 contextual_mode);
1625 return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state); 1578 return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state);
1626 } 1579 }
1627 1580
1628 1581
1629 void StoreIC::UpdateCaches(LookupResult* lookup, 1582 void StoreIC::UpdateCaches(LookupResult* lookup,
1630 Handle<JSObject> receiver, 1583 Handle<JSObject> receiver,
1631 Handle<String> name, 1584 Handle<String> name,
1632 Handle<Object> value) { 1585 Handle<Object> value) {
1633 ASSERT(lookup->IsFound()); 1586 ASSERT(lookup->IsFound());
1634 1587
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 receiver, lookup, transition, name); 1627 receiver, lookup, transition, name);
1675 } 1628 }
1676 case NORMAL: 1629 case NORMAL:
1677 if (kind() == Code::KEYED_STORE_IC) break; 1630 if (kind() == Code::KEYED_STORE_IC) break;
1678 if (receiver->IsGlobalObject()) { 1631 if (receiver->IsGlobalObject()) {
1679 // The stub generated for the global object picks the value directly 1632 // The stub generated for the global object picks the value directly
1680 // from the property cell. So the property must be directly on the 1633 // from the property cell. So the property must be directly on the
1681 // global object. 1634 // global object.
1682 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 1635 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
1683 Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate()); 1636 Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
1684 Handle<Type> union_type = PropertyCell::UpdatedType(cell, value); 1637 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value);
1685 StoreGlobalStub stub(union_type->IsConstant()); 1638 StoreGlobalStub stub(union_type->IsConstant());
1686 1639
1687 Handle<Code> code = stub.GetCodeCopyFromTemplate( 1640 Handle<Code> code = stub.GetCodeCopyFromTemplate(
1688 isolate(), receiver->map(), *cell); 1641 isolate(), receiver->map(), *cell);
1689 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 1642 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1690 HeapObject::UpdateMapCodeCache(receiver, name, code); 1643 HeapObject::UpdateMapCodeCache(receiver, name, code);
1691 return code; 1644 return code;
1692 } 1645 }
1693 ASSERT(holder.is_identical_to(receiver)); 1646 ASSERT(holder.is_identical_to(receiver));
1694 return isolate()->builtins()->StoreIC_Normal(); 1647 return isolate()->builtins()->StoreIC_Normal();
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 return generic_stub(); 1791 return generic_stub();
1839 } 1792 }
1840 } 1793 }
1841 1794
1842 // If the store mode isn't the standard mode, make sure that all polymorphic 1795 // If the store mode isn't the standard mode, make sure that all polymorphic
1843 // receivers are either external arrays, or all "normal" arrays. Otherwise, 1796 // receivers are either external arrays, or all "normal" arrays. Otherwise,
1844 // use the generic stub. 1797 // use the generic stub.
1845 if (store_mode != STANDARD_STORE) { 1798 if (store_mode != STANDARD_STORE) {
1846 int external_arrays = 0; 1799 int external_arrays = 0;
1847 for (int i = 0; i < target_receiver_maps.length(); ++i) { 1800 for (int i = 0; i < target_receiver_maps.length(); ++i) {
1848 if (target_receiver_maps[i]->has_external_array_elements()) { 1801 if (target_receiver_maps[i]->has_external_array_elements() ||
1802 target_receiver_maps[i]->has_fixed_typed_array_elements()) {
1849 external_arrays++; 1803 external_arrays++;
1850 } 1804 }
1851 } 1805 }
1852 if (external_arrays != 0 && 1806 if (external_arrays != 0 &&
1853 external_arrays != target_receiver_maps.length()) { 1807 external_arrays != target_receiver_maps.length()) {
1854 TRACE_GENERIC_IC(isolate(), "KeyedIC", 1808 TRACE_GENERIC_IC(isolate(), "KeyedIC",
1855 "unsupported combination of external and normal arrays"); 1809 "unsupported combination of external and normal arrays");
1856 return generic_stub(); 1810 return generic_stub();
1857 } 1811 }
1858 } 1812 }
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
2607 GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE); 2561 GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE);
2608 GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT); 2562 GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT);
2609 GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE); 2563 GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE);
2610 GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT); 2564 GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT);
2611 GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE); 2565 GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE);
2612 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE); 2566 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE);
2613 #undef GENERATE 2567 #undef GENERATE
2614 } 2568 }
2615 2569
2616 2570
2617 Handle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const { 2571 Type* BinaryOpIC::State::GetResultType(Zone* zone) const {
2618 Kind result_kind = result_kind_; 2572 Kind result_kind = result_kind_;
2619 if (HasSideEffects()) { 2573 if (HasSideEffects()) {
2620 result_kind = NONE; 2574 result_kind = NONE;
2621 } else if (result_kind == GENERIC && op_ == Token::ADD) { 2575 } else if (result_kind == GENERIC && op_ == Token::ADD) {
2622 return Type::Union(Type::Number(isolate), Type::String(isolate), isolate); 2576 return Type::Union(Type::Number(zone), Type::String(zone), zone);
2623 } else if (result_kind == NUMBER && op_ == Token::SHR) { 2577 } else if (result_kind == NUMBER && op_ == Token::SHR) {
2624 return Type::Unsigned32(isolate); 2578 return Type::Unsigned32(zone);
2625 } 2579 }
2626 ASSERT_NE(GENERIC, result_kind); 2580 ASSERT_NE(GENERIC, result_kind);
2627 return KindToType(result_kind, isolate); 2581 return KindToType(result_kind, zone);
2628 } 2582 }
2629 2583
2630 2584
2631 void BinaryOpIC::State::Print(StringStream* stream) const { 2585 void BinaryOpIC::State::Print(StringStream* stream) const {
2632 stream->Add("(%s", Token::Name(op_)); 2586 stream->Add("(%s", Token::Name(op_));
2633 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); 2587 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft");
2634 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); 2588 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight");
2635 if (CouldCreateAllocationMementos()) stream->Add("_CreateAllocationMementos"); 2589 if (CouldCreateAllocationMementos()) stream->Add("_CreateAllocationMementos");
2636 stream->Add(":%s*", KindToString(left_kind_)); 2590 stream->Add(":%s*", KindToString(left_kind_));
2637 if (fixed_right_arg_.has_value) { 2591 if (fixed_right_arg_.has_value) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2748 case NUMBER: return "Number"; 2702 case NUMBER: return "Number";
2749 case STRING: return "String"; 2703 case STRING: return "String";
2750 case GENERIC: return "Generic"; 2704 case GENERIC: return "Generic";
2751 } 2705 }
2752 UNREACHABLE(); 2706 UNREACHABLE();
2753 return NULL; 2707 return NULL;
2754 } 2708 }
2755 2709
2756 2710
2757 // static 2711 // static
2758 Handle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) { 2712 Type* BinaryOpIC::State::KindToType(Kind kind, Zone* zone) {
2759 switch (kind) { 2713 switch (kind) {
2760 case NONE: return Type::None(isolate); 2714 case NONE: return Type::None(zone);
2761 case SMI: return Type::Smi(isolate); 2715 case SMI: return Type::Smi(zone);
2762 case INT32: return Type::Signed32(isolate); 2716 case INT32: return Type::Signed32(zone);
2763 case NUMBER: return Type::Number(isolate); 2717 case NUMBER: return Type::Number(zone);
2764 case STRING: return Type::String(isolate); 2718 case STRING: return Type::String(zone);
2765 case GENERIC: return Type::Any(isolate); 2719 case GENERIC: return Type::Any(zone);
2766 } 2720 }
2767 UNREACHABLE(); 2721 UNREACHABLE();
2768 return Handle<Type>(); 2722 return NULL;
2769 } 2723 }
2770 2724
2771 2725
2772 MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site, 2726 MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site,
2773 Handle<Object> left, 2727 Handle<Object> left,
2774 Handle<Object> right) { 2728 Handle<Object> right) {
2775 State state(target()->extended_extra_ic_state()); 2729 State state(target()->extended_extra_ic_state());
2776 2730
2777 // Compute the actual result using the builtin for the binary operation. 2731 // Compute the actual result using the builtin for the binary operation.
2778 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( 2732 Object* builtin = isolate()->js_builtins_object()->javascript_builtin(
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2888 case UNIQUE_NAME: return "UNIQUE_NAME"; 2842 case UNIQUE_NAME: return "UNIQUE_NAME";
2889 case OBJECT: return "OBJECT"; 2843 case OBJECT: return "OBJECT";
2890 case KNOWN_OBJECT: return "KNOWN_OBJECT"; 2844 case KNOWN_OBJECT: return "KNOWN_OBJECT";
2891 case GENERIC: return "GENERIC"; 2845 case GENERIC: return "GENERIC";
2892 } 2846 }
2893 UNREACHABLE(); 2847 UNREACHABLE();
2894 return NULL; 2848 return NULL;
2895 } 2849 }
2896 2850
2897 2851
2898 Handle<Type> CompareIC::StateToType( 2852 Type* CompareIC::StateToType(
2899 Isolate* isolate, 2853 Zone* zone,
2900 CompareIC::State state, 2854 CompareIC::State state,
2901 Handle<Map> map) { 2855 Handle<Map> map) {
2902 switch (state) { 2856 switch (state) {
2903 case CompareIC::UNINITIALIZED: return Type::None(isolate); 2857 case CompareIC::UNINITIALIZED: return Type::None(zone);
2904 case CompareIC::SMI: return Type::Smi(isolate); 2858 case CompareIC::SMI: return Type::Smi(zone);
2905 case CompareIC::NUMBER: return Type::Number(isolate); 2859 case CompareIC::NUMBER: return Type::Number(zone);
2906 case CompareIC::STRING: return Type::String(isolate); 2860 case CompareIC::STRING: return Type::String(zone);
2907 case CompareIC::INTERNALIZED_STRING: 2861 case CompareIC::INTERNALIZED_STRING: return Type::InternalizedString(zone);
2908 return Type::InternalizedString(isolate); 2862 case CompareIC::UNIQUE_NAME: return Type::UniqueName(zone);
2909 case CompareIC::UNIQUE_NAME: return Type::UniqueName(isolate); 2863 case CompareIC::OBJECT: return Type::Receiver(zone);
2910 case CompareIC::OBJECT: return Type::Receiver(isolate);
2911 case CompareIC::KNOWN_OBJECT: 2864 case CompareIC::KNOWN_OBJECT:
2912 return map.is_null() 2865 return map.is_null() ? Type::Receiver(zone) : Type::Class(map, zone);
2913 ? Type::Receiver(isolate) : Type::Class(map, isolate); 2866 case CompareIC::GENERIC: return Type::Any(zone);
2914 case CompareIC::GENERIC: return Type::Any(isolate);
2915 } 2867 }
2916 UNREACHABLE(); 2868 UNREACHABLE();
2917 return Handle<Type>(); 2869 return NULL;
2918 } 2870 }
2919 2871
2920 2872
2921 void CompareIC::StubInfoToType(int stub_minor_key, 2873 void CompareIC::StubInfoToType(int stub_minor_key,
2922 Handle<Type>* left_type, 2874 Type** left_type,
2923 Handle<Type>* right_type, 2875 Type** right_type,
2924 Handle<Type>* overall_type, 2876 Type** overall_type,
2925 Handle<Map> map, 2877 Handle<Map> map,
2926 Isolate* isolate) { 2878 Zone* zone) {
2927 State left_state, right_state, handler_state; 2879 State left_state, right_state, handler_state;
2928 ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state, 2880 ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state,
2929 &handler_state, NULL); 2881 &handler_state, NULL);
2930 *left_type = StateToType(isolate, left_state); 2882 *left_type = StateToType(zone, left_state);
2931 *right_type = StateToType(isolate, right_state); 2883 *right_type = StateToType(zone, right_state);
2932 *overall_type = StateToType(isolate, handler_state, map); 2884 *overall_type = StateToType(zone, handler_state, map);
2933 } 2885 }
2934 2886
2935 2887
2936 CompareIC::State CompareIC::NewInputState(State old_state, 2888 CompareIC::State CompareIC::NewInputState(State old_state,
2937 Handle<Object> value) { 2889 Handle<Object> value) {
2938 switch (old_state) { 2890 switch (old_state) {
2939 case UNINITIALIZED: 2891 case UNINITIALIZED:
2940 if (value->IsSmi()) return SMI; 2892 if (value->IsSmi()) return SMI;
2941 if (value->IsHeapNumber()) return NUMBER; 2893 if (value->IsHeapNumber()) return NUMBER;
2942 if (value->IsInternalizedString()) return INTERNALIZED_STRING; 2894 if (value->IsInternalizedString()) return INTERNALIZED_STRING;
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
3220 #undef ADDR 3172 #undef ADDR
3221 }; 3173 };
3222 3174
3223 3175
3224 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3176 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3225 return IC_utilities[id]; 3177 return IC_utilities[id];
3226 } 3178 }
3227 3179
3228 3180
3229 } } // namespace v8::internal 3181 } } // 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