# HG changeset patch # User Doug Simon # Date 1335809720 -7200 # Node ID a53162ca82195ac649cf3a51e25feaa96035d62f # Parent f8ea2735ec4fc32585b0778e02c816b6a478ede9 introduced HotSpotKlassOop type to convey a klassOop value from the compiler to the C++ code instead of relying on the C++ code automagically converting a HotSpotTypeResolvedImpl value to a klassOop diff -r f8ea2735ec4f -r a53162ca8219 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotKlassOop.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotKlassOop.java Mon Apr 30 20:15:20 2012 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012, 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.ri; + +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.Compiler; + +/** + * A mechanism for safely conveying a HotSpot klassOop value from the compiler to the C++ code. + * Such values should not be directly exposed to Java code as they are not real Java + * objects. For instance, invoking a method on them or using them in an instanceof + * expression will most likely crash the VM. + */ +public class HotSpotKlassOop extends CompilerObject { + + private static final long serialVersionUID = -5445542223575839143L; + + /** + * The Java object from which the klassOop value can be derived (by the C++ code). + */ + public final Class javaMirror; + + HotSpotKlassOop(Compiler compiler, Class javaMirror) { + super(compiler); + this.javaMirror = javaMirror; + } +} diff -r f8ea2735ec4f -r a53162ca8219 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotType.java Mon Apr 30 15:41:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotType.java Mon Apr 30 20:15:20 2012 +0200 @@ -41,4 +41,10 @@ public final String name() { return name; } + + /** + * Gets the object representing the C++ klassOop for this type. + * Such a value cannot be safely exposed to Java code. + */ + public abstract HotSpotKlassOop klassOop(); } diff -r f8ea2735ec4f -r a53162ca8219 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypePrimitive.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypePrimitive.java Mon Apr 30 15:41:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypePrimitive.java Mon Apr 30 20:15:20 2012 +0200 @@ -37,12 +37,13 @@ private static final long serialVersionUID = -6208552348908071473L; private CiKind kind; - + private final HotSpotKlassOop klassOop; public HotSpotTypePrimitive(Compiler compiler, CiKind kind) { super(compiler); this.kind = kind; this.name = String.valueOf(Character.toUpperCase(kind.typeChar)); + this.klassOop = new HotSpotKlassOop(compiler, kind.toJavaClass()); } @Override @@ -175,4 +176,9 @@ public RiResolvedType resolve(RiResolvedType accessingClass) { return this; } + + @Override + public HotSpotKlassOop klassOop() { + return klassOop; + } } diff -r f8ea2735ec4f -r a53162ca8219 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolved.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolved.java Mon Apr 30 15:41:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolved.java Mon Apr 30 20:15:20 2012 +0200 @@ -35,4 +35,5 @@ RiField createRiField(String name, RiType type, int offset, int flags); + HotSpotKlassOop klassOop(); } diff -r f8ea2735ec4f -r a53162ca8219 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolvedImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolvedImpl.java Mon Apr 30 15:41:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeResolvedImpl.java Mon Apr 30 20:15:20 2012 +0200 @@ -118,11 +118,9 @@ case JavaClass: return CiConstant.forObject(javaMirror); case ObjectHub: - return CiConstant.forObject(this); + return CiConstant.forObject(klassOop()); case StaticFields: return CiConstant.forObject(javaMirror); - case TypeInfo: - return CiConstant.forObject(this); default: return null; } @@ -220,7 +218,7 @@ long id = offset + ((long) flags << 32); - // (thomaswue) Must cache the fields, because the local load elimination only works if the objects from two field lookups are equal. + // (thomaswue) Must cache the fields, because the local load elimination only works if the objects from two field lookups are identical. if (fieldCache == null) { fieldCache = new HashMap<>(8); } else { @@ -265,4 +263,15 @@ public RiResolvedType resolve(RiResolvedType accessingClass) { return this; } + + // (dnsimon) this value may require identity semantics + private HotSpotKlassOop klassOopCache; + + @Override + public synchronized HotSpotKlassOop klassOop() { + if (klassOopCache == null) { + klassOopCache = new HotSpotKlassOop(compiler, javaMirror); + } + return klassOopCache; + } } diff -r f8ea2735ec4f -r a53162ca8219 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeUnresolved.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeUnresolved.java Mon Apr 30 15:41:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotTypeUnresolved.java Mon Apr 30 20:15:20 2012 +0200 @@ -24,6 +24,7 @@ import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; +import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.Compiler; /** @@ -119,4 +120,9 @@ public RiResolvedType resolve(RiResolvedType accessingClass) { return (RiResolvedType) compiler.lookupType(name, (HotSpotTypeResolved) accessingClass, true); } + + @Override + public HotSpotKlassOop klassOop() { + throw GraalInternalError.shouldNotReachHere("HotSpotTypeUnresolved.klassOop"); + } } diff -r f8ea2735ec4f -r a53162ca8219 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java Mon Apr 30 15:41:14 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java Mon Apr 30 20:15:20 2012 +0200 @@ -288,7 +288,7 @@ @Override protected XirTemplate create(CiXirAssembler asm, long flags, int size) { XirOperand result = asm.restart(target.wordKind); - XirOperand type = asm.createInputParameter("type", CiKind.Object); + XirOperand hub = asm.createInputParameter("hub", CiKind.Object); XirOperand temp1 = asm.createRegisterTemp("temp1", target.wordKind, AMD64.rcx); XirOperand temp1o = asm.createRegister("temp1o", CiKind.Object, AMD64.rcx); @@ -299,7 +299,7 @@ XirLabel resume = asm.createInlineLabel("resume"); // check if the class is already initialized - asm.pload(CiKind.Int, temp2i, type, asm.i(config.klassStateOffset), false); + asm.pload(CiKind.Int, temp2i, hub, asm.i(config.klassStateOffset), false); asm.jneq(tlabFull, temp2i, asm.i(config.klassStateFullyInitialized)); XirOperand thread = asm.createRegisterTemp("thread", target.wordKind, AMD64.r15); @@ -312,9 +312,9 @@ asm.bindInline(resume); - asm.pload(target.wordKind, temp1, type, asm.i(config.instanceHeaderPrototypeOffset), false); + asm.pload(target.wordKind, temp1, hub, asm.i(config.instanceHeaderPrototypeOffset), false); asm.pstore(target.wordKind, result, temp1, false); - asm.mov(temp1o, type); // need a temporary register since Intel cannot store 64-bit constants to memory + asm.mov(temp1o, hub); // need a temporary register since Intel cannot store 64-bit constants to memory asm.pstore(CiKind.Object, result, asm.i(config.hubOffset), temp1o, false); if (size > 2 * target.wordSize) { @@ -327,7 +327,7 @@ // -- out of line ------------------------------------------------------- asm.bindOutOfLine(tlabFull); XirOperand arg = asm.createRegisterTemp("runtime call argument", CiKind.Object, AMD64.rdx); - asm.mov(arg, type); + asm.mov(arg, hub); useRegisters(asm, AMD64.rax); asm.callRuntime(config.newInstanceStub, result); asm.jmp(resume); @@ -871,26 +871,27 @@ @Override public XirSnippet genNewInstance(XirSite site, RiType type) { - int instanceSize = ((HotSpotTypeResolved) type).instanceSize(); - return new XirSnippet(newInstanceTemplates.get(site, instanceSize), XirArgument.forObject(type)); + HotSpotTypeResolved resolvedType = (HotSpotTypeResolved) type; + int instanceSize = resolvedType.instanceSize(); + return new XirSnippet(newInstanceTemplates.get(site, instanceSize), XirArgument.forObject(resolvedType.klassOop())); } @Override public XirSnippet genNewArray(XirSite site, XirArgument length, CiKind elementKind, RiType componentType, RiType arrayType) { if (elementKind == CiKind.Object) { assert arrayType instanceof RiResolvedType; - return new XirSnippet(newObjectArrayTemplates.get(site), length, XirArgument.forObject(arrayType)); + return new XirSnippet(newObjectArrayTemplates.get(site), length, XirArgument.forObject(((HotSpotType) arrayType).klassOop())); } else { assert arrayType == null; RiType primitiveArrayType = compiler.getCompilerToVM().getPrimitiveArrayType(elementKind); - return new XirSnippet(newTypeArrayTemplates.get(site, elementKind), length, XirArgument.forObject(primitiveArrayType)); + return new XirSnippet(newTypeArrayTemplates.get(site, elementKind), length, XirArgument.forObject(((HotSpotType) primitiveArrayType).klassOop())); } } @Override public XirSnippet genNewMultiArray(XirSite site, XirArgument[] lengths, RiType type) { XirArgument[] params = Arrays.copyOf(lengths, lengths.length + 1); - params[lengths.length] = XirArgument.forObject(type); + params[lengths.length] = XirArgument.forObject(((HotSpotType) type).klassOop()); return new XirSnippet(multiNewArrayTemplate.get(site, lengths.length), params); } @@ -906,9 +907,7 @@ params[i++] = hub; } for (RiResolvedType hint : hints) { - // The Graal C++ code auto-magically converts HotSpotTypeResolvedImpl into the corresponding klassOop. - // See CodeInstaller::site_DataPatch in graalCodeInstaller.cpp. - params[i++] = XirArgument.forObject(hint); + params[i++] = XirArgument.forObject(((HotSpotType) hint).klassOop()); } XirTemplate template = hintsExact ? checkCastTemplates.get(site, hints.length, EXACT_HINTS) : checkCastTemplates.get(site, hints.length); return new XirSnippet(template, params); @@ -927,9 +926,7 @@ params[i++] = hub; } for (RiResolvedType hint : hints) { - // The Graal C++ code auto-magically converts HotSpotTypeResolvedImpl into the corresponding klassOop. - // See CodeInstaller::site_DataPatch in graalCodeInstaller.cpp. - params[i++] = XirArgument.forObject(hint); + params[i++] = XirArgument.forObject(((HotSpotType) hint).klassOop()); } XirTemplate template = hintsExact ? instanceOfTemplates.get(site, hints.length, EXACT_HINTS) : instanceOfTemplates.get(site, hints.length); return new XirSnippet(template, params); @@ -950,9 +947,7 @@ params[i++] = trueValue; params[i++] = falseValue; for (RiResolvedType hint : hints) { - // The Graal C++ code auto-magically converts HotSpotTypeResolvedImpl into the corresponding klassOop. - // See CodeInstaller::site_DataPatch in graalCodeInstaller.cpp. - params[i++] = XirArgument.forObject(hint); + params[i++] = XirArgument.forObject(((HotSpotType) hint).klassOop()); } XirTemplate template = hintsExact ? materializeInstanceOfTemplates.get(site, hints.length, EXACT_HINTS) : materializeInstanceOfTemplates.get(site, hints.length); return new XirSnippet(template, params); diff -r f8ea2735ec4f -r a53162ca8219 graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiType.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiType.java Mon Apr 30 15:41:14 2012 +0200 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiType.java Mon Apr 30 20:15:20 2012 +0200 @@ -50,13 +50,7 @@ * The runtime representation of the "hub" of this type--that is, the closest part of the type * representation which is typically stored in the object header. */ - ObjectHub, - - /** - * The runtime representation of the type information for an object, which is typically used - * for subtype tests. - */ - TypeInfo + ObjectHub } /** diff -r f8ea2735ec4f -r a53162ca8219 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Mon Apr 30 15:41:14 2012 +0200 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Apr 30 20:15:20 2012 +0200 @@ -189,6 +189,7 @@ \ /* Support for Graal */ \ template(HotSpotTypeResolved_klass, com_oracle_graal_hotspot_HotSpotTypeResolved, Opt) \ + template(HotSpotKlassOop_klass, com_oracle_graal_hotspot_HotSpotKlassOop, Opt) \ template(HotSpotType_klass, com_oracle_graal_hotspot_HotSpotType, Opt) \ template(HotSpotField_klass, com_oracle_graal_hotspot_HotSpotField, Opt) \ template(HotSpotCompiledMethod_klass, com_oracle_graal_hotspot_HotSpotCompiledMethod, Opt) \ diff -r f8ea2735ec4f -r a53162ca8219 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Mon Apr 30 15:41:14 2012 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Apr 30 20:15:20 2012 +0200 @@ -279,6 +279,7 @@ template(com_oracle_graal_hotspot_HotSpotOptions, "com/oracle/graal/hotspot/HotSpotOptions") \ template(com_oracle_graal_hotspot_HotSpotTypeResolved, "com/oracle/graal/hotspot/ri/HotSpotTypeResolvedImpl") \ template(com_oracle_graal_hotspot_HotSpotType, "com/oracle/graal/hotspot/ri/HotSpotType") \ + template(com_oracle_graal_hotspot_HotSpotKlassOop, "com/oracle/graal/hotspot/ri/HotSpotKlassOop") \ template(com_oracle_graal_hotspot_HotSpotExceptionHandler, "com/oracle/graal/hotspot/ri/HotSpotExceptionHandler") \ template(com_oracle_graal_hotspot_HotSpotProxy, "com/oracle/graal/hotspot/HotSpotProxy") \ template(com_oracle_graal_hotspot_Compiler, "com/oracle/graal/hotspot/Compiler") \ diff -r f8ea2735ec4f -r a53162ca8219 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Mon Apr 30 15:41:14 2012 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Mon Apr 30 20:15:20 2012 +0200 @@ -743,8 +743,7 @@ case 's': case 'c': case 'i': - fatal("int-sized values not expected in DataPatch") - ; + fatal("int-sized values not expected in DataPatch"); break; case 'f': case 'j': @@ -773,9 +772,9 @@ address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); Handle obj = CiConstant::object(constant); - if (obj->is_a(HotSpotTypeResolved::klass())) { + if (obj->is_a(HotSpotKlassOop::klass())) { assert(!obj.is_null(), ""); - *((jobject*) operand) = JNIHandles::make_local(java_lang_Class::as_klassOop(HotSpotTypeResolved::javaMirror(obj))); + *((jobject*) operand) = JNIHandles::make_local(java_lang_Class::as_klassOop(HotSpotKlassOop::javaMirror(obj))); _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); TRACE_graal_3("relocating (HotSpotType) at %016x/%016x", instruction, operand); } else { diff -r f8ea2735ec4f -r a53162ca8219 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Mon Apr 30 15:41:14 2012 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Mon Apr 30 20:15:20 2012 +0200 @@ -58,6 +58,9 @@ boolean_field(HotSpotTypeResolved, isInterface) \ int_field(HotSpotTypeResolved, instanceSize) \ end_class \ + start_class(HotSpotKlassOop) \ + oop_field(HotSpotKlassOop, javaMirror, "Ljava/lang/Class;") \ + end_class \ start_class(HotSpotMethodResolved) \ oop_field(HotSpotMethodResolved, compiler, "Lcom/oracle/graal/hotspot/Compiler;") \ oop_field(HotSpotMethodResolved, name, "Ljava/lang/String;") \