Пример #1
0
void ObjArray::array_copy(ObjArray* src, jint src_pos, 
                          ObjArray* dst, jint dst_pos, jint length JVM_TRAPS) {
  // Special case. Boundary cases must be checked first
  // This allows the following call: copy_array(s, s.length(),
  // d.length(), 0).  This is correct, since the position is supposed
  // to be an 'in between point', i.e., s.length(), points to the
  // right of the last element.
  if (length == 0) {
    return;
  }

  OopDesc** src_start =
      (OopDesc**) src->field_base(base_offset() + src_pos * oopSize);
  OopDesc** dst_start =
      (OopDesc**) dst->field_base(base_offset() + dst_pos * oopSize);
  if (src->equals(dst)) {
    // since source and destination are equal we do not need conversion checks.
    jvm_memmove(dst_start, src_start, length * oopSize);
    oop_write_barrier_range(dst_start, length);
  } else {
    // We have to make sure all elements conform to the destination array
    ObjArrayClass::Raw dst_class = dst->blueprint();
    ObjArrayClass::Raw src_class = src->blueprint();
    JavaClass::Raw bound = dst_class().element_class();
    JavaClass::Raw stype = src_class().element_class();
    if (stype.equals(&bound) || stype().is_subtype_of(&bound)) {
      // elements are guaranteed to be subtypes, so no check necessary
      jvm_memmove(dst_start, src_start, length * oopSize);
      oop_write_barrier_range(dst_start, length);
      return;
    }
    
    // Slow case: need individual subtype checks
    // Do store checks first so they're guaranteed to be done even if
    // an exception is thrown obj_at_put contains a write barrier already
    Oop::Raw       element;
    JavaClass::Raw element_class;
    for (int index =0; index < length; index++) {
      element = src->obj_at( src_pos + index);
      if (element.is_null()) {
        dst->obj_at_put(dst_pos + index, &element);
      } else {
        element_class = element.blueprint();
        if (element_class().is_subtype_of(&bound)) {
          dst->obj_at_put(dst_pos + index, &element);
        } else {
          Throw::array_store_exception(subtype_check_failed JVM_THROW);
        }
      }
    }
  }
}
Пример #2
0
void CompiledMethod::shrink(jint code_size, jint relocation_size) {
  // The current implementation copies the relocation information down
  // and "shrinks" the compiled method object in place, allocating a
  // dummy filler object in the now unused end part.
  //
  // The compiled method object will generally not be the last object in
  // the heap, since the compiler allocates other objects and GC might
  // have occurred. However, if the GC always does sliding compaction
  // and the compiler *guarantees* not to hold on to any allocated
  // object other than the compiled method, we could simply move the
  // top of the object heap down!

  // Copy the relocation segment down
  void* src = field_base(end_offset() - relocation_size);
  void* dst = field_base(base_offset() + code_size);
  GUARANTEE(src >= dst, "should be copying down");
  jvm_memmove(dst, src, relocation_size); // possibly overlapping regions

  // Shrink compiled method object
  size_t new_size = CompiledMethodDesc::allocation_size(code_size +
                                                        relocation_size);
  Universe::shrink_object(this, new_size);
  ((CompiledMethodDesc*) obj())->set_size(code_size + relocation_size);
  GUARANTEE(object_size() == new_size, "invalid shrunk size");
}
Пример #3
0
bool CompiledMethod::expand_compiled_code_space(int delta, int relocation_size) {
  if (ObjectHeap::expand_current_compiled_method(delta)) {
    if (Verbose) {
      TTY_TRACE_CR(("Expanding compiled method from %d to %d bytes", 
                    size(), size() + delta));
    }
    void* src = field_base(end_offset() - relocation_size);
    void* dst = DERIVED(void*, src, delta);
    GUARANTEE(src < dst, "should be copying up");
    jvm_memmove(dst, src, relocation_size); // possibly overlapping regions
    // It's probably OK only to clear dst[-1], but let's just make sure.
    jvm_memset(src, 0, delta);
    ((CompiledMethodDesc*) obj())->set_size(size() + delta);
    
    

    if (VerifyGC > 2) {
      ObjectHeap::verify();
    }
    return true;
  } else {
    return false;
Пример #4
0
bool JarFileParser::find_end_of_central_header() {
  DECLARE_STATIC_BUFFER(unsigned char, buffer, TMPBUFFERSIZE);
  BufferedFile::Raw bf = buffered_file();

  /* Get the length of the file */
  const jint length = (int) bf().file_size();

  /* Calculate the smallest possible offset for the end header.  It
   * can be at most 0xFFFF + ENDHDRSIZ bytes from the end of the file, but
   * the file must also have a local header and a central header
   */
  jint minOffset = length - (0xFFFF + ENDHDRSIZ);
  if (minOffset < LOCHDRSIZ + CENHDRSIZ) {
    minOffset = LOCHDRSIZ + CENHDRSIZ;
  }

  /* We assume that "buffer" contains the contents
   * of part of the file. currentOffset contains the offset of buffer[0].
   */

  /* Read in the last ENDHDRSIZ bytes into the buffer.  99% of the time,
   * the file won't have a comment, and this is the only read we'll need */
  if ( (bf().seek(-ENDHDRSIZ, SEEK_END) < 0)
    || (bf().get_bytes(buffer, ENDHDRSIZ) != ENDHDRSIZ)) {
    return false;
  }
  /* Set currentOffset to be the offset of buffer[0] */
  jint currentOffset = length - ENDHDRSIZ;
  /* Set bp to be the location at which to start looking */
  unsigned const char* bp = buffer;

  for (;;) {
    /* "buffer" contains a block of data from the file, starting at
     * currentOffset "position" in the file.
     * We investigate whether   currentOffset + (bp - buffer)  is the start
     * of the end header in the zip file.
     *
     * We use a simplified version of Knuth-Morris-Pratt search algorithm.
     * The header we're looking for is 'P' 'K' 5  6
     */
    switch(bp[0]) {
    case '\006':   /* The header must start at least 3 bytes back */
      bp -= 3; break;
    case '\005':   /* The header must start at least 2 bytes back  */
      bp -= 2; break;
    case 'K':      /* The header must start at least 1 byte back  */
      bp -= 1; break;
    case 'P':      /* Either this is the header, or the header must
                    * start at least 4  back */
      if (bp[1] == 'K' && bp[2] == 5 && bp[3] == 6) {
        /* We have what may be a header.  Let's make sure the
         * implied length of the jar file matches the actual
         * length.
         */
        int endpos = (int) currentOffset + (bp - buffer);
        if (endpos + ENDHDRSIZ + ENDCOM(bp) == length) {
          juint cenOffset = endpos - ENDSIZ(bp);
          juint locOffset = cenOffset - ENDOFF(bp);
          unsigned char sig[4];

          if (bf().seek(locOffset, SEEK_SET) >= 0 &&
              bf().get_bytes(sig, 4) == 4 &&
              sig[0] == (unsigned char)'P' && 
              sig[1] == (unsigned char)'K' && 
              sig[2] == (unsigned char) 3  && 
              sig[3] == (unsigned char) 4) {

            raw_current_entry()->cenOffset = cenOffset;
            raw_current_entry()->nextCenOffset = cenOffset;
            raw_current_entry()->locOffset = locOffset;
#if ENABLE_ROM_GENERATOR
            raw_current_entry()->totalEntryCount = ENDTOT(bp);
#endif
          }
          return true; // Found central header
        }
      }
      /* FALL THROUGH */
    default:
      /* The header must start at least four characters back, since
       * the current character isn't in the header */
      bp -= 4;
    }
    if (bp < buffer) {
      /* We've moved outside our window into the file.  We must
       * move the window backwards */
      size_t count = (size_t) (currentOffset - minOffset); /* Bytes left in file */
      if (((jint)count) <= 0) {
        /* Nothing left to read.  Time to give up */
        return false;
      } else {
        /* up to ((bp - buffer) + ENDHDRSIZ) bytes in the buffer might
         * still be part of the end header, so the most bytes we can
         * actually read are
         *      TMPBUFFERSIZE - ((bp - buffer) + ENDHDRSIZE).
         */
        size_t available = (TMPBUFFERSIZE - ENDHDRSIZ) + (buffer - bp);
        if (count > available) {
          count = available;
        }
      }
      /* Back up, while keeping our virtual currentOffset the same */
      currentOffset -= count;
      bp += count;
      jvm_memmove(buffer + count, buffer, TMPBUFFERSIZE - count);
      if ( bf().seek(currentOffset, SEEK_SET) < 0 ||
           bf().get_bytes(buffer, count) != size_t(count) ) {
        return false;
      }
    }
  } /* end of for loop */
}
Пример #5
0
KNIEXPORT void KNI_SetRawArrayRegion(jarray arrayHandle, jsize offset,
                                     jsize n, const jbyte* srcBuffer) {
  address ta_start = _KNI_GetRawArrayRegion_start_address(arrayHandle, offset);
  (void)jvm_memmove(ta_start, srcBuffer, n);
}
Пример #6
0
KNIEXPORT void KNI_GetRawArrayRegion(jarray arrayHandle, jsize offset,
                                     jsize n, jbyte* dstBuffer) {
  address ta_start = _KNI_GetRawArrayRegion_start_address(arrayHandle, offset);
  (void)jvm_memmove(dstBuffer, ta_start, n);
}