Skip to content

Commit

Permalink
Merge pull request #14063 from EricYangIBM/fixCast
Browse files Browse the repository at this point in the history
Fix inconsistency between J9Class and annotation data when redefine (take 2)
  • Loading branch information
tajila committed Dec 3, 2021
2 parents bd8ad84 + b07a6f8 commit 5afc033
Show file tree
Hide file tree
Showing 29 changed files with 743 additions and 126 deletions.
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

0 comments on commit 5afc033

Please sign in to comment.