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(); |
ulan
2013/01/07 15:04:54
Can we add a comment here like in LoadIC case?
An
Toon Verwaest
2013/01/07 15:28:45
The code above calculates the target different fro
| |
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); | |
ulan
2013/01/07 15:04:54
missing break.
Toon Verwaest
2013/01/07 15:28:45
Done.
| |
1064 case DEBUG_BREAK: | |
1065 case DEBUG_PREPARE_STEP_IN: | |
1066 break; | |
1046 } | 1067 } |
1047 | 1068 |
1048 TRACE_IC("LoadIC", name, state, target()); | 1069 TRACE_IC("LoadIC", name, state, target()); |
1049 } | 1070 } |
1050 | 1071 |
1051 | 1072 |
1052 Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck( | 1073 Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck( |
1053 bool is_js_array, | 1074 bool is_js_array, |
1054 ElementsKind elements_kind, | 1075 ElementsKind elements_kind, |
1055 KeyedAccessGrowMode grow_mode) { | 1076 KeyedAccessGrowMode grow_mode) { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1289 name, receiver, holder); | 1310 name, receiver, holder); |
1290 break; | 1311 break; |
1291 default: | 1312 default: |
1292 // Always rewrite to the generic case so that we do not | 1313 // Always rewrite to the generic case so that we do not |
1293 // repeatedly try to rewrite. | 1314 // repeatedly try to rewrite. |
1294 code = generic_stub(); | 1315 code = generic_stub(); |
1295 break; | 1316 break; |
1296 } | 1317 } |
1297 } | 1318 } |
1298 | 1319 |
1299 // Patch the call site depending on the state of the cache. Make | 1320 // Patch the call site depending on the state of the cache. |
1300 // sure to always rewrite from monomorphic to megamorphic. | 1321 switch (state) { |
1301 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); | 1322 case UNINITIALIZED: |
1302 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { | 1323 case PREMONOMORPHIC: |
1303 set_target(*code); | 1324 set_target(*code); |
1304 } else if (state == MONOMORPHIC) { | 1325 break; |
1305 set_target(*megamorphic_stub()); | 1326 case MONOMORPHIC: |
1327 // Only move to megamorphic if the target changes. | |
1328 if (target() != *code) { | |
1329 set_target(*megamorphic_stub()); | |
1330 } | |
ulan
2013/01/07 15:04:54
missing break.
Toon Verwaest
2013/01/07 15:28:45
Done.
| |
1331 case MEGAMORPHIC: | |
1332 case DEBUG_BREAK: | |
1333 case DEBUG_PREPARE_STEP_IN: | |
1334 break; | |
1335 case MONOMORPHIC_PROTOTYPE_FAILURE: | |
1336 UNREACHABLE(); | |
1337 break; | |
1306 } | 1338 } |
1307 | 1339 |
1308 TRACE_IC("KeyedLoadIC", name, state, target()); | 1340 TRACE_IC("KeyedLoadIC", name, state, target()); |
1309 } | 1341 } |
1310 | 1342 |
1311 | 1343 |
1312 static bool StoreICableLookup(LookupResult* lookup) { | 1344 static bool StoreICableLookup(LookupResult* lookup) { |
1313 // Bail out if we didn't find a result. | 1345 // Bail out if we didn't find a result. |
1314 if (!lookup->IsFound()) return false; | 1346 if (!lookup->IsFound()) return false; |
1315 | 1347 |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1540 | 1572 |
1541 break; | 1573 break; |
1542 } | 1574 } |
1543 case NONEXISTENT: | 1575 case NONEXISTENT: |
1544 case HANDLER: | 1576 case HANDLER: |
1545 UNREACHABLE(); | 1577 UNREACHABLE(); |
1546 return; | 1578 return; |
1547 } | 1579 } |
1548 | 1580 |
1549 // Patch the call site depending on the state of the cache. | 1581 // Patch the call site depending on the state of the cache. |
1550 if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) { | 1582 switch (state) { |
1551 set_target(*code); | 1583 case UNINITIALIZED: |
1552 } else if (state == MONOMORPHIC) { | 1584 case PREMONOMORPHIC: |
1553 // Only move to megamorphic if the target changes. | 1585 case MONOMORPHIC_PROTOTYPE_FAILURE: |
1554 if (target() != *code) { | 1586 set_target(*code); |
1555 set_target((strict_mode == kStrictMode) | 1587 break; |
1556 ? megamorphic_stub_strict() | 1588 case MONOMORPHIC: |
1557 : megamorphic_stub()); | 1589 // Only move to megamorphic if the target changes. |
1558 } | 1590 if (target() != *code) { |
1559 } else if (state == MEGAMORPHIC) { | 1591 Map* map = target()->FindFirstMap(); |
1560 // Update the stub cache. | 1592 if (map != NULL) { |
1561 isolate()->stub_cache()->Set(*name, receiver->map(), *code); | 1593 isolate()->stub_cache()->Set(*name, map, target()); |
ulan
2013/01/07 15:04:54
Can we add a comment explaining this stub cache up
Toon Verwaest
2013/01/07 15:28:45
Done.
| |
1594 } | |
1595 isolate()->stub_cache()->Set(*name, receiver->map(), *code); | |
1596 set_target((strict_mode == kStrictMode) | |
1597 ? megamorphic_stub_strict() | |
1598 : megamorphic_stub()); | |
1599 } | |
1600 break; | |
1601 case MEGAMORPHIC: | |
1602 // Update the stub cache. | |
1603 isolate()->stub_cache()->Set(*name, receiver->map(), *code); | |
1604 break; | |
1605 case DEBUG_BREAK: | |
1606 case DEBUG_PREPARE_STEP_IN: | |
1607 break; | |
1562 } | 1608 } |
1563 | 1609 |
1564 TRACE_IC("StoreIC", name, state, target()); | 1610 TRACE_IC("StoreIC", name, state, target()); |
1565 } | 1611 } |
1566 | 1612 |
1567 | 1613 |
1568 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, | 1614 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, |
1569 Handle<Map> new_receiver_map) { | 1615 Handle<Map> new_receiver_map) { |
1570 ASSERT(!new_receiver_map.is_null()); | 1616 ASSERT(!new_receiver_map.is_null()); |
1571 for (int current = 0; current < receiver_maps->length(); ++current) { | 1617 for (int current = 0; current < receiver_maps->length(); ++current) { |
1572 if (!receiver_maps->at(current).is_null() && | 1618 if (!receiver_maps->at(current).is_null() && |
1573 receiver_maps->at(current).is_identical_to(new_receiver_map)) { | 1619 receiver_maps->at(current).is_identical_to(new_receiver_map)) { |
1574 return false; | 1620 return false; |
1575 } | 1621 } |
1576 } | 1622 } |
1577 receiver_maps->Add(new_receiver_map); | 1623 receiver_maps->Add(new_receiver_map); |
1578 return true; | 1624 return true; |
1579 } | 1625 } |
1580 | 1626 |
1581 | 1627 |
1582 void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub, | 1628 void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub, |
1583 MapHandleList* result) { | 1629 MapHandleList* result) { |
1584 ASSERT(stub->is_inline_cache_stub()); | 1630 ASSERT(stub->is_inline_cache_stub()); |
1585 if (!string_stub().is_null() && stub.is_identical_to(string_stub())) { | 1631 if (!string_stub().is_null() && stub.is_identical_to(string_stub())) { |
1586 return result->Add(isolate()->factory()->string_map()); | 1632 return result->Add(isolate()->factory()->string_map()); |
1587 } else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) { | 1633 } else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) { |
1588 if (stub->ic_state() == MONOMORPHIC) { | 1634 switch (stub->ic_state()) { |
1589 result->Add(Handle<Map>(stub->FindFirstMap())); | 1635 case MONOMORPHIC: |
1590 } else { | 1636 result->Add(Handle<Map>(stub->FindFirstMap())); |
1591 ASSERT(stub->ic_state() == MEGAMORPHIC); | 1637 break; |
1592 AssertNoAllocation no_allocation; | 1638 case MEGAMORPHIC: { |
1593 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 1639 AssertNoAllocation no_allocation; |
1594 for (RelocIterator it(*stub, mask); !it.done(); it.next()) { | 1640 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
1595 RelocInfo* info = it.rinfo(); | 1641 for (RelocIterator it(*stub, mask); !it.done(); it.next()) { |
1596 Handle<Object> object(info->target_object()); | 1642 RelocInfo* info = it.rinfo(); |
1597 ASSERT(object->IsMap()); | 1643 Handle<Object> object(info->target_object()); |
1598 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); | 1644 ASSERT(object->IsMap()); |
1645 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); | |
1646 } | |
1647 break; | |
1599 } | 1648 } |
1649 case UNINITIALIZED: | |
1650 case PREMONOMORPHIC: | |
1651 case MONOMORPHIC_PROTOTYPE_FAILURE: | |
1652 case DEBUG_BREAK: | |
1653 case DEBUG_PREPARE_STEP_IN: | |
1654 UNREACHABLE(); | |
1655 break; | |
1600 } | 1656 } |
1601 } | 1657 } |
1602 } | 1658 } |
1603 | 1659 |
1604 | 1660 |
1605 Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver, | 1661 Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver, |
1606 StubKind stub_kind, | 1662 StubKind stub_kind, |
1607 StrictModeFlag strict_mode, | 1663 StrictModeFlag strict_mode, |
1608 Handle<Code> generic_stub) { | 1664 Handle<Code> generic_stub) { |
1609 State ic_state = target()->ic_state(); | 1665 State ic_state = target()->ic_state(); |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2017 : generic_stub(); | 2073 : generic_stub(); |
2018 break; | 2074 break; |
2019 case HANDLER: | 2075 case HANDLER: |
2020 case NONEXISTENT: | 2076 case NONEXISTENT: |
2021 UNREACHABLE(); | 2077 UNREACHABLE(); |
2022 return; | 2078 return; |
2023 } | 2079 } |
2024 | 2080 |
2025 ASSERT(!code.is_null()); | 2081 ASSERT(!code.is_null()); |
2026 | 2082 |
2027 // Patch the call site depending on the state of the cache. Make | 2083 // Patch the call site depending on the state of the cache. |
2028 // sure to always rewrite from monomorphic to megamorphic. | 2084 switch (state) { |
2029 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); | 2085 case UNINITIALIZED: |
2030 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { | 2086 case PREMONOMORPHIC: |
2031 set_target(*code); | 2087 set_target(*code); |
2032 } else if (state == MONOMORPHIC) { | 2088 break; |
2033 set_target((strict_mode == kStrictMode) | 2089 case MONOMORPHIC: |
2034 ? *megamorphic_stub_strict() | 2090 // Only move to megamorphic if the target changes. |
2035 : *megamorphic_stub()); | 2091 if (target() != *code) { |
2092 set_target((strict_mode == kStrictMode) | |
2093 ? *megamorphic_stub_strict() | |
2094 : *megamorphic_stub()); | |
2095 } | |
2096 break; | |
2097 case MEGAMORPHIC: | |
2098 case DEBUG_BREAK: | |
2099 case DEBUG_PREPARE_STEP_IN: | |
2100 break; | |
2101 case MONOMORPHIC_PROTOTYPE_FAILURE: | |
2102 UNREACHABLE(); | |
2103 break; | |
2036 } | 2104 } |
2037 | 2105 |
2038 TRACE_IC("KeyedStoreIC", name, state, target()); | 2106 TRACE_IC("KeyedStoreIC", name, state, target()); |
2039 } | 2107 } |
2040 | 2108 |
2041 | 2109 |
2042 #undef TRACE_IC | 2110 #undef TRACE_IC |
2043 | 2111 |
2044 | 2112 |
2045 // ---------------------------------------------------------------------------- | 2113 // ---------------------------------------------------------------------------- |
2046 // Static IC stub generators. | 2114 // Static IC stub generators. |
2047 // | 2115 // |
2048 | 2116 |
2049 // Used from ic-<arch>.cc. | 2117 // Used from ic-<arch>.cc. |
2050 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { | 2118 RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { |
2051 HandleScope scope(isolate); | 2119 HandleScope scope(isolate); |
2052 ASSERT(args.length() == 2); | 2120 ASSERT(args.length() == 2); |
2053 CallIC ic(isolate); | 2121 CallIC ic(isolate); |
2054 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 2122 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
2055 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 2123 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
2056 MaybeObject* maybe_result = ic.LoadFunction(state, | 2124 MaybeObject* maybe_result = ic.LoadFunction(state, |
2057 extra_ic_state, | 2125 extra_ic_state, |
2058 args.at<Object>(0), | 2126 args.at<Object>(0), |
2059 args.at<String>(1)); | 2127 args.at<String>(1)); |
2060 // Result could be a function or a failure. | 2128 JSFunction* raw_function; |
2061 JSFunction* raw_function = NULL; | |
ulan
2013/01/07 15:04:54
I am not sure, might be that we need it to avoid c
Toon Verwaest
2013/01/07 15:28:45
I doubt it. It would be the only maybe->To(&value)
| |
2062 if (!maybe_result->To(&raw_function)) return maybe_result; | 2129 if (!maybe_result->To(&raw_function)) return maybe_result; |
2063 | 2130 |
2064 // The first time the inline cache is updated may be the first time the | 2131 // 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 | 2132 // 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 | 2133 // 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 | 2134 // and we do the compilation immediately, instead of waiting for the stub |
2068 // currently attached to the JSFunction object to trigger compilation. | 2135 // currently attached to the JSFunction object to trigger compilation. |
2069 if (raw_function->is_compiled()) return raw_function; | 2136 if (raw_function->is_compiled()) return raw_function; |
2070 | 2137 |
2071 Handle<JSFunction> function(raw_function); | 2138 Handle<JSFunction> function(raw_function); |
2072 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); | 2139 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); |
2073 return *function; | 2140 return *function; |
2074 } | 2141 } |
2075 | 2142 |
2076 | 2143 |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2778 #undef ADDR | 2845 #undef ADDR |
2779 }; | 2846 }; |
2780 | 2847 |
2781 | 2848 |
2782 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2849 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2783 return IC_utilities[id]; | 2850 return IC_utilities[id]; |
2784 } | 2851 } |
2785 | 2852 |
2786 | 2853 |
2787 } } // namespace v8::internal | 2854 } } // namespace v8::internal |
OLD | NEW |