Mercurial > hg > truffle
changeset 14561:e14198669e5c
Make data patch system use vm specific NarrowOop kind.
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Mon Mar 17 11:40:12 2014 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Mon Mar 17 11:53:51 2014 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.api.code; +import com.oracle.graal.api.code.CompilationResult.Data; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.meta.*; @@ -85,6 +86,11 @@ boolean needsDataPatch(Constant constant); /** + * Create a {@link Data} item for a {@link Constant}, that can be used in a {@link DataPatch}. + */ + Data createDataItem(Constant constant, int alignment); + + /** * Gets a description of the target architecture. */ TargetDescription getTarget();
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Mon Mar 17 11:40:12 2014 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Mon Mar 17 11:53:51 2014 +0100 @@ -154,64 +154,62 @@ public abstract int getSize(TargetDescription target); + public abstract Kind getKind(); + public abstract void emit(TargetDescription target, ByteBuffer buffer); } - public static final class ConstantData extends Data { + /** + * Represents a Java primitive value used in a {@link DataPatch}. This implementation uses + * {@link Kind#getByteCount()} bytes to encode each value. + */ + public static final class PrimitiveData extends Data { public final Constant constant; - public ConstantData(Constant constant, int alignment) { + public PrimitiveData(Constant constant, int alignment) { super(alignment); + assert constant.getKind().isPrimitive(); this.constant = constant; } @Override public int getSize(TargetDescription target) { - return target.getSizeInBytes(constant.getPlatformKind()); + return constant.getKind().getByteCount(); + } + + @Override + public Kind getKind() { + return constant.getKind(); } @Override public void emit(TargetDescription target, ByteBuffer buffer) { switch (constant.getKind()) { case Boolean: - assert getSize(target) == 1; buffer.put(constant.asBoolean() ? (byte) 1 : (byte) 0); break; case Byte: - assert getSize(target) == 1; buffer.put((byte) constant.asInt()); break; case Char: - assert getSize(target) == 2; buffer.putChar((char) constant.asInt()); break; case Short: - assert getSize(target) == 2; buffer.putShort((short) constant.asInt()); break; case Int: - assert getSize(target) == 4; buffer.putInt(constant.asInt()); break; case Long: - assert getSize(target) == 8; buffer.putLong(constant.asLong()); break; case Float: - assert getSize(target) == 4; buffer.putFloat(constant.asFloat()); break; case Double: - assert getSize(target) == 8; buffer.putDouble(constant.asDouble()); break; - case Object: - // placeholder for oop value - for (int i = 0; i < getSize(target); i++) { - buffer.put((byte) 0); - } - break; } } @@ -219,6 +217,24 @@ public String toString() { return constant.toString(); } + + @Override + public int hashCode() { + return constant.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof PrimitiveData) { + PrimitiveData other = (PrimitiveData) obj; + return constant.equals(other.constant); + } else { + return false; + } + } } public static final class RawData extends Data { @@ -236,6 +252,11 @@ } @Override + public Kind getKind() { + return Kind.Illegal; + } + + @Override public void emit(TargetDescription target, ByteBuffer buffer) { buffer.put(data); } @@ -250,6 +271,24 @@ } return ret.toString(); } + + @Override + public int hashCode() { + return Arrays.hashCode(data); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof RawData) { + RawData other = (RawData) obj; + return Arrays.equals(data, other.data); + } else { + return false; + } + } } /** @@ -260,53 +299,18 @@ public static final class DataPatch extends Site { private static final long serialVersionUID = 5771730331604867476L; - public Data externalData; - public Constant inlineData; - - DataPatch(int pcOffset, Data externalData) { - this(pcOffset, externalData, null); - } - - DataPatch(int pcOffset, Constant inlineData) { - this(pcOffset, null, inlineData); - } - - 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; - } + public Data data; + public boolean inline; - public Constant getConstant() { - if (inlineData != null) { - return inlineData; - } else if (externalData instanceof ConstantData) { - return ((ConstantData) externalData).constant; - } else { - return null; - } - } - - public int getAlignment() { - if (externalData instanceof ConstantData) { - return ((ConstantData) externalData).getAlignment(); - } else { - return 0; - } - } - - public String getDataString() { - if (inlineData != null) { - return inlineData.toString(); - } else { - return externalData.toString(); - } + public DataPatch(int pcOffset, Data data, boolean inline) { + super(pcOffset); + this.data = data; + this.inline = inline; } @Override public String toString() { - return String.format("%d[<data patch referring to data %s>]", pcOffset, getDataString()); + return String.format("%d[<data patch referring to %s data %s>]", pcOffset, inline ? "inline" : "external", data.toString()); } } @@ -538,18 +542,18 @@ */ public void recordDataReference(int codePos, Data data) { assert codePos >= 0 && data != null; - dataReferences.add(new DataPatch(codePos, data)); + dataReferences.add(new DataPatch(codePos, data, false)); } /** * 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 inlined constant occurs - * @param constant the constant that is referenced + * @param data the data that is referenced */ - public void recordInlineData(int codePos, Constant constant) { - assert codePos >= 0 && constant != null; - dataReferences.add(new DataPatch(codePos, constant)); + public void recordInlineData(int codePos, Data data) { + assert codePos >= 0 && data != null; + dataReferences.add(new DataPatch(codePos, data, true)); } /**
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Mon Mar 17 11:40:12 2014 +0100 +++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Mon Mar 17 11:53:51 2014 +0100 @@ -27,7 +27,7 @@ import org.junit.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CompilationResult.ConstantData; +import com.oracle.graal.api.code.CompilationResult.PrimitiveData; import com.oracle.graal.api.code.CompilationResult.RawData; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; @@ -59,7 +59,7 @@ public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) { AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig); Register ret = registerConfig.getReturnRegister(Kind.Double); - compResult.recordDataReference(asm.position(), new ConstantData(Constant.forDouble(84.72), 8)); + compResult.recordDataReference(asm.position(), new PrimitiveData(Constant.forDouble(84.72), 8)); asm.movdbl(ret, asm.getPlaceholder()); asm.ret(0); return asm.close(true);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Mar 17 11:40:12 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Mar 17 11:53:51 2014 +0100 @@ -293,14 +293,9 @@ for (int i = 0; i < dms.length; i++) { dms[i] = Debug.metric("DataPatches-" + Kind.values()[i].toString()); } - DebugMetric dmRaw = Debug.metric("DataPatches-raw"); for (DataPatch dp : ldp) { - if (dp.getConstant() != null) { - dms[dp.getConstant().getKind().ordinal()].add(1); - } else { - dmRaw.add(1); - } + dms[dp.data.getKind().ordinal()].add(1); } Debug.metric("CompilationResults").increment();
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Mon Mar 17 11:40:12 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Mon Mar 17 11:53:51 2014 +0100 @@ -33,6 +33,7 @@ import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; +import com.oracle.graal.hotspot.data.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; @@ -51,6 +52,9 @@ public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (kind == Kind.Long) { if (NumUtil.isInt(input.asLong())) { + if (input.getPrimitiveAnnotation() != null) { + crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), input.getPrimitiveAnnotation(), true)); + } masm.movl(address.toAddress(), (int) input.asLong()); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); @@ -59,7 +63,7 @@ if (input.isNull()) { masm.movl(address.toAddress(), 0); } else if (crb.target.inlineObjects) { - crb.recordInlineDataInCode(input); + crb.recordInlineDataInCode(new OopData(0, input.asObject(), true)); masm.movl(address.toAddress(), 0xDEADDEAD); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Mon Mar 17 11:40:12 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Mon Mar 17 11:53:51 2014 +0100 @@ -22,21 +22,17 @@ */ 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.Infopoint; import com.oracle.graal.api.code.CompilationResult.JumpTable; 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.*; +import com.oracle.graal.hotspot.data.*; /** * A {@link CompilationResult} with additional HotSpot-specific information required for installing @@ -53,111 +49,6 @@ public final DataSection dataSection; - /** - * Represents a reference to the data section. Before the code is installed, all {@link Data} - * items referenced by a {@link DataPatch} are put into the data section of the method, and - * replaced by {@link HotSpotData}. - */ - public static final class HotSpotData extends Data { - - /** - * The offset of the data item in the data section. - */ - public int offset; - - /** - * If the data item is an oop that needs to be patched by the runtime, this field contains - * the reference to the object. - */ - public Constant constant; - - public HotSpotData(int offset) { - super(0); - this.offset = offset; - } - - @Override - public int getSize(TargetDescription target) { - return 0; - } - - @Override - public void emit(TargetDescription target, ByteBuffer buffer) { - } - } - - /** - * Represents the data section of a method. - */ - public static final class DataSection { - - /** - * The minimum alignment required for this data section. - */ - public final int sectionAlignment; - - /** - * The raw data contained in the data section. - */ - public final byte[] data; - - /** - * A list of locations where oop pointers need to be patched by the runtime. - */ - public final HotSpotData[] patches; - - public DataSection(TargetDescription target, Site[] sites) { - int size = 0; - int patchCount = 0; - List<DataPatch> externalDataList = new ArrayList<>(); - - // find all external data items and determine total size of data section - 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.getAlignment()); - size += d.getSize(target); - 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; - - // build data section - for (DataPatch dataPatch : externalDataList) { - Data d = dataPatch.externalData; - - alignment = Math.max(alignment, d.getAlignment()); - index = NumUtil.roundUp(index, d.getAlignment()); - buffer.position(index); - - HotSpotData hsData = new HotSpotData(index); - if (dataPatch.getConstant() != null && dataPatch.getConstant().getKind() == Kind.Object) { - // record patch location for oop pointers - hsData.constant = dataPatch.getConstant(); - patches[patchIndex++] = hsData; - } - dataPatch.externalData = hsData; - - index += d.getSize(target); - d.emit(target, buffer); - } - - this.sectionAlignment = alignment; - } - } - public static class Comment { public final String text;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Mon Mar 17 11:40:12 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Mon Mar 17 11:53:51 2014 +0100 @@ -26,7 +26,7 @@ import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.code.CompilationResult.Infopoint; -import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.data.*; import com.oracle.graal.hotspot.stubs.*; /** @@ -50,11 +50,7 @@ private boolean checkStubInvariants(CompilationResult compResult) { assert compResult.getExceptionHandlers().isEmpty(); for (DataPatch data : compResult.getDataReferences()) { - 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; - } + assert !(data.data instanceof PatchedData) : this + " cannot have embedded object or metadata constant: " + data.data; } for (Infopoint infopoint : compResult.getInfopoints()) { assert infopoint instanceof Call : this + " cannot have non-call infopoint: " + infopoint;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java Mon Mar 17 11:53:51 2014 +0100 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.data; + +import java.nio.*; +import java.util.*; + +import com.oracle.graal.api.code.CompilationResult.Data; +import com.oracle.graal.api.code.CompilationResult.DataPatch; +import com.oracle.graal.api.code.CompilationResult.Site; +import com.oracle.graal.api.code.*; +import com.oracle.graal.asm.*; + +/** + * Represents the data section of a method. + */ +public final class DataSection { + + /** + * The minimum alignment required for this data section. + */ + public final int sectionAlignment; + + /** + * The raw data contained in the data section. + */ + public final byte[] data; + + /** + * A list of locations where oop pointers need to be patched by the runtime. + */ + public final DataPatch[] patches; + + public DataSection(TargetDescription target, Site[] sites) { + int size = 0; + int patchCount = 0; + List<DataPatch> externalDataList = new ArrayList<>(); + + // find all external data items and determine total size of data section + for (Site site : sites) { + if (site instanceof DataPatch) { + DataPatch dataPatch = (DataPatch) site; + Data d = dataPatch.data; + if (dataPatch.inline) { + assert d instanceof PatchedData : "unnecessary data patch"; + } else { + size = NumUtil.roundUp(size, d.getAlignment()); + size += d.getSize(target); + externalDataList.add(dataPatch); + if (d instanceof PatchedData) { + patchCount++; + } + } + } + } + + data = new byte[size]; + patches = new DataPatch[patchCount]; + ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.nativeOrder()); + int index = 0; + int patchIndex = 0; + int alignment = 0; + + // build data section + for (DataPatch dataPatch : externalDataList) { + assert !dataPatch.inline; + Data d = dataPatch.data; + + alignment = Math.max(alignment, d.getAlignment()); + index = NumUtil.roundUp(index, d.getAlignment()); + buffer.position(index); + + DataSectionReference reference = new DataSectionReference(index); + if (d instanceof PatchedData) { + // record patch location + patches[patchIndex++] = new DataPatch(index, d, true); + } + dataPatch.data = reference; + + index += d.getSize(target); + d.emit(target, buffer); + } + + this.sectionAlignment = alignment; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSectionReference.java Mon Mar 17 11:53:51 2014 +0100 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.data; + +import java.nio.*; + +import com.oracle.graal.api.code.CompilationResult.Data; +import com.oracle.graal.api.code.CompilationResult.DataPatch; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; + +/** + * Represents a reference to the data section. Before the code is installed, all {@link Data} items + * referenced by a {@link DataPatch} are put into the data section of the method, and replaced by + * {@link DataSectionReference}. + */ +public class DataSectionReference extends Data { + + public final int offset; + + protected DataSectionReference(int offset) { + super(0); + this.offset = offset; + } + + @Override + public int getSize(TargetDescription target) { + return 0; + } + + @Override + public Kind getKind() { + return Kind.Illegal; + } + + @Override + public void emit(TargetDescription target, ByteBuffer buffer) { + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java Mon Mar 17 11:53:51 2014 +0100 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.data; + +import java.nio.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; + +/** + * A data item that represents a metaspace pointer. + */ +public class MetaspaceData extends PatchedData { + + public final long value; + public final Object annotation; + public final boolean compressed; + + public MetaspaceData(int alignment, long value, Object annotation, boolean compressed) { + super(alignment); + assert annotation != null; + this.value = value; + this.annotation = annotation; + this.compressed = compressed; + } + + @Override + public int getSize(TargetDescription target) { + if (compressed) { + return target.getSizeInBytes(Kind.Int); + } else { + return target.getSizeInBytes(target.wordKind); + } + } + + @Override + public Kind getKind() { + return Kind.Long; + } + + @Override + public void emit(TargetDescription target, ByteBuffer buffer) { + switch (getSize(target)) { + case 4: + buffer.putInt((int) value); + break; + case 8: + buffer.putLong(value); + break; + default: + throw GraalInternalError.shouldNotReachHere("unexpected metaspace pointer size"); + } + } + + @Override + public String toString() { + return (compressed ? "NarrowPointer[0x" + Integer.toHexString((int) value) : "Pointer[0x" + Long.toHexString(value)) + "]{" + annotation + "}"; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java Mon Mar 17 11:53:51 2014 +0100 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.data; + +import java.nio.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.nodes.type.*; + +/** + * A data item that represents an oop value. + */ +public class OopData extends PatchedData { + + public final Object object; + public final boolean compressed; + + public OopData(int alignment, Object object, boolean compressed) { + super(alignment); + this.object = object; + this.compressed = compressed; + } + + @Override + public int getSize(TargetDescription target) { + if (compressed) { + return target.getSizeInBytes(NarrowOopStamp.NarrowOop); + } else { + return target.getSizeInBytes(Kind.Object); + } + } + + @Override + public Kind getKind() { + return Kind.Object; + } + + @Override + public void emit(TargetDescription target, ByteBuffer buffer) { + switch (getSize(target)) { + case 4: + buffer.putInt(0xDEADDEAD); + break; + case 8: + buffer.putLong(0xDEADDEADDEADDEADL); + break; + default: + throw GraalInternalError.shouldNotReachHere("unexpected oop size"); + } + } + + @Override + public String toString() { + return (compressed ? "NarrowOop[" : "Oop[") + Kind.Object.format(object) + "]"; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/PatchedData.java Mon Mar 17 11:53:51 2014 +0100 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.hotspot.data; + +import com.oracle.graal.api.code.CompilationResult.Data; + +/** + * Represents a data item that needs to be patched. + */ +public abstract class PatchedData extends Data { + + protected PatchedData(int alignment) { + super(alignment); + } +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Mon Mar 17 11:40:12 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Mon Mar 17 11:53:51 2014 +0100 @@ -29,14 +29,17 @@ import com.oracle.graal.api.code.CodeUtil.DefaultRefMapFormatter; import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; import com.oracle.graal.api.code.CompilationResult.Call; +import com.oracle.graal.api.code.CompilationResult.Data; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.code.CompilationResult.Infopoint; import com.oracle.graal.api.code.CompilationResult.Mark; +import com.oracle.graal.api.code.CompilationResult.PrimitiveData; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult; +import com.oracle.graal.hotspot.data.*; import com.oracle.graal.java.*; import com.oracle.graal.printer.*; @@ -82,7 +85,7 @@ } } for (DataPatch site : compResult.getDataReferences()) { - hcf.addOperandComment(site.pcOffset, "{" + site.getDataString() + "}"); + hcf.addOperandComment(site.pcOffset, "{" + site.data.toString() + "}"); } for (Mark mark : compResult.getMarks()) { hcf.addComment(mark.pcOffset, getMarkName(mark)); @@ -216,6 +219,16 @@ return constant.getPrimitiveAnnotation() != null; } + public Data createDataItem(Constant constant, int alignment) { + if (constant.getPrimitiveAnnotation() != null) { + return new MetaspaceData(alignment, constant.asLong(), constant.getPrimitiveAnnotation(), false); + } else if (constant.getKind().isObject()) { + return new OopData(alignment, constant.asObject(), false); + } else { + return new PrimitiveData(constant, alignment); + } + } + @Override public TargetDescription getTarget() { return target;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Mon Mar 17 11:40:12 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Mon Mar 17 11:53:51 2014 +0100 @@ -27,7 +27,6 @@ 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.*; @@ -157,6 +156,10 @@ } public void recordInlineDataInCode(Constant data) { + recordInlineDataInCode(codeCache.createDataItem(data, 0)); + } + + public void recordInlineDataInCode(Data data) { assert data != null; int pos = asm.position(); Debug.log("Inline data in code: pos = %d, data = %s", pos, data); @@ -165,7 +168,7 @@ public AbstractAddress recordDataReferenceInCode(Constant data, int alignment) { assert data != null; - return recordDataReferenceInCode(new ConstantData(data, alignment)); + return recordDataReferenceInCode(codeCache.createDataItem(data, alignment)); } public AbstractAddress recordDataReferenceInCode(Data data) {
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Mon Mar 17 11:40:12 2014 +0100 +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Mon Mar 17 11:53:51 2014 +0100 @@ -41,55 +41,32 @@ } } -inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) { - oop inlineData = CompilationResult_DataPatch::inlineData(site); - address pc = _instructions->start() + pc_offset; +inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) { + if (OopData::compressed(obj)) { + fatal("unimplemented: narrow oop relocation"); + } else { + address pc = _instructions->start() + pc_offset; + Handle obj = OopData::object(data); + jobject value = JNIHandles::make_local(obj()); - if (inlineData != NULL) { - oop kind = Constant::kind(inlineData); - char typeChar = Kind::typeChar(kind); + NativeMovConstReg* move = nativeMovConstReg_at(pc); + move->set_data((intptr_t) value); - 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(inlineData); - move->set_data(value); - break; - } - case 'a': { - NativeMovConstReg* move = nativeMovConstReg_at(pc); - Handle obj = Constant::object(inlineData); - jobject value = JNIHandles::make_local(obj()); - move->set_data((intptr_t) value); + // We need two relocations: one on the sethi and one on the add. + int oop_index = _oop_recorder->find_index(value); + RelocationHolder rspec = oop_Relocation::spec(oop_index); + _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec); + _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec); + } +} - // We need two relocations: one on the sethi and one on the add. - int oop_index = _oop_recorder->find_index(value); - RelocationHolder rspec = oop_Relocation::spec(oop_index); - _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec); - _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec); - 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); +inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) { + address pc = _instructions->start() + pc_offset; + jint offset = DataSectionReference::offset(data); - NativeMovRegMem* load = nativeMovRegMem_at(pc); - int disp = _constants_size + pc_offset - offset - BytesPerInstWord; - load->set_offset(-disp); - } + NativeMovRegMem* load = nativeMovRegMem_at(pc); + int disp = _constants_size + pc_offset - offset - BytesPerInstWord; + load->set_offset(-disp); } inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Mon Mar 17 11:40:12 2014 +0100 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Mon Mar 17 11:53:51 2014 +0100 @@ -59,68 +59,49 @@ } } -inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) { - oop inlineData = CompilationResult_DataPatch::inlineData(site); +inline bool check_metaspace_data(address pc, oop data) { + jlong value = MetaspaceData::value(data); + address operand = Assembler::locate_operand(pc, Assembler::imm_operand); + if (MetaspaceData::compressed(data)) { + assert(*((jint*) operand) == value, err_msg("wrong compressed metaspace pointer: %p != %p", *((jint*) operand), value)); + } else { + assert(*((jlong*) operand) == value, err_msg("wrong metaspace pointer: %p != %p", *((jlong*) operand), value)); + } + return true; +} + +inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) { address pc = _instructions->start() + pc_offset; - 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 'n': { - address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); - Handle obj = Constant::object(inlineData); + Handle obj = OopData::object(data); + jobject value = JNIHandles::make_local(obj()); + if (OopData::compressed(data)) { + address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); + 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); + } else { + address operand = Assembler::locate_operand(pc, Assembler::imm_operand); + *((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); + } +} - 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(inlineData); - break; - } - case 'a': { - address operand = Assembler::locate_operand(pc, Assembler::imm_operand); - Handle obj = Constant::object(inlineData); +inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) { + address pc = _instructions->start() + pc_offset; + jint offset = DataSectionReference::offset(data); - 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; - } - } 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; + address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); + address next_instruction = Assembler::locate_next_instruction(pc); + address dest = _constants->start() + offset; - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*) operand) = (jint) disp; + 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); - } + _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); } inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/share/vm/classfile/systemDictionary.hpp Mon Mar 17 11:40:12 2014 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Mar 17 11:53:51 2014 +0100 @@ -187,12 +187,14 @@ 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) \ do_klass(HotSpotForeignCallLinkage_klass, com_oracle_graal_hotspot_HotSpotForeignCallLinkage, Opt) \ + do_klass(DataSection_klass, com_oracle_graal_hotspot_data_DataSection, Opt) \ + do_klass(DataSectionReference_klass, com_oracle_graal_hotspot_data_DataSectionReference, Opt) \ + do_klass(MetaspaceData_klass, com_oracle_graal_hotspot_data_MetaspaceData, Opt) \ + do_klass(OopData_klass, com_oracle_graal_hotspot_data_OopData, Opt) \ do_klass(HotSpotCodeInfo_klass, com_oracle_graal_hotspot_meta_HotSpotCodeInfo, Opt) \ do_klass(HotSpotInstalledCode_klass, com_oracle_graal_hotspot_meta_HotSpotInstalledCode, Opt) \ do_klass(HotSpotNmethod_klass, com_oracle_graal_hotspot_meta_HotSpotNmethod, Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp Mon Mar 17 11:40:12 2014 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Mar 17 11:53:51 2014 +0100 @@ -296,14 +296,16 @@ 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") \ template(com_oracle_graal_hotspot_HotSpotForeignCallLinkage, "com/oracle/graal/hotspot/HotSpotForeignCallLinkage") \ template(com_oracle_graal_hotspot_bridge_VMToCompiler, "com/oracle/graal/hotspot/bridge/VMToCompiler") \ template(com_oracle_graal_hotspot_bridge_CompilerToVMImpl, "com/oracle/graal/hotspot/bridge/CompilerToVMImpl") \ + template(com_oracle_graal_hotspot_data_DataSection, "com/oracle/graal/hotspot/data/DataSection") \ + template(com_oracle_graal_hotspot_data_DataSectionReference, "com/oracle/graal/hotspot/data/DataSectionReference") \ + template(com_oracle_graal_hotspot_data_MetaspaceData, "com/oracle/graal/hotspot/data/MetaspaceData") \ + template(com_oracle_graal_hotspot_data_OopData, "com/oracle/graal/hotspot/data/OopData") \ template(com_oracle_graal_hotspot_meta_HotSpotCodeInfo, "com/oracle/graal/hotspot/meta/HotSpotCodeInfo") \ template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode, "com/oracle/graal/hotspot/meta/HotSpotInstalledCode") \ template(com_oracle_graal_hotspot_meta_HotSpotNmethod, "com/oracle/graal/hotspot/meta/HotSpotNmethod") \
--- a/src/share/vm/graal/graalCodeInstaller.cpp Mon Mar 17 11:40:12 2014 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Mon Mar 17 11:53:51 2014 +0100 @@ -157,6 +157,27 @@ return map; } +static void record_metadata_reference(oop obj, jlong prim, bool compressed, OopRecorder* oop_recorder) { + if (obj->is_a(HotSpotResolvedObjectType::klass())) { + Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj)); + if (compressed) { + assert(Klass::decode_klass((narrowKlass) prim) == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim)); + } else { + assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim)); + } + int index = oop_recorder->find_index(klass); + TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string()); + } else if (obj->is_a(HotSpotResolvedJavaMethod::klass())) { + Method* method = (Method*) (address) HotSpotResolvedJavaMethod::metaspaceMethod(obj); + assert(!compressed, err_msg("unexpected compressed method pointer %s @ %p = %p", method->name()->as_C_string(), method, prim)); + int index = oop_recorder->find_index(method); + TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string()); + } else { + assert(java_lang_String::is_instance(obj), + err_msg("unexpected metadata reference (%s) for constant %ld (%p)", obj->klass()->name()->as_C_string(), prim, prim)); + } +} + // Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectType.klass()). static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) { char kind = Kind::typeChar(Constant::kind(constant)); @@ -165,23 +186,15 @@ oop obj = Constant::object(constant); jlong prim = Constant::primitive(constant); if (obj != NULL) { - if (obj->is_a(HotSpotResolvedObjectType::klass())) { - Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj)); - assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim)); - int index = oop_recorder->find_index(klass); - TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string()); - } else if (obj->is_a(HotSpotResolvedJavaMethod::klass())) { - Method* method = (Method*) (address) HotSpotResolvedJavaMethod::metaspaceMethod(obj); - int index = oop_recorder->find_index(method); - TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string()); - } else { - assert(java_lang_String::is_instance(obj), - err_msg("unexpected annotation type (%s) for constant %ld (%p) of kind %c", obj->klass()->name()->as_C_string(), prim, prim, kind)); - } + record_metadata_reference(obj, prim, false, oop_recorder); } } } +static void record_metadata_in_patch(oop data, OopRecorder* oop_recorder) { + record_metadata_reference(MetaspaceData::annotation(data), MetaspaceData::value(data), MetaspaceData::compressed(data), oop_recorder); +} + ScopeValue* CodeInstaller::get_scope_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder) { second = NULL; if (value == Value::ILLEGAL()) { @@ -445,8 +458,8 @@ // Pre-calculate the constants section size. This is required for PC-relative addressing. _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); + guarantee(DataSection::sectionAlignment(_dataSection) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); + arrayOop data = (arrayOop) DataSection::data(_dataSection); _constants_size = data->length(); if (_constants_size > 0) { _constants_size = align_size_up(_constants_size, _constants->alignment()); @@ -482,30 +495,24 @@ // copy the constant data into the newly created CodeBuffer address end_data = _constants->start() + _constants_size; - arrayOop data = (arrayOop) HotSpotCompiledCode_DataSection::data(_dataSection); + arrayOop data = (arrayOop) DataSection::data(_dataSection); memcpy(_constants->start(), data->base(T_BYTE), data->length()); _constants->set_end(end_data); - objArrayOop patches = (objArrayOop) HotSpotCompiledCode_DataSection::patches(_dataSection); + objArrayOop patches = (objArrayOop) 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); + oop data = CompilationResult_DataPatch::data(patch); + if (data->is_a(MetaspaceData::klass())) { + record_metadata_in_patch(data, _oop_recorder); + } else if (data->is_a(OopData::klass())) { + Handle obj = OopData::object(data); + 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; + address dest = _constants->start() + CompilationResult_Site::pcOffset(patch); + assert(!OopData::compressed(data), err_msg("unexpected compressed oop in data section")); + _constants->relocate(dest, oop_Relocation::spec(oop_index)); } } @@ -777,19 +784,16 @@ } void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { - 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(inlineData, _oop_recorder); - break; - } + oop data = CompilationResult_DataPatch::data(site); + if (data->is_a(MetaspaceData::klass())) { + record_metadata_in_patch(data, _oop_recorder); + } else if (data->is_a(OopData::klass())) { + pd_patch_OopData(pc_offset, data); + } else if (data->is_a(DataSectionReference::klass())) { + pd_patch_DataSectionReference(pc_offset, data); + } else { + fatal("unknown data patch type"); } - CodeInstaller::pd_site_DataPatch(pc_offset, site); } void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
--- a/src/share/vm/graal/graalCodeInstaller.hpp Mon Mar 17 11:40:12 2014 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Mon Mar 17 11:53:51 2014 +0100 @@ -77,7 +77,8 @@ ExceptionHandlerTable _exception_handler_table; jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method); - void pd_site_DataPatch(int pc_offset, oop site); + void pd_patch_OopData(int pc_offset, oop data); + void pd_patch_DataSectionReference(int pc_offset, oop data); void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst); void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination); void pd_relocate_JavaMethod(oop method, jint pc_offset);
--- a/src/share/vm/graal/graalJavaAccess.hpp Mon Mar 17 11:40:12 2014 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Mon Mar 17 11:53:51 2014 +0100 @@ -79,16 +79,7 @@ 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;") \ + oop_field(HotSpotCompiledCode, dataSection, "Lcom/oracle/graal/hotspot/data/DataSection;") \ end_class \ start_class(HotSpotCompiledCode_Comment) \ oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;") \ @@ -97,7 +88,7 @@ start_class(HotSpotCompiledNmethod) \ oop_field(HotSpotCompiledNmethod, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;") \ int_field(HotSpotCompiledNmethod, entryBCI) \ - int_field(HotSpotCompiledNmethod, id) \ + int_field(HotSpotCompiledNmethod, id) \ end_class \ start_class(HotSpotCompiledRuntimeStub) \ oop_field(HotSpotCompiledRuntimeStub, stubName, "Ljava/lang/String;") \ @@ -105,6 +96,23 @@ start_class(HotSpotForeignCallLinkage) \ long_field(HotSpotForeignCallLinkage, address) \ end_class \ + start_class(DataSection) \ + int_field(DataSection, sectionAlignment) \ + oop_field(DataSection, data, "[B") \ + oop_field(DataSection, patches, "[Lcom/oracle/graal/api/code/CompilationResult$DataPatch;") \ + end_class \ + start_class(DataSectionReference) \ + int_field(DataSectionReference, offset) \ + end_class \ + start_class(MetaspaceData) \ + long_field(MetaspaceData, value) \ + oop_field(MetaspaceData, annotation, "Ljava/lang/Object;") \ + boolean_field(MetaspaceData, compressed) \ + end_class \ + start_class(OopData) \ + oop_field(OopData, object, "Ljava/lang/Object;") \ + boolean_field(OopData, compressed) \ + end_class \ start_class(ExternalCompilationResult) \ long_field(ExternalCompilationResult, entryPoint) \ end_class \ @@ -145,8 +153,7 @@ oop_field(CompilationResult_Call, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;") \ end_class \ start_class(CompilationResult_DataPatch) \ - oop_field(CompilationResult_DataPatch, externalData, "Lcom/oracle/graal/api/code/CompilationResult$Data;") \ - oop_field(CompilationResult_DataPatch, inlineData, "Lcom/oracle/graal/api/meta/Constant;") \ + oop_field(CompilationResult_DataPatch, data, "Lcom/oracle/graal/api/code/CompilationResult$Data;") \ end_class \ start_class(InfopointReason) \ static_oop_field(InfopointReason, UNKNOWN, "Lcom/oracle/graal/api/code/InfopointReason;") \