src/share/vm/services/memPtrArray.hpp

Tue, 08 Aug 2017 15:57:29 +0800

author
aoqi
date
Tue, 08 Aug 2017 15:57:29 +0800
changeset 6876
710a3c8b516e
parent 4053
33143ee07800
parent 0
f90c822e73f8
permissions
-rw-r--r--

merge

     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
    27 #include "memory/allocation.hpp"
    28 #include "services/memPtr.hpp"
    30 class MemPtr;
    31 class MemRecorder;
    32 class ArenaInfo;
    33 class MemSnapshot;
    35 extern "C" {
    36   typedef int (*FN_SORT)(const void *, const void *);
    37 }
    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.
    44 class MemPointerArray : public CHeapObj<mtNMT> {
    45  public:
    46   virtual ~MemPointerArray() { }
    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;
    62   NOT_PRODUCT(virtual int capacity() const = 0;)
    63 };
    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 };
    85 // implementation class
    86 class MemPointerArrayIteratorImpl : public MemPointerArrayIterator {
    87  protected:
    88   MemPointerArray*  _array;
    89   int               _pos;
    91  public:
    92   MemPointerArrayIteratorImpl(MemPointerArray* arr) {
    93     assert(arr != NULL, "Parameter check");
    94     _array = arr;
    95     _pos = 0;
    96   }
    98   virtual MemPointer* current() const {
    99     if (_pos < _array->length()) {
   100       return _array->at(_pos);
   101     }
   102     return NULL;
   103   }
   105   virtual MemPointer* next() {
   106     if (_pos + 1 < _array->length()) {
   107       return _array->at(++_pos);
   108     }
   109     _pos = _array->length();
   110     return NULL;
   111   }
   113   virtual MemPointer* peek_next() const {
   114     if (_pos + 1 < _array->length()) {
   115       return _array->at(_pos + 1);
   116     }
   117     return NULL;
   118   }
   120   virtual MemPointer* peek_prev() const {
   121     if (_pos > 0) {
   122       return _array->at(_pos - 1);
   123     }
   124     return NULL;
   125   }
   127   virtual void remove() {
   128     if (_pos < _array->length()) {
   129       _array->remove_at(_pos);
   130     }
   131   }
   133   virtual bool insert(MemPointer* ptr) {
   134     return _array->insert_at(ptr, _pos);
   135   }
   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 };
   148 // Memory pointer array implementation.
   149 // This implementation implements expandable array
   150 #define DEFAULT_PTR_ARRAY_SIZE 1024
   152 template <class E> class MemPointerArrayImpl : public MemPointerArray {
   153  private:
   154   int                   _max_size;
   155   int                   _size;
   156   bool                  _init_elements;
   157   E*                    _data;
   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   }
   170   virtual ~MemPointerArrayImpl() {
   171     if (_data != NULL) {
   172       raw_free(_data);
   173     }
   174   }
   176  public:
   177   bool out_of_memory() const {
   178     return (_data == NULL);
   179   }
   181   size_t instance_size() const {
   182     return sizeof(MemPointerArrayImpl<E>) + _max_size * sizeof(E);
   183   }
   185   bool is_empty() const {
   186     assert(_data != NULL, "Just check");
   187     return _size == 0;
   188   }
   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   }
   199   int length() const {
   200     assert(_data != NULL, "Just check");
   201     return _size;
   202   }
   204   NOT_PRODUCT(int capacity() const { return _max_size; })
   206   void clear() {
   207     assert(_data != NULL, "Just check");
   208     _size = 0;
   209   }
   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   }
   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   }
   233   bool remove_at(int pos) {
   234     assert(_data != NULL, "Just check");
   235     if (_size <= pos && pos >= 0) {
   236       return false;
   237     }
   238     -- _size;
   240     for (int index = pos; index < _size; index ++) {
   241       _data[index] = _data[index + 1];
   242     }
   243     return true;
   244   }
   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   }
   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   }
   269   void sort(FN_SORT fn) {
   270     assert(_data != NULL, "Just check");
   271     qsort((void*)_data, _size, sizeof(E), fn);
   272   }
   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   }
   293   void* raw_allocate(size_t elementSize, int items) {
   294     return os::malloc(elementSize * items, mtNMT);
   295   }
   297   void* raw_reallocate(void* ptr, size_t elementSize, int items) {
   298     return os::realloc(ptr, elementSize * items, mtNMT);
   299   }
   301   void  raw_free(void* ptr) {
   302     os::free(ptr, mtNMT);
   303   }
   304 };
   306 #endif // SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP

mercurial