int Bytecodes::special_length_at(address bcp) {
  Code code = code_at(bcp);
  switch (code) {
  case _wide:
    return wide_length_for(cast(*(bcp + 1)));
  case _tableswitch:
    { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
      jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
      jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
      jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
      // only return len if it can be represented as a positive int;
      // return -1 otherwise
      return (len > 0 && len == (int)len) ? len : -1;
    }

  case _lookupswitch:      // fall through    
  case _fast_binaryswitch: // fall through    
  case _fast_linearswitch: 
    { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
      jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
      jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
      // only return len if it can be represented as a positive int;
      // return -1 otherwise
      return (len > 0 && len == (int)len) ? len : -1;
    }
  }
  return 0;
}
Example #2
0
void Bytecodes::verify() {
#if USE_DEBUG_PRINTING
  GUARANTEE(number_of_java_codes -1 <= 0xff, "Too many bytecodes");
  int index = 0;
  for(BytecodeData* p = data; p->_name != NULL; p++) {
    GUARANTEE(p->_index == index, "index must match");
    Code code = (Code) index;
    if (is_defined(code)) {
      GUARANTEE((int) jvm_strlen(p->_format) == length_for(code), 
                "checking length");
    }
    if (wide_is_defined(code)) {
      GUARANTEE((int) jvm_strlen(p->_wide_format) == wide_length_for(code), 
                "checking length");
    }

    if (is_defined(code)) {
      if ((code == Bytecodes::_goto) ||
          (code == Bytecodes::_goto_w) ||
          (code >= Bytecodes::_ireturn && code <= Bytecodes::_return) ||
          (code == Bytecodes::_ret) ||
          (code == Bytecodes::_tableswitch) ||
          (code == Bytecodes::_lookupswitch) ||
          (code == Bytecodes::_athrow) ||
          (code == Bytecodes::_fast_invokenative)) {
        GUARANTEE(!can_fall_through(code), "cannot fall through");
      } else {
        GUARANTEE(can_fall_through(code), "can fall through");
      }
    }
    index++;
  }
#endif
}
Example #3
0
void Bytecodes::def(Code code, const char* name, const char* format, const char* wide_format, BasicType result_type, int depth, bool can_trap, Code java_code) {
  assert(wide_format == NULL || format != NULL, "short form must exist if there's a wide form");
  int len  = (format      != NULL ? (int) strlen(format)      : 0);
  int wlen = (wide_format != NULL ? (int) strlen(wide_format) : 0);
  _name          [code] = name;
  _result_type   [code] = result_type;
  _depth         [code] = depth;
  _lengths       [code] = (wlen << 4) | (len & 0xF);
  _java_code     [code] = java_code;
  int bc_flags = 0;
  if (can_trap)           bc_flags |= _bc_can_trap;
  if (java_code != code)  bc_flags |= _bc_can_rewrite;
  _flags[(u1)code+0*(1<<BitsPerByte)] = compute_flags(format,      bc_flags);
  _flags[(u1)code+1*(1<<BitsPerByte)] = compute_flags(wide_format, bc_flags);
  assert(is_defined(code)      == (format != NULL),      "");
  assert(wide_is_defined(code) == (wide_format != NULL), "");
  assert(length_for(code)      == len, "");
  assert(wide_length_for(code) == wlen, "");
}
Example #4
0
int Bytecodes::special_length_at(address bcp, address end) {
  Code code = code_at(bcp);
  switch (code) {
  case _wide:
    if (end != NULL && bcp + 1 >= end) {
      return -1; // don't read past end of code buffer
    }
    return wide_length_for(cast(*(bcp + 1)));
  case _tableswitch:
    { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
      if (end != NULL && aligned_bcp + 3*jintSize >= end) {
        return -1; // don't read past end of code buffer
      }
      jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize);
      jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
      jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize;
      // only return len if it can be represented as a positive int;
      // return -1 otherwise
      return (len > 0 && len == (int)len) ? len : -1;
    }

  case _lookupswitch:      // fall through
  case _fast_binaryswitch: // fall through
  case _fast_linearswitch:
    { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize);
      if (end != NULL && aligned_bcp + 2*jintSize >= end) {
        return -1; // don't read past end of code buffer
      }
      jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
      jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize;
      // only return len if it can be represented as a positive int;
      // return -1 otherwise
      return (len > 0 && len == (int)len) ? len : -1;
    }
  }
  // Note: Length functions must return <=0 for invalid bytecodes.
  return 0;
}