hotspot/src/share/vm/utilities/stack.hpp
changeset 13195 be27e1b6a4b9
parent 7397 5b173b4ca846
child 13963 e5b53c306fb5
equal deleted inserted replaced
13099:64752e56d721 13195:be27e1b6a4b9
    23  */
    23  */
    24 
    24 
    25 #ifndef SHARE_VM_UTILITIES_STACK_HPP
    25 #ifndef SHARE_VM_UTILITIES_STACK_HPP
    26 #define SHARE_VM_UTILITIES_STACK_HPP
    26 #define SHARE_VM_UTILITIES_STACK_HPP
    27 
    27 
       
    28 #include "memory/allocation.hpp"
    28 #include "memory/allocation.inline.hpp"
    29 #include "memory/allocation.inline.hpp"
    29 
    30 
    30 // Class Stack (below) grows and shrinks by linking together "segments" which
    31 // Class Stack (below) grows and shrinks by linking together "segments" which
    31 // are allocated on demand.  Segments are arrays of the element type (E) plus an
    32 // are allocated on demand.  Segments are arrays of the element type (E) plus an
    32 // extra pointer-sized field to store the segment link.  Recently emptied
    33 // extra pointer-sized field to store the segment link.  Recently emptied
    49 //
    50 //
    50 // The alloc() method must return storage aligned for any use.  The
    51 // The alloc() method must return storage aligned for any use.  The
    51 // implementation in class Stack assumes that alloc() will terminate the process
    52 // implementation in class Stack assumes that alloc() will terminate the process
    52 // if the allocation fails.
    53 // if the allocation fails.
    53 
    54 
    54 template <class E> class StackIterator;
    55 template <class E, MEMFLAGS F> class StackIterator;
    55 
    56 
    56 // StackBase holds common data/methods that don't depend on the element type,
    57 // StackBase holds common data/methods that don't depend on the element type,
    57 // factored out to reduce template code duplication.
    58 // factored out to reduce template code duplication.
    58 class StackBase
    59 template <MEMFLAGS F> class StackBase
    59 {
    60 {
    60 public:
    61 public:
    61   size_t segment_size()   const { return _seg_size; } // Elements per segment.
    62   size_t segment_size()   const { return _seg_size; } // Elements per segment.
    62   size_t max_size()       const { return _max_size; } // Max elements allowed.
    63   size_t max_size()       const { return _max_size; } // Max elements allowed.
    63   size_t max_cache_size() const { return _max_cache_size; } // Max segments
    64   size_t max_cache_size() const { return _max_cache_size; } // Max segments
    87 
    88 
    88 #ifdef __GNUC__
    89 #ifdef __GNUC__
    89 #define inline
    90 #define inline
    90 #endif // __GNUC__
    91 #endif // __GNUC__
    91 
    92 
    92 template <class E>
    93 template <class E, MEMFLAGS F>
    93 class Stack:  public StackBase
    94 class Stack:  public StackBase<F>
    94 {
    95 {
    95 public:
    96 public:
    96   friend class StackIterator<E>;
    97   friend class StackIterator<E, F>;
    97 
    98 
    98   // segment_size:    number of items per segment
    99   // segment_size:    number of items per segment
    99   // max_cache_size:  maxmium number of *segments* to cache
   100   // max_cache_size:  maxmium number of *segments* to cache
   100   // max_size:        maximum number of items allowed, rounded to a multiple of
   101   // max_size:        maximum number of items allowed, rounded to a multiple of
   101   //                  the segment size (0 == unlimited)
   102   //                  the segment size (0 == unlimited)
   102   inline Stack(size_t segment_size = default_segment_size(),
   103   inline Stack(size_t segment_size = default_segment_size(),
   103                size_t max_cache_size = 4, size_t max_size = 0);
   104                size_t max_cache_size = 4, size_t max_size = 0);
   104   inline ~Stack() { clear(true); }
   105   inline ~Stack() { clear(true); }
   105 
   106 
   106   inline bool is_empty() const { return _cur_seg == NULL; }
   107   inline bool is_empty() const { return this->_cur_seg == NULL; }
   107   inline bool is_full()  const { return _full_seg_size >= max_size(); }
   108   inline bool is_full()  const { return this->_full_seg_size >= this->max_size(); }
   108 
   109 
   109   // Performance sensitive code should use is_empty() instead of size() == 0 and
   110   // Performance sensitive code should use is_empty() instead of size() == 0 and
   110   // is_full() instead of size() == max_size().  Using a conditional here allows
   111   // is_full() instead of size() == max_size().  Using a conditional here allows
   111   // just one var to be updated when pushing/popping elements instead of two;
   112   // just one var to be updated when pushing/popping elements instead of two;
   112   // _full_seg_size is updated only when pushing/popping segments.
   113   // _full_seg_size is updated only when pushing/popping segments.
   113   inline size_t size() const {
   114   inline size_t size() const {
   114     return is_empty() ? 0 : _full_seg_size + _cur_seg_size;
   115     return is_empty() ? 0 : this->_full_seg_size + this->_cur_seg_size;
   115   }
   116   }
   116 
   117 
   117   inline void push(E elem);
   118   inline void push(E elem);
   118   inline E    pop();
   119   inline E    pop();
   119 
   120 
   159 private:
   160 private:
   160   E* _cur_seg;    // Current segment.
   161   E* _cur_seg;    // Current segment.
   161   E* _cache;      // Segment cache to avoid ping-ponging.
   162   E* _cache;      // Segment cache to avoid ping-ponging.
   162 };
   163 };
   163 
   164 
   164 template <class E> class ResourceStack:  public Stack<E>, public ResourceObj
   165 template <class E, MEMFLAGS F> class ResourceStack:  public Stack<E, F>, public ResourceObj
   165 {
   166 {
   166 public:
   167 public:
   167   // If this class becomes widely used, it may make sense to save the Thread
   168   // If this class becomes widely used, it may make sense to save the Thread
   168   // and use it when allocating segments.
   169   // and use it when allocating segments.
   169   ResourceStack(size_t segment_size = Stack<E>::default_segment_size()):
   170 //  ResourceStack(size_t segment_size = Stack<E, F>::default_segment_size()):
   170     Stack<E>(segment_size, max_uintx)
   171   ResourceStack(size_t segment_size): Stack<E, F>(segment_size, max_uintx)
   171     { }
   172     { }
   172 
   173 
   173   // Set the segment pointers to NULL so the parent dtor does not free them;
   174   // Set the segment pointers to NULL so the parent dtor does not free them;
   174   // that must be done by the ResourceMark code.
   175   // that must be done by the ResourceMark code.
   175   ~ResourceStack() { Stack<E>::reset(true); }
   176   ~ResourceStack() { Stack<E, F>::reset(true); }
   176 
   177 
   177 protected:
   178 protected:
   178   virtual E*   alloc(size_t bytes);
   179   virtual E*   alloc(size_t bytes);
   179   virtual void free(E* addr, size_t bytes);
   180   virtual void free(E* addr, size_t bytes);
   180 
   181 
   181 private:
   182 private:
   182   void clear(bool clear_cache = false);
   183   void clear(bool clear_cache = false);
   183 };
   184 };
   184 
   185 
   185 template <class E>
   186 template <class E, MEMFLAGS F>
   186 class StackIterator: public StackObj
   187 class StackIterator: public StackObj
   187 {
   188 {
   188 public:
   189 public:
   189   StackIterator(Stack<E>& stack): _stack(stack) { sync(); }
   190   StackIterator(Stack<E, F>& stack): _stack(stack) { sync(); }
   190 
   191 
   191   Stack<E>& stack() const { return _stack; }
   192   Stack<E, F>& stack() const { return _stack; }
   192 
   193 
   193   bool is_empty() const { return _cur_seg == NULL; }
   194   bool is_empty() const { return _cur_seg == NULL; }
   194 
   195 
   195   E  next() { return *next_addr(); }
   196   E  next() { return *next_addr(); }
   196   E* next_addr();
   197   E* next_addr();
   197 
   198 
   198   void sync(); // Sync the iterator's state to the stack's current state.
   199   void sync(); // Sync the iterator's state to the stack's current state.
   199 
   200 
   200 private:
   201 private:
   201   Stack<E>& _stack;
   202   Stack<E, F>& _stack;
   202   size_t    _cur_seg_size;
   203   size_t    _cur_seg_size;
   203   E*        _cur_seg;
   204   E*        _cur_seg;
   204   size_t    _full_seg_size;
   205   size_t    _full_seg_size;
   205 };
   206 };
   206 
   207