OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 // present) to guarantee failure by holding an invalid map (the null | 336 // present) to guarantee failure by holding an invalid map (the null |
337 // value). The offset can be patched to anything. | 337 // value). The offset can be patched to anything. |
338 PatchInlinedStore(address, Heap::null_value(), 0); | 338 PatchInlinedStore(address, Heap::null_value(), 0); |
339 } | 339 } |
340 | 340 |
341 | 341 |
342 void StoreIC::Clear(Address address, Code* target) { | 342 void StoreIC::Clear(Address address, Code* target) { |
343 if (target->ic_state() == UNINITIALIZED) return; | 343 if (target->ic_state() == UNINITIALIZED) return; |
344 ClearInlinedVersion(address); | 344 ClearInlinedVersion(address); |
345 SetTargetAtAddress(address, | 345 SetTargetAtAddress(address, |
346 target->extra_ic_state() == kStoreICStrict | 346 target->extra_ic_state() == kStrictMode |
347 ? initialize_stub_strict() | 347 ? initialize_stub_strict() |
348 : initialize_stub()); | 348 : initialize_stub()); |
349 } | 349 } |
350 | 350 |
351 | 351 |
352 void KeyedStoreIC::ClearInlinedVersion(Address address) { | 352 void KeyedStoreIC::ClearInlinedVersion(Address address) { |
353 // Insert null as the elements map to check for. This will make | 353 // Insert null as the elements map to check for. This will make |
354 // sure that the elements fast-case map check fails so that control | 354 // sure that the elements fast-case map check fails so that control |
355 // flows to the IC instead of the inlined version. | 355 // flows to the IC instead of the inlined version. |
356 PatchInlinedStore(address, Heap::null_value()); | 356 PatchInlinedStore(address, Heap::null_value()); |
357 } | 357 } |
358 | 358 |
359 | 359 |
360 void KeyedStoreIC::RestoreInlinedVersion(Address address) { | 360 void KeyedStoreIC::RestoreInlinedVersion(Address address) { |
361 // Restore the fast-case elements map check so that the inlined | 361 // Restore the fast-case elements map check so that the inlined |
362 // version can be used again. | 362 // version can be used again. |
363 PatchInlinedStore(address, Heap::fixed_array_map()); | 363 PatchInlinedStore(address, Heap::fixed_array_map()); |
364 } | 364 } |
365 | 365 |
366 | 366 |
367 void KeyedStoreIC::Clear(Address address, Code* target) { | 367 void KeyedStoreIC::Clear(Address address, Code* target) { |
368 if (target->ic_state() == UNINITIALIZED) return; | 368 if (target->ic_state() == UNINITIALIZED) return; |
369 SetTargetAtAddress(address, initialize_stub()); | 369 SetTargetAtAddress(address, |
| 370 target->extra_ic_state() == kStrictMode |
| 371 ? initialize_stub_strict() |
| 372 : initialize_stub()); |
370 } | 373 } |
371 | 374 |
372 | 375 |
373 static bool HasInterceptorGetter(JSObject* object) { | 376 static bool HasInterceptorGetter(JSObject* object) { |
374 return !object->GetNamedInterceptor()->getter()->IsUndefined(); | 377 return !object->GetNamedInterceptor()->getter()->IsUndefined(); |
375 } | 378 } |
376 | 379 |
377 | 380 |
378 static void LookupForRead(Object* object, | 381 static void LookupForRead(Object* object, |
379 String* name, | 382 String* name, |
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1219 if (use_ic) { | 1222 if (use_ic) { |
1220 Code* stub = generic_stub(); | 1223 Code* stub = generic_stub(); |
1221 if (state == UNINITIALIZED) { | 1224 if (state == UNINITIALIZED) { |
1222 if (object->IsString() && key->IsNumber()) { | 1225 if (object->IsString() && key->IsNumber()) { |
1223 stub = string_stub(); | 1226 stub = string_stub(); |
1224 } else if (object->IsJSObject()) { | 1227 } else if (object->IsJSObject()) { |
1225 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1228 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
1226 if (receiver->HasExternalArrayElements()) { | 1229 if (receiver->HasExternalArrayElements()) { |
1227 MaybeObject* probe = | 1230 MaybeObject* probe = |
1228 StubCache::ComputeKeyedLoadOrStoreExternalArray(*receiver, | 1231 StubCache::ComputeKeyedLoadOrStoreExternalArray(*receiver, |
1229 false); | 1232 false, |
| 1233 kNonStrictMode); |
1230 stub = probe->IsFailure() ? | 1234 stub = probe->IsFailure() ? |
1231 NULL : Code::cast(probe->ToObjectUnchecked()); | 1235 NULL : Code::cast(probe->ToObjectUnchecked()); |
1232 } else if (receiver->HasIndexedInterceptor()) { | 1236 } else if (receiver->HasIndexedInterceptor()) { |
1233 stub = indexed_interceptor_stub(); | 1237 stub = indexed_interceptor_stub(); |
1234 } else if (receiver->HasPixelElements()) { | 1238 } else if (receiver->HasPixelElements()) { |
1235 MaybeObject* probe = | 1239 MaybeObject* probe = |
1236 StubCache::ComputeKeyedLoadPixelArray(*receiver); | 1240 StubCache::ComputeKeyedLoadPixelArray(*receiver); |
1237 stub = probe->IsFailure() ? | 1241 stub = probe->IsFailure() ? |
1238 NULL : Code::cast(probe->ToObjectUnchecked()); | 1242 NULL : Code::cast(probe->ToObjectUnchecked()); |
1239 } else if (key->IsSmi() && | 1243 } else if (key->IsSmi() && |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1405 return *value; | 1409 return *value; |
1406 } | 1410 } |
1407 | 1411 |
1408 // Use specialized code for setting the length of arrays. | 1412 // Use specialized code for setting the length of arrays. |
1409 if (receiver->IsJSArray() | 1413 if (receiver->IsJSArray() |
1410 && name->Equals(Heap::length_symbol()) | 1414 && name->Equals(Heap::length_symbol()) |
1411 && receiver->AllowsSetElementsLength()) { | 1415 && receiver->AllowsSetElementsLength()) { |
1412 #ifdef DEBUG | 1416 #ifdef DEBUG |
1413 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n"); | 1417 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n"); |
1414 #endif | 1418 #endif |
1415 Builtins::Name target = (extra_ic_state == kStoreICStrict) | 1419 Builtins::Name target = (extra_ic_state == kStrictMode) |
1416 ? Builtins::StoreIC_ArrayLength_Strict | 1420 ? Builtins::StoreIC_ArrayLength_Strict |
1417 : Builtins::StoreIC_ArrayLength; | 1421 : Builtins::StoreIC_ArrayLength; |
1418 set_target(Builtins::builtin(target)); | 1422 set_target(Builtins::builtin(target)); |
1419 return receiver->SetProperty(*name, *value, NONE); | 1423 return receiver->SetProperty(*name, *value, NONE, |
| 1424 static_cast<StrictModeFlag>(extra_ic_state)); |
1420 } | 1425 } |
1421 | 1426 |
1422 // Lookup the property locally in the receiver. | 1427 // Lookup the property locally in the receiver. |
1423 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { | 1428 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { |
1424 LookupResult lookup; | 1429 LookupResult lookup; |
1425 | 1430 |
1426 if (LookupForWrite(*receiver, *name, &lookup)) { | 1431 if (LookupForWrite(*receiver, *name, &lookup)) { |
1427 bool can_be_inlined = | 1432 bool can_be_inlined = |
1428 state == UNINITIALIZED && | 1433 state == UNINITIALIZED && |
1429 lookup.IsProperty() && | 1434 lookup.IsProperty() && |
1430 lookup.holder() == *receiver && | 1435 lookup.holder() == *receiver && |
1431 lookup.type() == FIELD && | 1436 lookup.type() == FIELD && |
1432 !receiver->IsAccessCheckNeeded(); | 1437 !receiver->IsAccessCheckNeeded(); |
1433 | 1438 |
1434 if (can_be_inlined) { | 1439 if (can_be_inlined) { |
1435 Map* map = lookup.holder()->map(); | 1440 Map* map = lookup.holder()->map(); |
1436 // Property's index in the properties array. If negative we have | 1441 // Property's index in the properties array. If negative we have |
1437 // an inobject property. | 1442 // an inobject property. |
1438 int index = lookup.GetFieldIndex() - map->inobject_properties(); | 1443 int index = lookup.GetFieldIndex() - map->inobject_properties(); |
1439 if (index < 0) { | 1444 if (index < 0) { |
1440 // Index is an offset from the end of the object. | 1445 // Index is an offset from the end of the object. |
1441 int offset = map->instance_size() + (index * kPointerSize); | 1446 int offset = map->instance_size() + (index * kPointerSize); |
1442 if (PatchInlinedStore(address(), map, offset)) { | 1447 if (PatchInlinedStore(address(), map, offset)) { |
1443 set_target(megamorphic_stub()); | 1448 set_target(megamorphic_stub()); |
1444 #ifdef DEBUG | 1449 #ifdef DEBUG |
1445 if (FLAG_trace_ic) { | 1450 if (FLAG_trace_ic) { |
1446 PrintF("[StoreIC : inline patch %s]\n", *name->ToCString()); | 1451 PrintF("[StoreIC : inline patch %s]\n", *name->ToCString()); |
1447 } | 1452 } |
1448 #endif | 1453 #endif |
1449 return receiver->SetProperty(*name, *value, NONE); | 1454 return receiver->SetProperty( |
| 1455 *name, *value, NONE, |
| 1456 static_cast<StrictModeFlag>(extra_ic_state)); |
1450 #ifdef DEBUG | 1457 #ifdef DEBUG |
1451 | 1458 |
1452 } else { | 1459 } else { |
1453 if (FLAG_trace_ic) { | 1460 if (FLAG_trace_ic) { |
1454 PrintF("[StoreIC : no inline patch %s (patching failed)]\n", | 1461 PrintF("[StoreIC : no inline patch %s (patching failed)]\n", |
1455 *name->ToCString()); | 1462 *name->ToCString()); |
1456 } | 1463 } |
1457 } | 1464 } |
1458 } else { | 1465 } else { |
1459 if (FLAG_trace_ic) { | 1466 if (FLAG_trace_ic) { |
1460 PrintF("[StoreIC : no inline patch %s (not inobject)]\n", | 1467 PrintF("[StoreIC : no inline patch %s (not inobject)]\n", |
1461 *name->ToCString()); | 1468 *name->ToCString()); |
1462 } | 1469 } |
1463 } | 1470 } |
1464 } else { | 1471 } else { |
1465 if (state == PREMONOMORPHIC) { | 1472 if (state == PREMONOMORPHIC) { |
1466 if (FLAG_trace_ic) { | 1473 if (FLAG_trace_ic) { |
1467 PrintF("[StoreIC : no inline patch %s (not inlinable)]\n", | 1474 PrintF("[StoreIC : no inline patch %s (not inlinable)]\n", |
1468 *name->ToCString()); | 1475 *name->ToCString()); |
1469 #endif | 1476 #endif |
1470 } | 1477 } |
1471 } | 1478 } |
1472 } | 1479 } |
1473 | 1480 |
1474 // If no inlined store ic was patched, generate a stub for this | 1481 // If no inlined store ic was patched, generate a stub for this |
1475 // store. | 1482 // store. |
1476 UpdateCaches(&lookup, state, extra_ic_state, receiver, name, value); | 1483 UpdateCaches(&lookup, state, extra_ic_state, receiver, name, value); |
1477 } else { | 1484 } else { |
1478 // Strict mode doesn't allow setting non-existent global property. | 1485 // Strict mode doesn't allow setting non-existent global property. |
1479 if (extra_ic_state == kStoreICStrict && IsContextual(object)) { | 1486 if (extra_ic_state == kStrictMode) { |
1480 return ReferenceError("not_defined", name); | 1487 if (lookup.IsFound() && lookup.IsReadOnly()) { |
| 1488 return TypeError("strict_rdonly_property", object, name); |
| 1489 } else if (IsContextual(object)) { |
| 1490 return ReferenceError("not_defined", name); |
| 1491 } |
1481 } | 1492 } |
1482 } | 1493 } |
1483 } | 1494 } |
1484 | 1495 |
1485 if (receiver->IsJSGlobalProxy()) { | 1496 if (receiver->IsJSGlobalProxy()) { |
1486 // Generate a generic stub that goes to the runtime when we see a global | 1497 // Generate a generic stub that goes to the runtime when we see a global |
1487 // proxy as receiver. | 1498 // proxy as receiver. |
1488 Code* stub = (extra_ic_state == kStoreICStrict) | 1499 Code* stub = (extra_ic_state == kStrictMode) |
1489 ? global_proxy_stub_strict() | 1500 ? global_proxy_stub_strict() |
1490 : global_proxy_stub(); | 1501 : global_proxy_stub(); |
1491 if (target() != stub) { | 1502 if (target() != stub) { |
1492 set_target(stub); | 1503 set_target(stub); |
1493 #ifdef DEBUG | 1504 #ifdef DEBUG |
1494 TraceIC("StoreIC", name, state, target()); | 1505 TraceIC("StoreIC", name, state, target()); |
1495 #endif | 1506 #endif |
1496 } | 1507 } |
1497 } | 1508 } |
1498 | 1509 |
1499 // Set the property. | 1510 // Set the property. |
1500 return receiver->SetProperty(*name, *value, NONE); | 1511 return receiver->SetProperty(*name, *value, NONE, |
| 1512 static_cast<StrictModeFlag>(extra_ic_state)); |
1501 } | 1513 } |
1502 | 1514 |
1503 | 1515 |
1504 void StoreIC::UpdateCaches(LookupResult* lookup, | 1516 void StoreIC::UpdateCaches(LookupResult* lookup, |
1505 State state, | 1517 State state, |
1506 Code::ExtraICState extra_ic_state, | 1518 Code::ExtraICState extra_ic_state, |
1507 Handle<JSObject> receiver, | 1519 Handle<JSObject> receiver, |
1508 Handle<String> name, | 1520 Handle<String> name, |
1509 Handle<Object> value) { | 1521 Handle<Object> value) { |
1510 // Skip JSGlobalProxy. | 1522 // Skip JSGlobalProxy. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1575 // If we're unable to compute the stub (not enough memory left), we | 1587 // If we're unable to compute the stub (not enough memory left), we |
1576 // simply avoid updating the caches. | 1588 // simply avoid updating the caches. |
1577 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return; | 1589 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return; |
1578 | 1590 |
1579 // Patch the call site depending on the state of the cache. | 1591 // Patch the call site depending on the state of the cache. |
1580 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { | 1592 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { |
1581 set_target(Code::cast(code)); | 1593 set_target(Code::cast(code)); |
1582 } else if (state == MONOMORPHIC) { | 1594 } else if (state == MONOMORPHIC) { |
1583 // Only move to megamorphic if the target changes. | 1595 // Only move to megamorphic if the target changes. |
1584 if (target() != Code::cast(code)) { | 1596 if (target() != Code::cast(code)) { |
1585 set_target(extra_ic_state == kStoreICStrict | 1597 set_target(extra_ic_state == kStrictMode |
1586 ? megamorphic_stub_strict() | 1598 ? megamorphic_stub_strict() |
1587 : megamorphic_stub()); | 1599 : megamorphic_stub()); |
1588 } | 1600 } |
1589 } else if (state == MEGAMORPHIC) { | 1601 } else if (state == MEGAMORPHIC) { |
1590 // Update the stub cache. | 1602 // Update the stub cache. |
1591 StubCache::Set(*name, receiver->map(), Code::cast(code)); | 1603 StubCache::Set(*name, receiver->map(), Code::cast(code)); |
1592 } | 1604 } |
1593 | 1605 |
1594 #ifdef DEBUG | 1606 #ifdef DEBUG |
1595 TraceIC("StoreIC", name, state, target()); | 1607 TraceIC("StoreIC", name, state, target()); |
1596 #endif | 1608 #endif |
1597 } | 1609 } |
1598 | 1610 |
1599 | 1611 |
1600 MaybeObject* KeyedStoreIC::Store(State state, | 1612 MaybeObject* KeyedStoreIC::Store(State state, |
| 1613 Code::ExtraICState extra_ic_state, |
1601 Handle<Object> object, | 1614 Handle<Object> object, |
1602 Handle<Object> key, | 1615 Handle<Object> key, |
1603 Handle<Object> value) { | 1616 Handle<Object> value) { |
1604 if (key->IsSymbol()) { | 1617 if (key->IsSymbol()) { |
1605 Handle<String> name = Handle<String>::cast(key); | 1618 Handle<String> name = Handle<String>::cast(key); |
1606 | 1619 |
1607 // If the object is undefined or null it's illegal to try to set any | 1620 // If the object is undefined or null it's illegal to try to set any |
1608 // properties on it; throw a TypeError in that case. | 1621 // properties on it; throw a TypeError in that case. |
1609 if (object->IsUndefined() || object->IsNull()) { | 1622 if (object->IsUndefined() || object->IsNull()) { |
1610 return TypeError("non_object_property_store", object, name); | 1623 return TypeError("non_object_property_store", object, name); |
(...skipping 15 matching lines...) Expand all Loading... |
1626 // Lookup the property locally in the receiver. | 1639 // Lookup the property locally in the receiver. |
1627 LookupResult lookup; | 1640 LookupResult lookup; |
1628 receiver->LocalLookup(*name, &lookup); | 1641 receiver->LocalLookup(*name, &lookup); |
1629 | 1642 |
1630 // Update inline cache and stub cache. | 1643 // Update inline cache and stub cache. |
1631 if (FLAG_use_ic) { | 1644 if (FLAG_use_ic) { |
1632 UpdateCaches(&lookup, state, receiver, name, value); | 1645 UpdateCaches(&lookup, state, receiver, name, value); |
1633 } | 1646 } |
1634 | 1647 |
1635 // Set the property. | 1648 // Set the property. |
1636 return receiver->SetProperty(*name, *value, NONE); | 1649 return receiver->SetProperty(*name, *value, NONE, |
| 1650 static_cast<StrictModeFlag>(extra_ic_state)); |
1637 } | 1651 } |
1638 | 1652 |
1639 // Do not use ICs for objects that require access checks (including | 1653 // Do not use ICs for objects that require access checks (including |
1640 // the global object). | 1654 // the global object). |
1641 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); | 1655 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); |
1642 ASSERT(!(use_ic && object->IsJSGlobalProxy())); | 1656 ASSERT(!(use_ic && object->IsJSGlobalProxy())); |
1643 | 1657 |
1644 if (use_ic) { | 1658 if (use_ic) { |
1645 Code* stub = generic_stub(); | 1659 Code* stub = extra_ic_state == kStrictMode |
| 1660 ? generic_stub_strict() |
| 1661 : generic_stub(); |
| 1662 // TODO(mmaly): Fix IC specialization to take strict mode into account. |
| 1663 // Currently they jump to KeyedStoreIC_Miss which is non-strict. |
1646 if (state == UNINITIALIZED) { | 1664 if (state == UNINITIALIZED) { |
1647 if (object->IsJSObject()) { | 1665 if (object->IsJSObject()) { |
1648 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1666 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
1649 if (receiver->HasExternalArrayElements()) { | 1667 if (receiver->HasExternalArrayElements()) { |
1650 MaybeObject* probe = | 1668 MaybeObject* probe = |
1651 StubCache::ComputeKeyedLoadOrStoreExternalArray(*receiver, true); | 1669 StubCache::ComputeKeyedLoadOrStoreExternalArray( |
| 1670 *receiver, true, extra_ic_state); |
1652 stub = probe->IsFailure() ? | 1671 stub = probe->IsFailure() ? |
1653 NULL : Code::cast(probe->ToObjectUnchecked()); | 1672 NULL : Code::cast(probe->ToObjectUnchecked()); |
1654 } else if (receiver->HasPixelElements()) { | 1673 } else if (receiver->HasPixelElements()) { |
1655 MaybeObject* probe = | 1674 MaybeObject* probe = |
1656 StubCache::ComputeKeyedStorePixelArray(*receiver); | 1675 StubCache::ComputeKeyedStorePixelArray(*receiver); |
1657 stub = probe->IsFailure() ? | 1676 stub = probe->IsFailure() ? |
1658 NULL : Code::cast(probe->ToObjectUnchecked()); | 1677 NULL : Code::cast(probe->ToObjectUnchecked()); |
1659 } else if (key->IsSmi() && receiver->map()->has_fast_elements()) { | 1678 } else if (key->IsSmi() && receiver->map()->has_fast_elements()) { |
1660 MaybeObject* probe = | 1679 MaybeObject* probe = |
1661 StubCache::ComputeKeyedStoreSpecialized(*receiver); | 1680 StubCache::ComputeKeyedStoreSpecialized(*receiver); |
1662 stub = probe->IsFailure() ? | 1681 stub = probe->IsFailure() ? |
1663 NULL : Code::cast(probe->ToObjectUnchecked()); | 1682 NULL : Code::cast(probe->ToObjectUnchecked()); |
1664 } | 1683 } |
1665 } | 1684 } |
1666 } | 1685 } |
1667 if (stub != NULL) set_target(stub); | 1686 if (stub != NULL) set_target(stub); |
1668 } | 1687 } |
1669 | 1688 |
1670 // Set the property. | 1689 // Set the property. |
1671 return Runtime::SetObjectProperty(object, key, value, NONE); | 1690 ASSERT(extra_ic_state == kStrictMode || extra_ic_state == kNonStrictMode); |
| 1691 return Runtime::SetObjectProperty( |
| 1692 object, key, value, NONE, static_cast<StrictModeFlag>(extra_ic_state)); |
1672 } | 1693 } |
1673 | 1694 |
1674 | 1695 |
1675 void KeyedStoreIC::UpdateCaches(LookupResult* lookup, | 1696 void KeyedStoreIC::UpdateCaches(LookupResult* lookup, |
1676 State state, | 1697 State state, |
1677 Handle<JSObject> receiver, | 1698 Handle<JSObject> receiver, |
1678 Handle<String> name, | 1699 Handle<String> name, |
1679 Handle<Object> value) { | 1700 Handle<Object> value) { |
1680 // Skip JSGlobalProxy. | 1701 // Skip JSGlobalProxy. |
1681 if (receiver->IsJSGlobalProxy()) return; | 1702 if (receiver->IsJSGlobalProxy()) return; |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1893 return value; | 1914 return value; |
1894 } | 1915 } |
1895 | 1916 |
1896 | 1917 |
1897 // Used from ic-<arch>.cc. | 1918 // Used from ic-<arch>.cc. |
1898 MUST_USE_RESULT MaybeObject* KeyedStoreIC_Miss(Arguments args) { | 1919 MUST_USE_RESULT MaybeObject* KeyedStoreIC_Miss(Arguments args) { |
1899 NoHandleAllocation na; | 1920 NoHandleAllocation na; |
1900 ASSERT(args.length() == 3); | 1921 ASSERT(args.length() == 3); |
1901 KeyedStoreIC ic; | 1922 KeyedStoreIC ic; |
1902 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 1923 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
1903 return ic.Store(state, args.at<Object>(0), args.at<Object>(1), | 1924 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
1904 args.at<Object>(2)); | 1925 // TODO(mmaly): Validate extra_ic_state here and pass StrictModeFlag directly. |
| 1926 return ic.Store(state, extra_ic_state, args.at<Object>(0), |
| 1927 args.at<Object>(1), args.at<Object>(2)); |
1905 } | 1928 } |
1906 | 1929 |
1907 | 1930 |
1908 void BinaryOpIC::patch(Code* code) { | 1931 void BinaryOpIC::patch(Code* code) { |
1909 set_target(code); | 1932 set_target(code); |
1910 } | 1933 } |
1911 | 1934 |
1912 | 1935 |
1913 const char* BinaryOpIC::GetName(TypeInfo type_info) { | 1936 const char* BinaryOpIC::GetName(TypeInfo type_info) { |
1914 switch (type_info) { | 1937 switch (type_info) { |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2297 #undef ADDR | 2320 #undef ADDR |
2298 }; | 2321 }; |
2299 | 2322 |
2300 | 2323 |
2301 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2324 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2302 return IC_utilities[id]; | 2325 return IC_utilities[id]; |
2303 } | 2326 } |
2304 | 2327 |
2305 | 2328 |
2306 } } // namespace v8::internal | 2329 } } // namespace v8::internal |
OLD | NEW |