use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class MonitorSnippets method checkCounter.
@Snippet
private static void checkCounter(@ConstantParameter String errMsg) {
final Word counter = MonitorCounterNode.counter();
final int count = counter.readInt(0, MONITOR_COUNTER_LOCATION);
if (count != 0) {
vmError(errMsg, count);
}
}
use of org.graalvm.compiler.api.replacements.Snippet 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.compiler.api.replacements.Snippet in project graal by oracle.
the class NewObjectSnippets method newmultiarray.
/**
* Calls the runtime stub for implementing MULTIANEWARRAY.
*/
@Snippet
public static Object newmultiarray(KlassPointer hub, @ConstantParameter int rank, @VarargsParameter int[] dimensions) {
Word dims = DimensionsNode.allocaDimsArray(rank);
ExplodeLoopNode.explodeLoop();
for (int i = 0; i < rank; i++) {
dims.writeInt(i * 4, dimensions[i], LocationIdentity.init());
}
return newArrayCall(HotSpotBackend.NEW_MULTI_ARRAY, hub, rank, dims);
}
use of org.graalvm.compiler.api.replacements.Snippet 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.compiler.api.replacements.Snippet in project graal by oracle.
the class WriteBarrierSnippets method g1ArrayRangePostWriteBarrier.
@Snippet
public static void g1ArrayRangePostWriteBarrier(Address address, int length, @ConstantParameter int elementStride, @ConstantParameter Register threadRegister) {
if (length == 0) {
return;
}
Word thread = registerAsWord(threadRegister);
Word bufferAddress = thread.readWord(g1CardQueueBufferOffset(INJECTED_VMCONFIG));
Word indexAddress = thread.add(g1CardQueueIndexOffset(INJECTED_VMCONFIG));
long indexValue = thread.readWord(g1CardQueueIndexOffset(INJECTED_VMCONFIG)).rawValue();
int cardShift = cardTableShift(INJECTED_VMCONFIG);
final long cardStart = GraalHotSpotVMConfigNode.cardTableAddress();
long start = getPointerToFirstArrayElement(address, length, elementStride) >>> cardShift;
long end = getPointerToLastArrayElement(address, length, elementStride) >>> cardShift;
long count = end - start + 1;
while (count-- > 0) {
Word cardAddress = WordFactory.unsigned((start + cardStart) + count);
byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION);
// If the card is already dirty, (hence already enqueued) skip the insertion.
if (probability(NOT_FREQUENT_PROBABILITY, cardByte != g1YoungCardValue(INJECTED_VMCONFIG))) {
MembarNode.memoryBarrier(STORE_LOAD, GC_CARD_LOCATION);
byte cardByteReload = cardAddress.readByte(0, GC_CARD_LOCATION);
if (probability(NOT_FREQUENT_PROBABILITY, cardByteReload != dirtyCardValue(INJECTED_VMCONFIG))) {
cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION);
// initialize a new one and add the card entry.
if (indexValue != 0) {
indexValue = indexValue - wordSize();
Word logAddress = bufferAddress.add(WordFactory.unsigned(indexValue));
// Log the object to be scanned as well as update
// the card queue's next index.
logAddress.writeWord(0, cardAddress, GC_LOG_LOCATION);
indexAddress.writeWord(0, WordFactory.unsigned(indexValue), GC_INDEX_LOCATION);
} else {
g1PostBarrierStub(G1WBPOSTCALL, cardAddress);
}
}
}
}
}
Aggregations