allocation.hpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.21 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 # include <string.h>
00025 
00026 /*
00027   All classes in the virtual machine must be subclassed
00028   by one of the following allocation classes:
00029 
00030    "For objects allocated in the resource area."
00031    - ResourceObj
00032      - PrintableResourceObj
00033 
00034    "For objects allocated in the C-heap (managed by: free & malloc)."
00035    - CHeapObj
00036      - PrintableCHeapObj
00037 
00038    "For objects allocated on the stack."
00039    - StackObj
00040      - PrintableStackObj
00041 
00042    "For embedded objects."
00043    - ValueObj
00044 
00045    "For classes used as name spaces."
00046    - AllStatic
00047 
00048    "The printable subclasses are used for debugging and define virtual
00049     member functions for printing. Classes that avoid allocating the
00050     vtbl entries in the objects should therefore not the printable subclasses"
00051 */
00052 
00053 // base class ResourceObj follows at the end of the file because it uses ResourceArea
00054 
00055 // Base class for objects allocated in the c-heap.
00056 class CHeapObj {
00057  public:
00058   void* operator new(size_t size);
00059   void  operator delete(void* p);
00060   void* new_array(size_t size);
00061 };
00062 
00063 // Base class for objects allocated in the c-heap
00064 // with printing behavior
00065 class PrintableCHeapObj : public CHeapObj {
00066  public:
00067   virtual void print() = 0;
00068   virtual void print_short();
00069 };
00070 
00071 // Base class for objects allocated on the stack only.
00072 // Calling new or delete will result in fatal error.
00073 class StackObj {
00074  public:
00075   void* operator new(size_t size);
00076   void  operator delete(void* p);
00077 };
00078 
00079 // Base class for objects allocated on the stack only but
00080 // with printing behavior
00081 class PrintableStackObj : StackObj {
00082  public:
00083   virtual void print() = 0;
00084   virtual void print_short();
00085 };
00086 
00087 // Base class for objects used as value objects.
00088 // Calling new or delete will result in fatal error.
00089 class ValueObj {
00090  public:
00091   void* operator new(size_t size);
00092   void operator delete(void* p);
00093 };
00094 
00095 // Base class for classes that constitute name spaces.
00096 class AllStatic {
00097  public:
00098   void* operator new(size_t size);
00099   void operator delete(void* p);
00100 };
00101 
00102 
00103 // One of the following macros must be used when allocating an array to
00104 // determine which area the array should reside in.
00105 # define NEW_RESOURCE_ARRAY( type, size )\
00106     (type*) allocateResource( (size) * sizeof(type))
00107 
00108 # define NEW_C_HEAP_ARRAY( type, size )\
00109     (type*) malloc( (size) * sizeof(type)); //XSTR(type) " in " __FILE__)
00110 
00111 # define NEW_RESOURCE_OBJ( type ) NEW_RESOURCE_ARRAY( type, 1 )
00112 # define NEW_C_HEAP_OBJ( type )   NEW_C_HEAP_ARRAY( type, 1 )
00113 
00114 // The resource area holds temporary data structures of the VM.  Things
00115 // in the resource area can be deallocated very efficiently using
00116 // ResourceMarks.  (The destructor of a ResourceMark will deallocate
00117 // everything that was created since the ResourceMark was created.)
00118 
00119 const int min_resource_chunk_size = 256 * K;
00120 const int min_resource_free_size  =  32 * K;
00121 
00122 char* AllocatePageAligned(int size, char* name);
00123 char* AllocateHeap(int size, char* name);
00124 void  FreeHeap(void* p);
00125 
00126 extern "C" bool PrintResourceAllocation; // to break cycle in includeDB
00127 
00128 class ResourceAreaChunk: public PrintableCHeapObj {
00129   friend class ResourceMark;
00130   friend class ResourceArea;
00131   friend class Resources;
00132   char* bottom;
00133   char* top;
00134   char* first_free;
00135   ResourceAreaChunk* prev;
00136 
00137   int _allocated;     // Allocated bytes in this and previous chunks.
00138   int _previous_used; // Used bytes in previous chunks.
00139 
00140   void clear(char *start, char *end) { memset(start, 33, end - start); }
00141   void clear() { clear(bottom, first_free); }
00142   void freeTo(char *new_first_free);
00143 
00144 public:
00145   char* allocate_bytes(int size) {
00146     char* p = first_free;
00147     if (first_free + size <= top) {
00148 #ifndef PRODUCT
00149       if (PrintResourceAllocation) print_alloc(p, size);
00150 #endif
00151       first_free += size;
00152       return p;
00153     } else return NULL;
00154   }
00155 
00156   ResourceAreaChunk(int min_capacity, ResourceAreaChunk* previous);
00157   ~ResourceAreaChunk();
00158 
00159   void initialize(ResourceAreaChunk* previous);
00160 
00161   int capacity() { return top        - bottom; }
00162   int used()     { return first_free - bottom; }
00163   
00164   bool contains(void* p) {
00165     if (p >= (void*) bottom && p < (void*) top) return true;
00166     else if (prev) return prev->contains(p);
00167     else return false; }
00168 
00169   void print();
00170   void print_short();
00171  protected:
00172   void print_alloc(char* addr, int size);
00173 };
00174 
00175 class ResourceArea {
00176  public:
00177   ResourceAreaChunk* chunk;       // current chunk
00178 # ifdef ASSERT
00179   int nesting;            // current # of nested ResourceMarks
00180                           // (will warn if alloc with nesting == 0)
00181 # endif
00182   
00183   ResourceArea();
00184   ~ResourceArea();
00185 
00186   char* allocate_more_bytes(int size);
00187   char* allocate_bytes(int size) {
00188     assert(size    >= 0, "negative size in allocate_bytes");
00189 #ifdef ASSERT
00190     // NB: don't make it a fatal error -- otherwise, if you call certain functions
00191     // from the debugger, it might report a leak since there might not be a
00192     // ResourceMark.
00193     // However, in all other situations, calling allocate_bytes with nesting == 0
00194     // is a definitive memory leak.  -Urs 10/95
00195     static int warned = 0;      // to suppress multiple warnings (e.g. when allocating from the debugger)
00196     if (nesting < 1 && !warned++) error("memory leak: allocating w/o ResourceMark!");
00197 #endif
00198     if (size == 0) {
00199       // want to return an invalid pointer for a zero-sized allocation,
00200       // but not NULL, because routines may want to use NULL for failure.
00201       return (char*) 1;
00202     }
00203     size = roundTo(size, oopSize);
00204     char* p;
00205     if (chunk && (p = chunk->allocate_bytes(size))) return p;
00206     return allocate_more_bytes(size);
00207   }
00208 
00209   int capacity() { return chunk ? chunk->_allocated : 0; }
00210   
00211   int used();
00212   bool contains(void* p) { return chunk != NULL && chunk->contains(p); }
00213 };
00214 
00215 
00216 // A resource mark releases all resources allocated after it was created
00217 // when the mark is deleted.  Typically used as a local variable.
00218 class ResourceMark: StackObj {
00219  protected:
00220   static bool enabled;
00221   ResourceArea* area;
00222   ResourceAreaChunk* chunk;
00223   char* top;
00224  public:
00225   ResourceMark();
00226   ~ResourceMark();
00227 };
00228 
00229 class FinalResourceMark: public ResourceMark {
00230  public:
00231   FinalResourceMark();
00232   ~FinalResourceMark();
00233 };
00234 
00235 // A NoGCVerifier makes sure that inbetween its creation and deletion
00236 // there are no scavanges. Typically used as a local variable.
00237 
00238 class NoGCVerifier: StackObj {
00239  private:
00240   int old_scavenge_count;
00241  public:
00242   NoGCVerifier();
00243   ~NoGCVerifier();
00244 };
00245 
00246 
00247 class Resources {
00248  private:
00249   ResourceAreaChunk* freeChunks;        // list of unused chunks
00250   int               _allocated;    // total number of bytes allocated
00251   bool               _in_consistent_state;
00252   ResourceAreaChunk* getFromFreeList(int min_capacity);
00253  public:
00254   Resources();
00255   ResourceAreaChunk* new_chunk(int min_capacity, ResourceAreaChunk* area);
00256   
00257   void addToFreeList(ResourceAreaChunk* c);
00258   bool in_consistent_state() { return _in_consistent_state; }
00259 
00260   bool  contains(char* p);
00261   int capacity();
00262   int used();
00263 };
00264 
00265 extern Resources resources;
00266 extern ResourceArea resource_area;
00267 
00268 inline char* allocateResource(int size) {
00269   return resource_area.allocate_bytes(size);
00270 }
00271 
00272 
00273 // Base class for objects allocated in the resource area per default.
00274 // Optionally, objects may be allocated on the C heap with new(true) Foo(...)
00275 class ResourceObj {
00276  public:
00277   void* operator new(size_t size, bool on_C_heap = false) {
00278     return on_C_heap ? (char*) malloc(size) : allocateResource(size);
00279   }
00280 
00281   void  operator delete(void* p) {} // use explicit free() to deallocate heap-allocated objects
00282 };
00283 
00284 // Base class for objects allocated in the resource area
00285 // with printing behavior.
00286 class PrintableResourceObj : public ResourceObj {
00287  public:
00288   virtual void print() = 0;
00289   virtual void print_short();
00290 };
00291 

Generated on Mon Oct 9 13:37:00 2006 for Strongtalk VM by  doxygen 1.4.7