comparison src/share/vm/gc_implementation/g1/bufferingOopClosure.hpp @ 20804:7848fc12602b

Merge with jdk8u40-b25
author Gilles Duboscq <gilles.m.duboscq@oracle.com>
date Tue, 07 Apr 2015 14:58:49 +0200
parents 52b4284cb496 02e61cf08ab3
children
comparison
equal deleted inserted replaced
20184:84105dcdb05b 20804:7848fc12602b
1 /* 1 /*
2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 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. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
23 */ 23 */
24 24
25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
26 #define SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP 26 #define SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
27 27
28 #include "memory/genOopClosures.hpp" 28 #include "memory/iterator.hpp"
29 #include "memory/generation.hpp" 29 #include "oops/oopsHierarchy.hpp"
30 #include "runtime/os.hpp" 30 #include "runtime/os.hpp"
31 #include "utilities/taskqueue.hpp" 31 #include "utilities/debug.hpp"
32 32
33 // A BufferingOops closure tries to separate out the cost of finding roots 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 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 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 36 // to an oop* merely records that location in the array. Since this
39 // up, the wrapped closure is applied to all elements, keeping track of 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. 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 41 // The caller must be sure to call "done" to process any unprocessed
42 // buffered entriess. 42 // buffered entriess.
43 43
44 class Generation; 44 class BufferingOopClosure: public OopClosure {
45 class HeapRegion; 45 friend class TestBufferingOopClosure;
46 protected:
47 static const size_t BufferLength = 1024;
46 48
47 class BufferingOopClosure: public OopClosure { 49 // We need to know if the buffered addresses contain oops or narrowOops.
48 protected: 50 // We can't tag the addresses the way StarTask does, because we need to
49 enum PrivateConstants { 51 // be able to handle unaligned addresses coming from oops embedded in code.
50 BufferLength = 1024 52 //
51 }; 53 // The addresses for the full-sized oops are filled in from the bottom,
52 54 // while the addresses for the narrowOops are filled in from the top.
53 StarTask _buffer[BufferLength]; 55 OopOrNarrowOopStar _buffer[BufferLength];
54 StarTask* _buffer_top; 56 OopOrNarrowOopStar* _oop_top;
55 StarTask* _buffer_curr; 57 OopOrNarrowOopStar* _narrowOop_bottom;
56 58
57 OopClosure* _oc; 59 OopClosure* _oc;
58 double _closure_app_seconds; 60 double _closure_app_seconds;
59 61
60 void process_buffer () { 62
63 bool is_buffer_empty() {
64 return _oop_top == _buffer && _narrowOop_bottom == (_buffer + BufferLength - 1);
65 }
66
67 bool is_buffer_full() {
68 return _narrowOop_bottom < _oop_top;
69 }
70
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 }
78
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 }
86
87 // Apply the closure to all oops and clear the buffer.
88 // Accumulate the time it took.
89 void process_buffer() {
61 double start = os::elapsedTime(); 90 double start = os::elapsedTime();
62 for (StarTask* curr = _buffer; curr < _buffer_curr; ++curr) { 91
63 if (curr->is_narrow()) { 92 process_oops();
64 assert(UseCompressedOops, "Error"); 93 process_narrowOops();
65 _oc->do_oop((narrowOop*)(*curr)); 94
66 } else {
67 _oc->do_oop((oop*)(*curr));
68 }
69 }
70 _buffer_curr = _buffer;
71 _closure_app_seconds += (os::elapsedTime() - start); 95 _closure_app_seconds += (os::elapsedTime() - start);
72 } 96 }
73 97
74 template <class T> inline void do_oop_work(T* p) { 98 void process_buffer_if_full() {
75 if (_buffer_curr == _buffer_top) { 99 if (is_buffer_full()) {
76 process_buffer(); 100 process_buffer();
77 } 101 }
78 StarTask new_ref(p); 102 }
79 *_buffer_curr = new_ref; 103
80 ++_buffer_curr; 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 }
109
110 void add_oop(oop* p) {
111 assert(!is_buffer_full(), "Buffer should not be full");
112 *_oop_top = (OopOrNarrowOopStar)p;
113 _oop_top++;
81 } 114 }
82 115
83 public: 116 public:
84 virtual void do_oop(narrowOop* p) { do_oop_work(p); } 117 virtual void do_oop(narrowOop* p) {
85 virtual void do_oop(oop* p) { do_oop_work(p); } 118 process_buffer_if_full();
119 add_narrowOop(p);
120 }
86 121
87 void done () { 122 virtual void do_oop(oop* p) {
88 if (_buffer_curr > _buffer) { 123 process_buffer_if_full();
124 add_oop(p);
125 }
126
127 void done() {
128 if (!is_buffer_empty()) {
89 process_buffer(); 129 process_buffer();
90 } 130 }
91 } 131 }
92 double closure_app_seconds () { 132
133 double closure_app_seconds() {
93 return _closure_app_seconds; 134 return _closure_app_seconds;
94 } 135 }
95 BufferingOopClosure (OopClosure *oc) : 136
137 BufferingOopClosure(OopClosure *oc) :
96 _oc(oc), 138 _oc(oc),
97 _buffer_curr(_buffer), _buffer_top(_buffer + BufferLength), 139 _oop_top(_buffer),
140 _narrowOop_bottom(_buffer + BufferLength - 1),
98 _closure_app_seconds(0.0) { } 141 _closure_app_seconds(0.0) { }
99 }; 142 };
100 143
101 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP 144 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP