psPromotionManager.hpp 7.3 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31
#ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_HPP
#define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_HPP

#include "gc_implementation/parallelScavenge/psPromotionLAB.hpp"
#include "memory/allocation.hpp"
#include "utilities/taskqueue.hpp"

D
duke 已提交
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
//
// psPromotionManager is used by a single thread to manage object survival
// during a scavenge. The promotion manager contains thread local data only.
//
// NOTE! Be carefull when allocating the stacks on cheap. If you are going
// to use a promotion manager in more than one thread, the stacks MUST be
// on cheap. This can lead to memory leaks, though, as they are not auto
// deallocated.
//
// FIX ME FIX ME Add a destructor, and don't rely on the user to drain/flush/deallocate!
//

// Move to some global location
#define HAS_BEEN_MOVED 0x1501d01d
// End move to some global location

class MutableSpace;
class PSOldGen;
class ParCompactionManager;

class PSPromotionManager : public CHeapObj {
  friend class PSScavenge;
  friend class PSRefProcTaskExecutor;
 private:
  static PSPromotionManager**         _manager_array;
  static OopStarTaskQueueSet*         _stack_array_depth;
  static PSOldGen*                    _old_gen;
  static MutableSpace*                _young_space;

J
jcoomes 已提交
61 62 63 64 65
#if TASKQUEUE_STATS
  size_t                              _masked_pushes;
  size_t                              _masked_steals;
  size_t                              _arrays_chunked;
  size_t                              _array_chunks_processed;
D
duke 已提交
66

J
jcoomes 已提交
67 68
  void print_taskqueue_stats(uint i) const;
  void print_local_stats(uint i) const;
D
duke 已提交
69
  static void print_stats();
J
jcoomes 已提交
70 71 72

  void reset_stats();
#endif // TASKQUEUE_STATS
D
duke 已提交
73 74 75 76 77 78 79

  PSYoungPromotionLAB                 _young_lab;
  PSOldPromotionLAB                   _old_lab;
  bool                                _young_gen_is_full;
  bool                                _old_gen_is_full;

  OopStarTaskQueue                    _claimed_stack_depth;
80
  OverflowTaskQueue<oop>              _claimed_stack_breadth;
D
duke 已提交
81 82 83 84 85 86 87 88

  bool                                _totally_drain;
  uint                                _target_stack_size;

  uint                                _array_chunk_size;
  uint                                _min_array_size_for_chunking;

  // Accessors
89 90
  static PSOldGen* old_gen()         { return _old_gen; }
  static MutableSpace* young_space() { return _young_space; }
D
duke 已提交
91 92

  inline static PSPromotionManager* manager_array(int index);
93
  template <class T> inline void claim_or_forward_internal_depth(T* p);
D
duke 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110

  // On the task queues we push reference locations as well as
  // partially-scanned arrays (in the latter case, we push an oop to
  // the from-space image of the array and the length on the
  // from-space image indicates how many entries on the array we still
  // need to scan; this is basically how ParNew does partial array
  // scanning too). To be able to distinguish between reference
  // locations and partially-scanned array oops we simply mask the
  // latter oops with 0x01. The next three methods do the masking,
  // unmasking, and checking whether the oop is masked or not. Notice
  // that the signature of the mask and unmask methods looks a bit
  // strange, as they accept and return different types (oop and
  // oop*). This is because of the difference in types between what
  // the task queue holds (oop*) and oops to partially-scanned arrays
  // (oop). We do all the necessary casting in the mask / unmask
  // methods to avoid sprinkling the rest of the code with more casts.

111 112 113 114 115 116 117 118
  // These are added to the taskqueue so PS_CHUNKED_ARRAY_OOP_MASK (or any
  // future masks) can't conflict with COMPRESSED_OOP_MASK
#define PS_CHUNKED_ARRAY_OOP_MASK  0x2

  bool is_oop_masked(StarTask p) {
    // If something is marked chunked it's always treated like wide oop*
    return (((intptr_t)(oop*)p) & PS_CHUNKED_ARRAY_OOP_MASK) ==
                                  PS_CHUNKED_ARRAY_OOP_MASK;
D
duke 已提交
119 120 121 122
  }

  oop* mask_chunked_array_oop(oop obj) {
    assert(!is_oop_masked((oop*) obj), "invariant");
123
    oop* ret = (oop*) ((uintptr_t)obj | PS_CHUNKED_ARRAY_OOP_MASK);
D
duke 已提交
124 125 126 127
    assert(is_oop_masked(ret), "invariant");
    return ret;
  }

128
  oop unmask_chunked_array_oop(StarTask p) {
D
duke 已提交
129
    assert(is_oop_masked(p), "invariant");
130 131 132
    assert(!p.is_narrow(), "chunked array oops cannot be narrow");
    oop *chunk = (oop*)p;  // cast p to oop (uses conversion operator)
    oop ret = oop((oop*)((uintptr_t)chunk & ~PS_CHUNKED_ARRAY_OOP_MASK));
D
duke 已提交
133 134 135 136
    assert(!is_oop_masked((oop*) ret), "invariant");
    return ret;
  }

137 138
  template <class T> void  process_array_chunk_work(oop obj,
                                                    int start, int end);
D
duke 已提交
139 140
  void process_array_chunk(oop old);

141
  template <class T> void push_depth(T* p) {
142
    claimed_stack_depth()->push(p);
D
duke 已提交
143 144 145
  }

 protected:
146
  static OopStarTaskQueueSet* stack_array_depth()   { return _stack_array_depth; }
D
duke 已提交
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
 public:
  // Static
  static void initialize();

  static void pre_scavenge();
  static void post_scavenge();

  static PSPromotionManager* gc_thread_promotion_manager(int index);
  static PSPromotionManager* vm_thread_promotion_manager();

  static bool steal_depth(int queue_num, int* seed, StarTask& t) {
    return stack_array_depth()->steal(queue_num, seed, t);
  }

  PSPromotionManager();

  // Accessors
  OopStarTaskQueue* claimed_stack_depth() {
    return &_claimed_stack_depth;
  }

  bool young_gen_is_full()             { return _young_gen_is_full; }

  bool old_gen_is_full()               { return _old_gen_is_full; }
  void set_old_gen_is_full(bool state) { _old_gen_is_full = state; }

  // Promotion methods
174
  template<bool promote_immediately> oop copy_to_survivor_space(oop o);
D
duke 已提交
175 176 177 178 179 180
  oop oop_promotion_failed(oop obj, markOop obj_mark);

  void reset();

  void flush_labs();
  void drain_stacks(bool totally_drain) {
181
    drain_stacks_depth(totally_drain);
D
duke 已提交
182
  }
183
 public:
D
duke 已提交
184 185 186 187 188 189 190 191
  void drain_stacks_cond_depth() {
    if (claimed_stack_depth()->size() > _target_stack_size) {
      drain_stacks_depth(false);
    }
  }
  void drain_stacks_depth(bool totally_drain);

  bool stacks_empty() {
192
    return claimed_stack_depth()->is_empty();
D
duke 已提交
193 194
  }

195
  inline void process_popped_location_depth(StarTask p);
D
duke 已提交
196

197
  template <class T> inline void claim_or_forward_depth(T* p);
D
duke 已提交
198

J
jcoomes 已提交
199
  TASKQUEUE_STATS_ONLY(inline void record_steal(StarTask& p);)
D
duke 已提交
200
};
201 202

#endif // SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_HPP