use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class GenerateInterfaceDeclarations method emitCDeclarationsForJavaType.
static void emitCDeclarationsForJavaType(String Cname, RVMClass cls) {
// How many instance fields are there?
//
RVMField[] allFields = cls.getDeclaredFields();
int fieldCount = 0;
for (RVMField field : allFields) {
if (!field.isStatic()) {
fieldCount++;
}
}
RVMField[] fields = new RVMField[fieldCount];
for (int i = 0, j = 0; i < allFields.length; i++) {
if (!allFields[i].isStatic()) {
fields[j++] = allFields[i];
}
}
Arrays.sort(fields, new AscendingOffsetComparator());
// Emit field declarations
//
pln("struct " + Cname + " {");
// Set up cursor - scalars will waste 4 bytes on 64-bit arch
//
boolean needsAlign = VM.BuildFor64Addr;
int addrSize = VM.BuildFor32Addr ? 4 : 8;
// Header Space for objects
int startOffset = ObjectModel.objectStartOffset(cls);
Offset current = Offset.fromIntSignExtend(startOffset);
for (int i = 0; current.sLT(fields[0].getOffset()); i++) {
pln(" uint32_t headerPadding" + i + ";");
current = current.plus(4);
}
for (int i = 0; i < fields.length; i++) {
RVMField field = fields[i];
TypeReference t = field.getType();
Offset offset = field.getOffset();
String name = field.getName().toString();
// Align by blowing 4 bytes if needed
if (needsAlign && current.plus(4).EQ(offset)) {
pln(" uint32_t padding" + i + ";");
current = current.plus(4);
}
if (!current.EQ(offset)) {
System.err.printf("current (%s) and offset (%s) are neither identical nor differ by 4", unboxedValueString(current), unboxedValueString(offset));
System.exit(1);
}
if (t.isIntType()) {
current = current.plus(4);
pln(" uint32_t " + name + ";");
} else if (t.isLongType()) {
current = current.plus(8);
pln(" uint64_t " + name + ";");
} else if (t.isWordLikeType()) {
pln(" Address " + name + ";");
current = current.plus(addrSize);
} else if (t.isArrayType() && t.getArrayElementType().isWordLikeType()) {
pln(" Address * " + name + ";");
current = current.plus(addrSize);
} else if (t.isArrayType() && t.getArrayElementType().isIntType()) {
pln(" unsigned int * " + name + ";");
current = current.plus(addrSize);
} else if (t.isReferenceType()) {
pln(" Address " + name + ";");
current = current.plus(addrSize);
} else {
System.err.println("Unexpected field " + name + " with type " + t);
throw new RuntimeException("unexpected field type");
}
}
pln("};");
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class SpinLock method lock.
/**
* Acquire a lock.
*/
public void lock() {
if (!VM.runningVM)
return;
VM.disableYieldpoints();
RVMThread i = RVMThread.getCurrentThread();
RVMThread p;
int attempts = 0;
Offset latestContenderOffset = Entrypoints.latestContenderField.getOffset();
do {
p = Magic.objectAsThread(Magic.addressAsObject(Magic.prepareAddress(this, latestContenderOffset)));
if (p == null) {
// nobody owns the lock
if (Magic.attemptAddress(this, latestContenderOffset, Address.zero(), Magic.objectAsAddress(i))) {
if (!VM.MagicAttemptImpliesStoreLoadBarrier)
Magic.fence();
return;
} else {
// don't handle contention
continue;
}
} else if (MCS_Locking && Magic.objectAsAddress(p).NE(IN_FLUX)) {
// lock is owned, but not being changed
if (Magic.attemptAddress(this, latestContenderOffset, Magic.objectAsAddress(p), IN_FLUX)) {
if (!VM.MagicAttemptImpliesStoreLoadBarrier)
Magic.fence();
break;
}
}
handleMicrocontention(attempts++);
} while (true);
// i owns the lock
if (VM.VerifyAssertions && !MCS_Locking)
VM._assert(VM.NOT_REACHED);
i.awaitingSpinLock = this;
if (p.awaitingSpinLock != this) {
// make i first (and only) waiter on the contender chain
i.contenderLink = i;
} else {
// make i last waiter on the contender chain
i.contenderLink = p.contenderLink;
p.contenderLink = i;
}
// so other contender will see updated contender chain
Magic.fence();
// other threads can get at the lock
Magic.setObjectAtOffset(this, latestContenderOffset, i);
do {
// spin, waiting for the lock
// to make new value visible as soon as possible
Magic.combinedLoadBarrier();
} while (i.awaitingSpinLock == this);
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class SpinLock method tryLock.
/**
* Conditionally acquire a lock.
* @return whether acquisition succeeded
*/
public boolean tryLock() {
if (!VM.runningVM)
return true;
VM.disableYieldpoints();
Offset latestContenderOffset = Entrypoints.latestContenderField.getOffset();
if (Magic.prepareAddress(this, latestContenderOffset).isZero()) {
Address cp = Magic.objectAsAddress(RVMThread.getCurrentThread());
if (Magic.attemptAddress(this, latestContenderOffset, Address.zero(), cp)) {
if (!VM.MagicAttemptImpliesStoreLoadBarrier)
Magic.fence();
return true;
}
}
VM.enableYieldpoints();
return false;
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class SpinLock method unlock.
/**
* Release a lock.
*/
public void unlock() {
if (!VM.runningVM)
return;
// commit changes while lock was held so they are visible to the next processor that acquires the lock
Magic.fence();
Offset latestContenderOffset = Entrypoints.latestContenderField.getOffset();
RVMThread i = RVMThread.getCurrentThread();
if (!MCS_Locking) {
// latestContender = null;
Magic.setObjectAtOffset(this, latestContenderOffset, null);
VM.enableYieldpoints();
return;
}
RVMThread p;
do {
p = Magic.objectAsThread(Magic.addressAsObject(Magic.prepareAddress(this, latestContenderOffset)));
if (p == i) {
// nobody is waiting for the lock
if (Magic.attemptAddress(this, latestContenderOffset, Magic.objectAsAddress(p), Address.zero())) {
break;
}
} else if (Magic.objectAsAddress(p).NE(IN_FLUX)) {
// there are waiters, but the contention chain is not being changed
if (Magic.attemptAddress(this, latestContenderOffset, Magic.objectAsAddress(p), IN_FLUX)) {
break;
}
} else {
// in flux
// wait a little before trying again
handleMicrocontention(-1);
}
} while (true);
if (p != i) {
// p is the last thread on the chain of threads contending for the lock
// q is first thread on the chain
RVMThread q = p.contenderLink;
if (p == q) {
// only one thread waiting for the lock
// q now owns the lock
q.awaitingSpinLock = null;
// make sure the chain of waiting threads gets updated before another thread accesses the chain
Magic.fence();
// other contenders can get at the lock:
// latestContender = q;
Magic.setObjectAtOffset(this, latestContenderOffset, q);
} else {
// more than one thread waiting for the lock
// remove q from the chain
p.contenderLink = q.contenderLink;
// q now owns the lock
q.awaitingSpinLock = null;
// make sure the chain of waiting threads gets updated before another thread accesses the chain
Magic.fence();
// other contenders can get at the lock
Magic.setObjectAtOffset(this, latestContenderOffset, p);
}
}
VM.enableYieldpoints();
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class DynamicLibrary method load.
/**
* Load a dynamic library
* @param libName the name of the library to load.
* @return 0 on failure, 1 on success
*/
public static synchronized int load(String libName) {
DynamicLibrary dl = dynamicLibraries.get(libName);
if (dl != null) {
// success: already loaded
return 1;
} else {
// Convert file name from unicode to filesystem character set.
// (Assume file name is ASCII, for now).
//
byte[] asciiName = StringUtilities.stringToBytesNullTerminated(libName);
// make sure we have enough stack to load the library.
// This operation has been known to require more than 20K of stack.
RVMThread myThread = RVMThread.getCurrentThread();
Offset remaining = Magic.getFramePointer().diff(myThread.stackLimit);
int stackNeededInBytes = StackFrameLayout.getStackSizeDLOpen() - remaining.toInt();
if (stackNeededInBytes > 0) {
if (myThread.hasNativeStackFrame()) {
throw new java.lang.StackOverflowError("Not enough space to open shared library");
} else {
RVMThread.resizeCurrentStack(myThread.getStackLength() + stackNeededInBytes, null);
}
}
Address libHandler = SysCall.sysCall.sysDlopen(asciiName);
if (!libHandler.isZero()) {
dynamicLibraries.put(libName, new DynamicLibrary(libName, libHandler));
return 1;
} else {
// fail; file does not exist
return 0;
}
}
}
Aggregations