00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
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
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
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
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
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
00294
00295
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 }