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 1485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 | 1496 |
1497 | 1497 |
1498 Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver, | 1498 Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver, |
1499 StubKind stub_kind, | 1499 StubKind stub_kind, |
1500 StrictModeFlag strict_mode, | 1500 StrictModeFlag strict_mode, |
1501 Handle<Code> generic_stub) { | 1501 Handle<Code> generic_stub) { |
1502 State ic_state = target()->ic_state(); | 1502 State ic_state = target()->ic_state(); |
1503 KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind) | 1503 KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind) |
1504 ? ALLOW_JSARRAY_GROWTH | 1504 ? ALLOW_JSARRAY_GROWTH |
1505 : DO_NOT_ALLOW_JSARRAY_GROWTH; | 1505 : DO_NOT_ALLOW_JSARRAY_GROWTH; |
1506 if ((ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) && | 1506 |
1507 !IsTransitionStubKind(stub_kind)) { | 1507 bool monomorphic = false; |
| 1508 MapHandleList target_receiver_maps; |
| 1509 if (ic_state != UNINITIALIZED && ic_state != PREMONOMORPHIC) { |
| 1510 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); |
| 1511 } |
| 1512 if (!IsTransitionStubKind(stub_kind)) { |
| 1513 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { |
| 1514 monomorphic = true; |
| 1515 } else { |
| 1516 if (ic_state == MONOMORPHIC) { |
| 1517 // The first time a receiver is seen that is a transitioned version of |
| 1518 // the previous monomorphic receiver type, assume the new ElementsKind |
| 1519 // is the monomorphic type. This benefits global arrays that only |
| 1520 // transition once, and all call sites accessing them are faster if they |
| 1521 // remain monomorphic. If this optimistic assumption is not true, the IC |
| 1522 // will miss again and it will become polymorphic and support both the |
| 1523 // untransitioned and transitioned maps. |
| 1524 monomorphic = IsMoreGeneralElementsKindTransition( |
| 1525 target_receiver_maps.at(0)->elements_kind(), |
| 1526 receiver->GetElementsKind()); |
| 1527 } |
| 1528 } |
| 1529 } |
| 1530 |
| 1531 if (monomorphic) { |
1508 return ComputeMonomorphicStub( | 1532 return ComputeMonomorphicStub( |
1509 receiver, stub_kind, strict_mode, generic_stub); | 1533 receiver, stub_kind, strict_mode, generic_stub); |
1510 } | 1534 } |
1511 ASSERT(target() != *generic_stub); | 1535 ASSERT(target() != *generic_stub); |
1512 | 1536 |
1513 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS | 1537 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS |
1514 // via megamorphic stubs, since they don't have a map in their relocation info | 1538 // via megamorphic stubs, since they don't have a map in their relocation info |
1515 // and so the stubs can't be harvested for the object needed for a map check. | 1539 // and so the stubs can't be harvested for the object needed for a map check. |
1516 if (target()->type() != NORMAL) { | 1540 if (target()->type() != NORMAL) { |
1517 TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type"); | 1541 TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type"); |
1518 return generic_stub; | 1542 return generic_stub; |
1519 } | 1543 } |
1520 | 1544 |
1521 // Determine the list of receiver maps that this call site has seen, | 1545 // Determine the list of receiver maps that this call site has seen, |
1522 // adding the map that was just encountered. | 1546 // adding the map that was just encountered. |
1523 MapHandleList target_receiver_maps; | |
1524 Handle<Map> receiver_map(receiver->map()); | 1547 Handle<Map> receiver_map(receiver->map()); |
1525 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { | |
1526 target_receiver_maps.Add(receiver_map); | |
1527 } else { | |
1528 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); | |
1529 } | |
1530 bool map_added = | 1548 bool map_added = |
1531 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); | 1549 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); |
1532 if (IsTransitionStubKind(stub_kind)) { | 1550 if (IsTransitionStubKind(stub_kind)) { |
1533 Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); | 1551 Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); |
1534 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); | 1552 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); |
1535 } | 1553 } |
1536 if (!map_added) { | 1554 if (!map_added) { |
1537 // If the miss wasn't due to an unseen map, a polymorphic stub | 1555 // If the miss wasn't due to an unseen map, a polymorphic stub |
1538 // won't help, use the generic stub. | 1556 // won't help, use the generic stub. |
1539 TRACE_GENERIC_IC("KeyedIC", "same map added twice"); | 1557 TRACE_GENERIC_IC("KeyedIC", "same map added twice"); |
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2508 #undef ADDR | 2526 #undef ADDR |
2509 }; | 2527 }; |
2510 | 2528 |
2511 | 2529 |
2512 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2530 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2513 return IC_utilities[id]; | 2531 return IC_utilities[id]; |
2514 } | 2532 } |
2515 | 2533 |
2516 | 2534 |
2517 } } // namespace v8::internal | 2535 } } // namespace v8::internal |
OLD | NEW |