cardTableModRefBS.hpp revision 13249:a2753984d2c1
156893Sfenner/*
256893Sfenner * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
356893Sfenner * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
456893Sfenner *
556893Sfenner * This code is free software; you can redistribute it and/or modify it
656893Sfenner * under the terms of the GNU General Public License version 2 only, as
756893Sfenner * published by the Free Software Foundation.
856893Sfenner *
956893Sfenner * This code is distributed in the hope that it will be useful, but WITHOUT
1056893Sfenner * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1156893Sfenner * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1256893Sfenner * version 2 for more details (a copy is included in the LICENSE file that
1356893Sfenner * accompanied this code).
1456893Sfenner *
1556893Sfenner * You should have received a copy of the GNU General Public License version
1656893Sfenner * 2 along with this work; if not, write to the Free Software Foundation,
1756893Sfenner * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1856893Sfenner *
1956893Sfenner * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2056893Sfenner * or visit www.oracle.com if you need additional information or have any
2156893Sfenner * questions.
2256893Sfenner *
2356893Sfenner */
2456893Sfenner
2556893Sfenner#ifndef SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_HPP
2656893Sfenner#define SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_HPP
2756893Sfenner
2856893Sfenner#include "gc/shared/modRefBarrierSet.hpp"
2956893Sfenner#include "oops/oop.hpp"
3056893Sfenner#include "utilities/align.hpp"
3156893Sfenner
3256893Sfenner// This kind of "BarrierSet" allows a "CollectedHeap" to detect and
3356893Sfenner// enumerate ref fields that have been modified (since the last
3456893Sfenner// enumeration.)
3556893Sfenner
3656893Sfenner// As it currently stands, this barrier is *imprecise*: when a ref field in
3756893Sfenner// an object "o" is modified, the card table entry for the card containing
3856893Sfenner// the head of "o" is dirtied, not necessarily the card containing the
3956893Sfenner// modified field itself.  For object arrays, however, the barrier *is*
4056893Sfenner// precise; only the card containing the modified element is dirtied.
4156893Sfenner// Closures used to scan dirty cards should take these
4256893Sfenner// considerations into account.
4356893Sfenner
4456893Sfennerclass CardTableModRefBS: public ModRefBarrierSet {
4556893Sfenner  // Some classes get to look at some private stuff.
4656893Sfenner  friend class VMStructs;
4756893Sfenner protected:
4856893Sfenner
4956893Sfenner  enum CardValues {
5056893Sfenner    clean_card                  = -1,
5156893Sfenner    // The mask contains zeros in places for all other values.
5256893Sfenner    clean_card_mask             = clean_card - 31,
5356893Sfenner
5456893Sfenner    dirty_card                  =  0,
5556893Sfenner    precleaned_card             =  1,
5656893Sfenner    claimed_card                =  2,
5756893Sfenner    deferred_card               =  4,
5856893Sfenner    last_card                   =  8,
5956893Sfenner    CT_MR_BS_last_reserved      = 16
6056893Sfenner  };
6156893Sfenner
6256893Sfenner  // a word's worth (row) of clean card values
6356893Sfenner  static const intptr_t clean_card_row = (intptr_t)(-1);
6456893Sfenner
6556893Sfenner  // The declaration order of these const fields is important; see the
6656893Sfenner  // constructor before changing.
6756893Sfenner  const MemRegion _whole_heap;       // the region covered by the card table
6856893Sfenner  size_t          _guard_index;      // index of very last element in the card
6956893Sfenner                                     // table; it is set to a guard value
7056893Sfenner                                     // (last_card) and should never be modified
7156893Sfenner  size_t          _last_valid_index; // index of the last valid element
7256893Sfenner  const size_t    _page_size;        // page size used when mapping _byte_map
7356893Sfenner  size_t          _byte_map_size;    // in bytes
7456893Sfenner  jbyte*          _byte_map;         // the card marking array
7556893Sfenner
7656893Sfenner  int _cur_covered_regions;
7756893Sfenner  // The covered regions should be in address order.
7856893Sfenner  MemRegion* _covered;
7956893Sfenner  // The committed regions correspond one-to-one to the covered regions.
8056893Sfenner  // They represent the card-table memory that has been committed to service
8156893Sfenner  // the corresponding covered region.  It may be that committed region for
8256893Sfenner  // one covered region corresponds to a larger region because of page-size
8356893Sfenner  // roundings.  Thus, a committed region for one covered region may
8456893Sfenner  // actually extend onto the card-table space for the next covered region.
8556893Sfenner  MemRegion* _committed;
8656893Sfenner
8756893Sfenner  // The last card is a guard card, and we commit the page for it so
8856893Sfenner  // we can use the card for verification purposes. We make sure we never
8956893Sfenner  // uncommit the MemRegion for that page.
9056893Sfenner  MemRegion _guard_region;
9156893Sfenner
9256893Sfenner protected:
9356893Sfenner  inline size_t compute_byte_map_size();
9456893Sfenner
9556893Sfenner  // Finds and return the index of the region, if any, to which the given
9656893Sfenner  // region would be contiguous.  If none exists, assign a new region and
9756893Sfenner  // returns its index.  Requires that no more than the maximum number of
9856893Sfenner  // covered regions defined in the constructor are ever in use.
9956893Sfenner  int find_covering_region_by_base(HeapWord* base);
10056893Sfenner
10156893Sfenner  // Same as above, but finds the region containing the given address
10256893Sfenner  // instead of starting at a given base address.
10356893Sfenner  int find_covering_region_containing(HeapWord* addr);
10456893Sfenner
10556893Sfenner  // Resize one of the regions covered by the remembered set.
10656893Sfenner  virtual void resize_covered_region(MemRegion new_region);
10756893Sfenner
10856893Sfenner  // Returns the leftmost end of a committed region corresponding to a
10956893Sfenner  // covered region before covered region "ind", or else "NULL" if "ind" is
11056893Sfenner  // the first covered region.
11156893Sfenner  HeapWord* largest_prev_committed_end(int ind) const;
11256893Sfenner
11356893Sfenner  // Returns the part of the region mr that doesn't intersect with
11456893Sfenner  // any committed region other than self.  Used to prevent uncommitting
11556893Sfenner  // regions that are also committed by other regions.  Also protects
11656893Sfenner  // against uncommitting the guard region.
11756893Sfenner  MemRegion committed_unique_to_self(int self, MemRegion mr) const;
11856893Sfenner
11956893Sfenner  // Mapping from address to card marking array entry
12056893Sfenner  jbyte* byte_for(const void* p) const {
12156893Sfenner    assert(_whole_heap.contains(p),
12256893Sfenner           "Attempt to access p = " PTR_FORMAT " out of bounds of "
12356893Sfenner           " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
12456893Sfenner           p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
12556893Sfenner    jbyte* result = &byte_map_base[uintptr_t(p) >> card_shift];
12656893Sfenner    assert(result >= _byte_map && result < _byte_map + _byte_map_size,
12756893Sfenner           "out of bounds accessor for card marking array");
12856893Sfenner    return result;
12956893Sfenner  }
13056893Sfenner
13156893Sfenner  // The card table byte one after the card marking array
13256893Sfenner  // entry for argument address. Typically used for higher bounds
13356893Sfenner  // for loops iterating through the card table.
13456893Sfenner  jbyte* byte_after(const void* p) const {
13556893Sfenner    return byte_for(p) + 1;
13656893Sfenner  }
13756893Sfenner
13856893Sfenner protected:
13956893Sfenner  // Dirty the bytes corresponding to "mr" (not all of which must be
14056893Sfenner  // covered.)
14156893Sfenner  void dirty_MemRegion(MemRegion mr);
14256893Sfenner
14356893Sfenner  // Clear (to clean_card) the bytes entirely contained within "mr" (not
14456893Sfenner  // all of which must be covered.)
14556893Sfenner  void clear_MemRegion(MemRegion mr);
14656893Sfenner
14756893Sfennerpublic:
14856893Sfenner  // Constants
14956893Sfenner  enum SomePublicConstants {
15056893Sfenner    card_shift                  = 9,
15156893Sfenner    card_size                   = 1 << card_shift,
15256893Sfenner    card_size_in_words          = card_size / sizeof(HeapWord)
15356893Sfenner  };
15456893Sfenner
15556893Sfenner  static int clean_card_val()      { return clean_card; }
15656893Sfenner  static int clean_card_mask_val() { return clean_card_mask; }
15756893Sfenner  static int dirty_card_val()      { return dirty_card; }
15856893Sfenner  static int claimed_card_val()    { return claimed_card; }
15956893Sfenner  static int precleaned_card_val() { return precleaned_card; }
16056893Sfenner  static int deferred_card_val()   { return deferred_card; }
16156893Sfenner
16256893Sfenner  virtual void initialize();
16356893Sfenner
16456893Sfenner  // *** Barrier set functions.
16556893Sfenner
16656893Sfenner  bool has_write_ref_pre_barrier() { return false; }
16756893Sfenner
16856893Sfenner  // Initialization utilities; covered_words is the size of the covered region
16956893Sfenner  // in, um, words.
17056893Sfenner  inline size_t cards_required(size_t covered_words) {
17156893Sfenner    // Add one for a guard card, used to detect errors.
17256893Sfenner    const size_t words = align_up(covered_words, card_size_in_words);
17356893Sfenner    return words / card_size_in_words + 1;
17456893Sfenner  }
17556893Sfenner
17656893Sfennerprotected:
17756893Sfenner
17856893Sfenner  CardTableModRefBS(MemRegion whole_heap, const BarrierSet::FakeRtti& fake_rtti);
17956893Sfenner  ~CardTableModRefBS();
18056893Sfenner
18156893Sfenner  // Record a reference update. Note that these versions are precise!
18256893Sfenner  // The scanning code has to handle the fact that the write barrier may be
18356893Sfenner  // either precise or imprecise. We make non-virtual inline variants of
18456893Sfenner  // these functions here for performance.
18556893Sfenner
18656893Sfenner  void write_ref_field_work(oop obj, size_t offset, oop newVal);
18756893Sfenner  virtual void write_ref_field_work(void* field, oop newVal, bool release);
18856893Sfennerpublic:
18956893Sfenner
19056893Sfenner  bool has_write_ref_array_opt() { return true; }
19156893Sfenner  bool has_write_region_opt() { return true; }
19256893Sfenner
19356893Sfenner  inline void inline_write_region(MemRegion mr) {
19456893Sfenner    dirty_MemRegion(mr);
19556893Sfenner  }
19656893Sfennerprotected:
19756893Sfenner  void write_region_work(MemRegion mr) {
19856893Sfenner    inline_write_region(mr);
19956893Sfenner  }
20056893Sfennerpublic:
20156893Sfenner
20256893Sfenner  inline void inline_write_ref_array(MemRegion mr) {
20356893Sfenner    dirty_MemRegion(mr);
20456893Sfenner  }
20556893Sfennerprotected:
20656893Sfenner  void write_ref_array_work(MemRegion mr) {
20756893Sfenner    inline_write_ref_array(mr);
20856893Sfenner  }
20956893Sfennerpublic:
21056893Sfenner
21156893Sfenner  bool is_aligned(HeapWord* addr) {
21256893Sfenner    return is_card_aligned(addr);
21356893Sfenner  }
21456893Sfenner
21556893Sfenner  // *** Card-table-barrier-specific things.
21656893Sfenner
21756893Sfenner  template <class T> inline void inline_write_ref_field_pre(T* field, oop newVal) {}
21856893Sfenner
21956893Sfenner  template <class T> inline void inline_write_ref_field(T* field, oop newVal, bool release);
22056893Sfenner
22156893Sfenner  // These are used by G1, when it uses the card table as a temporary data
22256893Sfenner  // structure for card claiming.
22356893Sfenner  bool is_card_dirty(size_t card_index) {
22456893Sfenner    return _byte_map[card_index] == dirty_card_val();
22556893Sfenner  }
22656893Sfenner
22756893Sfenner  void mark_card_dirty(size_t card_index) {
22856893Sfenner    _byte_map[card_index] = dirty_card_val();
22956893Sfenner  }
23056893Sfenner
23156893Sfenner  bool is_card_clean(size_t card_index) {
23256893Sfenner    return _byte_map[card_index] == clean_card_val();
23356893Sfenner  }
23456893Sfenner
23556893Sfenner  // Card marking array base (adjusted for heap low boundary)
23656893Sfenner  // This would be the 0th element of _byte_map, if the heap started at 0x0.
23756893Sfenner  // But since the heap starts at some higher address, this points to somewhere
23856893Sfenner  // before the beginning of the actual _byte_map.
23956893Sfenner  jbyte* byte_map_base;
24056893Sfenner
24156893Sfenner  // Return true if "p" is at the start of a card.
24256893Sfenner  bool is_card_aligned(HeapWord* p) {
24356893Sfenner    jbyte* pcard = byte_for(p);
24456893Sfenner    return (addr_for(pcard) == p);
24556893Sfenner  }
24656893Sfenner
24756893Sfenner  HeapWord* align_to_card_boundary(HeapWord* p) {
24856893Sfenner    jbyte* pcard = byte_for(p + card_size_in_words - 1);
24956893Sfenner    return addr_for(pcard);
25056893Sfenner  }
25156893Sfenner
25256893Sfenner  // The kinds of precision a CardTableModRefBS may offer.
25356893Sfenner  enum PrecisionStyle {
25456893Sfenner    Precise,
25556893Sfenner    ObjHeadPreciseArray
25656893Sfenner  };
25756893Sfenner
25856893Sfenner  // Tells what style of precision this card table offers.
25956893Sfenner  PrecisionStyle precision() {
26056893Sfenner    return ObjHeadPreciseArray; // Only one supported for now.
26156893Sfenner  }
26256893Sfenner
26356893Sfenner  // ModRefBS functions.
26456893Sfenner  virtual void invalidate(MemRegion mr);
26556893Sfenner  void clear(MemRegion mr);
26656893Sfenner  void dirty(MemRegion mr);
26756893Sfenner
26856893Sfenner  // *** Card-table-RemSet-specific things.
26956893Sfenner
27056893Sfenner  static uintx ct_max_alignment_constraint();
27156893Sfenner
27256893Sfenner  // Apply closure "cl" to the dirty cards containing some part of
27356893Sfenner  // MemRegion "mr".
27456893Sfenner  void dirty_card_iterate(MemRegion mr, MemRegionClosure* cl);
27556893Sfenner
27656893Sfenner  // Return the MemRegion corresponding to the first maximal run
27756893Sfenner  // of dirty cards lying completely within MemRegion mr.
27856893Sfenner  // If reset is "true", then sets those card table entries to the given
27956893Sfenner  // value.
28056893Sfenner  MemRegion dirty_card_range_after_reset(MemRegion mr, bool reset,
28156893Sfenner                                         int reset_val);
28256893Sfenner
28356893Sfenner  // Provide read-only access to the card table array.
28456893Sfenner  const jbyte* byte_for_const(const void* p) const {
28556893Sfenner    return byte_for(p);
28656893Sfenner  }
28756893Sfenner  const jbyte* byte_after_const(const void* p) const {
28856893Sfenner    return byte_after(p);
28956893Sfenner  }
29056893Sfenner
29156893Sfenner  // Mapping from card marking array entry to address of first word
29256893Sfenner  HeapWord* addr_for(const jbyte* p) const {
29356893Sfenner    assert(p >= _byte_map && p < _byte_map + _byte_map_size,
29456893Sfenner           "out of bounds access to card marking array. p: " PTR_FORMAT
29556893Sfenner           " _byte_map: " PTR_FORMAT " _byte_map + _byte_map_size: " PTR_FORMAT,
29656893Sfenner           p2i(p), p2i(_byte_map), p2i(_byte_map + _byte_map_size));
29756893Sfenner    size_t delta = pointer_delta(p, byte_map_base, sizeof(jbyte));
29856893Sfenner    HeapWord* result = (HeapWord*) (delta << card_shift);
29956893Sfenner    assert(_whole_heap.contains(result),
30056893Sfenner           "Returning result = " PTR_FORMAT " out of bounds of "
30156893Sfenner           " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
30256893Sfenner           p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
30356893Sfenner    return result;
30456893Sfenner  }
30556893Sfenner
30656893Sfenner  // Mapping from address to card marking array index.
30756893Sfenner  size_t index_for(void* p) {
30856893Sfenner    assert(_whole_heap.contains(p),
30956893Sfenner           "Attempt to access p = " PTR_FORMAT " out of bounds of "
31056893Sfenner           " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
31156893Sfenner           p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
31256893Sfenner    return byte_for(p) - _byte_map;
31356893Sfenner  }
31456893Sfenner
31556893Sfenner  const jbyte* byte_for_index(const size_t card_index) const {
31656893Sfenner    return _byte_map + card_index;
31756893Sfenner  }
31856893Sfenner
31956893Sfenner  // Print a description of the memory for the barrier set
32056893Sfenner  virtual void print_on(outputStream* st) const;
32156893Sfenner
32256893Sfenner  void verify();
32356893Sfenner  void verify_guard();
32456893Sfenner
32556893Sfenner  // val_equals -> it will check that all cards covered by mr equal val
32656893Sfenner  // !val_equals -> it will check that all cards covered by mr do not equal val
32756893Sfenner  void verify_region(MemRegion mr, jbyte val, bool val_equals) PRODUCT_RETURN;
32856893Sfenner  void verify_not_dirty_region(MemRegion mr) PRODUCT_RETURN;
32956893Sfenner  void verify_dirty_region(MemRegion mr) PRODUCT_RETURN;
33056893Sfenner};
33156893Sfenner
33256893Sfennertemplate<>
33356893Sfennerstruct BarrierSet::GetName<CardTableModRefBS> {
33456893Sfenner  static const BarrierSet::Name value = BarrierSet::CardTableModRef;
33556893Sfenner};
33656893Sfenner
33756893Sfenner
33856893Sfenner#endif // SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_HPP
33956893Sfenner