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 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 if (lookup->holder() != *object && | 705 if (lookup->holder() != *object && |
706 HasNormalObjectsInPrototypeChain( | 706 HasNormalObjectsInPrototypeChain( |
707 isolate(), lookup, object->GetPrototype())) { | 707 isolate(), lookup, object->GetPrototype())) { |
708 // Suppress optimization for prototype chains with slow properties objects | 708 // Suppress optimization for prototype chains with slow properties objects |
709 // in the middle. | 709 // in the middle. |
710 return; | 710 return; |
711 } | 711 } |
712 | 712 |
713 // Compute the number of arguments. | 713 // Compute the number of arguments. |
714 int argc = target()->arguments_count(); | 714 int argc = target()->arguments_count(); |
715 bool had_proto_failure = false; | |
716 Handle<Code> code; | 715 Handle<Code> code; |
717 if (state == UNINITIALIZED) { | 716 if (state == UNINITIALIZED) { |
718 // This is the first time we execute this inline cache. | 717 // This is the first time we execute this inline cache. |
719 // Set the target to the pre monomorphic stub to delay | 718 // Set the target to the pre monomorphic stub to delay |
720 // setting the monomorphic state. | 719 // setting the monomorphic state. |
721 code = isolate()->stub_cache()->ComputeCallPreMonomorphic( | 720 code = isolate()->stub_cache()->ComputeCallPreMonomorphic( |
722 argc, kind_, extra_ic_state); | 721 argc, kind_, extra_ic_state); |
723 } else if (state == MONOMORPHIC) { | 722 } else if (state == MONOMORPHIC) { |
724 if (kind_ == Code::CALL_IC && | 723 if (kind_ == Code::CALL_IC && |
725 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { | 724 TryUpdateExtraICState(lookup, object, &extra_ic_state)) { |
726 code = ComputeMonomorphicStub(lookup, state, extra_ic_state, | 725 code = ComputeMonomorphicStub(lookup, state, extra_ic_state, |
727 object, name); | 726 object, name); |
728 } else if (kind_ == Code::CALL_IC && | 727 } else if (kind_ == Code::CALL_IC && |
729 TryRemoveInvalidPrototypeDependentStub(target(), | 728 TryRemoveInvalidPrototypeDependentStub(target(), |
730 *object, | 729 *object, |
731 *name)) { | 730 *name)) { |
732 had_proto_failure = true; | 731 state = MONOMORPHIC_PROTOTYPE_FAILURE; |
733 code = ComputeMonomorphicStub(lookup, state, extra_ic_state, | 732 code = ComputeMonomorphicStub(lookup, state, extra_ic_state, |
734 object, name); | 733 object, name); |
735 } else { | 734 } else { |
736 code = isolate()->stub_cache()->ComputeCallMegamorphic( | 735 code = isolate()->stub_cache()->ComputeCallMegamorphic( |
737 argc, kind_, extra_ic_state); | 736 argc, kind_, extra_ic_state); |
738 } | 737 } |
739 } else { | 738 } else { |
740 code = ComputeMonomorphicStub(lookup, state, extra_ic_state, | 739 code = ComputeMonomorphicStub(lookup, state, extra_ic_state, |
741 object, name); | 740 object, name); |
742 } | 741 } |
743 | 742 |
744 // If there's no appropriate stub we simply avoid updating the caches. | 743 // If there's no appropriate stub we simply avoid updating the caches. |
745 if (code.is_null()) return; | 744 if (code.is_null()) return; |
746 | 745 |
747 // Patch the call site depending on the state of the cache. | 746 // Patch the call site depending on the state of the cache. |
748 if (state == UNINITIALIZED || | 747 switch (state) { |
749 state == PREMONOMORPHIC || | 748 case UNINITIALIZED: |
750 state == MONOMORPHIC || | 749 case MONOMORPHIC_PROTOTYPE_FAILURE: |
751 state == MONOMORPHIC_PROTOTYPE_FAILURE) { | 750 case PREMONOMORPHIC: |
752 set_target(*code); | 751 set_target(*code); |
753 } else if (state == MEGAMORPHIC) { | 752 break; |
754 // Cache code holding map should be consistent with | 753 case MONOMORPHIC: |
755 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. | 754 if (code->ic_state() != MONOMORPHIC) { |
756 Handle<JSObject> cache_object = object->IsJSObject() | 755 Map* map = target()->FindFirstMap(); |
757 ? Handle<JSObject>::cast(object) | 756 if (map != NULL) { |
758 : Handle<JSObject>(JSObject::cast(object->GetPrototype())); | 757 isolate()->stub_cache()->Set(*name, map, target()); |
759 // Update the stub cache. | 758 } |
760 isolate()->stub_cache()->Set(*name, cache_object->map(), *code); | 759 } |
| 760 set_target(*code); |
| 761 break; |
| 762 case MEGAMORPHIC: { |
| 763 // Cache code holding map should be consistent with |
| 764 // GenerateMonomorphicCacheProbe. It is not the map which holds the stub. |
| 765 Handle<JSObject> cache_object = object->IsJSObject() |
| 766 ? Handle<JSObject>::cast(object) |
| 767 : Handle<JSObject>(JSObject::cast(object->GetPrototype())); |
| 768 // Update the stub cache. |
| 769 isolate()->stub_cache()->Set(*name, cache_object->map(), *code); |
| 770 break; |
| 771 } |
| 772 case DEBUG_BREAK: |
| 773 case DEBUG_PREPARE_STEP_IN: |
| 774 break; |
761 } | 775 } |
762 | 776 |
763 if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE; | |
764 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", | 777 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", |
765 name, state, target()); | 778 name, state, target()); |
766 } | 779 } |
767 | 780 |
768 | 781 |
769 MaybeObject* KeyedCallIC::LoadFunction(State state, | 782 MaybeObject* KeyedCallIC::LoadFunction(State state, |
770 Handle<Object> object, | 783 Handle<Object> object, |
771 Handle<Object> key) { | 784 Handle<Object> key) { |
772 if (key->IsSymbol()) { | 785 if (key->IsSymbol()) { |
773 return CallICBase::LoadFunction(state, | 786 return CallICBase::LoadFunction(state, |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 ASSERT(HasInterceptorGetter(*holder)); | 1030 ASSERT(HasInterceptorGetter(*holder)); |
1018 code = isolate()->stub_cache()->ComputeLoadInterceptor( | 1031 code = isolate()->stub_cache()->ComputeLoadInterceptor( |
1019 name, receiver, holder); | 1032 name, receiver, holder); |
1020 break; | 1033 break; |
1021 default: | 1034 default: |
1022 return; | 1035 return; |
1023 } | 1036 } |
1024 } | 1037 } |
1025 | 1038 |
1026 // Patch the call site depending on the state of the cache. | 1039 // Patch the call site depending on the state of the cache. |
1027 if (state == UNINITIALIZED || | 1040 switch (state) { |
1028 state == PREMONOMORPHIC || | 1041 case UNINITIALIZED: |
1029 state == MONOMORPHIC_PROTOTYPE_FAILURE) { | 1042 case PREMONOMORPHIC: |
1030 set_target(*code); | 1043 case MONOMORPHIC_PROTOTYPE_FAILURE: |
1031 } else if (state == MONOMORPHIC) { | 1044 set_target(*code); |
1032 // We are transitioning from monomorphic to megamorphic case. | 1045 break; |
1033 // Place the current monomorphic stub and stub compiled for | 1046 case MONOMORPHIC: |
1034 // the receiver into stub cache. | 1047 if (target() != *code) { |
1035 Map* map = target()->FindFirstMap(); | 1048 // We are transitioning from monomorphic to megamorphic case. |
1036 if (map != NULL) { | 1049 // Place the current monomorphic stub and stub compiled for |
1037 isolate()->stub_cache()->Set(*name, map, target()); | 1050 // the receiver into stub cache. |
1038 } | 1051 Map* map = target()->FindFirstMap(); |
1039 isolate()->stub_cache()->Set(*name, receiver->map(), *code); | 1052 if (map != NULL) { |
| 1053 isolate()->stub_cache()->Set(*name, map, target()); |
| 1054 } |
| 1055 isolate()->stub_cache()->Set(*name, receiver->map(), *code); |
1040 | 1056 |
1041 set_target(*megamorphic_stub()); | 1057 set_target(*megamorphic_stub()); |
1042 } else if (state == MEGAMORPHIC) { | 1058 } |
1043 // Cache code holding map should be consistent with | 1059 break; |
1044 // GenerateMonomorphicCacheProbe. | 1060 case MEGAMORPHIC: |
1045 isolate()->stub_cache()->Set(*name, receiver->map(), *code); | 1061 // Cache code holding map should be consistent with |
| 1062 // GenerateMonomorphicCacheProbe. |
| 1063 isolate()->stub_cache()->Set(*name, receiver->map(), *code); |
| 1064 break; |
| 1065 case DEBUG_BREAK: |
| 1066 case DEBUG_PREPARE_STEP_IN: |
| 1067 break; |
1046 } | 1068 } |
1047 | 1069 |
1048 TRACE_IC("LoadIC", name, state, target()); | 1070 TRACE_IC("LoadIC", name, state, target()); |
1049 } | 1071 } |
1050 | 1072 |
1051 | 1073 |
1052 Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck( | 1074 Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck( |
1053 bool is_js_array, | 1075 bool is_js_array, |
1054 ElementsKind elements_kind, | 1076 ElementsKind elements_kind, |
1055 KeyedAccessGrowMode grow_mode) { | 1077 KeyedAccessGrowMode grow_mode) { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 name, receiver, holder); | 1311 name, receiver, holder); |
1290 break; | 1312 break; |
1291 default: | 1313 default: |
1292 // Always rewrite to the generic case so that we do not | 1314 // Always rewrite to the generic case so that we do not |
1293 // repeatedly try to rewrite. | 1315 // repeatedly try to rewrite. |
1294 code = generic_stub(); | 1316 code = generic_stub(); |
1295 break; | 1317 break; |
1296 } | 1318 } |
1297 } | 1319 } |
1298 | 1320 |
1299 // Patch the call site depending on the state of the cache. Make | 1321 // Patch the call site depending on the state of the cache. |
1300 // sure to always rewrite from monomorphic to megamorphic. | 1322 switch (state) { |
1301 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); | 1323 case UNINITIALIZED: |
1302 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { | 1324 case PREMONOMORPHIC: |
1303 set_target(*code); | 1325 set_target(*code); |
1304 } else if (state == MONOMORPHIC) { | 1326 break; |
1305 set_target(*megamorphic_stub()); | 1327 case MONOMORPHIC: |
| 1328 // Only move to megamorphic if the target changes. |
| 1329 if (target() != *code) { |
| 1330 set_target(*megamorphic_stub()); |
| 1331 } |
| 1332 break; |
| 1333 case MEGAMORPHIC: |
| 1334 case DEBUG_BREAK: |
| 1335 case DEBUG_PREPARE_STEP_IN: |
| 1336 break; |
| 1337 case MONOMORPHIC_PROTOTYPE_FAILURE: |
| 1338 UNREACHABLE(); |
| 1339 break; |
1306 } | 1340 } |
1307 | 1341 |
1308 TRACE_IC("KeyedLoadIC", name, state, target()); | 1342 TRACE_IC("KeyedLoadIC", name, state, target()); |
1309 } | 1343 } |
1310 | 1344 |
1311 | 1345 |
1312 static bool StoreICableLookup(LookupResult* lookup) { | 1346 static bool StoreICableLookup(LookupResult* lookup) { |
1313 // Bail out if we didn't find a result. | 1347 // Bail out if we didn't find a result. |
1314 if (!lookup->IsFound()) return false; | 1348 if (!lookup->IsFound()) return false; |
1315 | 1349 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1540 | 1574 |
1541 break; | 1575 break; |
1542 } | 1576 } |
1543 case NONEXISTENT: | 1577 case NONEXISTENT: |
1544 case HANDLER: | 1578 case HANDLER: |
1545 UNREACHABLE(); | 1579 UNREACHABLE(); |
1546 return; | 1580 return; |
1547 } | 1581 } |
1548 | 1582 |
1549 // Patch the call site depending on the state of the cache. | 1583 // Patch the call site depending on the state of the cache. |
1550 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { | 1584 switch (state) { |
1551 set_target(*code); | 1585 case UNINITIALIZED: |
1552 } else if (state == MONOMORPHIC) { | 1586 case PREMONOMORPHIC: |
1553 // Only move to megamorphic if the target changes. | 1587 case MONOMORPHIC_PROTOTYPE_FAILURE: |
1554 if (target() != *code) { | 1588 set_target(*code); |
1555 set_target((strict_mode == kStrictMode) | 1589 break; |
1556 ? megamorphic_stub_strict() | 1590 case MONOMORPHIC: |
1557 : megamorphic_stub()); | 1591 // Only move to megamorphic if the target changes. |
1558 } | 1592 if (target() != *code) { |
1559 } else if (state == MEGAMORPHIC) { | 1593 // We are transitioning from monomorphic to megamorphic case. |
1560 // Update the stub cache. | 1594 // Place the current monomorphic stub and stub compiled for |
1561 isolate()->stub_cache()->Set(*name, receiver->map(), *code); | 1595 // the receiver into stub cache. |
| 1596 Map* map = target()->FindFirstMap(); |
| 1597 if (map != NULL) { |
| 1598 isolate()->stub_cache()->Set(*name, map, target()); |
| 1599 } |
| 1600 isolate()->stub_cache()->Set(*name, receiver->map(), *code); |
| 1601 set_target((strict_mode == kStrictMode) |
| 1602 ? megamorphic_stub_strict() |
| 1603 : megamorphic_stub()); |
| 1604 } |
| 1605 break; |
| 1606 case MEGAMORPHIC: |
| 1607 // Update the stub cache. |
| 1608 isolate()->stub_cache()->Set(*name, receiver->map(), *code); |
| 1609 break; |
| 1610 case DEBUG_BREAK: |
| 1611 case DEBUG_PREPARE_STEP_IN: |
| 1612 break; |
1562 } | 1613 } |
1563 | 1614 |
1564 TRACE_IC("StoreIC", name, state, target()); | 1615 TRACE_IC("StoreIC", name, state, target()); |
1565 } | 1616 } |
1566 | 1617 |
1567 | 1618 |
1568 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, | 1619 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, |
1569 Handle<Map> new_receiver_map) { | 1620 Handle<Map> new_receiver_map) { |
1570 ASSERT(!new_receiver_map.is_null()); | 1621 ASSERT(!new_receiver_map.is_null()); |
1571 for (int current = 0; current < receiver_maps->length(); ++current) { | 1622 for (int current = 0; current < receiver_maps->length(); ++current) { |
1572 if (!receiver_maps->at(current).is_null() && | 1623 if (!receiver_maps->at(current).is_null() && |
1573 receiver_maps->at(current).is_identical_to(new_receiver_map)) { | 1624 receiver_maps->at(current).is_identical_to(new_receiver_map)) { |
1574 return false; | 1625 return false; |
1575 } | 1626 } |
1576 } | 1627 } |
1577 receiver_maps->Add(new_receiver_map); | 1628 receiver_maps->Add(new_receiver_map); |
1578 return true; | 1629 return true; |
1579 } | 1630 } |
1580 | 1631 |
1581 | 1632 |
1582 void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub, | 1633 void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub, |
1583 MapHandleList* result) { | 1634 MapHandleList* result) { |
1584 ASSERT(stub->is_inline_cache_stub()); | 1635 ASSERT(stub->is_inline_cache_stub()); |
1585 if (!string_stub().is_null() && stub.is_identical_to(string_stub())) { | 1636 if (!string_stub().is_null() && stub.is_identical_to(string_stub())) { |
1586 return result->Add(isolate()->factory()->string_map()); | 1637 return result->Add(isolate()->factory()->string_map()); |
1587 } else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) { | 1638 } else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) { |
1588 if (stub->ic_state() == MONOMORPHIC) { | 1639 switch (stub->ic_state()) { |
1589 result->Add(Handle<Map>(stub->FindFirstMap())); | 1640 case MONOMORPHIC: |
1590 } else { | 1641 result->Add(Handle<Map>(stub->FindFirstMap())); |
1591 ASSERT(stub->ic_state() == MEGAMORPHIC); | 1642 break; |
1592 AssertNoAllocation no_allocation; | 1643 case MEGAMORPHIC: { |
1593 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 1644 AssertNoAllocation no_allocation; |
1594 for (RelocIterator it(*stub, mask); !it.done(); it.next()) { | 1645 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
1595 RelocInfo* info = it.rinfo(); | 1646 for (RelocIterator it(*stub, mask); !it.done(); it.next()) { |
1596 Handle<Object> object(info->target_object()); | 1647 RelocInfo* info = it.rinfo(); |
1597 ASSERT(object->IsMap()); | 1648 Handle<Object> object(info->target_object()); |
1598 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); | 1649 ASSERT(object->IsMap()); |
| 1650 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); |
| 1651 } |
| 1652 break; |
1599 } | 1653 } |
| 1654 case UNINITIALIZED: |
| 1655 case PREMONOMORPHIC: |
| 1656 case MONOMORPHIC_PROTOTYPE_FAILURE: |
| 1657 case DEBUG_BREAK: |
| 1658 case DEBUG_PREPARE_STEP_IN: |
| 1659 UNREACHABLE(); |
| 1660 break; |
1600 } | 1661 } |
1601 } | 1662 } |
1602 } | 1663 } |
1603 | 1664 |
1604 | 1665 |
1605 Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver, | 1666 Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver, |
1606 StubKind stub_kind, | 1667 StubKind stub_kind, |
1607 StrictModeFlag strict_mode, | 1668 StrictModeFlag strict_mode, |
1608 Handle<Code> generic_stub) { | 1669 Handle<Code> generic_stub) { |
1609 State ic_state = target()->ic_state(); | 1670 State ic_state = target()->ic_state(); |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2017 : generic_stub(); | 2078 : generic_stub(); |
2018 break; | 2079 break; |
2019 case HANDLER: | 2080 case HANDLER: |
2020 case NONEXISTENT: | 2081 case NONEXISTENT: |
2021 UNREACHABLE(); | 2082 UNREACHABLE(); |
2022 return; | 2083 return; |
2023 } | 2084 } |
2024 | 2085 |
2025 ASSERT(!code.is_null()); | 2086 ASSERT(!code.is_null()); |
2026 | 2087 |
2027 // Patch the call site depending on the state of the cache. Make | 2088 // Patch the call site depending on the state of the cache. |
2028 // sure to always rewrite from monomorphic to megamorphic. | 2089 switch (state) { |
2029 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); | 2090 case UNINITIALIZED: |
2030 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { | 2091 case PREMONOMORPHIC: |
2031 set_target(*code); | 2092 set_target(*code); |
2032 } else if (state == MONOMORPHIC) { | 2093 break; |
2033 set_target((strict_mode == kStrictMode) | 2094 case MONOMORPHIC: |
2034 ? *megamorphic_stub_strict() | 2095 // Only move to megamorphic if the target changes. |
2035 : *megamorphic_stub()); | 2096 if (target() != *code) { |
| 2097 set_target((strict_mode == kStrictMode) |
| 2098 ? *megamorphic_stub_strict() |
| 2099 : *megamorphic_stub()); |
| 2100 } |
| 2101 break; |
| 2102 case MEGAMORPHIC: |
| 2103 case DEBUG_BREAK: |
| 2104 case DEBUG_PREPARE_STEP_IN: |
| 2105 break; |
| 2106 case MONOMORPHIC_PROTOTYPE_FAILURE: |
| 2107 UNREACHABLE(); |
| 2108 break; |
2036 } | 2109 } |
2037 | 2110 |
2038 TRACE_IC("KeyedStoreIC", name, state, target()); | 2111 TRACE_IC("KeyedStoreIC", name, state, target()); |
2039 } | 2112 } |
2040 | 2113 |
2041 | 2114 |
2042 #undef TRACE_IC | 2115 #undef TRACE_IC |
2043 | 2116 |
2044 | 2117 |
2045 // ---------------------------------------------------------------------------- | 2118 // ---------------------------------------------------------------------------- |
2046 // Static IC stub generators. | 2119 // Static IC stub generators. |
2047 // | 2120 // |
2048 | 2121 |
2049 // Used from ic-<arch>.cc. | 2122 // Used from ic-<arch>.cc. |
2050 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { | 2123 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { |
2051 HandleScope scope(isolate); | 2124 HandleScope scope(isolate); |
2052 ASSERT(args.length() == 2); | 2125 ASSERT(args.length() == 2); |
2053 CallIC ic(isolate); | 2126 CallIC ic(isolate); |
2054 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 2127 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
2055 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 2128 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
2056 MaybeObject* maybe_result = ic.LoadFunction(state, | 2129 MaybeObject* maybe_result = ic.LoadFunction(state, |
2057 extra_ic_state, | 2130 extra_ic_state, |
2058 args.at<Object>(0), | 2131 args.at<Object>(0), |
2059 args.at<String>(1)); | 2132 args.at<String>(1)); |
2060 // Result could be a function or a failure. | 2133 JSFunction* raw_function; |
2061 JSFunction* raw_function = NULL; | |
2062 if (!maybe_result->To(&raw_function)) return maybe_result; | 2134 if (!maybe_result->To(&raw_function)) return maybe_result; |
2063 | 2135 |
2064 // The first time the inline cache is updated may be the first time the | 2136 // The first time the inline cache is updated may be the first time the |
2065 // function it references gets called. If the function is lazily compiled | 2137 // function it references gets called. If the function is lazily compiled |
2066 // then the first call will trigger a compilation. We check for this case | 2138 // then the first call will trigger a compilation. We check for this case |
2067 // and we do the compilation immediately, instead of waiting for the stub | 2139 // and we do the compilation immediately, instead of waiting for the stub |
2068 // currently attached to the JSFunction object to trigger compilation. | 2140 // currently attached to the JSFunction object to trigger compilation. |
2069 if (raw_function->is_compiled()) return raw_function; | 2141 if (raw_function->is_compiled()) return raw_function; |
2070 | 2142 |
2071 Handle<JSFunction> function(raw_function); | 2143 Handle<JSFunction> function(raw_function); |
2072 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); | 2144 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); |
2073 return *function; | 2145 return *function; |
2074 } | 2146 } |
2075 | 2147 |
2076 | 2148 |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2778 #undef ADDR | 2850 #undef ADDR |
2779 }; | 2851 }; |
2780 | 2852 |
2781 | 2853 |
2782 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2854 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2783 return IC_utilities[id]; | 2855 return IC_utilities[id]; |
2784 } | 2856 } |
2785 | 2857 |
2786 | 2858 |
2787 } } // namespace v8::internal | 2859 } } // namespace v8::internal |
OLD | NEW |