package org.jikesrvm.cellspu; import org.jikesrvm.VM; import org.jikesrvm.VM_Constants; import org.jikesrvm.SubordinateArchitecture.VM_CodeArray; import org.jikesrvm.runtime.VM_Magic; import org.jikesrvm.runtime.VM_Memory; import org.jikesrvm.runtime.VM_SubArchEntrypoints; import org.jikesrvm.runtime.VM_SubArchStatics; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.pragma.UninterruptibleNoWarn; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.AddressArray; import org.vmmagic.unboxed.Offset; public class VM_SubArchBootRecord implements VM_Constants { // reference to global subarch bootrecord private static VM_SubArchBootRecord br = null; // TODO - Remove private static AddressArray fakeTrapStrsStatic = AddressArray.create(4096); private static int fakeTrapStrsIdx = 0; // JTOC address and middle offset public Address jtocStart; public int jtocMiddleOffset; public int jtocNumericOffset; public int jtocReferenceOffset; public int jtocLastCachedNumericOffset; public int jtocLastCachedReferenceOffset; public Object classTOCsTable; public Object staticsSizeTable; // signal that JTOC has been modified public /* TODO - volatile? */ int jtocDirty; // Out of line machine code necessary to support runtime public VM_CodeArray oolRuntimeCodeInstructions; public int oolRuntimeCodeLength; // Runtime methods public VM_CodeArray runtimeEntryMethod; public int runtimeEntryLength; // table of strings used by fakeTrap's public AddressArray fakeTrapStrs; /** * Signals that the subarch processors / threads have booted up */ private volatile int subArchBootComplete = 0; /** * Specifies the number of subarch processors / threads which have been brought up */ private volatile int noSubArchProcs = 0; public void init() { if (VM.writingBootImage) { VM._assert(br == null); br = this; this.jtocStart = VM_Magic.objectAsAddress(VM_SubArchStatics.getSlotsAsIntArray()); this.jtocMiddleOffset = VM_SubArchStatics.middleOfTable << LOG_BYTES_IN_INT; this.jtocNumericOffset = BYTES_IN_INT - (VM_SubArchStatics.getNumberOfNumericSlots() << LOG_BYTES_IN_INT); this.jtocReferenceOffset = VM_SubArchStatics.getNumberOfReferenceSlots() << LOG_BYTES_IN_INT; this.jtocLastCachedNumericOffset = 0; this.jtocLastCachedReferenceOffset = 0; this.jtocDirty = 1; this.classTOCsTable = VM_SubArchStatics.getMethodTIB(); this.staticsSizeTable = VM_SubArchStatics.getSizeStaticsTable(); this.oolRuntimeCodeInstructions = VM_OutOfLineMachineCode.runtimeInstructionsMainMem; this.oolRuntimeCodeLength = VM_Memory.alignUp(this.oolRuntimeCodeInstructions.length() << LOG_BYTES_IN_INT, BYTES_IN_QUAD); this.runtimeEntryMethod = (VM_CodeArray) VM_SubArchEntrypoints.runtimeEntry.getCurrentEntryCodeArray(true); this.runtimeEntryLength = VM_SubArchEntrypoints.runtimeEntry.getSubArchLength(); this.fakeTrapStrs = fakeTrapStrsStatic; } } @Uninterruptible public static void setJtocDirty() { if (VM.runningVM) { br.jtocDirty = 1; } } @Uninterruptible public static boolean isJtocDirty() { if (VM.runningVM) { return br.jtocDirty != 0; } else { return true; } } @Uninterruptible public static void updateJtocNumeric() { if (VM.runningVM) { br.jtocNumericOffset = BYTES_IN_INT - (VM_SubArchStatics.getNumberOfNumericSlots() << LOG_BYTES_IN_INT); } } @Uninterruptible public static void updateJtocReference() { if (VM.runningVM) { br.jtocReferenceOffset = (VM_SubArchStatics.getNumberOfReferenceSlots() << LOG_BYTES_IN_INT); } } @UninterruptibleNoWarn public static boolean verifyUpdate(Offset slot) { if (VM.runningVM) { //VM.sysWriteln("offset - " + slot.toInt() + " last cached num = " + br.jtocLastCachedNumericOffset + " lst cached ref = " + br.jtocLastCachedReferenceOffset); // assert that slot being updated is not one that has already been cached by subarch return (slot.sLE(Offset.fromIntSignExtend(br.jtocLastCachedNumericOffset)) || slot.sGE(Offset.fromIntSignExtend(br.jtocLastCachedReferenceOffset))); } else { return true; } } public static boolean isSubArchStarted() { if (VM.runningVM) { return br.subArchBootComplete != 0; } else { return false; } } public static int getNumSubArchProcs() { if (VM.runningVM) { return br.noSubArchProcs; } else { return 0; } } public static int addFakeTrapStr(Address address) { fakeTrapStrsStatic.set(fakeTrapStrsIdx, address); fakeTrapStrsIdx += 1; return fakeTrapStrsIdx - 1; } }