1 /* 2 * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* General routines for manipulating a bag data structure */ 27 28 #include "util.h" 29 #include "bag.h" 30 31 struct bag { 32 void *items; /* hold items in bag, must align on itemSize */ 33 int used; /* number of items in bag */ 34 int allocated; /* space reserved */ 35 int itemSize; /* size of each item, should init to sizeof item */ 36 }; 37 38 struct bag * 39 bagCreateBag(int itemSize, int initialAllocation) { 40 struct bag *theBag = (struct bag *)jvmtiAllocate(sizeof(struct bag)); 41 if (theBag == NULL) { 42 return NULL; 43 } 44 itemSize = (itemSize + 7) & ~7; /* fit 8 byte boundary */ 45 theBag->items = jvmtiAllocate(initialAllocation * itemSize); 46 if (theBag->items == NULL) { 47 jvmtiDeallocate(theBag); 48 return NULL; 49 } 50 theBag->used = 0; 51 theBag->allocated = initialAllocation; 52 theBag->itemSize = itemSize; 53 return theBag; 54 } 55 56 struct bag * 57 bagDup(struct bag *oldBag) 58 { 59 struct bag *newBag = bagCreateBag(oldBag->itemSize, 60 oldBag->allocated); 61 if (newBag != NULL) { 62 newBag->used = oldBag->used; 63 (void)memcpy(newBag->items, oldBag->items, newBag->used * newBag->itemSize); 64 } 65 return newBag; 66 } 67 68 void 69 bagDestroyBag(struct bag *theBag) 70 { 71 if (theBag != NULL) { 72 jvmtiDeallocate(theBag->items); 73 jvmtiDeallocate(theBag); 74 } 75 } 76 77 void * 78 bagFind(struct bag *theBag, void *key) 79 { 80 char *items = theBag->items; 81 int itemSize = theBag->itemSize; 82 char *itemsEnd = items + (itemSize * theBag->used); 83 84 for (; items < itemsEnd; items += itemSize) { 85 /*LINTED*/ 86 if (*((void**)items) == key) { 87 return items; 88 } 89 } 90 return NULL; 91 } 92 93 void * 94 bagAdd(struct bag *theBag) 95 { 96 int allocated = theBag->allocated; 97 int itemSize = theBag->itemSize; 98 void *items = theBag->items; 99 void *ret; 100 101 /* if there are no unused slots reallocate */ 102 if (theBag->used >= allocated) { 103 void *new_items; 104 allocated *= 2; 105 new_items = jvmtiAllocate(allocated * itemSize); 106 if (new_items == NULL) { 107 return NULL; 108 } 109 (void)memcpy(new_items, items, (theBag->used) * itemSize); 110 jvmtiDeallocate(items); 111 items = new_items; 112 theBag->allocated = allocated; 113 theBag->items = items; 114 } 115 ret = ((char *)items) + (itemSize * (theBag->used)++); 116 (void)memset(ret, 0, itemSize); 117 return ret; 118 } 119 120 void 121 bagDelete(struct bag *theBag, void *condemned) 122 { 123 int used = --(theBag->used); 124 int itemSize = theBag->itemSize; 125 void *items = theBag->items; 126 void *tailItem = ((char *)items) + (used * itemSize); 127 128 if (condemned != tailItem) { 129 (void)memcpy(condemned, tailItem, itemSize); 130 } 131 } 132 133 void 134 bagDeleteAll(struct bag *theBag) 135 { 136 theBag->used = 0; 137 } 138 139 140 int 141 bagSize(struct bag *theBag) 142 { 143 return theBag->used; 144 } 145 146 jboolean 147 bagEnumerateOver(struct bag *theBag, bagEnumerateFunction func, void *arg) 148 { 149 char *items = theBag->items; 150 int itemSize = theBag->itemSize; 151 char *itemsEnd = items + (itemSize * theBag->used); 152 153 for (; items < itemsEnd; items += itemSize) { 154 if (!(func)((void *)items, arg)) { 155 return JNI_FALSE; 156 } 157 } 158 return JNI_TRUE; 159 } 160