meth: fix bug with BMH argument location
authorjrose
Sat Sep 06 20:29:59 2008 -0700 (14 months ago)
changeset 94083d62b930b
parent 876dd10b26151
child 107ae462165f50
meth: fix bug with BMH argument location
meth.patch
--- a/meth.patch Tue Aug 26 02:44:01 2008 -0700
+++ b/meth.patch Sat Sep 06 20:29:59 2008 -0700
@@ -2040,17 +2040,17 @@ new file mode 100644
+ rslotCount += lrc;
+ }
+ if (lac != 0) {
-+ int slot = ptypeCount + lac;
-+ slotToArgTab = new int[slot+1];
-+ argToSlotTab = new int[ptypeCount];
-+ for (int i = 0; i < epts.length; i++) {
-+ Class<?> pt = epts[i];
-+ if (hasTwoArgSlots(pt)) --slot;
-+ --slot;
-+ slotToArgTab[slot] = i+1;
-+ argToSlotTab[i] = slot;
-+ }
-+ assert(slot == 0); // filled the table
++ int slot = ptypeCount + lac;
++ slotToArgTab = new int[slot+1];
++ argToSlotTab = new int[ptypeCount];
++ for (int i = 0; i < epts.length; i++) {
++ Class<?> pt = epts[i];
++ if (hasTwoArgSlots(pt)) --slot;
++ --slot;
++ slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note
++ argToSlotTab[i] = slot;
++ }
++ assert(slot == 0); // filled the table
+ }
+ this.primCounts = pack(lrc, prc, lac, pac);
+ } else {
@@ -2060,10 +2060,10 @@ new file mode 100644
+ if (slotToArgTab == null) {
+ int slot = ptypeCount; // first arg is deepest in stack
+ slotToArgTab = new int[slot+1];
-+ argToSlotTab = new int[ptypeCount];
++ argToSlotTab = new int[ptypeCount];
+ for (int i = 0; i < ptypeCount; i++) {
+ --slot;
-+ slotToArgTab[slot] = i+1;
++ slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note
+ argToSlotTab[i] = slot;
+ }
+ }
@@ -2905,7 +2905,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/share/classes/java/dyn/impl/BMH.java
-@@ -0,0 +1,61 @@
+@@ -0,0 +1,65 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -2949,6 +2949,10 @@ new file mode 100644
+ this.receiver = receiver;
+ MH.init(this, mh, receiver);
+ checkHandler();
++ // FIXME: The JVM should have done this:
++ MethodTypeForm form = MethodTypeForm.of(type());
++ int argSlot = form.parameterSlotCount();
++ MH.setVMDataArgSlot(this, argSlot);
+ }
+
+ /** Make sure the receiver matches the first argument of the
@@ -3086,7 +3090,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/share/classes/java/dyn/impl/MH.java
-@@ -0,0 +1,242 @@
+@@ -0,0 +1,252 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -3314,6 +3318,16 @@ new file mode 100644
+ */
+ static native Object getVMRef(MH self);
+
++ /** Hack the vmData field, knowing that it is of the form [index | argslot].
++ * Leave index alone, set argslot to refer to the Nth argument.
++ * The JVM should do this, not the Java code, because vmdata is JVM-private.
++ */
++ static void setVMDataArgSlot(MH self, int argSlot) {
++ System.out.println("patching vmdata "+Long.toHexString(self.vmdata)+" of "+self);
++ long index = self.vmdata >> 32;
++ self.vmdata = (index << 32) | (argSlot << 32 >>> 32);
++ }
++
+ private static native void registerNatives();
+ static final boolean JVM_SUPPORT;
+ static {
@@ -3430,7 +3444,7 @@ new file mode 100644
new file mode 100644
--- /dev/null
+++ b/src/share/classes/java/dyn/util/MethodHandleInvoker.java
-@@ -0,0 +1,317 @@
+@@ -0,0 +1,330 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -3502,6 +3516,8 @@ new file mode 100644
+ { throw wrongType(mh); }
+ public Object invoke_LL(MethodHandle mh, Object a0)
+ { throw wrongType(mh); }
++ public Object invoke_LI(MethodHandle mh, int a0)
++ { throw wrongType(mh); }
+ public Object invoke_LLL(MethodHandle mh, Object a0, Object a1)
+ { throw wrongType(mh); }
+ public Object invoke_LLI(MethodHandle mh, Object a0, int a1)
@@ -3515,6 +3531,7 @@ new file mode 100644
+ public abstract long fake_invoke_J();
+ public abstract double fake_invoke_D();
+ public abstract Object fake_invoke_LL(Object a0);
++ public abstract Object fake_invoke_LI(int a0);
+ public abstract Object fake_invoke_LLL(Object a0, Object a1);
+ public abstract Object fake_invoke_LLI(Object a0, int a1);
+ }
@@ -3543,6 +3560,15 @@ new file mode 100644
+ @Override public Object invoke_LL(MethodHandle mh, Object a0) {
+ checkType(mh);
+ return ((FakeMethodHandle)mh).fake_invoke_LL(a0);
++ }
++ }
++
++ static class LI extends MethodHandleInvoker {
++ static final int FINGERPRINT = fL | fI<<fA0;
++ public LI(MethodType type) { super(type); }
++ @Override public Object invoke_LI(MethodHandle mh, int a0) {
++ checkType(mh);
++ return ((FakeMethodHandle)mh).fake_invoke_LI(a0);
+ }
+ }
+
@@ -3578,6 +3604,7 @@ new file mode 100644
+ case V.FINGERPRINT: template = V.class; break;
+ case L.FINGERPRINT: template = L.class; break;
+ case LL.FINGERPRINT: template = LL.class; break;
++ case LI.FINGERPRINT: template = LI.class; break;
+ case LLL.FINGERPRINT: template = LLL.class; break;
+ case LLI.FINGERPRINT: template = LLI.class; break;
+ }