Skip to content
This repository has been archived by the owner on Aug 16, 2023. It is now read-only.

Commit

Permalink
[GR-17988] Fixed bug in resolving cp entry for invoking clone on an a…
Browse files Browse the repository at this point in the history
…rray.

PullRequest: graal-jvmci-8/268
  • Loading branch information
dougxc committed Feb 22, 2020
2 parents 52a7245 + fe3b3cb commit e1059eb
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 28 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@
**/test-output/
**/workingsets.xml
/jdk*/
/openjdk*/
/src/closed
/make/closed
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2020, 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 jdk.vm.ci.runtime.test;

import org.junit.Assert;
import org.junit.Test;

import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.runtime.JVMCI;

public class ConstantPoolTest {

static Object cloneByteArray(byte[] arr) {
return arr.clone();
}

static Object cloneCharArray(char[] arr) {
return arr.clone();
}

static Object cloneShortArray(short[] arr) {
return arr.clone();
}

static Object cloneIntArray(int[] arr) {
return arr.clone();
}

static Object cloneFloatArray(float[] arr) {
return arr.clone();
}

static Object cloneLongArray(long[] arr) {
return arr.clone();
}

static Object cloneDoubleArray(double[] arr) {
return arr.clone();
}

static Object cloneObjectArray(Object[] arr) {
return arr.clone();
}

public static final int ALOAD_0 = 42; // 0x2A
public static final int INVOKEVIRTUAL = 182; // 0xB6

public static int beU2(byte[] data, int bci) {
return ((data[bci] & 0xff) << 8) | (data[bci + 1] & 0xff);
}

public static int beU1(byte[] data, int bci) {
return data[bci] & 0xff;
}

@Test
public void lookupArrayCloneMethodTest() throws Exception {
MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
ResolvedJavaType type = metaAccess.lookupJavaType(ConstantPoolTest.class);
for (ResolvedJavaMethod m : type.getDeclaredMethods()) {
if (m.getName().startsWith("clone")) {
byte[] bytecode = m.getCode();
Assert.assertNotNull(m.toString(), bytecode);
Assert.assertEquals(m.toString(), 5, bytecode.length);
Assert.assertEquals(m.toString(), ALOAD_0, beU1(bytecode, 0));
Assert.assertEquals(m.toString(), INVOKEVIRTUAL, beU1(bytecode, 1));
int cpi = beU2(bytecode, 2);
JavaMethod callee = m.getConstantPool().lookupMethod(cpi, INVOKEVIRTUAL);
Assert.assertTrue(callee.toString(), callee instanceof ResolvedJavaMethod);
}
}
}
}
24 changes: 3 additions & 21 deletions src/share/vm/jvmci/jvmciRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1239,12 +1239,11 @@ void JVMCIRuntime::get_field_by_index(InstanceKlass* accessor, fieldDescriptor&
// Perform an appropriate method lookup based on accessor, holder,
// name, signature, and bytecode.
methodHandle JVMCIRuntime::lookup_method(InstanceKlass* h_accessor,
InstanceKlass* h_holder,
Klass* h_holder,
Symbol* name,
Symbol* sig,
Bytecodes::Code bc) {
JVMCI_EXCEPTION_CONTEXT;
LinkResolver::check_klass_accessability(h_accessor, h_holder, KILL_COMPILE_ON_FATAL_(NULL));
// Accessibility checks are performed by caller.
methodHandle dest_method;
switch (bc) {
case Bytecodes::_invokestatic:
Expand Down Expand Up @@ -1319,8 +1318,7 @@ methodHandle JVMCIRuntime::get_method_by_index_impl(const constantPoolHandle& cp
}

if (holder_is_accessible) { // Our declared holder is loaded.
InstanceKlass* lookup = get_instance_klass_for_declared_method_holder(holder);
methodHandle m = lookup_method(accessor, lookup, name_sym, sig_sym, bc);
methodHandle m = lookup_method(accessor, holder, name_sym, sig_sym, bc);
if (!m.is_null()) {
// We found the method.
return m;
Expand All @@ -1333,22 +1331,6 @@ methodHandle JVMCIRuntime::get_method_by_index_impl(const constantPoolHandle& cp
return NULL;
}

// ------------------------------------------------------------------
InstanceKlass* JVMCIRuntime::get_instance_klass_for_declared_method_holder(Klass* method_holder) {
// For the case of <array>.clone(), the method holder can be an ArrayKlass*
// instead of an InstanceKlass*. For that case simply pretend that the
// declared holder is Object.clone since that's where the call will bottom out.
if (method_holder->oop_is_instance()) {
return InstanceKlass::cast(method_holder);
} else if (method_holder->oop_is_array()) {
return InstanceKlass::cast(SystemDictionary::Object_klass());
} else {
ShouldNotReachHere();
}
return NULL;
}


// ------------------------------------------------------------------
methodHandle JVMCIRuntime::get_method_by_index(const constantPoolHandle& cpool,
int index, Bytecodes::Code bc,
Expand Down
8 changes: 1 addition & 7 deletions src/share/vm/jvmci/jvmciRuntime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class JVMCIRuntime: public CHeapObj<mtJVMCI> {
// Helper methods
static bool check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass);
static methodHandle lookup_method(InstanceKlass* accessor,
InstanceKlass* holder,
Klass* holder,
Symbol* name,
Symbol* sig,
Bytecodes::Code bc);
Expand Down Expand Up @@ -205,12 +205,6 @@ class JVMCIRuntime: public CHeapObj<mtJVMCI> {
int method_index, Bytecodes::Code bc,
InstanceKlass* loading_klass);

// converts the Klass* representing the holder of a method into a
// InstanceKlass*. This is needed since the holder of a method in
// the bytecodes could be an array type. Basically this converts
// array types into java/lang/Object and other types stay as they are.
static InstanceKlass* get_instance_klass_for_declared_method_holder(Klass* klass);

// Helper routine for determining the validity of a compilation
// with respect to concurrent class loading.
static JVMCI::CodeInstallResult validate_compile_task_dependencies(Dependencies* target, JVMCICompileState* task, char** failure_detail);
Expand Down

0 comments on commit e1059eb

Please sign in to comment.