00001 /*! 00002 * @file heap_bimodal.c 00003 * 00004 * @brief @b bimodal heap management functions 00005 * 00006 * This is the second of two implementations of heap management. 00007 * It extends the simple malloc/free scheme by adding a single 00008 * large allocation for requests smaller tha a certain size. 00009 * This was added due to an apparent internal limit in @c @b malloc(3) 00010 * or perhaps a kernel limit that after a certain number of 00011 * calls and/or bytes of allocation and freeing, returns NULL 00012 * for no apparent reason. 00013 * 00014 * The common header file @link jvm/src/heap.h gc.h@endlink defines 00015 * the prototypes for all heap allocation implementations by way 00016 * of the @link #CONFIG_HEAP_TYPE_SIMPLE CONFIG_HEAP_TYPE_xxx@endlink 00017 * symbol definitions. 00018 * 00019 * 00020 * Here is a note taken from the original project 00021 * @link ./README README@endlink file: 00022 * 00023 * <i>(16) When nearing the end of the initial development, I ran 00024 * across what is probably a memory configuration limit on my 00025 * Solaris platform, which I did not bother to track down, but 00026 * rather work around. It seems that when calling malloc(3C) or 00027 * malloc(3MALLOC), after 2,280 malloc() allocations and 612 free() 00028 * invocations, there is something under the covers that does a 00029 * @b SIGSEGV, and it can happen in either routine. I therefore 00030 * extended the heap mechanism to allocate 1M slots of 'n' bytes 00031 * for small allocations up to this size. Everything else still 00032 * uses malloc(). In this way, I was able to finish development 00033 * on the JVM and release it to the ASF in a more timely manner. 00034 * In other words, I will let the team fix it! I am not sure that 00035 * the real project wants a static 'n + 1' MB data area just 00036 * hanging around the runtime just because I did not take time to 00037 * tune the system configuration!</i> 00038 * 00039 * This modified algorithm makes exactly two @b malloc() calls, one for 00040 * an array of fixed size slots of (@link #rbyte rbyte@endlink) 00041 * and the other for an array of (@link #rboolean rboolean@endlink) 00042 * for @link #rtrue rtrue@endlink/@link #rfalse rfalse@endlink on 00043 * whether a fixed-size memory slot is in use or not. 00044 * 00045 * 00046 * @section Control 00047 * 00048 * \$URL: https://svn.apache.org/path/name/heap_bimodal.c $ \$Id: heap_bimodal.c 0 09/28/2005 dlydick $ 00049 * 00050 * Copyright 2005 The Apache Software Foundation 00051 * or its licensors, as applicable. 00052 * 00053 * Licensed under the Apache License, Version 2.0 ("the License"); 00054 * you may not use this file except in compliance with the License. 00055 * You may obtain a copy of the License at 00056 * 00057 * http://www.apache.org/licenses/LICENSE-2.0 00058 * 00059 * Unless required by applicable law or agreed to in writing, 00060 * software distributed under the License is distributed on an 00061 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 00062 * either express or implied. 00063 * 00064 * See the License for the specific language governing permissions 00065 * and limitations under the License. 00066 * 00067 * @version \$LastChangedRevision: 0 $ 00068 * 00069 * @date \$LastChangedDate: 09/28/2005 $ 00070 * 00071 * @author \$LastChangedBy: dlydick $ 00072 * Original code contributed by Daniel Lydick on 09/28/2005. 00073 * 00074 * @section Reference 00075 * 00076 */ 00077 00078 #include "arch.h" 00079 ARCH_COPYRIGHT_APACHE(heap_bimodal, c, "$URL: https://svn.apache.org/path/name/heap_bimodal.c $ $Id: heap_bimodal.c 0 09/28/2005 dlydick $"); 00080 00081 #if defined(CONFIG_HEAP_TYPE_BIMODAL) || defined(CONFIG_COMPILE_ALL_OPTIONS) 00082 00083 00084 #include <errno.h> 00085 #include <stdlib.h> 00086 00087 #include "jvmcfg.h" 00088 #include "exit.h" 00089 #include "gc.h" 00090 #include "heap.h" 00091 #include "jvmclass.h" 00092 #include "util.h" 00093 00094 00095 /*! 00096 * @brief Small heap allocation area. 00097 * 00098 * For allocations up to @b n bytes, use this instead of system 00099 * allocation and thus minimize number of calls to @b malloc() 00100 * and @b free(). After 2,280 calls to @b malloc(3C) and 612 to 00101 * @b free(3C), the library would kick out a @b SIGSEGV for no apparent 00102 * reason. Use of @b malloc(3MALLOC) and @b free(3MALLOC) did 00103 * the same thing, with @b -lmalloc. Use of @b -lbsdmalloc was 00104 * at an even lower number. Therefore, it seems best to delay the 00105 * issue (See quotation above from @link ./README README@endlink file.) 00106 * 00107 * The value of the @link #HEAP_SLOT_SIZE HEAP_SLOT_SIZE@endlink 00108 * definition <b>ABSOLUTELY MUST BE A MULTIPLE of 4!!! </b> 00109 * (prefer 8 for future 64-bit implementation). This is 00110 * <b><code>sizeof(rvoid *)</code></b> and must be such to always 00111 * fundamentally avoid @b SIGSEGV on 4-byte accesses. 00112 */ 00113 #define HEAP_SLOT_SIZE 160 00114 00115 /*! 00116 * @brief Number of slots of this size. 00117 * 00118 * Any number of slots is possible, up to the reasonable 00119 * resource limits of the machine. 00120 */ 00121 #define HEAP_NUMBER_OF_SLOTS 1048576 00122 00123 00124 /*! 00125 * @brief Pointer for physical allocation for slots in use. 00126 */ 00127 static rboolean *pheap_slot_in_use; 00128 00129 /*! 00130 * @brief Pointer for physical allocation of heap block to manage. 00131 */ 00132 static rbyte *pheap_slot; 00133 00134 /*! 00135 * @brief Start up heap management methodology. 00136 * 00137 * In a malloc/free scheme, there is nothing 00138 * to do, but here, the two blocks @link #pheap_slot_in_use@endlink 00139 * and @link #pheap_slot pheap_slot@endlink must be allocated and 00140 * initialized. 00141 * 00142 * 00143 * @b Parameters: @link #rvoid rvoid@endlink 00144 * 00145 * 00146 * @return @link #rvoid rvoid@endlink 00147 * 00148 */ 00149 rvoid heap_init_bimodal() 00150 { 00151 rlong heapidx; 00152 00153 /* Set up slot flags */ 00154 pheap_slot_in_use = 00155 malloc(sizeof(rboolean) * HEAP_NUMBER_OF_SLOTS); 00156 00157 if (rnull == pheap_slot_in_use) 00158 { 00159 sysErrMsg("heap_init", "Cannot allocate slot flag storage"); 00160 exit_jvm(EXIT_HEAP_ALLOC); 00161 /*NOTREACHED*/ 00162 } 00163 00164 /* Initialize flag array to @link #rfalse rfalse@endlink */ 00165 for (heapidx = 0; 00166 heapidx < HEAP_NUMBER_OF_SLOTS; 00167 heapidx++) 00168 { 00169 pheap_slot_in_use[heapidx] = rfalse; 00170 } 00171 00172 00173 /* Set up slot storage itself, do not need to initialize */ 00174 pheap_slot = 00175 malloc(sizeof(rbyte) * 00176 HEAP_SLOT_SIZE * 00177 HEAP_NUMBER_OF_SLOTS); 00178 00179 if (rnull == pheap_slot) 00180 { 00181 free(pheap_slot_in_use); 00182 00183 sysErrMsg("heap_init", "Cannot allocate slot storage"); 00184 exit_jvm(EXIT_HEAP_ALLOC); 00185 /*NOTREACHED*/ 00186 } 00187 00188 /* Declare this module initialized */ 00189 jvm_heap_initialized = rtrue; 00190 00191 return; 00192 00193 } /* END of heap_init_bimodal() */ 00194 00195 00196 /*! 00197 * @brief Most recent error code from @c @b malloc(3), for use 00198 * by heap_get_error_bimodal(). 00199 */ 00200 static int heap_last_errno = ERROR0; 00201 00202 00203 /*! 00204 * @brief Number of calls to @c @b malloc(3). 00205 * 00206 * One of four global variables providing rudimentary statistics 00207 * for heap allocation history. 00208 * 00209 * @see heap_free_count 00210 * @see malloc_free_count 00211 * @see slot_free_count 00212 */ 00213 static rlong heap_malloc_count = 0; 00214 00215 /*! 00216 * @brief Number of calls to @c @b free(3). 00217 * 00218 * One of four global variables providing rudimentary statistics 00219 * for heap allocation history. 00220 * 00221 * @see heap_malloc_count 00222 * @see malloc_free_count 00223 * @see slot_free_count 00224 */ 00225 static rlong heap_free_count = 0; 00226 00227 /*! 00228 * @brief Number of allocations made from pheap_slot. 00229 * 00230 * One of four global variables providing rudimentary statistics 00231 * for heap allocation history. 00232 * 00233 * @see heap_malloc_count 00234 * @see heap_free_count 00235 * @see slot_free_count 00236 */ 00237 static rlong slot_alloc_count = 0; 00238 00239 /*! 00240 * @brief Number of allocations freed from pheap_slot. 00241 * 00242 * One of four global variables providing rudimentary statistics 00243 * for heap allocation history. 00244 * 00245 * @see heap_malloc_count 00246 * @see heap_free_count 00247 * @see slot_malloc_count 00248 */ 00249 static rlong slot_free_count = 0; 00250 00251 00252 /*! 00253 * @brief Original heap allocation method that uses 00254 * @e only @c @b malloc(3) and @c @b free(3). 00255 * 00256 * 00257 * @param size Number of bytes to allocate 00258 * 00259 * @param clrmem_flag Set memory to all zeroes 00260 * (@link #rtrue rtrue@endlink) or not 00261 * (@link #rfalse rfalse@endlink). 00262 * If @link #rtrue rtrue@endlink, 00263 * clear the allocated block, otherwise 00264 * return it with its existing contents. 00265 * 00266 * 00267 * @return (@link #rvoid rvoid@endlink *) to allocated area. 00268 * This pointer may be cast to any desired data type. If 00269 * size of zero bytes is requested, return 00270 * @link #rnull rnull@endlink and let caller croak 00271 * on @b SIGSEGV. If no memory is available 00272 * or some OS system call error happened, throw error, 00273 * but do @e not return. 00274 * 00275 * 00276 * @throws JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00277 * @link #JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00278 * if no memory is available@endlink. 00279 * 00280 * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 00281 @link #JVMCLASS_JAVA_LANG_INTERNALERROR 00282 * if other allocation error@endlink. 00283 * 00284 */ 00285 static rvoid *heap_get_common_simple_bimodal(int size, 00286 rboolean clrmem_flag) 00287 { 00288 rvoid *rc; 00289 00290 rc = malloc(size); 00291 00292 /* 00293 * If specific errors are returned, GC could free up some heap, 00294 * so run it and try again-- ONCE. If it fails a second time, 00295 * so be it. Let the application deal with the problem. 00296 */ 00297 if (rnull == rc) 00298 { 00299 switch(errno) 00300 { 00301 case ENOMEM: 00302 case EAGAIN: 00303 GC_RUN(rtrue); 00304 rc = malloc(size); 00305 00306 if (rnull == rc) 00307 { 00308 switch(errno) 00309 { 00310 case ENOMEM: 00311 case EAGAIN: 00312 exit_throw_exception(EXIT_HEAP_ALLOC, 00313 JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR); 00314 /*NOTREACHED*/ 00315 default: 00316 /* 00317 * Preserve errno for later inspection. 00318 * By doing it this way, other OS system 00319 * calls will not interfere with its value 00320 * and it can be inspected at leisure. 00321 */ 00322 heap_last_errno = errno; 00323 00324 exit_throw_exception(EXIT_HEAP_ALLOC, 00325 JVMCLASS_JAVA_LANG_INTERNALERROR); 00326 /*NOTREACHED*/ 00327 } 00328 } 00329 break; 00330 00331 default: 00332 /* 00333 * Preserve errno for later inspection. 00334 * By doing it this way, other OS system 00335 * calls will not interfere with its value 00336 * and it can be inspected at leisure. 00337 */ 00338 heap_last_errno = errno; 00339 00340 exit_throw_exception(EXIT_HEAP_ALLOC, 00341 JVMCLASS_JAVA_LANG_INTERNALERROR); 00342 /*NOTREACHED*/ 00343 } 00344 } 00345 00346 /* Clear block if requested */ 00347 if (rtrue == clrmem_flag) 00348 { 00349 rbyte *pb = (rbyte *) rc; 00350 00351 int i; 00352 for (i = 0; i < size; i++) 00353 { 00354 pb[i] = '\0'; 00355 } 00356 } 00357 00358 heap_malloc_count++; 00359 00360 return(rc); 00361 00362 } /* END of heap_get_common_simple_bimodal() */ 00363 00364 00365 /*! 00366 * @brief Allocate memory from heap to caller, judging which mode 00367 * to use for allocation. 00368 * 00369 * When finished, this pointer should be sent back to 00370 * @link #heap_free_data_bimodal() heap_free_xxxx_bimodal()@endlink 00371 * for reallocation. 00372 * 00373 * @warning Much of the JVM initialization ABSOLUTELY DEPENDS on 00374 * setting of the @b clrmem_flag value to 00375 * @link #rtrue rtrue@endlink so that allocated 00376 * structures contain all zeroes. If the heap 00377 * allocation scheme changes, this functionality needs 00378 * to be brought forward or change much of the code, not 00379 * only init code, but throughout the whole corpus. 00380 * 00381 * @remarks If @c @b malloc(3) returns an error other than out of 00382 * memory errors, then the system @b errno is saved out 00383 * into @link #heap_last_errno heap_last_errno@endlink 00384 * for retrieval by @c @b perror(3) or other user response. 00385 * This is typically useful for system-level debugging 00386 * when the OS or OS resources, security, etc., may be 00387 * getting in the way of proper allocation. 00388 * 00389 * 00390 * @param size Number of bytes to allocate 00391 * 00392 * @param clrmem_flag Set memory to all zeroes 00393 * (@link #rtrue rtrue@endlink) or 00394 * not (@link #rfalse rfalse@endlink). 00395 * If @link #rtrue rtrue@endlink, 00396 * clear the allocated block, otherwise 00397 * return it with its existing contents. 00398 * 00399 * 00400 * @return (@link #rvoid rvoid@endlink *) to allocated area. 00401 * This pointer may be cast to any desired data type. If 00402 * size of zero bytes is requested, return 00403 * @link #rnull rnull@endlink and let caller croak 00404 * on @b SIGSEGV. If no memory is available 00405 * or some OS system call error happened, throw error, 00406 * but do @e not return. 00407 * 00408 * 00409 * @throws JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00410 * @link #JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00411 * if no memory is available@endlink. 00412 * 00413 * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 00414 @link #JVMCLASS_JAVA_LANG_INTERNALERROR 00415 * if other allocation error@endlink. 00416 * 00417 */ 00418 static rvoid *heap_get_common_bimodal(int size, rboolean clrmem_flag) 00419 { 00420 rvoid *rc; /* Separate LOCATE_SLOT calc. from return() for debug */ 00421 rc = (rvoid *) rnull; 00422 00423 /* 00424 * Return rnull pointer when zero size requested. 00425 * Let caller fix that problem. 00426 */ 00427 if (0 == size) 00428 { 00429 return((rvoid *) rnull); 00430 } 00431 00432 errno = ERROR0; /* Clear out error code before calling */ 00433 00434 00435 /* Use pre-allocated area for small requests */ 00436 if (HEAP_SLOT_SIZE >= size) 00437 { 00438 /* Mark last allocated-- faster than always starting at 0 */ 00439 static rlong heapidxLAST = HEAP_NUMBER_OF_SLOTS - 1; 00440 00441 rlong heapidx; /* Just in case of large number of slots */ 00442 rlong count; 00443 00444 /* Scan flag array for first open slot */ 00445 00446 /* Study heap twice, before and after GC,and use same code*/ 00447 #define LOCATE_SLOT \ 00448 \ 00449 for (count = 0, heapidx = 1 + heapidxLAST; \ 00450 count < HEAP_NUMBER_OF_SLOTS; \ 00451 count++, heapidx++) \ 00452 { \ 00453 /* Wrap around last allocation to beginning */ \ 00454 if (HEAP_NUMBER_OF_SLOTS == heapidx) \ 00455 { \ 00456 heapidx = 0; \ 00457 } \ 00458 \ 00459 if (rfalse == pheap_slot_in_use[heapidx]) \ 00460 { \ 00461 /* Reserve a slot, return its data area pointer */ \ 00462 pheap_slot_in_use[heapidx] = rtrue; \ 00463 \ 00464 /* Also report which slot was last allocated */ \ 00465 heapidxLAST = heapidx; \ 00466 \ 00467 /* Count slot allocations */ \ 00468 slot_alloc_count++; \ 00469 \ 00470 rc = (rvoid *) \ 00471 &pheap_slot[heapidx * \ 00472 sizeof(rbyte) * \ 00473 HEAP_SLOT_SIZE]; \ 00474 /* Clear block if requested */ \ 00475 if (rtrue == clrmem_flag) \ 00476 { \ 00477 rbyte *pb = (rbyte *) rc; \ 00478 \ 00479 rint i; \ 00480 for (i = 0; i < size; i++) \ 00481 { \ 00482 pb[i] = '\0'; \ 00483 } \ 00484 } \ 00485 break; \ 00486 } \ 00487 } 00488 00489 LOCATE_SLOT; 00490 if (rnull != rc) 00491 { 00492 return(rc); 00493 } 00494 00495 /* If could not allocate, do one retry after GC */ 00496 GC_RUN(rtrue); 00497 00498 /* Scan flag array a second time for first open slot */ 00499 00500 LOCATE_SLOT; 00501 00502 if (rnull != rc) 00503 { 00504 return(rc); 00505 } 00506 00507 /* Sorry, nothing available, throw error */ 00508 00509 heap_last_errno = ERROR0; /* No OS error */ 00510 00511 exit_throw_exception(EXIT_HEAP_ALLOC, 00512 JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR); 00513 } 00514 else 00515 { 00516 return(heap_get_common_simple_bimodal(size, clrmem_flag)); 00517 } 00518 /*NOTREACHED*/ 00519 return((rvoid *) rnull); /* Satisfy compiler */ 00520 00521 } /* END of heap_get_common_bimodal() */ 00522 00523 00524 /*! 00525 * @brief Allocate memory for a @b method from heap to caller. 00526 * 00527 * When finished, this pointer should be sent back to 00528 * @link #heap_free_method_bimodal() heap_free_method_bimodal()@endlink 00529 * for reallocation. 00530 * 00531 * @remarks This implementation makes no distinction betwen 00532 * "method area heap" and any other usage. Other 00533 * implementations may choose to implement the 00534 * JVM Spec section 3.5.4 more rigorously. 00535 * 00536 * 00537 * @param size Number of bytes to allocate 00538 * 00539 * @param clrmem_flag Set memory to all zeroes 00540 * (@link #rtrue rtrue@endlink) or 00541 * not (@link #rfalse rfalse@endlink) 00542 * 00543 * 00544 * @return (@link #rvoid rvoid@endlink *) to allocated area. 00545 * This pointer may be cast to any desired data type. If 00546 * size of zero bytes is requested, return 00547 * @link #rnull rnull@endlink and let 00548 * caller croak on @b SIGSEGV. If no memory is available 00549 * or some OS system call error happened, throw error, 00550 * but do @e not return. 00551 * 00552 * 00553 * @throws JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00554 * @link #JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00555 * if no memory is available@endlink. 00556 * 00557 * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 00558 @link #JVMCLASS_JAVA_LANG_INTERNALERROR 00559 * if other allocation error@endlink. 00560 * 00561 */ 00562 rvoid *heap_get_method_bimodal(int size, rboolean clrmem_flag) 00563 { 00564 return(heap_get_common_bimodal(size, clrmem_flag)); 00565 00566 } /* END of heap_get_method_bimodal() */ 00567 00568 00569 /*! 00570 * @brief Allocate memory for a @b stack area from heap to caller. 00571 * 00572 * When finished, this pointer should be sent back 00573 * to @link #heap_free_stack_bimodal() heap_free_stack_bimodal()@endlink 00574 * for reallocation. 00575 * 00576 * 00577 * @param size Number of bytes to allocate 00578 * 00579 * @param clrmem_flag Set memory to all zeroes 00580 * (@link #rtrue rtrue@endlink) or 00581 * not (@link #rfalse rfalse@endlink) 00582 * 00583 * 00584 * @return (@link #rvoid rvoid@endlink *) to allocated area. 00585 * This pointer may be cast to any desired data type. If 00586 * size of zero bytes is requested, return 00587 * @link #rnull rnull@endlink and let 00588 * caller croak on @b SIGSEGV. If no memory is available 00589 * or some OS system call error happened, throw error, 00590 * but do @e not return. 00591 * 00592 * 00593 * @throws JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00594 * @link #JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00595 * if no memory is available@endlink. 00596 * 00597 * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 00598 @link #JVMCLASS_JAVA_LANG_INTERNALERROR 00599 * if other allocation error@endlink. 00600 * 00601 * 00602 * 00603 */ 00604 rvoid *heap_get_stack_bimodal(int size, rboolean clrmem_flag) 00605 { 00606 return(heap_get_common_bimodal(size, clrmem_flag)); 00607 00608 } /* END of heap_get_stack_bimodal() */ 00609 00610 00611 /*! 00612 * @brief Allocate memory for a @b data area from heap to caller. 00613 * 00614 * When finished, this pointer should be sent back 00615 * to @link #heap_free_data_bimodal() heap_free_data_bimodal()@endlink 00616 * for reallocation. 00617 * 00618 * 00619 * @param size Number of bytes to allocate 00620 * 00621 * @param clrmem_flag Set memory to all zeroes 00622 * (@link #rtrue rtrue@endlink) or 00623 * not (@link #rfalse rfalse@endlink) 00624 * 00625 * 00626 * @return (@link #rvoid rvoid@endlink *) to allocated area. 00627 * This pointer may be cast to any desired data type. If 00628 * size of zero bytes is requested, return 00629 * @link #rnull rnull@endlink and let 00630 * caller croak on @b SIGSEGV. If no memory is available 00631 * or some OS system call error happened, throw error, 00632 * but do @e not return. 00633 * 00634 * 00635 * @throws JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00636 * @link #JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00637 * if no memory is available@endlink. 00638 * 00639 * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 00640 @link #JVMCLASS_JAVA_LANG_INTERNALERROR 00641 * if other allocation error@endlink. 00642 * 00643 * 00644 * 00645 */ 00646 rvoid *heap_get_data_bimodal(int size, rboolean clrmem_flag) 00647 { 00648 return(heap_get_common_bimodal(size, clrmem_flag)); 00649 00650 } /* END of heap_get_data_bimodal() */ 00651 00652 00653 /*********************************************************************/ 00654 /*! 00655 * @brief Release a previously allocated block back into the heap for 00656 * future reallocation. 00657 * 00658 * If a @link #rnull rnull@endlink pointer is passed in, ignore 00659 * the request. 00660 * 00661 * 00662 * @param pheap_block An (@link #rvoid rvoid@endlink *) previously 00663 * returned by one of the 00664 * @link #heap_get_data_bimodal() 00665 heap_get_XXX_bimodal()@endlink functions. 00666 * 00667 * 00668 * @return @link #rvoid rvoid@endlink 00669 * 00670 * 00671 */ 00672 static rvoid heap_free_common_bimodal(rvoid *pheap_block) 00673 { 00674 /* Ignore @link #rnull rnull@endlink pointer */ 00675 if (rnull != pheap_block) 00676 { 00677 /* 00678 * Free pre-allocated area from deallocation of 00679 * small requests, all of which were allocated 00680 * in this block 00681 */ 00682 if ((((rbyte *) &pheap_slot[0]) <= ((rbyte *) pheap_block)) 00683 && 00684 (((rbyte *) 00685 &pheap_slot[sizeof(rbyte) * 00686 HEAP_SLOT_SIZE * 00687 HEAP_NUMBER_OF_SLOTS]) > 00688 ((rbyte *) pheap_block))) 00689 { 00690 rlong heapidx = 00691 (((rbyte *) pheap_block) - &pheap_slot[0]) / 00692 HEAP_SLOT_SIZE; 00693 00694 pheap_slot_in_use[heapidx] = rfalse; 00695 00696 /* Count slots freed */ 00697 slot_free_count++; 00698 00699 return; 00700 } 00701 else 00702 { 00703 /* Free larger requests */ 00704 heap_free_count++; 00705 00706 free(pheap_block); 00707 00708 return; 00709 } 00710 } 00711 00712 return; 00713 00714 } /* END of heap_free_common_bimodal() */ 00715 00716 00717 /*! 00718 * @brief Release a previously allocated @b method block back into 00719 * the heap for future reallocation. 00720 * 00721 * @remarks This implementation makes no distinction between 00722 * <b>method area heap</b> and any other usage. Other 00723 * implementations may choose to implement the 00724 * JVM Spec section 3.5.4 more rigorously. 00725 * 00726 * 00727 * @param pheap_block An (@link #rvoid rvoid@endlink *) previously 00728 * returned by @link #heap_get_method_bimodal() 00729 heap_get_method_bimodal()@endlink 00730 * 00731 * 00732 * @return @link #rvoid rvoid@endlink 00733 * 00734 */ 00735 rvoid heap_free_method_bimodal(rvoid *pheap_block) 00736 { 00737 heap_free_common_bimodal(pheap_block); 00738 00739 } /* END of heap_free_method_bimodal() */ 00740 00741 00742 /*! 00743 * @brief Release a previously allocated @b stack block back into 00744 * the heap for future reallocation. 00745 * 00746 * 00747 * @param pheap_block An (@link #rvoid rvoid@endlink *) previously 00748 * returned by @link #heap_get_stack_bimodal() 00749 heap_get_stack_bimodal()@endlink 00750 * 00751 * 00752 * @return @link #rvoid rvoid@endlink 00753 * 00754 */ 00755 rvoid heap_free_stack_bimodal(rvoid *pheap_block) 00756 { 00757 heap_free_common_bimodal(pheap_block); 00758 00759 } /* END of heap_free_stack_bimodal() */ 00760 00761 00762 /*! 00763 * @brief Release a previously allocated @b data block back 00764 * into the heap for future reallocation. 00765 * 00766 * 00767 * @param pheap_block An (@link #rvoid rvoid@endlink *) previously 00768 * returned by @link #heap_get_data_bimodal() 00769 heap_get_data_bimodal()@endlink 00770 * 00771 * 00772 * @return @link #rvoid rvoid@endlink 00773 * 00774 */ 00775 rvoid heap_free_data_bimodal(rvoid *pheap_block) 00776 { 00777 heap_free_common_bimodal(pheap_block); 00778 00779 } /* END of heap_free_data_bimodal() */ 00780 00781 00782 /*! 00783 * @brief Allocation failure diagnostic. 00784 * 00785 * Returns an @b errno value per @b "errno.h" if a 00786 * @link #rnull rnull@endlink pointer 00787 * is passed in, namely from the most recent call to a heap 00788 * allocation function. It may only be called once before the 00789 * value is cleared. If a non-null pointer is passed in, 00790 * @link #ERROR0 ERROR0@endlink is returned and the error status is 00791 * again cleared. 00792 * 00793 * 00794 * @param badptr Return value from heap allocation function. 00795 * 00796 * 00797 * @returns @link #ERROR0 ERROR0@endlink when no error was found 00798 * or non-null @b badptr given. 00799 * @link #heap_last_errno heap_last_errno@endlink 00800 * value otherwise. 00801 * 00802 */ 00803 int heap_get_error_bimodal(rvoid *badptr) 00804 { 00805 int rc; 00806 00807 if (rnull == badptr) 00808 { 00809 rc = heap_last_errno; 00810 heap_last_errno = ERROR0; 00811 return(rc); 00812 } 00813 else 00814 { 00815 heap_last_errno = ERROR0; 00816 00817 return(ERROR0); 00818 } 00819 00820 } /* END of heap_get_error_bimodal() */ 00821 00822 00823 /*! 00824 * @brief Shut down up heap management after JVM execution is finished. 00825 * 00826 * 00827 * @b Parameters: @link #rvoid rvoid@endlink 00828 * 00829 * 00830 * @return @link #rvoid rvoid@endlink 00831 * 00832 */ 00833 rvoid heap_shutdown_bimodal() 00834 { 00835 heap_last_errno = ERROR0; 00836 00837 /* Declare this module uninitialized */ 00838 jvm_heap_initialized = rfalse; 00839 00840 return; 00841 00842 } /* END of heap_shutdown_bimodal() */ 00843 00844 #endif /* CONFIG_HEAP_TYPE_BIMODAL || CONFIG_OPTIONS_COMPILE_ALL */ 00845 00846 00847 /* EOF */ 00848