Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

heap_simple.c

Go to the documentation of this file.
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 

Generated on Fri Sep 30 18:59:28 2005 by  doxygen 1.4.4