src/share/vm/services/memPtr.hpp

Thu, 18 Apr 2013 10:04:44 -0400

author
zgu
date
Thu, 18 Apr 2013 10:04:44 -0400
changeset 4959
b80cc96882f7
parent 4512
4102b59539ce
child 5272
1f4355cee9a2
permissions
-rw-r--r--

8012464: NMT: classes should not derive from _ValueObj, use VALUE_OBJ_CLASS_SPEC instead
Summary: NMT value objects should use VALUE_OBJ_CLASS_SPEC instead of deriving from _ValueObj
Reviewed-by: coleenp, hseigel, dholmes

     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_PTR_HPP
    26 #define SHARE_VM_SERVICES_MEM_PTR_HPP
    28 #include "memory/allocation.hpp"
    29 #include "runtime/atomic.hpp"
    30 #include "runtime/os.hpp"
    31 #include "runtime/safepoint.hpp"
    33 /*
    34  * global sequence generator that generates sequence numbers to serialize
    35  * memory records.
    36  */
    37 class SequenceGenerator : AllStatic {
    38  public:
    39   static jint next();
    41   // peek last sequence number
    42   static jint peek() {
    43     return _seq_number;
    44   }
    46   // reset sequence number
    47   static void reset() {
    48     assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required");
    49     _seq_number = 1;
    50     _generation ++;
    51   };
    53   static unsigned long current_generation() { return _generation; }
    54   NOT_PRODUCT(static jint max_seq_num() { return _max_seq_number; })
    56  private:
    57   static volatile jint             _seq_number;
    58   static volatile unsigned long    _generation;
    59   NOT_PRODUCT(static jint          _max_seq_number; )
    60 };
    62 /*
    63  * followings are the classes that are used to hold memory activity records in different stages.
    64  *   MemPointer
    65  *     |--------MemPointerRecord
    66  *                     |
    67  *                     |----MemPointerRecordEx
    68  *                     |           |
    69  *                     |           |-------SeqMemPointerRecordEx
    70  *                     |
    71  *                     |----SeqMemPointerRecord
    72  *                     |
    73  *                     |----VMMemRegion
    74  *                               |
    75  *                               |-----VMMemRegionEx
    76  *
    77  *
    78  *  prefix 'Seq' - sequenced, the record contains a sequence number
    79  *  surfix 'Ex'  - extension, the record contains a caller's pc
    80  *
    81  *  per-thread recorder : SeqMemPointerRecord(Ex)
    82  *  snapshot staging    : SeqMemPointerRecord(Ex)
    83  *  snapshot            : MemPointerRecord(Ex) and VMMemRegion(Ex)
    84  *
    85  */
    87 /*
    88  * class that wraps an address to a memory block,
    89  * the memory pointer either points to a malloc'd
    90  * memory block, or a mmap'd memory block
    91  */
    92 class MemPointer VALUE_OBJ_CLASS_SPEC {
    93  public:
    94   MemPointer(): _addr(0) { }
    95   MemPointer(address addr): _addr(addr) { }
    97   MemPointer(const MemPointer& copy_from) {
    98     _addr = copy_from.addr();
    99   }
   101   inline address addr() const {
   102     return _addr;
   103   }
   105   inline operator address() const {
   106     return addr();
   107   }
   109   inline bool operator == (const MemPointer& other) const {
   110     return addr() == other.addr();
   111   }
   113   inline MemPointer& operator = (const MemPointer& other) {
   114     _addr = other.addr();
   115     return *this;
   116   }
   118  protected:
   119   inline void set_addr(address addr) { _addr = addr; }
   121  protected:
   122   // memory address
   123   address    _addr;
   124 };
   126 /* MemPointerRecord records an activityand associated
   127  * attributes on a memory block.
   128  */
   129 class MemPointerRecord : public MemPointer {
   130  private:
   131   MEMFLAGS       _flags;
   132   size_t         _size;
   134 public:
   135   /* extension of MemoryType enum
   136    * see share/vm/memory/allocation.hpp for details.
   137    *
   138    * The tag values are associated to sorting orders, so be
   139    * careful if changes are needed.
   140    * The allocation records should be sorted ahead of tagging
   141    * records, which in turn ahead of deallocation records
   142    */
   143   enum MemPointerTags {
   144     tag_alloc            = 0x0001, // malloc or reserve record
   145     tag_commit           = 0x0002, // commit record
   146     tag_type             = 0x0003, // tag virtual memory to a memory type
   147     tag_uncommit         = 0x0004, // uncommit record
   148     tag_release          = 0x0005, // free or release record
   149     tag_size             = 0x0006, // arena size
   150     tag_masks            = 0x0007, // all tag bits
   151     vmBit                = 0x0008
   152   };
   154   /* helper functions to interpret the tagging flags */
   156   inline static bool is_allocation_record(MEMFLAGS flags) {
   157     return (flags & tag_masks) == tag_alloc;
   158   }
   160   inline static bool is_deallocation_record(MEMFLAGS flags) {
   161     return (flags & tag_masks) == tag_release;
   162   }
   164   inline static bool is_arena_record(MEMFLAGS flags) {
   165     return (flags & (otArena | tag_size)) == otArena;
   166   }
   168   inline static bool is_arena_memory_record(MEMFLAGS flags) {
   169     return (flags & (otArena | tag_size)) == (otArena | tag_size);
   170   }
   172   inline static bool is_virtual_memory_record(MEMFLAGS flags) {
   173     return (flags & vmBit) != 0;
   174   }
   176   inline static bool is_virtual_memory_reserve_record(MEMFLAGS flags) {
   177     return (flags & 0x0F) == (tag_alloc | vmBit);
   178   }
   180   inline static bool is_virtual_memory_commit_record(MEMFLAGS flags) {
   181     return (flags & 0x0F) == (tag_commit | vmBit);
   182   }
   184   inline static bool is_virtual_memory_uncommit_record(MEMFLAGS flags) {
   185     return (flags & 0x0F) == (tag_uncommit | vmBit);
   186   }
   188   inline static bool is_virtual_memory_release_record(MEMFLAGS flags) {
   189     return (flags & 0x0F) == (tag_release | vmBit);
   190   }
   192   inline static bool is_virtual_memory_type_record(MEMFLAGS flags) {
   193     return (flags & 0x0F) == (tag_type | vmBit);
   194   }
   196   /* tagging flags */
   197   inline static MEMFLAGS malloc_tag()                 { return tag_alloc;   }
   198   inline static MEMFLAGS free_tag()                   { return tag_release; }
   199   inline static MEMFLAGS arena_size_tag()             { return tag_size | otArena; }
   200   inline static MEMFLAGS virtual_memory_tag()         { return vmBit; }
   201   inline static MEMFLAGS virtual_memory_reserve_tag() { return (tag_alloc | vmBit); }
   202   inline static MEMFLAGS virtual_memory_commit_tag()  { return (tag_commit | vmBit); }
   203   inline static MEMFLAGS virtual_memory_uncommit_tag(){ return (tag_uncommit | vmBit); }
   204   inline static MEMFLAGS virtual_memory_release_tag() { return (tag_release | vmBit); }
   205   inline static MEMFLAGS virtual_memory_type_tag()    { return (tag_type | vmBit); }
   207  public:
   208   MemPointerRecord(): _size(0), _flags(mtNone) { }
   210   MemPointerRecord(address addr, MEMFLAGS memflags, size_t size = 0):
   211       MemPointer(addr), _flags(memflags), _size(size) { }
   213   MemPointerRecord(const MemPointerRecord& copy_from):
   214     MemPointer(copy_from), _flags(copy_from.flags()),
   215     _size(copy_from.size()) {
   216   }
   218   /* MemPointerRecord is not sequenced, it always return
   219    * 0 to indicate non-sequenced
   220    */
   221   virtual jint seq() const               { return 0; }
   223   inline size_t   size()  const          { return _size; }
   224   inline void set_size(size_t size)      { _size = size; }
   226   inline MEMFLAGS flags() const          { return _flags; }
   227   inline void set_flags(MEMFLAGS flags)  { _flags = flags; }
   229   MemPointerRecord& operator= (const MemPointerRecord& ptr) {
   230     MemPointer::operator=(ptr);
   231     _flags = ptr.flags();
   232 #ifdef ASSERT
   233     if (IS_ARENA_OBJ(_flags)) {
   234       assert(!is_vm_pointer(), "wrong flags");
   235       assert((_flags & ot_masks) == otArena, "wrong flags");
   236     }
   237 #endif
   238     _size = ptr.size();
   239     return *this;
   240   }
   242   // if the pointer represents a malloc-ed memory address
   243   inline bool is_malloced_pointer() const {
   244     return !is_vm_pointer();
   245   }
   247   // if the pointer represents a virtual memory address
   248   inline bool is_vm_pointer() const {
   249     return is_virtual_memory_record(_flags);
   250   }
   252   // if this record records a 'malloc' or virtual memory
   253   // 'reserve' call
   254   inline bool is_allocation_record() const {
   255     return is_allocation_record(_flags);
   256   }
   258   // if this record records a size information of an arena
   259   inline bool is_arena_memory_record() const {
   260     return is_arena_memory_record(_flags);
   261   }
   263   // if this pointer represents an address to an arena object
   264   inline bool is_arena_record() const {
   265     return is_arena_record(_flags);
   266   }
   268   // if this record represents a size information of specific arena
   269   inline bool is_memory_record_of_arena(const MemPointerRecord* arena_rc) {
   270     assert(is_arena_memory_record(), "not size record");
   271     assert(arena_rc->is_arena_record(), "not arena record");
   272     return (arena_rc->addr() + sizeof(void*)) == addr();
   273   }
   275   // if this record records a 'free' or virtual memory 'free' call
   276   inline bool is_deallocation_record() const {
   277     return is_deallocation_record(_flags);
   278   }
   280   // if this record records a virtual memory 'commit' call
   281   inline bool is_commit_record() const {
   282     return is_virtual_memory_commit_record(_flags);
   283   }
   285   // if this record records a virtual memory 'uncommit' call
   286   inline bool is_uncommit_record() const {
   287     return is_virtual_memory_uncommit_record(_flags);
   288   }
   290   // if this record is a tagging record of a virtual memory block
   291   inline bool is_type_tagging_record() const {
   292     return is_virtual_memory_type_record(_flags);
   293   }
   295   // if the two memory pointer records actually represent the same
   296   // memory block
   297   inline bool is_same_region(const MemPointerRecord* other) const {
   298     return (addr() == other->addr() && size() == other->size());
   299   }
   301   // if this memory region fully contains another one
   302   inline bool contains_region(const MemPointerRecord* other) const {
   303     return contains_region(other->addr(), other->size());
   304   }
   306   // if this memory region fully contains specified memory range
   307   inline bool contains_region(address add, size_t sz) const {
   308     return (addr() <= add && addr() + size() >= add + sz);
   309   }
   311   inline bool contains_address(address add) const {
   312     return (addr() <= add && addr() + size() > add);
   313   }
   315   // if this memory region overlaps another region
   316   inline bool overlaps_region(const MemPointerRecord* other) const {
   317     assert(other != NULL, "Just check");
   318     assert(size() > 0 && other->size() > 0, "empty range");
   319     return contains_address(other->addr()) ||
   320            contains_address(other->addr() + other->size() - 1) || // exclude end address
   321            other->contains_address(addr()) ||
   322            other->contains_address(addr() + size() - 1); // exclude end address
   323   }
   325 };
   327 // MemPointerRecordEx also records callsite pc, from where
   328 // the memory block is allocated
   329 class MemPointerRecordEx : public MemPointerRecord {
   330  private:
   331   address      _pc;  // callsite pc
   333  public:
   334   MemPointerRecordEx(): _pc(0) { }
   336   MemPointerRecordEx(address addr, MEMFLAGS memflags, size_t size = 0, address pc = 0):
   337     MemPointerRecord(addr, memflags, size), _pc(pc) {}
   339   MemPointerRecordEx(const MemPointerRecordEx& copy_from):
   340     MemPointerRecord(copy_from), _pc(copy_from.pc()) {}
   342   inline address pc() const { return _pc; }
   344   void init(const MemPointerRecordEx* mpe) {
   345     MemPointerRecord::operator=(*mpe);
   346     _pc = mpe->pc();
   347   }
   349   void init(const MemPointerRecord* mp) {
   350     MemPointerRecord::operator=(*mp);
   351     _pc = 0;
   352   }
   353 };
   355 // a virtual memory region. The region can represent a reserved
   356 // virtual memory region or a committed memory region
   357 class VMMemRegion : public MemPointerRecord {
   358 public:
   359   VMMemRegion() { }
   361   void init(const MemPointerRecord* mp) {
   362     assert(mp->is_vm_pointer(), "Sanity check");
   363     _addr = mp->addr();
   364       set_size(mp->size());
   365     set_flags(mp->flags());
   366   }
   368   VMMemRegion& operator=(const VMMemRegion& other) {
   369     MemPointerRecord::operator=(other);
   370     return *this;
   371   }
   373   inline bool is_reserved_region() const {
   374     return is_allocation_record();
   375   }
   377   inline bool is_committed_region() const {
   378     return is_commit_record();
   379   }
   381   /* base address of this virtual memory range */
   382   inline address base() const {
   383     return addr();
   384   }
   386   /* tag this virtual memory range to the specified memory type */
   387   inline void tag(MEMFLAGS f) {
   388     set_flags(flags() | (f & mt_masks));
   389   }
   391   // expand this region to also cover specified range.
   392   // The range has to be on either end of the memory region.
   393   void expand_region(address addr, size_t sz) {
   394     if (addr < base()) {
   395       assert(addr + sz == base(), "Sanity check");
   396       _addr = addr;
   397       set_size(size() + sz);
   398     } else {
   399       assert(base() + size() == addr, "Sanity check");
   400       set_size(size() + sz);
   401     }
   402   }
   404   // exclude the specified address range from this region.
   405   // The excluded memory range has to be on either end of this memory
   406   // region.
   407   inline void exclude_region(address add, size_t sz) {
   408     assert(is_reserved_region() || is_committed_region(), "Sanity check");
   409     assert(addr() != NULL && size() != 0, "Sanity check");
   410     assert(add >= addr() && add < addr() + size(), "Sanity check");
   411     assert(add == addr() || (add + sz) == (addr() + size()),
   412       "exclude in the middle");
   413     if (add == addr()) {
   414       set_addr(add + sz);
   415       set_size(size() - sz);
   416     } else {
   417       set_size(size() - sz);
   418     }
   419   }
   420 };
   422 class VMMemRegionEx : public VMMemRegion {
   423  private:
   424   jint   _seq;  // sequence number
   426  public:
   427   VMMemRegionEx(): _pc(0) { }
   429   void init(const MemPointerRecordEx* mpe) {
   430     VMMemRegion::init(mpe);
   431     _pc = mpe->pc();
   432   }
   434   void init(const MemPointerRecord* mpe) {
   435     VMMemRegion::init(mpe);
   436     _pc = 0;
   437   }
   439   VMMemRegionEx& operator=(const VMMemRegionEx& other) {
   440     VMMemRegion::operator=(other);
   441     _pc = other.pc();
   442     return *this;
   443   }
   445   inline address pc() const { return _pc; }
   446  private:
   447   address   _pc;
   448 };
   450 /*
   451  * Sequenced memory record
   452  */
   453 class SeqMemPointerRecord : public MemPointerRecord {
   454  private:
   455    jint _seq;  // sequence number
   457  public:
   458   SeqMemPointerRecord(): _seq(0){ }
   460   SeqMemPointerRecord(address addr, MEMFLAGS flags, size_t size)
   461     : MemPointerRecord(addr, flags, size) {
   462     _seq = SequenceGenerator::next();
   463   }
   465   SeqMemPointerRecord(const SeqMemPointerRecord& copy_from)
   466     : MemPointerRecord(copy_from) {
   467     _seq = copy_from.seq();
   468   }
   470   SeqMemPointerRecord& operator= (const SeqMemPointerRecord& ptr) {
   471     MemPointerRecord::operator=(ptr);
   472     _seq = ptr.seq();
   473     return *this;
   474   }
   476   inline jint seq() const {
   477     return _seq;
   478   }
   479 };
   483 class SeqMemPointerRecordEx : public MemPointerRecordEx {
   484  private:
   485   jint    _seq;  // sequence number
   487  public:
   488   SeqMemPointerRecordEx(): _seq(0) { }
   490   SeqMemPointerRecordEx(address addr, MEMFLAGS flags, size_t size,
   491     address pc): MemPointerRecordEx(addr, flags, size, pc) {
   492     _seq = SequenceGenerator::next();
   493   }
   495   SeqMemPointerRecordEx(const SeqMemPointerRecordEx& copy_from)
   496     : MemPointerRecordEx(copy_from) {
   497     _seq = copy_from.seq();
   498   }
   500   SeqMemPointerRecordEx& operator= (const SeqMemPointerRecordEx& ptr) {
   501     MemPointerRecordEx::operator=(ptr);
   502     _seq = ptr.seq();
   503     return *this;
   504   }
   506   inline jint seq() const {
   507     return _seq;
   508   }
   509 };
   511 #endif // SHARE_VM_SERVICES_MEM_PTR_HPP

mercurial