use of org.graalvm.word.Pointer in project graal by oracle.
the class MonitorSnippets method monitorexit.
@Snippet
public static void monitorexit(Object object, @ConstantParameter int lockDepth, @ConstantParameter Register threadRegister, @ConstantParameter boolean trace, @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {
trace(trace, " object: 0x%016lx\n", Word.objectToTrackedPointer(object));
final Word mark = loadWordFromObject(object, markOffset(INJECTED_VMCONFIG));
if (useBiasedLocking(INJECTED_VMCONFIG)) {
// Check for biased locking unlock case, which is a no-op
// Note: we do not have to check the thread ID for two reasons.
// First, the interpreter checks for IllegalMonitorStateException at
// a higher level. Second, if the bias was revoked while we held the
// lock, the object could not be rebiased toward another thread, so
// the bias bit would be clear.
trace(trace, " mark: 0x%016lx\n", mark);
if (probability(FREQUENT_PROBABILITY, mark.and(biasedLockMaskInPlace(INJECTED_VMCONFIG)).equal(WordFactory.unsigned(biasedLockPattern(INJECTED_VMCONFIG))))) {
endLockScope();
decCounter(options);
traceObject(trace, "-lock{bias}", object, false, options);
counters.unlockBias.inc();
return;
}
}
final Word lock = CurrentLockNode.currentLock(lockDepth);
// Load displaced mark
final Word displacedMark = lock.readWord(lockDisplacedMarkOffset(INJECTED_VMCONFIG), DISPLACED_MARK_WORD_LOCATION);
trace(trace, " displacedMark: 0x%016lx\n", displacedMark);
if (probability(NOT_LIKELY_PROBABILITY, displacedMark.equal(0))) {
// Recursive locking => done
traceObject(trace, "-lock{recursive}", object, false, options);
counters.unlockCasRecursive.inc();
} else {
if (!tryExitInflated(object, mark, lock, threadRegister, trace, options, counters)) {
verifyOop(object);
// Test if object's mark word is pointing to the displaced mark word, and if so,
// restore
// the displaced mark in the object - if the object's mark word is not pointing to
// the displaced mark word, do unlocking via runtime call.
Pointer objectPointer = Word.objectToTrackedPointer(object);
if (probability(VERY_FAST_PATH_PROBABILITY, objectPointer.logicCompareAndSwapWord(markOffset(INJECTED_VMCONFIG), lock, displacedMark, MARK_WORD_LOCATION))) {
traceObject(trace, "-lock{cas}", object, false, options);
counters.unlockCas.inc();
} else {
// The object's mark word was not pointing to the displaced header
traceObject(trace, "-lock{stub}", object, false, options);
counters.unlockStub.inc();
monitorexitStubC(MONITOREXIT, object, lock);
}
}
}
endLockScope();
decCounter(options);
}
use of org.graalvm.word.Pointer in project graal by oracle.
the class WriteBarrierSnippets method g1PreWriteBarrier.
@Snippet
public static void g1PreWriteBarrier(Address address, Object object, Object expectedObject, @ConstantParameter boolean doLoad, @ConstantParameter boolean nullCheck, @ConstantParameter Register threadRegister, @ConstantParameter boolean trace, @ConstantParameter Counters counters) {
if (nullCheck) {
NullCheckNode.nullCheck(address);
}
Word thread = registerAsWord(threadRegister);
verifyOop(object);
Object fixedExpectedObject = FixedValueAnchorNode.getObject(expectedObject);
Word field = Word.fromAddress(address);
Pointer previousOop = Word.objectToTrackedPointer(fixedExpectedObject);
byte markingValue = thread.readByte(g1SATBQueueMarkingOffset(INJECTED_VMCONFIG));
int gcCycle = 0;
if (trace) {
Pointer gcTotalCollectionsAddress = WordFactory.pointer(HotSpotReplacementsUtil.gcTotalCollectionsAddress(INJECTED_VMCONFIG));
gcCycle = (int) gcTotalCollectionsAddress.readLong(0);
log(trace, "[%d] G1-Pre Thread %p Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue());
log(trace, "[%d] G1-Pre Thread %p Expected Object %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(fixedExpectedObject).rawValue());
log(trace, "[%d] G1-Pre Thread %p Field %p\n", gcCycle, thread.rawValue(), field.rawValue());
log(trace, "[%d] G1-Pre Thread %p Marking %d\n", gcCycle, thread.rawValue(), markingValue);
log(trace, "[%d] G1-Pre Thread %p DoLoad %d\n", gcCycle, thread.rawValue(), doLoad ? 1L : 0L);
}
counters.g1AttemptedPreWriteBarrierCounter.inc();
// If the concurrent marker is enabled, the barrier is issued.
if (probability(NOT_FREQUENT_PROBABILITY, markingValue != (byte) 0)) {
// The load is always issued except the cases of CAS and referent field.
if (probability(LIKELY_PROBABILITY, doLoad)) {
previousOop = Word.objectToTrackedPointer(field.readObject(0, BarrierType.NONE));
if (trace) {
log(trace, "[%d] G1-Pre Thread %p Previous Object %p\n ", gcCycle, thread.rawValue(), previousOop.rawValue());
verifyOop(previousOop.toObject());
}
}
counters.g1EffectivePreWriteBarrierCounter.inc();
// If the previous value is null the barrier should not be issued.
if (probability(FREQUENT_PROBABILITY, previousOop.notEqual(0))) {
counters.g1ExecutedPreWriteBarrierCounter.inc();
// If the thread-local SATB buffer is full issue a native call which will
// initialize a new one and add the entry.
Word indexAddress = thread.add(g1SATBQueueIndexOffset(INJECTED_VMCONFIG));
Word indexValue = indexAddress.readWord(0);
if (probability(FREQUENT_PROBABILITY, indexValue.notEqual(0))) {
Word bufferAddress = thread.readWord(g1SATBQueueBufferOffset(INJECTED_VMCONFIG));
Word nextIndex = indexValue.subtract(wordSize());
Word logAddress = bufferAddress.add(nextIndex);
// Log the object to be marked as well as update the SATB's buffer next index.
logAddress.writeWord(0, previousOop, GC_LOG_LOCATION);
indexAddress.writeWord(0, nextIndex, GC_INDEX_LOCATION);
} else {
g1PreBarrierStub(G1WBPRECALL, previousOop.toObject());
}
}
}
}
use of org.graalvm.word.Pointer in project graal by oracle.
the class PosixAMD64VaListSnippets method vaArgLongSnippet.
@Snippet
protected static long vaArgLongSnippet(Pointer vaList) {
int gpOffset = vaList.readInt(GP_OFFSET_LOCATION);
if (gpOffset < MAX_GP_OFFSET) {
Pointer regSaveArea = vaList.readWord(REG_SAVE_AREA_LOCATION);
long v = regSaveArea.readLong(gpOffset);
vaList.writeInt(GP_OFFSET_LOCATION, gpOffset + 8);
return v;
} else {
Pointer overflowArgArea = vaList.readWord(OVERFLOW_ARG_AREA_LOCATION);
long v = overflowArgArea.readLong(0);
vaList.writeWord(OVERFLOW_ARG_AREA_LOCATION, overflowArgArea.add(OVERFLOW_ARG_AREA_ALIGNMENT));
return v;
}
}
use of org.graalvm.word.Pointer in project graal by oracle.
the class PosixIsolates method create.
@Uninterruptible(reason = "Thread state not yet set up.")
public static int create(WordPointer isolatePointer, @SuppressWarnings("unused") CEntryPointCreateIsolateParameters parameters) {
if (!SubstrateOptions.SpawnIsolates.getValue()) {
isolatePointer.write(CEntryPointSetup.SINGLE_ISOLATE_SENTINEL);
return Errors.NO_ERROR;
}
Word begin = IMAGE_HEAP_BEGIN.get();
Word size = IMAGE_HEAP_END.get().subtract(begin);
/*
* Request an anonymous memory mapping for this isolate's clone of the image heap. The start
* address of that mapping becomes the isolate's heap base address. We want extra heap
* chunks that we allocate later to be at a higher address than the heap base so that we can
* safely consider the base-relative offsets to be unsigned. Therefore, we request the
* lowest non-zero multiple of the page size as this mapping's address. However, that
* request is only a hint unless we use MAP_FIXED, which makes things much more complex on
* our end. Observations:
*
* - Without a hint to mmap(), anonymous mappings on Linux 4.4 (openSUSE) on x86_64 are
* created just before the mapped shared objects, and subsequent mappings are assigned
* decreasing addresses. However, specifying sysconf(_SC_PAGE_SIZE) as a hint for the first
* mapping reproducingly places it at a very low address, even before the loaded executable.
* Therefore, it seems that a number of isolates can be reliably created with their image
* heap clones at low addresses and with allocated heap chunks at higher addresses.
*
* - On Darwin 13.4, anonymous mappings are created after the mapped executable (and some
* malloc regions in between). Subsequent mappings are assigned increasing addresses that
* are close to each other. Specifying hints does not have a noticeable effect. Unmapping a
* mapping makes its address space immediately reusable. Due to the increasing addresses, a
* single isolate's heap can be safely created. However, because of the address space reuse,
* a heap chunk of an isolate can be allocated at a lower address than its heap base when
* another isolate unmaps a chunk at that location.
*/
long pageSize = Unistd.NoTransitions.sysconf(Unistd._SC_PAGE_SIZE());
Pointer heap = Mman.NoTransitions.mmap(Word.pointer(pageSize), size, PROT_READ() | PROT_WRITE(), MAP_ANON() | MAP_PRIVATE(), -1, 0);
if (heap.equal(MAP_FAILED())) {
return Errors.HEAP_CLONE_FAILED;
}
LibC.memcpy(heap, begin, size);
isolatePointer.write(heap);
return Errors.NO_ERROR;
}
use of org.graalvm.word.Pointer in project graal by oracle.
the class SnippetRuntime method deoptimize.
/**
* Foreign call: {@link #DEOPTIMIZE}.
*/
@SubstrateForeignCallTarget
private static void deoptimize(long actionAndReason, SpeculationReason speculation) {
Pointer sp = KnownIntrinsics.readCallerStackPointer();
DeoptimizationAction action = Deoptimizer.decodeDeoptAction(actionAndReason);
if (Deoptimizer.Options.TraceDeoptimization.getValue()) {
Log log = Log.log().string("[Deoptimization initiated").newline();
CodePointer ip = KnownIntrinsics.readReturnAddress();
SubstrateInstalledCode installedCode = CodeInfoTable.lookupInstalledCode(ip);
if (installedCode != null) {
log.string(" name: ").string(installedCode.getName()).newline();
}
log.string(" sp: ").hex(sp).string(" ip: ").hex(ip).newline();
DeoptimizationReason reason = Deoptimizer.decodeDeoptReason(actionAndReason);
log.string(" reason: ").string(reason.toString()).string(" action: ").string(action.toString()).newline();
int debugId = Deoptimizer.decodeDebugId(actionAndReason);
log.string(" debugId: ").signed(debugId).string(" speculation: ").string(Objects.toString(speculation)).newline();
CodeInfoQueryResult info = CodeInfoTable.lookupCodeInfoQueryResult(ip);
if (info != null) {
NodeSourcePosition sourcePosition = DeoptimizationSourcePositionDecoder.decode(debugId, info);
if (sourcePosition != null) {
log.string(" stack trace that triggered deoptimization:").newline();
NodeSourcePosition cur = sourcePosition;
while (cur != null) {
log.string(" at ");
if (cur.getMethod() != null) {
StackTraceElement element = cur.getMethod().asStackTraceElement(cur.getBCI());
if (element.getFileName() != null && element.getLineNumber() >= 0) {
log.string(element.toString());
} else {
log.string(cur.getMethod().format("%H.%n(%p)")).string(" bci ").signed(cur.getBCI());
}
} else {
log.string("[unknown method]");
}
log.newline();
cur = cur.getCaller();
}
}
}
}
if (action.doesInvalidateCompilation()) {
Deoptimizer.invalidateMethodOfFrame(sp, speculation);
} else {
Deoptimizer.deoptimizeFrame(sp, false, speculation);
}
if (Deoptimizer.Options.TraceDeoptimization.getValue()) {
Log.log().string("]").newline();
}
}
Aggregations