use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class WriteBarrierSnippets method g1PostWriteBarrier.
@Snippet
public static void g1PostWriteBarrier(Address address, Object object, Object value, @ConstantParameter boolean usePrecise, @ConstantParameter Register threadRegister, @ConstantParameter boolean trace, @ConstantParameter Counters counters) {
Word thread = registerAsWord(threadRegister);
Object fixedValue = FixedValueAnchorNode.getObject(value);
verifyOop(object);
verifyOop(fixedValue);
validateObject(object, fixedValue);
Pointer oop;
if (usePrecise) {
oop = Word.fromAddress(address);
} else {
oop = Word.objectToTrackedPointer(object);
}
int gcCycle = 0;
if (trace) {
Pointer gcTotalCollectionsAddress = WordFactory.pointer(HotSpotReplacementsUtil.gcTotalCollectionsAddress(INJECTED_VMCONFIG));
gcCycle = (int) gcTotalCollectionsAddress.readLong(0);
log(trace, "[%d] G1-Post Thread: %p Object: %p\n", gcCycle, thread.rawValue(), Word.objectToTrackedPointer(object).rawValue());
log(trace, "[%d] G1-Post Thread: %p Field: %p\n", gcCycle, thread.rawValue(), oop.rawValue());
}
Pointer writtenValue = Word.objectToTrackedPointer(fixedValue);
// The result of the xor reveals whether the installed pointer crosses heap regions.
// In case it does the write barrier has to be issued.
final int logOfHeapRegionGrainBytes = GraalHotSpotVMConfigNode.logOfHeapRegionGrainBytes();
UnsignedWord xorResult = (oop.xor(writtenValue)).unsignedShiftRight(logOfHeapRegionGrainBytes);
// Calculate the address of the card to be enqueued to the
// thread local card queue.
UnsignedWord cardBase = oop.unsignedShiftRight(cardTableShift(INJECTED_VMCONFIG));
final long startAddress = GraalHotSpotVMConfigNode.cardTableAddress();
int displacement = 0;
if (((int) startAddress) == startAddress && GraalHotSpotVMConfigNode.isCardTableAddressConstant()) {
displacement = (int) startAddress;
} else {
cardBase = cardBase.add(WordFactory.unsigned(startAddress));
}
Word cardAddress = (Word) cardBase.add(displacement);
counters.g1AttemptedPostWriteBarrierCounter.inc();
if (probability(FREQUENT_PROBABILITY, xorResult.notEqual(0))) {
counters.g1EffectiveAfterXORPostWriteBarrierCounter.inc();
// If the written value is not null continue with the barrier addition.
if (probability(FREQUENT_PROBABILITY, writtenValue.notEqual(0))) {
byte cardByte = cardAddress.readByte(0, GC_CARD_LOCATION);
counters.g1EffectiveAfterNullPostWriteBarrierCounter.inc();
// 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))) {
log(trace, "[%d] G1-Post Thread: %p Card: %p \n", gcCycle, thread.rawValue(), WordFactory.unsigned((int) cardByte).rawValue());
cardAddress.writeByte(0, (byte) 0, GC_CARD_LOCATION);
counters.g1ExecutedPostWriteBarrierCounter.inc();
// If the thread local card queue is full, issue a native call which will
// initialize a new one and add the card entry.
Word indexAddress = thread.add(g1CardQueueIndexOffset(INJECTED_VMCONFIG));
Word indexValue = thread.readWord(g1CardQueueIndexOffset(INJECTED_VMCONFIG));
if (probability(FREQUENT_PROBABILITY, indexValue.notEqual(0))) {
Word bufferAddress = thread.readWord(g1CardQueueBufferOffset(INJECTED_VMCONFIG));
Word nextIndex = indexValue.subtract(wordSize());
Word logAddress = bufferAddress.add(nextIndex);
// 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, nextIndex, GC_INDEX_LOCATION);
} else {
g1PostBarrierStub(G1WBPOSTCALL, cardAddress);
}
}
}
}
}
}
use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class ExceptionHandlerStub method exceptionHandler.
@Snippet
private static void exceptionHandler(Object exception, Word exceptionPc, @ConstantParameter Register threadRegister, @ConstantParameter OptionValues options) {
Word thread = registerAsWord(threadRegister);
checkNoExceptionInThread(thread, assertionsEnabled(INJECTED_VMCONFIG));
checkExceptionNotNull(assertionsEnabled(INJECTED_VMCONFIG), exception);
writeExceptionOop(thread, exception);
writeExceptionPc(thread, exceptionPc);
if (logging(options)) {
printf("handling exception %p (", Word.objectToTrackedPointer(exception).rawValue());
decipher(Word.objectToTrackedPointer(exception).rawValue());
printf(") at %p (", exceptionPc.rawValue());
decipher(exceptionPc.rawValue());
printf(")\n");
}
// patch throwing pc into return address so that deoptimization finds the right debug info
patchReturnAddress(exceptionPc);
Word handlerPc = exceptionHandlerForPc(EXCEPTION_HANDLER_FOR_PC, thread);
if (logging(options)) {
printf("handler for exception %p at %p is at %p (", Word.objectToTrackedPointer(exception).rawValue(), exceptionPc.rawValue(), handlerPc.rawValue());
decipher(handlerPc.rawValue());
printf(")\n");
}
// patch the return address so that this stub returns to the exception handler
jumpToExceptionHandler(handlerPc);
}
use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class PosixAMD64VaListSnippets method vaArgDoubleSnippet.
@Snippet
protected static double vaArgDoubleSnippet(Pointer vaList) {
int fpOffset = vaList.readInt(FP_OFFSET_LOCATION);
if (fpOffset < MAX_FP_OFFSET) {
Pointer regSaveArea = vaList.readWord(REG_SAVE_AREA_LOCATION);
double v = regSaveArea.readDouble(fpOffset);
// 16-byte XMM register
vaList.writeInt(FP_OFFSET_LOCATION, fpOffset + 16);
return v;
} else {
Pointer overflowArgArea = vaList.readWord(OVERFLOW_ARG_AREA_LOCATION);
double v = overflowArgArea.readDouble(0);
vaList.writeWord(OVERFLOW_ARG_AREA_LOCATION, overflowArgArea.add(OVERFLOW_ARG_AREA_ALIGNMENT));
return v;
}
}
use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class PosixCEntryPointSnippets method enterIsolateSnippet.
@Snippet
public static int enterIsolateSnippet(Isolate isolate) {
int result;
if (MultiThreaded.getValue()) {
writeCurrentVMThread(VMThreads.nullThread());
result = runtimeCall(ENTER_ISOLATE_MT, isolate);
if (result == Errors.NO_ERROR) {
Safepoint.transitionNativeToJava();
}
} else {
result = PosixIsolates.checkSanity(isolate);
if (result == Errors.NO_ERROR && UseHeapBaseRegister.getValue()) {
setHeapBase(PosixIsolates.getHeapBase(isolate));
}
}
return result;
}
use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class PosixCEntryPointSnippets method enterSnippet.
@Snippet
public static int enterSnippet(IsolateThread thread) {
Isolate isolate;
if (MultiThreaded.getValue()) {
if (thread.isNull()) {
return Errors.NULL_ARGUMENT;
}
writeCurrentVMThread(thread);
isolate = PosixVMThreads.IsolateTL.get(thread);
} else {
// single-threaded
if (SpawnIsolates.getValue()) {
if (thread.isNull()) {
return Errors.NULL_ARGUMENT;
}
} else if (!thread.equal(CEntryPointSetup.SINGLE_THREAD_SENTINEL)) {
return Errors.UNATTACHED_THREAD;
}
isolate = (Isolate) ((Word) thread).subtract(CEntryPointSetup.SINGLE_ISOLATE_TO_SINGLE_THREAD_ADDEND);
}
if (UseHeapBaseRegister.getValue()) {
setHeapBase(PosixIsolates.getHeapBase(isolate));
}
if (MultiThreaded.getValue()) {
Safepoint.transitionNativeToJava();
}
return Errors.NO_ERROR;
}
Aggregations