use of com.oracle.svm.core.hub.DynamicHub in project graal by oracle.
the class NativeImageHeap method writeObject.
private void writeObject(ObjectInfo info, final RelocatableBuffer roBuffer, final RelocatableBuffer rwBuffer) {
/*
* Write a reference from the object to its hub. This lives at layout.getHubOffset() from
* the object base.
*/
final RelocatableBuffer buffer = bufferForPartition(info, roBuffer, rwBuffer);
final int indexInSection = info.getIntIndexInSection(layout.getHubOffset());
assert layout.isReferenceAligned(info.getOffsetInPartition());
assert layout.isReferenceAligned(indexInSection);
final HostedClass clazz = info.getClazz();
final DynamicHub hub = clazz.getHub();
final long objectHeaderBits = Heap.getHeap().getObjectHeader().setBootImageOnLong(0L);
writeDynamicHub(buffer, indexInSection, hub, objectHeaderBits);
if (clazz.isInstanceClass()) {
JavaConstant con = SubstrateObjectConstant.forObject(info.getObject());
HybridLayout<?> hybridLayout = hybridLayouts.get(clazz);
HostedField hybridArrayField = null;
HostedField hybridBitsetField = null;
int maxBitIndex = -1;
Object hybridArray = null;
if (hybridLayout != null) {
hybridArrayField = hybridLayout.getArrayField();
hybridArray = SubstrateObjectConstant.asObject(hybridArrayField.readStorageValue(con));
hybridBitsetField = hybridLayout.getBitsetField();
if (hybridBitsetField != null) {
BitSet bitSet = (BitSet) SubstrateObjectConstant.asObject(hybridBitsetField.readStorageValue(con));
if (bitSet != null) {
/*
* Write the bits of the hybrid bit field. The bits are located between the
* array length and the instance fields.
*/
int bitsPerByte = Byte.SIZE;
for (int bit = bitSet.nextSetBit(0); bit >= 0; bit = bitSet.nextSetBit(bit + 1)) {
final int index = info.getIntIndexInSection(hybridLayout.getBitFieldOffset()) + bit / bitsPerByte;
if (index > maxBitIndex) {
maxBitIndex = index;
}
int mask = 1 << (bit % bitsPerByte);
assert mask < (1 << bitsPerByte);
buffer.putByte(index, (byte) (buffer.getByte(index) | mask));
}
}
}
}
/*
* Write the regular instance fields.
*/
for (HostedField field : clazz.getInstanceFields(true)) {
if (!field.equals(hybridArrayField) && !field.equals(hybridBitsetField) && field.isAccessed()) {
assert field.getLocation() >= 0;
assert info.getIntIndexInSection(field.getLocation()) > maxBitIndex;
writeField(buffer, info, field, con, info);
}
}
if (hub.getHashCodeOffset() != 0) {
buffer.putInt(info.getIntIndexInSection(hub.getHashCodeOffset()), info.getIdentityHashCode());
}
if (hybridArray != null) {
/*
* Write the hybrid array length and the array elements.
*/
int length = Array.getLength(hybridArray);
buffer.putInt(info.getIntIndexInSection(layout.getArrayLengthOffset()), length);
for (int i = 0; i < length; i++) {
final int elementIndex = info.getIntIndexInSection(hybridLayout.getArrayElementOffset(i));
final JavaKind elementKind = hybridLayout.getArrayElementKind();
final Object array = Array.get(hybridArray, i);
writeConstant(buffer, elementIndex, elementKind, array, info);
}
}
} else if (clazz.isArray()) {
JavaKind kind = clazz.getComponentType().getJavaKind();
Object array = info.getObject();
int length = Array.getLength(array);
buffer.putInt(info.getIntIndexInSection(layout.getArrayLengthOffset()), length);
buffer.putInt(info.getIntIndexInSection(layout.getArrayHashCodeOffset()), info.getIdentityHashCode());
if (array instanceof Object[]) {
Object[] oarray = (Object[]) array;
assert oarray.length == length;
for (int i = 0; i < length; i++) {
final int elementIndex = info.getIntIndexInSection(layout.getArrayElementOffset(kind, i));
final Object element = aUniverse.replaceObject(oarray[i]);
writeConstant(buffer, elementIndex, kind, element, info);
}
} else {
for (int i = 0; i < length; i++) {
final int elementIndex = info.getIntIndexInSection(layout.getArrayElementOffset(kind, i));
final Object element = Array.get(array, i);
writeConstant(buffer, elementIndex, kind, element, info);
}
}
} else {
throw shouldNotReachHere();
}
}
use of com.oracle.svm.core.hub.DynamicHub in project graal by oracle.
the class JNINativeCallWrapperMethod method buildGraph.
@Override
public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) {
JNIGraphKit kit = new JNIGraphKit(debug, providers, method);
StructuredGraph graph = kit.getGraph();
InvokeWithExceptionNode handleFrame = kit.nativeCallPrologue();
ValueNode callAddress = kit.nativeCallAddress(kit.createObject(linkage));
ValueNode environment = kit.environment();
JavaType javaReturnType = method.getSignature().getReturnType(null);
JavaType[] javaArgumentTypes = method.toParameterTypes();
List<ValueNode> javaArguments = kit.loadArguments(javaArgumentTypes);
List<ValueNode> jniArguments = new ArrayList<>(2 + javaArguments.size());
List<JavaType> jniArgumentTypes = new ArrayList<>(jniArguments.size());
JavaType environmentType = providers.getMetaAccess().lookupJavaType(JNIEnvironment.class);
JavaType objectHandleType = providers.getMetaAccess().lookupJavaType(JNIObjectHandle.class);
jniArguments.add(environment);
jniArgumentTypes.add(environmentType);
if (method.isStatic()) {
JavaConstant clazz = providers.getConstantReflection().asJavaClass(method.getDeclaringClass());
ConstantNode clazzNode = ConstantNode.forConstant(clazz, providers.getMetaAccess(), graph);
ValueNode box = kit.boxObjectInLocalHandle(clazzNode);
jniArguments.add(box);
jniArgumentTypes.add(objectHandleType);
}
for (int i = 0; i < javaArguments.size(); i++) {
ValueNode arg = javaArguments.get(i);
JavaType argType = javaArgumentTypes[i];
if (javaArgumentTypes[i].getJavaKind().isObject()) {
ValueNode obj = javaArguments.get(i);
arg = kit.boxObjectInLocalHandle(obj);
argType = objectHandleType;
}
jniArguments.add(arg);
jniArgumentTypes.add(argType);
}
assert jniArguments.size() == jniArgumentTypes.size();
JavaType jniReturnType = javaReturnType;
if (jniReturnType.getJavaKind().isObject()) {
jniReturnType = objectHandleType;
}
if (getOriginal().isSynchronized()) {
ValueNode monitorObject;
if (method.isStatic()) {
Constant hubConstant = providers.getConstantReflection().asObjectHub(method.getDeclaringClass());
DynamicHub hub = (DynamicHub) SubstrateObjectConstant.asObject(hubConstant);
monitorObject = ConstantNode.forConstant(SubstrateObjectConstant.forObject(hub), providers.getMetaAccess(), graph);
} else {
monitorObject = javaArguments.get(0);
}
MonitorIdNode monitorId = graph.add(new MonitorIdNode(kit.getFrameState().lockDepth(false)));
MonitorEnterNode monitorEnter = kit.append(new MonitorEnterNode(monitorObject, monitorId));
kit.getFrameState().pushLock(monitorEnter.object(), monitorEnter.getMonitorId());
monitorEnter.setStateAfter(kit.getFrameState().create(kit.bci(), monitorEnter));
}
kit.getFrameState().clearLocals();
Signature jniSignature = new JNISignature(jniArgumentTypes, jniReturnType);
ValueNode returnValue = kit.createCFunctionCall(callAddress, method, jniArguments, jniSignature, true, false);
if (getOriginal().isSynchronized()) {
MonitorIdNode monitorId = kit.getFrameState().peekMonitorId();
ValueNode monitorObject = kit.getFrameState().popLock();
MonitorExitNode monitorExit = kit.append(new MonitorExitNode(monitorObject, monitorId, null));
monitorExit.setStateAfter(kit.getFrameState().create(kit.bci(), monitorExit));
}
if (javaReturnType.getJavaKind().isObject()) {
// before destroying handles in epilogue
returnValue = kit.unboxHandle(returnValue);
}
kit.nativeCallEpilogue(handleFrame);
kit.rethrowPendingException();
if (javaReturnType.getJavaKind().isObject()) {
// Just before return to always run the epilogue and never suppress a pending exception
returnValue = castObject(kit, returnValue, (ResolvedJavaType) javaReturnType);
}
kit.createReturn(returnValue, javaReturnType.getJavaKind());
kit.mergeUnwinds();
assert graph.verify();
return graph;
}
use of com.oracle.svm.core.hub.DynamicHub 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.hub.DynamicHub in project graal by oracle.
the class TypeSnippets method instanceOfDynamicSnippet.
@Snippet
protected static Any instanceOfDynamicSnippet(DynamicHub type, Object object, Any trueValue, Any falseValue, @ConstantParameter boolean allowsNull) {
if (object == null) {
return allowsNull ? trueValue : falseValue;
}
Object objectNonNull = PiNode.piCastNonNull(object, SnippetAnchorNode.anchor());
/*
* We could use instanceOfMatches here instead of assignableFromMatches, but currently we do
* not preserve these at run time to keep the native image heap small.
*/
int[] matches = type.getAssignableFromMatches();
DynamicHub objectHub = loadHub(objectNonNull);
int le = DynamicHub.fromClass(matches.getClass()).getLayoutEncoding();
for (int i = 0; i < matches.length; i += 2) {
/*
* We cannot use regular array accesses like match[i] because we need to provide a
* custom LocationIdentity for the read.
*/
int matchTypeID = ObjectAccess.readInt(matches, LayoutEncoding.getArrayElementOffset(le, i), NamedLocationIdentity.FINAL_LOCATION);
int matchLength = ObjectAccess.readInt(matches, LayoutEncoding.getArrayElementOffset(le, i + 1), NamedLocationIdentity.FINAL_LOCATION);
if (UnsignedMath.belowThan(objectHub.getTypeID() - matchTypeID, matchLength)) {
return trueValue;
}
}
return falseValue;
}
use of com.oracle.svm.core.hub.DynamicHub in project graal by oracle.
the class SVMHost method registerType.
@Override
public void registerType(AnalysisType analysisType, ResolvedJavaType hostType) {
DynamicHub hub = createHub(analysisType);
Object existing = typeToHub.put(analysisType, hub);
assert existing == null;
existing = hubToType.put(hub, analysisType);
assert existing == null;
/* Compute the automatic substitutions. */
UnsafeAutomaticSubstitutionProcessor automaticSubstitutions = ImageSingletons.lookup(UnsafeAutomaticSubstitutionProcessor.class);
automaticSubstitutions.computeSubstitutions(hostType, options);
}
Aggregations