jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_blocks.c
changeset 32253 637b00638ed6
parent 32252 78117959e115
parent 32249 ba2c9c7773b6
child 32255 cc8c8786ef91
equal deleted inserted replaced
32252:78117959e115 32253:637b00638ed6
     1 /*
       
     2  * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  *
       
     8  *   - Redistributions of source code must retain the above copyright
       
     9  *     notice, this list of conditions and the following disclaimer.
       
    10  *
       
    11  *   - Redistributions in binary form must reproduce the above copyright
       
    12  *     notice, this list of conditions and the following disclaimer in the
       
    13  *     documentation and/or other materials provided with the distribution.
       
    14  *
       
    15  *   - Neither the name of Oracle nor the names of its
       
    16  *     contributors may be used to endorse or promote products derived
       
    17  *     from this software without specific prior written permission.
       
    18  *
       
    19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
       
    20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
       
    21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
       
    23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
       
    27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
       
    28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
       
    29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    30  */
       
    31 
       
    32 /*
       
    33  * This source code is provided to illustrate the usage of a given feature
       
    34  * or technique and has been deliberately simplified. Additional steps
       
    35  * required for a production-quality application, such as security checks,
       
    36  * input validation and proper error handling, might not be present in
       
    37  * this sample code.
       
    38  */
       
    39 
       
    40 
       
    41 /* Allocations from large blocks, no individual free's */
       
    42 
       
    43 #include "hprof.h"
       
    44 
       
    45 /*
       
    46  * This file contains some allocation code that allows you
       
    47  *   to have space allocated via larger blocks of space.
       
    48  * The only free allowed is of all the blocks and all the elements.
       
    49  * Elements can be of different alignments and fixed or variable sized.
       
    50  * The space allocated never moves.
       
    51  *
       
    52  */
       
    53 
       
    54 /* Get the real size allocated based on alignment and bytes needed */
       
    55 static int
       
    56 real_size(int alignment, int nbytes)
       
    57 {
       
    58     if ( alignment > 1 ) {
       
    59         int wasted;
       
    60 
       
    61         wasted = alignment - ( nbytes % alignment );
       
    62         if ( wasted != alignment ) {
       
    63             nbytes += wasted;
       
    64         }
       
    65     }
       
    66     return nbytes;
       
    67 }
       
    68 
       
    69 /* Add a new current_block to the Blocks* chain, adjust size if nbytes big. */
       
    70 static void
       
    71 add_block(Blocks *blocks, int nbytes)
       
    72 {
       
    73     int header_size;
       
    74     int block_size;
       
    75     BlockHeader *block_header;
       
    76 
       
    77     HPROF_ASSERT(blocks!=NULL);
       
    78     HPROF_ASSERT(nbytes>0);
       
    79 
       
    80     header_size          = real_size(blocks->alignment, sizeof(BlockHeader));
       
    81     block_size           = blocks->elem_size*blocks->population;
       
    82     if ( nbytes > block_size ) {
       
    83         block_size = real_size(blocks->alignment, nbytes);
       
    84     }
       
    85     block_header         = (BlockHeader*)HPROF_MALLOC(block_size+header_size);
       
    86     block_header->next   = NULL;
       
    87     block_header->bytes_left = block_size;
       
    88     block_header->next_pos   = header_size;
       
    89 
       
    90     /* Link in new block */
       
    91     if ( blocks->current_block != NULL ) {
       
    92         blocks->current_block->next = block_header;
       
    93     }
       
    94     blocks->current_block = block_header;
       
    95     if ( blocks->first_block == NULL ) {
       
    96         blocks->first_block = block_header;
       
    97     }
       
    98 }
       
    99 
       
   100 /* Initialize a new Blocks */
       
   101 Blocks *
       
   102 blocks_init(int alignment, int elem_size, int population)
       
   103 {
       
   104     Blocks *blocks;
       
   105 
       
   106     HPROF_ASSERT(alignment>0);
       
   107     HPROF_ASSERT(elem_size>0);
       
   108     HPROF_ASSERT(population>0);
       
   109 
       
   110     blocks                = (Blocks*)HPROF_MALLOC(sizeof(Blocks));
       
   111     blocks->alignment     = alignment;
       
   112     blocks->elem_size     = elem_size;
       
   113     blocks->population    = population;
       
   114     blocks->first_block   = NULL;
       
   115     blocks->current_block = NULL;
       
   116     return blocks;
       
   117 }
       
   118 
       
   119 /* Allocate bytes from a Blocks area. */
       
   120 void *
       
   121 blocks_alloc(Blocks *blocks, int nbytes)
       
   122 {
       
   123     BlockHeader *block;
       
   124     int   pos;
       
   125     void *ptr;
       
   126 
       
   127     HPROF_ASSERT(blocks!=NULL);
       
   128     HPROF_ASSERT(nbytes>=0);
       
   129     if ( nbytes == 0 ) {
       
   130         return NULL;
       
   131     }
       
   132 
       
   133     block = blocks->current_block;
       
   134     nbytes = real_size(blocks->alignment, nbytes);
       
   135     if ( block == NULL || block->bytes_left < nbytes ) {
       
   136         add_block(blocks, nbytes);
       
   137         block = blocks->current_block;
       
   138     }
       
   139     pos = block->next_pos;
       
   140     ptr = (void*)(((char*)block)+pos);
       
   141     block->next_pos   += nbytes;
       
   142     block->bytes_left -= nbytes;
       
   143     return ptr;
       
   144 }
       
   145 
       
   146 /* Terminate the Blocks */
       
   147 void
       
   148 blocks_term(Blocks *blocks)
       
   149 {
       
   150     BlockHeader *block;
       
   151 
       
   152     HPROF_ASSERT(blocks!=NULL);
       
   153 
       
   154     block = blocks->first_block;
       
   155     while ( block != NULL ) {
       
   156         BlockHeader *next_block;
       
   157 
       
   158         next_block = block->next;
       
   159         HPROF_FREE(block);
       
   160         block = next_block;
       
   161     }
       
   162     HPROF_FREE(blocks);
       
   163 }