hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
changeset 1 489c9b5090e2
child 1407 9006b01ba3fd
equal deleted inserted replaced
0:fd16c54261b3 1:489c9b5090e2
       
     1 /*
       
     2  * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 //
       
    26 // psPromotionManager is used by a single thread to manage object survival
       
    27 // during a scavenge. The promotion manager contains thread local data only.
       
    28 //
       
    29 // NOTE! Be carefull when allocating the stacks on cheap. If you are going
       
    30 // to use a promotion manager in more than one thread, the stacks MUST be
       
    31 // on cheap. This can lead to memory leaks, though, as they are not auto
       
    32 // deallocated.
       
    33 //
       
    34 // FIX ME FIX ME Add a destructor, and don't rely on the user to drain/flush/deallocate!
       
    35 //
       
    36 
       
    37 // Move to some global location
       
    38 #define HAS_BEEN_MOVED 0x1501d01d
       
    39 // End move to some global location
       
    40 
       
    41 
       
    42 class MutableSpace;
       
    43 class PSOldGen;
       
    44 class ParCompactionManager;
       
    45 class ObjectStartArray;
       
    46 class ParallelCompactData;
       
    47 class ParMarkBitMap;
       
    48 
       
    49 // Move to it's own file if this works out.
       
    50 
       
    51 class ParCompactionManager : public CHeapObj {
       
    52   friend class ParallelTaskTerminator;
       
    53   friend class ParMarkBitMap;
       
    54   friend class PSParallelCompact;
       
    55   friend class StealChunkCompactionTask;
       
    56   friend class UpdateAndFillClosure;
       
    57   friend class RefProcTaskExecutor;
       
    58 
       
    59  public:
       
    60 
       
    61 // ------------------------  Don't putback if not needed
       
    62   // Actions that the compaction manager should take.
       
    63   enum Action {
       
    64     Update,
       
    65     Copy,
       
    66     UpdateAndCopy,
       
    67     CopyAndUpdate,
       
    68     VerifyUpdate,
       
    69     ResetObjects,
       
    70     NotValid
       
    71   };
       
    72 // ------------------------  End don't putback if not needed
       
    73 
       
    74  private:
       
    75   static ParCompactionManager**  _manager_array;
       
    76   static OopTaskQueueSet*      _stack_array;
       
    77   static ObjectStartArray*     _start_array;
       
    78   static ChunkTaskQueueSet*    _chunk_array;
       
    79   static PSOldGen*             _old_gen;
       
    80 
       
    81   OopTaskQueue                 _marking_stack;
       
    82   GrowableArray<oop>*          _overflow_stack;
       
    83   // Is there a way to reuse the _marking_stack for the
       
    84   // saving empty chunks?  For now just create a different
       
    85   // type of TaskQueue.
       
    86 
       
    87 #ifdef USE_ChunkTaskQueueWithOverflow
       
    88   ChunkTaskQueueWithOverflow   _chunk_stack;
       
    89 #else
       
    90   ChunkTaskQueue               _chunk_stack;
       
    91   GrowableArray<size_t>*       _chunk_overflow_stack;
       
    92 #endif
       
    93 
       
    94 #if 1  // does this happen enough to need a per thread stack?
       
    95   GrowableArray<Klass*>*       _revisit_klass_stack;
       
    96 #endif
       
    97   static ParMarkBitMap* _mark_bitmap;
       
    98 
       
    99   Action _action;
       
   100 
       
   101   static PSOldGen* old_gen()             { return _old_gen; }
       
   102   static ObjectStartArray* start_array() { return _start_array; }
       
   103   static OopTaskQueueSet* stack_array()   { return _stack_array; }
       
   104 
       
   105   static void initialize(ParMarkBitMap* mbm);
       
   106 
       
   107  protected:
       
   108   // Array of tasks.  Needed by the ParallelTaskTerminator.
       
   109   static ChunkTaskQueueSet* chunk_array()   { return _chunk_array; }
       
   110 
       
   111   OopTaskQueue*  marking_stack()          { return &_marking_stack; }
       
   112   GrowableArray<oop>* overflow_stack()    { return _overflow_stack; }
       
   113 #ifdef USE_ChunkTaskQueueWithOverflow
       
   114   ChunkTaskQueueWithOverflow* chunk_stack() { return &_chunk_stack; }
       
   115 #else
       
   116   ChunkTaskQueue*  chunk_stack()          { return &_chunk_stack; }
       
   117   GrowableArray<size_t>* chunk_overflow_stack() { return _chunk_overflow_stack; }
       
   118 #endif
       
   119 
       
   120   // Pushes onto the marking stack.  If the marking stack is full,
       
   121   // pushes onto the overflow stack.
       
   122   void stack_push(oop obj);
       
   123   // Do not implement an equivalent stack_pop.  Deal with the
       
   124   // marking stack and overflow stack directly.
       
   125 
       
   126   // Pushes onto the chunk stack.  If the chunk stack is full,
       
   127   // pushes onto the chunk overflow stack.
       
   128   void chunk_stack_push(size_t chunk_index);
       
   129  public:
       
   130 
       
   131   Action action() { return _action; }
       
   132   void set_action(Action v) { _action = v; }
       
   133 
       
   134   inline static ParCompactionManager* manager_array(int index);
       
   135 
       
   136   ParCompactionManager();
       
   137   ~ParCompactionManager();
       
   138 
       
   139   void allocate_stacks();
       
   140   void deallocate_stacks();
       
   141   ParMarkBitMap* mark_bitmap() { return _mark_bitmap; }
       
   142 
       
   143   // Take actions in preparation for a compaction.
       
   144   static void reset();
       
   145 
       
   146   // void drain_stacks();
       
   147 
       
   148   bool should_update();
       
   149   bool should_copy();
       
   150   bool should_verify_only();
       
   151   bool should_reset_only();
       
   152 
       
   153 #if 1
       
   154   // Probably stays as a growable array
       
   155   GrowableArray<Klass*>* revisit_klass_stack() { return _revisit_klass_stack; }
       
   156 #endif
       
   157 
       
   158   // Save oop for later processing.  Must not fail.
       
   159   void save_for_scanning(oop m);
       
   160   // Get a oop for scanning.  If returns null, no oop were found.
       
   161   oop retrieve_for_scanning();
       
   162 
       
   163   // Save chunk for later processing.  Must not fail.
       
   164   void save_for_processing(size_t chunk_index);
       
   165   // Get a chunk for processing.  If returns null, no chunk were found.
       
   166   bool retrieve_for_processing(size_t& chunk_index);
       
   167 
       
   168   // Access function for compaction managers
       
   169   static ParCompactionManager* gc_thread_compaction_manager(int index);
       
   170 
       
   171   static bool steal(int queue_num, int* seed, Task& t) {
       
   172     return stack_array()->steal(queue_num, seed, t);
       
   173   }
       
   174 
       
   175   static bool steal(int queue_num, int* seed, ChunkTask& t) {
       
   176     return chunk_array()->steal(queue_num, seed, t);
       
   177   }
       
   178 
       
   179   // Process tasks remaining on any stack
       
   180   void drain_marking_stacks(OopClosure *blk);
       
   181 
       
   182   // Process tasks remaining on any stack
       
   183   void drain_chunk_stacks();
       
   184 
       
   185   // Process tasks remaining on any stack
       
   186   void drain_chunk_overflow_stack();
       
   187 
       
   188   // Debugging support
       
   189 #ifdef ASSERT
       
   190   bool stacks_have_been_allocated();
       
   191 #endif
       
   192 };
       
   193 
       
   194 inline ParCompactionManager* ParCompactionManager::manager_array(int index) {
       
   195   assert(_manager_array != NULL, "access of NULL manager_array");
       
   196   assert(index >= 0 && index <= (int)ParallelGCThreads,
       
   197     "out of range manager_array access");
       
   198   return _manager_array[index];
       
   199 }