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

Side by Side Diff: src/ic.cc

Issue 23702039: Use regular map-checks to guard string-length loading. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 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/ia32/stub-cache-ia32.cc ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // 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 861 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 // of its properties; throw a TypeError in that case. 872 // of its properties; throw a TypeError in that case.
873 if (object->IsUndefined() || object->IsNull()) { 873 if (object->IsUndefined() || object->IsNull()) {
874 return TypeError("non_object_property_load", object, name); 874 return TypeError("non_object_property_load", object, name);
875 } 875 }
876 876
877 if (FLAG_use_ic) { 877 if (FLAG_use_ic) {
878 // Use specialized code for getting the length of strings and 878 // Use specialized code for getting the length of strings and
879 // string wrapper objects. The length property of string wrapper 879 // string wrapper objects. The length property of string wrapper
880 // objects is read-only and therefore always returns the length of 880 // objects is read-only and therefore always returns the length of
881 // the underlying string value. See ECMA-262 15.5.5.1. 881 // the underlying string value. See ECMA-262 15.5.5.1.
882 if ((object->IsString() || object->IsStringWrapper()) && 882 if (object->IsStringWrapper() &&
883 name->Equals(isolate()->heap()->length_string())) { 883 name->Equals(isolate()->heap()->length_string())) {
884 Handle<Code> stub; 884 Handle<Code> stub;
885 if (state == UNINITIALIZED) { 885 if (state == UNINITIALIZED) {
886 stub = pre_monomorphic_stub(); 886 stub = pre_monomorphic_stub();
887 } else if (state == PREMONOMORPHIC) { 887 } else if (state == PREMONOMORPHIC || state == MONOMORPHIC) {
888 StringLengthStub string_length_stub(kind(), !object->IsString()); 888 StringLengthStub string_length_stub(kind());
889 stub = string_length_stub.GetCode(isolate());
890 } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
891 StringLengthStub string_length_stub(kind(), true);
892 stub = string_length_stub.GetCode(isolate()); 889 stub = string_length_stub.GetCode(isolate());
893 } else if (state != MEGAMORPHIC) { 890 } else if (state != MEGAMORPHIC) {
894 ASSERT(state != GENERIC); 891 ASSERT(state != GENERIC);
895 stub = megamorphic_stub(); 892 stub = megamorphic_stub();
896 } 893 }
897 if (!stub.is_null()) { 894 if (!stub.is_null()) {
898 set_target(*stub); 895 set_target(*stub);
899 #ifdef DEBUG 896 #ifdef DEBUG
900 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n"); 897 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /stringwrapper]\n");
901 #endif 898 #endif
902 } 899 }
903 // Get the string if we have a string wrapper object. 900 // Get the string if we have a string wrapper object.
904 Handle<Object> string = object->IsJSValue() 901 String* string = String::cast(JSValue::cast(*object)->value());
905 ? Handle<Object>(Handle<JSValue>::cast(object)->value(), isolate()) 902 return Smi::FromInt(string->length());
906 : object;
907 return Smi::FromInt(String::cast(*string)->length());
908 } 903 }
909 904
910 // Use specialized code for getting prototype of functions. 905 // Use specialized code for getting prototype of functions.
911 if (object->IsJSFunction() && 906 if (object->IsJSFunction() &&
912 name->Equals(isolate()->heap()->prototype_string()) && 907 name->Equals(isolate()->heap()->prototype_string()) &&
913 Handle<JSFunction>::cast(object)->should_have_prototype()) { 908 Handle<JSFunction>::cast(object)->should_have_prototype()) {
914 Handle<Code> stub; 909 Handle<Code> stub;
915 if (state == UNINITIALIZED) { 910 if (state == UNINITIALIZED) {
916 stub = pre_monomorphic_stub(); 911 stub = pre_monomorphic_stub();
917 } else if (state == PREMONOMORPHIC) { 912 } else if (state == PREMONOMORPHIC) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1258 UNREACHABLE(); 1253 UNREACHABLE();
1259 break; 1254 break;
1260 } 1255 }
1261 } 1256 }
1262 1257
1263 1258
1264 void LoadIC::UpdateCaches(LookupResult* lookup, 1259 void LoadIC::UpdateCaches(LookupResult* lookup,
1265 State state, 1260 State state,
1266 Handle<Object> object, 1261 Handle<Object> object,
1267 Handle<String> name) { 1262 Handle<String> name) {
1263 // TODO(verwaest): It would be nice to support loading fields from smis as
1264 // well. For now just fail to update the cache.
1268 if (!object->IsHeapObject()) return; 1265 if (!object->IsHeapObject()) return;
1269 1266
1270 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object); 1267 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
1271 1268
1272 Handle<Code> code; 1269 Handle<Code> code;
1273 if (state == UNINITIALIZED) { 1270 if (state == UNINITIALIZED) {
1274 // This is the first time we execute this inline cache. 1271 // This is the first time we execute this inline cache.
1275 // Set the target to the pre monomorphic stub to delay 1272 // Set the target to the pre monomorphic stub to delay
1276 // setting the monomorphic state. 1273 // setting the monomorphic state.
1277 code = pre_monomorphic_stub(); 1274 code = pre_monomorphic_stub();
1278 } else if (!lookup->IsCacheable()) { 1275 } else if (!lookup->IsCacheable()) {
1279 // Bail out if the result is not cacheable. 1276 // Bail out if the result is not cacheable.
1280 code = slow_stub(); 1277 code = slow_stub();
1278 } else if (object->IsString() &&
1279 name->Equals(isolate()->heap()->length_string())) {
1280 int length_index = String::kLengthOffset / kPointerSize;
1281 if (target()->is_load_stub()) {
1282 LoadFieldStub stub(true, length_index, Representation::Tagged());
1283 code = stub.GetCode(isolate());
1284 } else {
1285 KeyedLoadFieldStub stub(true, length_index, Representation::Tagged());
1286 code = stub.GetCode(isolate());
1287 }
1281 } else if (!object->IsJSObject()) { 1288 } else if (!object->IsJSObject()) {
1282 // TODO(jkummerow): It would be nice to support non-JSObjects in 1289 // TODO(jkummerow): It would be nice to support non-JSObjects in
1283 // ComputeLoadHandler, then we wouldn't need to go generic here. 1290 // ComputeLoadHandler, then we wouldn't need to go generic here.
1284 code = slow_stub(); 1291 code = slow_stub();
1285 } else { 1292 } else {
1286 code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name); 1293 code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name);
1287 if (code.is_null()) code = slow_stub(); 1294 if (code.is_null()) code = slow_stub();
1288 } 1295 }
1289 1296
1290 PatchCache(state, kNonStrictMode, receiver, name, code); 1297 PatchCache(state, kNonStrictMode, receiver, name, code);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 CallOptimization call_optimization(function); 1362 CallOptimization call_optimization(function);
1356 if (call_optimization.is_simple_api_call() && 1363 if (call_optimization.is_simple_api_call() &&
1357 call_optimization.IsCompatibleReceiver(*receiver) && 1364 call_optimization.IsCompatibleReceiver(*receiver) &&
1358 FLAG_js_accessor_ics) { 1365 FLAG_js_accessor_ics) {
1359 return isolate()->stub_cache()->ComputeLoadCallback( 1366 return isolate()->stub_cache()->ComputeLoadCallback(
1360 name, receiver, holder, call_optimization); 1367 name, receiver, holder, call_optimization);
1361 } 1368 }
1362 return isolate()->stub_cache()->ComputeLoadViaGetter( 1369 return isolate()->stub_cache()->ComputeLoadViaGetter(
1363 name, receiver, holder, function); 1370 name, receiver, holder, function);
1364 } else if (receiver->IsJSArray() && 1371 } else if (receiver->IsJSArray() &&
1365 name->Equals(isolate()->heap()->length_string())) { 1372 name->Equals(isolate()->heap()->length_string())) {
1366 PropertyIndex lengthIndex = 1373 PropertyIndex lengthIndex = PropertyIndex::NewHeaderIndex(
1367 PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize); 1374 JSArray::kLengthOffset / kPointerSize);
1368 return isolate()->stub_cache()->ComputeLoadField( 1375 return isolate()->stub_cache()->ComputeLoadField(
1369 name, receiver, holder, lengthIndex, Representation::Tagged()); 1376 name, receiver, holder, lengthIndex, Representation::Tagged());
1370 } 1377 }
1371 // TODO(dcarney): Handle correctly. 1378 // TODO(dcarney): Handle correctly.
1372 if (callback->IsDeclaredAccessorInfo()) break; 1379 if (callback->IsDeclaredAccessorInfo()) break;
1373 ASSERT(callback->IsForeign()); 1380 ASSERT(callback->IsForeign());
1374 // No IC support for old-style native accessors. 1381 // No IC support for old-style native accessors.
1375 break; 1382 break;
1376 } 1383 }
1377 case INTERCEPTOR: 1384 case INTERCEPTOR:
(...skipping 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after
3133 #undef ADDR 3140 #undef ADDR
3134 }; 3141 };
3135 3142
3136 3143
3137 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3144 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3138 return IC_utilities[id]; 3145 return IC_utilities[id];
3139 } 3146 }
3140 3147
3141 3148
3142 } } // namespace v8::internal 3149 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698