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 }