org.jikesrvm.classloader
Class Atom

java.lang.Object
  extended by org.jikesrvm.classloader.Atom

public final class Atom
extends Object

An utf8-encoded byte string.

Atom's are interned (canonicalized) so they may be compared for equality using the "==" operator.

Atoms are used to represent names, descriptors, and string literals appearing in a class's constant pool.

There is almost always a zero-length Atom, since any class which contains statements like:

          return "";
 
will have one in its constant pool.


Nested Class Summary
private static class Atom.InternedStrings
          Inner class responsible for string interning.
 
Field Summary
private static Atom[][] atoms
          Dictionary of all Atom instances.
private static byte[][] BOOTSTRAP_CLASS_PREFIX_SET
          The set of class prefixes that MUST be loaded by bootstrap classloader.
private static ImmutableEntryHashMapRVM<Atom,Atom> dictionary
          Used to canonicalize Atoms: possibly non-canonical Atom => Atom
private  int id
          The id of this atom
private static int LOG_ROW_SIZE
          2^LOG_ROW_SIZE is the number of elements per row
private static int nextId
          Used to assign ids.
private static byte[][] NON_BOOTSTRAP_CLASS_PREFIX_SET
          The set of class prefixes that MUST NOT be loaded by bootstrap classloader.
private static int ROW_MASK
          Mask to ascertain row from id number
private static byte[][] RVM_CLASS_PREFIXES
          The set of class prefixes for core RVM classes.
private  Object unicodeStringOrJTOCoffset
          A reference to either a unicode String encoding the atom, an offset in the JTOC holding a unicode string encoding the atom or null.
private  byte[] val
          The utf8 value this atom represents
 
Constructor Summary
private Atom(byte[] val, int id, String str)
          Create atom from the key that maps to it.
 
Method Summary
 String annotationClassToAnnotationInterface()
          Create a class name from a type name.
 Atom annotationInterfaceToAnnotationClass()
          Create an annotation name from a class name.
(package private)  Atom arrayDescriptorFromElementDescriptor()
          Return array descriptor corresponding to "this" array-element descriptor.
 String classFileNameFromDescriptor()
          Return name of class file corresponding to "this" class descriptor.
 String classNameFromDescriptor()
          Return class name corresponding to "this" class descriptor.
 Atom descriptorFromClassName()
          Return class descriptor corresponding to "this" class name.
 boolean equals(Object other)
          Outside of this class atoms are canonical and should be compared using ==.
static Atom findAsciiAtom(String str)
          Find an atom.
private static Atom findOrCreate(byte[] bytes, boolean create, String str)
          This is the findOrCreate() method through which all Atoms are ultimately created.
private static Atom findOrCreate(byte[] utf8, int off, int len, String str)
          Find an atom from the subsequence of another
static Atom findOrCreateAsciiAtom(String str)
          Find or create an atom.
static Atom findOrCreateUnicodeAtom(String str)
          Find or create an atom.
static Atom findOrCreateUtf8Atom(byte[] utf8)
          Find or create an atom.
static Atom findUnicodeAtom(String str)
          Find an atom.
static Atom findUtf8Atom(byte[] utf8)
          Find an atom.
static Atom getAtom(int id)
           
 byte[] getBytes()
          Return the underlying set of bytes for the Atom.
(package private)  int getId()
           
 int getStringLiteralOffset()
          Offset of an atom's string in the JTOC, for string literals
 int hashCode()
          Return the hashCode of an atom, this equals the unicode string encoding of the atom
static String internString(String str)
          External string intern method called from String.intern.
 boolean isAnnotationClass()
          Is this an annotation class name of the form Lfoo.bar$$;
 boolean isArrayDescriptor()
          Is "this" atom an array descriptor?
 boolean isBootstrapClassDescriptor()
           
 boolean isClassDescriptor()
          Is "this" atom a class descriptor?
 boolean isMethodDescriptor()
          Is "this" atom a method descriptor?
 boolean isReservedMemberName()
          Is "this" atom a reserved member name?
 boolean isRVMDescriptor()
           
 int length()
           
 int parseForArrayDimensionality()
          Parse "this" array descriptor to obtain number of dimensions in corresponding array type.
 Atom parseForArrayElementDescriptor()
          Parse "this" array descriptor to obtain descriptor for array's element type.
 byte parseForArrayElementTypeCode()
          Parse "this" array descriptor to obtain type code for its element type.
 Atom parseForInnermostArrayElementDescriptor()
          Return the innermost element type reference for an array
 Class<?>[] parseForParameterClasses(ClassLoader cl)
          Parse "this" method descriptor to obtain descriptions of method's parameters as classes.
 TypeReference[] parseForParameterTypes(ClassLoader cl)
          Parse "this" method descriptor to obtain descriptions of method's parameters.
 TypeReference parseForReturnType(ClassLoader cl)
          Parse "this" method descriptor to obtain description of method's return type.
 byte parseForTypeCode()
          Parse "this" field, parameter, or return descriptor to obtain its type code.
 void sysWrite()
           
 byte[] toByteArray()
          Get at a string-like representation without doing any heap allocation.
 String toString()
          Return printable representation of "this" atom.
 String toUnicodeString()
          Return atom as a string literal
private  String toUnicodeStringInternal()
          Atom as string literal or null if atom hasn't been converted
 
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

dictionary

private static final ImmutableEntryHashMapRVM<Atom,Atom> dictionary
Used to canonicalize Atoms: possibly non-canonical Atom => Atom


LOG_ROW_SIZE

private static final int LOG_ROW_SIZE
2^LOG_ROW_SIZE is the number of elements per row

See Also:
Constant Field Values

ROW_MASK

private static final int ROW_MASK
Mask to ascertain row from id number

See Also:
Constant Field Values

atoms

private static Atom[][] atoms
Dictionary of all Atom instances.


nextId

private static int nextId
Used to assign ids. Don't use id 0 to allow clients to use id 0 as a 'null'.


unicodeStringOrJTOCoffset

private Object unicodeStringOrJTOCoffset
A reference to either a unicode String encoding the atom, an offset in the JTOC holding a unicode string encoding the atom or null.


val

private final byte[] val
The utf8 value this atom represents


id

private final int id
The id of this atom


BOOTSTRAP_CLASS_PREFIX_SET

private static final byte[][] BOOTSTRAP_CLASS_PREFIX_SET
The set of class prefixes that MUST be loaded by bootstrap classloader.

See Also:
isBootstrapClassDescriptor()

NON_BOOTSTRAP_CLASS_PREFIX_SET

private static final byte[][] NON_BOOTSTRAP_CLASS_PREFIX_SET
The set of class prefixes that MUST NOT be loaded by bootstrap classloader.

See Also:
isBootstrapClassDescriptor()

RVM_CLASS_PREFIXES

private static final byte[][] RVM_CLASS_PREFIXES
The set of class prefixes for core RVM classes.

See Also:
isRVMDescriptor()
Constructor Detail

Atom

private Atom(byte[] val,
             int id,
             String str)
Create atom from the key that maps to it.

Method Detail

getId

int getId()
Returns:
the id of this atom.

findOrCreateUnicodeAtom

public static Atom findOrCreateUnicodeAtom(String str)
Find or create an atom.

Parameters:
str - atom value, as string literal whose characters are unicode
Returns:
atom

findUnicodeAtom

public static Atom findUnicodeAtom(String str)
Find an atom.

Parameters:
str - atom value, as string literal whose characters are unicode
Returns:
atom or null if it doesn't already exist

findOrCreateAsciiAtom

public static Atom findOrCreateAsciiAtom(String str)
Find or create an atom.

Parameters:
str - atom value, as string literal whose characters are from ascii subset of unicode (not including null)
Returns:
atom

findAsciiAtom

public static Atom findAsciiAtom(String str)
Find an atom.

Parameters:
str - atom value, as string literal whose characters are from ascii subset of unicode (not including null)
Returns:
atom or null if it doesn't already exist

findOrCreateUtf8Atom

public static Atom findOrCreateUtf8Atom(byte[] utf8)
Find or create an atom.

Parameters:
utf8 - atom value, as utf8 encoded bytes
Returns:
atom

findUtf8Atom

public static Atom findUtf8Atom(byte[] utf8)
Find an atom.

Parameters:
utf8 - atom value, as utf8 encoded bytes
Returns:
atom or null it it doesn't already exist

findOrCreate

private static Atom findOrCreate(byte[] utf8,
                                 int off,
                                 int len,
                                 String str)
Find an atom from the subsequence of another

Parameters:
utf8 - byte backing of atom
off - offset of new atom
len - length of new atom
str - possible string encoding of atom or null
Returns:
atom

findOrCreate

private static Atom findOrCreate(byte[] bytes,
                                 boolean create,
                                 String str)
This is the findOrCreate() method through which all Atoms are ultimately created. The constructor for Atom is a private method, so someone has to call one of the public findOrCreate() methods to get a new one. And they all feed through here.


getAtom

public static Atom getAtom(int id)
Parameters:
id - the id of an Atom
Returns:
the Atom whose id was given

toString

public String toString()
Return printable representation of "this" atom. Does not correctly handle UTF8 translation.

Overrides:
toString in class Object

toByteArray

public byte[] toByteArray()
Get at a string-like representation without doing any heap allocation. Hideous but necessary. We will use it in the PrintContainer class.


toUnicodeString

public String toUnicodeString()
                       throws UTFDataFormatException
Return atom as a string literal

Throws:
UTFDataFormatException

toUnicodeStringInternal

private String toUnicodeStringInternal()
Atom as string literal or null if atom hasn't been converted


getStringLiteralOffset

public int getStringLiteralOffset()
                           throws UTFDataFormatException
Offset of an atom's string in the JTOC, for string literals

Returns:
Offset of string literal in JTOC
Throws:
UTFDataFormatException

arrayDescriptorFromElementDescriptor

Atom arrayDescriptorFromElementDescriptor()
Return array descriptor corresponding to "this" array-element descriptor. this: array-element descriptor - something like "I" or "Ljava/lang/Object;"

Returns:
array descriptor - something like "[I" or "[Ljava/lang/Object;"

descriptorFromClassName

public Atom descriptorFromClassName()
Return class descriptor corresponding to "this" class name. this: class name - something like "java.lang.Object"

Returns:
class descriptor - something like "Ljava/lang/Object;"

classNameFromDescriptor

public String classNameFromDescriptor()
Return class name corresponding to "this" class descriptor. this: class descriptor - something like "Ljava/lang/String;"

Returns:
class name - something like "java.lang.String"

classFileNameFromDescriptor

public String classFileNameFromDescriptor()
Return name of class file corresponding to "this" class descriptor. this: class descriptor - something like "Ljava/lang/String;"

Returns:
class file name - something like "java/lang/String.class"

isReservedMemberName

public boolean isReservedMemberName()
Is "this" atom a reserved member name? Note: Sun has reserved all member names starting with '<' for future use. At present, only and are used.


isClassDescriptor

public boolean isClassDescriptor()
Is "this" atom a class descriptor?


isArrayDescriptor

public boolean isArrayDescriptor()
Is "this" atom an array descriptor?


isMethodDescriptor

public boolean isMethodDescriptor()
Is "this" atom a method descriptor?


parseForReturnType

public TypeReference parseForReturnType(ClassLoader cl)
Parse "this" method descriptor to obtain description of method's return type. this: method descriptor - something like "(III)V"

Returns:
type description

parseForParameterTypes

public TypeReference[] parseForParameterTypes(ClassLoader cl)
Parse "this" method descriptor to obtain descriptions of method's parameters. this: method descriptor - something like "(III)V"

Returns:
parameter descriptions

parseForParameterClasses

public Class<?>[] parseForParameterClasses(ClassLoader cl)
Parse "this" method descriptor to obtain descriptions of method's parameters as classes. this: method descriptor - something like "(III)V"

Returns:
parameter classes

getBytes

public byte[] getBytes()
Return the underlying set of bytes for the Atom. This can be used to perform comparisons without requiring the allocation of a string.


parseForTypeCode

public byte parseForTypeCode()
                      throws IllegalArgumentException
Parse "this" field, parameter, or return descriptor to obtain its type code. this: descriptor - something like "Ljava/lang/String;" or "[I" or "I"

Returns:
type code - something like ObjectTypeCode, ArrayTypeCode, or IntTypeCode The type code will be one of the following constants:
               constant         value
           ----------------     -----
            ClassTypeCode        'L'
            ArrayTypeCode        '['
            VoidTypeCode         'V'
            BooleanTypeCode      'Z'
            ByteTypeCode         'B'
            ShortTypeCode        'S'
            IntTypeCode          'I'
            LongTypeCode         'J'
            FloatTypeCode        'F'
            DoubleTypeCode       'D'
            CharTypeCode         'C'
 
Throws:
IllegalArgumentException

parseForArrayDimensionality

public int parseForArrayDimensionality()
Parse "this" array descriptor to obtain number of dimensions in corresponding array type. this: descriptor - something like "[Ljava/lang/String;" or "[[I"

Returns:
dimensionality - something like "1" or "2"

parseForArrayElementTypeCode

public byte parseForArrayElementTypeCode()
Parse "this" array descriptor to obtain type code for its element type. this: descriptor - something like "[Ljava/lang/String;" or "[I"

Returns:
type code - something like VM.ObjectTypeCode or VM.IntTypeCode The type code will be one of the constants appearing in the table above. Implementation note: This is supposed to be uninterruptible, since another allegedly uninterruptible method (RVMArray.getLogElementSize()) calls it.

parseForInnermostArrayElementDescriptor

public Atom parseForInnermostArrayElementDescriptor()
Return the innermost element type reference for an array


parseForArrayElementDescriptor

public Atom parseForArrayElementDescriptor()
Parse "this" array descriptor to obtain descriptor for array's element type. this: array descriptor - something like "[I"

Returns:
array element descriptor - something like "I"

isBootstrapClassDescriptor

public boolean isBootstrapClassDescriptor()
Returns:
true if this is a class descriptor of a bootstrap class (ie a class that must be loaded by the bootstrap class loader)

isRVMDescriptor

public boolean isRVMDescriptor()
Returns:
true if this is a class descriptor of a RVM core class. This is defined as one that it would be unwise to invalidate, since invalidating it might make it impossible to recompile.

annotationInterfaceToAnnotationClass

public Atom annotationInterfaceToAnnotationClass()
Create an annotation name from a class name. For example Lfoo.bar; becomes Lfoo.bar$$; NB in Sun VMs the annotation name of the first annotation is $Proxy1. Classpath may later rely on this to implement serialization correctly.


annotationClassToAnnotationInterface

public String annotationClassToAnnotationInterface()
Create a class name from a type name. For example Lfoo.bar$$; becomes the string foo.bar


isAnnotationClass

public boolean isAnnotationClass()
Is this an annotation class name of the form Lfoo.bar$$;


sysWrite

public void sysWrite()

length

public int length()

hashCode

public int hashCode()
Return the hashCode of an atom, this equals the unicode string encoding of the atom

Overrides:
hashCode in class Object

equals

public boolean equals(Object other)
Outside of this class atoms are canonical and should be compared using ==. This method is used to maintain atoms in internal hash tables and shouldn't be used externally.

Overrides:
equals in class Object

internString

public static String internString(String str)
External string intern method called from String.intern. This method should return a canonical string encoding for the given string and this string should also be canonical with string literals.

Parameters:
str - string to intern
Returns:
interned version of string