1 /*
2 * Copyright (c) 2009, 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_UTILITIES_STACK_INLINE_HPP
26 #define SHARE_VM_UTILITIES_STACK_INLINE_HPP
27
28 #include "utilities/stack.hpp"
29
30 // Stack is used by the GC code and in some hot paths a lot of the Stack
31 // code gets inlined. This is generally good, but when too much code has
32 // been inlined, no further inlining is allowed by GCC. Therefore we need
33 // to prevent parts of the slow path in Stack to be inlined to allow other
34 // code to be.
35 #if defined(TARGET_COMPILER_gcc)
36 #define NOINLINE __attribute__((noinline))
37 #else
38 #define NOINLINE
39 #endif
40
41 template <MEMFLAGS F> StackBase<F>::StackBase(size_t segment_size, size_t max_cache_size,
42 size_t max_size):
43 _seg_size(segment_size),
44 _max_cache_size(max_cache_size),
45 _max_size(adjust_max_size(max_size, segment_size))
46 {
47 assert(_max_size % _seg_size == 0, "not a multiple");
48 }
49
50 template <MEMFLAGS F> size_t StackBase<F>::adjust_max_size(size_t max_size, size_t seg_size)
51 {
52 assert(seg_size > 0, "cannot be 0");
53 assert(max_size >= seg_size || max_size == 0, "max_size too small");
54 const size_t limit = max_uintx - (seg_size - 1);
55 if (max_size == 0 || max_size > limit) {
56 max_size = limit;
57 }
58 return (max_size + seg_size - 1) / seg_size * seg_size;
59 }
60
134
135 template <class E, MEMFLAGS F>
136 E* Stack<E, F>::set_link(E* new_seg, E* old_seg)
137 {
138 *link_addr(new_seg) = old_seg;
139 return new_seg;
140 }
141
142 template <class E, MEMFLAGS F>
143 E* Stack<E, F>::alloc(size_t bytes)
144 {
145 return (E*) NEW_C_HEAP_ARRAY(char, bytes, F);
146 }
147
148 template <class E, MEMFLAGS F>
149 void Stack<E, F>::free(E* addr, size_t bytes)
150 {
151 FREE_C_HEAP_ARRAY(char, (char*) addr);
152 }
153
154 template <class E, MEMFLAGS F>
155 NOINLINE void Stack<E, F>::push_segment()
156 {
157 assert(this->_cur_seg_size == this->_seg_size, "current segment is not full");
158 E* next;
159 if (this->_cache_size > 0) {
160 // Use a cached segment.
161 next = _cache;
162 _cache = get_link(_cache);
163 --this->_cache_size;
164 } else {
165 next = alloc(segment_bytes());
166 DEBUG_ONLY(zap_segment(next, true);)
167 }
168 const bool at_empty_transition = is_empty();
169 this->_cur_seg = set_link(next, _cur_seg);
170 this->_cur_seg_size = 0;
171 this->_full_seg_size += at_empty_transition ? 0 : this->_seg_size;
172 DEBUG_ONLY(verify(at_empty_transition);)
173 }
262 void StackIterator<E, F>::sync()
263 {
264 _full_seg_size = _stack._full_seg_size;
265 _cur_seg_size = _stack._cur_seg_size;
266 _cur_seg = _stack._cur_seg;
267 }
268
269 template <class E, MEMFLAGS F>
270 E* StackIterator<E, F>::next_addr()
271 {
272 assert(!is_empty(), "no items left");
273 if (_cur_seg_size == 1) {
274 E* addr = _cur_seg;
275 _cur_seg = _stack.get_link(_cur_seg);
276 _cur_seg_size = _stack.segment_size();
277 _full_seg_size -= _stack.segment_size();
278 return addr;
279 }
280 return _cur_seg + --_cur_seg_size;
281 }
282
283 #undef NOINLINE
284
285 #endif // SHARE_VM_UTILITIES_STACK_INLINE_HPP
|
1 /*
2 * Copyright (c) 2009, 2016, 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_UTILITIES_STACK_INLINE_HPP
26 #define SHARE_VM_UTILITIES_STACK_INLINE_HPP
27
28 #include "utilities/stack.hpp"
29
30 template <MEMFLAGS F> StackBase<F>::StackBase(size_t segment_size, size_t max_cache_size,
31 size_t max_size):
32 _seg_size(segment_size),
33 _max_cache_size(max_cache_size),
34 _max_size(adjust_max_size(max_size, segment_size))
35 {
36 assert(_max_size % _seg_size == 0, "not a multiple");
37 }
38
39 template <MEMFLAGS F> size_t StackBase<F>::adjust_max_size(size_t max_size, size_t seg_size)
40 {
41 assert(seg_size > 0, "cannot be 0");
42 assert(max_size >= seg_size || max_size == 0, "max_size too small");
43 const size_t limit = max_uintx - (seg_size - 1);
44 if (max_size == 0 || max_size > limit) {
45 max_size = limit;
46 }
47 return (max_size + seg_size - 1) / seg_size * seg_size;
48 }
49
123
124 template <class E, MEMFLAGS F>
125 E* Stack<E, F>::set_link(E* new_seg, E* old_seg)
126 {
127 *link_addr(new_seg) = old_seg;
128 return new_seg;
129 }
130
131 template <class E, MEMFLAGS F>
132 E* Stack<E, F>::alloc(size_t bytes)
133 {
134 return (E*) NEW_C_HEAP_ARRAY(char, bytes, F);
135 }
136
137 template <class E, MEMFLAGS F>
138 void Stack<E, F>::free(E* addr, size_t bytes)
139 {
140 FREE_C_HEAP_ARRAY(char, (char*) addr);
141 }
142
143 // Stack is used by the GC code and in some hot paths a lot of the Stack
144 // code gets inlined. This is generally good, but when too much code has
145 // been inlined, no further inlining is allowed by GCC. Therefore we need
146 // to prevent parts of the slow path in Stack to be inlined to allow other
147 // code to be.
148 template <class E, MEMFLAGS F>
149 NOINLINE void Stack<E, F>::push_segment()
150 {
151 assert(this->_cur_seg_size == this->_seg_size, "current segment is not full");
152 E* next;
153 if (this->_cache_size > 0) {
154 // Use a cached segment.
155 next = _cache;
156 _cache = get_link(_cache);
157 --this->_cache_size;
158 } else {
159 next = alloc(segment_bytes());
160 DEBUG_ONLY(zap_segment(next, true);)
161 }
162 const bool at_empty_transition = is_empty();
163 this->_cur_seg = set_link(next, _cur_seg);
164 this->_cur_seg_size = 0;
165 this->_full_seg_size += at_empty_transition ? 0 : this->_seg_size;
166 DEBUG_ONLY(verify(at_empty_transition);)
167 }
256 void StackIterator<E, F>::sync()
257 {
258 _full_seg_size = _stack._full_seg_size;
259 _cur_seg_size = _stack._cur_seg_size;
260 _cur_seg = _stack._cur_seg;
261 }
262
263 template <class E, MEMFLAGS F>
264 E* StackIterator<E, F>::next_addr()
265 {
266 assert(!is_empty(), "no items left");
267 if (_cur_seg_size == 1) {
268 E* addr = _cur_seg;
269 _cur_seg = _stack.get_link(_cur_seg);
270 _cur_seg_size = _stack.segment_size();
271 _full_seg_size -= _stack.segment_size();
272 return addr;
273 }
274 return _cur_seg + --_cur_seg_size;
275 }
276
277 #endif // SHARE_VM_UTILITIES_STACK_INLINE_HPP
|