From: <cr...@us...> - 2009-09-18 07:23:28
|
Revision: 5681 http://jnode.svn.sourceforge.net/jnode/?rev=5681&view=rev Author: crawley Date: 2009-09-18 07:23:15 +0000 (Fri, 18 Sep 2009) Log Message: ----------- When a native method is replaced with a Java one (from a Native... class), the method's bytecode stream must still use the constant pool for the Native... class. Modified Paths: -------------- branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_BytecodeStream.java branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_Method.java branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_NormalMethod.java branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/Modifier.java branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/VmMember.java branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/VmMethod.java Modified: branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_BytecodeStream.java =================================================================== --- branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_BytecodeStream.java 2009-09-18 07:00:06 UTC (rev 5680) +++ branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_BytecodeStream.java 2009-09-18 07:23:15 UTC (rev 5681) @@ -16,8 +16,8 @@ * @author Igor Pechtchanski */ public class VM_BytecodeStream implements VM_BytecodeConstants, VM_SizeConstants { - private final VM_NormalMethod method; - private final VM_Class declaringClass; + private VM_NormalMethod method; + private VM_Class declaringClass; private final int bcLength; private final byte[] bcodes; private int bcIndex; @@ -25,6 +25,7 @@ private boolean wide; /** + * Create a bytecode stream from a method descriptor and an array of bytecodes. * @param m the method containing the bytecodes * @param bc the array of bytecodes */ @@ -35,6 +36,15 @@ bcLength = bc.length; bcIndex = 0; } + + /** + * Create a bytecode stream from an existing one. The method and bytecode + * array will be shared. + * @param stream the existing bytecode stream + */ + public VM_BytecodeStream(VM_BytecodeStream stream) { + this(stream.method, stream.bcodes); + } /** * Returns the method that this bytecode stream is from @@ -61,6 +71,14 @@ public final int length() { return bcLength; } + + /** + * Returns the bytecodes or {@code null}. + * @return the bytecode array + */ + public final byte[] bytecodes() { + return bcodes; + } /** * Returns the current bytecode index Modified: branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_Method.java =================================================================== --- branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_Method.java 2009-09-18 07:00:06 UTC (rev 5680) +++ branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_Method.java 2009-09-18 07:23:15 UTC (rev 5681) @@ -2,6 +2,7 @@ import java.nio.ByteBuffer; +import org.jnode.vm.classmgr.VmByteCode; import org.jnode.vm.classmgr.VmExceptions; import org.jnode.vm.classmgr.VmInstanceMethod; import org.jnode.vm.classmgr.VmLineNumberMap; @@ -41,7 +42,7 @@ } public final boolean hasNoInlinePragma() { - return ((VmMethod)jnodeMember).hasNoInlinePragma(); + return ((VmMethod) jnodeMember).hasNoInlinePragma(); } @@ -50,22 +51,24 @@ } public void invalidateCompiledMethod(VM_CompiledMethod cm) { - if (VM.VerifyAssertions) VM._assert(declaringClass.isInstantiated()); + if (VM.VerifyAssertions) { + VM._assert(declaringClass.isInstantiated()); + } if (currentCompiledMethod == cm) { - replaceCompiledMethod(null); + replaceCompiledMethod(null); } } public boolean isObjectInitializer() { - return ((VmMethod)jnodeMember).isConstructor(); + return ((VmMethod) jnodeMember).isConstructor(); } public boolean isNative() { - return ((VmMethod)jnodeMember).isNative(); + return ((VmMethod) jnodeMember).isNative(); } public boolean isAbstract() { - return ((VmMethod)jnodeMember).isAbstract(); + return ((VmMethod) jnodeMember).isAbstract(); } public boolean mayWrite(VM_Field f) { @@ -73,15 +76,15 @@ } public boolean isInterruptible() { - return !((VmMethod)jnodeMember).isUninterruptible(); + return !((VmMethod) jnodeMember).isUninterruptible(); } public boolean hasInlinePragma() { - return ((VmMethod)jnodeMember).hasInlinePragma(); + return ((VmMethod) jnodeMember).hasInlinePragma(); } public boolean isClassInitializer() { - return ((VmMethod)jnodeMember).isInitializer(); + return ((VmMethod) jnodeMember).isInitializer(); } public boolean isCompiled() { @@ -102,20 +105,26 @@ * Check that it provides the functionality you want before calling it. */ public static VM_Method buildFromJnodeMethod(VmMethod method) { - if(method == null) return null; - VM_Class dc = VM_Class.buildFromJnodeClass(method.getDeclaringClass()); + if (method == null) { + return null; + } + VM_Class dc = method.isReplacement() ? + VM_Class.buildFromJnodeClass(method.getRealDeclaringClass()) : + VM_Class.buildFromJnodeClass(method.getDeclaringClass()); String name = method.getName(); String desc = method.getSignature(); VM_Atom mn = VM_Atom.findOrCreateAsciiAtom(name); VM_Atom d = VM_Atom.findOrCreateAsciiAtom(desc); VM_MemberReference mr = VM_MemberReference.findOrCreate(dc.getTypeRef(), mn, d); - if (((VM_MethodReference)mr).isResolved()) - return (VM_Method)mr.resolveMember(); - VM_Method jikesMethod; - if(method.isAbstract()) - return jikesMethod = new VM_AbstractMethod(dc, mr, method.getModifiers(), null, method); - if(method.isNative()) - return jikesMethod = new VM_NativeMethod(dc, mr, method.getModifiers(), null, method); + if (((VM_MethodReference) mr).isResolved()) { + return (VM_Method) mr.resolveMember(); + } + if (method.isAbstract()) { + return new VM_AbstractMethod(dc, mr, method.getModifiers(), null, method); + } + if (method.isNative()) { + return new VM_NativeMethod(dc, mr, method.getModifiers(), null, method); + } //If we reach here the method is definitely "normal", i.e. not native and not abstract int bclength = method.getBytecodeSize(); @@ -125,27 +134,34 @@ VmExceptions jnodeExceptions = method.getExceptions(); VM_ExceptionHandlerMap eMap = null; int n = method.getBytecode().getExceptionHandlers().size(); - if (n!=0) eMap = new VM_ExceptionHandlerMap(method.getBytecode().getExceptionHandlers(), dc, n); - VmLineNumberMap jnodeLineMap = method.getBytecode().getLineNrs(); - int [] lineMap = new int[jnodeLineMap.getLength()]; - for (int i = 0; i < lineMap.length; i++) { - int startPC = jnodeLineMap.getStartPCAt(i); - int lineNumber = jnodeLineMap.getLineNrAt(i); - lineMap[i] = (lineNumber << BITS_IN_SHORT) | startPC; + if (n != 0) { + eMap = new VM_ExceptionHandlerMap(method.getBytecode().getExceptionHandlers(), dc, n); } - return jikesMethod = new VM_NormalMethod(dc, mr, method.getModifiers(), + VmLineNumberMap jnodeLineMap = method.getBytecode().getLineNrs(); + int [] lineMap; + if (jnodeLineMap == null) { + // FIXME ... figure out why this happens + lineMap = null; + } else { + lineMap = new int[jnodeLineMap.getLength()]; + for (int i = 0; i < lineMap.length; i++) { + int startPC = jnodeLineMap.getStartPCAt(i); + int lineNumber = jnodeLineMap.getLineNrAt(i); + lineMap[i] = (lineNumber << BITS_IN_SHORT) | startPC; + } + } + VM_NormalMethod jikesMethod = new VM_NormalMethod(dc, mr, method.getModifiers(), null, method.getBytecode().getNoLocals(), method.getNoArguments(), bcodes, eMap, lineMap, method); - - + return jikesMethod; } public int getSelector() { - return ((VmMethod)jnodeMember).getSelector(); + return ((VmMethod) jnodeMember).getSelector(); } public Offset getTibOffset() { - return Offset.fromIntZeroExtend(((VmInstanceMethod)jnodeMember).getTibOffset()); + return Offset.fromIntZeroExtend(((VmInstanceMethod) jnodeMember).getTibOffset()); } Modified: branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_NormalMethod.java =================================================================== --- branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_NormalMethod.java 2009-09-18 07:00:06 UTC (rev 5680) +++ branches/jikesRVM/core/src/core/com/ibm/JikesRVM/classloader/VM_NormalMethod.java 2009-09-18 07:23:15 UTC (rev 5681) @@ -132,7 +132,7 @@ /** * bytecodes for this method (null --> none) */ - private final byte[] bytecodes; + private final VM_BytecodeStream bytecodes; // Extra fields for on-stack replacement // TODO: rework the system so we don't waste space for this on the VM_Method @@ -152,12 +152,12 @@ private VM_ExceptionHandlerMap exceptionHandlerMap; public VM_NormalMethod(VM_Class dc, VM_MemberReference mr, int mo, - VM_TypeReference[] et, int lw, int ow, byte[] bc, + VM_TypeReference[] et, int lw, int ow, byte[] bcodes, VM_ExceptionHandlerMap eMap, int[] lm, VmMethod ref) { super(dc, mr, mo, et, ref); localWords = lw; operandWords = ow; - bytecodes = bc; + bytecodes = new VM_BytecodeStream(this, bcodes); exceptionHandlerMap = eMap; lineNumberMap = lm; computeSummary(); @@ -188,7 +188,7 @@ * @return object representing the bytecodes */ public final VM_BytecodeStream getBytecodes() { - return new VM_BytecodeStream(this, bytecodes); + return new VM_BytecodeStream(bytecodes); } @@ -257,10 +257,10 @@ if (VM.VerifyAssertions) VM._assert(this.synthesizedBytecodes == null); - byte[] newBytecodes = new byte[prologue.length + bytecodes.length]; + byte[] newBytecodes = new byte[prologue.length + bytecodes.length()]; System.arraycopy(prologue, 0, newBytecodes, 0, prologue.length); - System.arraycopy(bytecodes, 0, newBytecodes, prologue.length, - bytecodes.length); + System.arraycopy(bytecodes.bytecodes(), 0, newBytecodes, prologue.length, + bytecodes.length()); this.osrPrologue = prologue; this.synthesizedBytecodes = newBytecodes; Modified: branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java =================================================================== --- branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java 2009-09-18 07:00:06 UTC (rev 5680) +++ branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java 2009-09-18 07:23:15 UTC (rev 5681) @@ -1034,7 +1034,9 @@ rejectNatives); if (bc != null) { mts.setModifier(false, Modifier.ACC_NATIVE); + mts.setModifier(true, Modifier.ACC_REPLACED); mts.setBytecode(bc); + mts.setRealDeclaringClass(bc.getMethod().getDeclaringClass()); } else { if (rejectNatives) { throw new ClassFormatError("Native method " + mts); Modified: branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/Modifier.java =================================================================== --- branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/Modifier.java 2009-09-18 07:00:06 UTC (rev 5680) +++ branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/Modifier.java 2009-09-18 07:23:15 UTC (rev 5681) @@ -62,6 +62,12 @@ public static final int ACC_MAGIC = 0x10000000; // C /** + * Is this a replaced method; i.e. one declared as native and + * then replaced with a Java method by the boot image builder. + */ + public static final int ACC_REPLACED = 0x40000000; + + /** * Is this a special method (init, clinit) */ public static final int ACC_SPECIAL = 0x80000000; @@ -114,6 +120,10 @@ return ((modifier & ACC_NATIVE) != 0); } + public static boolean isReplaced(int modifier) { + return ((modifier & ACC_REPLACED) != 0); + } + public static boolean isInterface(int modifier) { return ((modifier & ACC_INTERFACE) != 0); } Modified: branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/VmMember.java =================================================================== --- branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/VmMember.java 2009-09-18 07:00:06 UTC (rev 5680) +++ branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/VmMember.java 2009-09-18 07:23:15 UTC (rev 5681) @@ -44,10 +44,14 @@ */ private int modifiers; /** - * Declaring class of this member + * Notional declaring class of this member */ protected final VmType<?> declaringClass; /** + * Actual declaring class of this member + */ + protected VmType<?> realDeclaringClass; + /** * Hashcode of name+signature */ private final int cachedHashCode; @@ -60,7 +64,8 @@ * @param modifiers * @param declaringClass */ - protected VmMember(String name, String signature, int modifiers, VmType declaringClass) { + protected VmMember(String name, String signature, int modifiers, + VmType declaringClass) { if (name.equals("<clinit>")) { modifiers |= Modifier.ACC_INITIALIZER; } else if (name.equals("<init>")) { @@ -73,6 +78,7 @@ this.signature = signature; this.modifiers = modifiers; this.declaringClass = declaringClass; + this.realDeclaringClass = declaringClass; this.cachedHashCode = calcHashCode(name, signature); } @@ -133,7 +139,7 @@ } /** - * Gets the Class i'm declared in. + * Gets the Class i'm notionally declared in. * * @return VmClass */ @@ -144,6 +150,26 @@ } /** + * Gets the Class i'm actually declared in. This differs from the + * notional declaring class if this is a native method that has been + * replaced by a Java method. + * + * @return VmClass + */ + @KernelSpace + @org.jnode.annotation.Uninterruptible + public final VmType<?> getRealDeclaringClass() { + return realDeclaringClass; + } + + /** + * Sets the Class i'm actually declared in. + */ + public void setRealDeclaringClass(VmType<?> realDeclaringClass) { + this.realDeclaringClass = realDeclaringClass; + } + + /** * Is this member public? * * @return boolean Modified: branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/VmMethod.java =================================================================== --- branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/VmMethod.java 2009-09-18 07:00:06 UTC (rev 5680) +++ branches/jikesRVM/core/src/core/org/jnode/vm/classmgr/VmMethod.java 2009-09-18 07:23:15 UTC (rev 5681) @@ -113,7 +113,7 @@ * @param declaringClass */ protected VmMethod(String name, String signature, int modifiers, - VmType<?> declaringClass) { + VmType<?> declaringClass) { super( name, signature, @@ -310,7 +310,11 @@ public final boolean isNative() { return Modifier.isNative(getModifiers()); } - + + public boolean isReplacement() { + return Modifier.isReplaced(getModifiers()); + } + public final boolean isSpecial() { return Modifier.isSpecial(getModifiers()); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |