00001 /*! 00002 * @file heap_simple.c 00003 * 00004 * @brief @b simple heap management functions 00005 * 00006 * This is the first of probably several implementations of heap 00007 * management for this JVM implementation. It uses the simple 00008 * OS/stdlib resources of @c @b malloc(3)/free(3) as the foundation 00009 * for its management scheme. The memory allocation pointer is 00010 * generated by @c @b malloc(3). Calling @c @b free(3) with this 00011 * same pointer marks the block of memory as available for 00012 * other allocation. 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 * @section Control 00021 * 00022 * \$URL: https://svn.apache.org/path/name/heap_simple.c $ \$Id: heap_simple.c 0 09/28/2005 dlydick $ 00023 * 00024 * Copyright 2005 The Apache Software Foundation 00025 * or its licensors, as applicable. 00026 * 00027 * Licensed under the Apache License, Version 2.0 ("the License"); 00028 * you may not use this file except in compliance with the License. 00029 * You may obtain a copy of the License at 00030 * 00031 * http://www.apache.org/licenses/LICENSE-2.0 00032 * 00033 * Unless required by applicable law or agreed to in writing, 00034 * software distributed under the License is distributed on an 00035 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 00036 * either express or implied. 00037 * 00038 * See the License for the specific language governing permissions 00039 * and limitations under the License. 00040 * 00041 * @version \$LastChangedRevision: 0 $ 00042 * 00043 * @date \$LastChangedDate: 09/28/2005 $ 00044 * 00045 * @author \$LastChangedBy: dlydick $ 00046 * Original code contributed by Daniel Lydick on 09/28/2005. 00047 * 00048 * @section Reference 00049 * 00050 */ 00051 00052 #include "arch.h" 00053 ARCH_COPYRIGHT_APACHE(heap_simple, c, "$URL: https://svn.apache.org/path/name/heap_simple.c $ $Id: heap_simple.c 0 09/28/2005 dlydick $"); 00054 00055 #if defined(CONFIG_HEAP_TYPE_SIMPLE) || defined(CONFIG_COMPILE_ALL_OPTIONS) 00056 00057 #include <errno.h> 00058 #include <stdlib.h> 00059 00060 #include "jvmcfg.h" 00061 #include "exit.h" 00062 #include "gc.h" 00063 #include "heap.h" 00064 #include "jvmclass.h" 00065 #include "util.h" 00066 00067 00068 /*! 00069 * @brief Start up heap management methodology. 00070 * 00071 * In a @b malloc/free scheme, there is nothing 00072 * to do, but in other methods there might be. 00073 * 00074 * 00075 * @b Parameters: @link #rvoid rvoid@endlink 00076 * 00077 * 00078 * @returns @link #rvoid rvoid@endlink 00079 * 00080 */ 00081 rvoid heap_init_simple() 00082 { 00083 ; /* Nothing to do in this methodology */ 00084 00085 /* Declare this module initialized */ 00086 jvm_heap_initialized = rtrue; 00087 00088 return; 00089 00090 } /* END of heap_init_simple() */ 00091 00092 00093 /*! 00094 * @brief Most recent error code from @c @b malloc(3), for use 00095 * by heap_get_error_simple(). 00096 */ 00097 static int heap_last_errno = ERROR0; 00098 00099 00100 /*! 00101 * @brief Number of calls to @c @b malloc(3). 00102 * 00103 * One of two global variables providing rudimentary statistics 00104 * for heap allocation history. 00105 * 00106 * @see heap_free_count 00107 */ 00108 static rlong heap_malloc_count = 0; 00109 00110 /*! 00111 * @brief Number of calls to @c @b free(3). 00112 * 00113 * One of two global variables providing rudimentary statistics 00114 * for heap allocation history. 00115 * 00116 * @see heap_malloc_count 00117 */ 00118 static rlong heap_free_count = 0; 00119 00120 /*! 00121 * @brief Simple heap allocation method that uses only @c @b malloc(3) 00122 * and @c @b free(3). 00123 * 00124 * 00125 * @param size Number of bytes to allocate 00126 * 00127 * @param clrmem_flag Set memory to all zeroes 00128 * (@link #rtrue rtrue@endlink) or not 00129 * (@link #rfalse rfalse@endlink). 00130 * If @link #rtrue rtrue@endlink, clear the 00131 * allocated block, otherwise 00132 * return it with its existing contents. 00133 * 00134 * 00135 * @returns (@link #rvoid rvoid@endlink *) to allocated area. 00136 * This pointer may be cast to any desired data type. 00137 * If size of zero bytes is requested, return 00138 * @link #rnull rnull@endlink and let caller croak 00139 * on @b SIGSEGV. If no memory is available 00140 * or some OS system call error happened, throw error, but 00141 * do @e not return. 00142 * 00143 * 00144 * @throws JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00145 * @link #JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00146 * if no memory is available.@endlink. 00147 * 00148 * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 00149 @link #JVMCLASS_JAVA_LANG_INTERNALERROR 00150 * if other allocation error@endlink. 00151 * 00152 */ 00153 static rvoid *heap_get_common_simple(int size, rboolean clrmem_flag) 00154 { 00155 rvoid *rc; 00156 00157 rc = malloc(size); 00158 00159 /* 00160 * If specific errors are returned, GC could free up some heap, 00161 * so run it and try again-- ONCE. If it fails a second time, 00162 * so be it. Let the application deal with the problem. 00163 */ 00164 if (rnull == rc) 00165 { 00166 switch(errno) 00167 { 00168 case ENOMEM: 00169 case EAGAIN: 00170 GC_RUN(rtrue); 00171 rc = malloc(size); 00172 00173 if (rnull == rc) 00174 { 00175 switch(errno) 00176 { 00177 case ENOMEM: 00178 case EAGAIN: 00179 exit_throw_exception(EXIT_HEAP_ALLOC, 00180 JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR); 00181 /*NOTREACHED*/ 00182 default: 00183 /* 00184 * Preserve errno for later inspection. 00185 * By doing it this way, other OS system 00186 * calls will not interfere with its value 00187 * and it can be inspected at leisure. 00188 */ 00189 heap_last_errno = errno; 00190 00191 exit_throw_exception(EXIT_HEAP_ALLOC, 00192 JVMCLASS_JAVA_LANG_INTERNALERROR); 00193 /*NOTREACHED*/ 00194 } 00195 } 00196 break; 00197 00198 default: 00199 /* 00200 * Preserve errno for later inspection. 00201 * By doing it this way, other OS system 00202 * calls will not interfere with its value 00203 * and it can be inspected at leisure. 00204 */ 00205 heap_last_errno = errno; 00206 00207 exit_throw_exception(EXIT_HEAP_ALLOC, 00208 JVMCLASS_JAVA_LANG_INTERNALERROR); 00209 /*NOTREACHED*/ 00210 } 00211 } 00212 00213 /* Clear block if requested */ 00214 if (rtrue == clrmem_flag) 00215 { 00216 rbyte *pb = (rbyte *) rc; 00217 00218 int i; 00219 for (i = 0; i < size; i++) 00220 { 00221 pb[i] = '\0'; 00222 } 00223 } 00224 00225 heap_malloc_count++; 00226 00227 return(rc); 00228 00229 } /* END of heap_get_common_simple() */ 00230 00231 00232 /*! 00233 * @brief Allocate memory for a method from heap to caller. 00234 * 00235 * When finished, this pointer should be sent back 00236 * to @link #heap_free_method_simple() heap_free_method_simple()@endlink 00237 * for reallocation. 00238 * 00239 * @note This implementation makes no distinction betwen 00240 * <b>method area heap </b> and any other usage. Other 00241 * implementations may choose to implement the 00242 * JVM Spec section 3.5.4 more rigorously. 00243 * 00244 * 00245 * @param size Number of bytes to allocate 00246 * 00247 * @param clrmem_flag Set memory to all zeroes 00248 * (@link #rtrue rtrue@endlink) or 00249 * not (@link #rfalse rfalse@endlink) 00250 * 00251 * 00252 * @returns (@link #rvoid rvoid@endlink *) to allocated area. 00253 * This pointer may be cast to any desired data type. 00254 * If size of zero bytes is requested, return 00255 * @link #rnull rnull@endlink and 00256 * let caller croak on @b SIGSEGV. If no memory is available 00257 * or some OS system call error happened, throw error, but 00258 * do @e not return. 00259 * 00260 * 00261 * @throws JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00262 * @link #JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00263 * if no memory is available@endlink. 00264 * 00265 * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 00266 @link #JVMCLASS_JAVA_LANG_INTERNALERROR 00267 * if other allocation error@endlink. 00268 * 00269 */ 00270 rvoid *heap_get_method_simple(int size, rboolean clrmem_flag) 00271 { 00272 return(heap_get_common_simple(size, clrmem_flag)); 00273 00274 } /* END of heap_get_method_simple() */ 00275 00276 00277 /*! 00278 * @brief Allocate memory for a stack area from heap to caller. 00279 * 00280 * When finished, this pointer should be sent back 00281 * to @link #heap_free_stack_simple() heap_free_stack_simple()@endlink 00282 * for reallocation. 00283 * 00284 * 00285 * @param size Number of bytes to allocate 00286 * 00287 * @param clrmem_flag Set memory to all zeroes 00288 * (@link #rtrue rtrue@endlink) or 00289 * not (@link #rfalse rfalse@endlink) 00290 * 00291 * 00292 * @returns (@link #rvoid rvoid@endlink *) to allocated area. 00293 * This pointer may be cast to any desired data type. 00294 * If size of zero bytes is requested, return 00295 * @link #rnull rnull@endlink and 00296 * let caller croak on @b SIGSEGV. If no memory is available 00297 * or some OS system call error happened, throw error, but 00298 * do @e not return. 00299 * 00300 * 00301 * @throws JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00302 * @link #JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00303 * if no memory is available@endlink. 00304 * 00305 * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 00306 @link #JVMCLASS_JAVA_LANG_INTERNALERROR 00307 * if other allocation error@endlink. 00308 * 00309 * 00310 * 00311 */ 00312 rvoid *heap_get_stack_simple(int size, rboolean clrmem_flag) 00313 { 00314 return(heap_get_common_simple(size, clrmem_flag)); 00315 00316 } /* END of heap_get_stack_simple() */ 00317 00318 00319 /*! 00320 * @brief Allocate memory for a data area from heap to caller. 00321 * 00322 * When finished, this pointer should be sent back 00323 * to @link #heap_free_data_simple() heap_free_data_simple()@endlink 00324 * for reallocation. 00325 * 00326 * 00327 * @param size Number of bytes to allocate 00328 * 00329 * @param clrmem_flag Set memory to all zeroes 00330 * (@link #rtrue rtrue@endlink) or 00331 * not (@link #rfalse rfalse@endlink) 00332 * 00333 * 00334 * @returns (@link #rvoid rvoid@endlink *) to allocated area. 00335 * This pointer may be cast to any desired data type. 00336 * If size of zero bytes is requested, return 00337 * @link #rnull rnull@endlink and 00338 * let caller croak on @b SIGSEGV. If no memory is available 00339 * or some OS system call error happened, throw error, but 00340 * do @e not return. 00341 * 00342 * 00343 * @throws JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00344 * @link #JVMCLASS_JAVA_LANG_OUTOFMEMORYERROR 00345 * if no memory is available@endlink. 00346 * 00347 * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 00348 @link #JVMCLASS_JAVA_LANG_INTERNALERROR 00349 * if other allocation error@endlink. 00350 * 00351 * 00352 * 00353 */ 00354 rvoid *heap_get_data_simple(int size, rboolean clrmem_flag) 00355 { 00356 return(heap_get_common_simple(size, clrmem_flag)); 00357 00358 } /* END of heap_get_data_simple() */ 00359 00360 00361 /*********************************************************************/ 00362 /*! 00363 * @brief Release a previously allocated block back into the heap for 00364 * future reallocation. 00365 * 00366 * If a @link #rnull rnull@endlink pointer is passed in, ignore 00367 * the request. 00368 * 00369 * 00370 * @param pheap_block An (@link #rvoid rvoid@endlink *) previously 00371 * returned by one of the 00372 @link #heap_get_data_simple() 00373 heap_get_XXX_simple()@endlink 00374 * functions. 00375 * 00376 * 00377 * @returns @link #rvoid rvoid@endlink 00378 * 00379 * 00380 */ 00381 static rvoid heap_free_common_simple(rvoid *pheap_block) 00382 { 00383 /* Ignore @link #rnull rnull@endlink pointer */ 00384 if (rnull != pheap_block) 00385 { 00386 /* Free larger requests */ 00387 heap_free_count++; 00388 00389 free(pheap_block); 00390 } 00391 00392 return; 00393 00394 } /* END of heap_free_common_simple() */ 00395 00396 00397 /*! 00398 * @brief Release a previously allocated @b method block back into 00399 * the heap for future reallocation. 00400 * 00401 * @note This implementation makes no distinction betwen 00402 * <b>method area heap</b> and any other usage. Other 00403 * implementations may choose to implement the 00404 * JVM Spec section 3.5.4 more rigorously. 00405 * 00406 * 00407 * @param pheap_block An (@link #rvoid rvoid@endlink *) previously 00408 * returned by 00409 * @link #heap_get_method_simple() 00410 heap_get_method_simple()@endlink 00411 * 00412 * 00413 * @returns @link #rvoid rvoid@endlink 00414 * 00415 */ 00416 rvoid heap_free_method_simple(rvoid *pheap_block) 00417 { 00418 heap_free_common_simple(pheap_block); 00419 00420 } /* END of heap_free_method_simple() */ 00421 00422 00423 /*! 00424 * @brief Release a previously allocated @b stack block back into 00425 * the heap for future reallocation. 00426 * 00427 * 00428 * @param pheap_block An (@link #rvoid rvoid@endlink *) previously 00429 * returned by 00430 * @link #heap_get_stack_simple() 00431 heap_get_stack_simple()@endlink 00432 * 00433 * 00434 * @returns @link #rvoid rvoid@endlink 00435 * 00436 */ 00437 rvoid heap_free_stack_simple(rvoid *pheap_block) 00438 { 00439 heap_free_common_simple(pheap_block); 00440 00441 } /* END of heap_free_stack_simple() */ 00442 00443 00444 /*! 00445 * @brief Release a previously allocated @b data block back 00446 * into the heap for future reallocation. 00447 * 00448 * 00449 * @param pheap_block An (@link #rvoid rvoid@endlink *) previously 00450 * returned by 00451 * @link #heap_get_data_simple() 00452 heap_get_data_simple()@endlink 00453 * 00454 * 00455 * @returns @link #rvoid rvoid@endlink 00456 * 00457 */ 00458 rvoid heap_free_data_simple(rvoid *pheap_block) 00459 { 00460 heap_free_common_simple(pheap_block); 00461 00462 } /* END of heap_free_data_simple() */ 00463 00464 00465 /*! 00466 * @brief Allocation failure diagnostic. 00467 * 00468 * Returns an @b errno value per @b "errno.h" if a 00469 * @link #rnull rnull@endlink pointer 00470 * is passed in, namely from the most recent call to a heap 00471 * allocation function. It may only be called once before the 00472 * value is cleared. If a non-null pointer is passed in, 00473 * @link #ERROR0 ERROR0@endlink is returned and the error status is 00474 * again cleared. 00475 * 00476 * 00477 * @param badptr Return value from heap allocation function. 00478 * 00479 * 00480 * @returns @link #ERROR0 ERROR0@endlink when no error was found 00481 * or non-null @b badptr given. 00482 * @link #heap_last_errno heap_last_errno@endlink 00483 * value otherwise. 00484 * 00485 */ 00486 int heap_get_error_simple(rvoid *badptr) 00487 { 00488 int rc; 00489 00490 if (rnull == badptr) 00491 { 00492 rc = heap_last_errno; 00493 heap_last_errno = ERROR0; 00494 return(rc); 00495 } 00496 else 00497 { 00498 heap_last_errno = ERROR0; 00499 00500 return(ERROR0); 00501 } 00502 00503 } /* END of heap_get_error_simple() */ 00504 00505 00506 /*! 00507 * @brief Shut down up heap management after JVM execution is finished. 00508 * 00509 * 00510 * @b Parameters: @link #rvoid rvoid@endlink 00511 * 00512 * 00513 * @returns @link #rvoid rvoid@endlink 00514 * 00515 */ 00516 rvoid heap_shutdown_simple() 00517 { 00518 heap_last_errno = ERROR0; 00519 00520 /* Declare this module uninitialized */ 00521 jvm_heap_initialized = rfalse; 00522 00523 return; 00524 00525 } /* END of heap_shutdown_simple() */ 00526 00527 #endif /* CONFIG_HEAP_TYPE_SIMPLE || CONFIG_OPTIONS_COMPILE_ALL */ 00528 00529 00530 /* EOF */ 00531