src/share/vm/services/memPtr.hpp

Tue, 24 Jul 2012 10:51:00 -0700

author
twisti
date
Tue, 24 Jul 2012 10:51:00 -0700
changeset 3969
1d7922586cf6
parent 3900
d2a62e0f25eb
child 3994
e5bf1c79ed5b
permissions
-rw-r--r--

7023639: JSR 292 method handle invocation needs a fast path for compiled code
6984705: JSR 292 method handle creation should not go through JNI
Summary: remove assembly code for JDK 7 chained method handles
Reviewed-by: jrose, twisti, kvn, mhaupt
Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>

     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     DEBUG_ONLY(_generation ++;)
    51   };
    53   DEBUG_ONLY(static unsigned long current_generation() { return (unsigned long)_generation; })
    54   DEBUG_ONLY(static jint max_seq_num() { return _max_seq_number; })
    56  private:
    57   static volatile jint _seq_number;
    58   DEBUG_ONLY(static jint _max_seq_number; )
    59   DEBUG_ONLY(static volatile unsigned long _generation; )
    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 : public _ValueObj {
    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_size_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_size_record() const {
   260     return is_arena_size_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_size_record_of_arena(const MemPointerRecord* arena_rc) {
   270     assert(is_arena_size_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   }
   294 };
   296 // MemPointerRecordEx also records callsite pc, from where
   297 // the memory block is allocated
   298 class MemPointerRecordEx : public MemPointerRecord {
   299  private:
   300   address      _pc;  // callsite pc
   302  public:
   303   MemPointerRecordEx(): _pc(0) { }
   305   MemPointerRecordEx(address addr, MEMFLAGS memflags, size_t size = 0, address pc = 0):
   306     MemPointerRecord(addr, memflags, size), _pc(pc) {}
   308   MemPointerRecordEx(const MemPointerRecordEx& copy_from):
   309     MemPointerRecord(copy_from), _pc(copy_from.pc()) {}
   311   inline address pc() const { return _pc; }
   313   void init(const MemPointerRecordEx* mpe) {
   314     MemPointerRecord::operator=(*mpe);
   315     _pc = mpe->pc();
   316   }
   318   void init(const MemPointerRecord* mp) {
   319     MemPointerRecord::operator=(*mp);
   320     _pc = 0;
   321   }
   322 };
   324 // a virtual memory region
   325 class VMMemRegion : public MemPointerRecord {
   326  private:
   327   // committed size
   328   size_t       _committed_size;
   330 public:
   331   VMMemRegion(): _committed_size(0) { }
   333   void init(const MemPointerRecord* mp) {
   334     assert(mp->is_vm_pointer(), "not virtual memory pointer");
   335     _addr = mp->addr();
   336     if (mp->is_commit_record() || mp->is_uncommit_record()) {
   337       _committed_size = mp->size();
   338       set_size(_committed_size);
   339     } else {
   340       set_size(mp->size());
   341       _committed_size = 0;
   342     }
   343     set_flags(mp->flags());
   344   }
   346   VMMemRegion& operator=(const VMMemRegion& other) {
   347     MemPointerRecord::operator=(other);
   348     _committed_size = other.committed_size();
   349     return *this;
   350   }
   352   inline bool is_reserve_record() const {
   353     return is_virtual_memory_reserve_record(flags());
   354   }
   356   inline bool is_release_record() const {
   357     return is_virtual_memory_release_record(flags());
   358   }
   360   // resize reserved VM range
   361   inline void set_reserved_size(size_t new_size) {
   362     assert(new_size >= committed_size(), "resize");
   363     set_size(new_size);
   364   }
   366   inline void commit(size_t size) {
   367     _committed_size += size;
   368   }
   370   inline void uncommit(size_t size) {
   371     if (_committed_size >= size) {
   372       _committed_size -= size;
   373     } else {
   374       _committed_size = 0;
   375     }
   376   }
   378   /*
   379    * if this virtual memory range covers whole range of
   380    * the other VMMemRegion
   381    */
   382   bool contains(const VMMemRegion* mr) const;
   384   /* base address of this virtual memory range */
   385   inline address base() const {
   386     return addr();
   387   }
   389   /* tag this virtual memory range to the specified memory type */
   390   inline void tag(MEMFLAGS f) {
   391     set_flags(flags() | (f & mt_masks));
   392   }
   394   // release part of memory range
   395   inline void partial_release(address add, size_t sz) {
   396     assert(add >= addr() && add < addr() + size(), "not valid address");
   397     // for now, it can partially release from the both ends,
   398     // but not in the middle
   399     assert(add == addr() || (add + sz) == (addr() + size()),
   400       "release in the middle");
   401     if (add == addr()) {
   402       set_addr(add + sz);
   403       set_size(size() - sz);
   404     } else {
   405       set_size(size() - sz);
   406     }
   407   }
   409   // the committed size of the virtual memory block
   410   inline size_t committed_size() const {
   411     return _committed_size;
   412   }
   414   // the reserved size of the virtual memory block
   415   inline size_t reserved_size() const {
   416     return size();
   417   }
   418 };
   420 class VMMemRegionEx : public VMMemRegion {
   421  private:
   422   jint   _seq;  // sequence number
   424  public:
   425   VMMemRegionEx(): _pc(0) { }
   427   void init(const MemPointerRecordEx* mpe) {
   428     VMMemRegion::init(mpe);
   429     _pc = mpe->pc();
   430   }
   432   void init(const MemPointerRecord* mpe) {
   433     VMMemRegion::init(mpe);
   434     _pc = 0;
   435   }
   437   VMMemRegionEx& operator=(const VMMemRegionEx& other) {
   438     VMMemRegion::operator=(other);
   439     _pc = other.pc();
   440     return *this;
   441   }
   443   inline address pc() const { return _pc; }
   444  private:
   445   address   _pc;
   446 };
   448 /*
   449  * Sequenced memory record
   450  */
   451 class SeqMemPointerRecord : public MemPointerRecord {
   452  private:
   453    jint _seq;  // sequence number
   455  public:
   456   SeqMemPointerRecord(): _seq(0){ }
   458   SeqMemPointerRecord(address addr, MEMFLAGS flags, size_t size)
   459     : MemPointerRecord(addr, flags, size) {
   460     _seq = SequenceGenerator::next();
   461   }
   463   SeqMemPointerRecord(const SeqMemPointerRecord& copy_from)
   464     : MemPointerRecord(copy_from) {
   465     _seq = copy_from.seq();
   466   }
   468   SeqMemPointerRecord& operator= (const SeqMemPointerRecord& ptr) {
   469     MemPointerRecord::operator=(ptr);
   470     _seq = ptr.seq();
   471     return *this;
   472   }
   474   inline jint seq() const {
   475     return _seq;
   476   }
   477 };
   481 class SeqMemPointerRecordEx : public MemPointerRecordEx {
   482  private:
   483   jint    _seq;  // sequence number
   485  public:
   486   SeqMemPointerRecordEx(): _seq(0) { }
   488   SeqMemPointerRecordEx(address addr, MEMFLAGS flags, size_t size,
   489     address pc): MemPointerRecordEx(addr, flags, size, pc) {
   490     _seq = SequenceGenerator::next();
   491   }
   493   SeqMemPointerRecordEx(const SeqMemPointerRecordEx& copy_from)
   494     : MemPointerRecordEx(copy_from) {
   495     _seq = copy_from.seq();
   496   }
   498   SeqMemPointerRecordEx& operator= (const SeqMemPointerRecordEx& ptr) {
   499     MemPointerRecordEx::operator=(ptr);
   500     _seq = ptr.seq();
   501     return *this;
   502   }
   504   inline jint seq() const {
   505     return _seq;
   506   }
   507 };
   509 #endif // SHARE_VM_SERVICES_MEM_PTR_HPP

mercurial