Mercurial > hg > truffle
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 |