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

changeset 6969
02e61cf08ab3
parent 6231
889068b9a088
child 7535
7ae4e26cb1e0
     1.1 --- a/src/share/vm/gc_implementation/g1/bufferingOopClosure.hpp	Tue Jan 14 16:40:33 2014 +0100
     1.2 +++ b/src/share/vm/gc_implementation/g1/bufferingOopClosure.hpp	Mon Feb 10 12:51:51 2014 +0100
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -25,10 +25,10 @@
    1.11  #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
    1.12  #define SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
    1.13  
    1.14 -#include "memory/genOopClosures.hpp"
    1.15 -#include "memory/generation.hpp"
    1.16 +#include "memory/iterator.hpp"
    1.17 +#include "oops/oopsHierarchy.hpp"
    1.18  #include "runtime/os.hpp"
    1.19 -#include "utilities/taskqueue.hpp"
    1.20 +#include "utilities/debug.hpp"
    1.21  
    1.22  // A BufferingOops closure tries to separate out the cost of finding roots
    1.23  // from the cost of applying closures to them.  It maintains an array of
    1.24 @@ -41,60 +41,103 @@
    1.25  // The caller must be sure to call "done" to process any unprocessed
    1.26  // buffered entriess.
    1.27  
    1.28 -class Generation;
    1.29 -class HeapRegion;
    1.30 +class BufferingOopClosure: public OopClosure {
    1.31 +  friend class TestBufferingOopClosure;
    1.32 +protected:
    1.33 +  static const size_t BufferLength = 1024;
    1.34  
    1.35 -class BufferingOopClosure: public OopClosure {
    1.36 -protected:
    1.37 -  enum PrivateConstants {
    1.38 -    BufferLength = 1024
    1.39 -  };
    1.40 -
    1.41 -  StarTask  _buffer[BufferLength];
    1.42 -  StarTask* _buffer_top;
    1.43 -  StarTask* _buffer_curr;
    1.44 +  // We need to know if the buffered addresses contain oops or narrowOops.
    1.45 +  // We can't tag the addresses the way StarTask does, because we need to
    1.46 +  // be able to handle unaligned addresses coming from oops embedded in code.
    1.47 +  //
    1.48 +  // The addresses for the full-sized oops are filled in from the bottom,
    1.49 +  // while the addresses for the narrowOops are filled in from the top.
    1.50 +  OopOrNarrowOopStar  _buffer[BufferLength];
    1.51 +  OopOrNarrowOopStar* _oop_top;
    1.52 +  OopOrNarrowOopStar* _narrowOop_bottom;
    1.53  
    1.54    OopClosure* _oc;
    1.55    double      _closure_app_seconds;
    1.56  
    1.57 -  void process_buffer () {
    1.58 +
    1.59 +  bool is_buffer_empty() {
    1.60 +    return _oop_top == _buffer && _narrowOop_bottom == (_buffer + BufferLength - 1);
    1.61 +  }
    1.62 +
    1.63 +  bool is_buffer_full() {
    1.64 +    return _narrowOop_bottom < _oop_top;
    1.65 +  }
    1.66 +
    1.67 +  // Process addresses containing full-sized oops.
    1.68 +  void process_oops() {
    1.69 +    for (OopOrNarrowOopStar* curr = _buffer; curr < _oop_top; ++curr) {
    1.70 +      _oc->do_oop((oop*)(*curr));
    1.71 +    }
    1.72 +    _oop_top = _buffer;
    1.73 +  }
    1.74 +
    1.75 +  // Process addresses containing narrow oops.
    1.76 +  void process_narrowOops() {
    1.77 +    for (OopOrNarrowOopStar* curr = _buffer + BufferLength - 1; curr > _narrowOop_bottom; --curr) {
    1.78 +      _oc->do_oop((narrowOop*)(*curr));
    1.79 +    }
    1.80 +    _narrowOop_bottom = _buffer + BufferLength - 1;
    1.81 +  }
    1.82 +
    1.83 +  // Apply the closure to all oops and clear the buffer.
    1.84 +  // Accumulate the time it took.
    1.85 +  void process_buffer() {
    1.86      double start = os::elapsedTime();
    1.87 -    for (StarTask* curr = _buffer; curr < _buffer_curr; ++curr) {
    1.88 -      if (curr->is_narrow()) {
    1.89 -        assert(UseCompressedOops, "Error");
    1.90 -        _oc->do_oop((narrowOop*)(*curr));
    1.91 -      } else {
    1.92 -        _oc->do_oop((oop*)(*curr));
    1.93 -      }
    1.94 -    }
    1.95 -    _buffer_curr = _buffer;
    1.96 +
    1.97 +    process_oops();
    1.98 +    process_narrowOops();
    1.99 +
   1.100      _closure_app_seconds += (os::elapsedTime() - start);
   1.101    }
   1.102  
   1.103 -  template <class T> inline void do_oop_work(T* p) {
   1.104 -    if (_buffer_curr == _buffer_top) {
   1.105 +  void process_buffer_if_full() {
   1.106 +    if (is_buffer_full()) {
   1.107        process_buffer();
   1.108      }
   1.109 -    StarTask new_ref(p);
   1.110 -    *_buffer_curr = new_ref;
   1.111 -    ++_buffer_curr;
   1.112 +  }
   1.113 +
   1.114 +  void add_narrowOop(narrowOop* p) {
   1.115 +    assert(!is_buffer_full(), "Buffer should not be full");
   1.116 +    *_narrowOop_bottom = (OopOrNarrowOopStar)p;
   1.117 +    _narrowOop_bottom--;
   1.118 +  }
   1.119 +
   1.120 +  void add_oop(oop* p) {
   1.121 +    assert(!is_buffer_full(), "Buffer should not be full");
   1.122 +    *_oop_top = (OopOrNarrowOopStar)p;
   1.123 +    _oop_top++;
   1.124    }
   1.125  
   1.126  public:
   1.127 -  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
   1.128 -  virtual void do_oop(oop* p)       { do_oop_work(p); }
   1.129 +  virtual void do_oop(narrowOop* p) {
   1.130 +    process_buffer_if_full();
   1.131 +    add_narrowOop(p);
   1.132 +  }
   1.133  
   1.134 -  void done () {
   1.135 -    if (_buffer_curr > _buffer) {
   1.136 +  virtual void do_oop(oop* p)       {
   1.137 +    process_buffer_if_full();
   1.138 +    add_oop(p);
   1.139 +  }
   1.140 +
   1.141 +  void done() {
   1.142 +    if (!is_buffer_empty()) {
   1.143        process_buffer();
   1.144      }
   1.145    }
   1.146 -  double closure_app_seconds () {
   1.147 +
   1.148 +  double closure_app_seconds() {
   1.149      return _closure_app_seconds;
   1.150    }
   1.151 -  BufferingOopClosure (OopClosure *oc) :
   1.152 +
   1.153 +  BufferingOopClosure(OopClosure *oc) :
   1.154      _oc(oc),
   1.155 -    _buffer_curr(_buffer), _buffer_top(_buffer + BufferLength),
   1.156 +    _oop_top(_buffer),
   1.157 +    _narrowOop_bottom(_buffer + BufferLength - 1),
   1.158      _closure_app_seconds(0.0) { }
   1.159  };
   1.160  

mercurial