| OLD | NEW |
| 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 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 static void LookupForRead(Handle<Object> object, | 428 static void LookupForRead(Handle<Object> object, |
| 429 Handle<String> name, | 429 Handle<String> name, |
| 430 LookupResult* lookup) { | 430 LookupResult* lookup) { |
| 431 // Skip all the objects with named interceptors, but | 431 // Skip all the objects with named interceptors, but |
| 432 // without actual getter. | 432 // without actual getter. |
| 433 while (true) { | 433 while (true) { |
| 434 object->Lookup(*name, lookup); | 434 object->Lookup(*name, lookup); |
| 435 // Besides normal conditions (property not found or it's not | 435 // Besides normal conditions (property not found or it's not |
| 436 // an interceptor), bail out if lookup is not cacheable: we won't | 436 // an interceptor), bail out if lookup is not cacheable: we won't |
| 437 // be able to IC it anyway and regular lookup should work fine. | 437 // be able to IC it anyway and regular lookup should work fine. |
| 438 if (!lookup->IsFound() | 438 if (!lookup->IsInterceptor() || !lookup->IsCacheable()) { |
| 439 || (lookup->type() != INTERCEPTOR) | |
| 440 || !lookup->IsCacheable()) { | |
| 441 return; | 439 return; |
| 442 } | 440 } |
| 443 | 441 |
| 444 Handle<JSObject> holder(lookup->holder()); | 442 Handle<JSObject> holder(lookup->holder()); |
| 445 if (HasInterceptorGetter(*holder)) { | 443 if (HasInterceptorGetter(*holder)) { |
| 446 return; | 444 return; |
| 447 } | 445 } |
| 448 | 446 |
| 449 holder->LocalLookupRealNamedProperty(*name, lookup); | 447 holder->LocalLookupRealNamedProperty(*name, lookup); |
| 450 if (lookup->IsProperty()) { | 448 if (lookup->IsProperty()) { |
| 451 ASSERT(lookup->type() != INTERCEPTOR); | 449 ASSERT(!lookup->IsInterceptor()); |
| 452 return; | 450 return; |
| 453 } | 451 } |
| 454 | 452 |
| 455 Handle<Object> proto(holder->GetPrototype()); | 453 Handle<Object> proto(holder->GetPrototype()); |
| 456 if (proto->IsNull()) { | 454 if (proto->IsNull()) { |
| 457 lookup->NotFound(); | 455 lookup->NotFound(); |
| 458 return; | 456 return; |
| 459 } | 457 } |
| 460 | 458 |
| 461 object = proto; | 459 object = proto; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 if (FLAG_use_ic) { | 545 if (FLAG_use_ic) { |
| 548 UpdateCaches(&lookup, state, extra_ic_state, object, name); | 546 UpdateCaches(&lookup, state, extra_ic_state, object, name); |
| 549 } | 547 } |
| 550 | 548 |
| 551 // Get the property. | 549 // Get the property. |
| 552 PropertyAttributes attr; | 550 PropertyAttributes attr; |
| 553 Handle<Object> result = | 551 Handle<Object> result = |
| 554 Object::GetProperty(object, object, &lookup, name, &attr); | 552 Object::GetProperty(object, object, &lookup, name, &attr); |
| 555 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 553 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 556 | 554 |
| 557 if (lookup.type() == INTERCEPTOR && attr == ABSENT) { | 555 if (lookup.IsInterceptor() && attr == ABSENT) { |
| 558 // If the object does not have the requested property, check which | 556 // If the object does not have the requested property, check which |
| 559 // exception we need to throw. | 557 // exception we need to throw. |
| 560 return IsContextual(object) | 558 return IsContextual(object) |
| 561 ? ReferenceError("not_defined", name) | 559 ? ReferenceError("not_defined", name) |
| 562 : TypeError("undefined_method", object, name); | 560 : TypeError("undefined_method", object, name); |
| 563 } | 561 } |
| 564 | 562 |
| 565 ASSERT(!result->IsTheHole()); | 563 ASSERT(!result->IsTheHole()); |
| 566 | 564 |
| 567 // Make receiver an object if the callee requires it. Strict mode or builtin | 565 // Make receiver an object if the callee requires it. Strict mode or builtin |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 } | 906 } |
| 909 LOG(isolate(), SuspectReadEvent(*name, *object)); | 907 LOG(isolate(), SuspectReadEvent(*name, *object)); |
| 910 } | 908 } |
| 911 | 909 |
| 912 // Update inline cache and stub cache. | 910 // Update inline cache and stub cache. |
| 913 if (FLAG_use_ic) { | 911 if (FLAG_use_ic) { |
| 914 UpdateCaches(&lookup, state, object, name); | 912 UpdateCaches(&lookup, state, object, name); |
| 915 } | 913 } |
| 916 | 914 |
| 917 PropertyAttributes attr; | 915 PropertyAttributes attr; |
| 918 if (lookup.IsFound() && | 916 if (lookup.IsInterceptor() || lookup.IsHandler()) { |
| 919 (lookup.type() == INTERCEPTOR || lookup.type() == HANDLER)) { | |
| 920 // Get the property. | 917 // Get the property. |
| 921 Handle<Object> result = | 918 Handle<Object> result = |
| 922 Object::GetProperty(object, object, &lookup, name, &attr); | 919 Object::GetProperty(object, object, &lookup, name, &attr); |
| 923 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 920 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 924 // If the property is not present, check if we need to throw an | 921 // If the property is not present, check if we need to throw an |
| 925 // exception. | 922 // exception. |
| 926 if (attr == ABSENT && IsContextual(object)) { | 923 if (attr == ABSENT && IsContextual(object)) { |
| 927 return ReferenceError("not_defined", name); | 924 return ReferenceError("not_defined", name); |
| 928 } | 925 } |
| 929 return *result; | 926 return *result; |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 // If we did not find a property, check if we need to throw an exception. | 1167 // If we did not find a property, check if we need to throw an exception. |
| 1171 if (!lookup.IsProperty() && IsContextual(object)) { | 1168 if (!lookup.IsProperty() && IsContextual(object)) { |
| 1172 return ReferenceError("not_defined", name); | 1169 return ReferenceError("not_defined", name); |
| 1173 } | 1170 } |
| 1174 | 1171 |
| 1175 if (FLAG_use_ic) { | 1172 if (FLAG_use_ic) { |
| 1176 UpdateCaches(&lookup, state, object, name); | 1173 UpdateCaches(&lookup, state, object, name); |
| 1177 } | 1174 } |
| 1178 | 1175 |
| 1179 PropertyAttributes attr; | 1176 PropertyAttributes attr; |
| 1180 if (lookup.IsFound() && lookup.type() == INTERCEPTOR) { | 1177 if (lookup.IsInterceptor()) { |
| 1181 // Get the property. | 1178 // Get the property. |
| 1182 Handle<Object> result = | 1179 Handle<Object> result = |
| 1183 Object::GetProperty(object, object, &lookup, name, &attr); | 1180 Object::GetProperty(object, object, &lookup, name, &attr); |
| 1184 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1181 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 1185 // If the property is not present, check if we need to throw an | 1182 // If the property is not present, check if we need to throw an |
| 1186 // exception. | 1183 // exception. |
| 1187 if (attr == ABSENT && IsContextual(object)) { | 1184 if (attr == ABSENT && IsContextual(object)) { |
| 1188 return ReferenceError("not_defined", name); | 1185 return ReferenceError("not_defined", name); |
| 1189 } | 1186 } |
| 1190 return *result; | 1187 return *result; |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1314 | 1311 |
| 1315 | 1312 |
| 1316 static bool LookupForWrite(Handle<JSObject> receiver, | 1313 static bool LookupForWrite(Handle<JSObject> receiver, |
| 1317 Handle<String> name, | 1314 Handle<String> name, |
| 1318 LookupResult* lookup) { | 1315 LookupResult* lookup) { |
| 1319 receiver->LocalLookup(*name, lookup); | 1316 receiver->LocalLookup(*name, lookup); |
| 1320 if (!StoreICableLookup(lookup)) { | 1317 if (!StoreICableLookup(lookup)) { |
| 1321 return false; | 1318 return false; |
| 1322 } | 1319 } |
| 1323 | 1320 |
| 1324 if (lookup->type() == INTERCEPTOR && | 1321 if (lookup->IsInterceptor() && |
| 1325 receiver->GetNamedInterceptor()->setter()->IsUndefined()) { | 1322 receiver->GetNamedInterceptor()->setter()->IsUndefined()) { |
| 1326 receiver->LocalLookupRealNamedProperty(*name, lookup); | 1323 receiver->LocalLookupRealNamedProperty(*name, lookup); |
| 1327 return StoreICableLookup(lookup); | 1324 return StoreICableLookup(lookup); |
| 1328 } | 1325 } |
| 1329 | 1326 |
| 1330 return true; | 1327 return true; |
| 1331 } | 1328 } |
| 1332 | 1329 |
| 1333 | 1330 |
| 1334 MaybeObject* StoreIC::Store(State state, | 1331 MaybeObject* StoreIC::Store(State state, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1431 | 1428 |
| 1432 void StoreIC::UpdateCaches(LookupResult* lookup, | 1429 void StoreIC::UpdateCaches(LookupResult* lookup, |
| 1433 State state, | 1430 State state, |
| 1434 StrictModeFlag strict_mode, | 1431 StrictModeFlag strict_mode, |
| 1435 Handle<JSObject> receiver, | 1432 Handle<JSObject> receiver, |
| 1436 Handle<String> name, | 1433 Handle<String> name, |
| 1437 Handle<Object> value) { | 1434 Handle<Object> value) { |
| 1438 ASSERT(!receiver->IsJSGlobalProxy()); | 1435 ASSERT(!receiver->IsJSGlobalProxy()); |
| 1439 ASSERT(StoreICableLookup(lookup)); | 1436 ASSERT(StoreICableLookup(lookup)); |
| 1440 // These are not cacheable, so we never see such LookupResults here. | 1437 // These are not cacheable, so we never see such LookupResults here. |
| 1441 ASSERT(lookup->type() != HANDLER); | 1438 ASSERT(!lookup->IsHandler()); |
| 1442 // We get only called for properties or transitions, see StoreICableLookup. | 1439 // We get only called for properties or transitions, see StoreICableLookup. |
| 1443 ASSERT(lookup->type() != NULL_DESCRIPTOR); | 1440 ASSERT(lookup->type() != NULL_DESCRIPTOR); |
| 1444 | 1441 |
| 1445 // If the property has a non-field type allowing map transitions | 1442 // If the property has a non-field type allowing map transitions |
| 1446 // where there is extra room in the object, we leave the IC in its | 1443 // where there is extra room in the object, we leave the IC in its |
| 1447 // current state. | 1444 // current state. |
| 1448 PropertyType type = lookup->type(); | 1445 PropertyType type = lookup->type(); |
| 1449 | 1446 |
| 1450 // Compute the code stub for this store; used for rewriting to | 1447 // Compute the code stub for this store; used for rewriting to |
| 1451 // monomorphic state and making sure that the code stub is in the | 1448 // monomorphic state and making sure that the code stub is in the |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1933 | 1930 |
| 1934 void KeyedStoreIC::UpdateCaches(LookupResult* lookup, | 1931 void KeyedStoreIC::UpdateCaches(LookupResult* lookup, |
| 1935 State state, | 1932 State state, |
| 1936 StrictModeFlag strict_mode, | 1933 StrictModeFlag strict_mode, |
| 1937 Handle<JSObject> receiver, | 1934 Handle<JSObject> receiver, |
| 1938 Handle<String> name, | 1935 Handle<String> name, |
| 1939 Handle<Object> value) { | 1936 Handle<Object> value) { |
| 1940 ASSERT(!receiver->IsJSGlobalProxy()); | 1937 ASSERT(!receiver->IsJSGlobalProxy()); |
| 1941 ASSERT(StoreICableLookup(lookup)); | 1938 ASSERT(StoreICableLookup(lookup)); |
| 1942 // These are not cacheable, so we never see such LookupResults here. | 1939 // These are not cacheable, so we never see such LookupResults here. |
| 1943 ASSERT(lookup->type() != HANDLER); | 1940 ASSERT(!lookup->IsHandler()); |
| 1944 // We get only called for properties or transitions, see StoreICableLookup. | 1941 // We get only called for properties or transitions, see StoreICableLookup. |
| 1945 ASSERT(lookup->type() != NULL_DESCRIPTOR); | 1942 ASSERT(lookup->type() != NULL_DESCRIPTOR); |
| 1946 | 1943 |
| 1947 // If the property has a non-field type allowing map transitions | 1944 // If the property has a non-field type allowing map transitions |
| 1948 // where there is extra room in the object, we leave the IC in its | 1945 // where there is extra room in the object, we leave the IC in its |
| 1949 // current state. | 1946 // current state. |
| 1950 PropertyType type = lookup->type(); | 1947 PropertyType type = lookup->type(); |
| 1951 | 1948 |
| 1952 // Compute the code stub for this store; used for rewriting to | 1949 // Compute the code stub for this store; used for rewriting to |
| 1953 // monomorphic state and making sure that the code stub is in the | 1950 // monomorphic state and making sure that the code stub is in the |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2109 JSArray* receiver = JSArray::cast(args[0]); | 2106 JSArray* receiver = JSArray::cast(args[0]); |
| 2110 Object* len = args[1]; | 2107 Object* len = args[1]; |
| 2111 | 2108 |
| 2112 // The generated code should filter out non-Smis before we get here. | 2109 // The generated code should filter out non-Smis before we get here. |
| 2113 ASSERT(len->IsSmi()); | 2110 ASSERT(len->IsSmi()); |
| 2114 | 2111 |
| 2115 #ifdef DEBUG | 2112 #ifdef DEBUG |
| 2116 // The length property has to be a writable callback property. | 2113 // The length property has to be a writable callback property. |
| 2117 LookupResult debug_lookup(isolate); | 2114 LookupResult debug_lookup(isolate); |
| 2118 receiver->LocalLookup(isolate->heap()->length_symbol(), &debug_lookup); | 2115 receiver->LocalLookup(isolate->heap()->length_symbol(), &debug_lookup); |
| 2119 ASSERT(debug_lookup.type() == CALLBACKS && !debug_lookup.IsReadOnly()); | 2116 ASSERT(debug_lookup.IsCallbacks() && !debug_lookup.IsReadOnly()); |
| 2120 #endif | 2117 #endif |
| 2121 | 2118 |
| 2122 Object* result; | 2119 Object* result; |
| 2123 { MaybeObject* maybe_result = receiver->SetElementsLength(len); | 2120 { MaybeObject* maybe_result = receiver->SetElementsLength(len); |
| 2124 if (!maybe_result->ToObject(&result)) return maybe_result; | 2121 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 2125 } | 2122 } |
| 2126 return len; | 2123 return len; |
| 2127 } | 2124 } |
| 2128 | 2125 |
| 2129 | 2126 |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2672 #undef ADDR | 2669 #undef ADDR |
| 2673 }; | 2670 }; |
| 2674 | 2671 |
| 2675 | 2672 |
| 2676 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2673 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2677 return IC_utilities[id]; | 2674 return IC_utilities[id]; |
| 2678 } | 2675 } |
| 2679 | 2676 |
| 2680 | 2677 |
| 2681 } } // namespace v8::internal | 2678 } } // namespace v8::internal |
| OLD | NEW |