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

Side by Side Diff: src/ic.cc

Issue 24205004: Rollback trunk to 3.21.16.2 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
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/isolate.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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 int index = frame->ComputeExpressionsCount() - (argc + 1); 542 int index = frame->ComputeExpressionsCount() - (argc + 1);
543 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); 543 frame->SetExpression(index, *isolate()->factory()->ToObject(object));
544 } 544 }
545 } 545 }
546 546
547 547
548 MaybeObject* CallICBase::LoadFunction(State state, 548 MaybeObject* CallICBase::LoadFunction(State state,
549 Code::ExtraICState extra_ic_state, 549 Code::ExtraICState extra_ic_state,
550 Handle<Object> object, 550 Handle<Object> object,
551 Handle<String> name) { 551 Handle<String> name) {
552 bool use_ic = FLAG_use_ic;
553 if (object->IsJSObject()) { 552 if (object->IsJSObject()) {
554 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 553 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
555 if (receiver->map()->is_deprecated()) { 554 if (receiver->map()->is_deprecated()) {
556 use_ic = false;
557 JSObject::MigrateInstance(receiver); 555 JSObject::MigrateInstance(receiver);
558 } 556 }
559 } 557 }
560 558
561 // If the object is undefined or null it's illegal to try to get any 559 // If the object is undefined or null it's illegal to try to get any
562 // of its properties; throw a TypeError in that case. 560 // of its properties; throw a TypeError in that case.
563 if (object->IsUndefined() || object->IsNull()) { 561 if (object->IsUndefined() || object->IsNull()) {
564 return TypeError("non_object_property_call", object, name); 562 return TypeError("non_object_property_call", object, name);
565 } 563 }
566 564
(...skipping 18 matching lines...) Expand all
585 583
586 if (!lookup.IsFound()) { 584 if (!lookup.IsFound()) {
587 // If the object does not have the requested property, check which 585 // If the object does not have the requested property, check which
588 // exception we need to throw. 586 // exception we need to throw.
589 return IsUndeclaredGlobal(object) 587 return IsUndeclaredGlobal(object)
590 ? ReferenceError("not_defined", name) 588 ? ReferenceError("not_defined", name)
591 : TypeError("undefined_method", object, name); 589 : TypeError("undefined_method", object, name);
592 } 590 }
593 591
594 // Lookup is valid: Update inline cache and stub cache. 592 // Lookup is valid: Update inline cache and stub cache.
595 if (use_ic) UpdateCaches(&lookup, state, extra_ic_state, object, name); 593 if (FLAG_use_ic) {
594 UpdateCaches(&lookup, state, extra_ic_state, object, name);
595 }
596 596
597 // Get the property. 597 // Get the property.
598 PropertyAttributes attr; 598 PropertyAttributes attr;
599 Handle<Object> result = 599 Handle<Object> result =
600 Object::GetProperty(object, object, &lookup, name, &attr); 600 Object::GetProperty(object, object, &lookup, name, &attr);
601 RETURN_IF_EMPTY_HANDLE(isolate(), result); 601 RETURN_IF_EMPTY_HANDLE(isolate(), result);
602 602
603 if (lookup.IsInterceptor() && attr == ABSENT) { 603 if (lookup.IsInterceptor() && attr == ABSENT) {
604 // If the object does not have the requested property, check which 604 // If the object does not have the requested property, check which
605 // exception we need to throw. 605 // exception we need to throw.
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
812 MaybeObject* KeyedCallIC::LoadFunction(State state, 812 MaybeObject* KeyedCallIC::LoadFunction(State state,
813 Handle<Object> object, 813 Handle<Object> object,
814 Handle<Object> key) { 814 Handle<Object> key) {
815 if (key->IsInternalizedString()) { 815 if (key->IsInternalizedString()) {
816 return CallICBase::LoadFunction(state, 816 return CallICBase::LoadFunction(state,
817 Code::kNoExtraICState, 817 Code::kNoExtraICState,
818 object, 818 object,
819 Handle<String>::cast(key)); 819 Handle<String>::cast(key));
820 } 820 }
821 821
822 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
823 if (object->IsJSObject()) { 822 if (object->IsJSObject()) {
824 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 823 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
825 if (receiver->map()->is_deprecated()) { 824 if (receiver->map()->is_deprecated()) {
826 use_ic = false;
827 JSObject::MigrateInstance(receiver); 825 JSObject::MigrateInstance(receiver);
828 } 826 }
829 } 827 }
830 828
831 if (object->IsUndefined() || object->IsNull()) { 829 if (object->IsUndefined() || object->IsNull()) {
832 return TypeError("non_object_property_call", object, key); 830 return TypeError("non_object_property_call", object, key);
833 } 831 }
834 832
833 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
835 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 834 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
836 835
837 if (use_ic && state != MEGAMORPHIC) { 836 if (use_ic && state != MEGAMORPHIC) {
838 int argc = target()->arguments_count(); 837 int argc = target()->arguments_count();
839 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic( 838 Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic(
840 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState); 839 argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
841 if (object->IsJSObject()) { 840 if (object->IsJSObject()) {
842 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 841 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
843 if (receiver->elements()->map() == 842 if (receiver->elements()->map() ==
844 isolate()->heap()->non_strict_arguments_elements_map()) { 843 isolate()->heap()->non_strict_arguments_elements_map()) {
(...skipping 23 matching lines...) Expand all
868 867
869 MaybeObject* LoadIC::Load(State state, 868 MaybeObject* LoadIC::Load(State state,
870 Handle<Object> object, 869 Handle<Object> object,
871 Handle<String> name) { 870 Handle<String> name) {
872 // If the object is undefined or null it's illegal to try to get any 871 // If the object is undefined or null it's illegal to try to get any
873 // of its properties; throw a TypeError in that case. 872 // of its properties; throw a TypeError in that case.
874 if (object->IsUndefined() || object->IsNull()) { 873 if (object->IsUndefined() || object->IsNull()) {
875 return TypeError("non_object_property_load", object, name); 874 return TypeError("non_object_property_load", object, name);
876 } 875 }
877 876
878 bool use_ic = FLAG_use_ic; 877 if (FLAG_use_ic) {
879
880 if (use_ic) {
881 // Use specialized code for getting the length of strings and 878 // Use specialized code for getting the length of strings and
882 // string wrapper objects. The length property of string wrapper 879 // string wrapper objects. The length property of string wrapper
883 // objects is read-only and therefore always returns the length of 880 // objects is read-only and therefore always returns the length of
884 // the underlying string value. See ECMA-262 15.5.5.1. 881 // the underlying string value. See ECMA-262 15.5.5.1.
885 if (object->IsStringWrapper() && 882 if ((object->IsString() || object->IsStringWrapper()) &&
886 name->Equals(isolate()->heap()->length_string())) { 883 name->Equals(isolate()->heap()->length_string())) {
887 Handle<Code> stub; 884 Handle<Code> stub;
888 if (state == UNINITIALIZED) { 885 if (state == UNINITIALIZED) {
889 stub = pre_monomorphic_stub(); 886 stub = pre_monomorphic_stub();
890 } else if (state == PREMONOMORPHIC || state == MONOMORPHIC) { 887 } else if (state == PREMONOMORPHIC) {
891 StringLengthStub string_length_stub(kind()); 888 StringLengthStub string_length_stub(kind(), !object->IsString());
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()); 892 stub = string_length_stub.GetCode(isolate());
893 } else if (state != MEGAMORPHIC) { 893 } else if (state != MEGAMORPHIC) {
894 ASSERT(state != GENERIC); 894 ASSERT(state != GENERIC);
895 stub = megamorphic_stub(); 895 stub = megamorphic_stub();
896 } 896 }
897 if (!stub.is_null()) { 897 if (!stub.is_null()) {
898 set_target(*stub); 898 set_target(*stub);
899 #ifdef DEBUG 899 #ifdef DEBUG
900 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /stringwrapper]\n"); 900 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
901 #endif 901 #endif
902 } 902 }
903 // Get the string if we have a string wrapper object. 903 // Get the string if we have a string wrapper object.
904 String* string = String::cast(JSValue::cast(*object)->value()); 904 Handle<Object> string = object->IsJSValue()
905 return Smi::FromInt(string->length()); 905 ? Handle<Object>(Handle<JSValue>::cast(object)->value(), isolate())
906 : object;
907 return Smi::FromInt(String::cast(*string)->length());
906 } 908 }
907 909
908 // Use specialized code for getting prototype of functions. 910 // Use specialized code for getting prototype of functions.
909 if (object->IsJSFunction() && 911 if (object->IsJSFunction() &&
910 name->Equals(isolate()->heap()->prototype_string()) && 912 name->Equals(isolate()->heap()->prototype_string()) &&
911 Handle<JSFunction>::cast(object)->should_have_prototype()) { 913 Handle<JSFunction>::cast(object)->should_have_prototype()) {
912 Handle<Code> stub; 914 Handle<Code> stub;
913 if (state == UNINITIALIZED) { 915 if (state == UNINITIALIZED) {
914 stub = pre_monomorphic_stub(); 916 stub = pre_monomorphic_stub();
915 } else if (state == PREMONOMORPHIC) { 917 } else if (state == PREMONOMORPHIC) {
(...skipping 11 matching lines...) Expand all
927 } 929 }
928 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object)); 930 return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object));
929 } 931 }
930 } 932 }
931 933
932 // Check if the name is trivially convertible to an index and get 934 // Check if the name is trivially convertible to an index and get
933 // the element or char if so. 935 // the element or char if so.
934 uint32_t index; 936 uint32_t index;
935 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { 937 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
936 // Rewrite to the generic keyed load stub. 938 // Rewrite to the generic keyed load stub.
937 if (use_ic) set_target(*generic_stub()); 939 if (FLAG_use_ic) set_target(*generic_stub());
938 return Runtime::GetElementOrCharAtOrFail(isolate(), object, index); 940 return Runtime::GetElementOrCharAtOrFail(isolate(), object, index);
939 } 941 }
940 942
941 if (object->IsJSObject()) { 943 if (object->IsJSObject()) {
942 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 944 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
943 if (receiver->map()->is_deprecated()) { 945 if (receiver->map()->is_deprecated()) {
944 use_ic = false;
945 JSObject::MigrateInstance(receiver); 946 JSObject::MigrateInstance(receiver);
946 } 947 }
947 } 948 }
948 949
949 // Named lookup in the object. 950 // Named lookup in the object.
950 LookupResult lookup(isolate()); 951 LookupResult lookup(isolate());
951 LookupForRead(object, name, &lookup); 952 LookupForRead(object, name, &lookup);
952 953
953 // If we did not find a property, check if we need to throw an exception. 954 // If we did not find a property, check if we need to throw an exception.
954 if (!lookup.IsFound()) { 955 if (!lookup.IsFound()) {
955 if (IsUndeclaredGlobal(object)) { 956 if (IsUndeclaredGlobal(object)) {
956 return ReferenceError("not_defined", name); 957 return ReferenceError("not_defined", name);
957 } 958 }
958 LOG(isolate(), SuspectReadEvent(*name, *object)); 959 LOG(isolate(), SuspectReadEvent(*name, *object));
959 } 960 }
960 961
961 // Update inline cache and stub cache. 962 // Update inline cache and stub cache.
962 if (use_ic) UpdateCaches(&lookup, state, object, name); 963 if (FLAG_use_ic) UpdateCaches(&lookup, state, object, name);
963 964
964 PropertyAttributes attr; 965 PropertyAttributes attr;
965 if (lookup.IsInterceptor() || lookup.IsHandler()) { 966 if (lookup.IsInterceptor() || lookup.IsHandler()) {
966 // Get the property. 967 // Get the property.
967 Handle<Object> result = 968 Handle<Object> result =
968 Object::GetProperty(object, object, &lookup, name, &attr); 969 Object::GetProperty(object, object, &lookup, name, &attr);
969 RETURN_IF_EMPTY_HANDLE(isolate(), result); 970 RETURN_IF_EMPTY_HANDLE(isolate(), result);
970 // If the property is not present, check if we need to throw an 971 // If the property is not present, check if we need to throw an
971 // exception. 972 // exception.
972 if (attr == ABSENT && IsUndeclaredGlobal(object)) { 973 if (attr == ABSENT && IsUndeclaredGlobal(object)) {
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 UNREACHABLE(); 1258 UNREACHABLE();
1258 break; 1259 break;
1259 } 1260 }
1260 } 1261 }
1261 1262
1262 1263
1263 void LoadIC::UpdateCaches(LookupResult* lookup, 1264 void LoadIC::UpdateCaches(LookupResult* lookup,
1264 State state, 1265 State state,
1265 Handle<Object> object, 1266 Handle<Object> object,
1266 Handle<String> name) { 1267 Handle<String> name) {
1267 // TODO(verwaest): It would be nice to support loading fields from smis as
1268 // well. For now just fail to update the cache.
1269 if (!object->IsHeapObject()) return; 1268 if (!object->IsHeapObject()) return;
1270 1269
1271 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object); 1270 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
1272 1271
1273 Handle<Code> code; 1272 Handle<Code> code;
1274 if (state == UNINITIALIZED) { 1273 if (state == UNINITIALIZED) {
1275 // This is the first time we execute this inline cache. 1274 // This is the first time we execute this inline cache.
1276 // Set the target to the pre monomorphic stub to delay 1275 // Set the target to the pre monomorphic stub to delay
1277 // setting the monomorphic state. 1276 // setting the monomorphic state.
1278 code = pre_monomorphic_stub(); 1277 code = pre_monomorphic_stub();
1279 } else if (!lookup->IsCacheable()) { 1278 } else if (!lookup->IsCacheable()) {
1280 // Bail out if the result is not cacheable. 1279 // Bail out if the result is not cacheable.
1281 code = slow_stub(); 1280 code = slow_stub();
1282 } else if (object->IsString() &&
1283 name->Equals(isolate()->heap()->length_string())) {
1284 int length_index = String::kLengthOffset / kPointerSize;
1285 if (target()->is_load_stub()) {
1286 LoadFieldStub stub(true, length_index, Representation::Tagged());
1287 code = stub.GetCode(isolate());
1288 } else {
1289 KeyedLoadFieldStub stub(true, length_index, Representation::Tagged());
1290 code = stub.GetCode(isolate());
1291 }
1292 } else if (!object->IsJSObject()) { 1281 } else if (!object->IsJSObject()) {
1293 // TODO(jkummerow): It would be nice to support non-JSObjects in 1282 // TODO(jkummerow): It would be nice to support non-JSObjects in
1294 // ComputeLoadHandler, then we wouldn't need to go generic here. 1283 // ComputeLoadHandler, then we wouldn't need to go generic here.
1295 code = slow_stub(); 1284 code = slow_stub();
1296 } else { 1285 } else {
1297 code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name); 1286 code = ComputeLoadHandler(lookup, Handle<JSObject>::cast(receiver), name);
1298 if (code.is_null()) code = slow_stub(); 1287 if (code.is_null()) code = slow_stub();
1299 } 1288 }
1300 1289
1301 PatchCache(state, kNonStrictMode, receiver, name, code); 1290 PatchCache(state, kNonStrictMode, receiver, name, code);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 name, receiver, holder, info); 1347 name, receiver, holder, info);
1359 } else if (callback->IsAccessorPair()) { 1348 } else if (callback->IsAccessorPair()) {
1360 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(), 1349 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(),
1361 isolate()); 1350 isolate());
1362 if (!getter->IsJSFunction()) break; 1351 if (!getter->IsJSFunction()) break;
1363 if (holder->IsGlobalObject()) break; 1352 if (holder->IsGlobalObject()) break;
1364 if (!holder->HasFastProperties()) break; 1353 if (!holder->HasFastProperties()) break;
1365 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); 1354 Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
1366 CallOptimization call_optimization(function); 1355 CallOptimization call_optimization(function);
1367 if (call_optimization.is_simple_api_call() && 1356 if (call_optimization.is_simple_api_call() &&
1368 call_optimization.IsCompatibleReceiver(*receiver)) { 1357 call_optimization.IsCompatibleReceiver(*receiver) &&
1358 FLAG_js_accessor_ics) {
1369 return isolate()->stub_cache()->ComputeLoadCallback( 1359 return isolate()->stub_cache()->ComputeLoadCallback(
1370 name, receiver, holder, call_optimization); 1360 name, receiver, holder, call_optimization);
1371 } 1361 }
1372 return isolate()->stub_cache()->ComputeLoadViaGetter( 1362 return isolate()->stub_cache()->ComputeLoadViaGetter(
1373 name, receiver, holder, function); 1363 name, receiver, holder, function);
1374 } else if (receiver->IsJSArray() && 1364 } else if (receiver->IsJSArray() &&
1375 name->Equals(isolate()->heap()->length_string())) { 1365 name->Equals(isolate()->heap()->length_string())) {
1376 PropertyIndex lengthIndex = PropertyIndex::NewHeaderIndex( 1366 PropertyIndex lengthIndex =
1377 JSArray::kLengthOffset / kPointerSize); 1367 PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize);
1378 return isolate()->stub_cache()->ComputeLoadField( 1368 return isolate()->stub_cache()->ComputeLoadField(
1379 name, receiver, holder, lengthIndex, Representation::Tagged()); 1369 name, receiver, holder, lengthIndex, Representation::Tagged());
1380 } 1370 }
1381 // TODO(dcarney): Handle correctly. 1371 // TODO(dcarney): Handle correctly.
1382 if (callback->IsDeclaredAccessorInfo()) break; 1372 if (callback->IsDeclaredAccessorInfo()) break;
1383 ASSERT(callback->IsForeign()); 1373 ASSERT(callback->IsForeign());
1384 // No IC support for old-style native accessors. 1374 // No IC support for old-style native accessors.
1385 break; 1375 break;
1386 } 1376 }
1387 case INTERCEPTOR: 1377 case INTERCEPTOR:
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1499 if (use_ic) { 1489 if (use_ic) {
1500 Handle<Code> stub = generic_stub(); 1490 Handle<Code> stub = generic_stub();
1501 if (miss_mode != MISS_FORCE_GENERIC) { 1491 if (miss_mode != MISS_FORCE_GENERIC) {
1502 if (object->IsString() && key->IsNumber()) { 1492 if (object->IsString() && key->IsNumber()) {
1503 if (state == UNINITIALIZED) { 1493 if (state == UNINITIALIZED) {
1504 stub = string_stub(); 1494 stub = string_stub();
1505 } 1495 }
1506 } else if (object->IsJSObject()) { 1496 } else if (object->IsJSObject()) {
1507 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1497 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1508 if (receiver->map()->is_deprecated()) { 1498 if (receiver->map()->is_deprecated()) {
1509 use_ic = false;
1510 JSObject::MigrateInstance(receiver); 1499 JSObject::MigrateInstance(receiver);
1511 } 1500 }
1512 1501
1513 if (receiver->elements()->map() == 1502 if (receiver->elements()->map() ==
1514 isolate()->heap()->non_strict_arguments_elements_map()) { 1503 isolate()->heap()->non_strict_arguments_elements_map()) {
1515 stub = non_strict_arguments_stub(); 1504 stub = non_strict_arguments_stub();
1516 } else if (receiver->HasIndexedInterceptor()) { 1505 } else if (receiver->HasIndexedInterceptor()) {
1517 stub = indexed_interceptor_stub(); 1506 stub = indexed_interceptor_stub();
1518 } else if (!key->ToSmi()->IsFailure() && 1507 } else if (!key->ToSmi()->IsFailure() &&
1519 (target() != *non_strict_arguments_stub())) { 1508 (target() != *non_strict_arguments_stub())) {
1520 stub = LoadElementStub(receiver); 1509 stub = LoadElementStub(receiver);
1521 } 1510 }
1522 } 1511 }
1523 } else { 1512 } else {
1524 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic"); 1513 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic");
1525 } 1514 }
1526 if (use_ic) { 1515 ASSERT(!stub.is_null());
1527 ASSERT(!stub.is_null()); 1516 set_target(*stub);
1528 set_target(*stub); 1517 TRACE_IC("KeyedLoadIC", key, state, target());
1529 TRACE_IC("KeyedLoadIC", key, state, target());
1530 }
1531 } 1518 }
1532 1519
1533 1520
1534 return Runtime::GetObjectPropertyOrFail(isolate(), object, key); 1521 return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
1535 } 1522 }
1536 1523
1537 1524
1538 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup, 1525 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
1539 Handle<JSObject> receiver, 1526 Handle<JSObject> receiver,
1540 Handle<String> name) { 1527 Handle<String> name) {
(...skipping 28 matching lines...) Expand all
1569 } else if (callback_object->IsAccessorPair()) { 1556 } else if (callback_object->IsAccessorPair()) {
1570 Handle<Object> getter( 1557 Handle<Object> getter(
1571 Handle<AccessorPair>::cast(callback_object)->getter(), 1558 Handle<AccessorPair>::cast(callback_object)->getter(),
1572 isolate()); 1559 isolate());
1573 if (!getter->IsJSFunction()) break; 1560 if (!getter->IsJSFunction()) break;
1574 if (holder->IsGlobalObject()) break; 1561 if (holder->IsGlobalObject()) break;
1575 if (!holder->HasFastProperties()) break; 1562 if (!holder->HasFastProperties()) break;
1576 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); 1563 Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
1577 CallOptimization call_optimization(function); 1564 CallOptimization call_optimization(function);
1578 if (call_optimization.is_simple_api_call() && 1565 if (call_optimization.is_simple_api_call() &&
1579 call_optimization.IsCompatibleReceiver(*receiver)) { 1566 call_optimization.IsCompatibleReceiver(*receiver) &&
1567 FLAG_js_accessor_ics) {
1580 return isolate()->stub_cache()->ComputeKeyedLoadCallback( 1568 return isolate()->stub_cache()->ComputeKeyedLoadCallback(
1581 name, receiver, holder, call_optimization); 1569 name, receiver, holder, call_optimization);
1582 } 1570 }
1583 } 1571 }
1584 break; 1572 break;
1585 } 1573 }
1586 case INTERCEPTOR: 1574 case INTERCEPTOR:
1587 ASSERT(HasInterceptorGetter(lookup->holder())); 1575 ASSERT(HasInterceptorGetter(lookup->holder()));
1588 return isolate()->stub_cache()->ComputeKeyedLoadInterceptor( 1576 return isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
1589 name, receiver, holder); 1577 name, receiver, holder);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1661 1649
1662 1650
1663 MaybeObject* StoreIC::Store(State state, 1651 MaybeObject* StoreIC::Store(State state,
1664 StrictModeFlag strict_mode, 1652 StrictModeFlag strict_mode,
1665 Handle<Object> object, 1653 Handle<Object> object,
1666 Handle<String> name, 1654 Handle<String> name,
1667 Handle<Object> value, 1655 Handle<Object> value,
1668 JSReceiver::StoreFromKeyed store_mode) { 1656 JSReceiver::StoreFromKeyed store_mode) {
1669 // Handle proxies. 1657 // Handle proxies.
1670 if (object->IsJSProxy()) { 1658 if (object->IsJSProxy()) {
1671 Handle<Object> result = JSReceiver::SetProperty( 1659 return JSReceiver::SetPropertyOrFail(
1672 Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode); 1660 Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode);
1673 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1674 return *result;
1675 } 1661 }
1676 1662
1677 // If the object is undefined or null it's illegal to try to set any 1663 // If the object is undefined or null it's illegal to try to set any
1678 // properties on it; throw a TypeError in that case. 1664 // properties on it; throw a TypeError in that case.
1679 if (object->IsUndefined() || object->IsNull()) { 1665 if (object->IsUndefined() || object->IsNull()) {
1680 return TypeError("non_object_property_store", object, name); 1666 return TypeError("non_object_property_store", object, name);
1681 } 1667 }
1682 1668
1683 // The length property of string values is read-only. Throw in strict mode. 1669 // The length property of string values is read-only. Throw in strict mode.
1684 if (strict_mode == kStrictMode && object->IsString() && 1670 if (strict_mode == kStrictMode && object->IsString() &&
1685 name->Equals(isolate()->heap()->length_string())) { 1671 name->Equals(isolate()->heap()->length_string())) {
1686 return TypeError("strict_read_only_property", object, name); 1672 return TypeError("strict_read_only_property", object, name);
1687 } 1673 }
1688 1674
1689 // Ignore other stores where the receiver is not a JSObject. 1675 // Ignore other stores where the receiver is not a JSObject.
1690 // TODO(1475): Must check prototype chains of object wrappers. 1676 // TODO(1475): Must check prototype chains of object wrappers.
1691 if (!object->IsJSObject()) return *value; 1677 if (!object->IsJSObject()) return *value;
1692 1678
1693 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1679 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1694 1680
1695 bool use_ic = FLAG_use_ic;
1696 if (receiver->map()->is_deprecated()) { 1681 if (receiver->map()->is_deprecated()) {
1697 use_ic = false;
1698 JSObject::MigrateInstance(receiver); 1682 JSObject::MigrateInstance(receiver);
1699 } 1683 }
1700 1684
1701 // Check if the given name is an array index. 1685 // Check if the given name is an array index.
1702 uint32_t index; 1686 uint32_t index;
1703 if (name->AsArrayIndex(&index)) { 1687 if (name->AsArrayIndex(&index)) {
1704 Handle<Object> result = 1688 Handle<Object> result =
1705 JSObject::SetElement(receiver, index, value, NONE, strict_mode); 1689 JSObject::SetElement(receiver, index, value, NONE, strict_mode);
1706 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1690 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1707 return *value; 1691 return *value;
1708 } 1692 }
1709 1693
1710 // Observed objects are always modified through the runtime. 1694 // Observed objects are always modified through the runtime.
1711 if (FLAG_harmony_observation && receiver->map()->is_observed()) { 1695 if (FLAG_harmony_observation && receiver->map()->is_observed()) {
1712 Handle<Object> result = JSReceiver::SetProperty( 1696 return JSReceiver::SetPropertyOrFail(
1713 receiver, name, value, NONE, strict_mode, store_mode); 1697 receiver, name, value, NONE, strict_mode, store_mode);
1714 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1715 return *result;
1716 } 1698 }
1717 1699
1718 // Use specialized code for setting the length of arrays with fast 1700 // Use specialized code for setting the length of arrays with fast
1719 // properties. Slow properties might indicate redefinition of the length 1701 // properties. Slow properties might indicate redefinition of the length
1720 // property. Note that when redefined using Object.freeze, it's possible 1702 // property. Note that when redefined using Object.freeze, it's possible
1721 // to have fast properties but a read-only length. 1703 // to have fast properties but a read-only length.
1722 if (use_ic && 1704 if (FLAG_use_ic &&
1723 receiver->IsJSArray() && 1705 receiver->IsJSArray() &&
1724 name->Equals(isolate()->heap()->length_string()) && 1706 name->Equals(isolate()->heap()->length_string()) &&
1725 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && 1707 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
1726 receiver->HasFastProperties() && 1708 receiver->HasFastProperties() &&
1727 !receiver->map()->is_frozen()) { 1709 !receiver->map()->is_frozen()) {
1728 Handle<Code> stub = 1710 Handle<Code> stub =
1729 StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate()); 1711 StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate());
1730 set_target(*stub); 1712 set_target(*stub);
1731 TRACE_IC("StoreIC", name, state, *stub); 1713 TRACE_IC("StoreIC", name, state, *stub);
1732 Handle<Object> result = JSReceiver::SetProperty( 1714 return JSReceiver::SetPropertyOrFail(
1733 receiver, name, value, NONE, strict_mode, store_mode); 1715 receiver, name, value, NONE, strict_mode, store_mode);
1734 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1735 return *result;
1736 } 1716 }
1737 1717
1738 if (receiver->IsJSGlobalProxy()) { 1718 if (receiver->IsJSGlobalProxy()) {
1739 if (use_ic && kind() != Code::KEYED_STORE_IC) { 1719 if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) {
1740 // Generate a generic stub that goes to the runtime when we see a global 1720 // Generate a generic stub that goes to the runtime when we see a global
1741 // proxy as receiver. 1721 // proxy as receiver.
1742 Handle<Code> stub = (strict_mode == kStrictMode) 1722 Handle<Code> stub = (strict_mode == kStrictMode)
1743 ? global_proxy_stub_strict() 1723 ? global_proxy_stub_strict()
1744 : global_proxy_stub(); 1724 : global_proxy_stub();
1745 set_target(*stub); 1725 set_target(*stub);
1746 TRACE_IC("StoreIC", name, state, *stub); 1726 TRACE_IC("StoreIC", name, state, *stub);
1747 } 1727 }
1748 Handle<Object> result = JSReceiver::SetProperty( 1728 return JSReceiver::SetPropertyOrFail(
1749 receiver, name, value, NONE, strict_mode, store_mode); 1729 receiver, name, value, NONE, strict_mode, store_mode);
1750 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1751 return *result;
1752 } 1730 }
1753 1731
1754 LookupResult lookup(isolate()); 1732 LookupResult lookup(isolate());
1755 bool can_store = LookupForWrite(receiver, name, value, &lookup, &state); 1733 bool can_store = LookupForWrite(receiver, name, value, &lookup, &state);
1756 if (!can_store && 1734 if (!can_store &&
1757 strict_mode == kStrictMode && 1735 strict_mode == kStrictMode &&
1758 !(lookup.IsProperty() && lookup.IsReadOnly()) && 1736 !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1759 IsUndeclaredGlobal(object)) { 1737 IsUndeclaredGlobal(object)) {
1760 // Strict mode doesn't allow setting non-existent global property. 1738 // Strict mode doesn't allow setting non-existent global property.
1761 return ReferenceError("not_defined", name); 1739 return ReferenceError("not_defined", name);
1762 } 1740 }
1763 if (use_ic) { 1741 if (FLAG_use_ic) {
1764 if (state == UNINITIALIZED) { 1742 if (state == UNINITIALIZED) {
1765 Handle<Code> stub = (strict_mode == kStrictMode) 1743 Handle<Code> stub = (strict_mode == kStrictMode)
1766 ? pre_monomorphic_stub_strict() 1744 ? pre_monomorphic_stub_strict()
1767 : pre_monomorphic_stub(); 1745 : pre_monomorphic_stub();
1768 set_target(*stub); 1746 set_target(*stub);
1769 TRACE_IC("StoreIC", name, state, *stub); 1747 TRACE_IC("StoreIC", name, state, *stub);
1770 } else if (can_store) { 1748 } else if (can_store) {
1771 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); 1749 UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1772 } else if (!name->IsCacheable(isolate()) || 1750 } else if (!name->IsCacheable(isolate()) ||
1773 lookup.IsNormal() || 1751 lookup.IsNormal() ||
1774 (lookup.IsField() && lookup.CanHoldValue(value))) { 1752 (lookup.IsField() && lookup.CanHoldValue(value))) {
1775 Handle<Code> stub = (strict_mode == kStrictMode) ? generic_stub_strict() 1753 Handle<Code> stub = (strict_mode == kStrictMode) ? generic_stub_strict()
1776 : generic_stub(); 1754 : generic_stub();
1777 set_target(*stub); 1755 set_target(*stub);
1778 } 1756 }
1779 } 1757 }
1780 1758
1781 // Set the property. 1759 // Set the property.
1782 Handle<Object> result = JSReceiver::SetProperty( 1760 return JSReceiver::SetPropertyOrFail(
1783 receiver, name, value, NONE, strict_mode, store_mode); 1761 receiver, name, value, NONE, strict_mode, store_mode);
1784 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1785 return *result;
1786 } 1762 }
1787 1763
1788 1764
1789 void StoreIC::UpdateCaches(LookupResult* lookup, 1765 void StoreIC::UpdateCaches(LookupResult* lookup,
1790 State state, 1766 State state,
1791 StrictModeFlag strict_mode, 1767 StrictModeFlag strict_mode,
1792 Handle<JSObject> receiver, 1768 Handle<JSObject> receiver,
1793 Handle<String> name, 1769 Handle<String> name,
1794 Handle<Object> value) { 1770 Handle<Object> value) {
1795 ASSERT(!receiver->IsJSGlobalProxy()); 1771 ASSERT(!receiver->IsJSGlobalProxy());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 name, receiver, holder, info, strict_mode); 1823 name, receiver, holder, info, strict_mode);
1848 } else if (callback->IsAccessorPair()) { 1824 } else if (callback->IsAccessorPair()) {
1849 Handle<Object> setter( 1825 Handle<Object> setter(
1850 Handle<AccessorPair>::cast(callback)->setter(), isolate()); 1826 Handle<AccessorPair>::cast(callback)->setter(), isolate());
1851 if (!setter->IsJSFunction()) break; 1827 if (!setter->IsJSFunction()) break;
1852 if (holder->IsGlobalObject()) break; 1828 if (holder->IsGlobalObject()) break;
1853 if (!holder->HasFastProperties()) break; 1829 if (!holder->HasFastProperties()) break;
1854 Handle<JSFunction> function = Handle<JSFunction>::cast(setter); 1830 Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
1855 CallOptimization call_optimization(function); 1831 CallOptimization call_optimization(function);
1856 if (call_optimization.is_simple_api_call() && 1832 if (call_optimization.is_simple_api_call() &&
1857 call_optimization.IsCompatibleReceiver(*receiver)) { 1833 call_optimization.IsCompatibleReceiver(*receiver) &&
1834 FLAG_js_accessor_ics) {
1858 return isolate()->stub_cache()->ComputeStoreCallback( 1835 return isolate()->stub_cache()->ComputeStoreCallback(
1859 name, receiver, holder, call_optimization, strict_mode); 1836 name, receiver, holder, call_optimization, strict_mode);
1860 } 1837 }
1861 return isolate()->stub_cache()->ComputeStoreViaSetter( 1838 return isolate()->stub_cache()->ComputeStoreViaSetter(
1862 name, receiver, holder, Handle<JSFunction>::cast(setter), 1839 name, receiver, holder, Handle<JSFunction>::cast(setter),
1863 strict_mode); 1840 strict_mode);
1864 } 1841 }
1865 // TODO(dcarney): Handle correctly. 1842 // TODO(dcarney): Handle correctly.
1866 if (callback->IsDeclaredAccessorInfo()) break; 1843 if (callback->IsDeclaredAccessorInfo()) break;
1867 ASSERT(callback->IsForeign()); 1844 ASSERT(callback->IsForeign());
(...skipping 1288 matching lines...) Expand 10 before | Expand all | Expand 10 after
3156 #undef ADDR 3133 #undef ADDR
3157 }; 3134 };
3158 3135
3159 3136
3160 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3137 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3161 return IC_utilities[id]; 3138 return IC_utilities[id];
3162 } 3139 }
3163 3140
3164 3141
3165 } } // namespace v8::internal 3142 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/isolate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698