# HG changeset patch # User Roland Schatz # Date 1414415269 -3600 # Node ID c2270ad35f575372668bb7a41c9634d824ca5822 # Parent cf09e921458fdf51bb9b3f778d15dfdeb67963b6 Better construction of data section and data patches. diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Mon Oct 27 14:07:49 2014 +0100 @@ -22,8 +22,8 @@ */ 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.code.DataSection.Data; import com.oracle.graal.api.meta.*; /** @@ -87,7 +87,7 @@ /** * Create a {@link Data} item for a {@link Constant}, that can be used in a {@link DataPatch}. */ - Data createDataItem(Constant constant, int alignment); + Data createDataItem(Constant constant); /** * Gets a description of the target architecture. diff -r cf09e921458f -r c2270ad35f57 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 Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -25,7 +25,6 @@ import static java.util.Collections.*; import java.io.*; -import java.nio.*; import java.util.*; import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; @@ -141,93 +140,28 @@ /** * Represents some external data that is referenced by the code. */ - public abstract static class Data { - - private final int alignment; - - protected Data(int alignment) { - this.alignment = alignment; - } + public abstract static class Reference implements Serializable { - public int getAlignment() { - return alignment; - } - - public abstract int getSize(TargetDescription target); - - public abstract Kind getKind(); - - public abstract void emit(TargetDescription target, ByteBuffer buffer); + private static final long serialVersionUID = 4841246083028477946L; } - public abstract static class ConstantData extends Data { + public static class ConstantReference extends Reference { + + private static final long serialVersionUID = 5841121930949053612L; - private final Constant constant; + private final VMConstant constant; - protected ConstantData(Constant constant, int alignment) { - super(alignment); + public ConstantReference(VMConstant constant) { this.constant = constant; } - public Constant getConstant() { + public VMConstant getConstant() { return constant; } - } - - /** - * 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 ConstantData { - - public PrimitiveData(Constant constant, int alignment) { - super(constant, alignment); - assert constant.getKind().isPrimitive(); - } - - @Override - public int getSize(TargetDescription target) { - return getConstant().getKind().getByteCount(); - } - - @Override - public Kind getKind() { - return getConstant().getKind(); - } - - @Override - public void emit(TargetDescription target, ByteBuffer buffer) { - switch (getConstant().getKind()) { - case Boolean: - buffer.put(getConstant().asBoolean() ? (byte) 1 : (byte) 0); - break; - case Byte: - buffer.put((byte) getConstant().asInt()); - break; - case Char: - buffer.putChar((char) getConstant().asInt()); - break; - case Short: - buffer.putShort((short) getConstant().asInt()); - break; - case Int: - buffer.putInt(getConstant().asInt()); - break; - case Long: - buffer.putLong(getConstant().asLong()); - break; - case Float: - buffer.putFloat(getConstant().asFloat()); - break; - case Double: - buffer.putDouble(getConstant().asDouble()); - break; - } - } @Override public String toString() { - return getConstant().toString(); + return constant.toString(); } @Override @@ -240,8 +174,8 @@ if (this == obj) { return true; } - if (obj instanceof PrimitiveData) { - PrimitiveData other = (PrimitiveData) obj; + if (obj instanceof ConstantReference) { + ConstantReference other = (ConstantReference) obj; return getConstant().equals(other.getConstant()); } else { return false; @@ -249,80 +183,44 @@ } } - public static final class RawData extends Data { - - public final byte[] data; + public static class DataSectionReference extends Reference { - public RawData(byte[] data, int alignment) { - super(alignment); - this.data = data; - } + private static final long serialVersionUID = 9011681879878139182L; - @Override - public int getSize(TargetDescription target) { - return data.length; - } + private int offset; - @Override - public Kind getKind() { - return Kind.Illegal; - } - - @Override - public void emit(TargetDescription target, ByteBuffer buffer) { - buffer.put(data); + public DataSectionReference() { + // will be set after the data section layout is fixed + offset = 0xDEADDEAD; } - @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(); + public int getOffset() { + return offset; } - @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; - } + public void setOffset(int offset) { + this.offset = offset; } } /** * Represents a code site that references some data. The associated data can be either a - * reference to an external {@link Data} item in the data section, or it may be an inlined + * {@link DataSectionReference reference} to the data section, or it may be an inlined * {@link Constant} that needs to be patched. */ public static final class DataPatch extends Site { private static final long serialVersionUID = 5771730331604867476L; - public Data data; - public boolean inline; + public Reference reference; - public DataPatch(int pcOffset, Data data, boolean inline) { + public DataPatch(int pcOffset, Reference reference) { super(pcOffset); - this.data = data; - this.inline = inline; + this.reference = reference; } @Override public String toString() { - return String.format("%d[]", pcOffset, inline ? "inline" : "external", data.toString()); + return String.format("%d[]", pcOffset, reference.toString()); } } @@ -453,8 +351,10 @@ private int id = -1; private int entryBCI = -1; + private final DataSection dataSection = new DataSection(); + private final List infopoints = new ArrayList<>(); - private final List dataReferences = new ArrayList<>(); + private final List dataPatches = new ArrayList<>(); private final List exceptionHandlers = new ArrayList<>(); private final List marks = new ArrayList<>(); @@ -521,6 +421,10 @@ return assumptions; } + public DataSection getDataSection() { + return dataSection; + } + /** * The total frame size of the method in bytes. This includes the return address pushed onto the * stack, if any. @@ -554,26 +458,16 @@ } /** - * Records a reference to the data section in the code section (e.g. to load an integer or - * floating point constant). + * Records a data patch in the code section. The data patch can refer to something in the + * {@link DataSectionReference data section} or directly to an {@link ConstantReference inlined + * constant}. * - * @param codePos the position in the code where the data reference occurs - * @param data the data that is referenced + * @param codePos The position in the code that needs to be patched. + * @param ref The reference that should be inserted in the code. */ - public void recordDataReference(int codePos, Data data) { - assert codePos >= 0 && data != null; - 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 data the data that is referenced - */ - public void recordInlineData(int codePos, Data data) { - assert codePos >= 0 && data != null; - dataReferences.add(new DataPatch(codePos, data, true)); + public void recordDataPatch(int codePos, Reference ref) { + assert codePos >= 0 && ref != null; + dataPatches.add(new DataPatch(codePos, ref)); } /** @@ -755,11 +649,11 @@ /** * @return the list of data references */ - public List getDataReferences() { - if (dataReferences.isEmpty()) { + public List getDataPatches() { + if (dataPatches.isEmpty()) { return emptyList(); } - return unmodifiableList(dataReferences); + return unmodifiableList(dataPatches); } /** @@ -788,7 +682,7 @@ public void reset() { infopoints.clear(); - dataReferences.clear(); + dataPatches.clear(); exceptionHandlers.clear(); marks.clear(); if (annotations != null) { diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DataSection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DataSection.java Mon Oct 27 14:07:49 2014 +0100 @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2014, 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.api.code; + +import java.io.*; +import java.nio.*; +import java.util.*; +import java.util.function.*; + +import com.oracle.graal.api.code.CompilationResult.DataPatch; +import com.oracle.graal.api.code.CompilationResult.DataSectionReference; +import com.oracle.graal.api.code.DataSection.Data; +import com.oracle.graal.api.meta.*; + +public class DataSection implements Serializable, Iterable { + + private static final long serialVersionUID = -1375715553825731716L; + + @FunctionalInterface + public interface DataBuilder { + + void emit(ByteBuffer buffer, Consumer patch); + + static DataBuilder raw(byte[] data) { + return (buffer, patch) -> buffer.put(data); + } + + static DataBuilder primitive(PrimitiveConstant c) { + switch (c.getKind()) { + case Boolean: + return (buffer, patch) -> buffer.put(c.asBoolean() ? (byte) 1 : (byte) 0); + case Byte: + return (buffer, patch) -> buffer.put((byte) c.asInt()); + case Char: + return (buffer, patch) -> buffer.putChar((char) c.asInt()); + case Short: + return (buffer, patch) -> buffer.putShort((short) c.asInt()); + case Int: + return (buffer, patch) -> buffer.putInt(c.asInt()); + case Long: + return (buffer, patch) -> buffer.putLong(c.asLong()); + case Float: + return (buffer, patch) -> buffer.putFloat(c.asFloat()); + case Double: + return (buffer, patch) -> buffer.putDouble(c.asDouble()); + default: + throw new IllegalArgumentException(); + } + } + + static DataBuilder zero(int size) { + switch (size) { + case 1: + return (buffer, patch) -> buffer.put((byte) 0); + case 2: + return (buffer, patch) -> buffer.putShort((short) 0); + case 4: + return (buffer, patch) -> buffer.putInt(0); + case 8: + return (buffer, patch) -> buffer.putLong(0L); + default: + return (buffer, patch) -> { + int rest = size; + while (rest > 8) { + buffer.putLong(0L); + rest -= 8; + } + while (rest > 0) { + buffer.put((byte) 0); + rest--; + } + }; + } + } + } + + public static class Data implements Serializable { + + private static final long serialVersionUID = -719932751800916080L; + + private int alignment; + private final int size; + private final DataBuilder builder; + + private DataSectionReference ref; + + public Data(int alignment, int size, DataBuilder builder) { + this.alignment = alignment; + this.size = size; + this.builder = builder; + + // initialized in DataSection.insertData(Data) + ref = null; + } + + public void updateAlignment(int newAlignment) { + if (newAlignment == alignment) { + return; + } + alignment = lcm(alignment, newAlignment); + } + + public int getAlignment() { + return alignment; + } + + public int getSize() { + return size; + } + + public DataBuilder getBuilder() { + return builder; + } + } + + private final ArrayList dataItems = new ArrayList<>(); + + private boolean finalLayout; + private int sectionAlignment; + private int sectionSize; + + /** + * Insert a {@link Data} item into the data section. If the item is already in the data section, + * the same {@link DataSectionReference} is returned. + * + * @param data the {@link Data} item to be inserted + * @return a unique {@link DataSectionReference} identifying the {@link Data} item + */ + public DataSectionReference insertData(Data data) { + assert !finalLayout; + if (data.ref == null) { + data.ref = new DataSectionReference(); + dataItems.add(data); + } + return data.ref; + } + + /** + * Compute the layout of the data section. This can be called only once, and after it has been + * called, the data section can no longer be modified. + */ + public void finalizeLayout() { + assert !finalLayout; + finalLayout = true; + + // simple heuristic: put items with larger alignment requirement first + dataItems.sort((a, b) -> a.alignment - b.alignment); + + int position = 0; + for (Data d : dataItems) { + sectionAlignment = lcm(sectionAlignment, d.alignment); + position = align(position, d.alignment); + + d.ref.setOffset(position); + position += d.size; + } + + sectionSize = position; + } + + /** + * Get the size of the data section. Can only be called after {@link #finalizeLayout}. + */ + public int getSectionSize() { + assert finalLayout; + return sectionSize; + } + + /** + * Get the minimum alignment requirement of the data section. Can only be called after + * {@link #finalizeLayout}. + */ + public int getSectionAlignment() { + assert finalLayout; + return sectionAlignment; + } + + /** + * Build the data section. Can only be called after {@link #finalizeLayout}. + * + * @param buffer The {@link ByteBuffer} where the data section should be built. The buffer must + * hold at least {@link #getSectionSize()} bytes. + * @param patch A {@link Consumer} to receive {@link DataPatch data patches} for relocations in + * the data section. + */ + public void buildDataSection(ByteBuffer buffer, Consumer patch) { + assert finalLayout; + for (Data d : dataItems) { + buffer.position(d.ref.getOffset()); + d.builder.emit(buffer, patch); + } + } + + public Data findData(DataSectionReference ref) { + for (Data d : dataItems) { + if (d.ref == ref) { + return d; + } + } + return null; + } + + public Iterator iterator() { + return dataItems.iterator(); + } + + private static int lcm(int x, int y) { + if (x == 0) { + return y; + } else if (y == 0) { + return x; + } + + int a = Math.max(x, y); + int b = Math.min(x, y); + while (b > 0) { + int tmp = a % b; + a = b; + b = tmp; + } + + int gcd = a; + return x * y / gcd; + } + + private static int align(int position, int alignment) { + return ((position + alignment - 1) / alignment) * alignment; + } +} diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/VMConstant.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/VMConstant.java Mon Oct 27 14:07:49 2014 +0100 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2014, 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.api.meta; + +public interface VMConstant extends Constant { +} diff -r cf09e921458f -r c2270ad35f57 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 Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -29,8 +29,9 @@ import org.junit.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CompilationResult.PrimitiveData; -import com.oracle.graal.api.code.CompilationResult.RawData; +import com.oracle.graal.api.code.CompilationResult.DataSectionReference; +import com.oracle.graal.api.code.DataSection.Data; +import com.oracle.graal.api.code.DataSection.DataBuilder; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.test.*; @@ -66,7 +67,9 @@ 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 PrimitiveData(Constant.forDouble(84.72), 8)); + Data data = new Data(8, 8, DataBuilder.primitive((PrimitiveConstant) Constant.forDouble(84.72))); + DataSectionReference ref = compResult.getDataSection().insertData(data); + compResult.recordDataPatch(asm.position(), ref); asm.movdbl(ret, asm.getPlaceholder()); asm.ret(0); return asm.close(true); @@ -86,7 +89,9 @@ byte[] rawBytes = new byte[8]; ByteBuffer.wrap(rawBytes).order(ByteOrder.nativeOrder()).putDouble(84.72); - compResult.recordDataReference(asm.position(), new RawData(rawBytes, 8)); + Data data = new Data(8, 8, DataBuilder.raw(rawBytes)); + DataSectionReference ref = compResult.getDataSection().insertData(data); + compResult.recordDataPatch(asm.position(), ref); asm.movdbl(ret, asm.getPlaceholder()); asm.ret(0); return asm.close(true); diff -r cf09e921458f -r c2270ad35f57 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 Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -31,6 +31,7 @@ import com.oracle.graal.alloc.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.CompilationResult.ConstantReference; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.ProfilingInfo.TriState; @@ -307,7 +308,7 @@ } if (Debug.isMeterEnabled()) { - List ldp = compilationResult.getDataReferences(); + List ldp = compilationResult.getDataPatches(); Kind[] kindValues = Kind.values(); DebugMetric[] dms = new DebugMetric[kindValues.length]; for (int i = 0; i < dms.length; i++) { @@ -315,7 +316,11 @@ } for (DataPatch dp : ldp) { - dms[dp.data.getKind().ordinal()].add(1); + Kind kind = Kind.Illegal; + if (dp.reference instanceof ConstantReference) { + kind = ((ConstantReference) dp.reference).getConstant().getKind(); + } + dms[kind.ordinal()].add(1); } Debug.metric("CompilationResults").increment(); diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -29,7 +29,6 @@ import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.compiler.common.*; -import com.oracle.graal.hotspot.data.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; @@ -58,21 +57,21 @@ } else if (y instanceof HotSpotObjectConstant) { if (HotSpotObjectConstant.isCompressed(y)) { // compressed oop - crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(y), true)); + crb.recordInlineDataInCode(y); masm.cmpl(asRegister(x), 0xDEADDEAD); } else { // uncompressed oop - AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(new OopData(8, HotSpotObjectConstant.asObject(y), false)); + AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(y, 8); masm.cmpq(asRegister(x), patch); } } else if (y instanceof HotSpotMetaspaceConstant) { if (y.getKind() == Kind.Int) { // compressed metaspace pointer - crb.recordInlineDataInCode(new MetaspaceData(0, y.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(y), true)); + crb.recordInlineDataInCode(y); masm.cmpl(asRegister(x), y.asInt()); } else { // uncompressed metaspace pointer - AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(new MetaspaceData(8, y.asLong(), HotSpotObjectConstant.asObject(y), false)); + AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(y, 8); masm.cmpq(asRegister(x), patch); } } else { @@ -99,7 +98,7 @@ } else if (y instanceof HotSpotObjectConstant) { if (HotSpotObjectConstant.isCompressed(y) && crb.target.inlineObjects) { // compressed oop - crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(y), true)); + crb.recordInlineDataInCode(y); masm.cmpl(address.toAddress(), 0xDEADDEAD); } else { // uncompressed oop @@ -108,11 +107,11 @@ } else if (y instanceof HotSpotMetaspaceConstant) { if (y.getKind() == Kind.Int) { // compressed metaspace pointer - crb.recordInlineDataInCode(new MetaspaceData(0, y.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(y), true)); + crb.recordInlineDataInCode(y); masm.cmpl(address.toAddress(), y.asInt()); } else if (y.getKind() == Kind.Long && NumUtil.is32bit(y.asLong())) { // uncompressed metaspace pointer - crb.recordInlineDataInCode(new MetaspaceData(0, y.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(y), false)); + crb.recordInlineDataInCode(y); masm.cmpq(address.toAddress(), (int) y.asLong()); } else { throw GraalInternalError.shouldNotReachHere(); diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Oct 27 14:07:49 2014 +0100 @@ -426,7 +426,7 @@ if (c.getKind() == Kind.Long) { int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL); if (c instanceof HotSpotMetaspaceConstant) { - return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c)); + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c), true); } else { return Constant.forIntegerKind(Kind.Int, compressedValue); } diff -r cf09e921458f -r c2270ad35f57 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 Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -33,7 +33,6 @@ import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; -import com.oracle.graal.hotspot.data.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.MoveOp; @@ -64,9 +63,8 @@ } } else if (input instanceof HotSpotObjectConstant) { boolean compressed = HotSpotObjectConstant.isCompressed(input); - OopData data = new OopData(compressed ? 4 : 8, HotSpotObjectConstant.asObject(input), compressed); if (crb.target.inlineObjects) { - crb.recordInlineDataInCode(data); + crb.recordInlineDataInCode(input); if (isRegister(result)) { if (compressed) { masm.movl(asRegister(result), 0xDEADDEAD); @@ -83,7 +81,7 @@ } } else { if (isRegister(result)) { - AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(data); + AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(input, compressed ? 4 : 8); if (compressed) { masm.movl(asRegister(result), address); } else { @@ -96,8 +94,7 @@ } else if (input instanceof HotSpotMetaspaceConstant) { assert input.getKind() == Kind.Int || input.getKind() == Kind.Long; boolean compressed = input.getKind() == Kind.Int; - MetaspaceData data = new MetaspaceData(compressed ? 4 : 8, input.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(input), compressed); - crb.recordInlineDataInCode(data); + crb.recordInlineDataInCode(input); if (isRegister(result)) { if (compressed) { masm.movl(asRegister(result), input.asInt()); @@ -140,7 +137,7 @@ } else if (input instanceof HotSpotObjectConstant) { if (HotSpotObjectConstant.isCompressed(input) && crb.target.inlineObjects) { // compressed oop - crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(input), true)); + crb.recordInlineDataInCode(input); masm.movl(address.toAddress(), 0xDEADDEAD); } else { // uncompressed oop @@ -149,7 +146,7 @@ } else if (input instanceof HotSpotMetaspaceConstant) { if (input.getKind() == Kind.Int) { // compressed metaspace pointer - crb.recordInlineDataInCode(new MetaspaceData(0, input.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(input), true)); + crb.recordInlineDataInCode(input); masm.movl(address.toAddress(), input.asInt()); } else { // uncompressed metaspace pointer diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Mon Oct 27 14:07:49 2014 +0100 @@ -43,9 +43,11 @@ import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.CodeAnnotation; import com.oracle.graal.api.code.CompilationResult.DataPatch; +import com.oracle.graal.api.code.CompilationResult.DataSectionReference; import com.oracle.graal.api.code.CompilationResult.ExceptionHandler; import com.oracle.graal.api.code.CompilationResult.Infopoint; import com.oracle.graal.api.code.CompilationResult.Mark; +import com.oracle.graal.api.code.DataSection.Data; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.hsail.*; @@ -297,7 +299,7 @@ HSAILHotSpotNmethod code = new HSAILHotSpotNmethod(javaMethod, hsailCode.getName(), false, true); code.setOopMapArray(hsailCode.getOopMapArray()); code.setUsesAllocationFlag(hsailCode.getUsesAllocationFlag()); - HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(getTarget(), javaMethod, compilationResult); + HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, compilationResult); CodeInstallResult result = getRuntime().getCompilerToVM().installCode(compiled, code, null); if (result != CodeInstallResult.OK) { return null; @@ -314,7 +316,7 @@ result.setEntryBCI(hsailCode.getEntryBCI()); assert hsailCode.getMarks().isEmpty(); assert hsailCode.getExceptionHandlers().isEmpty(); - assert hsailCode.getDataReferences().isEmpty(); + assert hsailCode.getDataPatches().isEmpty(); // from host code result.setTotalFrameSize(hostCode.getTotalFrameSize()); @@ -329,14 +331,13 @@ for (ExceptionHandler handler : hostCode.getExceptionHandlers()) { result.recordExceptionHandler(handler.pcOffset, handler.handlerPos); } - for (DataPatch patch : hostCode.getDataReferences()) { - if (patch.data != null) { - if (patch.inline) { - result.recordInlineData(patch.pcOffset, patch.data); - } else { - result.recordDataReference(patch.pcOffset, patch.data); - } + for (DataPatch patch : hostCode.getDataPatches()) { + if (patch.reference instanceof DataSectionReference) { + Data hostData = hostCode.getDataSection().findData((DataSectionReference) patch.reference); + Data resultData = new Data(hostData.getAlignment(), hostData.getSize(), hostData.getBuilder()); + patch.reference = result.getDataSection().insertData(resultData); } + result.recordDataPatch(patch.pcOffset, patch.reference); } for (Infopoint infopoint : hostCode.getInfopoints()) { if (infopoint instanceof Call) { diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Mon Oct 27 14:07:49 2014 +0100 @@ -257,7 +257,7 @@ if (c.getKind() == Kind.Long) { int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL); if (c instanceof HotSpotMetaspaceConstant) { - return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c)); + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c), true); } else { return Constant.forIntegerKind(Kind.Int, compressedValue); } diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java Mon Oct 27 14:07:49 2014 +0100 @@ -68,7 +68,7 @@ if (c.getKind() == Kind.Long) { int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL); if (c instanceof HotSpotMetaspaceConstant) { - return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c)); + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c), true); } else { return Constant.forIntegerKind(Kind.Int, compressedValue); } diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -49,7 +49,7 @@ protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, compResult.getName(), true); - HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(runtime().getTarget(), hsMethod, compResult); + HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(hsMethod, compResult); CodeInstallResult result = runtime().getCompilerToVM().installCode(compiledNmethod, installedCode, null); Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK); diff -r cf09e921458f -r c2270ad35f57 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 Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,17 +22,20 @@ */ package com.oracle.graal.hotspot; +import java.nio.*; import java.util.*; +import java.util.stream.*; +import java.util.stream.Stream.Builder; 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.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.hotspot.data.*; /** * A {@link CompilationResult} with additional HotSpot-specific information required for installing @@ -47,7 +50,9 @@ public final ExceptionHandler[] exceptionHandlers; public final Comment[] comments; - public final DataSection dataSection; + public final byte[] dataSection; + public final int dataSectionAlignment; + public final DataPatch[] dataSectionPatches; public static class Comment { @@ -60,10 +65,9 @@ } } - public HotSpotCompiledCode(TargetDescription target, CompilationResult compResult) { + public HotSpotCompiledCode(CompilationResult compResult) { this.comp = compResult; sites = getSortedSites(compResult); - dataSection = new DataSection(target, sites); if (compResult.getExceptionHandlers().isEmpty()) { exceptionHandlers = null; } else { @@ -88,6 +92,17 @@ } } assert validateFrames(); + + DataSection data = compResult.getDataSection(); + data.finalizeLayout(); + dataSection = new byte[data.getSectionSize()]; + + ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder()); + Builder patchBuilder = Stream.builder(); + data.buildDataSection(buffer, patchBuilder); + + dataSectionAlignment = data.getSectionAlignment(); + dataSectionPatches = patchBuilder.build().toArray(len -> new DataPatch[len]); } /** @@ -118,7 +133,7 @@ } private static Site[] getSortedSites(CompilationResult target) { - List[] lists = new List[]{target.getInfopoints(), target.getDataReferences(), target.getMarks()}; + List[] lists = new List[]{target.getInfopoints(), target.getDataPatches(), target.getMarks()}; int count = 0; for (List list : lists) { count += list.size(); diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,12 +36,12 @@ public final int id; public final long ctask; - public HotSpotCompiledNmethod(TargetDescription target, HotSpotResolvedJavaMethod method, CompilationResult compResult) { - this(target, method, compResult, 0L); + public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) { + this(method, compResult, 0L); } - public HotSpotCompiledNmethod(TargetDescription target, HotSpotResolvedJavaMethod method, CompilationResult compResult, long ctask) { - super(target, compResult); + public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long ctask) { + super(compResult); this.method = method; this.entryBCI = compResult.getEntryBCI(); this.id = compResult.getId(); diff -r cf09e921458f -r c2270ad35f57 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 Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,9 +26,9 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CompilationResult.Call; +import com.oracle.graal.api.code.CompilationResult.ConstantReference; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.code.CompilationResult.Infopoint; -import com.oracle.graal.hotspot.data.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; @@ -41,8 +41,8 @@ public final String stubName; - public HotSpotCompiledRuntimeStub(TargetDescription target, Stub stub, CompilationResult compResult) { - super(target, compResult); + public HotSpotCompiledRuntimeStub(Stub stub, CompilationResult compResult) { + super(compResult); this.stubName = stub.toString(); assert checkStubInvariants(compResult); } @@ -52,17 +52,20 @@ */ private boolean checkStubInvariants(CompilationResult compResult) { assert compResult.getExceptionHandlers().isEmpty(); - for (DataPatch data : compResult.getDataReferences()) { - if (data.data instanceof MetaspaceData) { - MetaspaceData meta = (MetaspaceData) data.data; - if (meta.annotation instanceof HotSpotResolvedObjectType && ((HotSpotResolvedObjectType) meta.annotation).getName().equals("[I")) { - // special handling for NewArrayStub - // embedding the type '[I' is safe, since it is never unloaded - continue; + for (DataPatch data : compResult.getDataPatches()) { + if (data.reference instanceof ConstantReference) { + ConstantReference ref = (ConstantReference) data.reference; + if (ref.getConstant() instanceof HotSpotMetaspaceConstant) { + Object object = HotSpotMetaspaceConstant.getMetaspaceObject(ref.getConstant()); + if (object instanceof HotSpotResolvedObjectType && ((HotSpotResolvedObjectType) object).getName().equals("[I")) { + // special handling for NewArrayStub + // embedding the type '[I' is safe, since it is never unloaded + continue; + } } } - assert !(data.data instanceof PatchedData) : this + " cannot have embedded object or metadata constant: " + data.data; + assert !(data.reference instanceof ConstantReference) : this + " cannot have embedded object or metadata constant: " + data.reference; } for (Infopoint infopoint : compResult.getInfopoints()) { assert infopoint instanceof Call : this + " cannot have non-call infopoint: " + infopoint; diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java Mon Oct 27 13:39:12 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * 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 externalDataList = new ArrayList<>(); - - Map dataMap = new HashMap<>(); - - // 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 { - Integer existingPos = dataMap.get(d); - if (existingPos == null) { - size = NumUtil.roundUp(size, d.getAlignment()); - size += d.getSize(target); - patchCount += PatchedData.getPatchCount(d); - dataMap.put(d, externalDataList.size()); - } - externalDataList.add(dataPatch); - } - } - } - - 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 (int i = 0; i < externalDataList.size(); i++) { - DataPatch dataPatch = externalDataList.get(i); - assert !dataPatch.inline; - Data d = dataPatch.data; - - Integer existingPos = dataMap.get(d); - if (existingPos == i) { - alignment = Math.max(alignment, d.getAlignment()); - index = NumUtil.roundUp(index, d.getAlignment()); - buffer.position(index); - - DataSectionReference reference = new DataSectionReference(index); - - // record patch locations - Iterator it = PatchedData.getPatches(d, index).iterator(); - while (it.hasNext()) { - patches[patchIndex++] = it.next(); - } - - dataPatch.data = reference; - - index += d.getSize(target); - d.emit(target, buffer); - } else { - dataPatch.data = externalDataList.get(existingPos).data; - } - } - - this.sectionAlignment = alignment; - } -} diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSectionReference.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSectionReference.java Mon Oct 27 13:39:12 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * 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) { - } - -} diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java Mon Oct 27 13:39:12 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * 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.compiler.common.*; - -/** - * 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 + "}"; - } -} diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java Mon Oct 27 13:39:12 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * 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.compiler.common.*; -import com.oracle.graal.hotspot.*; - -/** - * 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); - assert !compressed || HotSpotGraalRuntime.runtime().getConfig().useCompressedOops; - this.object = object; - this.compressed = compressed; - } - - @Override - public int getSize(TargetDescription target) { - if (compressed) { - return target.getSizeInBytes(Kind.Int); - } 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) + "]"; - } -} diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/PatchedData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/PatchedData.java Mon Oct 27 13:39:12 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * 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.util.stream.*; - -import com.oracle.graal.api.code.CompilationResult.Data; -import com.oracle.graal.api.code.CompilationResult.DataPatch; - -/** - * Represents a data item that needs to be patched. - */ -public abstract class PatchedData extends Data { - - protected PatchedData(int alignment) { - super(alignment); - } - - public int getPatchCount() { - return 1; - } - - public Stream getPatches(int offset) { - return Stream.of(new DataPatch(offset, this, true)); - } - - public static int getPatchCount(Data data) { - if (data instanceof PatchedData) { - return ((PatchedData) data).getPatchCount(); - } else { - return 0; - } - } - - public static Stream getPatches(Data data, int offset) { - if (data instanceof PatchedData) { - return ((PatchedData) data).getPatches(offset); - } else { - return Stream.empty(); - } - } -} diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -29,18 +29,18 @@ 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.ConstantReference; 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.code.DataSection.Data; +import com.oracle.graal.api.code.DataSection.DataBuilder; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; 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.lir.asm.*; import com.oracle.graal.printer.*; @@ -136,8 +136,8 @@ addOperandComment(hcf, infopoint.pcOffset, "{infopoint: " + infopoint.reason + "}"); } } - for (DataPatch site : compResult.getDataReferences()) { - hcf.addOperandComment(site.pcOffset, "{" + site.data.toString() + "}"); + for (DataPatch site : compResult.getDataPatches()) { + hcf.addOperandComment(site.pcOffset, "{" + site.reference.toString() + "}"); } for (Mark mark : compResult.getMarks()) { hcf.addComment(mark.pcOffset, MarkId.getEnum((int) mark.id).toString()); @@ -209,7 +209,7 @@ compResult.setId(method.allocateCompileId(compResult.getEntryBCI())); } HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), isDefault); - runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, method, compResult, ctask), installedCode, method.getSpeculationLog()); + runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, compResult, ctask), installedCode, method.getSpeculationLog()); return logOrDump(installedCode, compResult); } @@ -224,7 +224,7 @@ HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false); installedCode = code; } - CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, hotspotMethod, compResult), installedCode, log); + CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, compResult), installedCode, log); if (result != CodeInstallResult.OK) { throw new BailoutException(result != CodeInstallResult.DEPENDENCIES_FAILED, "Code installation failed: %s", result); } @@ -243,7 +243,7 @@ compResult.setId(javaMethod.allocateCompileId(compResult.getEntryBCI())); } HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true); - HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(target, javaMethod, compResult); + HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, compResult); CompilerToVM vm = runtime.getCompilerToVM(); CodeInstallResult result = vm.installCode(compiled, code, null); if (result != CodeInstallResult.OK) { @@ -256,16 +256,48 @@ return constant instanceof HotSpotMetaspaceConstant; } - public Data createDataItem(Constant constant, int alignment) { - if (constant instanceof HotSpotMetaspaceConstant) { - // constant.getKind() == target.wordKind for uncompressed pointers - // otherwise, it's a compressed pointer - return new MetaspaceData(alignment, constant.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(constant), constant.getKind() != target.wordKind); - } else if (constant.getKind().isObject()) { - return new OopData(alignment, HotSpotObjectConstant.asObject(constant), false); + public Data createDataItem(Constant constant) { + int size; + DataBuilder builder; + if (constant instanceof VMConstant) { + VMConstant vmConstant = (VMConstant) constant; + boolean compressed; + long raw; + if (vmConstant instanceof HotSpotObjectConstant) { + compressed = HotSpotObjectConstant.isCompressed(constant); + raw = 0xDEADDEADDEADDEADL; + } else if (vmConstant instanceof HotSpotMetaspaceConstant) { + compressed = vmConstant.getKind() != target.wordKind; + raw = vmConstant.asLong(); + } else { + throw GraalInternalError.shouldNotReachHere(); + } + + size = target.getSizeInBytes(compressed ? Kind.Int : target.wordKind); + if (size == 4) { + builder = (buffer, patch) -> { + patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant))); + buffer.putInt((int) raw); + }; + } else { + assert size == 8; + builder = (buffer, patch) -> { + patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant))); + buffer.putLong(raw); + }; + } + } else if (constant.isNull()) { + boolean compressed = HotSpotObjectConstant.isCompressed(constant); + size = target.getSizeInBytes(compressed ? Kind.Int : target.wordKind); + builder = DataBuilder.zero(size); + } else if (constant instanceof PrimitiveConstant) { + size = target.getSizeInBytes(constant.getKind()); + builder = DataBuilder.primitive((PrimitiveConstant) constant); } else { - return new PrimitiveData(constant, alignment); + throw GraalInternalError.shouldNotReachHere(); } + + return new Data(size, size, builder); } @Override diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -166,10 +166,10 @@ assert bits == 32 && kind == Kind.Int; long klassPointer = config().getKlassEncoding().uncompress((int) rawValue); assert klassPointer == runtime.getCompilerToVM().readUnsafeKlassPointer(base); - return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(klassPointer)); + return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(klassPointer), true); } else { assert bits == 64 && kind == Kind.Long; - return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(rawValue)); + return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(rawValue), false); } } else { switch (kind) { diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java Mon Oct 27 14:07:49 2014 +0100 @@ -26,12 +26,12 @@ import com.oracle.graal.api.meta.*; -public final class HotSpotMetaspaceConstant extends PrimitiveConstant implements HotSpotConstant { +public final class HotSpotMetaspaceConstant extends PrimitiveConstant implements HotSpotConstant, VMConstant { private static final long serialVersionUID = 1003463314013122983L; - public static Constant forMetaspaceObject(Kind kind, long primitive, Object metaspaceObject) { - return new HotSpotMetaspaceConstant(kind, primitive, metaspaceObject); + public static Constant forMetaspaceObject(Kind kind, long primitive, Object metaspaceObject, boolean compressed) { + return new HotSpotMetaspaceConstant(kind, primitive, metaspaceObject, compressed); } public static Object getMetaspaceObject(Constant constant) { @@ -39,10 +39,12 @@ } private final Object metaspaceObject; + private final boolean compressed; - private HotSpotMetaspaceConstant(Kind kind, long primitive, Object metaspaceObject) { + private HotSpotMetaspaceConstant(Kind kind, long primitive, Object metaspaceObject, boolean compressed) { super(kind, primitive); this.metaspaceObject = metaspaceObject; + this.compressed = compressed; } @Override @@ -57,6 +59,6 @@ @Override public String toString() { - return super.toString() + "{" + metaspaceObject + "}"; + return super.toString() + "{" + metaspaceObject + (compressed ? ";compressed}" : "}"); } } diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java Mon Oct 27 14:07:49 2014 +0100 @@ -28,7 +28,7 @@ * Represents a constant non-{@code null} object reference, within the compiler and across the * compiler/runtime interface. */ -public final class HotSpotObjectConstant extends AbstractConstant implements HotSpotConstant { +public final class HotSpotObjectConstant extends AbstractConstant implements HotSpotConstant, VMConstant { private static final long serialVersionUID = 3592151693708093496L; diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Oct 27 14:07:49 2014 +0100 @@ -160,7 +160,7 @@ * Gets the address of the C++ Method object for this method. */ public Constant getMetaspaceMethodConstant() { - return HotSpotMetaspaceConstant.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this); + return HotSpotMetaspaceConstant.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this, false); } public long getMetaspaceMethod() { diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -769,7 +769,7 @@ * Gets the metaspace Klass boxed in a {@link Constant}. */ public Constant klass() { - return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, getMetaspaceKlass(), this); + return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, getMetaspaceKlass(), this, false); } public boolean isPrimaryType() { diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -80,7 +80,7 @@ return ((HotSpotObjectConstant) c).compress(); } else if (c instanceof HotSpotMetaspaceConstant) { assert c.getKind() == Kind.Long; - return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, encoding.compress(c.asLong()), HotSpotMetaspaceConstant.getMetaspaceObject(c)); + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, encoding.compress(c.asLong()), HotSpotMetaspaceConstant.getMetaspaceObject(c), true); } else { throw GraalInternalError.shouldNotReachHere("invalid constant input for compress op: " + c); } @@ -93,7 +93,7 @@ return ((HotSpotObjectConstant) c).uncompress(); } else if (c instanceof HotSpotMetaspaceConstant) { assert c.getKind() == Kind.Int; - return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Long, encoding.uncompress(c.asInt()), HotSpotMetaspaceConstant.getMetaspaceObject(c)); + return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Long, encoding.uncompress(c.asInt()), HotSpotMetaspaceConstant.getMetaspaceObject(c), false); } else { throw GraalInternalError.shouldNotReachHere("invalid constant input for uncompress op: " + c); } diff -r cf09e921458f -r c2270ad35f57 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -174,7 +174,7 @@ try (Scope s = Debug.scope("CodeInstall")) { Stub stub = Stub.this; HotSpotRuntimeStub installedCode = new HotSpotRuntimeStub(stub); - HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(backend.getTarget(), stub, compResult); + HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(stub, compResult); CodeInstallResult result = runtime().getCompilerToVM().installCode(hsCompResult, installedCode, null); if (result != CodeInstallResult.OK) { diff -r cf09e921458f -r c2270ad35f57 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 Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import static java.lang.Float.*; import com.oracle.graal.amd64.*; -import com.oracle.graal.api.code.CompilationResult.RawData; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; @@ -333,8 +332,7 @@ @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - RawData rawData = new RawData(data, 16); - masm.leaq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(rawData)); + masm.leaq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(data, 16)); } } diff -r cf09e921458f -r c2270ad35f57 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 Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java Mon Oct 27 14:07:49 2014 +0100 @@ -27,15 +27,45 @@ import static com.oracle.graal.asm.sparc.SPARCAssembler.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import static com.oracle.graal.sparc.SPARC.*; -import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; -import static com.oracle.graal.lir.StandardOp.*; -import com.oracle.graal.api.code.CompilationResult.RawData; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Add; +import com.oracle.graal.asm.sparc.SPARCAssembler.Fmovd; +import com.oracle.graal.asm.sparc.SPARCAssembler.Fmovs; +import com.oracle.graal.asm.sparc.SPARCAssembler.Fzerod; +import com.oracle.graal.asm.sparc.SPARCAssembler.Fzeros; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldf; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsb; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsh; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Lduh; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx; +import com.oracle.graal.asm.sparc.SPARCAssembler.Membar; +import com.oracle.graal.asm.sparc.SPARCAssembler.Movdtox; +import com.oracle.graal.asm.sparc.SPARCAssembler.Movstosw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Movstouw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Movwtos; +import com.oracle.graal.asm.sparc.SPARCAssembler.Movxtod; +import com.oracle.graal.asm.sparc.SPARCAssembler.Or; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stb; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stdf; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stf; +import com.oracle.graal.asm.sparc.SPARCAssembler.Sth; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stw; +import com.oracle.graal.asm.sparc.SPARCAssembler.Stx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cas; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Casx; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Clr; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov; +import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx; import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.StandardOp.ImplicitNullCheck; +import com.oracle.graal.lir.StandardOp.MoveOp; +import com.oracle.graal.lir.StandardOp.NullCheck; import com.oracle.graal.lir.asm.*; import com.oracle.graal.sparc.*; import com.oracle.graal.sparc.SPARC.CPUFeature; @@ -355,8 +385,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - RawData rawData = new RawData(data, 16); - SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(rawData); + SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(data, 16); assert addr == masm.getPlaceholder(); final boolean forceRelocatable = true; Register dstReg = asRegister(result); @@ -818,7 +847,8 @@ delaySlotLir.emitControlTransfer(crb, masm); new Clr(asRegister(result)).emit(masm); } else if (crb.target.inlineObjects) { - crb.recordInlineDataInCode(input); // relocatable cannot be delayed + VMConstant vmConstant = (VMConstant) input; + crb.recordInlineDataInCode(vmConstant); // relocatable cannot be delayed new Setx(0xDEADDEADDEADDEADL, asRegister(result), true).emit(masm); } else { throw GraalInternalError.unimplemented(); diff -r cf09e921458f -r c2270ad35f57 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 Mon Oct 27 13:39:12 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -27,7 +27,10 @@ import java.util.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CompilationResult.Data; +import com.oracle.graal.api.code.CompilationResult.ConstantReference; +import com.oracle.graal.api.code.CompilationResult.DataSectionReference; +import com.oracle.graal.api.code.DataSection.Data; +import com.oracle.graal.api.code.DataSection.DataBuilder; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.compiler.common.*; @@ -77,6 +80,8 @@ private List exceptionInfoList; + private final IdentityHashMap dataCache; + public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, FrameContext frameContext, CompilationResult compilationResult) { this.target = codeCache.getTarget(); this.codeCache = codeCache; @@ -86,6 +91,9 @@ this.compilationResult = compilationResult; this.frameContext = frameContext; assert frameContext != null; + + // constants are already GVNed in the high level graph, so we can use an IdentityHashMap + this.dataCache = new IdentityHashMap<>(); } public void setTotalFrameSize(int frameSize) { @@ -154,27 +162,39 @@ } 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); - compilationResult.recordInlineData(pos, data); + if (data instanceof VMConstant) { + compilationResult.recordDataPatch(pos, new ConstantReference((VMConstant) data)); + } + } + + private AbstractAddress recordDataSectionReference(Data data) { + assert data != null; + DataSectionReference reference = compilationResult.getDataSection().insertData(data); + compilationResult.recordDataPatch(asm.position(), reference); + return asm.getPlaceholder(); } - public AbstractAddress recordDataReferenceInCode(Constant data, int alignment) { - assert data != null; - return recordDataReferenceInCode(codeCache.createDataItem(data, alignment)); + public AbstractAddress recordDataReferenceInCode(Constant constant, int alignment) { + assert constant != null; + Debug.log("Constant reference in code: pos = %d, data = %s", asm.position(), constant); + Data data = dataCache.get(constant); + if (data == null) { + data = codeCache.createDataItem(constant); + dataCache.put(constant, data); + } + data.updateAlignment(alignment); + return recordDataSectionReference(data); } - public AbstractAddress recordDataReferenceInCode(Data data) { + public AbstractAddress recordDataReferenceInCode(byte[] data, int alignment) { assert data != null; - int pos = asm.position(); - Debug.log("Data reference in code: pos = %d, data = %s", pos, data); - compilationResult.recordDataReference(pos, data); - return asm.getPlaceholder(); + if (Debug.isLogEnabled()) { + Debug.log("Data reference in code: pos = %d, data = %s", asm.position(), Arrays.toString(data)); + } + return recordDataSectionReference(new Data(alignment, data.length, DataBuilder.raw(data))); } /** diff -r cf09e921458f -r c2270ad35f57 src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp --- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp Mon Oct 27 13:39:12 2014 -0700 +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp Mon Oct 27 14:07:49 2014 +0100 @@ -40,11 +40,11 @@ } } -void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) { +void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) { address pc = _instructions->start() + pc_offset; - Handle obj = OopData::object(data); + Handle obj = HotSpotObjectConstant::object(constant); jobject value = JNIHandles::make_local(obj()); - if (OopData::compressed(data)) { + if (HotSpotObjectConstant::compressed(constant)) { fatal("unimplemented: narrow oop relocation"); } else { NativeMovConstReg* move = nativeMovConstReg_at(pc); @@ -58,15 +58,14 @@ } } -void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) { +void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) { address pc = _instructions->start() + pc_offset; address const_start = _constants->start(); - jint offset = DataSectionReference::offset(data); - address dest = _constants->start() + offset; + address dest = _constants->start() + data_offset; _instructions->relocate(pc + NativeMovConstReg::sethi_offset, internal_word_Relocation::spec((address) dest)); _instructions->relocate(pc + NativeMovConstReg::add_offset, internal_word_Relocation::spec((address) dest)); - TRACE_graal_3("relocating at %p with destination at %p (%d)", pc, dest, offset); + TRACE_graal_3("relocating at %p with destination at %p (%d)", pc, dest, data_offset); } void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) { diff -r cf09e921458f -r c2270ad35f57 src/cpu/x86/vm/graalCodeInstaller_x86.cpp --- a/src/cpu/x86/vm/graalCodeInstaller_x86.cpp Mon Oct 27 13:39:12 2014 -0700 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.cpp Mon Oct 27 14:07:49 2014 +0100 @@ -58,11 +58,11 @@ } } -void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) { +void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) { address pc = _instructions->start() + pc_offset; - Handle obj = OopData::object(data); + Handle obj = HotSpotObjectConstant::object(constant); jobject value = JNIHandles::make_local(obj()); - if (OopData::compressed(data)) { + if (HotSpotObjectConstant::compressed(constant)) { 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); @@ -75,20 +75,19 @@ } } -void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) { +void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) { address pc = _instructions->start() + pc_offset; - jint offset = DataSectionReference::offset(data); address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); address next_instruction = Assembler::locate_next_instruction(pc); - address dest = _constants->start() + offset; + address dest = _constants->start() + data_offset; 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); + TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, data_offset); } void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) { diff -r cf09e921458f -r c2270ad35f57 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Mon Oct 27 13:39:12 2014 -0700 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Oct 27 14:07:49 2014 +0100 @@ -195,10 +195,6 @@ GRAAL_ONLY(do_klass(HotSpotCompiledRuntimeStub_klass, com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub, Graal)) \ GRAAL_ONLY(do_klass(HotSpotForeignCallLinkage_klass, com_oracle_graal_hotspot_HotSpotForeignCallLinkage, Graal)) \ GRAAL_ONLY(do_klass(HotSpotReferenceMap_klass, com_oracle_graal_hotspot_HotSpotReferenceMap, Graal)) \ - GRAAL_ONLY(do_klass(DataSection_klass, com_oracle_graal_hotspot_data_DataSection, Graal)) \ - GRAAL_ONLY(do_klass(DataSectionReference_klass, com_oracle_graal_hotspot_data_DataSectionReference, Graal)) \ - GRAAL_ONLY(do_klass(MetaspaceData_klass, com_oracle_graal_hotspot_data_MetaspaceData, Graal)) \ - GRAAL_ONLY(do_klass(OopData_klass, com_oracle_graal_hotspot_data_OopData, Graal)) \ GRAAL_ONLY(do_klass(HotSpotInstalledCode_klass, com_oracle_graal_hotspot_meta_HotSpotInstalledCode, Graal)) \ GRAAL_ONLY(do_klass(HotSpotNmethod_klass, com_oracle_graal_hotspot_meta_HotSpotNmethod, Graal)) \ GRAAL_ONLY(do_klass(HotSpotResolvedJavaMethod_klass, com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, Graal)) \ @@ -221,7 +217,9 @@ GRAAL_ONLY(do_klass(BytecodeFrame_klass, com_oracle_graal_api_code_BytecodeFrame, Graal)) \ GRAAL_ONLY(do_klass(CompilationResult_klass, com_oracle_graal_api_code_CompilationResult, Graal)) \ GRAAL_ONLY(do_klass(CompilationResult_Call_klass, com_oracle_graal_api_code_CompilationResult_Call, Graal)) \ + GRAAL_ONLY(do_klass(CompilationResult_ConstantReference_klass, com_oracle_graal_api_code_CompilationResult_ConstantReference, Graal)) \ GRAAL_ONLY(do_klass(CompilationResult_DataPatch_klass, com_oracle_graal_api_code_CompilationResult_DataPatch, Graal)) \ + GRAAL_ONLY(do_klass(CompilationResult_DataSectionReference_klass, com_oracle_graal_api_code_CompilationResult_DataSectionReference, Graal)) \ GRAAL_ONLY(do_klass(CompilationResult_ExceptionHandler_klass, com_oracle_graal_api_code_CompilationResult_ExceptionHandler, Graal))\ GRAAL_ONLY(do_klass(CompilationResult_Mark_klass, com_oracle_graal_api_code_CompilationResult_Mark, Graal)) \ GRAAL_ONLY(do_klass(CompilationResult_Infopoint_klass, com_oracle_graal_api_code_CompilationResult_Infopoint, Graal)) \ diff -r cf09e921458f -r c2270ad35f57 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon Oct 27 13:39:12 2014 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -302,10 +302,6 @@ GRAAL_ONLY(template(com_oracle_graal_hotspot_HotSpotForeignCallLinkage, "com/oracle/graal/hotspot/HotSpotForeignCallLinkage")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_HotSpotReferenceMap, "com/oracle/graal/hotspot/HotSpotReferenceMap")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_bridge_CompilerToVMImpl, "com/oracle/graal/hotspot/bridge/CompilerToVMImpl")) \ - GRAAL_ONLY(template(com_oracle_graal_hotspot_data_DataSection, "com/oracle/graal/hotspot/data/DataSection")) \ - GRAAL_ONLY(template(com_oracle_graal_hotspot_data_DataSectionReference, "com/oracle/graal/hotspot/data/DataSectionReference")) \ - GRAAL_ONLY(template(com_oracle_graal_hotspot_data_MetaspaceData, "com/oracle/graal/hotspot/data/MetaspaceData")) \ - GRAAL_ONLY(template(com_oracle_graal_hotspot_data_OopData, "com/oracle/graal/hotspot/data/OopData")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode, "com/oracle/graal/hotspot/meta/HotSpotInstalledCode")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotNmethod, "com/oracle/graal/hotspot/meta/HotSpotNmethod")) \ GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod, "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod")) \ @@ -335,7 +331,9 @@ GRAAL_ONLY(template(com_oracle_graal_api_code_Assumptions_CallSiteTargetValue,"com/oracle/graal/api/code/Assumptions$CallSiteTargetValue")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult, "com/oracle/graal/api/code/CompilationResult")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_Call, "com/oracle/graal/api/code/CompilationResult$Call")) \ + GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_ConstantReference, "com/oracle/graal/api/code/CompilationResult$ConstantReference")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_DataPatch, "com/oracle/graal/api/code/CompilationResult$DataPatch")) \ + GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_DataSectionReference, "com/oracle/graal/api/code/CompilationResult$DataSectionReference")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_ExceptionHandler, "com/oracle/graal/api/code/CompilationResult$ExceptionHandler")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_Mark, "com/oracle/graal/api/code/CompilationResult$Mark")) \ GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_Infopoint, "com/oracle/graal/api/code/CompilationResult$Infopoint")) \ diff -r cf09e921458f -r c2270ad35f57 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Mon Oct 27 13:39:12 2014 -0700 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Mon Oct 27 14:07:49 2014 +0100 @@ -199,8 +199,8 @@ } } -static void record_metadata_in_patch(oop data, OopRecorder* oop_recorder) { - record_metadata_reference(MetaspaceData::annotation(data), MetaspaceData::value(data), MetaspaceData::compressed(data) != 0, oop_recorder); +static void record_metadata_in_patch(Handle& constant, OopRecorder* oop_recorder) { + record_metadata_reference(HotSpotMetaspaceConstant::metaspaceObject(constant), HotSpotMetaspaceConstant::primitive(constant), HotSpotMetaspaceConstant::compressed(constant), oop_recorder); } ScopeValue* CodeInstaller::get_scope_value(oop value, int total_frame_size, GrowableArray* objects, ScopeValue* &second, OopRecorder* oop_recorder) { @@ -498,13 +498,14 @@ // Pre-calculate the constants section size. This is required for PC-relative addressing. _data_section_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSection(compiled_code)); - guarantee(DataSection::sectionAlignment(data_section()) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); - typeArrayHandle data = DataSection::data(data_section()); - _constants_size = data->length(); + guarantee(HotSpotCompiledCode::dataSectionAlignment(compiled_code) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); + _constants_size = data_section()->length(); if (_constants_size > 0) { _constants_size = align_size_up(_constants_size, _constants->alignment()); } + _data_section_patches_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSectionPatches(compiled_code)); + #ifndef PRODUCT _comments_handle = JNIHandles::make_local(HotSpotCompiledCode::comments(compiled_code)); #endif @@ -556,30 +557,33 @@ if (!_instructions->allocates2(end_pc)) { return false; } - memcpy(_instructions->start(), code()->base(T_BYTE), _code_size); + memcpy(_instructions->start(), code()->base(T_BYTE), code()->length()); _instructions->set_end(end_pc); // copy the constant data into the newly created CodeBuffer address end_data = _constants->start() + _constants_size; - typeArrayHandle data(DataSection::data(data_section())); - memcpy(_constants->start(), data->base(T_BYTE), data->length()); + memcpy(_constants->start(), data_section()->base(T_BYTE), _constants_size); _constants->set_end(end_data); - objArrayHandle patches = DataSection::patches(data_section()); - for (int i = 0; i < patches->length(); i++) { - Handle patch = patches->obj_at(i); - Handle 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); + for (int i = 0; i < data_section_patches()->length(); i++) { + Handle patch = data_section_patches()->obj_at(i); + Handle reference = CompilationResult_DataPatch::reference(patch); + assert(reference->is_a(CompilationResult_ConstantReference::klass()), err_msg("patch in data section must be a ConstantReference")); + Handle constant = CompilationResult_ConstantReference::constant(reference); + if (constant->is_a(HotSpotMetaspaceConstant::klass())) { + record_metadata_in_patch(constant, _oop_recorder); + } else if (constant->is_a(HotSpotObjectConstant::klass())) { + Handle obj = HotSpotObjectConstant::object(constant); jobject value = JNIHandles::make_local(obj()); int oop_index = _oop_recorder->find_index(value); 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)); + if (HotSpotObjectConstant::compressed(constant)) { + fatal("unexpected compressed oop in data section"); + } else { + _constants->relocate(dest, oop_Relocation::spec(oop_index)); + } } else { ShouldNotReachHere(); } @@ -898,13 +902,20 @@ } void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { - 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); + oop reference = CompilationResult_DataPatch::reference(site); + if (reference->is_a(CompilationResult_ConstantReference::klass())) { + Handle constant = CompilationResult_ConstantReference::constant(reference); + if (constant->is_a(HotSpotObjectConstant::klass())) { + pd_patch_OopConstant(pc_offset, constant); + } else if (constant->is_a(HotSpotMetaspaceConstant::klass())) { + record_metadata_in_patch(constant, _oop_recorder); + } else { + fatal("unknown constant type in data patch"); + } + } else if (reference->is_a(CompilationResult_DataSectionReference::klass())) { + int data_offset = CompilationResult_DataSectionReference::offset(reference); + assert(0 <= data_offset && data_offset < _constants_size, err_msg("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size)); + pd_patch_DataSectionReference(pc_offset, data_offset); } else { fatal("unknown data patch type"); } diff -r cf09e921458f -r c2270ad35f57 src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Mon Oct 27 13:39:12 2014 -0700 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Mon Oct 27 14:07:49 2014 +0100 @@ -53,6 +53,7 @@ Arena _arena; jobject _data_section_handle; + jobject _data_section_patches_handle; jobject _sites_handle; jobject _exception_handlers_handle; CodeOffsets _offsets; @@ -86,8 +87,8 @@ static LocationValue* _illegal_value; jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method); - void pd_patch_OopData(int pc_offset, oop data); - void pd_patch_DataSectionReference(int pc_offset, oop data); + void pd_patch_OopConstant(int pc_offset, Handle& constant); + void pd_patch_DataSectionReference(int pc_offset, int data_offset); 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); @@ -96,6 +97,7 @@ objArrayOop sites() { return (objArrayOop) JNIHandles::resolve(_sites_handle); } arrayOop code() { return (arrayOop) JNIHandles::resolve(_code_handle); } arrayOop data_section() { return (arrayOop) JNIHandles::resolve(_data_section_handle); } + objArrayOop data_section_patches() { return (objArrayOop) JNIHandles::resolve(_data_section_patches_handle); } objArrayOop exception_handlers() { return (objArrayOop) JNIHandles::resolve(_exception_handlers_handle); } #ifndef PRODUCT objArrayOop comments() { return (objArrayOop) JNIHandles::resolve(_comments_handle); } diff -r cf09e921458f -r c2270ad35f57 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Mon Oct 27 13:39:12 2014 -0700 +++ b/src/share/vm/graal/graalJavaAccess.hpp Mon Oct 27 14:07:49 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,7 +73,9 @@ objArrayOop_field(HotSpotCompiledCode, sites, "[Lcom/oracle/graal/api/code/CompilationResult$Site;") \ objArrayOop_field(HotSpotCompiledCode, exceptionHandlers, "[Lcom/oracle/graal/api/code/CompilationResult$ExceptionHandler;") \ objArrayOop_field(HotSpotCompiledCode, comments, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$Comment;") \ - oop_field(HotSpotCompiledCode, dataSection, "Lcom/oracle/graal/hotspot/data/DataSection;") \ + typeArrayOop_field(HotSpotCompiledCode, dataSection, "[B") \ + int_field(HotSpotCompiledCode, dataSectionAlignment) \ + objArrayOop_field(HotSpotCompiledCode, dataSectionPatches, "[Lcom/oracle/graal/api/code/CompilationResult$DataPatch;") \ end_class \ start_class(HotSpotCompiledCode_Comment) \ oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;") \ @@ -91,23 +93,6 @@ start_class(HotSpotForeignCallLinkage) \ long_field(HotSpotForeignCallLinkage, address) \ end_class \ - start_class(DataSection) \ - int_field(DataSection, sectionAlignment) \ - typeArrayOop_field(DataSection, data, "[B") \ - objArrayOop_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 \ @@ -148,7 +133,13 @@ oop_field(CompilationResult_Call, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;") \ end_class \ start_class(CompilationResult_DataPatch) \ - oop_field(CompilationResult_DataPatch, data, "Lcom/oracle/graal/api/code/CompilationResult$Data;") \ + oop_field(CompilationResult_DataPatch, reference, "Lcom/oracle/graal/api/code/CompilationResult$Reference;") \ + end_class \ + start_class(CompilationResult_ConstantReference) \ + oop_field(CompilationResult_ConstantReference, constant, "Lcom/oracle/graal/api/meta/VMConstant;") \ + end_class \ + start_class(CompilationResult_DataSectionReference) \ + int_field(CompilationResult_DataSectionReference, offset) \ end_class \ start_class(InfopointReason) \ static_oop_field(InfopointReason, UNKNOWN, "Lcom/oracle/graal/api/code/InfopointReason;") \ @@ -214,10 +205,12 @@ end_class \ start_class(HotSpotObjectConstant) \ oop_field(HotSpotObjectConstant, object, "Ljava/lang/Object;") \ + boolean_field(HotSpotObjectConstant, compressed) \ end_class \ start_class(HotSpotMetaspaceConstant) \ long_field(HotSpotMetaspaceConstant, primitive) \ oop_field(HotSpotMetaspaceConstant, metaspaceObject, "Ljava/lang/Object;") \ + boolean_field(HotSpotMetaspaceConstant, compressed) \ end_class \ start_class(Kind) \ char_field(Kind, typeChar) \