Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2015-06-23 10:24:39 +0300
committerjfrijters <jfrijters>2015-06-23 10:24:39 +0300
commit75b9e730c8697759745ff79584bed644e4f7e7a5 (patch)
tree2e287686c2ce07202eeca905c4602b98c208f9e3
parente6322146dbaf32f9586401cd48e5df1abf40a521 (diff)
Fixed regression introduced with pairwise convert optimization. MethodHandle String construction is now handled much more cleanly by hooking DirectMethodHandle.makeAllocator() instead of fiddling with the MemberName.
-rw-r--r--openjdk/map.xml38
-rw-r--r--runtime/Dummy.OpenJDK.Core.cs19
-rw-r--r--runtime/openjdk/java.lang.invoke.cs77
3 files changed, 69 insertions, 65 deletions
diff --git a/openjdk/map.xml b/openjdk/map.xml
index 4bbb3412..0b50611d 100644
--- a/openjdk/map.xml
+++ b/openjdk/map.xml
@@ -2888,6 +2888,15 @@
<ret />
</body>
</method>
+ <method name="_type" sig="(Ljava.lang.invoke.MethodType;)V" modifiers="final">
+ <attribute type="IKVM.Attributes.HideFromJavaAttribute" sig="()V" />
+ <body>
+ <ldarg_0 />
+ <ldarg_1 />
+ <stfld class="java.lang.invoke.MemberName" name="type" sig="Ljava.lang.Object;" />
+ <ret />
+ </body>
+ </method>
<method name="_flags" sig="()I" modifiers="final">
<attribute type="IKVM.Attributes.HideFromJavaAttribute" sig="()V" />
<body>
@@ -2969,20 +2978,29 @@
</replace-method-call>
</method>
</class>
- <class name="java.lang.invoke.MethodHandles$Lookup">
- <!-- We hook this to undo the fiddling we do to support string constructors -->
- <method name="revealDirect" sig="(Ljava.lang.invoke.MethodHandle;)Ljava.lang.invoke.MethodHandleInfo;">
- <replace-method-call class="java.lang.invoke.MethodHandle" name="internalMemberName" sig="()Ljava.lang.invoke.MemberName;">
- <code>
- <call type="Java_java_lang_invoke_MethodHandleNatives" name="internalMemberName" sig="(Ljava.lang.invoke.MethodHandle;)Ljava.lang.invoke.MemberName;" />
- </code>
- </replace-method-call>
- </method>
- </class>
<class name="java.lang.invoke.DirectMethodHandle">
+ <method name="_preparedLambdaForm" sig="(Ljava.lang.invoke.MethodType;I)Ljava.lang.invoke.LambdaForm;" modifiers="static">
+ <body>
+ <ldarg_0 />
+ <ldarg_1 />
+ <call class="java.lang.invoke.DirectMethodHandle" name="preparedLambdaForm" sig="(Ljava.lang.invoke.MethodType;I)Ljava.lang.invoke.LambdaForm;" />
+ <ret />
+ </body>
+ </method>
<method name="allocateInstance" sig="(Ljava.lang.Object;)Ljava.lang.Object;">
<attribute type="System.Security.SecuritySafeCriticalAttribute" sig="()V" />
</method>
+ <method name="makeAllocator" sig="(Ljava.lang.invoke.MemberName;)Ljava.lang.invoke.DirectMethodHandle;">
+ <prologue>
+ <ldarg_0 />
+ <call type="Java_java_lang_invoke_DirectMethodHandle" name="makeStringAllocator" sig="(Ljava.lang.invoke.MemberName;)Ljava.lang.invoke.DirectMethodHandle;" />
+ <dup />
+ <brfalse name="continue" />
+ <ret />
+ <label name="continue" />
+ <pop />
+ </prologue>
+ </method>
</class>
<class name="java.lang.invoke.MethodType">
<field name="voidAdapter" sig="Ljava.lang.Object;" modifiers="">
diff --git a/runtime/Dummy.OpenJDK.Core.cs b/runtime/Dummy.OpenJDK.Core.cs
index e9968b28..95fce5b2 100644
--- a/runtime/Dummy.OpenJDK.Core.cs
+++ b/runtime/Dummy.OpenJDK.Core.cs
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2010 Jeroen Frijters
+ Copyright (C) 2010-2014 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -53,10 +53,8 @@ namespace java
namespace invoke
{
- public class MemberName { }
- public class AdapterMethodHandle { }
- public class BoundMethodHandle { }
public class DirectMethodHandle { }
+ public class MemberName { }
public class MethodType { }
public class MethodHandle { }
public class CallSite { }
@@ -64,8 +62,10 @@ namespace java
namespace reflect
{
- public class Constructor { }
- public class Method { }
+ public class Constructor : Executable { }
+ public class Executable { }
+ public class Field { }
+ public class Method : Executable { }
}
}
@@ -92,3 +92,10 @@ namespace java
public class Vector { }
}
}
+
+namespace sun.reflect
+{
+ public interface ConstructorAccessor { }
+ public interface FieldAccessor { }
+ public interface MethodAccessor { }
+}
diff --git a/runtime/openjdk/java.lang.invoke.cs b/runtime/openjdk/java.lang.invoke.cs
index 6929b6c5..5c892eba 100644
--- a/runtime/openjdk/java.lang.invoke.cs
+++ b/runtime/openjdk/java.lang.invoke.cs
@@ -31,6 +31,26 @@ using IKVM.Internal;
using java.lang.invoke;
using jlClass = java.lang.Class;
+static class Java_java_lang_invoke_DirectMethodHandle
+{
+ // this is called from DirectMethodHandle.makeAllocator() via a map.xml prologue patch
+ public static DirectMethodHandle makeStringAllocator(MemberName member)
+ {
+#if FIRST_PASS
+ return null;
+#else
+ // we cannot construct strings via the standard two-pass approach (allocateObject followed by constructor invocation),
+ // so we special case string construction here (to call our static factory method instead)
+ if (member.getDeclaringClass() == CoreClasses.java.lang.String.Wrapper.ClassObject)
+ {
+ MethodType mt = member.getMethodType().changeReturnType(CoreClasses.java.lang.String.Wrapper.ClassObject);
+ return new DirectMethodHandle(mt, DirectMethodHandle._preparedLambdaForm(mt, MethodTypeForm.LF_INVSTATIC), member, null);
+ }
+ return null;
+#endif
+ }
+}
+
static class Java_java_lang_invoke_MethodHandle
{
public static object invokeExact(MethodHandle thisObject, object[] args)
@@ -136,35 +156,6 @@ static class Java_java_lang_invoke_MethodHandleNatives
return tw.IsInstance(obj) || (tw == CoreClasses.cli.System.Object.Wrapper && obj is Array);
}
- // called from Lookup.revealDirect() (instead of MethodHandle.internalMemberName()) via map.xml replace-method-call
- public static MemberName internalMemberName(MethodHandle mh)
- {
-#if FIRST_PASS
- return null;
-#else
- MemberName mn = mh.internalMemberName();
- if (mn.isStatic() && mn.getName() == "<init>")
- {
- // HACK since we convert String constructors into static methods, we have to undo that here
- // Note that the MemberName we return is only used for a security check and by InfoFromMemberName (a MethodHandleInfo implementation),
- // so we don't need to make it actually invokable.
- MemberName alt = new MemberName();
- typeof(MemberName).GetField("clazz", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(alt, mn.getDeclaringClass());
- typeof(MemberName).GetField("name", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(alt, mn.getName());
- typeof(MemberName).GetField("type", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(alt, mn.getMethodType().changeReturnType(typeof(void)));
- int flags = mn._flags();
- flags -= MethodHandleNatives.Constants.MN_IS_METHOD;
- flags += MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR;
- flags &= ~(MethodHandleNatives.Constants.MN_REFERENCE_KIND_MASK << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT);
- flags |= MethodHandleNatives.Constants.REF_newInvokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
- flags &= ~MethodHandleNatives.Constants.ACC_STATIC;
- alt._flags(flags);
- return alt;
- }
- return mn;
-#endif
- }
-
public static void init(MemberName self, object refObj)
{
init(self, refObj, false);
@@ -209,6 +200,10 @@ static class Java_java_lang_invoke_MethodHandleNatives
{
flags |= MethodHandleNatives.Constants.REF_invokeStatic << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
}
+ else if (mw.IsConstructor && !wantSpecial)
+ {
+ flags |= MethodHandleNatives.Constants.REF_newInvokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
+ }
else if (mw.IsPrivate || mw.IsFinal || mw.IsConstructor || wantSpecial)
{
flags |= MethodHandleNatives.Constants.REF_invokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
@@ -232,16 +227,11 @@ static class Java_java_lang_invoke_MethodHandleNatives
{
parameters1[i] = mw.GetParameters()[i].ClassObject;
}
- MethodType mt = MethodType.methodType(typeof(string), parameters1);
- typeof(MemberName).GetField("type", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(self, mt);
- self.vmtarget = CreateMemberNameDelegate(mw, null, false, mt);
- flags -= MethodHandleNatives.Constants.REF_invokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
- flags += MethodHandleNatives.Constants.REF_invokeStatic << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
- flags -= MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR;
- flags += MethodHandleNatives.Constants.MN_IS_METHOD;
- flags += MethodHandleNatives.Constants.ACC_STATIC;
+ MethodType mt = MethodType.methodType(PrimitiveTypeWrapper.VOID.ClassObject, parameters1);
+ self._type(mt);
self._flags(flags);
self._clazz(mw.DeclaringType.ClassObject);
+ self.vmtarget = CreateMemberNameDelegate(mw, null, false, self.getMethodType().changeReturnType(CoreClasses.java.lang.String.Wrapper.ClassObject));
return;
}
self._flags(flags);
@@ -369,8 +359,7 @@ static class Java_java_lang_invoke_MethodHandleNatives
}
if (mw.IsConstructor && mw.DeclaringType == CoreClasses.java.lang.String.Wrapper)
{
- typeof(MemberName).GetField("type", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(self, self.getMethodType().changeReturnType(typeof(string)));
- self.vmtarget = CreateMemberNameDelegate(mw, caller, false, self.getMethodType());
+ self.vmtarget = CreateMemberNameDelegate(mw, caller, false, self.getMethodType().changeReturnType(CoreClasses.java.lang.String.Wrapper.ClassObject));
}
else if (!mw.IsConstructor || invokeSpecial || newInvokeSpecial)
{
@@ -398,16 +387,6 @@ static class Java_java_lang_invoke_MethodHandleNatives
{
self._flags(self._flags() | MemberName.CALLER_SENSITIVE);
}
- if (mw.IsConstructor && mw.DeclaringType == CoreClasses.java.lang.String.Wrapper)
- {
- int flags = self._flags();
- flags -= MethodHandleNatives.Constants.REF_invokeSpecial << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
- flags += MethodHandleNatives.Constants.REF_invokeStatic << MethodHandleNatives.Constants.MN_REFERENCE_KIND_SHIFT;
- flags -= MethodHandleNatives.Constants.MN_IS_CONSTRUCTOR;
- flags += MethodHandleNatives.Constants.MN_IS_METHOD;
- flags += MethodHandleNatives.Constants.ACC_STATIC;
- self._flags(flags);
- }
}
private static void ResolveField(MemberName self)