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

heap_bimodal.c

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

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