Search in sources :

Example 11 with DynamicHub

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();
    }
}
Also used : HostedField(com.oracle.svm.hosted.meta.HostedField) DynamicHub(com.oracle.svm.core.hub.DynamicHub) BitSet(java.util.BitSet) JavaConstant(jdk.vm.ci.meta.JavaConstant) HostedClass(com.oracle.svm.hosted.meta.HostedClass) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 12 with DynamicHub

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;
}
Also used : MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) Constant(jdk.vm.ci.meta.Constant) SubstrateObjectConstant(com.oracle.svm.core.meta.SubstrateObjectConstant) JavaConstant(jdk.vm.ci.meta.JavaConstant) ArrayList(java.util.ArrayList) JavaConstant(jdk.vm.ci.meta.JavaConstant) MonitorExitNode(org.graalvm.compiler.nodes.java.MonitorExitNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) JavaType(jdk.vm.ci.meta.JavaType) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) MonitorEnterNode(org.graalvm.compiler.nodes.java.MonitorEnterNode) Signature(jdk.vm.ci.meta.Signature) ValueNode(org.graalvm.compiler.nodes.ValueNode) DynamicHub(com.oracle.svm.core.hub.DynamicHub)

Example 13 with DynamicHub

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());
    }
}
Also used : HashMap(java.util.HashMap) ObjectLayout(com.oracle.svm.core.config.ObjectLayout) CFunctionPointer(org.graalvm.nativeimage.c.function.CFunctionPointer) ReferenceMapEncoder(com.oracle.svm.core.heap.ReferenceMapEncoder) HybridLayout(com.oracle.svm.hosted.config.HybridLayout) DynamicHub(com.oracle.svm.core.hub.DynamicHub) DynamicHubSupport(com.oracle.svm.core.hub.DynamicHubSupport) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 14 with DynamicHub

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;
}
Also used : DynamicHub(com.oracle.svm.core.hub.DynamicHub) Snippet(org.graalvm.compiler.api.replacements.Snippet)

Example 15 with DynamicHub

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);
}
Also used : UnsafeAutomaticSubstitutionProcessor(com.oracle.svm.hosted.substitute.UnsafeAutomaticSubstitutionProcessor) DynamicHub(com.oracle.svm.core.hub.DynamicHub)

Aggregations

DynamicHub (com.oracle.svm.core.hub.DynamicHub)28 UnsignedWord (org.graalvm.word.UnsignedWord)11 AnalysisType (com.oracle.graal.pointsto.meta.AnalysisType)5 ObjectLayout (com.oracle.svm.core.config.ObjectLayout)4 JavaConstant (jdk.vm.ci.meta.JavaConstant)4 JavaKind (jdk.vm.ci.meta.JavaKind)4 SVMHost (com.oracle.svm.hosted.SVMHost)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 Snippet (org.graalvm.compiler.api.replacements.Snippet)3 Pointer (org.graalvm.word.Pointer)3 AnalysisField (com.oracle.graal.pointsto.meta.AnalysisField)2 SubstrateObjectConstant (com.oracle.svm.core.meta.SubstrateObjectConstant)2 SubstrateType (com.oracle.svm.graal.meta.SubstrateType)2 HostedField (com.oracle.svm.hosted.meta.HostedField)2 HostedType (com.oracle.svm.hosted.meta.HostedType)2 Arrays (java.util.Arrays)2 HashSet (java.util.HashSet)2 BigBang (com.oracle.graal.pointsto.BigBang)1 ObjectScanner (com.oracle.graal.pointsto.ObjectScanner)1