src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Tue Jul 8 14:06:47 2014
--- new/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Tue Jul 8 14:06:47 2014
*** 33,42 ****
--- 33,43 ----
import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.LambdaForm.BasicType.*;
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
+ import java.lang.invoke.MethodHandleImpl.ArrayAccessor;
import sun.invoke.util.ValueConversions;
import sun.invoke.util.VerifyAccess;
import sun.invoke.util.VerifyType;
import sun.invoke.util.Wrapper;
import sun.reflect.misc.ReflectUtil;
*** 425,434 ****
--- 426,469 ----
}
private void emitAstoreInsn(int index) {
emitStoreInsn(L_TYPE, index);
}
+ private byte arrayTypeCode(Wrapper elementType) {
+ switch (elementType) {
+ case BOOLEAN: return Opcodes.T_BOOLEAN;
+ case BYTE: return Opcodes.T_BYTE;
+ case CHAR: return Opcodes.T_CHAR;
+ case SHORT: return Opcodes.T_SHORT;
+ case INT: return Opcodes.T_INT;
+ case LONG: return Opcodes.T_LONG;
+ case FLOAT: return Opcodes.T_FLOAT;
+ case DOUBLE: return Opcodes.T_DOUBLE;
+ case OBJECT: return 0; // in place of Opcodes.T_OBJECT
+ default: throw new InternalError();
+ }
+ }
+
+ private int arrayInsnOpcode(byte tcode, int aaop) throws InternalError {
+ assert(aaop == Opcodes.AASTORE || aaop == Opcodes.AALOAD);
+ int xas;
+ switch (tcode) {
+ case Opcodes.T_BOOLEAN: xas = Opcodes.BASTORE; break;
+ case Opcodes.T_BYTE: xas = Opcodes.BASTORE; break;
+ case Opcodes.T_CHAR: xas = Opcodes.CASTORE; break;
+ case Opcodes.T_SHORT: xas = Opcodes.SASTORE; break;
+ case Opcodes.T_INT: xas = Opcodes.IASTORE; break;
+ case Opcodes.T_LONG: xas = Opcodes.LASTORE; break;
+ case Opcodes.T_FLOAT: xas = Opcodes.FASTORE; break;
+ case Opcodes.T_DOUBLE: xas = Opcodes.DASTORE; break;
+ case 0: xas = Opcodes.AASTORE; break;
+ default: throw new InternalError();
+ }
+ return xas - Opcodes.AASTORE + aaop;
+ }
+
+
private void freeFrameLocal(int oldFrameLocal) {
int i = indexForFrameLocal(oldFrameLocal);
if (i < 0) return;
BasicType type = localTypes[i];
int newFrameLocal = makeLocalTemp(type);
*** 614,623 ****
--- 649,662 ----
} else if (isGuardWithCatch(i)) {
onStack = emitGuardWithCatch(i);
i = i+2; // Jump to the end of GWC idiom
} else if (isNewArray(rtype, name)) {
emitNewArray(rtype, name);
+ } else if (isArrayLoad(member)) {
+ emitArrayLoad(name);
+ } else if (isArrayStore(member)) {
+ emitArrayStore(name);
} else if (isStaticallyInvocable(member)) {
emitStaticInvoke(name);
} else {
emitInvoke(name);
}
*** 632,641 ****
--- 671,709 ----
final byte[] classFile = cw.toByteArray();
maybeDump(className, classFile);
return classFile;
}
+ boolean isArrayLoad(MemberName member) {
+ return member != null &&
+ member.getDeclaringClass() == ArrayAccessor.class &&
+ member.getName() != null &&
+ member.getName().startsWith("getElement");
+ }
+
+ boolean isArrayStore(MemberName member) {
+ return member != null &&
+ member.getDeclaringClass() == ArrayAccessor.class &&
+ member.getName() != null &&
+ member.getName().startsWith("setElement");
+ }
+
+ void emitArrayLoad(Name name) { emitArrayOp(name, Opcodes.AALOAD); }
+ void emitArrayStore(Name name) { emitArrayOp(name, Opcodes.AASTORE); }
+
+ void emitArrayOp(Name name, int arrayOpcode) {
+ assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE;
+ Class<?> elementType = name.function.methodType().parameterType(0).getComponentType();
+ assert elementType != null;
+ emitPushArguments(name);
+ if (elementType.isPrimitive()) {
+ Wrapper w = Wrapper.forPrimitiveType(elementType);
+ arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode);
+ }
+ mv.visitInsn(arrayOpcode);
+ }
+
/**
* Emit an invoke for the given name.
*/
void emitInvoke(Name name) {
assert(!isLinkerMethodInvoke(name)); // should use the static path for these
*** 839,848 ****
--- 907,921 ----
if (fn != ValueConversions.varargsArray(rtype, size))
return false;
return true;
}
+ static boolean match(MemberName member, MethodHandle fn) {
+ if (member == null || fn == null) return false;
+ return member.equals(fn.internalMemberName());
+ }
+
/**
* Check if MemberName is a call to a method named {@code name} in class {@code declaredClass}.
*/
private boolean memberRefersTo(MemberName member, Class<?> declaringClass, String name) {
return member != null &&
src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File