src/share/vm/gc_implementation/g1/bufferingOopClosure.hpp

Thu, 23 Oct 2014 12:02:08 -0700

author
asaha
date
Thu, 23 Oct 2014 12:02:08 -0700
changeset 7476
c2844108a708
parent 6969
02e61cf08ab3
child 7535
7ae4e26cb1e0
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright (c) 2001, 2014, 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_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
    26 #define SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
    28 #include "memory/iterator.hpp"
    29 #include "oops/oopsHierarchy.hpp"
    30 #include "runtime/os.hpp"
    31 #include "utilities/debug.hpp"
    33 // A BufferingOops closure tries to separate out the cost of finding roots
    34 // from the cost of applying closures to them.  It maintains an array of
    35 // ref-containing locations.  Until the array is full, applying the closure
    36 // to an oop* merely records that location in the array.  Since this
    37 // closure app cost is small, an elapsed timer can approximately attribute
    38 // all of this cost to the cost of finding the roots.  When the array fills
    39 // up, the wrapped closure is applied to all elements, keeping track of
    40 // this elapsed time of this process, and leaving the array empty.
    41 // The caller must be sure to call "done" to process any unprocessed
    42 // buffered entriess.
    44 class BufferingOopClosure: public OopClosure {
    45   friend class TestBufferingOopClosure;
    46 protected:
    47   static const size_t BufferLength = 1024;
    49   // We need to know if the buffered addresses contain oops or narrowOops.
    50   // We can't tag the addresses the way StarTask does, because we need to
    51   // be able to handle unaligned addresses coming from oops embedded in code.
    52   //
    53   // The addresses for the full-sized oops are filled in from the bottom,
    54   // while the addresses for the narrowOops are filled in from the top.
    55   OopOrNarrowOopStar  _buffer[BufferLength];
    56   OopOrNarrowOopStar* _oop_top;
    57   OopOrNarrowOopStar* _narrowOop_bottom;
    59   OopClosure* _oc;
    60   double      _closure_app_seconds;
    63   bool is_buffer_empty() {
    64     return _oop_top == _buffer && _narrowOop_bottom == (_buffer + BufferLength - 1);
    65   }
    67   bool is_buffer_full() {
    68     return _narrowOop_bottom < _oop_top;
    69   }
    71   // Process addresses containing full-sized oops.
    72   void process_oops() {
    73     for (OopOrNarrowOopStar* curr = _buffer; curr < _oop_top; ++curr) {
    74       _oc->do_oop((oop*)(*curr));
    75     }
    76     _oop_top = _buffer;
    77   }
    79   // Process addresses containing narrow oops.
    80   void process_narrowOops() {
    81     for (OopOrNarrowOopStar* curr = _buffer + BufferLength - 1; curr > _narrowOop_bottom; --curr) {
    82       _oc->do_oop((narrowOop*)(*curr));
    83     }
    84     _narrowOop_bottom = _buffer + BufferLength - 1;
    85   }
    87   // Apply the closure to all oops and clear the buffer.
    88   // Accumulate the time it took.
    89   void process_buffer() {
    90     double start = os::elapsedTime();
    92     process_oops();
    93     process_narrowOops();
    95     _closure_app_seconds += (os::elapsedTime() - start);
    96   }
    98   void process_buffer_if_full() {
    99     if (is_buffer_full()) {
   100       process_buffer();
   101     }
   102   }
   104   void add_narrowOop(narrowOop* p) {
   105     assert(!is_buffer_full(), "Buffer should not be full");
   106     *_narrowOop_bottom = (OopOrNarrowOopStar)p;
   107     _narrowOop_bottom--;
   108   }
   110   void add_oop(oop* p) {
   111     assert(!is_buffer_full(), "Buffer should not be full");
   112     *_oop_top = (OopOrNarrowOopStar)p;
   113     _oop_top++;
   114   }
   116 public:
   117   virtual void do_oop(narrowOop* p) {
   118     process_buffer_if_full();
   119     add_narrowOop(p);
   120   }
   122   virtual void do_oop(oop* p)       {
   123     process_buffer_if_full();
   124     add_oop(p);
   125   }
   127   void done() {
   128     if (!is_buffer_empty()) {
   129       process_buffer();
   130     }
   131   }
   133   double closure_app_seconds() {
   134     return _closure_app_seconds;
   135   }
   137   BufferingOopClosure(OopClosure *oc) :
   138     _oc(oc),
   139     _oop_top(_buffer),
   140     _narrowOop_bottom(_buffer + BufferLength - 1),
   141     _closure_app_seconds(0.0) { }
   142 };
   144 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP

mercurial