hotspot/src/share/vm/adlc/arena.cpp
changeset 1 489c9b5090e2
child 5547 f4b087cbb361
equal deleted inserted replaced
0:fd16c54261b3 1:489c9b5090e2
       
     1 /*
       
     2  * Copyright 1998-2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "adlc.hpp"
       
    26 
       
    27 void* Chunk::operator new(size_t requested_size, size_t length) {
       
    28   return CHeapObj::operator new(requested_size + length);
       
    29 }
       
    30 
       
    31 void  Chunk::operator delete(void* p, size_t length) {
       
    32   CHeapObj::operator delete(p);
       
    33 }
       
    34 
       
    35 Chunk::Chunk(size_t length) {
       
    36   _next = NULL;         // Chain on the linked list
       
    37   _len  = length;       // Save actual size
       
    38 }
       
    39 
       
    40 //------------------------------chop-------------------------------------------
       
    41 void Chunk::chop() {
       
    42   Chunk *k = this;
       
    43   while( k ) {
       
    44     Chunk *tmp = k->_next;
       
    45     // clear out this chunk (to detect allocation bugs)
       
    46     memset(k, 0xBAADBABE, k->_len);
       
    47     free(k);                    // Free chunk (was malloc'd)
       
    48     k = tmp;
       
    49   }
       
    50 }
       
    51 
       
    52 void Chunk::next_chop() {
       
    53   _next->chop();
       
    54   _next = NULL;
       
    55 }
       
    56 
       
    57 //------------------------------Arena------------------------------------------
       
    58 Arena::Arena( size_t init_size ) {
       
    59   init_size = (init_size+3) & ~3;
       
    60   _first = _chunk = new (init_size) Chunk(init_size);
       
    61   _hwm = _chunk->bottom();      // Save the cached hwm, max
       
    62   _max = _chunk->top();
       
    63   set_size_in_bytes(init_size);
       
    64 }
       
    65 
       
    66 Arena::Arena() {
       
    67   _first = _chunk = new (Chunk::init_size) Chunk(Chunk::init_size);
       
    68   _hwm = _chunk->bottom();      // Save the cached hwm, max
       
    69   _max = _chunk->top();
       
    70   set_size_in_bytes(Chunk::init_size);
       
    71 }
       
    72 
       
    73 Arena::Arena( Arena *a )
       
    74 : _chunk(a->_chunk), _hwm(a->_hwm), _max(a->_max), _first(a->_first) {
       
    75   set_size_in_bytes(a->size_in_bytes());
       
    76 }
       
    77 
       
    78 //------------------------------used-------------------------------------------
       
    79 // Total of all Chunks in arena
       
    80 size_t Arena::used() const {
       
    81   size_t sum = _chunk->_len - (_max-_hwm); // Size leftover in this Chunk
       
    82   register Chunk *k = _first;
       
    83   while( k != _chunk) {         // Whilst have Chunks in a row
       
    84     sum += k->_len;             // Total size of this Chunk
       
    85     k = k->_next;               // Bump along to next Chunk
       
    86   }
       
    87   return sum;                   // Return total consumed space.
       
    88 }
       
    89 
       
    90 //------------------------------grow-------------------------------------------
       
    91 // Grow a new Chunk
       
    92 void* Arena::grow( size_t x ) {
       
    93   // Get minimal required size.  Either real big, or even bigger for giant objs
       
    94   size_t len = max(x, Chunk::size);
       
    95 
       
    96   register Chunk *k = _chunk;   // Get filled-up chunk address
       
    97   _chunk = new (len) Chunk(len);
       
    98 
       
    99   if( k ) k->_next = _chunk;    // Append new chunk to end of linked list
       
   100   else _first = _chunk;
       
   101   _hwm  = _chunk->bottom();     // Save the cached hwm, max
       
   102   _max =  _chunk->top();
       
   103   set_size_in_bytes(size_in_bytes() + len);
       
   104   void* result = _hwm;
       
   105   _hwm += x;
       
   106   return result;
       
   107 }
       
   108 
       
   109 //------------------------------calloc-----------------------------------------
       
   110 // Allocate zeroed storage in Arena
       
   111 void *Arena::Acalloc( size_t items, size_t x ) {
       
   112   size_t z = items*x;   // Total size needed
       
   113   void *ptr = Amalloc(z);       // Get space
       
   114   memset( ptr, 0, z );          // Zap space
       
   115   return ptr;                   // Return space
       
   116 }
       
   117 
       
   118 //------------------------------realloc----------------------------------------
       
   119 // Reallocate storage in Arena.
       
   120 void *Arena::Arealloc( void *old_ptr, size_t old_size, size_t new_size ) {
       
   121   char *c_old = (char*)old_ptr; // Handy name
       
   122   // Stupid fast special case
       
   123   if( new_size <= old_size ) {  // Shrink in-place
       
   124     if( c_old+old_size == _hwm) // Attempt to free the excess bytes
       
   125       _hwm = c_old+new_size;    // Adjust hwm
       
   126     return c_old;
       
   127   }
       
   128 
       
   129   // See if we can resize in-place
       
   130   if( (c_old+old_size == _hwm) &&       // Adjusting recent thing
       
   131       (c_old+new_size <= _max) ) {      // Still fits where it sits
       
   132     _hwm = c_old+new_size;      // Adjust hwm
       
   133     return c_old;               // Return old pointer
       
   134   }
       
   135 
       
   136   // Oops, got to relocate guts
       
   137   void *new_ptr = Amalloc(new_size);
       
   138   memcpy( new_ptr, c_old, old_size );
       
   139   Afree(c_old,old_size);        // Mostly done to keep stats accurate
       
   140   return new_ptr;
       
   141 }
       
   142 
       
   143 //------------------------------reset------------------------------------------
       
   144 // Reset this Arena to empty, and return this Arenas guts in a new Arena.
       
   145 Arena *Arena::reset(void) {
       
   146   Arena *a = new Arena(this);   // New empty arena
       
   147   _first = _chunk = NULL;       // Normal, new-arena initialization
       
   148   _hwm = _max = NULL;
       
   149   return a;                     // Return Arena with guts
       
   150 }
       
   151 
       
   152 //------------------------------contains---------------------------------------
       
   153 // Determine if pointer belongs to this Arena or not.
       
   154 bool Arena::contains( const void *ptr ) const {
       
   155   if( (void*)_chunk->bottom() <= ptr && ptr < (void*)_hwm )
       
   156     return true;                // Check for in this chunk
       
   157   for( Chunk *c = _first; c; c = c->_next )
       
   158     if( (void*)c->bottom() <= ptr && ptr < (void*)c->top())
       
   159       return true;              // Check for every chunk in Arena
       
   160   return false;                 // Not in any Chunk, so not in Arena
       
   161 }
       
   162 
       
   163 //-----------------------------------------------------------------------------
       
   164 // CHeapObj
       
   165 
       
   166 void* CHeapObj::operator new(size_t size){
       
   167   return (void *) malloc(size);
       
   168 }
       
   169 
       
   170 void CHeapObj::operator delete(void* p){
       
   171  free(p);
       
   172 }