int Bytecode_loadconstant::raw_index() const { Bytecodes::Code rawc = code(); assert(rawc != Bytecodes::_wide, "verifier prevents this"); if (Bytecodes::java_code(rawc) == Bytecodes::_ldc) return get_index_u1(rawc); else return get_index_u2(rawc, false); }
// ------------------------------------------------------------------ // ciBytecodeStream::get_constant_raw_index // // If this bytecode is one of the ldc variants, get the index of the // referenced constant. int ciBytecodeStream::get_constant_raw_index() const { // work-alike for Bytecode_loadconstant::raw_index() switch (cur_bc()) { case Bytecodes::_ldc: return get_index_u1(); case Bytecodes::_ldc_w: case Bytecodes::_ldc2_w: return get_index_u2(); default: ShouldNotReachHere(); return 0; } }
// ------------------------------------------------------------------ // ciBytecodeStream::get_klass_index // // If this bytecodes references a klass, return the index of the // referenced klass. int ciBytecodeStream::get_klass_index() const { switch(cur_bc()) { case Bytecodes::_ldc: return get_index_u1(); case Bytecodes::_ldc_w: case Bytecodes::_ldc2_w: case Bytecodes::_checkcast: case Bytecodes::_instanceof: case Bytecodes::_anewarray: case Bytecodes::_multianewarray: case Bytecodes::_new: case Bytecodes::_newarray: return get_index_u2(); default: ShouldNotReachHere(); return 0; } }
int get_index_special() { return (is_wide()) ? get_index_u2() : get_index_u1(); }
int get_index_u1_cpcache() { return get_index_u1() + ConstantPool::CPCACHE_INDEX_TAG; }
void BytecodePrinter::print_attributes(int bci, outputStream* st) { // Show attributes of pre-rewritten codes Bytecodes::Code code = Bytecodes::java_code(raw_code()); // If the code doesn't have any fields there's nothing to print. // note this is ==1 because the tableswitch and lookupswitch are // zero size (for some reason) and we want to print stuff out for them. if (Bytecodes::length_for(code) == 1) { st->cr(); return; } switch(code) { // Java specific bytecodes only matter. case Bytecodes::_bipush: st->print_cr(" " INT32_FORMAT, get_byte()); break; case Bytecodes::_sipush: st->print_cr(" " INT32_FORMAT, get_short()); break; case Bytecodes::_ldc: if (Bytecodes::uses_cp_cache(raw_code())) { print_constant(get_index_u1_cpcache(), st); } else { print_constant(get_index_u1(), st); } break; case Bytecodes::_ldc_w: case Bytecodes::_ldc2_w: if (Bytecodes::uses_cp_cache(raw_code())) { print_constant(get_index_u2_cpcache(), st); } else { print_constant(get_index_u2(), st); } break; case Bytecodes::_iload: case Bytecodes::_lload: case Bytecodes::_fload: case Bytecodes::_dload: case Bytecodes::_aload: case Bytecodes::_istore: case Bytecodes::_lstore: case Bytecodes::_fstore: case Bytecodes::_dstore: case Bytecodes::_astore: st->print_cr(" #%d", get_index_special()); break; case Bytecodes::_iinc: { int index = get_index_special(); jint offset = is_wide() ? get_short(): get_byte(); st->print_cr(" #%d " INT32_FORMAT, index, offset); } break; case Bytecodes::_newarray: { BasicType atype = (BasicType)get_index_u1(); const char* str = type2name(atype); if (str == NULL || atype == T_OBJECT || atype == T_ARRAY) { assert(false, "Unidentified basic type"); } st->print_cr(" %s", str); } break; case Bytecodes::_anewarray: { int klass_index = get_index_u2(); ConstantPool* constants = method()->constants(); Symbol* name = constants->klass_name_at(klass_index); st->print_cr(" %s ", name->as_C_string()); } break; case Bytecodes::_multianewarray: { int klass_index = get_index_u2(); int nof_dims = get_index_u1(); ConstantPool* constants = method()->constants(); Symbol* name = constants->klass_name_at(klass_index); st->print_cr(" %s %d", name->as_C_string(), nof_dims); } break; case Bytecodes::_ifeq: case Bytecodes::_ifnull: case Bytecodes::_iflt: case Bytecodes::_ifle: case Bytecodes::_ifne: case Bytecodes::_ifnonnull: case Bytecodes::_ifgt: case Bytecodes::_ifge: case Bytecodes::_if_icmpeq: case Bytecodes::_if_icmpne: case Bytecodes::_if_icmplt: case Bytecodes::_if_icmpgt: case Bytecodes::_if_icmple: case Bytecodes::_if_icmpge: case Bytecodes::_if_acmpeq: case Bytecodes::_if_acmpne: case Bytecodes::_goto: case Bytecodes::_jsr: st->print_cr(" %d", bci + get_short()); break; case Bytecodes::_goto_w: case Bytecodes::_jsr_w: st->print_cr(" %d", bci + get_int()); break; case Bytecodes::_ret: st->print_cr(" %d", get_index_special()); break; case Bytecodes::_tableswitch: { align(); int default_dest = bci + get_int(); int lo = get_int(); int hi = get_int(); int len = hi - lo + 1; jint* dest = NEW_RESOURCE_ARRAY(jint, len); for (int i = 0; i < len; i++) { dest[i] = bci + get_int(); } st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ", default_dest, lo, hi); int first = true; for (int ll = lo; ll <= hi; ll++, first = false) { int idx = ll - lo; const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" : ", %d:" INT32_FORMAT " (delta: %d)"; st->print(format, ll, dest[idx], dest[idx]-bci); } st->cr(); } break; case Bytecodes::_lookupswitch: { align(); int default_dest = bci + get_int(); int len = get_int(); jint* key = NEW_RESOURCE_ARRAY(jint, len); jint* dest = NEW_RESOURCE_ARRAY(jint, len); for (int i = 0; i < len; i++) { key [i] = get_int(); dest[i] = bci + get_int(); }; st->print(" %d %d ", default_dest, len); bool first = true; for (int ll = 0; ll < len; ll++, first = false) { const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT : ", " INT32_FORMAT ":" INT32_FORMAT ; st->print(format, key[ll], dest[ll]); } st->cr(); } break; case Bytecodes::_putstatic: case Bytecodes::_getstatic: case Bytecodes::_putfield: case Bytecodes::_getfield: print_field_or_method(get_index_u2_cpcache(), st); break; case Bytecodes::_invokevirtual: case Bytecodes::_invokespecial: case Bytecodes::_invokestatic: print_field_or_method(get_index_u2_cpcache(), st); break; case Bytecodes::_invokeinterface: { int i = get_index_u2_cpcache(); int n = get_index_u1(); get_byte(); // ignore zero byte print_field_or_method(i, st); } break; case Bytecodes::_invokedynamic: print_field_or_method(get_index_u4(), st); break; case Bytecodes::_new: case Bytecodes::_checkcast: case Bytecodes::_instanceof: { int i = get_index_u2(); ConstantPool* constants = method()->constants(); Symbol* name = constants->klass_name_at(i); st->print_cr(" %d <%s>", i, name->as_C_string()); } break; case Bytecodes::_wide: // length is zero not one, but printed with no more info. break; default: ShouldNotReachHere(); break; } }
int get_index_u1_cpcache() { return get_index_u1() + constantPoolOopDesc::CPCACHE_INDEX_TAG; }
// Get a byte index following this bytecode. // If prefixed with a wide bytecode, get a wide index. int get_index() const { assert(!has_cache_index(), "else use cpcache variant"); return (_pc == _was_wide) // was widened? ? get_index_u2(true) // yes, return wide index : get_index_u1(); // no, return narrow index }