Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/gc_implementation/g1/bufferingOopClosure.hpp
38920 views
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
*/
24
25
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
26
#define SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
27
28
#include "memory/iterator.hpp"
29
#include "oops/oopsHierarchy.hpp"
30
#include "runtime/os.hpp"
31
#include "utilities/debug.hpp"
32
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.
43
44
class BufferingOopClosure: public OopClosure {
45
friend class TestBufferingOopClosure;
46
protected:
47
static const size_t BufferLength = 1024;
48
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;
58
59
OopClosure* _oc;
60
double _closure_app_seconds;
61
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() {
90
double start = os::elapsedTime();
91
92
process_oops();
93
process_narrowOops();
94
95
_closure_app_seconds += (os::elapsedTime() - start);
96
}
97
98
void process_buffer_if_full() {
99
if (is_buffer_full()) {
100
process_buffer();
101
}
102
}
103
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++;
114
}
115
116
public:
117
virtual void do_oop(narrowOop* p) {
118
process_buffer_if_full();
119
add_narrowOop(p);
120
}
121
122
virtual void do_oop(oop* p) {
123
process_buffer_if_full();
124
add_oop(p);
125
}
126
127
void done() {
128
if (!is_buffer_empty()) {
129
process_buffer();
130
}
131
}
132
133
double closure_app_seconds() {
134
return _closure_app_seconds;
135
}
136
137
BufferingOopClosure(OopClosure *oc) :
138
_oc(oc),
139
_oop_top(_buffer),
140
_narrowOop_bottom(_buffer + BufferLength - 1),
141
_closure_app_seconds(0.0) { }
142
};
143
144
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_BUFFERINGOOPCLOSURE_HPP
145
146