alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (parNewGeneration.hpp)

This example Java source code file (parNewGeneration.hpp) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

defnewgeneration\:\:isaliveclosure, generation, heapword, objtoscanqueueset, oopsingenclosure, parevacuatefollowersclosure, parkeepaliveclosure, parnewgeneration, parnewrefproctaskexecutor, parrootscanwithoutbarrierclosure, parscanthreadstateset, parscanweakrefclosure, stack, taskqueue_stats

The parNewGeneration.hpp Java example source code

/*
 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
 * 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.
 *
 * 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.
 *
 */

#ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
#define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP

#include "gc_implementation/shared/gcTrace.hpp"
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
#include "gc_implementation/shared/copyFailedInfo.hpp"
#include "memory/defNewGeneration.hpp"
#include "memory/padded.hpp"
#include "utilities/taskqueue.hpp"

class ChunkArray;
class ParScanWithoutBarrierClosure;
class ParScanWithBarrierClosure;
class ParRootScanWithoutBarrierClosure;
class ParRootScanWithBarrierTwoGensClosure;
class ParEvacuateFollowersClosure;

// It would be better if these types could be kept local to the .cpp file,
// but they must be here to allow ParScanClosure::do_oop_work to be defined
// in genOopClosures.inline.hpp.

typedef Padded<OopTaskQueue> ObjToScanQueue;
typedef GenericTaskQueueSet<ObjToScanQueue, mtGC> ObjToScanQueueSet;

class ParKeepAliveClosure: public DefNewGeneration::KeepAliveClosure {
 private:
  ParScanWeakRefClosure* _par_cl;
 protected:
  template <class T> void do_oop_work(T* p);
 public:
  ParKeepAliveClosure(ParScanWeakRefClosure* cl);
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
};

// The state needed by thread performing parallel young-gen collection.
class ParScanThreadState {
  friend class ParScanThreadStateSet;
 private:
  ObjToScanQueue *_work_queue;
  Stack<oop, mtGC>* const _overflow_stack;

  ParGCAllocBuffer _to_space_alloc_buffer;

  ParScanWithoutBarrierClosure         _to_space_closure; // scan_without_gc_barrier
  ParScanWithBarrierClosure            _old_gen_closure; // scan_with_gc_barrier
  ParRootScanWithoutBarrierClosure     _to_space_root_closure; // scan_root_without_gc_barrier
  // One of these two will be passed to process_strong_roots, which will
  // set its generation.  The first is for two-gen configs where the
  // old gen collects the perm gen; the second is for arbitrary configs.
  // The second isn't used right now (it used to be used for the train, an
  // incremental collector) but the declaration has been left as a reminder.
  ParRootScanWithBarrierTwoGensClosure _older_gen_closure;
  // This closure will always be bound to the old gen; it will be used
  // in evacuate_followers.
  ParRootScanWithBarrierTwoGensClosure _old_gen_root_closure; // scan_old_root_with_gc_barrier
  ParEvacuateFollowersClosure          _evacuate_followers;
  DefNewGeneration::IsAliveClosure     _is_alive_closure;
  ParScanWeakRefClosure                _scan_weak_ref_closure;
  ParKeepAliveClosure                  _keep_alive_closure;


  Space* _to_space;
  Space* to_space() { return _to_space; }

  ParNewGeneration* _young_gen;
  ParNewGeneration* young_gen() const { return _young_gen; }

  Generation* _old_gen;
  Generation* old_gen() { return _old_gen; }

  HeapWord *_young_old_boundary;

  int _hash_seed;
  int _thread_num;
  ageTable _ageTable;

  bool _to_space_full;

#if TASKQUEUE_STATS
  size_t _term_attempts;
  size_t _overflow_refills;
  size_t _overflow_refill_objs;
#endif // TASKQUEUE_STATS

  // Stats for promotion failure
  PromotionFailedInfo _promotion_failed_info;

  // Timing numbers.
  double _start;
  double _start_strong_roots;
  double _strong_roots_time;
  double _start_term;
  double _term_time;

  // Helper for trim_queues. Scans subset of an array and makes
  // remainder available for work stealing.
  void scan_partial_array_and_push_remainder(oop obj);

  // In support of CMS' parallel rescan of survivor space.
  ChunkArray* _survivor_chunk_array;
  ChunkArray* survivor_chunk_array() { return _survivor_chunk_array; }

  void record_survivor_plab(HeapWord* plab_start, size_t plab_word_size);

  ParScanThreadState(Space* to_space_, ParNewGeneration* gen_,
                     Generation* old_gen_, int thread_num_,
                     ObjToScanQueueSet* work_queue_set_,
                     Stack<oop, mtGC>* overflow_stacks_,
                     size_t desired_plab_sz_,
                     ParallelTaskTerminator& term_);

 public:
  ageTable* age_table() {return &_ageTable;}

  ObjToScanQueue* work_queue() { return _work_queue; }

  ParGCAllocBuffer* to_space_alloc_buffer() {
    return &_to_space_alloc_buffer;
  }

  ParEvacuateFollowersClosure&      evacuate_followers_closure() { return _evacuate_followers; }
  DefNewGeneration::IsAliveClosure& is_alive_closure() { return _is_alive_closure; }
  ParScanWeakRefClosure&            scan_weak_ref_closure() { return _scan_weak_ref_closure; }
  ParKeepAliveClosure&              keep_alive_closure() { return _keep_alive_closure; }
  ParScanClosure&                   older_gen_closure() { return _older_gen_closure; }
  ParRootScanWithoutBarrierClosure& to_space_root_closure() { return _to_space_root_closure; };

  // Decrease queue size below "max_size".
  void trim_queues(int max_size);

  // Private overflow stack usage
  Stack<oop, mtGC>* overflow_stack() { return _overflow_stack; }
  bool take_from_overflow_stack();
  void push_on_overflow_stack(oop p);

  // Is new_obj a candidate for scan_partial_array_and_push_remainder method.
  inline bool should_be_partially_scanned(oop new_obj, oop old_obj) const;

  int* hash_seed()  { return &_hash_seed; }
  int  thread_num() { return _thread_num; }

  // Allocate a to-space block of size "sz", or else return NULL.
  HeapWord* alloc_in_to_space_slow(size_t word_sz);

  HeapWord* alloc_in_to_space(size_t word_sz) {
    HeapWord* obj = to_space_alloc_buffer()->allocate(word_sz);
    if (obj != NULL) return obj;
    else return alloc_in_to_space_slow(word_sz);
  }

  HeapWord* young_old_boundary() { return _young_old_boundary; }

  void set_young_old_boundary(HeapWord *boundary) {
    _young_old_boundary = boundary;
  }

  // Undo the most recent allocation ("obj", of "word_sz").
  void undo_alloc_in_to_space(HeapWord* obj, size_t word_sz);

  // Promotion failure stats
  void register_promotion_failure(size_t sz) {
    _promotion_failed_info.register_copy_failure(sz);
  }
  PromotionFailedInfo& promotion_failed_info() {
    return _promotion_failed_info;
  }
  bool promotion_failed() {
    return _promotion_failed_info.has_failed();
  }
  void print_promotion_failure_size();

#if TASKQUEUE_STATS
  TaskQueueStats & taskqueue_stats() const { return _work_queue->stats; }

  size_t term_attempts() const             { return _term_attempts; }
  size_t overflow_refills() const          { return _overflow_refills; }
  size_t overflow_refill_objs() const      { return _overflow_refill_objs; }

  void note_term_attempt()                 { ++_term_attempts; }
  void note_overflow_refill(size_t objs)   {
    ++_overflow_refills; _overflow_refill_objs += objs;
  }

  void reset_stats();
#endif // TASKQUEUE_STATS

  void start_strong_roots() {
    _start_strong_roots = os::elapsedTime();
  }
  void end_strong_roots() {
    _strong_roots_time += (os::elapsedTime() - _start_strong_roots);
  }
  double strong_roots_time() const { return _strong_roots_time; }
  void start_term_time() {
    TASKQUEUE_STATS_ONLY(note_term_attempt());
    _start_term = os::elapsedTime();
  }
  void end_term_time() {
    _term_time += (os::elapsedTime() - _start_term);
  }
  double term_time() const { return _term_time; }

  double elapsed_time() const {
    return os::elapsedTime() - _start;
  }
};

class ParNewGenTask: public AbstractGangTask {
 private:
  ParNewGeneration*            _gen;
  Generation*                  _next_gen;
  HeapWord*                    _young_old_boundary;
  class ParScanThreadStateSet* _state_set;

public:
  ParNewGenTask(ParNewGeneration*      gen,
                Generation*            next_gen,
                HeapWord*              young_old_boundary,
                ParScanThreadStateSet* state_set);

  HeapWord* young_old_boundary() { return _young_old_boundary; }

  void work(uint worker_id);

  // Reset the terminator in ParScanThreadStateSet for
  // "active_workers" threads.
  virtual void set_for_termination(int active_workers);
};

class KeepAliveClosure: public DefNewGeneration::KeepAliveClosure {
 protected:
  template <class T> void do_oop_work(T* p);
 public:
  KeepAliveClosure(ScanWeakRefClosure* cl);
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
};

class EvacuateFollowersClosureGeneral: public VoidClosure {
 private:
  GenCollectedHeap* _gch;
  int               _level;
  OopsInGenClosure* _scan_cur_or_nonheap;
  OopsInGenClosure* _scan_older;
 public:
  EvacuateFollowersClosureGeneral(GenCollectedHeap* gch, int level,
                                  OopsInGenClosure* cur,
                                  OopsInGenClosure* older);
  virtual void do_void();
};

// Closure for scanning ParNewGeneration.
// Same as ScanClosure, except does parallel GC barrier.
class ScanClosureWithParBarrier: public ScanClosure {
 protected:
  template <class T> void do_oop_work(T* p);
 public:
  ScanClosureWithParBarrier(ParNewGeneration* g, bool gc_barrier);
  virtual void do_oop(oop* p);
  virtual void do_oop(narrowOop* p);
};

// Implements AbstractRefProcTaskExecutor for ParNew.
class ParNewRefProcTaskExecutor: public AbstractRefProcTaskExecutor {
 private:
  ParNewGeneration&      _generation;
  ParScanThreadStateSet& _state_set;
 public:
  ParNewRefProcTaskExecutor(ParNewGeneration& generation,
                            ParScanThreadStateSet& state_set)
    : _generation(generation), _state_set(state_set)
  { }

  // Executes a task using worker threads.
  virtual void execute(ProcessTask& task);
  virtual void execute(EnqueueTask& task);
  // Switch to single threaded mode.
  virtual void set_single_threaded_mode();
};


// A Generation that does parallel young-gen collection.

class ParNewGeneration: public DefNewGeneration {
  friend class ParNewGenTask;
  friend class ParNewRefProcTask;
  friend class ParNewRefProcTaskExecutor;
  friend class ParScanThreadStateSet;
  friend class ParEvacuateFollowersClosure;

 private:
  // The per-worker-thread work queues
  ObjToScanQueueSet* _task_queues;

  // Per-worker-thread local overflow stacks
  Stack<oop, mtGC>* _overflow_stacks;

  // Desired size of survivor space plab's
  PLABStats _plab_stats;

  // A list of from-space images of to-be-scanned objects, threaded through
  // klass-pointers (klass information already copied to the forwarded
  // image.)  Manipulated with CAS.
  oop _overflow_list;
  NOT_PRODUCT(ssize_t _num_par_pushes;)

  // If true, older generation does not support promotion undo, so avoid.
  static bool _avoid_promotion_undo;

  // This closure is used by the reference processor to filter out
  // references to live referent.
  DefNewGeneration::IsAliveClosure _is_alive_closure;

  static oop real_forwardee_slow(oop obj);
  static void waste_some_time();

  // Preserve the mark of "obj", if necessary, in preparation for its mark
  // word being overwritten with a self-forwarding-pointer.
  void preserve_mark_if_necessary(oop obj, markOop m);

  void handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer);

 protected:

  bool _survivor_overflow;

  bool avoid_promotion_undo() { return _avoid_promotion_undo; }
  void set_avoid_promotion_undo(bool v) { _avoid_promotion_undo = v; }

  bool survivor_overflow() { return _survivor_overflow; }
  void set_survivor_overflow(bool v) { _survivor_overflow = v; }

 public:
  ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level);

  ~ParNewGeneration() {
    for (uint i = 0; i < ParallelGCThreads; i++)
        delete _task_queues->queue(i);

    delete _task_queues;
  }

  virtual void ref_processor_init();
  virtual Generation::Name kind()        { return Generation::ParNew; }
  virtual const char* name() const;
  virtual const char* short_name() const { return "ParNew"; }

  // override
  virtual bool refs_discovery_is_mt()     const {
    assert(UseParNewGC, "ParNewGeneration only when UseParNewGC");
    return ParallelGCThreads > 1;
  }

  // Make the collection virtual.
  virtual void collect(bool   full,
                       bool   clear_all_soft_refs,
                       size_t size,
                       bool   is_tlab);

  // This needs to be visible to the closure function.
  // "obj" is the object to be copied, "m" is a recent value of its mark
  // that must not contain a forwarding pointer (though one might be
  // inserted in "obj"s mark word by a parallel thread).
  inline oop copy_to_survivor_space(ParScanThreadState* par_scan_state,
                             oop obj, size_t obj_sz, markOop m) {
    if (_avoid_promotion_undo) {
       return copy_to_survivor_space_avoiding_promotion_undo(par_scan_state,
                                                             obj, obj_sz, m);
    }

    return copy_to_survivor_space_with_undo(par_scan_state, obj, obj_sz, m);
  }

  oop copy_to_survivor_space_avoiding_promotion_undo(ParScanThreadState* par_scan_state,
                             oop obj, size_t obj_sz, markOop m);

  oop copy_to_survivor_space_with_undo(ParScanThreadState* par_scan_state,
                             oop obj, size_t obj_sz, markOop m);

  // in support of testing overflow code
  NOT_PRODUCT(int _overflow_counter;)
  NOT_PRODUCT(bool should_simulate_overflow();)

  // Accessor for overflow list
  oop overflow_list() { return _overflow_list; }

  // Push the given (from-space) object on the global overflow list.
  void push_on_overflow_list(oop from_space_obj, ParScanThreadState* par_scan_state);

  // If the global overflow list is non-empty, move some tasks from it
  // onto "work_q" (which need not be empty).  No more than 1/4 of the
  // available space on "work_q" is used.
  bool take_from_overflow_list(ParScanThreadState* par_scan_state);
  bool take_from_overflow_list_work(ParScanThreadState* par_scan_state);

  // The task queues to be used by parallel GC threads.
  ObjToScanQueueSet* task_queues() {
    return _task_queues;
  }

  PLABStats* plab_stats() {
    return &_plab_stats;
  }

  size_t desired_plab_sz() {
    return _plab_stats.desired_plab_sz();
  }

  static oop real_forwardee(oop obj);

  DEBUG_ONLY(static bool is_legal_forward_ptr(oop p);)
};

#endif // SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP

Other Java examples (source code examples)

Here is a short list of links related to this Java parNewGeneration.hpp source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.