# HG changeset patch # User Roland Schatz # Date 1396965318 -7200 # Node ID 652564fe42d55f88de5a62d397d9844febe85256 # Parent bceb077143aef94128c4470afe553d4558511196 Use CompressionNode for accessing compressed Klass pointers. diff -r bceb077143ae -r 652564fe42d5 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java Tue Apr 08 15:44:41 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java Tue Apr 08 15:55:18 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,11 +59,21 @@ * * @param base the base address from which the value is read. * @param displacement the displacement within the object in bytes - * @param compressible whether this is a read of a compressed or an uncompressed pointer * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the * value cannot be read. */ - Constant readUnsafeConstant(Kind kind, Constant base, long displacement, boolean compressible); + Constant readUnsafeConstant(Kind kind, Constant base, long displacement); + + /** + * Reads a primitive value using a base address and a displacement. + * + * @param kind the {@link Kind} of the returned {@link Constant} object + * @param base the base address from which the value is read + * @param displacement the displacement within the object in bytes + * @param bits the number of bits to read from memory + * @return the read value encapsulated in a {@link Constant} object of {@link Kind} kind + */ + Constant readRawConstant(Kind kind, Constant base, long displacement, int bits); /** * Converts the given {@link Kind#isPrimitive() primitive} constant to a boxed diff -r bceb077143ae -r 652564fe42d5 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Apr 08 15:44:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Apr 08 15:55:18 2014 +0200 @@ -455,16 +455,40 @@ @Override public Value emitCompress(Value pointer, CompressEncoding encoding) { - Variable result = newVariable(NarrowOopStamp.NarrowOop); - append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding)); - return result; + if (pointer.getPlatformKind() == Kind.Object) { + Variable result = newVariable(NarrowOopStamp.NarrowOop); + append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding)); + return result; + } else { + assert pointer.getPlatformKind() == Kind.Long; + Variable result = newVariable(Kind.Int); + AllocatableValue base = Value.ILLEGAL; + if (encoding.base != 0) { + base = newVariable(Kind.Long); + append(new AMD64Move.MoveToRegOp(Kind.Long, base, Constant.forLong(encoding.base))); + } + append(new AMD64HotSpotMove.CompressPointer(result, asAllocatable(pointer), base, encoding)); + return result; + } } @Override public Value emitUncompress(Value pointer, CompressEncoding encoding) { - Variable result = newVariable(Kind.Object); - append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding)); - return result; + if (pointer.getPlatformKind() == NarrowOopStamp.NarrowOop) { + Variable result = newVariable(Kind.Object); + append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding)); + return result; + } else { + assert pointer.getPlatformKind() == Kind.Int; + Variable result = newVariable(Kind.Long); + AllocatableValue base = Value.ILLEGAL; + if (encoding.base != 0) { + base = newVariable(Kind.Long); + append(new AMD64Move.MoveToRegOp(Kind.Long, base, Constant.forLong(encoding.base))); + } + append(new AMD64HotSpotMove.UncompressPointer(result, asAllocatable(pointer), base, encoding)); + return result; + } } @Override diff -r bceb077143ae -r 652564fe42d5 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Tue Apr 08 15:44:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Tue Apr 08 15:55:18 2014 +0200 @@ -35,7 +35,6 @@ import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.hotspot.data.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; @@ -82,7 +81,7 @@ @Def({REG, HINT}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; - @Temp({REG, ILLEGAL}) protected AllocatableValue baseRegister; + @Use({REG, ILLEGAL}) protected AllocatableValue baseRegister; public CompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding) { this.result = result; @@ -93,12 +92,9 @@ @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - if (result.getPlatformKind() == NarrowOopStamp.NarrowOop) { - AMD64Move.move(Kind.Long, crb, masm, result, input); - encodePointer(masm, asRegister(result), asRegister(baseRegister), encoding); - } else { - throw GraalInternalError.unimplemented(); - } + AMD64Move.move(Kind.Long, crb, masm, result, input); + Register base = encoding.base != 0 ? asRegister(baseRegister) : null; + encodePointer(masm, asRegister(result), base, encoding); } } @@ -108,7 +104,7 @@ @Def({REG, HINT}) protected AllocatableValue result; @Use({REG}) protected AllocatableValue input; - @Temp({REG, ILLEGAL}) protected AllocatableValue baseRegister; + @Use({REG, ILLEGAL}) protected AllocatableValue baseRegister; public UncompressPointer(AllocatableValue result, AllocatableValue input, AllocatableValue baseRegister, CompressEncoding encoding) { this.result = result; @@ -119,12 +115,9 @@ @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - if (result.getKind() == Kind.Object) { - AMD64Move.move(Kind.Int, crb, masm, result, input); - decodePointer(masm, asRegister(result), asRegister(baseRegister), encoding); - } else { - throw GraalInternalError.unimplemented(); - } + AMD64Move.move(Kind.Int, crb, masm, result, input); + Register base = encoding.base != 0 ? asRegister(baseRegister) : null; + decodePointer(masm, asRegister(result), base, encoding); } } diff -r bceb077143ae -r 652564fe42d5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Apr 08 15:44:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Apr 08 15:55:18 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1499,6 +1499,22 @@ this.alignment = alignment; } + public int compress(long ptr) { + if (ptr == 0L) { + return 0; + } else { + return (int) ((ptr - base) >>> shift); + } + } + + public long uncompress(int ptr) { + if (ptr == 0) { + return 0L; + } else { + return (ptr & 0xFFFFFFFFL) << shift + base; + } + } + @Override public String toString() { return "base: " + base + " shift: " + shift + " alignment: " + alignment; diff -r bceb077143ae -r 652564fe42d5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Tue Apr 08 15:44:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Tue Apr 08 15:55:18 2014 +0200 @@ -56,7 +56,7 @@ } @Override - public Constant readUnsafeConstant(Kind kind, Constant baseConstant, long initialDisplacement, boolean compressible) { + public Constant readUnsafeConstant(Kind kind, Constant baseConstant, long initialDisplacement) { Object base; long displacement; if (baseConstant.getKind() == Kind.Object) { @@ -103,7 +103,7 @@ return Constant.forDouble(base == null ? unsafe.getDouble(displacement) : unsafe.getDouble(base, displacement)); case Object: { Object o = null; - if (compressible) { + if (baseConstant.getKind() == Kind.Object) { o = unsafe.getObject(base, displacement); } else { o = runtime.getCompilerToVM().readUnsafeUncompressedPointer(base, displacement); @@ -116,6 +116,71 @@ } @Override + public Constant readRawConstant(Kind kind, Constant baseConstant, long initialDisplacement, int bits) { + Object base; + long displacement; + if (baseConstant.getKind() == Kind.Object) { + base = HotSpotObjectConstant.asObject(baseConstant); + displacement = initialDisplacement; + if (base == null) { + return null; + } + } else if (baseConstant.getKind().isNumericInteger()) { + long baseLong = baseConstant.asLong(); + if (baseLong == 0L) { + return null; + } + displacement = initialDisplacement + baseLong; + base = null; + } else { + throw GraalInternalError.shouldNotReachHere(); + } + + long rawValue; + switch (bits) { + case 8: + rawValue = base == null ? unsafe.getByte(displacement) : unsafe.getByte(base, displacement); + break; + case 16: + rawValue = base == null ? unsafe.getShort(displacement) : unsafe.getShort(base, displacement); + break; + case 32: + rawValue = base == null ? unsafe.getInt(displacement) : unsafe.getInt(base, displacement); + break; + case 64: + rawValue = base == null ? unsafe.getLong(displacement) : unsafe.getLong(base, displacement); + break; + default: + throw GraalInternalError.shouldNotReachHere(); + } + + if (base != null && displacement == config().hubOffset) { + if (config().useCompressedClassPointers) { + assert bits == 32 && kind == Kind.Int; + long klassPointer = config().getKlassEncoding().uncompress((int) rawValue); + assert klassPointer == runtime.getCompilerToVM().readUnsafeKlassPointer(base); + return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(klassPointer)); + } else { + assert bits == 64 && kind == Kind.Long; + return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(rawValue)); + } + } else { + switch (kind) { + case Int: + return Constant.forInt((int) rawValue); + case Long: + return Constant.forLong(rawValue); + case Float: + return Constant.forFloat(Float.intBitsToFloat((int) rawValue)); + case Double: + return Constant.forDouble(Double.longBitsToDouble(rawValue)); + default: + throw GraalInternalError.shouldNotReachHere(); + } + } + } + + @Override public Constant readArrayElement(Constant array, int index) { if (array.getKind() != Kind.Object || array.isNull()) { return null; diff -r bceb077143ae -r 652564fe42d5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Tue Apr 08 15:44:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Tue Apr 08 15:55:18 2014 +0200 @@ -234,7 +234,7 @@ int vtableEntryOffset = hsMethod.vtableEntryOffset(); assert vtableEntryOffset > 0; Kind wordKind = runtime.getTarget().wordKind; - FloatingReadNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck); + ValueNode hub = createReadHub(graph, wordKind, receiver, receiverNullCheck); ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod); // We use LocationNode.ANY_LOCATION for the reads that access the @@ -418,7 +418,7 @@ } } else { Kind wordKind = runtime.getTarget().wordKind; - FloatingReadNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck); + ValueNode arrayClass = createReadHub(graph, wordKind, array, boundsCheck); LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, runtime.getConfig().arrayClassElementOffset, graph); /* * Anchor the read of the element klass to the cfg, because it is only valid when @@ -524,7 +524,7 @@ assert loadHub.getKind() == wordKind; ValueNode object = loadHub.object(); GuardingNode guard = loadHub.getGuard(); - FloatingReadNode hub = createReadHub(graph, wordKind, object, guard); + ValueNode hub = createReadHub(graph, wordKind, object, guard); graph.replaceFloating(loadHub, hub); } } @@ -795,18 +795,37 @@ return metaspaceMethod; } - private FloatingReadNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) { + private ValueNode createReadHub(StructuredGraph graph, Kind wordKind, ValueNode object, GuardingNode guard) { HotSpotVMConfig config = runtime.getConfig(); LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, config.hubOffset, graph); assert !object.isConstant() || object.asConstant().isNull(); - return graph.unique(new FloatingReadNode(object, location, null, StampFactory.forKind(wordKind), guard, BarrierType.NONE, config.useCompressedClassPointers)); + + Stamp hubStamp; + if (config.useCompressedClassPointers) { + hubStamp = StampFactory.forInteger(32, false); + } else { + hubStamp = StampFactory.forKind(wordKind); + } + + FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(object, location, null, hubStamp, guard, BarrierType.NONE, false)); + if (config.useCompressedClassPointers) { + return CompressionNode.uncompress(memoryRead, config.getKlassEncoding()); + } else { + return memoryRead; + } } private WriteNode createWriteHub(StructuredGraph graph, Kind wordKind, ValueNode object, ValueNode value) { HotSpotVMConfig config = runtime.getConfig(); LocationNode location = ConstantLocationNode.create(HUB_LOCATION, wordKind, config.hubOffset, graph); assert !object.isConstant() || object.asConstant().isNull(); - return graph.add(new WriteNode(object, value, location, BarrierType.NONE, config.useCompressedClassPointers)); + + ValueNode writeValue = value; + if (config.useCompressedClassPointers) { + writeValue = CompressionNode.compress(value, config.getKlassEncoding()); + } + + return graph.add(new WriteNode(object, writeValue, location, BarrierType.NONE, false)); } private static BarrierType getFieldLoadBarrierType(HotSpotResolvedJavaField loadField) { diff -r bceb077143ae -r 652564fe42d5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Apr 08 15:44:41 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Apr 08 15:55:18 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -244,7 +244,7 @@ /** * Determines if a given object contains this field. - * + * * @return true iff this is a non-static field and its declaring class is assignable from * {@code object}'s class */ @@ -260,13 +260,13 @@ if (receiver == null) { assert isStatic(modifiers); if (holder.isInitialized()) { - return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), HotSpotObjectConstant.forObject(holder.mirror()), offset, getKind() == Kind.Object); + return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), HotSpotObjectConstant.forObject(holder.mirror()), offset); } return null; } else { assert !isStatic(modifiers); assert receiver.isNonNull() && isInObject(HotSpotObjectConstant.asObject(receiver)); - return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver, offset, getKind() == Kind.Object); + return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver, offset); } } @@ -331,7 +331,7 @@ /** * Checks if this field has the {@link Stable} annotation. - * + * * @return true if field has {@link Stable} annotation, false otherwise */ public boolean isStable() { diff -r bceb077143ae -r 652564fe42d5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Apr 08 15:44:41 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Tue Apr 08 15:55:18 2014 +0200 @@ -90,16 +90,22 @@ } } if (tool.canonicalizeReads()) { - if (metaAccess != null && object != null && object.isConstant()) { + if (metaAccess != null && object != null && object.isConstant() && !compressible) { if ((location.getLocationIdentity() == LocationIdentity.FINAL_LOCATION || location.getLocationIdentity() == LocationIdentity.ARRAY_LENGTH_LOCATION) && location instanceof ConstantLocationNode) { long displacement = ((ConstantLocationNode) location).getDisplacement(); - Kind kind = location.getValueKind(); Constant base = object.asConstant(); if (base != null) { - Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible); + Constant constant; + if (read.stamp() instanceof PrimitiveStamp) { + PrimitiveStamp stamp = (PrimitiveStamp) read.stamp(); + constant = tool.getConstantReflection().readRawConstant(stamp.getStackKind(), base, displacement, stamp.getBits()); + } else { + assert read.stamp() instanceof ObjectStamp; + constant = tool.getConstantReflection().readUnsafeConstant(Kind.Object, base, displacement); + } if (constant != null) { - return ConstantNode.forConstant(constant, metaAccess, read.graph()); + return ConstantNode.forConstant(read.stamp(), constant, metaAccess, read.graph()); } } } diff -r bceb077143ae -r 652564fe42d5 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java Tue Apr 08 15:44:41 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadFinalNode.java Tue Apr 08 15:55:18 2014 +0200 @@ -57,7 +57,7 @@ @Override public Node canonical(CanonicalizerTool tool) { if (object.isConstant() && !object.isNullConstant() && offset.isConstant()) { - Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant(), offset.asConstant().asLong(), accessKind == Kind.Object); + Constant constant = tool.getConstantReflection().readUnsafeConstant(accessKind, object.asConstant(), offset.asConstant().asLong()); return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph()); } return this;