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