allocation.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.23 $ */
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 "incls/_precompiled.incl"
00025 # include "incls/_allocation.cpp.incl"
00026 
00027 ResourceArea resource_area;
00028 
00029 void PrintableResourceObj::print_short() { print(); }
00030 void PrintableCHeapObj::print_short()    { print(); }
00031 void PrintableStackObj::print_short()    { print(); }
00032 
00033 void* CHeapObj::operator new(size_t size){
00034   return (void *) AllocateHeap(size, "operator-new");
00035 }
00036 
00037 void CHeapObj::operator delete(void* p){
00038  assert( !resources.contains((char*)p),
00039         "CHeapObj should not be in resource area");
00040  FreeHeap(p);
00041 }
00042 
00043 void* StackObj::operator new(size_t size) {
00044   Unused(size);
00045   ShouldNotCallThis();
00046   return 0;
00047 };
00048 
00049 void StackObj::operator delete(void* p) {
00050   Unused(p);
00051   ShouldNotCallThis();
00052 };
00053 
00054 void* ValueObj::operator new(size_t size) {
00055   Unused(size);
00056   ShouldNotCallThis();
00057   return 0;
00058 };
00059 
00060 void ValueObj::operator delete(void* p) {
00061   Unused(p);
00062   ShouldNotCallThis();
00063 };
00064 
00065 ResourceAreaChunk::ResourceAreaChunk(int min_capacity,
00066                                      ResourceAreaChunk* previous) {
00067   // lprintf("Resources cap=%d used=%d\n", resources.capacity(), resources.used());
00068 
00069   int size = max(min_capacity + min_resource_free_size,
00070                   min_resource_chunk_size);
00071   bottom = (char*) AllocateHeap(size,"resourceAreaChunk");
00072   top    = bottom + size;
00073   initialize(previous);
00074 }
00075 
00076 void ResourceAreaChunk::initialize(ResourceAreaChunk* previous) {
00077   first_free  = bottom;
00078   prev        = previous;
00079 
00080   _allocated     = capacity() + (prev ? prev->_allocated : 0);
00081   _previous_used = prev ? (prev->_previous_used + used()) : 0;
00082 }
00083 
00084 ResourceAreaChunk::~ResourceAreaChunk() {
00085   FreeHeap(bottom);
00086 }
00087 
00088 void ResourceAreaChunk::print() {
00089   if (prev) prev->print();
00090   print_short();
00091   lprintf(": [%#lx, %#lx), prev = %#lx\n", bottom, top, prev);
00092 }
00093 
00094 void ResourceAreaChunk::print_short() { std->print("ResourceAreaChunk %#lx", this); }
00095 void ResourceAreaChunk::print_alloc(char* addr, int size) {
00096   std->print_cr("allocating %ld bytes at %#lx", size, addr);
00097 }
00098 
00099 ResourceArea::ResourceArea() {
00100   chunk = NULL;
00101 # ifdef ASSERT
00102   nesting = 0;
00103 # endif
00104 }
00105 
00106 ResourceArea::~ResourceArea() {
00107   // deallocate all chunks
00108   ResourceAreaChunk* prevc;
00109   for (ResourceAreaChunk* c = chunk; c != NULL; c = prevc) {
00110     prevc = c->prev;
00111     resources.addToFreeList(c);
00112   }
00113 }
00114 
00115 char* ResourceArea::allocate_more_bytes(int size) {
00116   chunk = resources.new_chunk(size, chunk);
00117   char* p = chunk->allocate_bytes(size);
00118   assert(p, "Nothing returned");
00119   return p;
00120 }
00121 
00122 int ResourceArea::used() {
00123   if (chunk == NULL) return 0;
00124   return chunk->used() + (chunk->prev ? chunk->prev->_previous_used : 0);
00125 }
00126 
00127 Resources resources;
00128 
00129 int Resources::capacity() { return _allocated; }
00130 
00131 int Resources::used() {
00132   return resource_area.used();
00133 }
00134 
00135 static bool  in_rsrc;
00136 static char* p_rsrc;
00137 
00138 bool Resources::contains(char* p) {
00139   in_rsrc = false;
00140   p_rsrc = p;
00141   // FIX LATER  processes->processesDo(rsrcf2);
00142   return in_rsrc;
00143 }
00144 
00145 void Resources::addToFreeList(ResourceAreaChunk* c) {
00146   if (ZapResourceArea)
00147     c->clear();
00148   c->prev = freeChunks;
00149   freeChunks = c;
00150 }
00151 
00152 ResourceAreaChunk* Resources::getFromFreeList(int min_capacity) {
00153   if (!freeChunks) return NULL;
00154 
00155   // Handle the first element special
00156   if (freeChunks->capacity() >= min_capacity) {
00157     ResourceAreaChunk* res = freeChunks;
00158     freeChunks = freeChunks->prev;
00159     return res;
00160   }
00161 
00162   ResourceAreaChunk* cursor = freeChunks;
00163   while (cursor->prev) {
00164     if (cursor->prev->capacity() >= min_capacity) {
00165       ResourceAreaChunk* res = cursor->prev;
00166       cursor->prev = cursor->prev->prev;
00167       return res;
00168     }
00169     cursor = cursor->prev;
00170   }
00171 
00172   // No suitable chunk found
00173   return NULL;
00174 }
00175 
00176     
00177 ResourceAreaChunk* Resources::new_chunk(int min_capacity,
00178                                         ResourceAreaChunk* previous) {
00179   _in_consistent_state = false;
00180   ResourceAreaChunk* res = getFromFreeList(min_capacity);
00181   if (res) {
00182     res->initialize(previous);
00183   } else {
00184     res = new ResourceAreaChunk(min_capacity, previous);
00185     _allocated += res->capacity();
00186     if (PrintResourceChunkAllocation) {
00187       std->print("*allocating new resource area chunk of >=%d bytes, new total = %d bytes\n", min_capacity, _allocated);
00188     }
00189   }
00190   _in_consistent_state = true;
00191 
00192   assert(res, "just checking");
00193 
00194   return res;
00195 }
00196 
00197 void ResourceAreaChunk::freeTo(char *new_first_free) {
00198   assert(new_first_free <= first_free, "unfreeing in resource area");
00199   if (ZapResourceArea) clear(new_first_free, first_free);
00200   first_free= new_first_free;
00201 }
00202 
00203 Resources::Resources() {
00204  _allocated           = 0;
00205  _in_consistent_state = true;
00206 }
00207 
00208 bool ResourceMark::enabled = true;
00209 
00210 ResourceMark::ResourceMark() {
00211   if (!enabled) return;
00212   area  = &resource_area;
00213   chunk = area->chunk;
00214   top   = chunk ? chunk->first_free : NULL;
00215 # ifdef ASSERT
00216   area->nesting++;
00217   assert(area->nesting > 0, "nesting must be positive");
00218 # endif
00219 }
00220 
00221 
00222 ResourceMark::~ResourceMark() {
00223   if (!enabled) return;
00224 # ifdef ASSERT
00225   assert(area->nesting > 0, "nesting must be positive");
00226   area->nesting--;
00227 # endif
00228   if (PrintResourceAllocation) {
00229     lprintf("deallocating to mark %#lx\n", top);
00230   }
00231   ResourceAreaChunk* prevc;
00232   for (ResourceAreaChunk* c = area->chunk; c != chunk; c = prevc) {
00233     // deallocate all chunks behind marked chunk
00234     prevc = c->prev;
00235     resources.addToFreeList(c);
00236   }
00237   area->chunk = c;
00238   if (c == NULL) {
00239     top = NULL;
00240     return;
00241   }
00242   c->freeTo(top); 
00243   if (top == c->bottom) {
00244     // this chunk is completely unused - deallocate it
00245     area->chunk = c->prev;
00246     resources.addToFreeList(c);
00247   }
00248 }
00249 
00250 FinalResourceMark::FinalResourceMark() {
00251   enabled = false;
00252 }
00253 
00254 FinalResourceMark::~FinalResourceMark() {
00255   enabled = true;
00256 }
00257 
00258 
00259 NoGCVerifier::NoGCVerifier() {
00260   old_scavenge_count = Universe::scavengeCount;
00261 }
00262 
00263 
00264 NoGCVerifier::~NoGCVerifier() {
00265   if (old_scavenge_count != Universe::scavengeCount) {
00266     warning("scavenge in a NoGCVerifier secured function");
00267   }
00268 }
00269 
00270 char *align(void* p, int alignment) {
00271   int number = (int) p;
00272   int adjust =  alignment - (number%alignment) % alignment;
00273   return (char*) number + adjust;
00274 }
00275 
00276 char* AllocatePageAligned(int size, char* name) {
00277   int page_size = Universe::page_size();
00278   char* block = align(malloc(size + page_size), page_size);
00279   if (PrintHeapAllocation)
00280     lprintf("Malloc (page-aligned) %s: %d = %#lx\n", name, size, block);
00281   return block;
00282 }
00283 
00284 char* AllocateHeap(int size, char* name) {
00285   if (PrintHeapAllocation) lprintf("Heap %7d %s\n", size, name);
00286   return (char*) malloc(size);
00287 }
00288 
00289 void FreeHeap(void* p) {
00290   free(p);
00291 }
00292 
00293 // The global operator new should never be called since it will usually indicate
00294 // a memory leak.  Use CHeapObj as the base class of such objects to make it explicit
00295 // that they're allocated on the C heap.
00296 void* operator new(size_t size){
00297   fatal("should not call global (default) operator new");
00298   return (void *) AllocateHeap(size, "global operator new");
00299 }

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