Search in sources :

Example 31 with JavaKind

use of jdk.vm.ci.meta.JavaKind in project graal by oracle.

the class CInterfaceInvocationPlugin method replaceBitfieldAccessor.

private boolean replaceBitfieldAccessor(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, StructBitfieldInfo bitfieldInfo, AccessorInfo accessorInfo) {
    int byteOffset = bitfieldInfo.getByteOffsetInfo().getProperty();
    int startBit = bitfieldInfo.getStartBitInfo().getProperty();
    int endBit = bitfieldInfo.getEndBitInfo().getProperty();
    boolean isUnsigned = bitfieldInfo.isUnsigned();
    assert byteOffset >= 0 && byteOffset < ((SizableInfo) bitfieldInfo.getParent()).getSizeInfo().getProperty();
    assert startBit >= 0 && startBit < 8;
    assert endBit >= startBit && endBit < 64;
    /*
         * The startBit is always in the first byte. Therefore, the endBit tells us how many bytes
         * we actually have to read and write.
         */
    JavaKind memoryKind;
    if (endBit < 8) {
        memoryKind = JavaKind.Byte;
    } else if (endBit < 16) {
        memoryKind = JavaKind.Short;
    } else if (endBit < 32) {
        memoryKind = JavaKind.Int;
    } else {
        memoryKind = JavaKind.Long;
    }
    int numBytes = memoryKind.getByteCount();
    /*
         * Try to align the byteOffset to be a multiple of numBytes. That should always be possible,
         * but we don't trust the C compiler and memory layout enough to make it an assertion.
         */
    int alignmentCorrection = byteOffset % numBytes;
    if (alignmentCorrection > 0 && endBit + alignmentCorrection * 8 < numBytes * 8) {
        byteOffset -= alignmentCorrection;
        startBit += alignmentCorrection * 8;
        endBit += alignmentCorrection * 8;
    }
    assert byteOffset >= 0 && byteOffset < ((SizableInfo) bitfieldInfo.getParent()).getSizeInfo().getProperty();
    assert startBit >= 0 && startBit < numBytes * 8;
    assert endBit >= startBit && endBit < numBytes * 8;
    int numBits = endBit - startBit + 1;
    assert numBits > 0 && numBits <= numBytes * 8;
    /*
         * The bit-operations on the value are either performed on Int or Long. We do not perform 8
         * or 16 bit arithmetic operations.
         */
    JavaKind computeKind = memoryKind.getStackKind();
    Stamp computeStamp = StampFactory.forKind(computeKind);
    int computeBits = computeKind.getBitCount();
    assert startBit >= 0 && startBit < computeBits;
    assert endBit >= startBit && endBit < computeBits;
    assert computeBits >= numBits;
    assert args.length == accessorInfo.parameterCount(true);
    ValueNode base = args[accessorInfo.baseParameterNumber(true)];
    StructuredGraph graph = b.getGraph();
    /*
         * Read the memory location. This is also necessary for writes, since we need to keep the
         * bits around the written bitfield unchanged.
         */
    ValueNode address = makeAddress(graph, args, accessorInfo, base, byteOffset, -1);
    LocationIdentity locationIdentity = makeLocationIdentity(b, method, args, accessorInfo);
    Stamp stamp = StampFactory.forInteger(memoryKind.getBitCount());
    ValueNode cur = readOp(b, address, locationIdentity, stamp, accessorInfo);
    cur = adaptPrimitiveType(graph, cur, memoryKind, computeKind, true);
    switch(accessorInfo.getAccessorKind()) {
        case GETTER:
            {
                if (isUnsigned) {
                    /*
                     * Unsigned reads: shift the bitfield to the right and mask out the unnecessary
                     * high-order bits.
                     */
                    cur = graph.unique(new RightShiftNode(cur, ConstantNode.forInt(startBit, graph)));
                    cur = graph.unique(new AndNode(cur, ConstantNode.forIntegerStamp(computeStamp, (1L << numBits) - 1, graph)));
                } else {
                    /*
                     * Signed reads: shift the bitfield to the right end to get the sign bit in
                     * place, then do a signed left shift to have a proper sign extension.
                     */
                    cur = graph.unique(new LeftShiftNode(cur, ConstantNode.forInt(computeBits - endBit - 1, graph)));
                    cur = graph.unique(new RightShiftNode(cur, ConstantNode.forInt(computeBits - numBits, graph)));
                }
                JavaKind resultKind = wordTypes.asKind(b.getInvokeReturnType());
                b.push(pushKind(method), adaptPrimitiveType(graph, cur, computeKind, resultKind == JavaKind.Boolean ? resultKind : resultKind.getStackKind(), isUnsigned));
                return true;
            }
        case SETTER:
            {
                /* Zero out the bits of our bitfields, i.e., the bits we are going to change. */
                long mask = ~(((1L << numBits) - 1) << startBit);
                cur = graph.unique(new AndNode(cur, ConstantNode.forIntegerStamp(computeStamp, mask, graph)));
                /*
                 * Mask the unnecessary high-order bits of the value to be written, and shift it to
                 * its place.
                 */
                ValueNode value = args[accessorInfo.valueParameterNumber(true)];
                value = adaptPrimitiveType(graph, value, value.getStackKind(), computeKind, isUnsigned);
                value = graph.unique(new AndNode(value, ConstantNode.forIntegerStamp(computeStamp, (1L << numBits) - 1, graph)));
                value = graph.unique(new LeftShiftNode(value, ConstantNode.forInt(startBit, graph)));
                /* Combine the leftover bits of the original memory word with the new value. */
                cur = graph.unique(new OrNode(cur, value));
                /* Narrow value to the number of bits we need to write. */
                cur = adaptPrimitiveType(graph, cur, computeKind, memoryKind, true);
                /* Perform the write (bitcount is taken from the stamp of the written value). */
                writeOp(b, address, locationIdentity, cur, accessorInfo);
                return true;
            }
        default:
            throw shouldNotReachHere();
    }
}
Also used : Stamp(org.graalvm.compiler.core.common.type.Stamp) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode) RightShiftNode(org.graalvm.compiler.nodes.calc.RightShiftNode) LocationIdentity(org.graalvm.word.LocationIdentity) CInterfaceLocationIdentity(com.oracle.svm.core.c.struct.CInterfaceLocationIdentity) AndNode(org.graalvm.compiler.nodes.calc.AndNode) LeftShiftNode(org.graalvm.compiler.nodes.calc.LeftShiftNode) JavaKind(jdk.vm.ci.meta.JavaKind) OrNode(org.graalvm.compiler.nodes.calc.OrNode)

Example 32 with JavaKind

use of jdk.vm.ci.meta.JavaKind in project graal by oracle.

the class CInterfaceInvocationPlugin method replaceConstant.

private boolean replaceConstant(GraphBuilderContext b, ResolvedJavaMethod method, ConstantInfo constantInfo) {
    Object value = constantInfo.getValueInfo().getProperty();
    JavaKind kind = wordTypes.asKind(b.getInvokeReturnType());
    ConstantNode valueNode;
    switch(constantInfo.getKind()) {
        case INTEGER:
        case POINTER:
            if (method.getSignature().getReturnKind() == JavaKind.Boolean) {
                valueNode = ConstantNode.forBoolean((long) value != 0, b.getGraph());
            } else {
                valueNode = ConstantNode.forIntegerKind(kind, (long) value, b.getGraph());
            }
            break;
        case FLOAT:
            valueNode = ConstantNode.forFloatingKind(kind, (double) value, b.getGraph());
            break;
        case STRING:
        case BYTEARRAY:
            valueNode = ConstantNode.forConstant(SubstrateObjectConstant.forObject(value), b.getMetaAccess(), b.getGraph());
            break;
        default:
            throw shouldNotReachHere("Unexpected constant kind " + constantInfo);
    }
    b.push(pushKind(method), valueNode);
    return true;
}
Also used : ConstantNode(org.graalvm.compiler.nodes.ConstantNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 33 with JavaKind

use of jdk.vm.ci.meta.JavaKind in project graal by oracle.

the class UniverseBuilder method makeType.

private HostedType makeType(AnalysisType aType) {
    if (aType == null) {
        return null;
    }
    HostedType hType = hUniverse.types.get(aType);
    if (hType != null) {
        return hType;
    }
    String typeName = aType.getName();
    assert !typeName.contains("/hotspot/") || typeName.contains("/jtt/hotspot/") : "HotSpot object in image " + typeName;
    assert !typeName.contains("/analysis/meta/") : "Analysis meta object in image " + typeName;
    assert !typeName.contains("/hosted/meta/") : "Hosted meta object in image " + typeName;
    AnalysisType[] aInterfaces = aType.getInterfaces();
    HostedInterface[] sInterfaces = new HostedInterface[aInterfaces.length];
    for (int i = 0; i < aInterfaces.length; i++) {
        sInterfaces[i] = (HostedInterface) makeType(aInterfaces[i]);
    }
    JavaKind kind = aType.getJavaKind();
    JavaKind storageKind = aType.getStorageKind();
    if (aType.getJavaKind() != JavaKind.Object) {
        assert !aType.isInterface() && !aType.isInstanceClass() && !aType.isArray();
        hType = new HostedPrimitiveType(hUniverse, aType, kind, storageKind);
        hUniverse.kindToType.put(hType.getJavaKind(), hType);
    } else if (aType.isInterface()) {
        assert !aType.isInstanceClass() && !aType.isArray();
        hType = new HostedInterface(hUniverse, aType, kind, storageKind, sInterfaces);
    } else if (aType.isInstanceClass()) {
        assert !aType.isInterface() && !aType.isArray();
        HostedInstanceClass superClass = (HostedInstanceClass) makeType(aType.getSuperclass());
        boolean isCloneable = aMetaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(aType);
        hType = new HostedInstanceClass(hUniverse, aType, kind, storageKind, superClass, sInterfaces, isCloneable);
        if (superClass == null) {
            hUniverse.kindToType.put(JavaKind.Object, hType);
        }
    } else if (aType.isArray()) {
        assert !aType.isInterface() && !aType.isInstanceClass();
        HostedClass superType = (HostedClass) makeType(aType.getSuperclass());
        HostedType componentType = makeType(aType.getComponentType());
        hType = new HostedArrayClass(hUniverse, aType, kind, storageKind, superType, sInterfaces, componentType);
        int dimension = hType.getArrayDimension();
        if (hType.getBaseType().getSuperclass() != null) {
            makeType(hType.getBaseType().getSuperclass().getArrayClass(dimension - 1).getWrapped().getArrayClass());
        }
        if (hType.getBaseType().isInterface()) {
            makeType(hUniverse.getObjectClass().getArrayClass(dimension - 1).getWrapped().getArrayClass());
        }
        for (HostedInterface interf : hType.getBaseType().getInterfaces()) {
            makeType(interf.getArrayClass(dimension - 1).getWrapped().getArrayClass());
        }
    } else {
        throw shouldNotReachHere();
    }
    hUniverse.types.put(aType, hType);
    /*
         * Set enclosing type lazily to avoid cyclic dependency between interfaces and enclosing
         * types. For example, in Scala an interface can extends its inner type.
         */
    if (aType.getEnclosingType() != null) {
        hType.setEnclosingType(makeType(aType.getEnclosingType()));
    }
    return hType;
}
Also used : AnalysisType(com.oracle.graal.pointsto.meta.AnalysisType) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 34 with JavaKind

use of jdk.vm.ci.meta.JavaKind in project graal by oracle.

the class AMD64HotSpotSafepointOp method emitGlobalPoll.

private static void emitGlobalPoll(CompilationResultBuilder crb, AMD64MacroAssembler asm, GraalHotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) {
    assert !atReturn || state == null : "state is unneeded at return";
    if (ImmutableCode.getValue(crb.getOptions())) {
        JavaKind hostWordKind = JavaKind.Long;
        int alignment = hostWordKind.getBitCount() / Byte.SIZE;
        JavaConstant pollingPageAddress = JavaConstant.forIntegerKind(hostWordKind, config.safepointPollingAddress);
        // co-located with the immutable code.
        if (GeneratePIC.getValue(crb.getOptions())) {
            asm.movq(scratch, asm.getPlaceholder(-1));
        } else {
            asm.movq(scratch, (AMD64Address) crb.recordDataReferenceInCode(pollingPageAddress, alignment));
        }
        final int pos = asm.position();
        crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
        if (state != null) {
            crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
        }
        asm.testl(rax, new AMD64Address(scratch));
    } else if (isPollingPageFar(config)) {
        asm.movq(scratch, config.safepointPollingAddress);
        crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_FAR : config.MARKID_POLL_FAR);
        final int pos = asm.position();
        if (state != null) {
            crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
        }
        asm.testl(rax, new AMD64Address(scratch));
    } else {
        crb.recordMark(atReturn ? config.MARKID_POLL_RETURN_NEAR : config.MARKID_POLL_NEAR);
        final int pos = asm.position();
        if (state != null) {
            crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT);
        }
        // The C++ code transforms the polling page offset into an RIP displacement
        // to the real address at that offset in the polling page.
        asm.testl(rax, new AMD64Address(rip, 0));
    }
}
Also used : JavaConstant(jdk.vm.ci.meta.JavaConstant) AMD64Address(org.graalvm.compiler.asm.amd64.AMD64Address) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 35 with JavaKind

use of jdk.vm.ci.meta.JavaKind in project graal by oracle.

the class PEReadEliminationClosure method processUnsafeStore.

private boolean processUnsafeStore(RawStoreNode store, PEReadEliminationBlockState state, GraphEffectList effects) {
    ResolvedJavaType type = StampTool.typeOrNull(store.object());
    if (type != null && type.isArray()) {
        JavaKind accessKind = store.accessKind();
        JavaKind componentKind = type.getComponentType().getJavaKind();
        LocationIdentity location = NamedLocationIdentity.getArrayLocation(componentKind);
        if (store.offset().isConstant()) {
            long offset = store.offset().asJavaConstant().asLong();
            boolean overflowAccess = isOverflowAccess(accessKind, componentKind);
            int index = overflowAccess ? -1 : VirtualArrayNode.entryIndexForOffset(tool.getArrayOffsetProvider(), offset, accessKind, type.getComponentType(), Integer.MAX_VALUE);
            return processStore(store, store.object(), location, index, accessKind, overflowAccess, store.value(), state, effects);
        } else {
            processIdentity(state, location);
        }
    } else {
        state.killReadCache();
    }
    return false;
}
Also used : LocationIdentity(org.graalvm.word.LocationIdentity) FieldLocationIdentity(org.graalvm.compiler.nodes.FieldLocationIdentity) NamedLocationIdentity(org.graalvm.compiler.nodes.NamedLocationIdentity) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) MemoryCheckpoint(org.graalvm.compiler.nodes.memory.MemoryCheckpoint) JavaKind(jdk.vm.ci.meta.JavaKind)

Aggregations

JavaKind (jdk.vm.ci.meta.JavaKind)90 ValueNode (org.graalvm.compiler.nodes.ValueNode)44 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)24 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)17 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)16 AddressNode (org.graalvm.compiler.nodes.memory.address.AddressNode)13 OffsetAddressNode (org.graalvm.compiler.nodes.memory.address.OffsetAddressNode)12 JavaType (jdk.vm.ci.meta.JavaType)11 Stamp (org.graalvm.compiler.core.common.type.Stamp)10 LocationIdentity (org.graalvm.word.LocationIdentity)10 ArrayList (java.util.ArrayList)9 JavaConstant (jdk.vm.ci.meta.JavaConstant)9 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)8 FrameState (org.graalvm.compiler.nodes.FrameState)8 GraphBuilderContext (org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext)8 Signature (jdk.vm.ci.meta.Signature)7 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)7 ObjectLayout (com.oracle.svm.core.config.ObjectLayout)6 ObjectStamp (org.graalvm.compiler.core.common.type.ObjectStamp)6 InvokeWithExceptionNode (org.graalvm.compiler.nodes.InvokeWithExceptionNode)6