< prev index next >

src/share/vm/utilities/stack.inline.hpp

Print this page
rev 10456 : 8151593: Cleanup definition/usage of INLINE/NOINLINE macros and add xlC support
Contributed-by: matthias.baesken@sap.com
   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
< prev index next >