src/share/vm/gc_implementation/g1/g1InCSetState.hpp

changeset 7651
c132be0fb74d
child 9327
f96fcd9e1e1b
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/gc_implementation/g1/g1InCSetState.hpp	Fri Dec 19 09:21:06 2014 +0100
     1.3 @@ -0,0 +1,132 @@
     1.4 +/*
     1.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1INCSETSTATE_HPP
    1.29 +#define SHARE_VM_GC_IMPLEMENTATION_G1_G1INCSETSTATE_HPP
    1.30 +
    1.31 +#include "gc_implementation/g1/g1BiasedArray.hpp"
    1.32 +#include "memory/allocation.hpp"
    1.33 +
    1.34 +// Per-region state during garbage collection.
    1.35 +struct InCSetState {
    1.36 + public:
    1.37 +  // We use different types to represent the state value. Particularly SPARC puts
    1.38 +  // values in structs from "left to right", i.e. MSB to LSB. This results in many
    1.39 +  // unnecessary shift operations when loading and storing values of this type.
    1.40 +  // This degrades performance significantly (>10%) on that platform.
    1.41 +  // Other tested ABIs do not seem to have this problem, and actually tend to
    1.42 +  // favor smaller types, so we use the smallest usable type there.
    1.43 +#ifdef SPARC
    1.44 +  #define CSETSTATE_FORMAT INTPTR_FORMAT
    1.45 +  typedef intptr_t in_cset_state_t;
    1.46 +#else
    1.47 +  #define CSETSTATE_FORMAT "%d"
    1.48 +  typedef int8_t in_cset_state_t;
    1.49 +#endif
    1.50 + private:
    1.51 +  in_cset_state_t _value;
    1.52 + public:
    1.53 +  enum {
    1.54 +    // Selection of the values were driven to micro-optimize the encoding and
    1.55 +    // frequency of the checks.
    1.56 +    // The most common check is whether the region is in the collection set or not.
    1.57 +    // This encoding allows us to use an != 0 check which in some architectures
    1.58 +    // (x86*) can be encoded slightly more efficently than a normal comparison
    1.59 +    // against zero.
    1.60 +    // The same situation occurs when checking whether the region is humongous
    1.61 +    // or not, which is encoded by values < 0.
    1.62 +    // The other values are simply encoded in increasing generation order, which
    1.63 +    // makes getting the next generation fast by a simple increment.
    1.64 +    Humongous    = -1,    // The region is humongous - note that actually any value < 0 would be possible here.
    1.65 +    NotInCSet    =  0,    // The region is not in the collection set.
    1.66 +    Young        =  1,    // The region is in the collection set and a young region.
    1.67 +    Old          =  2,    // The region is in the collection set and an old region.
    1.68 +    Num
    1.69 +  };
    1.70 +
    1.71 +  InCSetState(in_cset_state_t value = NotInCSet) : _value(value) {
    1.72 +    assert(is_valid(), err_msg("Invalid state %d", _value));
    1.73 +  }
    1.74 +
    1.75 +  in_cset_state_t value() const        { return _value; }
    1.76 +
    1.77 +  void set_old()                       { _value = Old; }
    1.78 +
    1.79 +  bool is_in_cset_or_humongous() const { return _value != NotInCSet; }
    1.80 +  bool is_in_cset() const              { return _value > NotInCSet; }
    1.81 +  bool is_humongous() const            { return _value < NotInCSet; }
    1.82 +  bool is_young() const                { return _value == Young; }
    1.83 +  bool is_old() const                  { return _value == Old; }
    1.84 +
    1.85 +#ifdef ASSERT
    1.86 +  bool is_default() const              { return !is_in_cset_or_humongous(); }
    1.87 +  bool is_valid() const                { return (_value >= Humongous) && (_value < Num); }
    1.88 +  bool is_valid_gen() const            { return (_value >= Young && _value <= Old); }
    1.89 +#endif
    1.90 +};
    1.91 +
    1.92 +// Instances of this class are used for quick tests on whether a reference points
    1.93 +// into the collection set and into which generation or is a humongous object
    1.94 +//
    1.95 +// Each of the array's elements indicates whether the corresponding region is in
    1.96 +// the collection set and if so in which generation, or a humongous region.
    1.97 +//
    1.98 +// We use this to speed up reference processing during young collection and
    1.99 +// quickly reclaim humongous objects. For the latter, by making a humongous region
   1.100 +// succeed this test, we sort-of add it to the collection set. During the reference
   1.101 +// iteration closures, when we see a humongous region, we then simply mark it as
   1.102 +// referenced, i.e. live.
   1.103 +class G1InCSetStateFastTestBiasedMappedArray : public G1BiasedMappedArray<InCSetState> {
   1.104 + protected:
   1.105 +  InCSetState default_value() const { return InCSetState::NotInCSet; }
   1.106 + public:
   1.107 +  void set_humongous(uintptr_t index) {
   1.108 +    assert(get_by_index(index).is_default(),
   1.109 +           err_msg("State at index " INTPTR_FORMAT" should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
   1.110 +    set_by_index(index, InCSetState::Humongous);
   1.111 +  }
   1.112 +
   1.113 +  void clear_humongous(uintptr_t index) {
   1.114 +    set_by_index(index, InCSetState::NotInCSet);
   1.115 +  }
   1.116 +
   1.117 +  void set_in_young(uintptr_t index) {
   1.118 +    assert(get_by_index(index).is_default(),
   1.119 +           err_msg("State at index " INTPTR_FORMAT" should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
   1.120 +    set_by_index(index, InCSetState::Young);
   1.121 +  }
   1.122 +
   1.123 +  void set_in_old(uintptr_t index) {
   1.124 +    assert(get_by_index(index).is_default(),
   1.125 +           err_msg("State at index " INTPTR_FORMAT" should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value()));
   1.126 +    set_by_index(index, InCSetState::Old);
   1.127 +  }
   1.128 +
   1.129 +  bool is_in_cset_or_humongous(HeapWord* addr) const { return at(addr).is_in_cset_or_humongous(); }
   1.130 +  bool is_in_cset(HeapWord* addr) const { return at(addr).is_in_cset(); }
   1.131 +  InCSetState at(HeapWord* addr) const { return get_by_address(addr); }
   1.132 +  void clear() { G1BiasedMappedArray<InCSetState>::clear(); }
   1.133 +};
   1.134 +
   1.135 +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1INCSETSTATE_HPP

mercurial