private static int linearSearch(ObjArray methods, Symbol name, Symbol signature) { int len = (int) methods.getLength(); for (int index = 0; index < len; index++) { Method m = (Method) methods.getObjAt(index); if (m.getSignature().equals(signature) && m.getName().equals(name)) { return index; } } return -1; }
private static Method findMethod(ObjArray methods, Symbol name, Symbol signature) { int len = (int) methods.getLength(); // methods are sorted, so do binary search int l = 0; int h = len - 1; while (l <= h) { int mid = (l + h) >> 1; Method m = (Method) methods.getObjAt(mid); int res = m.getName().fastCompare(name); if (res == 0) { // found matching name; do linear search to find matching signature // first, quick check for common case if (m.getSignature().equals(signature)) return m; // search downwards through overloaded methods int i; for (i = mid - 1; i >= l; i--) { Method m1 = (Method) methods.getObjAt(i); if (!m1.getName().equals(name)) break; if (m1.getSignature().equals(signature)) return m1; } // search upwards for (i = mid + 1; i <= h; i++) { Method m1 = (Method) methods.getObjAt(i); if (!m1.getName().equals(name)) break; if (m1.getSignature().equals(signature)) return m1; } // not found if (Assert.ASSERTS_ENABLED) { int index = linearSearch(methods, name, signature); if (index != -1) { throw new DebuggerException("binary search bug: should have found entry " + index); } } return null; } else if (res < 0) { l = mid + 1; } else { h = mid - 1; } } if (Assert.ASSERTS_ENABLED) { int index = linearSearch(methods, name, signature); if (index != -1) { throw new DebuggerException("binary search bug: should have found entry " + index); } } return null; }
protected short getConstantPoolIndex(int bci) { // get ConstantPool index from ConstantPoolCacheIndex at given bci short cpCacheIndex = method.getBytecodeShortArg(bci); if (cpCache == null) { return cpCacheIndex; } else { // change byte-ordering and go via cache return (short) cpCache.getEntryAt((int) (0xFFFF & bytes.swapShort(cpCacheIndex))).getConstantPoolIndex(); } }
public void rewrite() { int bytecode = Bytecodes._illegal; int hotspotcode = Bytecodes._illegal; int len = 0; for (int bci = 0; bci < code.length; ) { hotspotcode = Bytecodes.codeAt(method, bci); bytecode = Bytecodes.javaCode(hotspotcode); if (Assert.ASSERTS_ENABLED) { int code_from_buffer = 0xFF & code[bci]; Assert.that( code_from_buffer == hotspotcode || code_from_buffer == Bytecodes._breakpoint, "Unexpected bytecode found in method bytecode buffer!"); } // update the code buffer hotspot specific bytecode with the jvm bytecode code[bci] = (byte) (0xFF & bytecode); short cpoolIndex = 0; switch (bytecode) { // bytecodes with ConstantPoolCache index case Bytecodes._getstatic: case Bytecodes._putstatic: case Bytecodes._getfield: case Bytecodes._putfield: case Bytecodes._invokevirtual: case Bytecodes._invokespecial: case Bytecodes._invokestatic: case Bytecodes._invokeinterface: { cpoolIndex = getConstantPoolIndex(bci + 1); writeShort(code, bci + 1, cpoolIndex); break; } } len = Bytecodes.lengthFor(bytecode); if (len <= 0) len = Bytecodes.lengthAt(method, bci); if (DEBUG) { String operand = ""; switch (len) { case 2: operand += code[bci + 1]; break; case 3: operand += (cpoolIndex != 0) ? cpoolIndex : method.getBytecodeShortArg(bci + 1); break; case 5: operand += method.getBytecodeIntArg(bci + 1); break; } // the operand following # is not quite like javap output. // in particular, for goto & goto_w, the operand is PC relative // offset for jump. Javap adds relative offset with current PC // to give absolute bci to jump to. String message = "\t\t" + bci + " " + Bytecodes.name(bytecode); if (hotspotcode != bytecode) message += " [" + Bytecodes.name(hotspotcode) + "]"; if (operand != "") message += " #" + operand; if (DEBUG) debugMessage(message); } bci += len; } }