8311102: Write annotations in the classfile dumped by SA
Reviewed-by: cjplummer, stuefe
This commit is contained in:
parent
61932f49a5
commit
c710e71178
@ -41,6 +41,7 @@ typedef Array<u1> AnnotationArray;
|
||||
// a type_annotation instance.
|
||||
|
||||
class Annotations: public MetaspaceObj {
|
||||
friend class VMStructs;
|
||||
friend class JVMCIVMStructs;
|
||||
|
||||
// If you add a new field that points to any metaspace object, you
|
||||
|
@ -325,6 +325,10 @@
|
||||
nonstatic_field(Symbol, _body[0], u1) \
|
||||
nonstatic_field(TypeArrayKlass, _max_length, jint) \
|
||||
nonstatic_field(OopHandle, _obj, oop*) \
|
||||
nonstatic_field(Annotations, _class_annotations, Array<u1>*) \
|
||||
nonstatic_field(Annotations, _fields_annotations, Array<Array<u1>*>*) \
|
||||
nonstatic_field(Annotations, _class_type_annotations, Array<u1>*) \
|
||||
nonstatic_field(Annotations, _fields_type_annotations, Array<Array<u1>*>*) \
|
||||
\
|
||||
/***********************/ \
|
||||
/* Constant Pool Cache */ \
|
||||
@ -965,6 +969,7 @@
|
||||
unchecked_nonstatic_field(Array<Method*>, _data, sizeof(Method*)) \
|
||||
unchecked_nonstatic_field(Array<Klass*>, _data, sizeof(Klass*)) \
|
||||
unchecked_nonstatic_field(Array<ResolvedIndyEntry>, _data, sizeof(ResolvedIndyEntry)) \
|
||||
unchecked_nonstatic_field(Array<Array<u1>*>, _data, sizeof(Array<u1>*)) \
|
||||
\
|
||||
/*********************************/ \
|
||||
/* java_lang_Class fields */ \
|
||||
@ -1171,6 +1176,7 @@
|
||||
declare_type(Method, Metadata) \
|
||||
declare_type(MethodCounters, MetaspaceObj) \
|
||||
declare_type(ConstMethod, MetaspaceObj) \
|
||||
declare_type(Annotations, MetaspaceObj) \
|
||||
\
|
||||
declare_toplevel_type(MethodData::CompilerCounters) \
|
||||
\
|
||||
@ -1894,6 +1900,7 @@
|
||||
declare_type(Array<Klass*>, MetaspaceObj) \
|
||||
declare_type(Array<Method*>, MetaspaceObj) \
|
||||
declare_type(Array<ResolvedIndyEntry>, MetaspaceObj) \
|
||||
declare_type(Array<Array<u1>*>, MetaspaceObj) \
|
||||
\
|
||||
declare_toplevel_type(BitMap) \
|
||||
declare_type(BitMapView, BitMap) \
|
||||
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.jvm.hotspot.oops;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.interpreter.Bytecodes;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
import sun.jvm.hotspot.utilities.Observable;
|
||||
import sun.jvm.hotspot.utilities.Observer;
|
||||
|
||||
// An Annotation is an oop containing annotations as described in the class file
|
||||
|
||||
public class Annotations extends Metadata {
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ArrayOfU1Array fieldAnnotationsArray;
|
||||
private ArrayOfU1Array fieldTypeAnnotationsArray;
|
||||
|
||||
public Annotations(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public boolean isAnnotations() { return true; }
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||
Type type = db.lookupType("Annotations");
|
||||
classAnnotations = type.getAddressField("_class_annotations");
|
||||
fieldsAnnotations = type.getAddressField("_fields_annotations");
|
||||
classTypeAnnotations = type.getAddressField("_class_type_annotations");
|
||||
fieldsTypeAnnotations = type.getAddressField("_fields_type_annotations");
|
||||
}
|
||||
|
||||
private static AddressField classAnnotations;
|
||||
private static AddressField fieldsAnnotations;
|
||||
private static AddressField classTypeAnnotations;
|
||||
private static AddressField fieldsTypeAnnotations;
|
||||
|
||||
public U1Array getClassAnnotations() {
|
||||
Address addr = classAnnotations.getValue(getAddress());
|
||||
return VMObjectFactory.newObject(U1Array.class, addr);
|
||||
}
|
||||
|
||||
public U1Array getFieldAnnotations(int fieldIndex) {
|
||||
if (fieldAnnotationsArray == null) {
|
||||
Address addr = fieldsAnnotations.getValue(getAddress());
|
||||
fieldAnnotationsArray = VMObjectFactory.newObject(ArrayOfU1Array.class, addr);
|
||||
}
|
||||
if (fieldAnnotationsArray != null) {
|
||||
Address addr = fieldAnnotationsArray.at(fieldIndex);
|
||||
return VMObjectFactory.newObject(U1Array.class, addr);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public U1Array getClassTypeAnnotations() {
|
||||
Address addr = classTypeAnnotations.getValue(getAddress());
|
||||
return VMObjectFactory.newObject(U1Array.class, addr);
|
||||
}
|
||||
|
||||
public U1Array getFieldTypeAnnotations(int fieldIndex) {
|
||||
if (fieldTypeAnnotationsArray == null) {
|
||||
Address addr = fieldsTypeAnnotations.getValue(getAddress());
|
||||
fieldTypeAnnotationsArray = VMObjectFactory.newObject(ArrayOfU1Array.class, addr);
|
||||
}
|
||||
if (fieldTypeAnnotationsArray != null) {
|
||||
Address addr = fieldTypeAnnotationsArray.at(fieldIndex);
|
||||
return VMObjectFactory.newObject(U1Array.class, addr);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void printValueOn(PrintStream tty) {
|
||||
tty.print("Annotations" + "@" + getAddress());
|
||||
}
|
||||
}
|
@ -417,31 +417,42 @@ public class ConstMethod extends Metadata {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private boolean hasMethodParameters() {
|
||||
return (getFlags() & HAS_METHOD_PARAMETERS) != 0;
|
||||
public U1Array getMethodAnnotations() {
|
||||
if (hasMethodAnnotations()) {
|
||||
Address addr = getAddressAtOffset(getSize() - getMethodAnnotationsOffset());
|
||||
return VMObjectFactory.newObject(U1Array.class, addr);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasGenericSignature() {
|
||||
return (getFlags() & HAS_GENERIC_SIGNATURE) != 0;
|
||||
public U1Array getParameterAnnotations() {
|
||||
if (hasParameterAnnotations()) {
|
||||
Address addr = getAddressAtOffset(getSize() - getParameterAnnotationsOffset());
|
||||
return VMObjectFactory.newObject(U1Array.class, addr);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasMethodAnnotations() {
|
||||
return (getFlags() & HAS_METHOD_ANNOTATIONS) != 0;
|
||||
public U1Array getTypeAnnotations() {
|
||||
if (hasTypeAnnotations()) {
|
||||
Address addr = getAddressAtOffset(getSize() - getTypeAnnotationsOffset());
|
||||
return VMObjectFactory.newObject(U1Array.class, addr);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasParameterAnnotations() {
|
||||
return (getFlags() & HAS_PARAMETER_ANNOTATIONS) != 0;
|
||||
public U1Array getDefaultAnnotations() {
|
||||
if (hasDefaultAnnotations()) {
|
||||
Address addr = getAddressAtOffset(getSize() - getDefaultAnnotationsOffset());
|
||||
return VMObjectFactory.newObject(U1Array.class, addr);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasDefaultAnnotations() {
|
||||
return (getFlags() & HAS_DEFAULT_ANNOTATIONS) != 0;
|
||||
}
|
||||
|
||||
private boolean hasTypeAnnotations() {
|
||||
return (getFlags() & HAS_TYPE_ANNOTATIONS) != 0;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Internals only below this point
|
||||
//
|
||||
@ -610,4 +621,70 @@ public class ConstMethod extends Metadata {
|
||||
return offset;
|
||||
}
|
||||
|
||||
private boolean hasMethodParameters() {
|
||||
return (getFlags() & HAS_METHOD_PARAMETERS) != 0;
|
||||
}
|
||||
|
||||
private boolean hasGenericSignature() {
|
||||
return (getFlags() & HAS_GENERIC_SIGNATURE) != 0;
|
||||
}
|
||||
|
||||
private Address getAddressAtOffset(long offsetInWords) {
|
||||
return getAddress().getAddressAt(offsetInWords * VM.getVM().getAddressSize());
|
||||
}
|
||||
|
||||
// Pointers to annotations are stored towards the end of the ConstMethod in following format.
|
||||
// Each of the pointer may or may not be present.
|
||||
//
|
||||
// |<-------------- getSize() -----------------|
|
||||
// start of ConstMethod end of ConstMethod
|
||||
// | |
|
||||
// V V
|
||||
// | ... | default | type | parameter | method |
|
||||
//
|
||||
// These methods return the offset of the pointer to the requested annotation from the end of ConstMethod.
|
||||
private int getMethodAnnotationsOffset() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
private int getParameterAnnotationsOffset() {
|
||||
int offset = 1;
|
||||
if (hasMethodAnnotations()) {
|
||||
offset += getMethodAnnotationsOffset();
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
private int getTypeAnnotationsOffset() {
|
||||
int offset = 1;
|
||||
if (hasParameterAnnotations()) {
|
||||
offset += getParameterAnnotationsOffset();
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
private int getDefaultAnnotationsOffset() {
|
||||
int offset = 1;
|
||||
if (hasTypeAnnotations()) {
|
||||
offset += getTypeAnnotationsOffset();
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
private boolean hasMethodAnnotations() {
|
||||
return (getFlags() & HAS_METHOD_ANNOTATIONS) != 0;
|
||||
}
|
||||
|
||||
private boolean hasParameterAnnotations() {
|
||||
return (getFlags() & HAS_PARAMETER_ANNOTATIONS) != 0;
|
||||
}
|
||||
|
||||
private boolean hasTypeAnnotations() {
|
||||
return (getFlags() & HAS_TYPE_ANNOTATIONS) != 0;
|
||||
}
|
||||
|
||||
private boolean hasDefaultAnnotations() {
|
||||
return (getFlags() & HAS_DEFAULT_ANNOTATIONS) != 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ public class InstanceKlass extends Klass {
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||
Type type = db.lookupType("InstanceKlass");
|
||||
annotations = type.getAddressField("_annotations");
|
||||
arrayKlasses = new MetadataField(type.getAddressField("_array_klasses"), 0);
|
||||
methods = type.getAddressField("_methods");
|
||||
defaultMethods = type.getAddressField("_default_methods");
|
||||
@ -130,6 +131,7 @@ public class InstanceKlass extends Klass {
|
||||
}
|
||||
}
|
||||
|
||||
private static AddressField annotations;
|
||||
private static MetadataField arrayKlasses;
|
||||
private static AddressField methods;
|
||||
private static AddressField defaultMethods;
|
||||
@ -375,7 +377,6 @@ public class InstanceKlass extends Klass {
|
||||
public long majorVersion() { return getConstants().majorVersion(); }
|
||||
public long minorVersion() { return getConstants().minorVersion(); }
|
||||
public Symbol getGenericSignature() { return getConstants().getGenericSignature(); }
|
||||
|
||||
// "size helper" == instance size in words
|
||||
public long getSizeHelper() {
|
||||
int lh = getLayoutHelper();
|
||||
@ -384,6 +385,10 @@ public class InstanceKlass extends Klass {
|
||||
}
|
||||
return lh / VM.getVM().getAddressSize();
|
||||
}
|
||||
public Annotations getAnnotations() {
|
||||
Address addr = annotations.getValue(getAddress());
|
||||
return VMObjectFactory.newObject(Annotations.class, addr);
|
||||
}
|
||||
|
||||
// same as enum InnerClassAttributeOffset in VM code.
|
||||
private static class InnerClassAttributeOffset {
|
||||
@ -859,6 +864,42 @@ public class InstanceKlass extends Klass {
|
||||
return VMObjectFactory.newObject(U2Array.class, addr);
|
||||
}
|
||||
|
||||
public U1Array getClassAnnotations() {
|
||||
Annotations annotations = getAnnotations();
|
||||
if (annotations != null) {
|
||||
return annotations.getClassAnnotations();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public U1Array getClassTypeAnnotations() {
|
||||
Annotations annotations = getAnnotations();
|
||||
if (annotations != null) {
|
||||
return annotations.getClassTypeAnnotations();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public U1Array getFieldAnnotations(int fieldIndex) {
|
||||
Annotations annotations = getAnnotations();
|
||||
if (annotations != null) {
|
||||
return annotations.getFieldAnnotations(fieldIndex);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public U1Array getFieldTypeAnnotations(int fieldIndex) {
|
||||
Annotations annotations = getAnnotations();
|
||||
if (annotations != null) {
|
||||
return annotations.getFieldTypeAnnotations(fieldIndex);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Internals only below this point
|
||||
//
|
||||
|
@ -71,6 +71,7 @@ public abstract class Metadata extends VMObject {
|
||||
metadataConstructor.addMapping("ConstMethod", ConstMethod.class);
|
||||
metadataConstructor.addMapping("ConstantPool", ConstantPool.class);
|
||||
metadataConstructor.addMapping("ConstantPoolCache", ConstantPoolCache.class);
|
||||
metadataConstructor.addMapping("Annotations", Annotations.class);
|
||||
}
|
||||
|
||||
public static Metadata instantiateWrapperFor(Address addr) {
|
||||
|
@ -40,6 +40,7 @@ import sun.jvm.hotspot.types.Type;
|
||||
import sun.jvm.hotspot.types.TypeDataBase;
|
||||
import sun.jvm.hotspot.types.WrongTypeException;
|
||||
import sun.jvm.hotspot.utilities.Assert;
|
||||
import sun.jvm.hotspot.utilities.U1Array;
|
||||
|
||||
// A Method represents a Java method
|
||||
|
||||
@ -376,4 +377,20 @@ public class Method extends Metadata {
|
||||
OopUtilities.escapeString(getName().asString()) + " " +
|
||||
getSignature().asString();
|
||||
}
|
||||
|
||||
public U1Array getAnnotations() {
|
||||
return getConstMethod().getMethodAnnotations();
|
||||
}
|
||||
|
||||
public U1Array getParameterAnnotations() {
|
||||
return getConstMethod().getParameterAnnotations();
|
||||
}
|
||||
|
||||
public U1Array getTypeAnnotations() {
|
||||
return getConstMethod().getTypeAnnotations();
|
||||
}
|
||||
|
||||
public U1Array getAnnotationDefault() {
|
||||
return getConstMethod().getDefaultAnnotations();
|
||||
}
|
||||
}
|
||||
|
@ -406,6 +406,16 @@ public class ClassWriter implements /* imports */ ClassConstants
|
||||
if (genSigIndex != 0)
|
||||
fieldAttributeCount++;
|
||||
|
||||
U1Array fieldAnnotations = klass.getFieldAnnotations(index);
|
||||
if (fieldAnnotations != null) {
|
||||
fieldAttributeCount++;
|
||||
}
|
||||
|
||||
U1Array fieldTypeAnnotations = klass.getFieldTypeAnnotations(index);
|
||||
if (fieldTypeAnnotations != null) {
|
||||
fieldAttributeCount++;
|
||||
}
|
||||
|
||||
dos.writeShort(fieldAttributeCount);
|
||||
|
||||
// write synthetic, if applicable
|
||||
@ -425,6 +435,14 @@ public class ClassWriter implements /* imports */ ClassConstants
|
||||
dos.writeShort(genSigIndex);
|
||||
if (DEBUG) debugMessage("\tfield generic signature index " + genSigIndex);
|
||||
}
|
||||
|
||||
if (fieldAnnotations != null) {
|
||||
writeAnnotationAttribute("RuntimeVisibleAnnotations", fieldAnnotations);
|
||||
}
|
||||
|
||||
if (fieldTypeAnnotations != null) {
|
||||
writeAnnotationAttribute("RuntimeVisibleTypeAnnotations", fieldTypeAnnotations);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -492,6 +510,26 @@ public class ClassWriter implements /* imports */ ClassConstants
|
||||
if (isGeneric)
|
||||
methodAttributeCount++;
|
||||
|
||||
final U1Array annotations = m.getAnnotations();
|
||||
if (annotations != null) {
|
||||
methodAttributeCount++;
|
||||
}
|
||||
|
||||
final U1Array parameterAnnotations = m.getParameterAnnotations();
|
||||
if (parameterAnnotations != null) {
|
||||
methodAttributeCount++;
|
||||
}
|
||||
|
||||
final U1Array typeAnnotations = m.getTypeAnnotations();
|
||||
if (typeAnnotations != null) {
|
||||
methodAttributeCount++;
|
||||
}
|
||||
|
||||
final U1Array annotationDefault = m.getAnnotationDefault();
|
||||
if (annotationDefault != null) {
|
||||
methodAttributeCount++;
|
||||
}
|
||||
|
||||
dos.writeShort(methodAttributeCount);
|
||||
if (DEBUG) debugMessage("\tmethod attribute count = " + methodAttributeCount);
|
||||
|
||||
@ -687,6 +725,22 @@ public class ClassWriter implements /* imports */ ClassConstants
|
||||
if (isGeneric) {
|
||||
writeGenericSignature(m.getGenericSignature().asString());
|
||||
}
|
||||
|
||||
if (annotationDefault != null) {
|
||||
writeAnnotationAttribute("AnnotationDefault", annotationDefault);
|
||||
}
|
||||
|
||||
if (annotations != null) {
|
||||
writeAnnotationAttribute("RuntimeVisibleAnnotations", annotations);
|
||||
}
|
||||
|
||||
if (parameterAnnotations != null) {
|
||||
writeAnnotationAttribute("RuntimeVisibleParameterAnnotations", parameterAnnotations);
|
||||
}
|
||||
|
||||
if (typeAnnotations != null) {
|
||||
writeAnnotationAttribute("RuntimeVisibleTypeAnnotations", typeAnnotations);
|
||||
}
|
||||
}
|
||||
|
||||
protected void rewriteByteCode(Method m, byte[] code) {
|
||||
@ -731,6 +785,16 @@ public class ClassWriter implements /* imports */ ClassConstants
|
||||
classAttributeCount++;
|
||||
}
|
||||
|
||||
U1Array classAnnotations = klass.getClassAnnotations();
|
||||
if (classAnnotations != null) {
|
||||
classAttributeCount++;
|
||||
}
|
||||
|
||||
U1Array classTypeAnnotations = klass.getClassTypeAnnotations();
|
||||
if (classTypeAnnotations != null) {
|
||||
classAttributeCount++;
|
||||
}
|
||||
|
||||
dos.writeShort(classAttributeCount);
|
||||
if (DEBUG) debugMessage("class attribute count = " + classAttributeCount);
|
||||
|
||||
@ -792,5 +856,26 @@ public class ClassWriter implements /* imports */ ClassConstants
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (classAnnotations != null) {
|
||||
writeAnnotationAttribute("RuntimeVisibleAnnotations", classAnnotations);
|
||||
}
|
||||
|
||||
if (classTypeAnnotations != null) {
|
||||
writeAnnotationAttribute("RuntimeVisibleTypeAnnotations", classTypeAnnotations);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeAnnotationAttribute(String annotationName, U1Array annotation) throws IOException {
|
||||
int length = annotation.length();
|
||||
Short annotationNameIndex = utf8ToIndex.get(annotationName);
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(annotationNameIndex != null, "should not be null");
|
||||
}
|
||||
writeIndex(annotationNameIndex.shortValue());
|
||||
dos.writeInt(length);
|
||||
for (int index = 0; index < length; index++) {
|
||||
dos.writeByte(annotation.at(index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package sun.jvm.hotspot.utilities;
|
||||
|
||||
import sun.jvm.hotspot.debugger.Address;
|
||||
import sun.jvm.hotspot.runtime.VM;
|
||||
import sun.jvm.hotspot.types.Type;
|
||||
import sun.jvm.hotspot.types.TypeDataBase;
|
||||
import sun.jvm.hotspot.types.WrongTypeException;
|
||||
import sun.jvm.hotspot.utilities.Observable;
|
||||
import sun.jvm.hotspot.utilities.Observer;
|
||||
|
||||
public class ArrayOfU1Array extends GenericArray {
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||
elemType = db.lookupType("Array<u1>*");
|
||||
|
||||
Type type = db.lookupType("Array<Array<u1>*>");
|
||||
dataFieldOffset = type.getAddressField("_data").getOffset();
|
||||
}
|
||||
|
||||
private static long dataFieldOffset;
|
||||
protected static Type elemType;
|
||||
|
||||
public ArrayOfU1Array(Address addr) {
|
||||
super(addr, dataFieldOffset);
|
||||
}
|
||||
|
||||
public Address at(int i) {
|
||||
return getAddressAt(i);
|
||||
}
|
||||
|
||||
public Type getElemType() {
|
||||
return elemType;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user