Thu, 21 Aug 2014 16:44:41 +0200
8055098: WB API should be extended to provide information about size and age of object.
Summary: Extend the WhiteBox API to provide information about the size and age of objects. Further add a mechanism to trigger a young GC.
Reviewed-by: tschatzl, sjohanss
Contributed-by: Leonid Mesnik <leonid.mesnik@oracle.com>
johnc@5078 | 1 | /* |
drchase@6680 | 2 | * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. |
johnc@5078 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
johnc@5078 | 4 | * |
johnc@5078 | 5 | * This code is free software; you can redistribute it and/or modify it |
johnc@5078 | 6 | * under the terms of the GNU General Public License version 2 only, as |
johnc@5078 | 7 | * published by the Free Software Foundation. |
johnc@5078 | 8 | * |
johnc@5078 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
johnc@5078 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
johnc@5078 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
johnc@5078 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
johnc@5078 | 13 | * accompanied this code). |
johnc@5078 | 14 | * |
johnc@5078 | 15 | * You should have received a copy of the GNU General Public License version |
johnc@5078 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
johnc@5078 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
johnc@5078 | 18 | * |
johnc@5078 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
johnc@5078 | 20 | * or visit www.oracle.com if you need additional information or have any |
johnc@5078 | 21 | * questions. |
johnc@5078 | 22 | * |
johnc@5078 | 23 | */ |
johnc@5078 | 24 | |
johnc@5078 | 25 | #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1CARDCOUNTS_HPP |
johnc@5078 | 26 | #define SHARE_VM_GC_IMPLEMENTATION_G1_G1CARDCOUNTS_HPP |
johnc@5078 | 27 | |
tschatzl@7051 | 28 | #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp" |
johnc@5078 | 29 | #include "memory/allocation.hpp" |
johnc@5078 | 30 | #include "runtime/virtualspace.hpp" |
johnc@5078 | 31 | #include "utilities/globalDefinitions.hpp" |
johnc@5078 | 32 | |
johnc@5078 | 33 | class CardTableModRefBS; |
tschatzl@7051 | 34 | class G1CardCounts; |
johnc@5078 | 35 | class G1CollectedHeap; |
tschatzl@7051 | 36 | class G1RegionToSpaceMapper; |
johnc@5078 | 37 | class HeapRegion; |
johnc@5078 | 38 | |
tschatzl@7051 | 39 | class G1CardCountsMappingChangedListener : public G1MappingChangedListener { |
tschatzl@7051 | 40 | private: |
tschatzl@7051 | 41 | G1CardCounts* _counts; |
tschatzl@7051 | 42 | public: |
tschatzl@7051 | 43 | void set_cardcounts(G1CardCounts* counts) { _counts = counts; } |
tschatzl@7051 | 44 | |
tschatzl@7051 | 45 | virtual void on_commit(uint start_idx, size_t num_regions); |
tschatzl@7051 | 46 | }; |
tschatzl@7051 | 47 | |
johnc@5078 | 48 | // Table to track the number of times a card has been refined. Once |
johnc@5078 | 49 | // a card has been refined a certain number of times, it is |
johnc@5078 | 50 | // considered 'hot' and its refinement is delayed by inserting the |
johnc@5078 | 51 | // card into the hot card cache. The card will then be refined when |
johnc@5078 | 52 | // it is evicted from the hot card cache, or when the hot card cache |
johnc@5078 | 53 | // is 'drained' during the next evacuation pause. |
johnc@5078 | 54 | |
johnc@5078 | 55 | class G1CardCounts: public CHeapObj<mtGC> { |
tschatzl@7051 | 56 | G1CardCountsMappingChangedListener _listener; |
tschatzl@7051 | 57 | |
johnc@5078 | 58 | G1CollectedHeap* _g1h; |
johnc@5078 | 59 | |
johnc@5078 | 60 | // The table of counts |
johnc@5078 | 61 | jubyte* _card_counts; |
johnc@5078 | 62 | |
johnc@5078 | 63 | // Max capacity of the reserved space for the counts table |
johnc@5078 | 64 | size_t _reserved_max_card_num; |
johnc@5078 | 65 | |
johnc@5078 | 66 | // CardTable bottom. |
johnc@5078 | 67 | const jbyte* _ct_bot; |
johnc@5078 | 68 | |
johnc@5078 | 69 | // Barrier set |
johnc@5078 | 70 | CardTableModRefBS* _ct_bs; |
johnc@5078 | 71 | |
johnc@5078 | 72 | // Returns true if the card counts table has been reserved. |
johnc@5078 | 73 | bool has_reserved_count_table() { return _card_counts != NULL; } |
johnc@5078 | 74 | |
johnc@5078 | 75 | // Returns true if the card counts table has been reserved and committed. |
johnc@5078 | 76 | bool has_count_table() { |
tschatzl@7051 | 77 | return has_reserved_count_table(); |
johnc@5078 | 78 | } |
johnc@5078 | 79 | |
johnc@5078 | 80 | size_t ptr_2_card_num(const jbyte* card_ptr) { |
johnc@5078 | 81 | assert(card_ptr >= _ct_bot, |
shade@5709 | 82 | err_msg("Invalid card pointer: " |
johnc@5078 | 83 | "card_ptr: " PTR_FORMAT ", " |
johnc@5078 | 84 | "_ct_bot: " PTR_FORMAT, |
drchase@6680 | 85 | p2i(card_ptr), p2i(_ct_bot))); |
johnc@5078 | 86 | size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(jbyte)); |
tschatzl@7051 | 87 | assert(card_num >= 0 && card_num < _reserved_max_card_num, |
drchase@6680 | 88 | err_msg("card pointer out of range: " PTR_FORMAT, p2i(card_ptr))); |
johnc@5078 | 89 | return card_num; |
johnc@5078 | 90 | } |
johnc@5078 | 91 | |
johnc@5078 | 92 | jbyte* card_num_2_ptr(size_t card_num) { |
tschatzl@7051 | 93 | assert(card_num >= 0 && card_num < _reserved_max_card_num, |
shade@5709 | 94 | err_msg("card num out of range: "SIZE_FORMAT, card_num)); |
johnc@5078 | 95 | return (jbyte*) (_ct_bot + card_num); |
johnc@5078 | 96 | } |
johnc@5078 | 97 | |
johnc@5078 | 98 | // Clear the counts table for the given (exclusive) index range. |
johnc@5078 | 99 | void clear_range(size_t from_card_num, size_t to_card_num); |
johnc@5078 | 100 | |
johnc@5078 | 101 | public: |
johnc@5078 | 102 | G1CardCounts(G1CollectedHeap* g1h); |
johnc@5078 | 103 | |
tschatzl@7051 | 104 | void initialize(G1RegionToSpaceMapper* mapper); |
johnc@5078 | 105 | |
johnc@5078 | 106 | // Increments the refinement count for the given card. |
johnc@5078 | 107 | // Returns the pre-increment count value. |
johnc@5078 | 108 | uint add_card_count(jbyte* card_ptr); |
johnc@5078 | 109 | |
johnc@5078 | 110 | // Returns true if the given count is high enough to be considered |
johnc@5078 | 111 | // 'hot'; false otherwise. |
johnc@5078 | 112 | bool is_hot(uint count); |
johnc@5078 | 113 | |
johnc@5078 | 114 | // Clears the card counts for the cards spanned by the region |
johnc@5078 | 115 | void clear_region(HeapRegion* hr); |
johnc@5078 | 116 | |
tschatzl@7051 | 117 | // Clears the card counts for the cards spanned by the MemRegion |
tschatzl@7051 | 118 | void clear_range(MemRegion mr); |
tschatzl@7051 | 119 | |
johnc@5078 | 120 | // Clear the entire card counts table during GC. |
johnc@5078 | 121 | void clear_all(); |
johnc@5078 | 122 | }; |
johnc@5078 | 123 | |
johnc@5078 | 124 | #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1CARDCOUNTS_HPP |