00001 /* 00002 * @(#)hprof_stack.c 1.11 10/03/23 00003 * 00004 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * -Redistribution of source code must retain the above copyright notice, this 00010 * list of conditions and the following disclaimer. 00011 * 00012 * -Redistribution in binary form must reproduce the above copyright notice, 00013 * this list of conditions and the following disclaimer in the documentation 00014 * and/or other materials provided with the distribution. 00015 * 00016 * Neither the name of Oracle or the names of contributors may 00017 * be used to endorse or promote products derived from this software without 00018 * specific prior written permission. 00019 * 00020 * This software is provided "AS IS," without a warranty of any kind. ALL 00021 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING 00022 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE 00023 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") 00024 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE 00025 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 00026 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST 00027 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, 00028 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY 00029 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 00030 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 00031 * 00032 * You acknowledge that this software is not designed, licensed or intended 00033 * for use in the design, construction, operation or maintenance of any 00034 * nuclear facility. 00035 */ 00036 00037 /* Simple stack storage mechanism (or simple List). */ 00038 00039 /* 00040 * Stack is any depth (grows as it needs to), elements are arbitrary 00041 * length but known at stack init time. 00042 * 00043 * Stack elements can be accessed via pointers (be careful, if stack 00044 * moved while you point into stack you have problems) 00045 * 00046 * Pointers to stack elements passed in are copied. 00047 * 00048 * Since the stack can be inspected, it can be used for more than just 00049 * a simple stack. 00050 * 00051 */ 00052 00053 #include "hprof.h" 00054 00055 static void 00056 resize(Stack *stack) 00057 { 00058 void *old_elements; 00059 void *new_elements; 00060 int old_size; 00061 int new_size; 00062 00063 HPROF_ASSERT(stack!=NULL); 00064 HPROF_ASSERT(stack->elements!=NULL); 00065 HPROF_ASSERT(stack->size>0); 00066 HPROF_ASSERT(stack->elem_size>0); 00067 HPROF_ASSERT(stack->incr_size>0); 00068 old_size = stack->size; 00069 old_elements = stack->elements; 00070 if ( (stack->resizes % 10) && stack->incr_size < (old_size >> 2) ) { 00071 stack->incr_size = old_size >> 2; /* 1/4 the old_size */ 00072 } 00073 new_size = old_size + stack->incr_size; 00074 new_elements = HPROF_MALLOC(new_size*stack->elem_size); 00075 (void)memcpy(new_elements, old_elements, old_size*stack->elem_size); 00076 stack->size = new_size; 00077 stack->elements = new_elements; 00078 HPROF_FREE(old_elements); 00079 stack->resizes++; 00080 } 00081 00082 Stack * 00083 stack_init(int init_size, int incr_size, int elem_size) 00084 { 00085 Stack *stack; 00086 void *elements; 00087 00088 HPROF_ASSERT(init_size>0); 00089 HPROF_ASSERT(elem_size>0); 00090 HPROF_ASSERT(incr_size>0); 00091 stack = (Stack*)HPROF_MALLOC((int)sizeof(Stack)); 00092 elements = HPROF_MALLOC(init_size*elem_size); 00093 stack->size = init_size; 00094 stack->incr_size = incr_size; 00095 stack->elem_size = elem_size; 00096 stack->count = 0; 00097 stack->elements = elements; 00098 stack->resizes = 0; 00099 return stack; 00100 } 00101 00102 void * 00103 stack_element(Stack *stack, int i) 00104 { 00105 HPROF_ASSERT(stack!=NULL); 00106 HPROF_ASSERT(stack->elements!=NULL); 00107 HPROF_ASSERT(stack->count>i); 00108 HPROF_ASSERT(i>=0); 00109 return (void*)(((char*)stack->elements) + i * stack->elem_size); 00110 } 00111 00112 void * 00113 stack_top(Stack *stack) 00114 { 00115 void *element; 00116 00117 HPROF_ASSERT(stack!=NULL); 00118 element = NULL; 00119 if ( stack->count > 0 ) { 00120 element = stack_element(stack, (stack->count-1)); 00121 } 00122 return element; 00123 } 00124 00125 int 00126 stack_depth(Stack *stack) 00127 { 00128 HPROF_ASSERT(stack!=NULL); 00129 return stack->count; 00130 } 00131 00132 void * 00133 stack_pop(Stack *stack) 00134 { 00135 void *element; 00136 00137 element = stack_top(stack); 00138 if ( element != NULL ) { 00139 stack->count--; 00140 } 00141 return element; 00142 } 00143 00144 void 00145 stack_push(Stack *stack, void *element) 00146 { 00147 void *top_element; 00148 00149 HPROF_ASSERT(stack!=NULL); 00150 if ( stack->count >= stack->size ) { 00151 resize(stack); 00152 } 00153 stack->count++; 00154 top_element = stack_top(stack); 00155 (void)memcpy(top_element, element, stack->elem_size); 00156 } 00157 00158 void 00159 stack_term(Stack *stack) 00160 { 00161 HPROF_ASSERT(stack!=NULL); 00162 if ( stack->elements != NULL ) { 00163 HPROF_FREE(stack->elements); 00164 } 00165 HPROF_FREE(stack); 00166 } 00167
1.6.1