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();
}
}
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;
}
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;
}
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));
}
}
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;
}
Aggregations