hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.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 // Tasks for parallel compaction of the old generation
       
    27 //
       
    28 // Tasks are created and enqueued on a task queue. The
       
    29 // tasks for parallel old collector for marking objects
       
    30 // are MarkFromRootsTask and ThreadRootsMarkingTask.
       
    31 //
       
    32 // MarkFromRootsTask's are created
       
    33 // with a root group (e.g., jni_handles) and when the do_it()
       
    34 // method of a MarkFromRootsTask is executed, it starts marking
       
    35 // form it's root group.
       
    36 //
       
    37 // ThreadRootsMarkingTask's are created for each Java thread.  When
       
    38 // the do_it() method of a ThreadRootsMarkingTask is executed, it
       
    39 // starts marking from the thread's roots.
       
    40 //
       
    41 // The enqueuing of the MarkFromRootsTask and ThreadRootsMarkingTask
       
    42 // do little more than create the task and put it on a queue.  The
       
    43 // queue is a GCTaskQueue and threads steal tasks from this GCTaskQueue.
       
    44 //
       
    45 // In addition to the MarkFromRootsTask and ThreadRootsMarkingTask
       
    46 // tasks there are StealMarkingTask tasks.  The StealMarkingTask's
       
    47 // steal a reference from the marking stack of another
       
    48 // thread and transitively marks the object of the reference
       
    49 // and internal references.  After successfully stealing a reference
       
    50 // and marking it, the StealMarkingTask drains its marking stack
       
    51 // stack before attempting another steal.
       
    52 //
       
    53 // ThreadRootsMarkingTask
       
    54 //
       
    55 // This task marks from the roots of a single thread. This task
       
    56 // enables marking of thread roots in parallel.
       
    57 //
       
    58 
       
    59 class ParallelTaskTerminator;
       
    60 
       
    61 class ThreadRootsMarkingTask : public GCTask {
       
    62  private:
       
    63   JavaThread* _java_thread;
       
    64   VMThread* _vm_thread;
       
    65  public:
       
    66   ThreadRootsMarkingTask(JavaThread* root) : _java_thread(root), _vm_thread(NULL) {}
       
    67   ThreadRootsMarkingTask(VMThread* root) : _java_thread(NULL), _vm_thread(root) {}
       
    68 
       
    69   char* name() { return (char *)"thread-roots-marking-task"; }
       
    70 
       
    71   virtual void do_it(GCTaskManager* manager, uint which);
       
    72 };
       
    73 
       
    74 
       
    75 //
       
    76 // MarkFromRootsTask
       
    77 //
       
    78 // This task marks from all the roots to all live
       
    79 // objects.
       
    80 //
       
    81 //
       
    82 
       
    83 class MarkFromRootsTask : public GCTask {
       
    84  public:
       
    85   enum RootType {
       
    86     universe              = 1,
       
    87     jni_handles           = 2,
       
    88     threads               = 3,
       
    89     object_synchronizer   = 4,
       
    90     flat_profiler         = 5,
       
    91     management            = 6,
       
    92     jvmti                 = 7,
       
    93     system_dictionary     = 8,
       
    94     vm_symbols            = 9,
       
    95     reference_processing  = 10
       
    96   };
       
    97  private:
       
    98   RootType _root_type;
       
    99  public:
       
   100   MarkFromRootsTask(RootType value) : _root_type(value) {}
       
   101 
       
   102   char* name() { return (char *)"mark-from-roots-task"; }
       
   103 
       
   104   virtual void do_it(GCTaskManager* manager, uint which);
       
   105 };
       
   106 
       
   107 //
       
   108 // RefProcTaskProxy
       
   109 //
       
   110 // This task is used as a proxy to parallel reference processing tasks .
       
   111 //
       
   112 
       
   113 class RefProcTaskProxy : public GCTask {
       
   114   typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
       
   115   ProcessTask & _rp_task;
       
   116   uint          _work_id;
       
   117 public:
       
   118   RefProcTaskProxy(ProcessTask & rp_task, uint work_id)
       
   119     : _rp_task(rp_task),
       
   120       _work_id(work_id)
       
   121   { }
       
   122 
       
   123 private:
       
   124   virtual char* name() { return (char *)"Process referents by policy in parallel"; }
       
   125 
       
   126   virtual void do_it(GCTaskManager* manager, uint which);
       
   127 };
       
   128 
       
   129 
       
   130 
       
   131 //
       
   132 // RefEnqueueTaskProxy
       
   133 //
       
   134 // This task is used as a proxy to parallel reference processing tasks .
       
   135 //
       
   136 
       
   137 class RefEnqueueTaskProxy: public GCTask {
       
   138   typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
       
   139   EnqueueTask& _enq_task;
       
   140   uint         _work_id;
       
   141 
       
   142 public:
       
   143   RefEnqueueTaskProxy(EnqueueTask& enq_task, uint work_id)
       
   144     : _enq_task(enq_task),
       
   145       _work_id(work_id)
       
   146   { }
       
   147 
       
   148   virtual char* name() { return (char *)"Enqueue reference objects in parallel"; }
       
   149   virtual void do_it(GCTaskManager* manager, uint which)
       
   150   {
       
   151     _enq_task.work(_work_id);
       
   152   }
       
   153 };
       
   154 
       
   155 
       
   156 //
       
   157 // RefProcTaskExecutor
       
   158 //
       
   159 // Task executor is an interface for the reference processor to run
       
   160 // tasks using GCTaskManager.
       
   161 //
       
   162 
       
   163 class RefProcTaskExecutor: public AbstractRefProcTaskExecutor {
       
   164   virtual void execute(ProcessTask& task);
       
   165   virtual void execute(EnqueueTask& task);
       
   166 };
       
   167 
       
   168 
       
   169 //
       
   170 // StealMarkingTask
       
   171 //
       
   172 // This task is used to distribute work to idle threads.
       
   173 //
       
   174 
       
   175 class StealMarkingTask : public GCTask {
       
   176  private:
       
   177    ParallelTaskTerminator* const _terminator;
       
   178  private:
       
   179 
       
   180  public:
       
   181   char* name() { return (char *)"steal-marking-task"; }
       
   182 
       
   183   StealMarkingTask(ParallelTaskTerminator* t);
       
   184 
       
   185   ParallelTaskTerminator* terminator() { return _terminator; }
       
   186 
       
   187   virtual void do_it(GCTaskManager* manager, uint which);
       
   188 };
       
   189 
       
   190 //
       
   191 // StealChunkCompactionTask
       
   192 //
       
   193 // This task is used to distribute work to idle threads.
       
   194 //
       
   195 
       
   196 class StealChunkCompactionTask : public GCTask {
       
   197  private:
       
   198    ParallelTaskTerminator* const _terminator;
       
   199  public:
       
   200   StealChunkCompactionTask(ParallelTaskTerminator* t);
       
   201 
       
   202   char* name() { return (char *)"steal-chunk-task"; }
       
   203   ParallelTaskTerminator* terminator() { return _terminator; }
       
   204 
       
   205   virtual void do_it(GCTaskManager* manager, uint which);
       
   206 };
       
   207 
       
   208 //
       
   209 // UpdateDensePrefixTask
       
   210 //
       
   211 // This task is used to update the dense prefix
       
   212 // of a space.
       
   213 //
       
   214 
       
   215 class UpdateDensePrefixTask : public GCTask {
       
   216  private:
       
   217   PSParallelCompact::SpaceId _space_id;
       
   218   size_t _chunk_index_start;
       
   219   size_t _chunk_index_end;
       
   220 
       
   221  public:
       
   222   char* name() { return (char *)"update-dense_prefix-task"; }
       
   223 
       
   224   UpdateDensePrefixTask(PSParallelCompact::SpaceId space_id,
       
   225                         size_t chunk_index_start,
       
   226                         size_t chunk_index_end);
       
   227 
       
   228   virtual void do_it(GCTaskManager* manager, uint which);
       
   229 };
       
   230 
       
   231 //
       
   232 // DrainStacksCompactionTask
       
   233 //
       
   234 // This task processes chunks that have been added to the stacks of each
       
   235 // compaction manager.
       
   236 //
       
   237 // Trying to use one draining thread does not work because there are no
       
   238 // guarantees about which task will be picked up by which thread.  For example,
       
   239 // if thread A gets all the preloaded chunks, thread A may not get a draining
       
   240 // task (they may all be done by other threads).
       
   241 //
       
   242 
       
   243 class DrainStacksCompactionTask : public GCTask {
       
   244  public:
       
   245   char* name() { return (char *)"drain-chunk-task"; }
       
   246   virtual void do_it(GCTaskManager* manager, uint which);
       
   247 };