src/share/vm/services/memRecorder.hpp

Tue, 08 Jan 2013 14:04:25 -0500

author
zgu
date
Tue, 08 Jan 2013 14:04:25 -0500
changeset 4400
ecd24264898b
parent 4193
716c64bda5ba
child 4512
4102b59539ce
permissions
-rw-r--r--

8005048: NMT: #loaded classes needs to just show the # defined classes
Summary: Count number of instance classes so that it matches class metadata size
Reviewed-by: coleenp, acorn

     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  */
    25 #ifndef SHARE_VM_SERVICES_MEM_RECORDER_HPP
    26 #define SHARE_VM_SERVICES_MEM_RECORDER_HPP
    28 #include "memory/allocation.hpp"
    29 #include "runtime/os.hpp"
    30 #include "services/memPtrArray.hpp"
    32 class MemSnapshot;
    33 class MemTracker;
    34 class MemTrackWorker;
    36 // Fixed size memory pointer array implementation
    37 template <class E, int SIZE> class FixedSizeMemPointerArray :
    38   public MemPointerArray {
    39   // This implementation is for memory recorder only
    40   friend class MemRecorder;
    42  private:
    43   E      _data[SIZE];
    44   int    _size;
    46  protected:
    47   FixedSizeMemPointerArray(bool init_elements = false):
    48    _size(0){
    49     if (init_elements) {
    50       for (int index = 0; index < SIZE; index ++) {
    51         ::new ((void*)&_data[index]) E();
    52       }
    53     }
    54   }
    56   void* operator new(size_t size, const std::nothrow_t& nothrow_constant) {
    57     // the instance is part of memRecorder, needs to be tagged with 'otNMTRecorder'
    58     // to avoid recursion
    59     return os::malloc(size, (mtNMT | otNMTRecorder));
    60   }
    62   void* operator new(size_t size) {
    63     assert(false, "use nothrow version");
    64     return NULL;
    65   }
    67   void operator delete(void* p) {
    68     os::free(p, (mtNMT | otNMTRecorder));
    69   }
    71   // instance size
    72   inline size_t instance_size() const {
    73     return sizeof(FixedSizeMemPointerArray<E, SIZE>);
    74   }
    76   NOT_PRODUCT(int capacity() const { return SIZE; })
    78  public:
    79   // implementation of public interface
    80   bool out_of_memory() const { return false; }
    81   bool is_empty()      const { return _size == 0; }
    82   bool is_full()             { return length() >= SIZE; }
    83   int  length()        const { return _size; }
    85   void clear() {
    86     _size = 0;
    87   }
    89   bool append(MemPointer* ptr) {
    90     if (is_full()) return false;
    91     _data[_size ++] = *(E*)ptr;
    92     return true;
    93   }
    95   virtual bool insert_at(MemPointer* p, int pos) {
    96     assert(false, "append only");
    97     return false;
    98   }
   100   virtual bool remove_at(int pos) {
   101     assert(false, "not supported");
   102     return false;
   103   }
   105   MemPointer* at(int index) const {
   106     assert(index >= 0 && index < length(),
   107       "parameter check");
   108     return ((E*)&_data[index]);
   109   }
   111   void sort(FN_SORT fn) {
   112     qsort((void*)_data, _size, sizeof(E), fn);
   113   }
   115   bool shrink() {
   116     return false;
   117   }
   118 };
   121 // This iterator requires pre-sorted MemPointerArray, which is sorted by:
   122 //  1. address
   123 //  2. allocation type
   124 //  3. sequence number
   125 // During the array walking, iterator collapses pointers with the same
   126 // address and allocation type, and only returns the one with highest
   127 // sequence number.
   128 //
   129 // This is read-only iterator, update methods are asserted.
   130 class SequencedRecordIterator : public MemPointerArrayIterator {
   131  private:
   132    MemPointerArrayIteratorImpl _itr;
   133    MemPointer*                 _cur;
   135  public:
   136   SequencedRecordIterator(const MemPointerArray* arr):
   137     _itr(const_cast<MemPointerArray*>(arr)) {
   138     _cur = next_record();
   139   }
   141   SequencedRecordIterator(const SequencedRecordIterator& itr):
   142     _itr(itr._itr) {
   143     _cur = next_record();
   144   }
   146   // return the pointer at current position
   147   virtual MemPointer* current() const {
   148     return _cur;
   149   };
   151   // return the next pointer and advance current position
   152   virtual MemPointer* next() {
   153     _cur = next_record();
   154     return _cur;
   155   }
   157   // return the next pointer without advancing current position
   158   virtual MemPointer* peek_next() const {
   159     assert(false, "not implemented");
   160     return NULL;
   162   }
   163   // return the previous pointer without changing current position
   164   virtual MemPointer* peek_prev() const {
   165     assert(false, "not implemented");
   166     return NULL;
   167   }
   169   // remove the pointer at current position
   170   virtual void remove() {
   171     assert(false, "read-only iterator");
   172   };
   173   // insert the pointer at current position
   174   virtual bool insert(MemPointer* ptr) {
   175     assert(false, "read-only iterator");
   176     return false;
   177   }
   179   virtual bool insert_after(MemPointer* ptr) {
   180     assert(false, "read-only iterator");
   181     return false;
   182   }
   183  private:
   184   // collapse the 'same kind' of records, and return this 'kind' of
   185   // record with highest sequence number
   186   MemPointer* next_record();
   188   // Test if the two records are the same kind: the same memory block and allocation
   189   // type.
   190   inline bool same_kind(const MemPointerRecord* p1, const MemPointerRecord* p2) const {
   191     assert(!p1->is_vm_pointer() && !p2->is_vm_pointer(), "malloc pointer only");
   192     return (p1->addr() == p2->addr() &&
   193       (p1->flags() &MemPointerRecord::tag_masks) ==
   194       (p2->flags() & MemPointerRecord::tag_masks));
   195   }
   196 };
   200 #define DEFAULT_RECORDER_PTR_ARRAY_SIZE 512
   202 class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
   203   friend class MemSnapshot;
   204   friend class MemTracker;
   205   friend class MemTrackWorker;
   206   friend class GenerationData;
   208  protected:
   209   // the array that holds memory records
   210   MemPointerArray*         _pointer_records;
   212  private:
   213   // used for linked list
   214   MemRecorder*             _next;
   215   // active recorder can only record a certain generation data
   216   debug_only(unsigned long _generation;)
   218  protected:
   219   _NOINLINE_ MemRecorder();
   220   ~MemRecorder();
   222   // record a memory operation
   223   bool record(address addr, MEMFLAGS flags, size_t size, address caller_pc = 0);
   225   // linked list support
   226   inline void set_next(MemRecorder* rec) {
   227     _next = rec;
   228   }
   230   inline MemRecorder* next() const {
   231     return _next;
   232   }
   234   // if the recorder is full
   235   inline bool is_full() const {
   236     assert(_pointer_records != NULL, "just check");
   237     return _pointer_records->is_full();
   238   }
   240   // if running out of memory when initializing recorder's internal
   241   // data
   242   inline bool out_of_memory() const {
   243     return (_pointer_records == NULL ||
   244       _pointer_records->out_of_memory());
   245   }
   247   inline void clear() {
   248     assert(_pointer_records != NULL, "Just check");
   249     _pointer_records->clear();
   250   }
   252   SequencedRecordIterator pointer_itr();
   254  protected:
   255   // number of MemRecorder instance
   256   static volatile jint _instance_count;
   258  private:
   259   // sorting function, sort records into following order
   260   // 1. memory address
   261   // 2. allocation type
   262   // 3. sequence number
   263   static int sort_record_fn(const void* e1, const void* e2);
   265   debug_only(void check_dup_seq(jint seq) const;)
   266   debug_only(void set_generation();)
   267 };
   269 #endif // SHARE_VM_SERVICES_MEM_RECORDER_HPP

mercurial