src/share/vm/memory/sharedHeap.hpp

Wed, 15 Feb 2012 10:12:55 -0800

author
never
date
Wed, 15 Feb 2012 10:12:55 -0800
changeset 3571
09d00c18e323
parent 3357
441e946dc1af
child 4037
da91efe96a93
permissions
-rw-r--r--

7145537: minor tweaks to LogEvents
Reviewed-by: kvn, twisti

     1 /*
     2  * Copyright (c) 2000, 2010, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #ifndef SHARE_VM_MEMORY_SHAREDHEAP_HPP
    26 #define SHARE_VM_MEMORY_SHAREDHEAP_HPP
    28 #include "gc_interface/collectedHeap.hpp"
    29 #include "memory/generation.hpp"
    30 #include "memory/permGen.hpp"
    32 // A "SharedHeap" is an implementation of a java heap for HotSpot.  This
    33 // is an abstract class: there may be many different kinds of heaps.  This
    34 // class defines the functions that a heap must implement, and contains
    35 // infrastructure common to all heaps.
    37 class PermGen;
    38 class Generation;
    39 class BarrierSet;
    40 class GenRemSet;
    41 class Space;
    42 class SpaceClosure;
    43 class OopClosure;
    44 class OopsInGenClosure;
    45 class ObjectClosure;
    46 class SubTasksDone;
    47 class WorkGang;
    48 class FlexibleWorkGang;
    49 class CollectorPolicy;
    50 class KlassHandle;
    52 // Note on use of FlexibleWorkGang's for GC.
    53 // There are three places where task completion is determined.
    54 // In
    55 //    1) ParallelTaskTerminator::offer_termination() where _n_threads
    56 //    must be set to the correct value so that count of workers that
    57 //    have offered termination will exactly match the number
    58 //    working on the task.  Tasks such as those derived from GCTask
    59 //    use ParallelTaskTerminator's.  Tasks that want load balancing
    60 //    by work stealing use this method to gauge completion.
    61 //    2) SubTasksDone has a variable _n_threads that is used in
    62 //    all_tasks_completed() to determine completion.  all_tasks_complete()
    63 //    counts the number of tasks that have been done and then reset
    64 //    the SubTasksDone so that it can be used again.  When the number of
    65 //    tasks is set to the number of GC workers, then _n_threads must
    66 //    be set to the number of active GC workers. G1CollectedHeap,
    67 //    HRInto_G1RemSet, GenCollectedHeap and SharedHeap have SubTasksDone.
    68 //    This seems too many.
    69 //    3) SequentialSubTasksDone has an _n_threads that is used in
    70 //    a way similar to SubTasksDone and has the same dependency on the
    71 //    number of active GC workers.  CompactibleFreeListSpace and Space
    72 //    have SequentialSubTasksDone's.
    73 // Example of using SubTasksDone and SequentialSubTasksDone
    74 // G1CollectedHeap::g1_process_strong_roots() calls
    75 //  process_strong_roots(false, // no scoping; this is parallel code
    76 //                       collecting_perm_gen, so,
    77 //                       &buf_scan_non_heap_roots,
    78 //                       &eager_scan_code_roots,
    79 //                       &buf_scan_perm);
    80 //  which delegates to SharedHeap::process_strong_roots() and uses
    81 //  SubTasksDone* _process_strong_tasks to claim tasks.
    82 //  process_strong_roots() calls
    83 //      rem_set()->younger_refs_iterate(perm_gen(), perm_blk);
    84 //  to scan the card table and which eventually calls down into
    85 //  CardTableModRefBS::par_non_clean_card_iterate_work().  This method
    86 //  uses SequentialSubTasksDone* _pst to claim tasks.
    87 //  Both SubTasksDone and SequentialSubTasksDone call their method
    88 //  all_tasks_completed() to count the number of GC workers that have
    89 //  finished their work.  That logic is "when all the workers are
    90 //  finished the tasks are finished".
    91 //
    92 //  The pattern that appears  in the code is to set _n_threads
    93 //  to a value > 1 before a task that you would like executed in parallel
    94 //  and then to set it to 0 after that task has completed.  A value of
    95 //  0 is a "special" value in set_n_threads() which translates to
    96 //  setting _n_threads to 1.
    97 //
    98 //  Some code uses _n_terminiation to decide if work should be done in
    99 //  parallel.  The notorious possibly_parallel_oops_do() in threads.cpp
   100 //  is an example of such code.  Look for variable "is_par" for other
   101 //  examples.
   102 //
   103 //  The active_workers is not reset to 0 after a parallel phase.  It's
   104 //  value may be used in later phases and in one instance at least
   105 //  (the parallel remark) it has to be used (the parallel remark depends
   106 //  on the partitioning done in the previous parallel scavenge).
   108 class SharedHeap : public CollectedHeap {
   109   friend class VMStructs;
   111   friend class VM_GC_Operation;
   112   friend class VM_CGC_Operation;
   114 private:
   115   // For claiming strong_roots tasks.
   116   SubTasksDone* _process_strong_tasks;
   118 protected:
   119   // There should be only a single instance of "SharedHeap" in a program.
   120   // This is enforced with the protected constructor below, which will also
   121   // set the static pointer "_sh" to that instance.
   122   static SharedHeap* _sh;
   124   // All heaps contain a "permanent generation."  This is some ways
   125   // similar to a generation in a generational system, in other ways not.
   126   // See the "PermGen" class.
   127   PermGen* _perm_gen;
   129   // and the Gen Remembered Set, at least one good enough to scan the perm
   130   // gen.
   131   GenRemSet* _rem_set;
   133   // A gc policy, controls global gc resource issues
   134   CollectorPolicy *_collector_policy;
   136   // See the discussion below, in the specification of the reader function
   137   // for this variable.
   138   int _strong_roots_parity;
   140   // If we're doing parallel GC, use this gang of threads.
   141   FlexibleWorkGang* _workers;
   143   // Full initialization is done in a concrete subtype's "initialize"
   144   // function.
   145   SharedHeap(CollectorPolicy* policy_);
   147   // Returns true if the calling thread holds the heap lock,
   148   // or the calling thread is a par gc thread and the heap_lock is held
   149   // by the vm thread doing a gc operation.
   150   bool heap_lock_held_for_gc();
   151   // True if the heap_lock is held by the a non-gc thread invoking a gc
   152   // operation.
   153   bool _thread_holds_heap_lock_for_gc;
   155 public:
   156   static SharedHeap* heap() { return _sh; }
   158   CollectorPolicy *collector_policy() const { return _collector_policy; }
   160   void set_barrier_set(BarrierSet* bs);
   161   SubTasksDone* process_strong_tasks() { return _process_strong_tasks; }
   163   // Does operations required after initialization has been done.
   164   virtual void post_initialize();
   166   // Initialization of ("weak") reference processing support
   167   virtual void ref_processing_init();
   169   void set_perm(PermGen* perm_gen) { _perm_gen = perm_gen; }
   171   // This function returns the "GenRemSet" object that allows us to scan
   172   // generations; at least the perm gen, possibly more in a fully
   173   // generational heap.
   174   GenRemSet* rem_set() { return _rem_set; }
   176   // These function return the "permanent" generation, in which
   177   // reflective objects are allocated and stored.  Two versions, the second
   178   // of which returns the view of the perm gen as a generation.
   179   PermGen* perm() const { return _perm_gen; }
   180   Generation* perm_gen() const { return _perm_gen->as_gen(); }
   182   // Iteration functions.
   183   void oop_iterate(OopClosure* cl) = 0;
   185   // Same as above, restricted to a memory region.
   186   virtual void oop_iterate(MemRegion mr, OopClosure* cl) = 0;
   188   // Iterate over all objects allocated since the last collection, calling
   189   // "cl->do_object" on each.  The heap must have been initialized properly
   190   // to support this function, or else this call will fail.
   191   virtual void object_iterate_since_last_GC(ObjectClosure* cl) = 0;
   193   // Iterate over all spaces in use in the heap, in an undefined order.
   194   virtual void space_iterate(SpaceClosure* cl) = 0;
   196   // A SharedHeap will contain some number of spaces.  This finds the
   197   // space whose reserved area contains the given address, or else returns
   198   // NULL.
   199   virtual Space* space_containing(const void* addr) const = 0;
   201   bool no_gc_in_progress() { return !is_gc_active(); }
   203   // Some collectors will perform "process_strong_roots" in parallel.
   204   // Such a call will involve claiming some fine-grained tasks, such as
   205   // scanning of threads.  To make this process simpler, we provide the
   206   // "strong_roots_parity()" method.  Collectors that start parallel tasks
   207   // whose threads invoke "process_strong_roots" must
   208   // call "change_strong_roots_parity" in sequential code starting such a
   209   // task.  (This also means that a parallel thread may only call
   210   // process_strong_roots once.)
   211   //
   212   // For calls to process_strong_roots by sequential code, the parity is
   213   // updated automatically.
   214   //
   215   // The idea is that objects representing fine-grained tasks, such as
   216   // threads, will contain a "parity" field.  A task will is claimed in the
   217   // current "process_strong_roots" call only if its parity field is the
   218   // same as the "strong_roots_parity"; task claiming is accomplished by
   219   // updating the parity field to the strong_roots_parity with a CAS.
   220   //
   221   // If the client meats this spec, then strong_roots_parity() will have
   222   // the following properties:
   223   //   a) to return a different value than was returned before the last
   224   //      call to change_strong_roots_parity, and
   225   //   c) to never return a distinguished value (zero) with which such
   226   //      task-claiming variables may be initialized, to indicate "never
   227   //      claimed".
   228  private:
   229   void change_strong_roots_parity();
   230  public:
   231   int strong_roots_parity() { return _strong_roots_parity; }
   233   // Call these in sequential code around process_strong_roots.
   234   // strong_roots_prologue calls change_strong_roots_parity, if
   235   // parallel tasks are enabled.
   236   class StrongRootsScope : public MarkingCodeBlobClosure::MarkScope {
   237   public:
   238     StrongRootsScope(SharedHeap* outer, bool activate = true);
   239     ~StrongRootsScope();
   240   };
   241   friend class StrongRootsScope;
   243   enum ScanningOption {
   244     SO_None                = 0x0,
   245     SO_AllClasses          = 0x1,
   246     SO_SystemClasses       = 0x2,
   247     SO_Strings             = 0x4,
   248     SO_CodeCache           = 0x8
   249   };
   251   FlexibleWorkGang* workers() const { return _workers; }
   253   // Invoke the "do_oop" method the closure "roots" on all root locations.
   254   // If "collecting_perm_gen" is false, then roots that may only contain
   255   // references to permGen objects are not scanned; instead, in that case,
   256   // the "perm_blk" closure is applied to all outgoing refs in the
   257   // permanent generation.  The "so" argument determines which of roots
   258   // the closure is applied to:
   259   // "SO_None" does none;
   260   // "SO_AllClasses" applies the closure to all entries in the SystemDictionary;
   261   // "SO_SystemClasses" to all the "system" classes and loaders;
   262   // "SO_Strings" applies the closure to all entries in StringTable;
   263   // "SO_CodeCache" applies the closure to all elements of the CodeCache.
   264   void process_strong_roots(bool activate_scope,
   265                             bool collecting_perm_gen,
   266                             ScanningOption so,
   267                             OopClosure* roots,
   268                             CodeBlobClosure* code_roots,
   269                             OopsInGenClosure* perm_blk);
   271   // Apply "blk" to all the weak roots of the system.  These include
   272   // JNI weak roots, the code cache, system dictionary, symbol table,
   273   // string table.
   274   void process_weak_roots(OopClosure* root_closure,
   275                           CodeBlobClosure* code_roots,
   276                           OopClosure* non_root_closure);
   278   // The functions below are helper functions that a subclass of
   279   // "SharedHeap" can use in the implementation of its virtual
   280   // functions.
   282 public:
   284   // Do anything common to GC's.
   285   virtual void gc_prologue(bool full) = 0;
   286   virtual void gc_epilogue(bool full) = 0;
   288   // Sets the number of parallel threads that will be doing tasks
   289   // (such as process strong roots) subsequently.
   290   virtual void set_par_threads(uint t);
   292   int n_termination();
   293   void set_n_termination(int t);
   295   //
   296   // New methods from CollectedHeap
   297   //
   299   size_t permanent_capacity() const {
   300     assert(perm_gen(), "NULL perm gen");
   301     return perm_gen()->capacity();
   302   }
   304   size_t permanent_used() const {
   305     assert(perm_gen(), "NULL perm gen");
   306     return perm_gen()->used();
   307   }
   309   bool is_in_permanent(const void *p) const {
   310     assert(perm_gen(), "NULL perm gen");
   311     return perm_gen()->is_in_reserved(p);
   312   }
   314   // Different from is_in_permanent in that is_in_permanent
   315   // only checks if p is in the reserved area of the heap
   316   // and this checks to see if it in the commited area.
   317   // This is typically used by things like the forte stackwalker
   318   // during verification of suspicious frame values.
   319   bool is_permanent(const void *p) const {
   320     assert(perm_gen(), "NULL perm gen");
   321     return perm_gen()->is_in(p);
   322   }
   324   HeapWord* permanent_mem_allocate(size_t size) {
   325     assert(perm_gen(), "NULL perm gen");
   326     return _perm_gen->mem_allocate(size);
   327   }
   329   void permanent_oop_iterate(OopClosure* cl) {
   330     assert(perm_gen(), "NULL perm gen");
   331     _perm_gen->oop_iterate(cl);
   332   }
   334   void permanent_object_iterate(ObjectClosure* cl) {
   335     assert(perm_gen(), "NULL perm gen");
   336     _perm_gen->object_iterate(cl);
   337   }
   339   // Some utilities.
   340   void print_size_transition(outputStream* out,
   341                              size_t bytes_before,
   342                              size_t bytes_after,
   343                              size_t capacity);
   344 };
   346 #endif // SHARE_VM_MEMORY_SHAREDHEAP_HPP

mercurial