Path: blob/master/test/hotspot/jtreg/runtime/MemberName/ResolvedMethodTableHash.java
40942 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 824971926* @summary ResolvedMethodTable hash function should take method class into account27* @run main/othervm/manual -Xmx256m -XX:MaxMetaspaceSize=256m ResolvedMethodTableHash 20000028*/2930import java.lang.invoke.MethodHandle;31import java.lang.invoke.MethodHandles;32import java.lang.invoke.MethodType;33import java.nio.ByteBuffer;34import java.util.ArrayList;35import java.util.List;3637// The test generates thousands MethodHandles to the methods of the same name38// and the same signature. This should not take too long, unless Method hash39// function takes only the name and the signature as an input.40public class ResolvedMethodTableHash extends ClassLoader {4142// Generate a MethodHandle for ClassName.m()43private MethodHandle generate(String className) throws ReflectiveOperationException {44byte[] buf = new byte[100];45int size = writeClass(buf, className);46Class<?> cls = defineClass(null, buf, 0, size);47return MethodHandles.publicLookup().findStatic(cls, "m", MethodType.methodType(void.class));48}4950private MethodHandle generateWithSameName() throws ReflectiveOperationException {51byte[] buf = new byte[100];52int size = writeClass(buf, "MH$$");53// use different classloader instances to load the classes with the same name54Class<?> cls = new ResolvedMethodTableHash().defineClass(null, buf, 0, size);55return MethodHandles.publicLookup().findStatic(cls, "m", MethodType.methodType(void.class));56}5758// Produce a class file with the given name and a single method:59// public static native void m();60private int writeClass(byte[] buf, String className) {61return ByteBuffer.wrap(buf)62.putInt(0xCAFEBABE) // magic63.putInt(50) // version: 5064.putShort((short) 7) // constant_pool_count: 765.put((byte) 7).putShort((short) 2)66.put((byte) 1).putShort((short) className.length()).put(className.getBytes())67.put((byte) 7).putShort((short) 4)68.put((byte) 1).putShort((short) 16).put("java/lang/Object".getBytes())69.put((byte) 1).putShort((short) 1).put("m".getBytes())70.put((byte) 1).putShort((short) 3).put("()V".getBytes())71.putShort((short) 0x21) // access_flags: public super72.putShort((short) 1) // this_class: #173.putShort((short) 3) // super_class: #374.putShort((short) 0) // interfaces_count: 075.putShort((short) 0) // fields_count: 076.putShort((short) 1) // methods_count: 177.putShort((short) 0x109) // access_flags: public static native78.putShort((short) 5) // name_index: #579.putShort((short) 6) // descriptor_index: #680.putShort((short) 0) // attributes_count: 081.putShort((short) 0) // attributes_count: 082.position();83}8485public static void main(String[] args) throws Exception {86ResolvedMethodTableHash generator = new ResolvedMethodTableHash();87List<MethodHandle> handles = new ArrayList<>();8889int count = args.length > 0 ? Integer.parseInt(args[0]) : 200000;9091for (int i = 0; i < count; i++) {92// prevents metaspace oom93if (i % 20 != 0) {94handles.add(generator.generate("MH$" + i));95} else {96handles.add(generator.generateWithSameName());97}98if (i % 1000 == 0) {99System.out.println("Generated " + i + " handles");100}101}102103System.out.println("Test passed");104}105}106107108