couple questions on method handle combinators
Paul Sandoz
paul.sandoz at oracle.com
Tue Jun 13 23:36:10 UTC 2017
In an attempt to simplify the test and to try and obtain invokeExact semantics for inlining i created a new test.
This one crashes the VM :-)
Paul.
# Internal Error (/Users/sandoz/Projects/jdk10/valhalla/hotspot/src/share/vm/opto/type.cpp:2084), pid=59955, tid=26883
# assert(type != ciEnv::current()->___Value_klass()) failed: unsupported
...
Current CompileTask:
C2: 4213 353 % GWTTest::run_Q @ 4 (29 bytes)
Stack: [0x000000011bbbd000,0x000000011bcbd000], sp=0x000000011bcb9d60, free space=1011k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.dylib+0xc9ac54] VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x4d4
V [libjvm.dylib+0xc9b416] VMError::report_and_die(Thread*, char const*, int, char const*, char const*, __va_list_tag*)+0x4a
V [libjvm.dylib+0x4cc1e1] report_vm_error(char const*, int, char const*, char const*, ...)+0xcd
V [libjvm.dylib+0xc3fe07] TypeTuple::make_domain(ciInstanceKlass*, ciSignature*, bool)+0x307
V [libjvm.dylib+0xc48c5a] TypeFunc::make(ciMethod*)+0x52
V [libjvm.dylib+0x6520bd] GraphKit::round_double_arguments(ciMethod*)+0x1d
V [libjvm.dylib+0x551a4c] Parse::do_call()+0x568
V [libjvm.dylib+0xac7f82] Parse::do_one_bytecode()+0xf4
V [libjvm.dylib+0xabb98f] Parse::do_one_block()+0x35f
V [libjvm.dylib+0xaba470] Parse::do_all_blocks()+0x428
V [libjvm.dylib+0xab704c] Parse::Parse(JVMState*, ciMethod*, float)+0xa1e
V [libjvm.dylib+0x350cfc] ParseGenerator::generate(JVMState*)+0xb6
V [libjvm.dylib+0x551bac] Parse::do_call()+0x6c8
V [libjvm.dylib+0xac7f82] Parse::do_one_bytecode()+0xf4
V [libjvm.dylib+0xabb98f] Parse::do_one_block()+0x35f
V [libjvm.dylib+0xaba470] Parse::do_all_blocks()+0x428
V [libjvm.dylib+0xab704c] Parse::Parse(JVMState*, ciMethod*, float)+0xa1e
V [libjvm.dylib+0x350cfc] ParseGenerator::generate(JVMState*)+0xb6
V [libjvm.dylib+0x551bac] Parse::do_call()+0x6c8
V [libjvm.dylib+0xac7f82] Parse::do_one_bytecode()+0xf4
V [libjvm.dylib+0xabb98f] Parse::do_one_block()+0x35f
V [libjvm.dylib+0xaba470] Parse::do_all_blocks()+0x428
V [libjvm.dylib+0xab704c] Parse::Parse(JVMState*, ciMethod*, float)+0xa1e
V [libjvm.dylib+0x350cfc] ParseGenerator::generate(JVMState*)+0xb6
V [libjvm.dylib+0x46554e] Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool, DirectiveSet*)+0x8c8
V [libjvm.dylib+0x46857b] Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool, DirectiveSet*)+0x31
V [libjvm.dylib+0x34f680] C2Compiler::compile_method(ciEnv*, ciMethod*, int, DirectiveSet*)+0x130
/*
* Copyright (c) 2017, 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
* @run testng/othervm
* -Djava.lang.invoke.MethodHandle.DUMP_CLASS_FILES=true
* -Dvalhalla.enablePoolPatches=true
* -Xverify:none
* -XX:-TieredCompilation
* -XX:+EnableMVT
* -XX:+ValueArrayFlatten
* -XX:+ValueTypePassFieldsAsArgs
* -XX:+ValueTypeReturnedAsFields
* -XX:+VerifyAdapterSharing
* -XX:+EnableValhalla
* -XX:ValueArrayElemMaxFlatSize=-1
* -XX:ValueArrayElemMaxFlatOops=-1
* -XX:+FullGCALotWithValueTypes
* GWTTest
*/
/*
* -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
* -XX:-TieredCompilation
* -XX:+EnableMVT
* -XX:+ValueArrayFlatten
* -XX:+ValueTypePassFieldsAsArgs
* -XX:+ValueTypeReturnedAsFields
* -XX:+VerifyAdapterSharing
* -XX:+EnableValhalla
* -XX:ValueArrayElemMaxFlatSize=-1
* -XX:ValueArrayElemMaxFlatOops=-1
* -XX:+FullGCALotWithValueTypes
*/
import jdk.experimental.value.ValueType;
import org.testng.annotations.Test;
import valhalla.shady.MinimalValueTypes_1_0;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.Objects;
public class GWTTest {
@jvm.internal.value.DeriveValueType
static final class V {
final int x;
final int y;
public V(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
V v = (V) o;
return x == v.x &&
y == v.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer(this.getClass().getSimpleName());
sb.append("{");
sb.append("x=").append(x);
sb.append(", y=").append(y);
sb.append('}');
return sb.toString();
}
}
static final ValueType<?> VT = ValueType.forClass(V.class);
static final Class<?> DVT;
static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
static final V V1 = new V(1, 1);
static final V V2 = new V(2, 2);
static final MethodHandle Q_MH_GWT;
static final MethodHandle L_MH_GWT;
static {
try {
DVT = MinimalValueTypes_1_0.getValueTypeClass(V.class);
}
catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
try {
MethodHandle v1 = LOOKUP.findStatic(GWTTest.class, "v1", MethodType.methodType(V.class));
MethodHandle v2 = LOOKUP.findStatic(GWTTest.class, "v2", MethodType.methodType(V.class));
MethodHandle test = LOOKUP.findStatic(GWTTest.class, "test", MethodType.methodType(boolean.class));
MethodHandle v_unbox = VT.unbox();
MethodHandle q_gwt = MethodHandles.guardWithTest(
test,
MethodHandles.filterReturnValue(v1, v_unbox),
MethodHandles.filterReturnValue(v2, v_unbox)
);
Q_MH_GWT = MethodHandles.filterReturnValue(
q_gwt,
VT.findGetter(LOOKUP, "x", int.class));
MethodHandle l_gwt = MethodHandles.guardWithTest(
test,
v1,
v2
);
L_MH_GWT = MethodHandles.filterReturnValue(
l_gwt,
LOOKUP.findGetter(V.class, "x", int.class));
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
static boolean test() {
return false;
}
static V v1() {
return V1;
}
static V v2() {
return V2;
}
static int run_Q() throws Throwable {
int sum = 0;
for (int i = 0; i < 100_000; i++) {
int v = (int) Q_MH_GWT.invokeExact();
sum += v;
}
return sum;
}
@Test
public void testGWT_Q() throws Throwable {
int r = run_Q();
System.out.println(r);
}
static int run_L() throws Throwable {
int sum = 0;
for (int i = 0; i < 100_000; i++) {
int v = (int) L_MH_GWT.invokeExact();
sum += v;
}
return sum;
}
@Test
public void testGWT_L() throws Throwable {
int r = run_L();
System.out.println(r);
}
public static void main(String[] args) throws Throwable {
GWTTest t = new GWTTest();
t.testGWT_L();
t.testGWT_Q();
}
}
More information about the valhalla-dev
mailing list