# HG changeset patch # User Roland Schatz # Date 1389269384 -3600 # Node ID 4e679d50ba9a00fe03c466d00925743b1d2f0969 # Parent 55a8ca3f49f76c424a3e71be31b3e899f95d5249 Move data section building code to Java. diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Thu Jan 09 13:09:44 2014 +0100 @@ -25,6 +25,7 @@ import static java.util.Collections.*; import java.io.*; +import java.nio.*; import java.util.*; import com.oracle.graal.api.meta.*; @@ -136,6 +137,65 @@ } } + public abstract static class Data { + + public final int size; + public final int alignment; + + public abstract void emit(ByteBuffer buffer); + + protected Data(int size, int alignment) { + this.size = size; + this.alignment = alignment; + } + } + + public static final class ConstantData extends Data { + + public final Constant constant; + + public ConstantData(Constant constant, int alignment) { + super(8, alignment); + this.constant = constant; + } + + @Override + public void emit(ByteBuffer buffer) { + constant.putPrimitive(buffer); + } + + @Override + public String toString() { + return constant.toString(); + } + } + + public static final class RawData extends Data { + + public final byte[] data; + + public RawData(byte[] data, int alignment) { + super(data.length, alignment); + this.data = data; + } + + @Override + public void emit(ByteBuffer buffer) { + buffer.put(data); + } + + @Override + public String toString() { + Formatter ret = new Formatter(); + boolean first = true; + for (byte b : data) { + ret.format(first ? "%02X" : " %02X", b); + first = false; + } + return ret.toString(); + } + } + /** * Represents a reference to data from the code. The associated data can be either a * {@link Constant} or a raw byte array. The raw byte array is patched as is, no endian swapping @@ -144,44 +204,39 @@ public static final class DataPatch extends Site { private static final long serialVersionUID = 5771730331604867476L; - public final Constant constant; - public final byte[] rawConstant; - public final int alignment; + public Data externalData; + public Constant inlineData; - /** - * Determines if the data is encoded inline or is loaded from a separate data area. - */ - public final boolean inlined; + DataPatch(int pcOffset, Data externalData) { + this(pcOffset, externalData, null); + } - DataPatch(int pcOffset, byte[] data, int alignment) { - this(pcOffset, null, data, alignment, false); + DataPatch(int pcOffset, Constant inlineData) { + this(pcOffset, null, inlineData); } - DataPatch(int pcOffset, Constant data, int alignment, boolean inlined) { - this(pcOffset, data, null, alignment, inlined); + private DataPatch(int pcOffset, Data externalData, Constant inlineData) { + super(pcOffset); + assert (externalData == null) != (inlineData == null) : "data patch can not be both external and inlined"; + this.externalData = externalData; + this.inlineData = inlineData; } - private DataPatch(int pcOffset, Constant data, byte[] rawData, int alignment, boolean inlined) { - super(pcOffset); - assert (data == null) != (rawData == null) : "only one of data and rawData is allowed"; - assert !inlined || rawData == null : "rawData can not be inlined"; - this.constant = data; - this.rawConstant = rawData; - this.alignment = alignment; - this.inlined = inlined; + public Constant getConstant() { + if (inlineData != null) { + return inlineData; + } else if (externalData instanceof ConstantData) { + return ((ConstantData) externalData).constant; + } else { + return null; + } } public String getDataString() { - if (constant != null) { - return constant.toString(); + if (inlineData != null) { + return inlineData.toString(); } else { - Formatter ret = new Formatter(); - boolean first = true; - for (byte b : rawConstant) { - ret.format(first ? "%02X" : " %02X", b); - first = false; - } - return ret.toString(); + return externalData.toString(); } } @@ -400,27 +455,21 @@ * * @param codePos the position in the code where the data reference occurs * @param data the data that is referenced - * @param alignment the alignment requirement of the data or 0 if there is no alignment - * requirement - * @param inlined specifies if the data is encoded inline or is loaded from a separate data area */ - public void recordDataReference(int codePos, Constant data, int alignment, boolean inlined) { + public void recordDataReference(int codePos, Data data) { assert codePos >= 0 && data != null; - dataReferences.add(new DataPatch(codePos, data, alignment, inlined)); + dataReferences.add(new DataPatch(codePos, data)); } /** - * Records a reference to the data section in the code section (e.g. to load an integer or - * floating point constant). + * Records a reference to an inlined constant in the code section (e.g. to load a constant oop). * - * @param codePos the position in the code where the data reference occurs - * @param data a byte array containing the raw data that is referenced - * @param alignment the alignment requirement of the data or 0 if there is no alignment - * requirement + * @param codePos the position in the code where the inlined constant occurs + * @param constant the constant that is referenced */ - public void recordDataReference(int codePos, byte[] data, int alignment) { - assert codePos >= 0 && data != null && data.length > 0; - dataReferences.add(new DataPatch(codePos, data, alignment)); + public void recordInlineData(int codePos, Constant constant) { + assert codePos >= 0 && constant != null; + dataReferences.add(new DataPatch(codePos, constant)); } /** diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Thu Jan 09 13:09:44 2014 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.api.meta; +import java.nio.*; + /** * Represents a constant (boxed) value, such as an integer, floating point number, or object * reference, within the compiler and across the compiler/runtime interface. Exports a set of @@ -110,6 +112,10 @@ return object == null && primitive == 0; } + public void putPrimitive(ByteBuffer buffer) { + buffer.putLong(primitive); + } + @Override public String toString() { if (getKind() == Kind.Illegal) { diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java --- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Thu Jan 09 13:09:44 2014 +0100 @@ -27,6 +27,8 @@ import org.junit.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CompilationResult.ConstantData; +import com.oracle.graal.api.code.CompilationResult.RawData; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.Buffer; import com.oracle.graal.asm.amd64.*; @@ -58,7 +60,7 @@ public Buffer generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) { AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig); Register ret = registerConfig.getReturnRegister(Kind.Double); - compResult.recordDataReference(asm.codeBuffer.position(), Constant.forDouble(84.72), 8, false); + compResult.recordDataReference(asm.codeBuffer.position(), new ConstantData(Constant.forDouble(84.72), 8)); asm.movdbl(ret, asm.getPlaceholder()); asm.ret(0); return asm.codeBuffer; @@ -78,7 +80,7 @@ byte[] rawBytes = new byte[8]; ByteBuffer.wrap(rawBytes).order(ByteOrder.nativeOrder()).putDouble(84.72); - compResult.recordDataReference(asm.codeBuffer.position(), rawBytes, 8); + compResult.recordDataReference(asm.codeBuffer.position(), new RawData(rawBytes, 8)); asm.movdbl(ret, asm.getPlaceholder()); asm.ret(0); return asm.codeBuffer; diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Jan 09 13:09:44 2014 +0100 @@ -298,8 +298,8 @@ DebugMetric dmRaw = Debug.metric("DataPatches-raw"); for (DataPatch dp : ldp) { - if (dp.constant != null) { - dms[dp.constant.getKind().ordinal()].add(1); + if (dp.getConstant() != null) { + dms[dp.getConstant().getKind().ordinal()].add(1); } else { dmRaw.add(1); } diff -r 55a8ca3f49f7 -r 4e679d50ba9a 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 Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Thu Jan 09 13:09:44 2014 +0100 @@ -59,7 +59,7 @@ if (input.isNull()) { masm.movl(address.toAddress(), 0); } else if (crb.target.inlineObjects) { - crb.recordDataReferenceInCode(input, 0, true); + crb.recordInlineDataInCode(input); masm.movl(address.toAddress(), 0xDEADDEAD); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java Thu Jan 09 13:09:44 2014 +0100 @@ -79,7 +79,7 @@ Constant pollingPageAddress = Constant.forIntegerKind(hostWordKind, config.safepointPollingAddress, null); // This move will be patched to load the safepoint page from a data segment // co-located with the immutable code. - asm.movq(scratch, (AMD64Address) crb.recordDataReferenceInCode(pollingPageAddress, alignment, false)); + asm.movq(scratch, (AMD64Address) crb.recordDataReferenceInCode(pollingPageAddress, alignment)); final int pos = asm.codeBuffer.position(); crb.recordMark(atReturn ? MARK_POLL_RETURN_FAR : MARK_POLL_FAR); if (state != null) { diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Thu Jan 09 13:09:44 2014 +0100 @@ -22,12 +22,20 @@ */ package com.oracle.graal.hotspot; +import java.nio.*; import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CompilationResult.CodeAnnotation; import com.oracle.graal.api.code.CompilationResult.CodeComment; +import com.oracle.graal.api.code.CompilationResult.Data; +import com.oracle.graal.api.code.CompilationResult.DataPatch; +import com.oracle.graal.api.code.CompilationResult.ExceptionHandler; import com.oracle.graal.api.code.CompilationResult.JumpTable; -import com.oracle.graal.api.code.CompilationResult.*; +import com.oracle.graal.api.code.CompilationResult.Mark; +import com.oracle.graal.api.code.CompilationResult.Site; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.*; /** * A {@link CompilationResult} with additional HotSpot-specific information required for installing @@ -42,6 +50,76 @@ public final ExceptionHandler[] exceptionHandlers; public final Comment[] comments; + public final DataSection dataSection; + + public static final class HotSpotData extends Data { + + public int offset; + public Constant constant; + + public HotSpotData(int offset) { + super(0, 0); + this.offset = offset; + } + + @Override + public void emit(ByteBuffer buffer) { + } + } + + public static final class DataSection { + + public final int sectionAlignment; + public final byte[] data; + public final HotSpotData[] patches; + + public DataSection(Site[] sites) { + int size = 0; + int patchCount = 0; + List externalDataList = new ArrayList<>(); + for (Site site : sites) { + if (site instanceof DataPatch) { + DataPatch dataPatch = (DataPatch) site; + if (dataPatch.externalData != null) { + Data d = dataPatch.externalData; + size = NumUtil.roundUp(size, d.alignment); + size += d.size; + externalDataList.add(dataPatch); + if (dataPatch.getConstant() != null && dataPatch.getConstant().getKind() == Kind.Object) { + patchCount++; + } + } + } + } + + data = new byte[size]; + patches = new HotSpotData[patchCount]; + ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.nativeOrder()); + int index = 0; + int patchIndex = 0; + int alignment = 0; + for (DataPatch dataPatch : externalDataList) { + Data d = dataPatch.externalData; + + alignment = Math.max(alignment, d.alignment); + index = NumUtil.roundUp(index, d.alignment); + buffer.position(index); + + HotSpotData hsData = new HotSpotData(index); + if (dataPatch.getConstant() != null && dataPatch.getConstant().getKind() == Kind.Object) { + hsData.constant = dataPatch.getConstant(); + patches[patchIndex++] = hsData; + } + dataPatch.externalData = hsData; + + index += d.size; + d.emit(buffer); + } + + this.sectionAlignment = alignment; + } + } + public static class Comment { public final String text; @@ -56,6 +134,7 @@ public HotSpotCompiledCode(CompilationResult compResult) { this.comp = compResult; sites = getSortedSites(compResult); + dataSection = new DataSection(sites); if (compResult.getExceptionHandlers().isEmpty()) { exceptionHandlers = null; } else { diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Thu Jan 09 13:09:44 2014 +0100 @@ -50,7 +50,7 @@ private boolean checkStubInvariants(CompilationResult compResult) { assert compResult.getExceptionHandlers().isEmpty(); for (DataPatch data : compResult.getDataReferences()) { - Constant constant = data.constant; + Constant constant = data.getConstant(); if (constant != null) { assert constant.getKind() != Kind.Object : this + " cannot have embedded object constant: " + constant; assert constant.getPrimitiveAnnotation() == null : this + " cannot have embedded metadata: " + constant; diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java Thu Jan 09 13:09:44 2014 +0100 @@ -132,7 +132,7 @@ switch (key.getKind()) { case Int: if (crb.codeCache.needsDataPatch(keyConstants[index])) { - crb.recordDataReferenceInCode(keyConstants[index], 0, true); + crb.recordInlineDataInCode(keyConstants[index]); } long lc = keyConstants[index].asLong(); assert NumUtil.isInt(lc); diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Thu Jan 09 13:09:44 2014 +0100 @@ -460,7 +460,7 @@ switch (input.getKind().getStackKind()) { case Int: if (crb.codeCache.needsDataPatch(input)) { - crb.recordDataReferenceInCode(input, 0, true); + crb.recordInlineDataInCode(input); } // Do not optimize with an XOR as this instruction may be between // a CMP and a Jcc in which case the XOR will modify the condition @@ -472,7 +472,7 @@ boolean patch = false; if (crb.codeCache.needsDataPatch(input)) { patch = true; - crb.recordDataReferenceInCode(input, 0, true); + crb.recordInlineDataInCode(input); } // Do not optimize with an XOR as this instruction may be between // a CMP and a Jcc in which case the XOR will modify the condition @@ -516,10 +516,10 @@ if (input.isNull()) { masm.movq(asRegister(result), 0x0L); } else if (crb.target.inlineObjects) { - crb.recordDataReferenceInCode(input, 0, true); + crb.recordInlineDataInCode(input); masm.movq(asRegister(result), 0xDEADDEADDEADDEADL); } else { - masm.movq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(input, 0, false)); + masm.movq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(input, 0)); } break; default: diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java Thu Jan 09 13:09:44 2014 +0100 @@ -226,7 +226,7 @@ case Int: case Long: if (crb.codeCache.needsDataPatch(keyConstants[index])) { - crb.recordDataReferenceInCode(keyConstants[index], 0, true); + crb.recordInlineDataInCode(keyConstants[index]); } new Setp(EQ, keyConstants[index], key, predRegNum).emit(masm); break; diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java --- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java Thu Jan 09 13:09:44 2014 +0100 @@ -216,7 +216,7 @@ case Int: case Long: if (crb.codeCache.needsDataPatch(input)) { - crb.recordDataReferenceInCode(input, 0, true); + crb.recordInlineDataInCode(input); } new Mov(dest, input).emit(masm); break; @@ -224,7 +224,7 @@ if (input.isNull()) { new Mov(dest, Constant.forLong(0x0L)).emit(masm); } else if (crb.target.inlineObjects) { - crb.recordDataReferenceInCode(input, 0, true); + crb.recordInlineDataInCode(input); new Mov(dest, Constant.forLong(0xDEADDEADDEADDEADL)).emit(masm); } else { // new Mov(dest, crb.recordDataReferenceInCode(input, 0, false)); diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java Thu Jan 09 13:09:44 2014 +0100 @@ -313,7 +313,7 @@ switch (key.getKind()) { case Int: if (crb.codeCache.needsDataPatch(keyConstants[index])) { - crb.recordDataReferenceInCode(keyConstants[index], 0, true); + crb.recordInlineDataInCode(keyConstants[index]); } long lc = keyConstants[index].asLong(); assert NumUtil.isInt(lc); diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Thu Jan 09 13:09:44 2014 +0100 @@ -432,7 +432,7 @@ switch (input.getKind().getStackKind()) { case Int: if (crb.codeCache.needsDataPatch(input)) { - crb.recordDataReferenceInCode(input, 0, true); + crb.recordInlineDataInCode(input); new Setuw(input.asInt(), asRegister(result)).emit(masm); } else { if (input.isDefaultForKind()) { @@ -444,7 +444,7 @@ break; case Long: { if (crb.codeCache.needsDataPatch(input)) { - crb.recordDataReferenceInCode(input, 0, true); + crb.recordInlineDataInCode(input); new Setx(input.asLong(), asRegister(result), true).emit(masm); } else { if (input.isDefaultForKind()) { @@ -459,7 +459,7 @@ if (input.isNull()) { new Clr(asRegister(result)).emit(masm); } else if (crb.target.inlineObjects) { - crb.recordDataReferenceInCode(input, 0, true); + crb.recordInlineDataInCode(input); new Setx(0xDEADDEADDEADDEADL, asRegister(result), true).emit(masm); } else { Register dst = asRegister(result); diff -r 55a8ca3f49f7 -r 4e679d50ba9a graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Thu Jan 09 11:46:07 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Thu Jan 09 13:09:44 2014 +0100 @@ -27,6 +27,8 @@ import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CompilationResult.ConstantData; +import com.oracle.graal.api.code.CompilationResult.Data; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.debug.*; @@ -158,19 +160,23 @@ compilationResult.recordInfopoint(pos, debugInfo, reason); } - public AbstractAddress recordDataReferenceInCode(Constant data, int alignment, boolean inlined) { + public void recordInlineDataInCode(Constant data) { + assert data != null; + int pos = asm.codeBuffer.position(); + Debug.log("Inline data in code: pos = %d, data = %s", pos, data.toString()); + compilationResult.recordInlineData(pos, data); + } + + public AbstractAddress recordDataReferenceInCode(Constant data, int alignment) { + assert data != null; + return recordDataReferenceInCode(new ConstantData(data, alignment)); + } + + public AbstractAddress recordDataReferenceInCode(Data data) { assert data != null; int pos = asm.codeBuffer.position(); Debug.log("Data reference in code: pos = %d, data = %s", pos, data.toString()); - compilationResult.recordDataReference(pos, data, alignment, inlined); - return asm.getPlaceholder(); - } - - public AbstractAddress recordDataReferenceInCode(byte[] data, int alignment) { - assert data != null; - int pos = asm.codeBuffer.position(); - Debug.log("Raw data reference in code: pos = %d, data = %s", pos, data.toString()); - compilationResult.recordDataReference(pos, data, alignment); + compilationResult.recordDataReference(pos, data); return asm.getPlaceholder(); } @@ -228,7 +234,7 @@ public AbstractAddress asFloatConstRef(Value value, int alignment) { assert value.getKind() == Kind.Float && isConstant(value); - return recordDataReferenceInCode((Constant) value, alignment, false); + return recordDataReferenceInCode((Constant) value, alignment); } /** @@ -240,7 +246,7 @@ public AbstractAddress asDoubleConstRef(Value value, int alignment) { assert value.getKind() == Kind.Double && isConstant(value); - return recordDataReferenceInCode((Constant) value, alignment, false); + return recordDataReferenceInCode((Constant) value, alignment); } /** @@ -248,7 +254,7 @@ */ public AbstractAddress asLongConstRef(Value value) { assert value.getKind() == Kind.Long && isConstant(value); - return recordDataReferenceInCode((Constant) value, 8, false); + return recordDataReferenceInCode((Constant) value, 8); } /** @@ -256,7 +262,7 @@ */ public AbstractAddress asObjectConstRef(Value value) { assert value.getKind() == Kind.Object && isConstant(value); - return recordDataReferenceInCode((Constant) value, 8, false); + return recordDataReferenceInCode((Constant) value, 8); } public AbstractAddress asIntAddr(Value value) { diff -r 55a8ca3f49f7 -r 4e679d50ba9a src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp --- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Thu Jan 09 11:46:07 2014 +0100 +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Thu Jan 09 13:09:44 2014 +0100 @@ -42,52 +42,32 @@ } inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) { - oop constant = CompilationResult_DataPatch::constant(site); - int alignment = CompilationResult_DataPatch::alignment(site); - bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; - - oop kind = Constant::kind(constant); - char typeChar = Kind::typeChar(kind); - + oop inlineData = CompilationResult_DataPatch::inlineData(site); address pc = _instructions->start() + pc_offset; - switch (typeChar) { - case 'z': - case 'b': - case 's': - case 'c': - case 'i': - fatal("int-sized values not expected in DataPatch"); - break; - case 'f': - case 'j': - case 'd': { - if (inlined) { + if (inlineData != NULL) { + oop kind = Constant::kind(inlineData); + char typeChar = Kind::typeChar(kind); + + switch (typeChar) { + case 'z': + case 'b': + case 's': + case 'c': + case 'i': + fatal("int-sized values not expected in DataPatch"); + break; + case 'f': + case 'j': + case 'd': { NativeMovConstReg* move = nativeMovConstReg_at(pc); - uint64_t value = Constant::primitive(constant); + uint64_t value = Constant::primitive(inlineData); move->set_data(value); - } else { - int size = _constants->size(); - if (alignment > 0) { - guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); - size = align_size_up(size, alignment); - } - // we don't care if this is a long/double/etc., the primitive field contains the right bits - address dest = _constants->start() + size; - _constants->set_end(dest); - uint64_t value = Constant::primitive(constant); - _constants->emit_int64(value); - - NativeMovRegMem* load = nativeMovRegMem_at(pc); - int disp = _constants_size + pc_offset - size - BytesPerInstWord; - load->set_offset(-disp); + break; } - break; - } - case 'a': { - if (inlined) { + case 'a': { NativeMovConstReg* move = nativeMovConstReg_at(pc); - Handle obj = Constant::object(constant); + Handle obj = Constant::object(inlineData); jobject value = JNIHandles::make_local(obj()); move->set_data((intptr_t) value); @@ -96,30 +76,19 @@ RelocationHolder rspec = oop_Relocation::spec(oop_index); _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec); _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec); - } else { - int size = _constants->size(); - if (alignment > 0) { - guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); - size = align_size_up(size, alignment); - } - address dest = _constants->start() + size; - _constants->set_end(dest); - Handle obj = Constant::object(constant); - jobject value = JNIHandles::make_local(obj()); - _constants->emit_address((address) value); + break; + } + default: + fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); + break; + } + } else { + oop dataRef = CompilationResult_DataPatch::externalData(site); + jint offset = HotSpotCompiledCode_HotSpotData::offset(dataRef); - NativeMovRegMem* load = nativeMovRegMem_at(pc); - int disp = _constants_size + pc_offset - size - BytesPerInstWord; - load->set_offset(-disp); - - int oop_index = _oop_recorder->find_index(value); - _constants->relocate(dest, oop_Relocation::spec(oop_index)); - } - break; - } - default: - fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); - break; + NativeMovRegMem* load = nativeMovRegMem_at(pc); + int disp = _constants_size + pc_offset - offset - BytesPerInstWord; + load->set_offset(-disp); } } diff -r 55a8ca3f49f7 -r 4e679d50ba9a src/cpu/x86/vm/graalCodeInstaller_x86.hpp --- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Thu Jan 09 11:46:07 2014 +0100 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Thu Jan 09 13:09:44 2014 +0100 @@ -60,91 +60,65 @@ } inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) { - int alignment = CompilationResult_DataPatch::alignment(site); - bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; - + oop inlineData = CompilationResult_DataPatch::inlineData(site); address pc = _instructions->start() + pc_offset; - oop constant = CompilationResult_DataPatch::constant(site); - char typeChar; - if (constant != NULL) { - oop kind = Constant::kind(constant); - typeChar = Kind::typeChar(kind); - } else { - assert(!inlined, "cannot inline raw constants"); - typeChar = '*'; - } + if (inlineData != NULL) { + oop kind = Constant::kind(inlineData); + char typeChar = Kind::typeChar(kind); - switch (typeChar) { - case 'z': - case 'b': - case 's': - case 'c': - fatal("int-sized values not expected in DataPatch"); - break; - - case 'i': { - address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); - Handle obj = Constant::object(constant); + switch (typeChar) { + case 'z': + case 'b': + case 's': + case 'c': + fatal("int-sized values not expected in DataPatch"); + break; + case 'i': { + address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); + Handle obj = Constant::object(inlineData); - jobject value = JNIHandles::make_local(obj()); - int oop_index = _oop_recorder->find_index(value); - _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand); - TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand); - break; - } - - case 'f': - case 'j': - case 'd': - case '*': { - if (inlined) { + jobject value = JNIHandles::make_local(obj()); + int oop_index = _oop_recorder->find_index(value); + _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand); + TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand); + break; + } + case 'f': + case 'j': + case 'd': + case '*': { address operand = Assembler::locate_operand(pc, Assembler::imm_operand); - *((jlong*) operand) = Constant::primitive(constant); - } else { - address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); - address next_instruction = Assembler::locate_next_instruction(pc); - int size = _constants->size(); - if (alignment > 0) { - guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); - size = align_size_up(size, alignment); - } - // we don't care if this is a long/double/etc., the primitive field contains the right bits - address dest = _constants->start() + size; - _constants->set_end(dest); - if (constant != NULL) { - uint64_t value = Constant::primitive(constant); - _constants->emit_int64(value); - } else { - arrayOop rawConstant = arrayOop(CompilationResult_DataPatch::rawConstant(site)); - int8_t *ptr = (int8_t*) rawConstant->base(T_BYTE); - for (int i = rawConstant->length(); i > 0; i--, ptr++) { - _constants->emit_int8(*ptr); - } - } + *((jlong*) operand) = Constant::primitive(inlineData); + break; + } + case 'a': { + address operand = Assembler::locate_operand(pc, Assembler::imm_operand); + Handle obj = Constant::object(inlineData); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*) operand) = (jint) disp; - - _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); - TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, pc, operand, dest, size); + jobject value = JNIHandles::make_local(obj()); + *((jobject*) operand) = value; + _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand); + break; } - break; + default: + fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); + break; } - case 'a': { - address operand = Assembler::locate_operand(pc, Assembler::imm_operand); - Handle obj = Constant::object(constant); + } else { + oop dataRef = CompilationResult_DataPatch::externalData(site); + jint offset = HotSpotCompiledCode_HotSpotData::offset(dataRef); + address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); + address next_instruction = Assembler::locate_next_instruction(pc); + address dest = _constants->start() + offset; - jobject value = JNIHandles::make_local(obj()); - *((jobject*) operand) = value; - _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand); - break; - } - default: - fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); - break; + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*) operand) = (jint) disp; + + _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); + TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset); } } diff -r 55a8ca3f49f7 -r 4e679d50ba9a src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Thu Jan 09 11:46:07 2014 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Thu Jan 09 13:09:44 2014 +0100 @@ -187,6 +187,8 @@ do_klass(BitSet_klass, java_util_BitSet, Opt) \ /* graal.hotspot */ \ do_klass(HotSpotCompiledCode_klass, com_oracle_graal_hotspot_HotSpotCompiledCode, Opt) \ + do_klass(HotSpotCompiledCode_HotSpotData_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_HotSpotData, Opt) \ + do_klass(HotSpotCompiledCode_DataSection_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_DataSection, Opt) \ do_klass(HotSpotCompiledCode_Comment_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_Comment, Opt) \ do_klass(HotSpotCompiledNmethod_klass, com_oracle_graal_hotspot_HotSpotCompiledNmethod, Opt) \ do_klass(HotSpotCompiledRuntimeStub_klass, com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub, Opt) \ diff -r 55a8ca3f49f7 -r 4e679d50ba9a src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Thu Jan 09 11:46:07 2014 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Thu Jan 09 13:09:44 2014 +0100 @@ -296,6 +296,8 @@ template(com_oracle_graal_hotspot_HotSpotKlassOop, "com/oracle/graal/hotspot/HotSpotKlassOop") \ template(com_oracle_graal_hotspot_HotSpotOptions, "com/oracle/graal/hotspot/HotSpotOptions") \ template(com_oracle_graal_hotspot_HotSpotCompiledCode, "com/oracle/graal/hotspot/HotSpotCompiledCode") \ + template(com_oracle_graal_hotspot_HotSpotCompiledCode_HotSpotData, "com/oracle/graal/hotspot/HotSpotCompiledCode$HotSpotData") \ + template(com_oracle_graal_hotspot_HotSpotCompiledCode_DataSection, "com/oracle/graal/hotspot/HotSpotCompiledCode$DataSection") \ template(com_oracle_graal_hotspot_HotSpotCompiledCode_Comment, "com/oracle/graal/hotspot/HotSpotCompiledCode$Comment") \ template(com_oracle_graal_hotspot_HotSpotCompiledNmethod, "com/oracle/graal/hotspot/HotSpotCompiledNmethod") \ template(com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub, "com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub") \ diff -r 55a8ca3f49f7 -r 4e679d50ba9a src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Thu Jan 09 11:46:07 2014 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Thu Jan 09 13:09:44 2014 +0100 @@ -435,7 +435,13 @@ _custom_stack_area_offset = CompilationResult::customStackAreaOffset(comp_result); // Pre-calculate the constants section size. This is required for PC-relative addressing. - _constants_size = calculate_constants_size(); + _dataSection = HotSpotCompiledCode::dataSection(compiled_code); + guarantee(HotSpotCompiledCode_DataSection::sectionAlignment(_dataSection) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); + arrayOop data = (arrayOop) HotSpotCompiledCode_DataSection::data(_dataSection); + _constants_size = data->length(); + if (_constants_size > 0) { + _constants_size = align_size_up(_constants_size, _constants->alignment()); + } #ifndef PRODUCT _comments = (arrayOop) HotSpotCompiledCode::comments(compiled_code); @@ -465,6 +471,35 @@ memcpy(_instructions->start(), _code->base(T_BYTE), _code_size); _instructions->set_end(end_pc); + // copy the constant data into the newly created CodeBuffer + address end_data = _constants->start() + _constants_size; + arrayOop data = (arrayOop) HotSpotCompiledCode_DataSection::data(_dataSection); + memcpy(_constants->start(), data->base(T_BYTE), data->length()); + _constants->set_end(end_data); + + objArrayOop patches = (objArrayOop) HotSpotCompiledCode_DataSection::patches(_dataSection); + for (int i = 0; i < patches->length(); i++) { + oop patch = patches->obj_at(i); + oop constant = HotSpotCompiledCode_HotSpotData::constant(patch); + oop kind = Constant::kind(constant); + char typeChar = Kind::typeChar(kind); + switch (typeChar) { + case 'f': + case 'j': + case 'd': + record_metadata_in_constant(constant, _oop_recorder); + break; + case 'a': + Handle obj = Constant::object(constant); + jobject value = JNIHandles::make_local(obj()); + int oop_index = _oop_recorder->find_index(value); + + address dest = _constants->start() + HotSpotCompiledCode_HotSpotData::offset(patch); + _constants->relocate(dest, oop_Relocation::spec(oop_index)); + break; + } + } + for (int i = 0; i < _sites->length(); i++) { oop site = ((objArrayOop) (_sites))->obj_at(i); jint pc_offset = CompilationResult_Site::pcOffset(site); @@ -508,39 +543,6 @@ return true; } -/** - * Calculate the constants section size by iterating over all DataPatches. - * Knowing the size of the constants section before patching instructions - * is necessary for PC-relative addressing. - */ -int CodeInstaller::calculate_constants_size() { - int size = 0; - - for (int i = 0; i < _sites->length(); i++) { - oop site = ((objArrayOop) (_sites))->obj_at(i); - jint pc_offset = CompilationResult_Site::pcOffset(site); - - if (site->is_a(CompilationResult_DataPatch::klass())) { - int alignment = CompilationResult_DataPatch::alignment(site); - bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE; - - if (!inlined) { - if (alignment > 0) { - guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); - size = align_size_up(size, alignment); - } - if (CompilationResult_DataPatch::constant(site) != NULL) { - size = size + sizeof(int64_t); - } else { - arrayOop rawConstant = arrayOop(CompilationResult_DataPatch::rawConstant(site)); - size = size + rawConstant->length(); - } - } - } - } - return size == 0 ? 0 : align_size_up(size, _constants->alignment()); -} - void CodeInstaller::assumption_MethodContents(Handle assumption) { Handle method_handle = Assumptions_MethodContents::method(assumption()); methodHandle method = getMethodFromHotSpotMethod(method_handle()); @@ -766,15 +768,15 @@ } void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { - oop constant = CompilationResult_DataPatch::constant(site); - if (constant != NULL) { - oop kind = Constant::kind(constant); + oop inlineData = CompilationResult_DataPatch::inlineData(site); + if (inlineData != NULL) { + oop kind = Constant::kind(inlineData); char typeChar = Kind::typeChar(kind); switch (typeChar) { case 'f': case 'j': case 'd': - record_metadata_in_constant(constant, _oop_recorder); + record_metadata_in_constant(inlineData, _oop_recorder); break; } } diff -r 55a8ca3f49f7 -r 4e679d50ba9a src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Thu Jan 09 11:46:07 2014 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Thu Jan 09 13:09:44 2014 +0100 @@ -50,6 +50,7 @@ Arena _arena; + oop _dataSection; arrayOop _sites; arrayOop _exception_handlers; CodeOffsets _offsets; @@ -102,8 +103,6 @@ // perform data and call relocation on the CodeBuffer bool initialize_buffer(CodeBuffer& buffer); - int calculate_constants_size(); - void assumption_MethodContents(Handle assumption); void assumption_NoFinalizableSubclass(Handle assumption); void assumption_ConcreteSubtype(Handle assumption); diff -r 55a8ca3f49f7 -r 4e679d50ba9a src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Thu Jan 09 11:46:07 2014 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Thu Jan 09 13:09:44 2014 +0100 @@ -81,6 +81,16 @@ oop_field(HotSpotCompiledCode, sites, "[Lcom/oracle/graal/api/code/CompilationResult$Site;") \ oop_field(HotSpotCompiledCode, exceptionHandlers, "[Lcom/oracle/graal/api/code/CompilationResult$ExceptionHandler;") \ oop_field(HotSpotCompiledCode, comments, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$Comment;") \ + oop_field(HotSpotCompiledCode, dataSection, "Lcom/oracle/graal/hotspot/HotSpotCompiledCode$DataSection;") \ + end_class \ + start_class(HotSpotCompiledCode_HotSpotData) \ + int_field(HotSpotCompiledCode_HotSpotData, offset) \ + oop_field(HotSpotCompiledCode_HotSpotData, constant, "Lcom/oracle/graal/api/meta/Constant;") \ + end_class \ + start_class(HotSpotCompiledCode_DataSection) \ + int_field(HotSpotCompiledCode_DataSection, sectionAlignment) \ + oop_field(HotSpotCompiledCode_DataSection, data, "[B") \ + oop_field(HotSpotCompiledCode_DataSection, patches, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$HotSpotData;") \ end_class \ start_class(HotSpotCompiledCode_Comment) \ oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;") \ @@ -97,7 +107,7 @@ long_field(HotSpotForeignCallLinkage, address) \ end_class \ start_class(ExternalCompilationResult) \ - long_field(ExternalCompilationResult, entryPoint) \ + long_field(ExternalCompilationResult, entryPoint) \ end_class \ start_class(CompilationResult) \ int_field(CompilationResult, frameSize) \ @@ -137,10 +147,8 @@ oop_field(CompilationResult_Call, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;") \ end_class \ start_class(CompilationResult_DataPatch) \ - oop_field(CompilationResult_DataPatch, constant, "Lcom/oracle/graal/api/meta/Constant;") \ - oop_field(CompilationResult_DataPatch, rawConstant, "[B") \ - int_field(CompilationResult_DataPatch, alignment) \ - boolean_field(CompilationResult_DataPatch, inlined) \ + oop_field(CompilationResult_DataPatch, externalData, "Lcom/oracle/graal/api/code/CompilationResult$Data;") \ + oop_field(CompilationResult_DataPatch, inlineData, "Lcom/oracle/graal/api/meta/Constant;") \ end_class \ start_class(InfopointReason) \ static_oop_field(InfopointReason, UNKNOWN, "Lcom/oracle/graal/api/code/InfopointReason;") \