Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inconsistency between J9Class and annotation data when redefine (take 2) #14063

Merged
merged 2 commits into from
Dec 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
package com.ibm.oti.reflect;

/*******************************************************************************
* Copyright (c) 2010, 2020 IBM Corp. and others
* Copyright (c) 2010, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -33,6 +33,7 @@
/*[ELSE]*/
import sun.reflect.ConstantPool;
/*[ENDIF]*/
import com.ibm.oti.vm.VM;

public class AnnotationParser {

Expand Down Expand Up @@ -73,6 +74,7 @@ public static Object parseDefaultValue(Method method) {
if (elementValueData == null) return null;
ByteBuffer buf = ByteBuffer.wrap(elementValueData);
Class clazz = method.getDeclaringClass();
Object internalConstantPool = VM.getVMLangAccess().getInternalConstantPoolFromClass(clazz);

/* The AnnotationParser boxes primitive return types */
Class returnType = method.getReturnType();
Expand All @@ -95,14 +97,15 @@ public static Object parseDefaultValue(Method method) {
returnType = Double.class;
}
}
return sun.reflect.annotation.AnnotationParser.parseMemberValue(returnType, buf, getConstantPool(clazz), clazz);
return sun.reflect.annotation.AnnotationParser.parseMemberValue(returnType, buf, getConstantPool(internalConstantPool), clazz);
}

public static Annotation[] parseAnnotations(byte[] annotationsData, Class clazz) {
Object internalConstantPool = VM.getVMLangAccess().getInternalConstantPoolFromClass(clazz);
return sun.reflect.annotation.AnnotationParser.toArray(
sun.reflect.annotation.AnnotationParser.parseAnnotations(
annotationsData,
getConstantPool(clazz),
getConstantPool(internalConstantPool),
clazz));
}

Expand All @@ -112,7 +115,7 @@ public static Annotation[] parseAnnotations(byte[] annotationsData, Class clazz)
private static native byte[] getParameterAnnotationsData(Constructor constructor);
private static native byte[] getParameterAnnotationsData(Method method);
private static native byte[] getDefaultValueData(Method method);
static native ConstantPool getConstantPool(Class clazz);
static native ConstantPool getConstantPool(Object internalConstantPool);
private static native byte[] getAnnotationsDataImpl(java.lang.Class clazz);

private static Annotation[][] parseParameterAnnotations(byte[] annotationsData, Class<?> declaringClass, int parametersCount) {
Expand All @@ -123,6 +126,7 @@ private static Annotation[][] parseParameterAnnotations(byte[] annotationsData,
}
return annotations;
}
return sun.reflect.annotation.AnnotationParser.parseParameterAnnotations(annotationsData, getConstantPool(declaringClass), declaringClass);
Object internalConstantPool = VM.getVMLangAccess().getInternalConstantPoolFromClass(declaringClass);
return sun.reflect.annotation.AnnotationParser.parseParameterAnnotations(annotationsData, getConstantPool(internalConstantPool), declaringClass);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@

import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Constructor;
import com.ibm.oti.vm.VM;
/*[IF JAVA_SPEC_VERSION == 8]
import sun.misc.Unsafe;
/*[ELSE]*/
import jdk.internal.misc.Unsafe;
/*[ENDIF]*/

/*******************************************************************************
* Copyright (c) 2014, 2014 IBM Corp. and others
* Copyright (c) 2014, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -99,7 +105,17 @@ private static byte[] getAttributeData(Class clazz) {
*/
public static AnnotatedType[] buildAnnotatedInterfaces(Class clazz) {
byte[] attr = getAttributeData(clazz);
AnnotatedType[] annotatedInterfaces = sun.reflect.annotation.TypeAnnotationParser.buildAnnotatedInterfaces(attr, AnnotationParser.getConstantPool(clazz), clazz);
long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET + ((attr.length * Unsafe.ARRAY_BYTE_INDEX_SCALE) - VM.FJ9OBJECT_SIZE);
long ramCPAddr = 0;
if (VM.FJ9OBJECT_SIZE == 4) {
/* Compressed object refs */
ramCPAddr = Integer.toUnsignedLong(Unsafe.getUnsafe().getInt(attr, offset));
} else {
ramCPAddr = Unsafe.getUnsafe().getLong(attr, offset);
}
Object internalConstantPool = VM.getVMLangAccess().createInternalConstantPool(ramCPAddr);

AnnotatedType[] annotatedInterfaces = sun.reflect.annotation.TypeAnnotationParser.buildAnnotatedInterfaces(attr, AnnotationParser.getConstantPool(internalConstantPool), clazz);
return annotatedInterfaces;
}
/**
Expand All @@ -109,7 +125,17 @@ public static AnnotatedType[] buildAnnotatedInterfaces(Class clazz) {
*/
public static AnnotatedType buildAnnotatedSupertype(Class clazz) {
byte[] attr = getAttributeData(clazz);
AnnotatedType annotatedSuperclass = sun.reflect.annotation.TypeAnnotationParser.buildAnnotatedSuperclass(attr, AnnotationParser.getConstantPool(clazz), clazz);
long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET + ((attr.length * Unsafe.ARRAY_BYTE_INDEX_SCALE) - VM.FJ9OBJECT_SIZE);
long ramCPAddr = 0;
if (VM.FJ9OBJECT_SIZE == 4) {
/* Compressed object refs */
ramCPAddr = Integer.toUnsignedLong(Unsafe.getUnsafe().getInt(attr, offset));
} else {
ramCPAddr = Unsafe.getUnsafe().getLong(attr, offset);
}
Object internalConstantPool = VM.getVMLangAccess().createInternalConstantPool(ramCPAddr);

AnnotatedType annotatedSuperclass = sun.reflect.annotation.TypeAnnotationParser.buildAnnotatedSuperclass(attr, AnnotationParser.getConstantPool(internalConstantPool), clazz);
return annotatedSuperclass;
}
}
7 changes: 7 additions & 0 deletions jcl/src/java.base/share/classes/com/ibm/oti/vm/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -572,4 +572,11 @@ public static int markCurrentThreadAsSystem()

private static native int markCurrentThreadAsSystemImpl();

/**
* Gets the J9ConstantPool address from a J9Class address
* @param j9clazz J9Class address
* @return Address of J9ConstantPool
*/
public static native long getJ9ConstantPoolFromJ9Class(long j9clazz);

}
36 changes: 27 additions & 9 deletions jcl/src/java.base/share/classes/com/ibm/oti/vm/VMLangAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,38 @@ public interface VMLangAccess {
/*[ENDIF]*/

/**
* Returns an InternalRamClass object.
*
* @param addr - the native addr of the J9Class
* @return An InternalRamClass object
*/
public Object createInternalRamClass(long addr);
* Returns an InternalConstantPool object.
*
* @param addr - the native addr of the J9ConstantPool
* @return An InternalConstantPool object
*/
public Object createInternalConstantPool(long addr);

/**
* Returns a ConstantPool object
*
* @param internalRamClass An object ref to an internalRamClass
* @param internalConstantPool An object ref to an InternalConstantPool
* @return ConstantPool instance
*/
public ConstantPool getConstantPool(Object internalRamClass);
public ConstantPool getConstantPool(Object internalConstantPool);

/**
* Returns an InternalConstantPool object from a J9Class address. The ConstantPool
* natives expect an InternalConstantPool as the constantPoolOop parameter.
*
* @param j9class the native address of the J9Class
* @return InternalConstantPool a wrapper for a j9constantpool
*/
public Object getInternalConstantPoolFromJ9Class(long j9class);

/**
* Returns an InternalConstantPool object from a Class. The ConstantPool
* natives expect an InternalConstantPool as the constantPoolOop parameter.
*
* @param clazz the Class to fetch the constant pool from
* @return an InternalConstantPool wrapper for a j9constantpool
*/
public Object getInternalConstantPoolFromClass(Class clazz);

/*[IF Sidecar19-SE]*/
/**
Expand Down
16 changes: 13 additions & 3 deletions jcl/src/java.base/share/classes/java/lang/Class.java
Original file line number Diff line number Diff line change
Expand Up @@ -3349,10 +3349,20 @@ private AnnotationCache getAnnotationCache() {
if (annotationsData == null) {
annotationCacheResult = new AnnotationCache(null, buildAnnotations(null));
} else {
long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET + ((annotationsData.length * Unsafe.ARRAY_BYTE_INDEX_SCALE) - VM.FJ9OBJECT_SIZE);
long ramCPAddr = 0;
if (VM.FJ9OBJECT_SIZE == 4) {
/* Compressed object refs */
ramCPAddr = Integer.toUnsignedLong(unsafe.getInt(annotationsData, offset));
} else {
ramCPAddr = unsafe.getLong(annotationsData, offset);
}
Object internalCP = VM.getVMLangAccess().createInternalConstantPool(ramCPAddr);

Annotation[] directAnnotations = sun.reflect.annotation.AnnotationParser.toArray(
sun.reflect.annotation.AnnotationParser.parseAnnotations(
annotationsData,
getConstantPool(),
getConstantPool(internalCP),
this));

LinkedHashMap<Class<? extends Annotation>, Annotation> directAnnotationsMap = new LinkedHashMap<>(directAnnotations.length * 4 / 3);
Expand Down Expand Up @@ -5049,8 +5059,8 @@ Object setMethodHandleCache(Object cache) {
return result;
}

ConstantPool getConstantPool() {
return SharedSecrets.getJavaLangAccess().getConstantPool(this);
ConstantPool getConstantPool(Object internalCP) {
return VM.getVMLangAccess().getConstantPool(internalCP);
}

/*[IF Sidecar19-SE]*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*[INCLUDE-IF Sidecar18-SE]*/
package java.lang;
/*******************************************************************************
* Copyright (c) 2017, 2017 IBM Corp. and others
* Copyright (c) 2017, 2021 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand All @@ -23,14 +23,14 @@
*******************************************************************************/

/**
* Represents the internal J9Class
*
* Represents the internal J9ConstantPool
*
*/
final class InternalRamClass {
final class InternalConstantPool {
@SuppressWarnings("unused")
private final long vmref;
public InternalRamClass(long addr) {

public InternalConstantPool(long addr) {
vmref = addr;
}
}
55 changes: 43 additions & 12 deletions jcl/src/java.base/share/classes/java/lang/VMAccess.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@


import com.ibm.oti.vm.*;
import com.ibm.jit.JITHelpers;

/**
* Helper class to allow privileged access to classes
Expand Down Expand Up @@ -185,26 +186,56 @@ public Package getSystemPackage(String name) {
/*[ENDIF]*/

/**
* Returns a InternalRamClass object.
*
* @param addr - the native addr of the J9Class
* @return A InternalRamClass reference object
*/
* Returns an InternalConstantPool object.
*
* @param addr - the native addr of the J9ConstantPool
* @return An InternalConstantPool reference object
*/
@Override
public Object createInternalRamClass(long addr) {
return new InternalRamClass(addr);
public Object createInternalConstantPool(long addr) {
return new InternalConstantPool(addr);
}

/**
* Returns a ConstantPool object
* @param internalRamClass An object ref to a j9class
* @param internalConstantPool An object ref to a j9constantpool
* @return ConstantPool instance
*/
@Override
public ConstantPool getConstantPool(Object internalRamClass) {
return Access.getConstantPool(internalRamClass);
public ConstantPool getConstantPool(Object internalConstantPool) {
return Access.getConstantPool(internalConstantPool);
}


/**
* Returns an InternalConstantPool object from a J9Class address. The ConstantPool
* natives expect an InternalConstantPool as the constantPoolOop parameter.
*
* @param j9class the native address of the J9Class
* @return InternalConstantPool a wrapper for a j9constantpool
*/
public Object getInternalConstantPoolFromJ9Class(long j9class) {
long j9constantpool = VM.getJ9ConstantPoolFromJ9Class(j9class);
return createInternalConstantPool(j9constantpool);
}

/**
* Returns an InternalConstantPool object from a Class. The ConstantPool
* natives expect an InternalConstantPool as the constantPoolOop parameter.
*
* @param clazz the Class to fetch the constant pool from
* @return an InternalConstantPool wrapper for a j9constantpool
*/
public Object getInternalConstantPoolFromClass(Class clazz) {
JITHelpers helpers = JITHelpers.getHelpers();
long j9class;
if (helpers.is32Bit()) {
j9class = helpers.getJ9ClassFromClass32(clazz);
} else {
j9class = helpers.getJ9ClassFromClass64(clazz);
}
return getInternalConstantPoolFromJ9Class(j9class);
}

/*[IF Sidecar19-SE]*/
@Override
public void addPackageToList(java.lang.Class<?> newClass, ClassLoader loader) {
Expand Down
Loading