提交 237bbe7d 编写于 作者: V vlivanov

8037210: Get rid of char-based descriptions 'J' of basic types

Reviewed-by: jrose, psandoz, twisti
上级 6aadd150
......@@ -31,6 +31,7 @@ import java.util.Arrays;
import sun.invoke.util.VerifyAccess;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.LambdaForm.BasicType.*;
import static java.lang.invoke.MethodTypeForm.*;
import static java.lang.invoke.MethodHandleStatics.*;
import java.lang.ref.WeakReference;
......@@ -124,11 +125,6 @@ class DirectMethodHandle extends MethodHandle {
return new Constructor(mtype, lform, ctor, init, instanceClass);
}
@Override
MethodHandle copyWith(MethodType mt, LambdaForm lf) {
return new DirectMethodHandle(mt, lf, member);
}
@Override
String internalProperties() {
return "/DMH="+member.toString();
......@@ -146,9 +142,9 @@ class DirectMethodHandle extends MethodHandle {
}
@Override
MethodHandle bindArgument(int pos, char basicType, Object value) {
MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
// If the member needs dispatching, do so.
if (pos == 0 && basicType == 'L') {
if (pos == 0 && basicType == L_TYPE) {
DirectMethodHandle concrete = maybeRebind(value);
if (concrete != null)
return concrete.bindReceiver(value);
......@@ -274,7 +270,7 @@ class DirectMethodHandle extends MethodHandle {
result = NEW_OBJ;
}
names[LINKER_CALL] = new Name(linker, outArgs);
lambdaName += "_" + LambdaForm.basicTypeSignature(mtype);
lambdaName += "_" + shortenSignature(basicTypeSignature(mtype));
LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
// This is a tricky bit of code. Don't send it through the LF interpreter.
lform.compileToBytecode();
......
......@@ -27,12 +27,12 @@ package java.lang.invoke;
import java.util.*;
import java.lang.invoke.LambdaForm.BasicType;
import sun.invoke.util.*;
import sun.misc.Unsafe;
import static java.lang.invoke.MethodHandleStatics.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.lang.invoke.LambdaForm.BasicType.*;
/**
* A method handle is a typed, directly executable reference to an underlying method,
......@@ -731,7 +731,7 @@ public abstract class MethodHandle {
* <li>If the return type <em>T0</em> is void and <em>T1</em> a primitive,
* a zero value is introduced.
* </ul>
* (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types,
* (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types,
* because neither corresponds specifically to the <em>dynamic type</em> of any
* actual argument or return value.)
* <p>
......@@ -1376,7 +1376,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
}
/*non-public*/
MethodHandle bindArgument(int pos, char basicType, Object value) {
MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
// Override this if it can be improved.
return rebind().bindArgument(pos, basicType, value);
}
......@@ -1384,26 +1384,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
/*non-public*/
MethodHandle bindReceiver(Object receiver) {
// Override this if it can be improved.
return bindArgument(0, 'L', receiver);
}
/*non-public*/
MethodHandle bindImmediate(int pos, char basicType, Object value) {
// Bind an immediate value to a position in the arguments.
// This means, elide the respective argument,
// and replace all references to it in NamedFunction args with the specified value.
// CURRENT RESTRICTIONS
// * only for pos 0 and UNSAFE (position is adjusted in MHImpl to make API usable for others)
assert pos == 0 && basicType == 'L' && value instanceof Unsafe;
MethodType type2 = type.dropParameterTypes(pos, pos + 1); // adjustment: ignore receiver!
LambdaForm form2 = form.bindImmediate(pos + 1, basicType, value); // adjust pos to form-relative pos
return copyWith(type2, form2);
}
/*non-public*/
MethodHandle copyWith(MethodType mt, LambdaForm lf) {
throw new InternalError("copyWith: " + this.getClass());
return bindArgument(0, L_TYPE, receiver);
}
/*non-public*/
......
......@@ -412,7 +412,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
@Override
MethodHandle bindArgument(int pos, char basicType, Object value) {
MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
return asFixedArity().bindArgument(pos, basicType, value);
}
......
......@@ -78,7 +78,7 @@ class MethodHandleNatives {
// The JVM calls MethodHandleNatives.<clinit>. Cascade the <clinit> calls as needed:
MethodHandleImpl.initStatics();
}
}
// All compile-time constants go here.
// There is an opportunity to check them against the JVM's idea of them.
......@@ -293,6 +293,17 @@ class MethodHandleNatives {
Class<?> caller = (Class<?>)callerObj;
String name = nameObj.toString().intern();
MethodType type = (MethodType)typeObj;
if (!TRACE_METHOD_LINKAGE)
return linkCallSiteImpl(caller, bootstrapMethod, name, type,
staticArguments, appendixResult);
return linkCallSiteTracing(caller, bootstrapMethod, name, type,
staticArguments, appendixResult);
}
static MemberName linkCallSiteImpl(Class<?> caller,
MethodHandle bootstrapMethod,
String name, MethodType type,
Object staticArguments,
Object[] appendixResult) {
CallSite callSite = CallSite.makeSite(bootstrapMethod,
name,
type,
......@@ -306,6 +317,30 @@ class MethodHandleNatives {
return Invokers.linkToCallSiteMethod(type);
}
}
// Tracing logic:
static MemberName linkCallSiteTracing(Class<?> caller,
MethodHandle bootstrapMethod,
String name, MethodType type,
Object staticArguments,
Object[] appendixResult) {
Object bsmReference = bootstrapMethod.internalMemberName();
if (bsmReference == null) bsmReference = bootstrapMethod;
Object staticArglist = (staticArguments instanceof Object[] ?
java.util.Arrays.asList((Object[]) staticArguments) :
staticArguments);
System.out.println("linkCallSite "+caller.getName()+" "+
bsmReference+" "+
name+type+"/"+staticArglist);
try {
MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type,
staticArguments, appendixResult);
System.out.println("linkCallSite => "+res+" + "+appendixResult[0]);
return res;
} catch (Throwable ex) {
System.out.println("linkCallSite => throw "+ex);
throw ex;
}
}
/**
* The JVM wants a pointer to a MethodType. Oblige it by finding or creating one.
......
......@@ -65,6 +65,16 @@ import sun.misc.Unsafe;
COMPILE_THRESHOLD = (Integer) values[4];
}
/** Tell if any of the debugging switches are turned on.
* If this is the case, it is reasonable to perform extra checks or save extra information.
*/
/*non-public*/ static boolean debugEnabled() {
return (DEBUG_METHOD_HANDLE_NAMES |
DUMP_CLASS_FILES |
TRACE_INTERPRETER |
TRACE_METHOD_LINKAGE);
}
/*non-public*/ static String getNameString(MethodHandle target, MethodType type) {
if (type == null)
type = target.type();
......@@ -93,6 +103,9 @@ import sun.misc.Unsafe;
}
// handy shared exception makers (they simplify the common case code)
/*non-public*/ static InternalError newInternalError(String message) {
return new InternalError(message);
}
/*non-public*/ static InternalError newInternalError(String message, Throwable cause) {
return new InternalError(message, cause);
}
......
......@@ -37,13 +37,13 @@ import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants;
import java.lang.invoke.LambdaForm.BasicType;
import static java.lang.invoke.LambdaForm.BasicType.*;
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
import java.util.concurrent.ConcurrentHashMap;
import sun.security.util.SecurityConstants;
/**
* This class consists exclusively of static methods that operate on or return
* method handles. They fall into several categories:
......@@ -2202,12 +2202,12 @@ assert((int)twice.invokeExact(21) == 42);
Object value = values[i];
Class<?> ptype = oldType.parameterType(pos+i);
if (ptype.isPrimitive()) {
char btype = 'I';
BasicType btype = I_TYPE;
Wrapper w = Wrapper.forPrimitiveType(ptype);
switch (w) {
case LONG: btype = 'J'; break;
case FLOAT: btype = 'F'; break;
case DOUBLE: btype = 'D'; break;
case LONG: btype = J_TYPE; break;
case FLOAT: btype = F_TYPE; break;
case DOUBLE: btype = D_TYPE; break;
}
// perform unboxing and/or primitive conversion
value = w.convert(value, ptype);
......@@ -2218,7 +2218,7 @@ assert((int)twice.invokeExact(21) == 42);
if (pos == 0) {
result = result.bindReceiver(value);
} else {
result = result.bindArgument(pos, 'L', value);
result = result.bindArgument(pos, L_TYPE, value);
}
}
return result;
......
......@@ -26,9 +26,7 @@
package java.lang.invoke;
import static java.lang.invoke.LambdaForm.*;
import static java.lang.invoke.MethodHandleNatives.Constants.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.lang.invoke.LambdaForm.BasicType.*;
/**
* A method handle whose behavior is determined only by its LambdaForm.
......@@ -44,7 +42,7 @@ final class SimpleMethodHandle extends MethodHandle {
}
@Override
MethodHandle bindArgument(int pos, char basicType, Object value) {
MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
MethodType type2 = type().dropParameterTypes(pos, pos+1);
LambdaForm form2 = internalForm().bind(1+pos, BoundMethodHandle.SpeciesData.EMPTY);
return BoundMethodHandle.bindSingle(type2, form2, basicType, value);
......@@ -61,10 +59,4 @@ final class SimpleMethodHandle extends MethodHandle {
LambdaForm form2 = internalForm().permuteArguments(1, reorder, basicTypes(newType.parameterList()));
return new SimpleMethodHandle(newType, form2);
}
@Override
MethodHandle copyWith(MethodType mt, LambdaForm lf) {
return new SimpleMethodHandle(mt, lf);
}
}
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/* @test
* @summary unit tests for java.lang.invoke.LambdaForm
* @run junit/othervm test.java.lang.invoke.LambdaFormTest
*/
package test.java.lang.invoke;
import org.junit.Test;
import java.lang.reflect.Method;
import static org.junit.Assert.*;
public class LambdaFormTest {
static final Method M_shortenSignature;
static {
try {
Class<?> impl = Class.forName("java.lang.invoke.LambdaForm", false, null);
Method m = impl.getDeclaredMethod("shortenSignature", String.class);
m.setAccessible(true);
M_shortenSignature = m;
} catch(Exception e) {
throw new AssertionError(e);
}
}
public static String shortenSignature(String signature) throws ReflectiveOperationException {
return (String)M_shortenSignature.invoke(null, signature);
}
@Test
public void testShortenSignature() throws ReflectiveOperationException {
for (String s : new String[] {
// invariant strings:
"L", "LL", "ILL", "LIL", "LLI", "IILL", "ILIL", "ILLI",
// a few mappings:
"LLL=L3", "LLLL=L4", "LLLLLLLLLL=L10",
"IIIDDD=I3D3", "IDDD=ID3", "IIDDD=IID3", "IIID=I3D", "IIIDD=I3DD"
}) {
String s2 = s.substring(s.indexOf('=')+1);
String s1 = s.equals(s2) ? s : s.substring(0, s.length() - s2.length() - 1);
// mix the above cases with before and after reps of Z*
for (int k = -3; k <= 3; k++) {
String beg = (k < 0 ? "ZZZZ".substring(-k) : "");
String end = (k > 0 ? "ZZZZ".substring(+k) : "");
String ks1 = beg+s1+end;
String ks2 = shortenSignature(beg)+s2+shortenSignature(end);
String ks3 = shortenSignature(ks1);
assertEquals(ks2, ks3);
}
}
}
public static void main(String[] args) throws ReflectiveOperationException {
LambdaFormTest test = new LambdaFormTest();
test.testShortenSignature();
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册