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

Side by Side Diff: src/ic.cc

Issue 8352003: Handlify upper layers of KeyedLoadIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments, rebase. Created 9 years, 2 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/objects.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 ? initialize_stub_strict() 361 ? initialize_stub_strict()
362 : initialize_stub()); 362 : initialize_stub());
363 } 363 }
364 364
365 365
366 static bool HasInterceptorGetter(JSObject* object) { 366 static bool HasInterceptorGetter(JSObject* object) {
367 return !object->GetNamedInterceptor()->getter()->IsUndefined(); 367 return !object->GetNamedInterceptor()->getter()->IsUndefined();
368 } 368 }
369 369
370 370
371 static void LookupForRead(Object* object,
372 String* name,
373 LookupResult* lookup) {
374 AssertNoAllocation no_gc;
375 // Skip all the objects with named interceptors, but
376 // without actual getter.
377 while (true) {
378 object->Lookup(name, lookup);
379 // Besides normal conditions (property not found or it's not
380 // an interceptor), bail out if lookup is not cacheable: we won't
381 // be able to IC it anyway and regular lookup should work fine.
382 if (!lookup->IsFound()
383 || (lookup->type() != INTERCEPTOR)
384 || !lookup->IsCacheable()) {
385 return;
386 }
387
388 JSObject* holder = lookup->holder();
389 if (HasInterceptorGetter(holder)) {
390 return;
391 }
392
393 holder->LocalLookupRealNamedProperty(name, lookup);
394 if (lookup->IsProperty()) {
395 ASSERT(lookup->type() != INTERCEPTOR);
396 return;
397 }
398
399 Object* proto = holder->GetPrototype();
400 if (proto->IsNull()) {
401 lookup->NotFound();
402 return;
403 }
404
405 object = proto;
406 }
407 }
408
409
410 static void LookupForRead(Handle<Object> object, 371 static void LookupForRead(Handle<Object> object,
411 Handle<String> name, 372 Handle<String> name,
412 LookupResult* lookup) { 373 LookupResult* lookup) {
413 // Skip all the objects with named interceptors, but 374 // Skip all the objects with named interceptors, but
414 // without actual getter. 375 // without actual getter.
415 while (true) { 376 while (true) {
416 object->Lookup(*name, lookup); 377 object->Lookup(*name, lookup);
417 // Besides normal conditions (property not found or it's not 378 // Besides normal conditions (property not found or it's not
418 // an interceptor), bail out if lookup is not cacheable: we won't 379 // an interceptor), bail out if lookup is not cacheable: we won't
419 // be able to IC it anyway and regular lookup should work fine. 380 // be able to IC it anyway and regular lookup should work fine.
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 return object; 1061 return object;
1101 } 1062 }
1102 1063
1103 1064
1104 MaybeObject* KeyedLoadIC::Load(State state, 1065 MaybeObject* KeyedLoadIC::Load(State state,
1105 Handle<Object> object, 1066 Handle<Object> object,
1106 Handle<Object> key, 1067 Handle<Object> key,
1107 bool force_generic_stub) { 1068 bool force_generic_stub) {
1108 // Check for values that can be converted into a symbol. 1069 // Check for values that can be converted into a symbol.
1109 // TODO(1295): Remove this code. 1070 // TODO(1295): Remove this code.
1110 HandleScope scope(isolate());
1111 if (key->IsHeapNumber() && 1071 if (key->IsHeapNumber() &&
1112 isnan(HeapNumber::cast(*key)->value())) { 1072 isnan(Handle<HeapNumber>::cast(key)->value())) {
1113 key = isolate()->factory()->nan_symbol(); 1073 key = isolate()->factory()->nan_symbol();
1114 } else if (key->IsUndefined()) { 1074 } else if (key->IsUndefined()) {
1115 key = isolate()->factory()->undefined_symbol(); 1075 key = isolate()->factory()->undefined_symbol();
1116 } 1076 }
1117 1077
1118 if (key->IsSymbol()) { 1078 if (key->IsSymbol()) {
1119 Handle<String> name = Handle<String>::cast(key); 1079 Handle<String> name = Handle<String>::cast(key);
1120 1080
1121 // If the object is undefined or null it's illegal to try to get any 1081 // If the object is undefined or null it's illegal to try to get any
1122 // of its properties; throw a TypeError in that case. 1082 // of its properties; throw a TypeError in that case.
1123 if (object->IsUndefined() || object->IsNull()) { 1083 if (object->IsUndefined() || object->IsNull()) {
1124 return TypeError("non_object_property_load", object, name); 1084 return TypeError("non_object_property_load", object, name);
1125 } 1085 }
1126 1086
1127 if (FLAG_use_ic) { 1087 if (FLAG_use_ic) {
1128 // TODO(1073): don't ignore the current stub state. 1088 // TODO(1073): don't ignore the current stub state.
1129 1089
1130 // Use specialized code for getting the length of strings. 1090 // Use specialized code for getting the length of strings.
1131 if (object->IsString() && 1091 if (object->IsString() &&
1132 name->Equals(isolate()->heap()->length_symbol())) { 1092 name->Equals(isolate()->heap()->length_symbol())) {
1133 Handle<String> string = Handle<String>::cast(object); 1093 Handle<String> string = Handle<String>::cast(object);
1134 Object* code = NULL; 1094 Handle<Code> code =
1135 { MaybeObject* maybe_code = 1095 isolate()->stub_cache()->ComputeKeyedLoadStringLength(name,
1136 isolate()->stub_cache()->ComputeKeyedLoadStringLength(*name, 1096 string);
1137 *string); 1097 ASSERT(!code.is_null());
1138 if (!maybe_code->ToObject(&code)) return maybe_code; 1098 set_target(*code);
1139 }
1140 set_target(Code::cast(code));
1141 #ifdef DEBUG 1099 #ifdef DEBUG
1142 TraceIC("KeyedLoadIC", name, state, target()); 1100 TraceIC("KeyedLoadIC", name, state, target());
1143 #endif // DEBUG 1101 #endif // DEBUG
1144 return Smi::FromInt(string->length()); 1102 return Smi::FromInt(string->length());
1145 } 1103 }
1146 1104
1147 // Use specialized code for getting the length of arrays. 1105 // Use specialized code for getting the length of arrays.
1148 if (object->IsJSArray() && 1106 if (object->IsJSArray() &&
1149 name->Equals(isolate()->heap()->length_symbol())) { 1107 name->Equals(isolate()->heap()->length_symbol())) {
1150 Handle<JSArray> array = Handle<JSArray>::cast(object); 1108 Handle<JSArray> array = Handle<JSArray>::cast(object);
1151 Object* code; 1109 Handle<Code> code =
1152 { MaybeObject* maybe_code = 1110 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(name, array);
1153 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(*name, 1111 ASSERT(!code.is_null());
1154 *array); 1112 set_target(*code);
1155 if (!maybe_code->ToObject(&code)) return maybe_code;
1156 }
1157 set_target(Code::cast(code));
1158 #ifdef DEBUG 1113 #ifdef DEBUG
1159 TraceIC("KeyedLoadIC", name, state, target()); 1114 TraceIC("KeyedLoadIC", name, state, target());
1160 #endif // DEBUG 1115 #endif // DEBUG
1161 return JSArray::cast(*object)->length(); 1116 return array->length();
1162 } 1117 }
1163 1118
1164 // Use specialized code for getting prototype of functions. 1119 // Use specialized code for getting prototype of functions.
1165 if (object->IsJSFunction() && 1120 if (object->IsJSFunction() &&
1166 name->Equals(isolate()->heap()->prototype_symbol()) && 1121 name->Equals(isolate()->heap()->prototype_symbol()) &&
1167 JSFunction::cast(*object)->should_have_prototype()) { 1122 Handle<JSFunction>::cast(object)->should_have_prototype()) {
1168 Handle<JSFunction> function = Handle<JSFunction>::cast(object); 1123 Handle<JSFunction> function = Handle<JSFunction>::cast(object);
1169 Object* code; 1124 Handle<Code> code =
1170 { MaybeObject* maybe_code = 1125 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype(
1171 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype( 1126 name, function);
1172 *name, *function); 1127 ASSERT(!code.is_null());
1173 if (!maybe_code->ToObject(&code)) return maybe_code; 1128 set_target(*code);
1174 }
1175 set_target(Code::cast(code));
1176 #ifdef DEBUG 1129 #ifdef DEBUG
1177 TraceIC("KeyedLoadIC", name, state, target()); 1130 TraceIC("KeyedLoadIC", name, state, target());
1178 #endif // DEBUG 1131 #endif // DEBUG
1179 return Accessors::FunctionGetPrototype(*object, 0); 1132 return Accessors::FunctionGetPrototype(*object, 0);
1180 } 1133 }
1181 } 1134 }
1182 1135
1183 // Check if the name is trivially convertible to an index and get 1136 // Check if the name is trivially convertible to an index and get
1184 // the element or char if so. 1137 // the element or char if so.
1185 uint32_t index = 0; 1138 uint32_t index = 0;
1186 if (name->AsArrayIndex(&index)) { 1139 if (name->AsArrayIndex(&index)) {
1187 HandleScope scope(isolate());
1188 // Rewrite to the generic keyed load stub. 1140 // Rewrite to the generic keyed load stub.
1189 if (FLAG_use_ic) set_target(generic_stub()); 1141 if (FLAG_use_ic) set_target(*generic_stub());
1190 return Runtime::GetElementOrCharAt(isolate(), object, index); 1142 return Runtime::GetElementOrCharAt(isolate(), object, index);
1191 } 1143 }
1192 1144
1193 // Named lookup. 1145 // Named lookup.
1194 LookupResult lookup(isolate()); 1146 LookupResult lookup(isolate());
1195 LookupForRead(*object, *name, &lookup); 1147 LookupForRead(object, name, &lookup);
1196 1148
1197 // If we did not find a property, check if we need to throw an exception. 1149 // If we did not find a property, check if we need to throw an exception.
1198 if (!lookup.IsProperty() && IsContextual(object)) { 1150 if (!lookup.IsProperty() && IsContextual(object)) {
1199 return ReferenceError("not_defined", name); 1151 return ReferenceError("not_defined", name);
1200 } 1152 }
1201 1153
1202 if (FLAG_use_ic) { 1154 if (FLAG_use_ic) {
1203 UpdateCaches(&lookup, state, object, name); 1155 UpdateCaches(&lookup, state, object, name);
1204 } 1156 }
1205 1157
1206 PropertyAttributes attr; 1158 PropertyAttributes attr;
1207 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) { 1159 if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
1208 // Get the property. 1160 // Get the property.
1209 Object* result; 1161 Handle<Object> result =
1210 { MaybeObject* maybe_result = 1162 Object::GetProperty(object, object, &lookup, name, &attr);
1211 object->GetProperty(*object, &lookup, *name, &attr); 1163 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1212 if (!maybe_result->ToObject(&result)) return maybe_result;
1213 }
1214 // If the property is not present, check if we need to throw an 1164 // If the property is not present, check if we need to throw an
1215 // exception. 1165 // exception.
1216 if (attr == ABSENT && IsContextual(object)) { 1166 if (attr == ABSENT && IsContextual(object)) {
1217 return ReferenceError("not_defined", name); 1167 return ReferenceError("not_defined", name);
1218 } 1168 }
1219 return result; 1169 return *result;
1220 } 1170 }
1221 1171
1222 return object->GetProperty(*object, &lookup, *name, &attr); 1172 return object->GetProperty(*object, &lookup, *name, &attr);
1223 } 1173 }
1224 1174
1225 // Do not use ICs for objects that require access checks (including 1175 // Do not use ICs for objects that require access checks (including
1226 // the global object). 1176 // the global object).
1227 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); 1177 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
1228 1178
1229 if (use_ic) { 1179 if (use_ic) {
1230 Code* stub = generic_stub(); 1180 Handle<Code> stub = generic_stub();
1231 if (!force_generic_stub) { 1181 if (!force_generic_stub) {
1232 if (object->IsString() && key->IsNumber()) { 1182 if (object->IsString() && key->IsNumber()) {
1233 if (state == UNINITIALIZED) { 1183 if (state == UNINITIALIZED) {
1234 stub = string_stub(); 1184 stub = string_stub();
1235 } 1185 }
1236 } else if (object->IsJSObject()) { 1186 } else if (object->IsJSObject()) {
1237 JSObject* receiver = JSObject::cast(*object); 1187 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1238 Heap* heap = Handle<JSObject>::cast(object)->GetHeap(); 1188 if (receiver->elements()->map() ==
1239 Map* elements_map = Handle<JSObject>::cast(object)->elements()->map(); 1189 isolate()->heap()->non_strict_arguments_elements_map()) {
1240 if (elements_map == heap->non_strict_arguments_elements_map()) {
1241 stub = non_strict_arguments_stub(); 1190 stub = non_strict_arguments_stub();
1242 } else if (receiver->HasIndexedInterceptor()) { 1191 } else if (receiver->HasIndexedInterceptor()) {
1243 stub = indexed_interceptor_stub(); 1192 stub = indexed_interceptor_stub();
1244 } else if (key->IsSmi() && (target() != non_strict_arguments_stub())) { 1193 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1245 MaybeObject* maybe_stub = ComputeStub(receiver, 1194 stub = ComputeStub(receiver, LOAD, kNonStrictMode, stub);
1246 LOAD,
1247 kNonStrictMode,
1248 stub);
1249 stub = maybe_stub->IsFailure() ?
1250 NULL : Code::cast(maybe_stub->ToObjectUnchecked());
1251 } 1195 }
1252 } 1196 }
1253 } 1197 }
1254 if (stub != NULL) set_target(stub); 1198 if (!stub.is_null()) set_target(*stub);
1255 } 1199 }
1256 1200
1257 #ifdef DEBUG 1201 #ifdef DEBUG
1258 TraceIC("KeyedLoadIC", key, state, target()); 1202 TraceIC("KeyedLoadIC", key, state, target());
1259 #endif // DEBUG 1203 #endif // DEBUG
1260 1204
1261 // Get the property. 1205 // Get the property.
1262 return Runtime::GetObjectProperty(isolate(), object, key); 1206 return Runtime::GetObjectProperty(isolate(), object, key);
1263 } 1207 }
1264 1208
1265 1209
1266 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, 1210 void KeyedLoadIC::UpdateCaches(LookupResult* lookup,
1267 Handle<Object> object, Handle<String> name) { 1211 State state,
1212 Handle<Object> object,
1213 Handle<String> name) {
1268 // Bail out if we didn't find a result. 1214 // Bail out if we didn't find a result.
1269 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 1215 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
1270 1216
1271 if (!object->IsJSObject()) return; 1217 if (!object->IsJSObject()) return;
1272 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1218 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1273 1219
1274 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return; 1220 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
1275 1221
1276 // Compute the code stub for this load. 1222 // Compute the code stub for this load.
1277 MaybeObject* maybe_code = NULL; 1223 Handle<Code> code;
1278 Object* code;
1279 1224
1280 if (state == UNINITIALIZED) { 1225 if (state == UNINITIALIZED) {
1281 // This is the first time we execute this inline cache. 1226 // This is the first time we execute this inline cache.
1282 // Set the target to the pre monomorphic stub to delay 1227 // Set the target to the pre monomorphic stub to delay
1283 // setting the monomorphic state. 1228 // setting the monomorphic state.
1284 maybe_code = pre_monomorphic_stub(); 1229 code = pre_monomorphic_stub();
1285 } else { 1230 } else {
1286 // Compute a monomorphic stub. 1231 // Compute a monomorphic stub.
1232 Handle<JSObject> holder(lookup->holder());
1287 switch (lookup->type()) { 1233 switch (lookup->type()) {
1288 case FIELD: { 1234 case FIELD:
1289 maybe_code = isolate()->stub_cache()->ComputeKeyedLoadField( 1235 code = isolate()->stub_cache()->ComputeKeyedLoadField(
1290 *name, *receiver, lookup->holder(), lookup->GetFieldIndex()); 1236 name, receiver, holder, lookup->GetFieldIndex());
1291 break; 1237 break;
1292 }
1293 case CONSTANT_FUNCTION: { 1238 case CONSTANT_FUNCTION: {
1294 Object* constant = lookup->GetConstantFunction(); 1239 Handle<Object> constant(lookup->GetConstantFunction());
1295 maybe_code = isolate()->stub_cache()->ComputeKeyedLoadConstant( 1240 code = isolate()->stub_cache()->ComputeKeyedLoadConstant(
1296 *name, *receiver, lookup->holder(), constant); 1241 name, receiver, holder, constant);
1297 break; 1242 break;
1298 } 1243 }
1299 case CALLBACKS: { 1244 case CALLBACKS: {
1300 if (!lookup->GetCallbackObject()->IsAccessorInfo()) return; 1245 Handle<Object> callback_object(lookup->GetCallbackObject());
1301 AccessorInfo* callback = 1246 if (!callback_object->IsAccessorInfo()) return;
1302 AccessorInfo::cast(lookup->GetCallbackObject()); 1247 Handle<AccessorInfo> callback =
1248 Handle<AccessorInfo>::cast(callback_object);
1303 if (v8::ToCData<Address>(callback->getter()) == 0) return; 1249 if (v8::ToCData<Address>(callback->getter()) == 0) return;
1304 maybe_code = isolate()->stub_cache()->ComputeKeyedLoadCallback( 1250 code = isolate()->stub_cache()->ComputeKeyedLoadCallback(
1305 *name, *receiver, lookup->holder(), callback); 1251 name, receiver, holder, callback);
1306 break; 1252 break;
1307 } 1253 }
1308 case INTERCEPTOR: { 1254 case INTERCEPTOR:
1309 ASSERT(HasInterceptorGetter(lookup->holder())); 1255 ASSERT(HasInterceptorGetter(lookup->holder()));
1310 maybe_code = isolate()->stub_cache()->ComputeKeyedLoadInterceptor( 1256 code = isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
1311 *name, *receiver, lookup->holder()); 1257 name, receiver, holder);
1312 break; 1258 break;
1313 } 1259 default:
1314 default: {
1315 // Always rewrite to the generic case so that we do not 1260 // Always rewrite to the generic case so that we do not
1316 // repeatedly try to rewrite. 1261 // repeatedly try to rewrite.
1317 maybe_code = generic_stub(); 1262 code = generic_stub();
1318 break; 1263 break;
1319 }
1320 } 1264 }
1321 } 1265 }
1322 1266
1323 // If we're unable to compute the stub (not enough memory left), we
1324 // simply avoid updating the caches.
1325 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
1326
1327 // Patch the call site depending on the state of the cache. Make 1267 // Patch the call site depending on the state of the cache. Make
1328 // sure to always rewrite from monomorphic to megamorphic. 1268 // sure to always rewrite from monomorphic to megamorphic.
1329 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); 1269 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
1330 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { 1270 if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
1331 set_target(Code::cast(code)); 1271 set_target(*code);
1332 } else if (state == MONOMORPHIC) { 1272 } else if (state == MONOMORPHIC) {
1333 set_target(megamorphic_stub()); 1273 set_target(*megamorphic_stub());
1334 } 1274 }
1335 1275
1336 #ifdef DEBUG 1276 #ifdef DEBUG
1337 TraceIC("KeyedLoadIC", name, state, target()); 1277 TraceIC("KeyedLoadIC", name, state, target());
1338 #endif 1278 #endif
1339 } 1279 }
1340 1280
1341 1281
1342 static bool StoreICableLookup(LookupResult* lookup) { 1282 static bool StoreICableLookup(LookupResult* lookup) {
1343 // Bail out if we didn't find a result. 1283 // Bail out if we didn't find a result.
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 return false; 1499 return false;
1560 } 1500 }
1561 } 1501 }
1562 receiver_maps->Add(new_receiver_map); 1502 receiver_maps->Add(new_receiver_map);
1563 return true; 1503 return true;
1564 } 1504 }
1565 1505
1566 1506
1567 void KeyedIC::GetReceiverMapsForStub(Code* stub, MapList* result) { 1507 void KeyedIC::GetReceiverMapsForStub(Code* stub, MapList* result) {
1568 ASSERT(stub->is_inline_cache_stub()); 1508 ASSERT(stub->is_inline_cache_stub());
1569 if (stub == string_stub()) { 1509 if (!string_stub().is_null() && stub == *string_stub()) {
1570 return result->Add(isolate()->heap()->string_map()); 1510 return result->Add(isolate()->heap()->string_map());
1571 } else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) { 1511 } else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) {
1572 if (stub->ic_state() == MONOMORPHIC) { 1512 if (stub->ic_state() == MONOMORPHIC) {
1573 result->Add(Map::cast(stub->FindFirstMap())); 1513 result->Add(Map::cast(stub->FindFirstMap()));
1574 } else { 1514 } else {
1575 ASSERT(stub->ic_state() == MEGAMORPHIC); 1515 ASSERT(stub->ic_state() == MEGAMORPHIC);
1576 AssertNoAllocation no_allocation; 1516 AssertNoAllocation no_allocation;
1577 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 1517 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
1578 for (RelocIterator it(stub, mask); !it.done(); it.next()) { 1518 for (RelocIterator it(stub, mask); !it.done(); it.next()) {
1579 RelocInfo* info = it.rinfo(); 1519 RelocInfo* info = it.rinfo();
1580 Object* object = info->target_object(); 1520 Object* object = info->target_object();
1581 ASSERT(object->IsMap()); 1521 ASSERT(object->IsMap());
1582 AddOneReceiverMapIfMissing(result, Map::cast(object)); 1522 AddOneReceiverMapIfMissing(result, Map::cast(object));
1583 } 1523 }
1584 } 1524 }
1585 } 1525 }
1586 } 1526 }
1587 1527
1588 1528
1529 Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
1530 StubKind stub_kind,
1531 StrictModeFlag strict_mode,
1532 Handle<Code> generic_stub) {
1533 CALL_HEAP_FUNCTION(isolate(),
1534 ComputeStub(*receiver,
1535 stub_kind,
1536 strict_mode,
1537 *generic_stub),
1538 Code);
1539 }
1540
1541
1542
1589 MaybeObject* KeyedIC::ComputeStub(JSObject* receiver, 1543 MaybeObject* KeyedIC::ComputeStub(JSObject* receiver,
1590 StubKind stub_kind, 1544 StubKind stub_kind,
1591 StrictModeFlag strict_mode, 1545 StrictModeFlag strict_mode,
1592 Code* generic_stub) { 1546 Code* generic_stub) {
1593 State ic_state = target()->ic_state(); 1547 State ic_state = target()->ic_state();
1594 if ((ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) && 1548 if ((ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) &&
1595 !IsTransitionStubKind(stub_kind)) { 1549 !IsTransitionStubKind(stub_kind)) {
1596 Code* monomorphic_stub; 1550 Code* monomorphic_stub;
1597 MaybeObject* maybe_stub = ComputeMonomorphicStub(receiver, 1551 MaybeObject* maybe_stub = ComputeMonomorphicStub(receiver,
1598 stub_kind, 1552 stub_kind,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 MaybeObject* maybe_update = cache->Update(&target_receiver_maps, flags, stub); 1610 MaybeObject* maybe_update = cache->Update(&target_receiver_maps, flags, stub);
1657 if (maybe_update->IsFailure()) return maybe_update; 1611 if (maybe_update->IsFailure()) return maybe_update;
1658 return stub; 1612 return stub;
1659 } 1613 }
1660 1614
1661 1615
1662 MaybeObject* KeyedIC::ComputeMonomorphicStubWithoutMapCheck( 1616 MaybeObject* KeyedIC::ComputeMonomorphicStubWithoutMapCheck(
1663 Map* receiver_map, 1617 Map* receiver_map,
1664 StrictModeFlag strict_mode) { 1618 StrictModeFlag strict_mode) {
1665 if ((receiver_map->instance_type() & kNotStringTag) == 0) { 1619 if ((receiver_map->instance_type() & kNotStringTag) == 0) {
1666 ASSERT(string_stub() != NULL); 1620 ASSERT(!string_stub().is_null());
1667 return string_stub(); 1621 return *string_stub();
1668 } else { 1622 } else {
1669 ASSERT(receiver_map->has_dictionary_elements() || 1623 ASSERT(receiver_map->has_dictionary_elements() ||
1670 receiver_map->has_fast_elements() || 1624 receiver_map->has_fast_elements() ||
1671 receiver_map->has_fast_smi_only_elements() || 1625 receiver_map->has_fast_smi_only_elements() ||
1672 receiver_map->has_fast_double_elements() || 1626 receiver_map->has_fast_double_elements() ||
1673 receiver_map->has_external_array_elements()); 1627 receiver_map->has_external_array_elements());
1674 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1628 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1675 return GetElementStubWithoutMapCheck(is_js_array, 1629 return GetElementStubWithoutMapCheck(is_js_array,
1676 receiver_map->elements_kind()); 1630 receiver_map->elements_kind());
1677 } 1631 }
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1986 HandleScope scope(isolate); 1940 HandleScope scope(isolate);
1987 ASSERT(args.length() == 2); 1941 ASSERT(args.length() == 2);
1988 LoadIC ic(isolate); 1942 LoadIC ic(isolate);
1989 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1943 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1990 return ic.Load(state, args.at<Object>(0), args.at<String>(1)); 1944 return ic.Load(state, args.at<Object>(0), args.at<String>(1));
1991 } 1945 }
1992 1946
1993 1947
1994 // Used from ic-<arch>.cc 1948 // Used from ic-<arch>.cc
1995 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { 1949 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) {
1996 NoHandleAllocation na; 1950 HandleScope scope(isolate);
1997 ASSERT(args.length() == 2); 1951 ASSERT(args.length() == 2);
1998 KeyedLoadIC ic(isolate); 1952 KeyedLoadIC ic(isolate);
1999 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1953 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
2000 return ic.Load(state, args.at<Object>(0), args.at<Object>(1), false); 1954 return ic.Load(state, args.at<Object>(0), args.at<Object>(1), false);
2001 } 1955 }
2002 1956
2003 1957
2004 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) { 1958 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) {
2005 NoHandleAllocation na; 1959 HandleScope scope(isolate);
2006 ASSERT(args.length() == 2); 1960 ASSERT(args.length() == 2);
2007 KeyedLoadIC ic(isolate); 1961 KeyedLoadIC ic(isolate);
2008 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1962 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
2009 return ic.Load(state, args.at<Object>(0), args.at<Object>(1), true); 1963 return ic.Load(state, args.at<Object>(0), args.at<Object>(1), true);
2010 } 1964 }
2011 1965
2012 1966
2013 // Used from ic-<arch>.cc. 1967 // Used from ic-<arch>.cc.
2014 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { 1968 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) {
2015 HandleScope scope; 1969 HandleScope scope;
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
2543 #undef ADDR 2497 #undef ADDR
2544 }; 2498 };
2545 2499
2546 2500
2547 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2501 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2548 return IC_utilities[id]; 2502 return IC_utilities[id];
2549 } 2503 }
2550 2504
2551 2505
2552 } } // namespace v8::internal 2506 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698