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

Side by Side Diff: src/ic.cc

Issue 23890030: Rollback trunk to 3.21.15. (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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
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) &&
1369 FLAG_js_accessor_ics) { 1358 FLAG_js_accessor_ics) {
1370 return isolate()->stub_cache()->ComputeLoadCallback( 1359 return isolate()->stub_cache()->ComputeLoadCallback(
1371 name, receiver, holder, call_optimization); 1360 name, receiver, holder, call_optimization);
1372 } 1361 }
1373 return isolate()->stub_cache()->ComputeLoadViaGetter( 1362 return isolate()->stub_cache()->ComputeLoadViaGetter(
1374 name, receiver, holder, function); 1363 name, receiver, holder, function);
1375 } else if (receiver->IsJSArray() && 1364 } else if (receiver->IsJSArray() &&
1376 name->Equals(isolate()->heap()->length_string())) { 1365 name->Equals(isolate()->heap()->length_string())) {
1377 PropertyIndex lengthIndex = PropertyIndex::NewHeaderIndex( 1366 PropertyIndex lengthIndex =
1378 JSArray::kLengthOffset / kPointerSize); 1367 PropertyIndex::NewHeaderIndex(JSArray::kLengthOffset / kPointerSize);
1379 return isolate()->stub_cache()->ComputeLoadField( 1368 return isolate()->stub_cache()->ComputeLoadField(
1380 name, receiver, holder, lengthIndex, Representation::Tagged()); 1369 name, receiver, holder, lengthIndex, Representation::Tagged());
1381 } 1370 }
1382 // TODO(dcarney): Handle correctly. 1371 // TODO(dcarney): Handle correctly.
1383 if (callback->IsDeclaredAccessorInfo()) break; 1372 if (callback->IsDeclaredAccessorInfo()) break;
1384 ASSERT(callback->IsForeign()); 1373 ASSERT(callback->IsForeign());
1385 // No IC support for old-style native accessors. 1374 // No IC support for old-style native accessors.
1386 break; 1375 break;
1387 } 1376 }
1388 case INTERCEPTOR: 1377 case INTERCEPTOR:
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1500 if (use_ic) { 1489 if (use_ic) {
1501 Handle<Code> stub = generic_stub(); 1490 Handle<Code> stub = generic_stub();
1502 if (miss_mode != MISS_FORCE_GENERIC) { 1491 if (miss_mode != MISS_FORCE_GENERIC) {
1503 if (object->IsString() && key->IsNumber()) { 1492 if (object->IsString() && key->IsNumber()) {
1504 if (state == UNINITIALIZED) { 1493 if (state == UNINITIALIZED) {
1505 stub = string_stub(); 1494 stub = string_stub();
1506 } 1495 }
1507 } else if (object->IsJSObject()) { 1496 } else if (object->IsJSObject()) {
1508 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1497 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1509 if (receiver->map()->is_deprecated()) { 1498 if (receiver->map()->is_deprecated()) {
1510 use_ic = false;
1511 JSObject::MigrateInstance(receiver); 1499 JSObject::MigrateInstance(receiver);
1512 } 1500 }
1513 1501
1514 if (receiver->elements()->map() == 1502 if (receiver->elements()->map() ==
1515 isolate()->heap()->non_strict_arguments_elements_map()) { 1503 isolate()->heap()->non_strict_arguments_elements_map()) {
1516 stub = non_strict_arguments_stub(); 1504 stub = non_strict_arguments_stub();
1517 } else if (receiver->HasIndexedInterceptor()) { 1505 } else if (receiver->HasIndexedInterceptor()) {
1518 stub = indexed_interceptor_stub(); 1506 stub = indexed_interceptor_stub();
1519 } else if (!key->ToSmi()->IsFailure() && 1507 } else if (!key->ToSmi()->IsFailure() &&
1520 (target() != *non_strict_arguments_stub())) { 1508 (target() != *non_strict_arguments_stub())) {
1521 stub = LoadElementStub(receiver); 1509 stub = LoadElementStub(receiver);
1522 } 1510 }
1523 } 1511 }
1524 } else { 1512 } else {
1525 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic"); 1513 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic");
1526 } 1514 }
1527 if (use_ic) { 1515 ASSERT(!stub.is_null());
1528 ASSERT(!stub.is_null()); 1516 set_target(*stub);
1529 set_target(*stub); 1517 TRACE_IC("KeyedLoadIC", key, state, target());
1530 TRACE_IC("KeyedLoadIC", key, state, target());
1531 }
1532 } 1518 }
1533 1519
1534 1520
1535 return Runtime::GetObjectPropertyOrFail(isolate(), object, key); 1521 return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
1536 } 1522 }
1537 1523
1538 1524
1539 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup, 1525 Handle<Code> KeyedLoadIC::ComputeLoadHandler(LookupResult* lookup,
1540 Handle<JSObject> receiver, 1526 Handle<JSObject> receiver,
1541 Handle<String> name) { 1527 Handle<String> name) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 return JSReceiver::SetPropertyOrFail( 1696 return JSReceiver::SetPropertyOrFail(
1713 receiver, name, value, NONE, strict_mode, store_mode); 1697 receiver, name, value, NONE, strict_mode, store_mode);
1714 } 1698 }
1715 1699
1716 // Use specialized code for setting the length of arrays with fast 1700 // Use specialized code for setting the length of arrays with fast
1717 // properties. Slow properties might indicate redefinition of the length 1701 // properties. Slow properties might indicate redefinition of the length
1718 // property. Note that when redefined using Object.freeze, it's possible 1702 // property. Note that when redefined using Object.freeze, it's possible
1719 // to have fast properties but a read-only length. 1703 // to have fast properties but a read-only length.
1720 if (use_ic && 1704 if (FLAG_use_ic &&
1721 receiver->IsJSArray() && 1705 receiver->IsJSArray() &&
1722 name->Equals(isolate()->heap()->length_string()) && 1706 name->Equals(isolate()->heap()->length_string()) &&
1723 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && 1707 Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
1724 receiver->HasFastProperties() && 1708 receiver->HasFastProperties() &&
1725 !receiver->map()->is_frozen()) { 1709 !receiver->map()->is_frozen()) {
1726 Handle<Code> stub = 1710 Handle<Code> stub =
1727 StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate()); 1711 StoreArrayLengthStub(kind(), strict_mode).GetCode(isolate());
1728 set_target(*stub); 1712 set_target(*stub);
1729 TRACE_IC("StoreIC", name, state, *stub); 1713 TRACE_IC("StoreIC", name, state, *stub);
1730 return JSReceiver::SetPropertyOrFail( 1714 return JSReceiver::SetPropertyOrFail(
1731 receiver, name, value, NONE, strict_mode, store_mode); 1715 receiver, name, value, NONE, strict_mode, store_mode);
1732 } 1716 }
1733 1717
1734 if (receiver->IsJSGlobalProxy()) { 1718 if (receiver->IsJSGlobalProxy()) {
1735 if (use_ic && kind() != Code::KEYED_STORE_IC) { 1719 if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) {
1736 // 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
1737 // proxy as receiver. 1721 // proxy as receiver.
1738 Handle<Code> stub = (strict_mode == kStrictMode) 1722 Handle<Code> stub = (strict_mode == kStrictMode)
1739 ? global_proxy_stub_strict() 1723 ? global_proxy_stub_strict()
1740 : global_proxy_stub(); 1724 : global_proxy_stub();
1741 set_target(*stub); 1725 set_target(*stub);
1742 TRACE_IC("StoreIC", name, state, *stub); 1726 TRACE_IC("StoreIC", name, state, *stub);
1743 } 1727 }
1744 return JSReceiver::SetPropertyOrFail( 1728 return JSReceiver::SetPropertyOrFail(
1745 receiver, name, value, NONE, strict_mode, store_mode); 1729 receiver, name, value, NONE, strict_mode, store_mode);
1746 } 1730 }
1747 1731
1748 LookupResult lookup(isolate()); 1732 LookupResult lookup(isolate());
1749 bool can_store = LookupForWrite(receiver, name, value, &lookup, &state); 1733 bool can_store = LookupForWrite(receiver, name, value, &lookup, &state);
1750 if (!can_store && 1734 if (!can_store &&
1751 strict_mode == kStrictMode && 1735 strict_mode == kStrictMode &&
1752 !(lookup.IsProperty() && lookup.IsReadOnly()) && 1736 !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1753 IsUndeclaredGlobal(object)) { 1737 IsUndeclaredGlobal(object)) {
1754 // Strict mode doesn't allow setting non-existent global property. 1738 // Strict mode doesn't allow setting non-existent global property.
1755 return ReferenceError("not_defined", name); 1739 return ReferenceError("not_defined", name);
1756 } 1740 }
1757 if (use_ic) { 1741 if (FLAG_use_ic) {
1758 if (state == UNINITIALIZED) { 1742 if (state == UNINITIALIZED) {
1759 Handle<Code> stub = (strict_mode == kStrictMode) 1743 Handle<Code> stub = (strict_mode == kStrictMode)
1760 ? pre_monomorphic_stub_strict() 1744 ? pre_monomorphic_stub_strict()
1761 : pre_monomorphic_stub(); 1745 : pre_monomorphic_stub();
1762 set_target(*stub); 1746 set_target(*stub);
1763 TRACE_IC("StoreIC", name, state, *stub); 1747 TRACE_IC("StoreIC", name, state, *stub);
1764 } else if (can_store) { 1748 } else if (can_store) {
1765 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); 1749 UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1766 } else if (!name->IsCacheable(isolate()) || 1750 } else if (!name->IsCacheable(isolate()) ||
1767 lookup.IsNormal() || 1751 lookup.IsNormal() ||
(...skipping 1381 matching lines...) Expand 10 before | Expand all | Expand 10 after
3149 #undef ADDR 3133 #undef ADDR
3150 }; 3134 };
3151 3135
3152 3136
3153 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3137 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3154 return IC_utilities[id]; 3138 return IC_utilities[id];
3155 } 3139 }
3156 3140
3157 3141
3158 } } // 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