mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8366455: Move VarHandles.GuardMethodGenerator to execute on build
Reviewed-by: psandoz, redestad, erikj
This commit is contained in:
parent
1ebe949507
commit
cdc8b5eb83
@ -130,6 +130,9 @@ TOOL_PUBLICSUFFIXLIST = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_clas
|
||||
TOOL_FIXUPPANDOC = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
|
||||
build.tools.fixuppandoc.Main
|
||||
|
||||
TOOL_VARHANDLEGUARDMETHODGENERATOR = $(JAVA_SMALL) -cp $(BUILDTOOLS_OUTPUTDIR)/jdk_tools_classes \
|
||||
build.tools.methodhandle.VarHandleGuardMethodGenerator
|
||||
|
||||
################################################################################
|
||||
|
||||
# Executable javascript filter for man page generation using pandoc.
|
||||
|
||||
@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package build.tools.methodhandle;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.classfile.TypeKind;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A helper program to generate the VarHandleGuards class with a set of
|
||||
* static guard methods each of which corresponds to a particular shape and
|
||||
* performs a type check of the symbolic type descriptor with the VarHandle
|
||||
* type descriptor before linking/invoking to the underlying operation as
|
||||
* characterized by the operation member name on the VarForm of the
|
||||
* VarHandle.
|
||||
* <p>
|
||||
* The generated class essentially encapsulates pre-compiled LambdaForms,
|
||||
* one for each method, for the most common set of method signatures.
|
||||
* This reduces static initialization costs, footprint costs, and circular
|
||||
* dependencies that may arise if a class is generated per LambdaForm.
|
||||
* <p>
|
||||
* A maximum of L*T*S methods will be generated where L is the number of
|
||||
* access modes kinds (or unique operation signatures) and T is the number
|
||||
* of variable types and S is the number of shapes (such as instance field,
|
||||
* static field, or array access).
|
||||
* If there are 4 unique operation signatures, 5 basic types (Object, int,
|
||||
* long, float, double), and 3 shapes then a maximum of 60 methods will be
|
||||
* generated. However, the number is likely to be less since there may
|
||||
* be duplicate signatures.
|
||||
* <p>
|
||||
* Each method is annotated with @LambdaForm.Compiled to inform the runtime
|
||||
* that such methods should be treated as if a method of a class that is the
|
||||
* result of compiling a LambdaForm. Annotation of such methods is
|
||||
* important for correct evaluation of certain assertions and method return
|
||||
* type profiling in HotSpot.
|
||||
*
|
||||
* @see java.lang.invoke.GenerateJLIClassesHelper
|
||||
*/
|
||||
public final class VarHandleGuardMethodGenerator {
|
||||
|
||||
static final String CLASS_HEADER = """
|
||||
/*
|
||||
* Copyright (c) 2014, 2025, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package java.lang.invoke;
|
||||
|
||||
import jdk.internal.vm.annotation.AOTSafeClassInitializer;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
import jdk.internal.vm.annotation.Hidden;
|
||||
|
||||
// This file is generated by build.tools.methodhandle.VarHandleGuardMethodGenerator.
|
||||
// Do not edit!
|
||||
@AOTSafeClassInitializer
|
||||
final class VarHandleGuards {
|
||||
""";
|
||||
|
||||
static final String GUARD_METHOD_SIG_TEMPLATE = "<RETURN> <NAME>_<SIGNATURE>(<PARAMS>)";
|
||||
|
||||
static final String GUARD_METHOD_TEMPLATE =
|
||||
"""
|
||||
@ForceInline
|
||||
@LambdaForm.Compiled
|
||||
@Hidden
|
||||
static final <METHOD> throws Throwable {
|
||||
boolean direct = handle.checkAccessModeThenIsDirect(ad);
|
||||
if (direct && handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
|
||||
<RESULT_ERASED>MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);<RETURN_ERASED>
|
||||
} else {
|
||||
MethodHandle mh = handle.getMethodHandle(ad.mode);
|
||||
<RETURN>mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(<LINK_TO_INVOKER_ARGS>);
|
||||
}
|
||||
}""";
|
||||
|
||||
static final String GUARD_METHOD_TEMPLATE_V =
|
||||
"""
|
||||
@ForceInline
|
||||
@LambdaForm.Compiled
|
||||
@Hidden
|
||||
static final <METHOD> throws Throwable {
|
||||
boolean direct = handle.checkAccessModeThenIsDirect(ad);
|
||||
if (direct && handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
|
||||
MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);
|
||||
} else if (direct && handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
|
||||
MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);
|
||||
} else {
|
||||
MethodHandle mh = handle.getMethodHandle(ad.mode);
|
||||
mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(<LINK_TO_INVOKER_ARGS>);
|
||||
}
|
||||
}""";
|
||||
|
||||
// A template for deriving the operations
|
||||
// could be supported by annotating VarHandle directly with the
|
||||
// operation kind and shape
|
||||
interface VarHandleTemplate {
|
||||
Object get();
|
||||
|
||||
void set(Object value);
|
||||
|
||||
boolean compareAndSet(Object actualValue, Object expectedValue);
|
||||
|
||||
Object compareAndExchange(Object actualValue, Object expectedValue);
|
||||
|
||||
Object getAndUpdate(Object value);
|
||||
}
|
||||
|
||||
record HandleType(Class<?> receiver, Class<?>... intermediates) {
|
||||
}
|
||||
|
||||
public static void main(String... args) throws Throwable {
|
||||
if (args.length != 1) {
|
||||
System.err.println("Usage: java VarHandleGuardMethodGenerator VarHandleGuards.java");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
Path outputFile = Path.of(args[0]);
|
||||
|
||||
try (PrintWriter pw = new PrintWriter(Files.newBufferedWriter(
|
||||
outputFile,
|
||||
StandardCharsets.UTF_8,
|
||||
StandardOpenOption.CREATE,
|
||||
StandardOpenOption.TRUNCATE_EXISTING))) {
|
||||
print(pw);
|
||||
}
|
||||
}
|
||||
|
||||
public static void print(PrintWriter pw) {
|
||||
pw.println(CLASS_HEADER);
|
||||
|
||||
// Declare the stream of shapes
|
||||
List<HandleType> hts = List.of(
|
||||
// Object->T
|
||||
new HandleType(Object.class),
|
||||
|
||||
// <static>->T
|
||||
new HandleType(null),
|
||||
|
||||
// Array[index]->T
|
||||
new HandleType(Object.class, int.class),
|
||||
|
||||
// MS[base]->T
|
||||
new HandleType(Object.class, long.class),
|
||||
|
||||
// MS[base][offset]->T
|
||||
new HandleType(Object.class, long.class, long.class)
|
||||
);
|
||||
|
||||
// The 5 JVM calling convention types
|
||||
List<Class<?>> basicTypes = List.of(Object.class, int.class, long.class, float.class, double.class);
|
||||
|
||||
Stream.of(VarHandleTemplate.class.getMethods()).<MethodType>
|
||||
mapMulti((m, sink) -> {
|
||||
for (var ht : hts) {
|
||||
for (var bt : basicTypes) {
|
||||
sink.accept(generateMethodType(m, ht.receiver, bt, ht.intermediates));
|
||||
}
|
||||
}
|
||||
}).
|
||||
distinct().
|
||||
map(VarHandleGuardMethodGenerator::generateMethod).
|
||||
forEach(pw::println);
|
||||
|
||||
pw.println("}");
|
||||
}
|
||||
|
||||
static MethodType generateMethodType(Method m, Class<?> receiver, Class<?> value, Class<?>... intermediates) {
|
||||
Class<?> returnType = m.getReturnType() == Object.class
|
||||
? value : m.getReturnType();
|
||||
|
||||
List<Class<?>> params = new ArrayList<>();
|
||||
if (receiver != null)
|
||||
params.add(receiver);
|
||||
Collections.addAll(params, intermediates);
|
||||
for (var p : m.getParameters()) {
|
||||
params.add(value);
|
||||
}
|
||||
return MethodType.methodType(returnType, params);
|
||||
}
|
||||
|
||||
static String generateMethod(MethodType mt) {
|
||||
Class<?> returnType = mt.returnType();
|
||||
|
||||
var params = new LinkedHashMap<String, String>();
|
||||
params.put("handle", className(VarHandle.class));
|
||||
for (int i = 0; i < mt.parameterCount(); i++) {
|
||||
params.put("arg" + i, className(mt.parameterType(i)));
|
||||
}
|
||||
params.put("ad", "VarHandle.AccessDescriptor");
|
||||
|
||||
// Generate method signature line
|
||||
String RETURN = className(returnType);
|
||||
String NAME = "guard";
|
||||
String SIGNATURE = getSignature(mt);
|
||||
String PARAMS = params.entrySet().stream().
|
||||
map(e -> e.getValue() + " " + e.getKey()).
|
||||
collect(Collectors.joining(", "));
|
||||
String METHOD = GUARD_METHOD_SIG_TEMPLATE.
|
||||
replace("<RETURN>", RETURN).
|
||||
replace("<NAME>", NAME).
|
||||
replace("<SIGNATURE>", SIGNATURE).
|
||||
replace("<PARAMS>", PARAMS);
|
||||
|
||||
// Generate method
|
||||
params.remove("ad");
|
||||
|
||||
List<String> LINK_TO_STATIC_ARGS = new ArrayList<>(params.keySet());
|
||||
LINK_TO_STATIC_ARGS.add("handle.vform.getMemberName(ad.mode)");
|
||||
|
||||
List<String> LINK_TO_INVOKER_ARGS = new ArrayList<>(params.keySet());
|
||||
LINK_TO_INVOKER_ARGS.set(0, LINK_TO_INVOKER_ARGS.get(0) + ".asDirect()");
|
||||
|
||||
RETURN = returnType == void.class
|
||||
? ""
|
||||
: returnType == Object.class
|
||||
? "return "
|
||||
: "return (" + returnType.getName() + ") ";
|
||||
|
||||
String RESULT_ERASED = returnType == void.class
|
||||
? ""
|
||||
: returnType != Object.class
|
||||
? "return (" + returnType.getName() + ") "
|
||||
: "Object r = ";
|
||||
|
||||
String RETURN_ERASED = returnType != Object.class
|
||||
? ""
|
||||
: "\n return ad.returnType.cast(r);";
|
||||
|
||||
String template = returnType == void.class
|
||||
? GUARD_METHOD_TEMPLATE_V
|
||||
: GUARD_METHOD_TEMPLATE;
|
||||
return template.
|
||||
replace("<METHOD>", METHOD).
|
||||
replace("<NAME>", NAME).
|
||||
replaceAll("<RETURN>", RETURN).
|
||||
replace("<RESULT_ERASED>", RESULT_ERASED).
|
||||
replace("<RETURN_ERASED>", RETURN_ERASED).
|
||||
replaceAll("<LINK_TO_STATIC_ARGS>", String.join(", ", LINK_TO_STATIC_ARGS)).
|
||||
replace("<LINK_TO_INVOKER_ARGS>", String.join(", ", LINK_TO_INVOKER_ARGS))
|
||||
.indent(4);
|
||||
}
|
||||
|
||||
static String className(Class<?> c) {
|
||||
String n = c.getCanonicalName();
|
||||
if (n == null)
|
||||
throw new IllegalArgumentException("Not representable in source code: " + c);
|
||||
if (!c.isPrimitive() && c.getPackageName().equals("java.lang")) {
|
||||
n = n.substring("java.lang.".length());
|
||||
} else if (c.getPackageName().equals("java.lang.invoke")) {
|
||||
n = n.substring("java.lang.invoke.".length());
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static String getSignature(MethodType m) {
|
||||
StringBuilder sb = new StringBuilder(m.parameterCount() + 1);
|
||||
|
||||
for (int i = 0; i < m.parameterCount(); i++) {
|
||||
Class<?> pt = m.parameterType(i);
|
||||
sb.append(getCharType(pt));
|
||||
}
|
||||
|
||||
sb.append('_').append(getCharType(m.returnType()));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static char getCharType(Class<?> pt) {
|
||||
return TypeKind.from(pt).upperBound().descriptorString().charAt(0);
|
||||
}
|
||||
}
|
||||
@ -302,5 +302,17 @@ TARGETS += $(GENSRC_VARHANDLES)
|
||||
|
||||
################################################################################
|
||||
|
||||
GENSRC_VARHANDLEGUARDS := $(VARHANDLES_GENSRC_DIR)/VarHandleGuards.java
|
||||
|
||||
$(GENSRC_VARHANDLEGUARDS): $(BUILD_TOOLS_JDK)
|
||||
$(call LogInfo, Generating $@)
|
||||
$(call MakeTargetDir)
|
||||
$(TOOL_VARHANDLEGUARDMETHODGENERATOR) \
|
||||
$(GENSRC_VARHANDLEGUARDS)
|
||||
|
||||
TARGETS += $(GENSRC_VARHANDLEGUARDS)
|
||||
|
||||
################################################################################
|
||||
|
||||
endif # include guard
|
||||
include MakeIncludeEnd.gmk
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -657,242 +657,4 @@ final class VarHandles {
|
||||
!RuntimeException.class.isAssignableFrom(clazz) &&
|
||||
!Error.class.isAssignableFrom(clazz);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * A helper program to generate the VarHandleGuards class with a set of
|
||||
// * static guard methods each of which corresponds to a particular shape and
|
||||
// * performs a type check of the symbolic type descriptor with the VarHandle
|
||||
// * type descriptor before linking/invoking to the underlying operation as
|
||||
// * characterized by the operation member name on the VarForm of the
|
||||
// * VarHandle.
|
||||
// * <p>
|
||||
// * The generated class essentially encapsulates pre-compiled LambdaForms,
|
||||
// * one for each method, for the most set of common method signatures.
|
||||
// * This reduces static initialization costs, footprint costs, and circular
|
||||
// * dependencies that may arise if a class is generated per LambdaForm.
|
||||
// * <p>
|
||||
// * A maximum of L*T*S methods will be generated where L is the number of
|
||||
// * access modes kinds (or unique operation signatures) and T is the number
|
||||
// * of variable types and S is the number of shapes (such as instance field,
|
||||
// * static field, or array access).
|
||||
// * If there are 4 unique operation signatures, 5 basic types (Object, int,
|
||||
// * long, float, double), and 3 shapes then a maximum of 60 methods will be
|
||||
// * generated. However, the number is likely to be less since there
|
||||
// * be duplicate signatures.
|
||||
// * <p>
|
||||
// * Each method is annotated with @LambdaForm.Compiled to inform the runtime
|
||||
// * that such methods should be treated as if a method of a class that is the
|
||||
// * result of compiling a LambdaForm. Annotation of such methods is
|
||||
// * important for correct evaluation of certain assertions and method return
|
||||
// * type profiling in HotSpot.
|
||||
// */
|
||||
// public static class GuardMethodGenerator {
|
||||
//
|
||||
// static final String GUARD_METHOD_SIG_TEMPLATE = "<RETURN> <NAME>_<SIGNATURE>(<PARAMS>)";
|
||||
//
|
||||
// static final String GUARD_METHOD_TEMPLATE =
|
||||
// """
|
||||
// @ForceInline
|
||||
// @LambdaForm.Compiled
|
||||
// @Hidden
|
||||
// static final <METHOD> throws Throwable {
|
||||
// boolean direct = handle.checkAccessModeThenIsDirect(ad);
|
||||
// if (direct && handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
|
||||
// <RESULT_ERASED>MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);<RETURN_ERASED>
|
||||
// } else {
|
||||
// MethodHandle mh = handle.getMethodHandle(ad.mode);
|
||||
// <RETURN>mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(<LINK_TO_INVOKER_ARGS>);
|
||||
// }
|
||||
// }""";
|
||||
//
|
||||
// static final String GUARD_METHOD_TEMPLATE_V =
|
||||
// """
|
||||
// @ForceInline
|
||||
// @LambdaForm.Compiled
|
||||
// @Hidden
|
||||
// static final <METHOD> throws Throwable {
|
||||
// boolean direct = handle.checkAccessModeThenIsDirect(ad);
|
||||
// if (direct && handle.vform.methodType_table[ad.type] == ad.symbolicMethodTypeErased) {
|
||||
// MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);
|
||||
// } else if (direct && handle.vform.getMethodType_V(ad.type) == ad.symbolicMethodTypeErased) {
|
||||
// MethodHandle.linkToStatic(<LINK_TO_STATIC_ARGS>);
|
||||
// } else {
|
||||
// MethodHandle mh = handle.getMethodHandle(ad.mode);
|
||||
// mh.asType(ad.symbolicMethodTypeInvoker).invokeBasic(<LINK_TO_INVOKER_ARGS>);
|
||||
// }
|
||||
// }""";
|
||||
//
|
||||
// // A template for deriving the operations
|
||||
// // could be supported by annotating VarHandle directly with the
|
||||
// // operation kind and shape
|
||||
// interface VarHandleTemplate {
|
||||
// Object get();
|
||||
//
|
||||
// void set(Object value);
|
||||
//
|
||||
// boolean compareAndSet(Object actualValue, Object expectedValue);
|
||||
//
|
||||
// Object compareAndExchange(Object actualValue, Object expectedValue);
|
||||
//
|
||||
// Object getAndUpdate(Object value);
|
||||
// }
|
||||
//
|
||||
// record HandleType(Class<?> receiver, Class<?>... intermediates) {
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param args parameters
|
||||
// */
|
||||
// public static void main(String[] args) {
|
||||
// System.out.println("package java.lang.invoke;");
|
||||
// System.out.println();
|
||||
// System.out.println("import jdk.internal.vm.annotation.AOTSafeClassInitializer;");
|
||||
// System.out.println("import jdk.internal.vm.annotation.ForceInline;");
|
||||
// System.out.println("import jdk.internal.vm.annotation.Hidden;");
|
||||
// System.out.println();
|
||||
// System.out.println("// This class is auto-generated by " +
|
||||
// GuardMethodGenerator.class.getName() +
|
||||
// ". Do not edit.");
|
||||
// System.out.println("@AOTSafeClassInitializer");
|
||||
// System.out.println("final class VarHandleGuards {");
|
||||
//
|
||||
// System.out.println();
|
||||
//
|
||||
// // Declare the stream of shapes
|
||||
// List<HandleType> hts = List.of(
|
||||
// // Object->T
|
||||
// new HandleType(Object.class),
|
||||
//
|
||||
// // <static>->T
|
||||
// new HandleType(null),
|
||||
//
|
||||
// // Array[index]->T
|
||||
// new HandleType(Object.class, int.class),
|
||||
//
|
||||
// // MS[base]->T
|
||||
// new HandleType(Object.class, long.class),
|
||||
//
|
||||
// // MS[base][offset]->T
|
||||
// new HandleType(Object.class, long.class, long.class)
|
||||
// );
|
||||
//
|
||||
// Stream.of(VarHandleTemplate.class.getMethods()).<MethodType>
|
||||
// mapMulti((m, sink) -> {
|
||||
// for (var ht : hts) {
|
||||
// for (var bt : LambdaForm.BasicType.ARG_TYPES) {
|
||||
// sink.accept(generateMethodType(m, ht.receiver, bt.btClass, ht.intermediates));
|
||||
// }
|
||||
// }
|
||||
// }).
|
||||
// distinct().
|
||||
// map(GuardMethodGenerator::generateMethod).
|
||||
// forEach(System.out::println);
|
||||
//
|
||||
// System.out.println("}");
|
||||
// }
|
||||
//
|
||||
// static MethodType generateMethodType(Method m, Class<?> receiver, Class<?> value, Class<?>... intermediates) {
|
||||
// Class<?> returnType = m.getReturnType() == Object.class
|
||||
// ? value : m.getReturnType();
|
||||
//
|
||||
// List<Class<?>> params = new ArrayList<>();
|
||||
// if (receiver != null)
|
||||
// params.add(receiver);
|
||||
// java.util.Collections.addAll(params, intermediates);
|
||||
// for (var p : m.getParameters()) {
|
||||
// params.add(value);
|
||||
// }
|
||||
// return MethodType.methodType(returnType, params);
|
||||
// }
|
||||
//
|
||||
// static String generateMethod(MethodType mt) {
|
||||
// Class<?> returnType = mt.returnType();
|
||||
//
|
||||
// var params = new java.util.LinkedHashMap<String, Class<?>>();
|
||||
// params.put("handle", VarHandle.class);
|
||||
// for (int i = 0; i < mt.parameterCount(); i++) {
|
||||
// params.put("arg" + i, mt.parameterType(i));
|
||||
// }
|
||||
// params.put("ad", VarHandle.AccessDescriptor.class);
|
||||
//
|
||||
// // Generate method signature line
|
||||
// String RETURN = className(returnType);
|
||||
// String NAME = "guard";
|
||||
// String SIGNATURE = getSignature(mt);
|
||||
// String PARAMS = params.entrySet().stream().
|
||||
// map(e -> className(e.getValue()) + " " + e.getKey()).
|
||||
// collect(java.util.stream.Collectors.joining(", "));
|
||||
// String METHOD = GUARD_METHOD_SIG_TEMPLATE.
|
||||
// replace("<RETURN>", RETURN).
|
||||
// replace("<NAME>", NAME).
|
||||
// replace("<SIGNATURE>", SIGNATURE).
|
||||
// replace("<PARAMS>", PARAMS);
|
||||
//
|
||||
// // Generate method
|
||||
// params.remove("ad");
|
||||
//
|
||||
// List<String> LINK_TO_STATIC_ARGS = new ArrayList<>(params.keySet());
|
||||
// LINK_TO_STATIC_ARGS.add("handle.vform.getMemberName(ad.mode)");
|
||||
//
|
||||
// List<String> LINK_TO_INVOKER_ARGS = new ArrayList<>(params.keySet());
|
||||
// LINK_TO_INVOKER_ARGS.set(0, LINK_TO_INVOKER_ARGS.get(0) + ".asDirect()");
|
||||
//
|
||||
// RETURN = returnType == void.class
|
||||
// ? ""
|
||||
// : returnType == Object.class
|
||||
// ? "return "
|
||||
// : "return (" + returnType.getName() + ") ";
|
||||
//
|
||||
// String RESULT_ERASED = returnType == void.class
|
||||
// ? ""
|
||||
// : returnType != Object.class
|
||||
// ? "return (" + returnType.getName() + ") "
|
||||
// : "Object r = ";
|
||||
//
|
||||
// String RETURN_ERASED = returnType != Object.class
|
||||
// ? ""
|
||||
// : "\n return ad.returnType.cast(r);";
|
||||
//
|
||||
// String template = returnType == void.class
|
||||
// ? GUARD_METHOD_TEMPLATE_V
|
||||
// : GUARD_METHOD_TEMPLATE;
|
||||
// return template.
|
||||
// replace("<METHOD>", METHOD).
|
||||
// replace("<NAME>", NAME).
|
||||
// replaceAll("<RETURN>", RETURN).
|
||||
// replace("<RESULT_ERASED>", RESULT_ERASED).
|
||||
// replace("<RETURN_ERASED>", RETURN_ERASED).
|
||||
// replaceAll("<LINK_TO_STATIC_ARGS>", String.join(", ", LINK_TO_STATIC_ARGS)).
|
||||
// replace("<LINK_TO_INVOKER_ARGS>", String.join(", ", LINK_TO_INVOKER_ARGS))
|
||||
// .indent(4);
|
||||
// }
|
||||
//
|
||||
// static String className(Class<?> c) {
|
||||
// String n = c.getName();
|
||||
// if (n.startsWith("java.lang.")) {
|
||||
// n = n.replace("java.lang.", "");
|
||||
// if (n.startsWith("invoke.")) {
|
||||
// n = n.replace("invoke.", "");
|
||||
// }
|
||||
// }
|
||||
// return n.replace('$', '.');
|
||||
// }
|
||||
//
|
||||
// static String getSignature(MethodType m) {
|
||||
// StringBuilder sb = new StringBuilder(m.parameterCount() + 1);
|
||||
//
|
||||
// for (int i = 0; i < m.parameterCount(); i++) {
|
||||
// Class<?> pt = m.parameterType(i);
|
||||
// sb.append(getCharType(pt));
|
||||
// }
|
||||
//
|
||||
// sb.append('_').append(getCharType(m.returnType()));
|
||||
//
|
||||
// return sb.toString();
|
||||
// }
|
||||
//
|
||||
// static char getCharType(Class<?> pt) {
|
||||
// return Wrapper.forBasicType(pt).basicTypeChar();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user