1 /* 2 * Copyright (c) 2001, 2008, 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 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include "defines.h" 31 #include "bytes.h" 32 #include "utils.h" 33 34 35 static byte dummy[1 << 10]; 36 37 bool bytes::inBounds(const void* p) { 38 return p >= ptr && p < limit(); 39 } 40 41 void bytes::malloc(size_t len_) { 42 len = len_; 43 ptr = NEW(byte, add_size(len_, 1)); // add trailing zero byte always 44 if (ptr == null) { 45 // set ptr to some victim memory, to ease escape 46 set(dummy, sizeof(dummy)-1); 47 unpack_abort(ERROR_ENOMEM); 48 } 49 } 50 51 void bytes::realloc(size_t len_) { 52 if (len == len_) return; // nothing to do 53 if (ptr == dummy) return; // escaping from an error 54 if (ptr == null) { 55 malloc(len_); 56 return; 57 } 58 byte* oldptr = ptr; 59 ptr = (len_ >= PSIZE_MAX) ? null : (byte*)::realloc(ptr, add_size(len_, 1)); 60 if (ptr != null) { 61 mtrace('r', oldptr, 0); 62 mtrace('m', ptr, len_+1); 63 if (len < len_) memset(ptr+len, 0, len_-len); 64 ptr[len_] = 0; 65 len = len_; 66 } else { 67 ptr = oldptr; // ease our escape 68 unpack_abort(ERROR_ENOMEM); 69 } 70 } 71 72 void bytes::free() { 73 if (ptr == dummy) return; // escaping from an error 74 if (ptr != null) { 75 mtrace('f', ptr, 0); 76 ::free(ptr); 77 } 78 len = 0; 79 ptr = 0; 80 } 81 82 int bytes::indexOf(byte c) { 83 byte* p = (byte*) memchr(ptr, c, len); 84 return (p == 0) ? -1 : (int)(p - ptr); 85 } 86 87 byte* bytes::writeTo(byte* bp) { 88 memcpy(bp, ptr, len); 89 return bp+len; 90 } 91 92 int bytes::compareTo(bytes& other) { 93 size_t l1 = len; 94 size_t l2 = other.len; 95 int cmp = memcmp(ptr, other.ptr, (l1 < l2) ? l1 : l2); 96 if (cmp != 0) return cmp; 97 return (l1 < l2) ? -1 : (l1 > l2) ? 1 : 0; 98 } 99 100 void bytes::saveFrom(const void* ptr_, size_t len_) { 101 malloc(len_); 102 // Save as much as possible. (Helps unpacker::abort.) 103 if (len_ > len) { 104 assert(ptr == dummy); // error recovery 105 len_ = len; 106 } 107 copyFrom(ptr_, len_); 108 } 109 110 //#TODO: Need to fix for exception handling 111 void bytes::copyFrom(const void* ptr_, size_t len_, size_t offset) { 112 assert(len_ == 0 || inBounds(ptr + offset)); 113 assert(len_ == 0 || inBounds(ptr + offset+len_-1)); 114 memcpy(ptr+offset, ptr_, len_); 115 } 116 117 118 #ifndef PRODUCT 119 const char* bytes::string() { 120 if (len == 0) return ""; 121 if (ptr[len] == 0 && strlen((char*)ptr) == len) return (const char*) ptr; 122 bytes junk; 123 junk.saveFrom(*this); 124 return (char*) junk.ptr; 125 } 126 #endif 127 128 // Make sure there are 'o' bytes beyond the fill pointer, 129 // advance the fill pointer, and return the old fill pointer. 130 byte* fillbytes::grow(size_t s) { 131 size_t nlen = add_size(b.len, s); 132 if (nlen <= allocated) { 133 b.len = nlen; 134 return limit()-s; 135 } 136 size_t maxlen = nlen; 137 if (maxlen < 128) maxlen = 128; 138 if (maxlen < allocated*2) maxlen = allocated*2; 139 if (allocated == 0) { 140 // Initial buffer was not malloced. Do not reallocate it. 141 bytes old = b; 142 b.malloc(maxlen); 143 if (b.len == maxlen) 144 old.writeTo(b.ptr); 145 } else { 146 b.realloc(maxlen); 147 } 148 allocated = b.len; 149 if (allocated != maxlen) { 150 assert(unpack_aborting()); 151 b.len = nlen-s; // back up 152 return dummy; // scribble during error recov. 153 } 154 // after realloc, recompute pointers 155 b.len = nlen; 156 assert(b.len <= allocated); 157 return limit()-s; 158 } 159 160 void fillbytes::ensureSize(size_t s) { 161 if (allocated >= s) return; 162 size_t len0 = b.len; 163 grow(s - size()); 164 b.len = len0; // put it back 165 } 166 167 int ptrlist::indexOf(const void* x) { 168 int len = length(); 169 for (int i = 0; i < len; i++) { 170 if (get(i) == x) return i; 171 } 172 return -1; 173 } 174 175 void ptrlist::freeAll() { 176 int len = length(); 177 for (int i = 0; i < len; i++) { 178 void* p = (void*) get(i); 179 if (p != null) { 180 mtrace('f', p, 0); 181 ::free(p); 182 } 183 } 184 free(); 185 } 186 187 int intlist::indexOf(int x) { 188 int len = length(); 189 for (int i = 0; i < len; i++) { 190 if (get(i) == x) return i; 191 } 192 return -1; 193 }