// Rewrites a method given the index_map information void Rewriter::scan_method(methodOop method, bool reverse) { int nof_jsrs = 0; bool has_monitor_bytecodes = false; { // We cannot tolerate a GC in this block, because we've // cached the bytecodes in 'code_base'. If the methodOop // moves, the bytecodes will also move. No_Safepoint_Verifier nsv; Bytecodes::Code c; // Bytecodes and their length const address code_base = method->code_base(); const int code_length = method->code_size(); int bc_length; for (int bci = 0; bci < code_length; bci += bc_length) { address bcp = code_base + bci; int prefix_length = 0; c = (Bytecodes::Code)(*bcp); // Since we have the code, see if we can get the length // directly. Some more complicated bytecodes will report // a length of zero, meaning we need to make another method // call to calculate the length. bc_length = Bytecodes::length_for(c); if (bc_length == 0) { bc_length = Bytecodes::length_at(method, bcp); // length_at will put us at the bytecode after the one modified // by 'wide'. We don't currently examine any of the bytecodes // modified by wide, but in case we do in the future... if (c == Bytecodes::_wide) { prefix_length = 1; c = (Bytecodes::Code)bcp[1]; } } assert(bc_length != 0, "impossible bytecode length"); switch (c) { case Bytecodes::_lookupswitch : { #ifndef CC_INTERP Bytecode_lookupswitch bc(method, bcp); (*bcp) = ( bc.number_of_pairs() < BinarySwitchThreshold ? Bytecodes::_fast_linearswitch : Bytecodes::_fast_binaryswitch ); #endif break; } case Bytecodes::_fast_linearswitch: case Bytecodes::_fast_binaryswitch: { #ifndef CC_INTERP (*bcp) = Bytecodes::_lookupswitch; #endif break; } case Bytecodes::_getstatic : // fall through case Bytecodes::_putstatic : // fall through case Bytecodes::_getfield : // fall through case Bytecodes::_putfield : // fall through case Bytecodes::_invokevirtual : // fall through case Bytecodes::_invokespecial : // fall through case Bytecodes::_invokestatic : case Bytecodes::_invokeinterface: rewrite_member_reference(bcp, prefix_length+1, reverse); break; case Bytecodes::_invokedynamic: rewrite_invokedynamic(bcp, prefix_length+1, reverse); break; case Bytecodes::_ldc: case Bytecodes::_fast_aldc: maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse); break; case Bytecodes::_ldc_w: case Bytecodes::_fast_aldc_w: maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse); break; case Bytecodes::_jsr : // fall through case Bytecodes::_jsr_w : nof_jsrs++; break; case Bytecodes::_monitorenter : // fall through case Bytecodes::_monitorexit : has_monitor_bytecodes = true; break; } } } // Update access flags if (has_monitor_bytecodes) { method->set_has_monitor_bytecodes(); } // The present of a jsr bytecode implies that the method might potentially // have to be rewritten, so we run the oopMapGenerator on the method if (nof_jsrs > 0) { method->set_has_jsrs(); // Second pass will revisit this method. assert(method->has_jsrs(), "didn't we just set this?"); } }