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; }
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 }
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, ""); }
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; }