org.jikesrvm.compilers.baseline
Class ReferenceMaps

java.lang.Object
  extended by org.jikesrvm.compilers.baseline.ReferenceMaps
All Implemented Interfaces:
ArchitectureSpecific.BaselineConstants, Constants, HeapLayoutConstants, ArchConstants, BaselineConstants, RegisterConstants, StackframeLayoutConstants, TrapConstants, ThinLockConstants, TIBLayoutConstants, SizeConstants

public final class ReferenceMaps
extends Object
implements ArchitectureSpecific.BaselineConstants

class that provides stack (and local var) map for a baseline compiled method GC uses the methods provided here


Nested Class Summary
private static class ReferenceMaps.MergeOperation
          Kinds of merge operation when merging delta maps into table maps
 
Nested classes/interfaces inherited from interface org.jikesrvm.ia32.RegisterConstants
RegisterConstants.FloatingPointMachineRegister, RegisterConstants.FPR, RegisterConstants.GPR, RegisterConstants.MachineRegister, RegisterConstants.MM, RegisterConstants.XMM
 
Field Summary
private static int BITS_PER_MAP_ELEMENT
          Number of bits in each map element
private  int bitsPerMap
          Number of bits in each map
static byte JSR_INDEX_MASK
           
static byte JSR_MASK
           
private  JSRInfo jsrInfo
           
static SpinLock jsrLock
          Serializes JSR processing
private  int mapCount
          Number of maps
private  int[] MCSites
           
static int NOMORE
           
private  byte[] referenceMaps
           
static int STARTINDEX
           
 
Fields inherited from interface org.jikesrvm.ia32.BaselineConstants
BRIDGE_FRAME_EXTRA_SIZE, EBP_SAVE_OFFSET, EBX_SAVE_OFFSET, EDI_SAVE_OFFSET, FPU_SAVE_OFFSET, LG_WORDSIZE, S0, S1, SAVED_GPRS, SAVED_GPRS_FOR_SAVE_LS_REGISTERS, SP, STACKFRAME_FIRST_PARAMETER_OFFSET, STACKFRAME_REG_SAVE_OFFSET, T0, T0_int, T0_SAVE_OFFSET, T1, T1_int, T1_SAVE_OFFSET, TR, WORDSIZE, XMM_SAVE_OFFSET
 
Fields inherited from interface org.jikesrvm.Constants
NOT_REACHED, REFLECTION_FPRS_BITS, REFLECTION_FPRS_MASK, REFLECTION_GPRS_BITS, REFLECTION_GPRS_MASK
 
Fields inherited from interface org.jikesrvm.objectmodel.ThinLockConstants
TL_DEDICATED_U16_OFFSET, TL_DEDICATED_U16_SHIFT, TL_LOCK_COUNT_MASK, TL_LOCK_COUNT_SHIFT, TL_LOCK_COUNT_UNIT, TL_LOCK_ID_MASK, TL_LOCK_ID_SHIFT, TL_NUM_BITS_RC, TL_NUM_BITS_STAT, TL_NUM_BITS_TID, TL_STAT_BIASABLE, TL_STAT_FAT, TL_STAT_MASK, TL_STAT_SHIFT, TL_STAT_THIN, TL_THREAD_ID_MASK, TL_THREAD_ID_SHIFT, TL_UNLOCK_MASK
 
Fields inherited from interface org.jikesrvm.SizeConstants
BITS_IN_ADDRESS, BITS_IN_BOOLEAN, BITS_IN_BYTE, BITS_IN_CHAR, BITS_IN_DOUBLE, BITS_IN_EXTENT, BITS_IN_FLOAT, BITS_IN_INT, BITS_IN_LONG, BITS_IN_OFFSET, BITS_IN_PAGE, BITS_IN_SHORT, BITS_IN_WORD, BYTES_IN_ADDRESS, BYTES_IN_BOOLEAN, BYTES_IN_BYTE, BYTES_IN_CHAR, BYTES_IN_DOUBLE, BYTES_IN_EXTENT, BYTES_IN_FLOAT, BYTES_IN_INT, BYTES_IN_LONG, BYTES_IN_OFFSET, BYTES_IN_PAGE, BYTES_IN_SHORT, BYTES_IN_WORD, LOG_BITS_IN_ADDRESS, LOG_BITS_IN_BOOLEAN, LOG_BITS_IN_BYTE, LOG_BITS_IN_CHAR, LOG_BITS_IN_DOUBLE, LOG_BITS_IN_EXTENT, LOG_BITS_IN_FLOAT, LOG_BITS_IN_INT, LOG_BITS_IN_LONG, LOG_BITS_IN_OFFSET, LOG_BITS_IN_PAGE, LOG_BITS_IN_SHORT, LOG_BITS_IN_WORD, LOG_BYTES_IN_ADDRESS, LOG_BYTES_IN_BOOLEAN, LOG_BYTES_IN_BYTE, LOG_BYTES_IN_CHAR, LOG_BYTES_IN_DOUBLE, LOG_BYTES_IN_EXTENT, LOG_BYTES_IN_FLOAT, LOG_BYTES_IN_INT, LOG_BYTES_IN_LONG, LOG_BYTES_IN_OFFSET, LOG_BYTES_IN_PAGE, LOG_BYTES_IN_SHORT, LOG_BYTES_IN_WORD
 
Fields inherited from interface org.jikesrvm.objectmodel.TIBLayoutConstants
IMT_METHOD_SLOTS, NEEDS_DYNAMIC_LINK, TIB_ARRAY_ELEMENT_TIB_INDEX, TIB_DOES_IMPLEMENT_INDEX, TIB_FIRST_SPECIALIZED_METHOD_INDEX, TIB_FIRST_VIRTUAL_METHOD_INDEX, TIB_INTERFACE_DISPATCH_TABLE_INDEX, TIB_SUPERCLASS_IDS_INDEX, TIB_TYPE_INDEX
 
Fields inherited from interface org.jikesrvm.HeapLayoutConstants
BAD_MAP_COMPRESSION, BOOT_IMAGE_CODE_END, BOOT_IMAGE_CODE_SIZE, BOOT_IMAGE_CODE_START, BOOT_IMAGE_DATA_END, BOOT_IMAGE_DATA_SIZE, BOOT_IMAGE_DATA_START, BOOT_IMAGE_END, BOOT_IMAGE_RMAP_END, BOOT_IMAGE_RMAP_START, MAX_BOOT_IMAGE_RMAP_SIZE, MAXIMUM_MAPPABLE
 
Fields inherited from interface org.jikesrvm.ia32.ArchConstants
SSE2_BASE, SSE2_FULL
 
Fields inherited from interface org.jikesrvm.ia32.StackframeLayoutConstants
BYTES_IN_STACKSLOT, FPU_STATE_SIZE, INVISIBLE_METHOD_ID, LOG_BYTES_IN_STACKSLOT, STACK_SIZE_BOOT, STACK_SIZE_COLLECTOR, STACK_SIZE_DLOPEN, STACK_SIZE_GCDISABLED, STACK_SIZE_GROW, STACK_SIZE_GUARD, STACK_SIZE_JNINATIVE_GROW, STACK_SIZE_MAX, STACK_SIZE_NORMAL, STACK_SIZE_SYSCALL, STACKFRAME_ALIGNMENT, STACKFRAME_BODY_OFFSET, STACKFRAME_FRAME_POINTER_OFFSET, STACKFRAME_HEADER_SIZE, STACKFRAME_METHOD_ID_OFFSET, STACKFRAME_RETURN_ADDRESS_OFFSET, STACKFRAME_SENTINEL_FP, XMM_STATE_SIZE
 
Fields inherited from interface org.jikesrvm.ia32.RegisterConstants
ALL_FPRS, ALL_GPRS, EAX, EBP, EBX, ECX, EDI, EDX, ESI, ESP, FP0, FP1, FP2, FP3, FP4, FP5, FP6, FP7, INSTRUCTION_WIDTH, LG_INSTRUCTION_WIDTH, MM0, MM1, MM10, MM11, MM12, MM13, MM14, MM15, MM2, MM3, MM4, MM5, MM6, MM7, MM8, MM9, NATIVE_NONVOLATILE_FPRS, NATIVE_NONVOLATILE_GPRS, NATIVE_PARAMETER_FPRS, NATIVE_PARAMETER_GPRS, NATIVE_VOLATILE_FPRS, NATIVE_VOLATILE_GPRS, NONVOLATILE_FPRS, NONVOLATILE_GPRS, NUM_FPRS, NUM_GPRS, NUM_NONVOLATILE_FPRS, NUM_NONVOLATILE_GPRS, NUM_PARAMETER_FPRS, NUM_PARAMETER_GPRS, NUM_RETURN_FPRS, NUM_RETURN_GPRS, NUM_VOLATILE_FPRS, NUM_VOLATILE_GPRS, PARAMETER_FPRS, PARAMETER_GPRS, R0, R1, R10, R11, R12, R13, R14, R15, R2, R3, R4, R5, R6, R7, R8, R9, RETURN_FPRS, RETURN_GPRS, STACK_POINTER, THREAD_REGISTER, VOLATILE_FPRS, VOLATILE_GPRS, XMM0, XMM1, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9
 
Fields inherited from interface org.jikesrvm.ia32.TrapConstants
RVM_TRAP_BASE
 
Constructor Summary
ReferenceMaps(BaselineCompiledMethod cm, int[] stackHeights, byte[] localTypes)
           
 
Method Summary
private  int addUnusualMap(UnusualMaps jsrSiteMap)
          Add an UnusualMap to the array of unusual maps, expand the array and referencemap array if necessary
private  int bytesPerMap()
          size of individual maps
 void cleanupPointers()
          This routine is used to clean out the MethodMap of structures that were allocated from temporary storage.
private  UnusualMaps combineDeltaMaps(int jsrUnusualMapid)
          Merges unusual maps (occurs in nested jsr conditions) by merging each nested delta map ( as represented by the jsrMapid of the location site) into the jsrInfo.extraUnusualMap where the deltas are accumulated
private  byte convertMapElement(byte[] curBBMap, int offset, int len, byte reftype)
          convert a portion of an array word of Bytes into a bitmap of references i.e. given a byte array, a starting offset in the array, the length to scan, and the type of byte to scan for ... convert the area in the array to a word of bits ... max length is 31 i.e.
private  void copyBitMap(int extramapindex, int index)
          Copies a bit map into the extra unusualmap.
private  void finalMergeMaps(int jsrBaseMapIndex, UnusualMaps deltaMap)
          This method will merge the jsr invoker's base map with changes due to *all* nested jsr subroutines.
(package private)  int findUnusualMap(int mapid)
          Finds an unsual map with an index greater than 127.
 int getNextJSRAddressIndex(Offset nextMachineCodeOffset, NormalMethod m)
           
 int getNextJSRRefIndex(int index)
          Given an offset in the jsr reference map, return the offset where the next returnAddress can be found.
 int getNextJSRReturnAddrIndex(int index)
          Given an offset in the jsr returnAddress map, return the offset where the next returnAddress can be found.
private  int getNextMapElement()
          get Next free word in referencemaps for GC call sites
 int getNextRefIndex(int index, int siteindex)
           
 int getStackDepth(int mapid)
          For debugging (used with CheckRefMaps) Note: all maps are the same size
 boolean isLocalRefType(RVMMethod method, Offset mcoff, int lidx)
          Query if a local variable has a reference type value
 int locateGCPoint(Offset machCodeOffset, RVMMethod method)
          Given a machine code instruction offset, return an index to identify the stack map closest to the offset ( but not beyond).
private  void mergeMap(int targetindex, int deltaindex, ReferenceMaps.MergeOperation Op)
          Merges a delta map into a target map.
 void recordingComplete()
          Called when all the recording for this map is complete.
 void recordJSRSubroutineMap(int byteindex, byte[] currReferenceMap, int BBLastPtr, int returnAddrIndex, boolean replacemap)
          Record a map for a point within a JSR Subroutine.
 void recordStkMap(int byteindex, byte[] byteMap, int BBLastPtr, boolean replacemap)
          Given the information about a GC point, record the information in the proper tables.
private  int scanByte(int bitnum, int bytenum, int toscan, byte[] map)
          Scans for a reference in a byte.
(package private)  int scanByteArray(byte[] byteMap, int BBLastPtr, byte refType, int mapslot, boolean skipOneBit)
          Scans the byte array to look for the type of information that was requested.
private  int scanForNextRef(int bitnum, int wordnum, int remaining, byte[] map)
          Scans the map for the next reference.
 int setupJSRSubroutineMap(int mapid)
          Setup a map within a JSR Subroutine.
 void showAMap(int MCSiteIndex)
          Show the basic information for a single map.
 void showInfo()
          Shows the basic information for each of the maps.
 void showOffsets()
          Show the offsets for all the maps.
 int showReferenceMapStatistics(RVMMethod method)
           
 int size()
           
 void startNewMaps(int gcPointCount, int jsrCount, int parameterWords)
          start setting up the reference maps for this method.
 void translateByte2Machine(int[] b2m)
          After code is generated, translate the bytecode indices recorded in MCSites array into real machine code offsets.
private  void unusualMapcopy(UnusualMaps from)
          Makes a deep copy of from into jsrInfo.extraUnusualMap
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

JSR_MASK

public static final byte JSR_MASK
See Also:
Constant Field Values

JSR_INDEX_MASK

public static final byte JSR_INDEX_MASK
See Also:
Constant Field Values

STARTINDEX

public static final int STARTINDEX
See Also:
Constant Field Values

NOMORE

public static final int NOMORE
See Also:
Constant Field Values

jsrLock

public static final SpinLock jsrLock
Serializes JSR processing


BITS_PER_MAP_ELEMENT

private static final int BITS_PER_MAP_ELEMENT
Number of bits in each map element

See Also:
Constant Field Values

referenceMaps

private byte[] referenceMaps

MCSites

private int[] MCSites

bitsPerMap

private final int bitsPerMap
Number of bits in each map


mapCount

private int mapCount
Number of maps


jsrInfo

private JSRInfo jsrInfo
Constructor Detail

ReferenceMaps

ReferenceMaps(BaselineCompiledMethod cm,
              int[] stackHeights,
              byte[] localTypes)
Method Detail

bytesPerMap

private int bytesPerMap()
size of individual maps


locateGCPoint

public int locateGCPoint(Offset machCodeOffset,
                         RVMMethod method)
Given a machine code instruction offset, return an index to identify the stack map closest to the offset ( but not beyond).

Usage note: "machCodeOffset" must point to the instruction *following* the actual instruction whose stack map is sought. This allows us to properly handle the case where the only address we have to work with is a return address (i.e. from a stackframe) or an exception address (i.e. from a null pointer dereference, array bounds check, or divide by zero) on a machine architecture with variable length instructions. In such situations we'd have no idea how far to back up the instruction pointer to point to the "call site" or "exception site".

If the located site is within the scope of a jsr subroutine the index value returned is a negative number.


getNextRefIndex

public int getNextRefIndex(int index,
                           int siteindex)
Parameters:
index - offset in the reference stack frame,
siteindex - index that indicates the callsite (siteindex),
Returns:
return the offset where the next reference can be found.

getNextJSRRefIndex

public int getNextJSRRefIndex(int index)
Given an offset in the jsr reference map, return the offset where the next returnAddress can be found.

NOTE: There is only one JSR map for the entire method because it has to be constructed at GC time and would normally require additional storage.

To avoid this, the space for one map is pre-allocated and the map is built in that space. When multiple threads exist and if GC runs in multiple threads concurrently, then the MethodMap must be locked when a JSR map is being scanned. This should be a low probability event.

Parameters:
index - offset in the JSR reference map,
Returns:
The offset where the next reference can be found or NOMORE when no more pointers can be found

getNextJSRReturnAddrIndex

public int getNextJSRReturnAddrIndex(int index)
Given an offset in the jsr returnAddress map, return the offset where the next returnAddress can be found.

NOTE: there is only one jsr returnAddress map for the entire method because it has to be be constructed a GC time and would normally require additional storage. To avoid this, the space for one map is pre-allocated and the map is built in that space. When multiple threads exist and if GC runs in multiple threads concurrently, then the MethodMap must be locked when a jsr map is being scanned. This should be a low probability event.

NOTE: return addresses are handled separately from references because they point inside an object ( internal pointers)

Parameters:
index - offset in the JSR returnAddress map,
Returns:
The offset where the next reference can be found or NOMORE when no more pointers can be found

getStackDepth

public int getStackDepth(int mapid)
For debugging (used with CheckRefMaps) Note: all maps are the same size


size

public int size()

startNewMaps

public void startNewMaps(int gcPointCount,
                         int jsrCount,
                         int parameterWords)
start setting up the reference maps for this method.


recordStkMap

public void recordStkMap(int byteindex,
                         byte[] byteMap,
                         int BBLastPtr,
                         boolean replacemap)
Given the information about a GC point, record the information in the proper tables.

Parameters:
byteindex - the index in the bytecode of this site
byteMap - a byte array that describes the contents of the local variables and the java stack
BBLastPtr - the last offset of a byte that contains information about the map
replacemap - whether this map is a replacement for a currently existing map

recordJSRSubroutineMap

public void recordJSRSubroutineMap(int byteindex,
                                   byte[] currReferenceMap,
                                   int BBLastPtr,
                                   int returnAddrIndex,
                                   boolean replacemap)
Record a map for a point within a JSR Subroutine. This requires setting up one of the unusual maps.

Parameters:
byteindex - index into the byte code array of the point for the map
currReferenceMap - map of references and return addresses that were set within the JSR Subroutine
BBLastPtr - map runs from -1 to BBLastPtr inclusively
returnAddrIndex - Index in the stack where the return address for the jsr routine (in which this gcpoint is located) can be found
replacemap - false if this is the first time this map point has been recorded.

addUnusualMap

private int addUnusualMap(UnusualMaps jsrSiteMap)
Add an UnusualMap to the array of unusual maps, expand the array and referencemap array if necessary

Parameters:
jsrSiteMap - unusualMap to be added to array

setupJSRSubroutineMap

public int setupJSRSubroutineMap(int mapid)
Setup a map within a JSR Subroutine. This requires using up one of the unusual maps. This routine is called when the caller gets a negative mapindex value return from locateGCPoint(org.vmmagic.unboxed.Offset, org.jikesrvm.classloader.RVMMethod). This routine searches the map tables and uses its stack frameAddress input to build reference and returnAddress maps. The caller uses the getNext... routines to scan these maps for offsets in the frame of the related references.

Steps for this routine:

  1. use the mapid to get index of the Unusual Map
  2. from the unusual map and the frame - get the location of the jsr invoker
  3. from the invoker address and the code base address - get the machine code offset from the machine code offset locate the map for that instruction
  4. if the invoker was itself in a jsr- merge the delta maps of each jsr and compute the new total delta maps
  5. else the invoker was not already in a jsr merge the unusual map differences with the invoker map

Parameters:
mapid - Index of map of instruction where map is required ( this value was returned by locateGCpoint)

getNextJSRAddressIndex

public int getNextJSRAddressIndex(Offset nextMachineCodeOffset,
                                  NormalMethod m)

recordingComplete

public void recordingComplete()
Called when all the recording for this map is complete. Can now sort or perform other cleanups


translateByte2Machine

public void translateByte2Machine(int[] b2m)
After code is generated, translate the bytecode indices recorded in MCSites array into real machine code offsets.


convertMapElement

private byte convertMapElement(byte[] curBBMap,
                               int offset,
                               int len,
                               byte reftype)
convert a portion of an array word of Bytes into a bitmap of references i.e. given a byte array, a starting offset in the array, the length to scan, and the type of byte to scan for ... convert the area in the array to a word of bits ... max length is 31 i.e. BITS_PER_MAP_ELEMENT


getNextMapElement

private int getNextMapElement()
get Next free word in referencemaps for GC call sites


scanForNextRef

private int scanForNextRef(int bitnum,
                           int wordnum,
                           int remaining,
                           byte[] map)
Scans the map for the next reference.

Parameters:
bitnum - starting bitnumber in a map (inclusive)
wordnum - index of the corresponding byte,
remaining - remaining number of bits in the map,
map - map to search
Returns:
TODO document me

scanByte

private int scanByte(int bitnum,
                     int bytenum,
                     int toscan,
                     byte[] map)
Scans for a reference in a byte.

Parameters:
bitnum - bitnumber in the map
bytenum - index of the corresponding map byte
toscan - the remaining number of bits in the byte,
map - the map
Returns:
next ref in the byte or zero if not found

scanByteArray

int scanByteArray(byte[] byteMap,
                  int BBLastPtr,
                  byte refType,
                  int mapslot,
                  boolean skipOneBit)
Scans the byte array to look for the type of information that was requested. Builds a bit array in the stack maps with the information.

Parameters:
byteMap - bytearray where each byte describes the corresponding word on a stack
BBLastPtr - length of the byte array
refType - type of information that is to be scanned
mapslot - slot where map should be stored, 0 for next free slot
skipOneBit - should a bit in the bitarray be skipped? Necessary for setRef and setNonRef maps so so they are properly merged with jsr base maps.
Returns:
index of the map in the reference map

unusualMapcopy

private void unusualMapcopy(UnusualMaps from)
Makes a deep copy of from into jsrInfo.extraUnusualMap

Parameters:
from -

copyBitMap

private void copyBitMap(int extramapindex,
                        int index)
Copies a bit map into the extra unusualmap.

Parameters:
extramapindex - the index of the map in the jsrInfo.extraUnusualMap ie the "to" map
index - he index of the map to copy ie the "from" map

combineDeltaMaps

private UnusualMaps combineDeltaMaps(int jsrUnusualMapid)
Merges unusual maps (occurs in nested jsr conditions) by merging each nested delta map ( as represented by the jsrMapid of the location site) into the jsrInfo.extraUnusualMap where the deltas are accumulated

Parameters:
jsrUnusualMapid - the delta map's id
Returns:
merged map

mergeMap

private void mergeMap(int targetindex,
                      int deltaindex,
                      ReferenceMaps.MergeOperation Op)
Merges a delta map into a target map.

Parameters:
targetindex - the delta map's index in the reference map table
deltaindex - the target map's index in the reference map tbale
Op - the merge operation to use

finalMergeMaps

private void finalMergeMaps(int jsrBaseMapIndex,
                            UnusualMaps deltaMap)
This method will merge the jsr invoker's base map with changes due to *all* nested jsr subroutines.

The nested jsr subroutine maps were merged into a single delta map prior to the calling of this method. We therefore know that the base map can never be due to a subroutine (since all subroutines have been merged), and therefore that there are no return address maps due to the invoker (since return addresses are only due to the subroutine maps).

Parameters:
jsrBaseMapIndex - The map index for the invoker
deltaMap - The map for the invoked subroutine/s (all nested subroutine maps are guaranteed to have been combined prior to calling this)

cleanupPointers

public void cleanupPointers()
This routine is used to clean out the MethodMap of structures that were allocated from temporary storage. Temporary storage is freed up between stack frames as the GC scans the stack.


findUnusualMap

int findUnusualMap(int mapid)
Finds an unsual map with an index greater than 127. It returns the index by doing a sequential scan and looking for the mapid in the normal map directory.

Parameters:
mapid - the map's id
Returns:
the map's index

showInfo

public void showInfo()
Shows the basic information for each of the maps. This is for testing use.


showAMap

public void showAMap(int MCSiteIndex)
Show the basic information for a single map. This is for testing use.


showOffsets

public void showOffsets()
Show the offsets for all the maps. This is for test use.


showReferenceMapStatistics

public int showReferenceMapStatistics(RVMMethod method)

isLocalRefType

public boolean isLocalRefType(RVMMethod method,
                              Offset mcoff,
                              int lidx)
Query if a local variable has a reference type value

Parameters:
method - The method we're asking about.
mcoff - The machine code offset of the instruction *following* the actual instruction.
lidx - the local index
Returns:
true, if it is a reference type. false, otherwise