hotspot/src/share/vm/services/memPtrArray.hpp
changeset 25961 983a1ebcc848
parent 25939 41d12a329ec7
parent 25960 729cd80956ae
child 25962 8f95d0407e21
child 26141 9f502e461cde
child 26161 f75b959a3b46
child 26175 d8a4e0741439
equal deleted inserted replaced
25939:41d12a329ec7 25961:983a1ebcc848
     1 /*
       
     2  * Copyright (c) 2012, 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 #ifndef SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP
       
    25 #define SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP
       
    26 
       
    27 #include "memory/allocation.hpp"
       
    28 #include "services/memPtr.hpp"
       
    29 
       
    30 class MemPtr;
       
    31 class MemRecorder;
       
    32 class ArenaInfo;
       
    33 class MemSnapshot;
       
    34 
       
    35 extern "C" {
       
    36   typedef int (*FN_SORT)(const void *, const void *);
       
    37 }
       
    38 
       
    39 
       
    40 // Memory pointer array interface. This array is used by NMT to hold
       
    41 // various memory block information.
       
    42 // The memory pointer arrays are usually walked with their iterators.
       
    43 
       
    44 class MemPointerArray : public CHeapObj<mtNMT> {
       
    45  public:
       
    46   virtual ~MemPointerArray() { }
       
    47 
       
    48   // return true if it can not allocate storage for the data
       
    49   virtual bool out_of_memory() const = 0;
       
    50   virtual bool is_empty() const = 0;
       
    51   virtual bool is_full() = 0;
       
    52   virtual int  length() const = 0;
       
    53   virtual void clear() = 0;
       
    54   virtual bool append(MemPointer* ptr) = 0;
       
    55   virtual bool insert_at(MemPointer* ptr, int pos) = 0;
       
    56   virtual bool remove_at(int pos) = 0;
       
    57   virtual MemPointer* at(int index) const = 0;
       
    58   virtual void sort(FN_SORT fn) = 0;
       
    59   virtual size_t instance_size() const = 0;
       
    60   virtual bool shrink() = 0;
       
    61 
       
    62   NOT_PRODUCT(virtual int capacity() const = 0;)
       
    63 };
       
    64 
       
    65 // Iterator interface
       
    66 class MemPointerArrayIterator VALUE_OBJ_CLASS_SPEC {
       
    67  public:
       
    68   // return the pointer at current position
       
    69   virtual MemPointer* current() const = 0;
       
    70   // return the next pointer and advance current position
       
    71   virtual MemPointer* next() = 0;
       
    72   // return next pointer without advancing current position
       
    73   virtual MemPointer* peek_next() const = 0;
       
    74   // return previous pointer without changing current position
       
    75   virtual MemPointer* peek_prev() const = 0;
       
    76   // remove the pointer at current position
       
    77   virtual void        remove() = 0;
       
    78   // insert the pointer at current position
       
    79   virtual bool        insert(MemPointer* ptr) = 0;
       
    80   // insert specified element after current position and
       
    81   // move current position to newly inserted position
       
    82   virtual bool        insert_after(MemPointer* ptr) = 0;
       
    83 };
       
    84 
       
    85 // implementation class
       
    86 class MemPointerArrayIteratorImpl : public MemPointerArrayIterator {
       
    87  protected:
       
    88   MemPointerArray*  _array;
       
    89   int               _pos;
       
    90 
       
    91  public:
       
    92   MemPointerArrayIteratorImpl(MemPointerArray* arr) {
       
    93     assert(arr != NULL, "Parameter check");
       
    94     _array = arr;
       
    95     _pos = 0;
       
    96   }
       
    97 
       
    98   virtual MemPointer* current() const {
       
    99     if (_pos < _array->length()) {
       
   100       return _array->at(_pos);
       
   101     }
       
   102     return NULL;
       
   103   }
       
   104 
       
   105   virtual MemPointer* next() {
       
   106     if (_pos + 1 < _array->length()) {
       
   107       return _array->at(++_pos);
       
   108     }
       
   109     _pos = _array->length();
       
   110     return NULL;
       
   111   }
       
   112 
       
   113   virtual MemPointer* peek_next() const {
       
   114     if (_pos + 1 < _array->length()) {
       
   115       return _array->at(_pos + 1);
       
   116     }
       
   117     return NULL;
       
   118   }
       
   119 
       
   120   virtual MemPointer* peek_prev() const {
       
   121     if (_pos > 0) {
       
   122       return _array->at(_pos - 1);
       
   123     }
       
   124     return NULL;
       
   125   }
       
   126 
       
   127   virtual void remove() {
       
   128     if (_pos < _array->length()) {
       
   129       _array->remove_at(_pos);
       
   130     }
       
   131   }
       
   132 
       
   133   virtual bool insert(MemPointer* ptr) {
       
   134     return _array->insert_at(ptr, _pos);
       
   135   }
       
   136 
       
   137   virtual bool insert_after(MemPointer* ptr) {
       
   138     if (_array->insert_at(ptr, _pos + 1)) {
       
   139       _pos ++;
       
   140       return true;
       
   141     }
       
   142     return false;
       
   143   }
       
   144 };
       
   145 
       
   146 
       
   147 
       
   148 // Memory pointer array implementation.
       
   149 // This implementation implements expandable array
       
   150 #define DEFAULT_PTR_ARRAY_SIZE 1024
       
   151 
       
   152 template <class E> class MemPointerArrayImpl : public MemPointerArray {
       
   153  private:
       
   154   int                   _max_size;
       
   155   int                   _size;
       
   156   bool                  _init_elements;
       
   157   E*                    _data;
       
   158 
       
   159  public:
       
   160   MemPointerArrayImpl(int initial_size = DEFAULT_PTR_ARRAY_SIZE, bool init_elements = true):
       
   161    _max_size(initial_size), _size(0), _init_elements(init_elements) {
       
   162     _data = (E*)raw_allocate(sizeof(E), initial_size);
       
   163     if (_init_elements) {
       
   164       for (int index = 0; index < _max_size; index ++) {
       
   165         ::new ((void*)&_data[index]) E();
       
   166       }
       
   167     }
       
   168   }
       
   169 
       
   170   virtual ~MemPointerArrayImpl() {
       
   171     if (_data != NULL) {
       
   172       raw_free(_data);
       
   173     }
       
   174   }
       
   175 
       
   176  public:
       
   177   bool out_of_memory() const {
       
   178     return (_data == NULL);
       
   179   }
       
   180 
       
   181   size_t instance_size() const {
       
   182     return sizeof(MemPointerArrayImpl<E>) + _max_size * sizeof(E);
       
   183   }
       
   184 
       
   185   bool is_empty() const {
       
   186     assert(_data != NULL, "Just check");
       
   187     return _size == 0;
       
   188   }
       
   189 
       
   190   bool is_full() {
       
   191     assert(_data != NULL, "Just check");
       
   192     if (_size < _max_size) {
       
   193       return false;
       
   194     } else {
       
   195       return !expand_array();
       
   196     }
       
   197   }
       
   198 
       
   199   int length() const {
       
   200     assert(_data != NULL, "Just check");
       
   201     return _size;
       
   202   }
       
   203 
       
   204   NOT_PRODUCT(int capacity() const { return _max_size; })
       
   205 
       
   206   void clear() {
       
   207     assert(_data != NULL, "Just check");
       
   208     _size = 0;
       
   209   }
       
   210 
       
   211   bool append(MemPointer* ptr) {
       
   212     assert(_data != NULL, "Just check");
       
   213     if (is_full()) {
       
   214       return false;
       
   215     }
       
   216     _data[_size ++] = *(E*)ptr;
       
   217     return true;
       
   218   }
       
   219 
       
   220   bool insert_at(MemPointer* ptr, int pos) {
       
   221     assert(_data != NULL, "Just check");
       
   222     if (is_full()) {
       
   223       return false;
       
   224     }
       
   225     for (int index = _size; index > pos; index --) {
       
   226       _data[index] = _data[index - 1];
       
   227     }
       
   228     _data[pos] = *(E*)ptr;
       
   229     _size ++;
       
   230     return true;
       
   231   }
       
   232 
       
   233   bool remove_at(int pos) {
       
   234     assert(_data != NULL, "Just check");
       
   235     if (_size <= pos && pos >= 0) {
       
   236       return false;
       
   237     }
       
   238     -- _size;
       
   239 
       
   240     for (int index = pos; index < _size; index ++) {
       
   241       _data[index] = _data[index + 1];
       
   242     }
       
   243     return true;
       
   244   }
       
   245 
       
   246   MemPointer* at(int index) const {
       
   247     assert(_data != NULL, "Just check");
       
   248     assert(index >= 0 && index < _size, "illegal index");
       
   249     return &_data[index];
       
   250   }
       
   251 
       
   252   bool shrink() {
       
   253     float used = ((float)_size) / ((float)_max_size);
       
   254     if (used < 0.40) {
       
   255       E* old_ptr = _data;
       
   256       int new_size = ((_max_size) / (2 * DEFAULT_PTR_ARRAY_SIZE) + 1) * DEFAULT_PTR_ARRAY_SIZE;
       
   257       _data = (E*)raw_reallocate(_data, sizeof(E), new_size);
       
   258       if (_data == NULL) {
       
   259         _data = old_ptr;
       
   260         return false;
       
   261       } else {
       
   262         _max_size = new_size;
       
   263         return true;
       
   264       }
       
   265     }
       
   266     return false;
       
   267   }
       
   268 
       
   269   void sort(FN_SORT fn) {
       
   270     assert(_data != NULL, "Just check");
       
   271     qsort((void*)_data, _size, sizeof(E), fn);
       
   272   }
       
   273 
       
   274  private:
       
   275   bool  expand_array() {
       
   276     assert(_data != NULL, "Not yet allocated");
       
   277     E* old_ptr = _data;
       
   278     if ((_data = (E*)raw_reallocate((void*)_data, sizeof(E),
       
   279       _max_size + DEFAULT_PTR_ARRAY_SIZE)) == NULL) {
       
   280       _data = old_ptr;
       
   281       return false;
       
   282     } else {
       
   283       _max_size += DEFAULT_PTR_ARRAY_SIZE;
       
   284       if (_init_elements) {
       
   285         for (int index = _size; index < _max_size; index ++) {
       
   286           ::new ((void*)&_data[index]) E();
       
   287         }
       
   288       }
       
   289       return true;
       
   290     }
       
   291   }
       
   292 
       
   293   void* raw_allocate(size_t elementSize, int items) {
       
   294     return os::malloc(elementSize * items, mtNMT);
       
   295   }
       
   296 
       
   297   void* raw_reallocate(void* ptr, size_t elementSize, int items) {
       
   298     return os::realloc(ptr, elementSize * items, mtNMT);
       
   299   }
       
   300 
       
   301   void  raw_free(void* ptr) {
       
   302     os::free(ptr, mtNMT);
       
   303   }
       
   304 };
       
   305 
       
   306 #endif // SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP