use of com.oracle.svm.core.heap.ReferenceMapEncoder in project graal by oracle.
the class CollectingObjectReferenceVisitor method encodeReferenceMaps.
private void encodeReferenceMaps() {
ReferenceMapEncoder referenceMapEncoder = new ReferenceMapEncoder();
for (IPData data : entries.values()) {
referenceMapEncoder.add(data.referenceMap);
}
referenceMapEncoding = referenceMapEncoder.encodeAll(allocator);
for (IPData data : entries.values()) {
data.referenceMapIndex = referenceMapEncoder.lookupEncoding(data.referenceMap);
}
}
use of com.oracle.svm.core.heap.ReferenceMapEncoder in project graal by oracle.
the class VMThreadMTFeature method beforeCompilation.
@Override
public void beforeCompilation(BeforeCompilationAccess config) {
List<VMThreadLocalInfo> sortedThreadLocalInfos = threadLocalCollector.sortThreadLocals(config, threadLocalAtOffsetZero);
SubstrateReferenceMap referenceMap = new SubstrateReferenceMap();
int nextOffset = 0;
for (VMThreadLocalInfo info : sortedThreadLocalInfos) {
assert nextOffset % Math.min(8, info.sizeInBytes) == 0 : "alignment mismatch: " + info.sizeInBytes + ", " + nextOffset;
if (info.isObject) {
final boolean isCompressed = false;
referenceMap.markReferenceAtIndex(nextOffset / info.sizeInBytes, isCompressed);
}
info.offset = nextOffset;
nextOffset += info.sizeInBytes;
}
VMError.guarantee(threadLocalAtOffsetZero == null || threadLocalCollector.getInfo(threadLocalAtOffsetZero).offset == 0);
ReferenceMapEncoder encoder = new ReferenceMapEncoder();
encoder.add(referenceMap);
objectReferenceWalker.vmThreadReferenceMapEncoding = encoder.encodeAll(null);
objectReferenceWalker.vmThreadReferenceMapIndex = encoder.lookupEncoding(referenceMap);
objectReferenceWalker.vmThreadSize = nextOffset;
/* Remember the final sorted list. */
VMThreadLocalInfos.setInfos(sortedThreadLocalInfos);
}
use of com.oracle.svm.core.heap.ReferenceMapEncoder in project graal by oracle.
the class UniverseBuilder method buildHubs.
private void buildHubs() {
ReferenceMapEncoder referenceMapEncoder = new ReferenceMapEncoder();
Map<HostedType, ReferenceMapEncoder.Input> referenceMaps = new HashMap<>();
for (HostedType type : hUniverse.orderedTypes) {
ReferenceMapEncoder.Input referenceMap = createReferenceMap(type);
referenceMaps.put(type, referenceMap);
referenceMapEncoder.add(referenceMap);
}
ImageSingletons.lookup(DynamicHubSupport.class).setData(referenceMapEncoder.encodeAll(null));
ObjectLayout ol = ConfigurationValues.getObjectLayout();
for (HostedType type : hUniverse.orderedTypes) {
int layoutHelper;
int monitorOffset = 0;
int hashCodeOffset = 0;
if (type.isInstanceClass()) {
HostedInstanceClass instanceClass = (HostedInstanceClass) type;
if (instanceClass.isAbstract()) {
layoutHelper = LayoutEncoding.forAbstract();
} else if (HybridLayout.isHybrid(type)) {
HybridLayout<?> hybridLayout = new HybridLayout<>(instanceClass, ol);
JavaKind kind = hybridLayout.getArrayElementKind();
layoutHelper = LayoutEncoding.forArray(kind == JavaKind.Object, hybridLayout.getArrayBaseOffset(), ol.getArrayIndexShift(kind), ol.getAlignment());
} else {
layoutHelper = LayoutEncoding.forInstance(ConfigurationValues.getObjectLayout().alignUp(instanceClass.getInstanceSize()));
}
monitorOffset = instanceClass.getMonitorFieldOffset();
hashCodeOffset = instanceClass.getHashCodeFieldOffset();
} else if (type.isArray()) {
JavaKind kind = type.getComponentType().getStorageKind();
layoutHelper = LayoutEncoding.forArray(kind == JavaKind.Object, ol.getArrayBaseOffset(kind), ol.getArrayIndexShift(kind), ol.getAlignment());
hashCodeOffset = ol.getArrayHashCodeOffset();
} else if (type.isInterface()) {
layoutHelper = LayoutEncoding.forInterface();
} else if (type.isPrimitive()) {
layoutHelper = LayoutEncoding.forPrimitive();
} else {
throw shouldNotReachHere();
}
/*
* The vtable entry values are available only after the code cache layout is fixed, so
* leave them 0.
*/
CFunctionPointer[] vtable = new CFunctionPointer[type.vtable.length];
for (int idx = 0; idx < type.vtable.length; idx++) {
/*
* We install a CodePointer in the vtable; when generating relocation info, we will
* know these point into .text
*/
vtable[idx] = MethodPointer.factory(type.vtable[idx]);
}
// pointer maps in Dynamic Hub
ReferenceMapEncoder.Input referenceMap = referenceMaps.get(type);
assert referenceMap != null;
long referenceMapIndex = referenceMapEncoder.lookupEncoding(referenceMap);
DynamicHub hub = type.getHub();
hub.setData(layoutHelper, type.getTypeID(), monitorOffset, hashCodeOffset, type.getAssignableFromMatches(), type.instanceOfBits, vtable, referenceMapIndex, type.isInstantiated());
}
}
use of com.oracle.svm.core.heap.ReferenceMapEncoder in project graal by oracle.
the class InstalledCodeBuilder method installOperation.
@SuppressWarnings("try")
private void installOperation() {
AMD64InstructionPatcher patcher = new AMD64InstructionPatcher(compilation);
patchData(patcher);
int updatedCodeSize = patchCalls(patcher);
assert updatedCodeSize <= constantsOffset;
// Store the compiled code
for (int index = 0; index < updatedCodeSize; index++) {
code.writeByte(index, compiledBytes[index]);
}
/* Primitive constants are written directly to the code memory. */
ByteBuffer constantsBuffer = SubstrateUtil.wrapAsByteBuffer(code.add(constantsOffset), compilation.getDataSection().getSectionSize());
/*
* Object constants are stored in an Object[] array first, because we have to be careful
* that they are always exposed as roots to the GC.
*/
ObjectConstantsHolder objectConstants = new ObjectConstantsHolder(compilation);
compilation.getDataSection().buildDataSection(constantsBuffer, (position, constant) -> {
objectConstants.add(position, KnownIntrinsics.convertUnknownValue(SubstrateObjectConstant.asObject(constant), Object.class));
});
// Open the PinnedAllocator for the meta-information.
metaInfoAllocator.open();
try {
runtimeMethodInfo = metaInfoAllocator.newInstance(RuntimeMethodInfo.class);
constantsWalker = metaInfoAllocator.newInstance(ConstantsWalker.class);
ReferenceMapEncoder encoder = new ReferenceMapEncoder();
encoder.add(objectConstants.referenceMap);
constantsWalker.referenceMapEncoding = encoder.encodeAll(metaInfoAllocator);
constantsWalker.referenceMapIndex = encoder.lookupEncoding(objectConstants.referenceMap);
constantsWalker.constantsAddr = code.add(constantsOffset);
constantsWalker.constantsSize = compilation.getDataSection().getSectionSize();
Heap.getHeap().getGC().registerObjectReferenceWalker(constantsWalker);
/*
* We now have the constantsWalker initialized and registered, but it is still inactive.
* Writing the actual object constants to the code memory needs to be atomic regarding
* to GC. After everything is written, we activate the constantsWalker.
*/
try (NoAllocationVerifier verifier = NoAllocationVerifier.factory("InstalledCodeBuilder.install")) {
writeObjectConstantsToCode(objectConstants);
}
createCodeChunkInfos();
InstalledCodeObserver.InstalledCodeObserverHandle[] observerHandles = InstalledCodeObserverSupport.installObservers(codeObservers, metaInfoAllocator);
runtimeMethodInfo.setData((CodePointer) code, WordFactory.unsigned(codeSize), installedCode, constantsWalker, metaInfoAllocator, observerHandles);
} finally {
metaInfoAllocator.close();
}
Throwable[] errorBox = { null };
VMOperation.enqueueBlockingSafepoint("Install code", () -> {
try {
CodeInfoTable.getRuntimeCodeCache().addMethod(runtimeMethodInfo);
/*
* This call makes the new code visible, i.e., other threads can start executing it
* immediately. So all metadata must be registered at this point.
*/
installedCode.setAddress(code.rawValue(), method);
} catch (Throwable e) {
errorBox[0] = e;
}
});
if (errorBox[0] != null) {
throw rethrow(errorBox[0]);
}
compilation = null;
}
Aggregations