# HG changeset patch # User Thomas Wuerthinger # Date 1303914332 -7200 # Node ID f6125fb5bfbc6d4def6f1b18d04cccef4c76c004 # Parent a384fac3fd343b0f63a889bae63afeb4518347a6 Removed intrinsics. diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/C1XIntrinsic.java --- a/graal/GraalCompiler/src/com/sun/c1x/C1XIntrinsic.java Wed Apr 27 15:49:27 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2009, 2011, 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.sun.c1x; - -import java.util.*; - -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * This enum represents all of the intrinsics, i.e. a library methods that - * are treated specially by the compiler. Note that the list includes more intrinsics - * than are currently handled by C1X. - * - * @author Ben L. Titzer - */ -public enum C1XIntrinsic { - - // java.lang.Object - java_lang_Object$init ("java.lang.Object", "", "()V"), - java_lang_Object$hashCode ("java.lang.Object", "hashCode", "()I"), - java_lang_Object$getClass ("java.lang.Object", "getClass", "()Ljava/lang/Class;"), - java_lang_Object$clone ("java.lang.Object", "clone", "()Ljava/lang/Object;"), - - // java.lang.Class - java_lang_Class$isAssignableFrom ("java.lang.Class", "isAssignableFrom", "(Ljava/lang/Class;)Z"), - java_lang_Class$isInstance ("java.lang.Class", "isInstance", "(Ljava/lang/Object;)Z"), - java_lang_Class$getModifiers ("java.lang.Class", "getModifiers", "()I"), - java_lang_Class$isInterface ("java.lang.Class", "isInterface", "()Z"), - java_lang_Class$isArray ("java.lang.Class", "isArray", "()Z"), - java_lang_Class$isPrimitive ("java.lang.Class", "isPrimitive", "()Z"), - java_lang_Class$getSuperclass ("java.lang.Class", "getSuperclass", "()Ljava/lang/Class;"), - java_lang_Class$getComponentType ("java.lang.Class", "getComponentType", "()Ljava/lang/Class;"), - - // java.util.Arrays - java_util_Arrays$copyOf ("java.util.Arrays", "copyOf", "([Ljava/lang/Object;I)[Ljava/lang/Object;"), - - // java.lang.String - java_lang_String$compareTo ("java.lang.String", "compareTo", "(Ljava/lang/String;)I"), - java_lang_String$indexOf ("java.lang.String", "indexOf", "(Ljava/lang/String;)I"), - java_lang_String$equals ("java.lang.String", "equals", "(Ljava/lang/Object;)Z"), - - // java.lang.Math - java_lang_Math$abs ("java.lang.Math", "abs", "(D)D"), - java_lang_Math$sin ("java.lang.Math", "sin", "(D)D"), - java_lang_Math$cos ("java.lang.Math", "cos", "(D)D"), - java_lang_Math$tan ("java.lang.Math", "tan", "(D)D"), - java_lang_Math$atan2 ("java.lang.Math", "atan2", "(DD)D"), - java_lang_Math$sqrt ("java.lang.Math", "sqrt", "(D)D"), - java_lang_Math$log ("java.lang.Math", "log", "(D)D"), - java_lang_Math$log10 ("java.lang.Math", "log10", "(D)D"), - java_lang_Math$pow ("java.lang.Math", "pow", "(DD)D"), - java_lang_Math$exp ("java.lang.Math", "exp", "(D)D"), - java_lang_Math$min ("java.lang.Math", "min", "(II)I"), - java_lang_Math$max ("java.lang.Math", "max", "(II)I"), - - // java.lang.Float - java_lang_Float$floatToRawIntBits ("java.lang.Float", "floatToRawIntBits", "(F)I"), - java_lang_Float$floatToIntBits ("java.lang.Float", "floatToIntBits", "(F)I"), - java_lang_Float$intBitsToFloat ("java.lang.Float", "intBitsToFloat", "(I)F"), - - // java.lang.Double - java_lang_Double$doubleToRawLongBits ("java.lang.Double", "doubleToRawLongBits", "(D)J"), - java_lang_Double$doubleToLongBits ("java.lang.Double", "doubleToLongBits", "(D)J"), - java_lang_Double$longBitsToDouble ("java.lang.Double", "longBitsToDouble", "(J)D"), - - // java.lang.Integer - java_lang_Integer$bitCount ("java.lang.Integer", "bitCount", "(I)I"), - java_lang_Integer$reverseBytes ("java.lang.Integer", "reverseBytes", "(I)I"), - - // java.lang.Long - java_lang_Long$bitCount ("java.lang.Long", "bitCount", "(J)I"), - java_lang_Long$reverseBytes ("java.lang.Long", "reverseBytes", "(J)J"), - - // java.lang.System - java_lang_System$identityHashCode ("java.lang.System", "identityHashCode", "(Ljava/lang/Object;)I"), - java_lang_System$currentTimeMillis ("java.lang.System", "currentTimeMillis", "()J"), - java_lang_System$nanoTime ("java.lang.System", "nanoTime", "()J"), - java_lang_System$arraycopy ("java.lang.System", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V"), - - // java.lang.Thread - java_lang_Thread$currentThread ("java.lang.Thread", "currentThread", "()Ljava/lang/Thread;"), - - // java.lang.reflect.Array - java_lang_reflect_Array$getLength ("java.lang.reflect.Array", "getLength", "(Ljava/lang/Object;)I"), - java_lang_reflect_Array$newArray ("java.lang.reflect.Array", "newArray", "(Ljava/lang/Class;I)Ljava/lang/Object;"), - - // java.nio.Buffer - java_nio_Buffer$checkIndex ("java.nio.Buffer", "checkIndex", "(I)I"), - - // sun.misc.Unsafe - sun_misc_Unsafe$compareAndSwapObject ("sun.misc.Unsafe", "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z"), - sun_misc_Unsafe$compareAndSwapLong ("sun.misc.Unsafe", "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z"), - sun_misc_Unsafe$compareAndSwapInt ("sun.misc.Unsafe", "compareAndSwapInt", "(Ljava/lang/Object;JII)Z"); - - private static final HashMap> intrinsicMap = new HashMap>(100); - - /** - * The name of the class in which this method is declared. - */ - public final String className; - - /** - * The name of this intrinsic method. - */ - public final String methodName; - - /** - * The signature of this intrinsic method as a string. - */ - public final String signature; - - C1XIntrinsic(String className, String methodName, String signature) { - // Check that enum names are according to convention. - assert className.equals(name().substring(0, name().indexOf('$')).replace('_', '.')); - assert methodName.equals("") || methodName.equals(name().substring(name().indexOf('$') + 1)); - this.methodName = methodName; - this.className = className; - this.signature = signature; - } - - static { - // iterate through all the intrinsics and add them to the map - for (C1XIntrinsic i : C1XIntrinsic.values()) { - // note that the map uses internal names to map lookup faster - String className = CiUtil.toInternalName(i.className); - HashMap map = intrinsicMap.get(className); - if (map == null) { - map = new HashMap(); - intrinsicMap.put(className, map); - } - map.put(i.methodName + i.signature, i); - } - } - - /** - * Looks up an intrinsic for the specified method. - * @param method the compiler interface method - * @return a reference to the intrinsic for the method, if the method is an intrinsic - * (and is loaded); {@code null} otherwise - */ - public static C1XIntrinsic getIntrinsic(RiMethod method) { - RiType holder = method.holder(); - if (method.isResolved() && holder.isResolved() && holder.isInitialized()) { - // note that the map uses internal names to make lookup faster - HashMap map = intrinsicMap.get(holder.name()); - if (map != null) { - C1XIntrinsic result = map.get(method.name() + method.signature().asString()); - return result; - } - } - return null; - } -} diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/C1XOptions.java --- a/graal/GraalCompiler/src/com/sun/c1x/C1XOptions.java Wed Apr 27 15:49:27 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/C1XOptions.java Wed Apr 27 16:25:32 2011 +0200 @@ -52,9 +52,6 @@ public static int MaximumDesiredSize = 8000; public static int MaximumShortLoopSize = 5; - // intrinsification settings - public static boolean OptIntrinsify = ____; - // debugging settings public static boolean VerifyPointerMaps = ____; public static boolean PinAllInstructions = ____; @@ -196,7 +193,6 @@ // Level 3 optimizations OptCSEArrayLength = lll; - OptIntrinsify = lll; OptInlineExcept = lll; OptInlineSynchronized = lll; UseStackMapTableLiveness = lll; diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java --- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Wed Apr 27 15:49:27 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Wed Apr 27 16:25:32 2011 +0200 @@ -472,90 +472,6 @@ } @Override - public void visitIntrinsic(Intrinsic x) { - Value[] vals = x.arguments(); - XirSnippet snippet; - - switch (x.intrinsic()) { - case java_lang_Float$intBitsToFloat: - case java_lang_Double$doubleToRawLongBits: - case java_lang_Double$longBitsToDouble: - case java_lang_Float$floatToRawIntBits: { - visitFPIntrinsics(x); - return; - } - - case java_lang_System$currentTimeMillis: { - assert x.numberOfArguments() == 0 : "wrong type"; - CiValue reg = callRuntimeWithResult(CiRuntimeCall.JavaTimeMillis, null, (CiValue[]) null); - CiValue result = createResultVariable(x); - lir.move(reg, result); - return; - } - - case java_lang_System$nanoTime: { - assert x.numberOfArguments() == 0 : "wrong type"; - CiValue reg = callRuntimeWithResult(CiRuntimeCall.JavaTimeNanos, null, (CiValue[]) null); - CiValue result = createResultVariable(x); - lir.move(reg, result); - return; - } - - case java_lang_Object$init: - visitRegisterFinalizer(x); - return; - - case java_lang_Math$log: // fall through - case java_lang_Math$log10: // fall through - case java_lang_Math$abs: // fall through - case java_lang_Math$sqrt: // fall through - case java_lang_Math$tan: // fall through - case java_lang_Math$sin: // fall through - case java_lang_Math$cos: - genMathIntrinsic(x); - return; - - case sun_misc_Unsafe$compareAndSwapObject: - genCompareAndSwap(x, CiKind.Object); - return; - case sun_misc_Unsafe$compareAndSwapInt: - genCompareAndSwap(x, CiKind.Int); - return; - case sun_misc_Unsafe$compareAndSwapLong: - genCompareAndSwap(x, CiKind.Long); - return; - - case java_lang_Thread$currentThread: - snippet = xir.genCurrentThread(site(x)); - if (snippet != null) { - emitXir(snippet, x, null, null, true); - return; - } - break; - - case java_lang_Object$getClass: - snippet = xir.genGetClass(site(x), toXirArgument(vals[0])); - if (snippet != null) { - emitXir(snippet, x, stateFor(x), null, true); - return; - } - break; - } - - - XirArgument[] args = new XirArgument[vals.length]; - for (int i = 0; i < vals.length; i++) { - args[i] = toXirArgument(vals[i]); - } - snippet = xir.genIntrinsic(site(x), args, x.target()); - if (snippet != null) { - emitXir(snippet, x, x.stateBefore() == null ? null : stateFor(x), null, true); - return; - } - x.setOperand(emitInvokeKnown(x.target(), x.stateBefore(), vals)); - } - - @Override public void visitInvoke(Invoke x) { RiMethod target = x.target(); LIRDebugInfo info = stateFor(x, x.stateBefore()); @@ -1267,17 +1183,9 @@ return operand; } - private void visitFPIntrinsics(Intrinsic x) { - assert x.numberOfArguments() == 1 : "wrong type"; - CiValue reg = createResultVariable(x); - CiValue value = load(x.argumentAt(0)); - CiValue tmp = forceToSpill(value, x.kind, false); - lir.move(tmp, reg); - } - - private void visitRegisterFinalizer(Intrinsic x) { - assert x.numberOfArguments() == 1 : "wrong type"; - CiValue receiver = load(x.argumentAt(0)); + @Override + public void visitRegisterFinalizer(RegisterFinalizer x) { + CiValue receiver = load(x.object()); LIRDebugInfo info = stateFor(x, x.stateBefore()); callRuntime(CiRuntimeCall.RegisterFinalizer, info, receiver); setNoResult(x); @@ -1880,10 +1788,6 @@ protected abstract void genPutObjectUnsafe(CiValue src, CiValue offset, CiValue data, CiKind kind, boolean isVolatile); - protected abstract void genCompareAndSwap(Intrinsic x, CiKind kind); - - protected abstract void genMathIntrinsic(Intrinsic x); - /** * Implements site-specific information for the XIR interface. */ diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java Wed Apr 27 15:49:27 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java Wed Apr 27 16:25:32 2011 +0200 @@ -26,7 +26,6 @@ import java.util.*; -import com.sun.c1x.*; import com.sun.c1x.ir.*; import com.sun.c1x.util.*; import com.sun.cri.bytecode.*; @@ -138,7 +137,7 @@ ExceptionMap(RiMethod method, byte[] code) { canTrap = new CiBitMap(code.length); - isObjectInit = C1XIntrinsic.getIntrinsic(method) == C1XIntrinsic.java_lang_Object$init; + isObjectInit = (method.isConstructor() && method.holder().superType() == null); allHandlers = method.exceptionHandlers(); handlerMap = new ArrayMap>(firstBlock, firstBlock + code.length / 5); } diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java --- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Wed Apr 27 15:49:27 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java Wed Apr 27 16:25:32 2011 +0200 @@ -153,45 +153,11 @@ finishStartBlock(startBlock, stdEntry); } - // 5. - C1XIntrinsic intrinsic = C1XOptions.OptIntrinsify ? C1XIntrinsic.getIntrinsic(rootMethod) : null; - if (intrinsic != null) { - lastInstr = stdEntry; - // 6A.1 the root method is an intrinsic; load the parameters onto the stack and try to inline it - if (C1XOptions.OptIntrinsify) { - // try to inline an Intrinsic node - boolean isStatic = Modifier.isStatic(rootMethod.accessFlags()); - int argsSize = rootMethod.signature().argumentSlots(!isStatic); - Value[] args = new Value[argsSize]; - for (int i = 0; i < args.length; i++) { - args[i] = curState.localAt(i); - } - if (tryInlineIntrinsic(rootMethod, args, isStatic, intrinsic)) { - // intrinsic inlining succeeded, add the return node - CiKind rt = returnKind(rootMethod).stackKind(); - Value result = null; - if (rt != CiKind.Void) { - result = pop(rt); - } - genReturn(result); - BlockEnd end = (BlockEnd) lastInstr; - stdEntry.setEnd(end); - end.setStateAfter(curState.immutableCopy(bci())); - } else { - // try intrinsic failed; do the normal parsing - scopeData.addToWorkList(stdEntry); - iterateAllBlocks(); - } - } else { - // 6B.1 do the normal parsing - scopeData.addToWorkList(stdEntry); - iterateAllBlocks(); - } - } else { - // 6B.1 do the normal parsing - scopeData.addToWorkList(stdEntry); - iterateAllBlocks(); - } + // 5. SKIPPED: look for intrinsics + + // 6B.1 do the normal parsing + scopeData.addToWorkList(stdEntry); + iterateAllBlocks(); if (syncHandler != null && syncHandler.stateBefore() != null) { // generate unlocking code if the exception handler is reachable @@ -1079,17 +1045,14 @@ } if (needsCheck) { - // append a call to the registration intrinsic - loadLocal(0, CiKind.Object); - FrameState stateBefore = curState.immutableCopy(bci()); - append(new Intrinsic(CiKind.Void, C1XIntrinsic.java_lang_Object$init, - null, curState.popArguments(1), false, stateBefore, true, true)); + // append a call to the finalizer registration + append(new RegisterFinalizer(curState.loadLocal(0), curState.immutableCopy(bci()))); C1XMetrics.InlinedFinalizerChecks++; } } void genReturn(Value x) { - if (C1XIntrinsic.getIntrinsic(method()) == C1XIntrinsic.java_lang_Object$init) { + if (method().isConstructor() && method().holder().superType() == null) { callRegisterFinalizer(); } @@ -1324,10 +1287,7 @@ assert x.next() == null : "instruction should not have been appended yet"; assert lastInstr.next() == null : "cannot append instruction to instruction which isn't end (" + lastInstr + "->" + lastInstr.next() + ")"; if (lastInstr instanceof Base) { - assert x instanceof Intrinsic : "may only happen when inlining intrinsics"; - Instruction prev = lastInstr.prev(lastInstr.block()); - prev.setNext(x, bci); - x.setNext(lastInstr, bci); + assert false : "may only happen when inlining intrinsics"; } else { lastInstr = lastInstr.setNext(x, bci); } @@ -1357,7 +1317,7 @@ } private boolean hasUncontrollableSideEffects(Value x) { - return x instanceof Invoke || x instanceof Intrinsic && !((Intrinsic) x).preservesState() || x instanceof ResolveClass; + return x instanceof Invoke || x instanceof ResolveClass; } private BlockBegin blockAtOrNull(int bci) { @@ -1466,14 +1426,6 @@ boolean tryRemoveCall(RiMethod target, Value[] args, boolean isStatic) { if (target.isResolved()) { - if (C1XOptions.OptIntrinsify) { - // try to create an intrinsic node instead of a call - C1XIntrinsic intrinsic = C1XIntrinsic.getIntrinsic(target); - if (intrinsic != null && tryInlineIntrinsic(target, args, isStatic, intrinsic)) { - // this method is not an intrinsic - return true; - } - } if (C1XOptions.CanonicalizeFoldableMethods) { // next try to fold the method call if (tryFoldable(target, args)) { @@ -1484,104 +1436,6 @@ return false; } - private boolean tryInlineIntrinsic(RiMethod target, Value[] args, boolean isStatic, C1XIntrinsic intrinsic) { - boolean preservesState = true; - boolean canTrap = false; - - Instruction result = null; - - // handle intrinsics differently - switch (intrinsic) { - - case java_lang_System$arraycopy: - if (compilation.runtime.supportsArrayIntrinsics()) { - break; - } else { - return false; - } - case java_lang_Object$getClass: - canTrap = true; - break; - case java_lang_Thread$currentThread: - break; - case java_util_Arrays$copyOf: - if (args[0].declaredType() != null && args[0].declaredType().isArrayClass() && compilation.runtime.supportsArrayIntrinsics()) { - break; - } else { - return false; - } - case java_lang_Object$init: // fall through - case java_lang_String$equals: // fall through - case java_lang_String$compareTo: // fall through - case java_lang_String$indexOf: // fall through - case java_lang_Math$max: // fall through - case java_lang_Math$min: // fall through - case java_lang_Math$atan2: // fall through - case java_lang_Math$pow: // fall through - case java_lang_Math$exp: // fall through - case java_nio_Buffer$checkIndex: // fall through - case java_lang_System$identityHashCode: // fall through - case java_lang_System$currentTimeMillis: // fall through - case java_lang_System$nanoTime: // fall through - case java_lang_Object$hashCode: // fall through - case java_lang_Class$isAssignableFrom: // fall through - case java_lang_Class$isInstance: // fall through - case java_lang_Class$getModifiers: // fall through - case java_lang_Class$isInterface: // fall through - case java_lang_Class$isArray: // fall through - case java_lang_Class$isPrimitive: // fall through - case java_lang_Class$getSuperclass: // fall through - case java_lang_Class$getComponentType: // fall through - case java_lang_reflect_Array$getLength: // fall through - case java_lang_reflect_Array$newArray: // fall through - case java_lang_Double$doubleToLongBits: // fall through - case java_lang_Float$floatToIntBits: // fall through - case java_lang_Math$sin: // fall through - case java_lang_Math$cos: // fall through - case java_lang_Math$tan: // fall through - case java_lang_Math$log: // fall through - case java_lang_Math$log10: // fall through - case java_lang_Integer$bitCount: // fall through - case java_lang_Integer$reverseBytes: // fall through - case java_lang_Long$bitCount: // fall through - case java_lang_Long$reverseBytes: // fall through - case java_lang_Object$clone: return false; - // TODO: preservesState and canTrap for complex intrinsics - } - - - - // get the arguments for the intrinsic - CiKind resultType = returnKind(target); - - if (C1XOptions.PrintInlinedIntrinsics) { - TTY.println("Inlining intrinsic: " + intrinsic); - } - - // Create state before intrinsic. - for (int i = 0; i < args.length; ++i) { - if (args[i] != null) { - curState.push(args[i].kind.stackKind(), args[i]); - } - } - - // Create the intrinsic node. - if (intrinsic == C1XIntrinsic.java_lang_System$arraycopy) { - result = genArrayCopy(target, args); - } else if (intrinsic == C1XIntrinsic.java_util_Arrays$copyOf) { - result = genArrayClone(target, args); - } else { - result = new Intrinsic(resultType.stackKind(), intrinsic, target, args, isStatic, curState.immutableCopy(bci()), preservesState, canTrap); - } - - // Pop arguments. - curState.popArguments(args.length); - - pushReturn(resultType, append(result)); - stats.intrinsicCount++; - return true; - } - private Instruction genArrayClone(RiMethod target, Value[] args) { FrameState state = curState.immutableCopy(bci()); Value array = args[0]; diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/ir/DefaultValueVisitor.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/DefaultValueVisitor.java Wed Apr 27 15:49:27 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/DefaultValueVisitor.java Wed Apr 27 16:25:32 2011 +0200 @@ -56,7 +56,6 @@ @Override public void visitIf(If i) { visit(i); } @Override public void visitIfOp(IfOp i) { visit(i); } @Override public void visitInstanceOf(InstanceOf i) { visit(i); } - @Override public void visitIntrinsic(Intrinsic i) { visit(i); } @Override public void visitInvoke(Invoke i) { visit(i); } @Override public void visitLoadField(LoadField i) { visit(i); } @Override public void visitLoadIndexed(LoadIndexed i) { visit(i); } @@ -75,6 +74,7 @@ @Override public void visitNullCheck(NullCheck i) { visit(i); } @Override public void visitOsrEntry(OsrEntry i) { visit(i); } @Override public void visitPhi(Phi i) { visit(i); } + @Override public void visitRegisterFinalizer(RegisterFinalizer i) { visit(i); } @Override public void visitResolveClass(ResolveClass i) { visit(i); } @Override public void visitReturn(Return i) { visit(i); } @Override public void visitShiftOp(ShiftOp i) { visit(i); } diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/ir/Intrinsic.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/Intrinsic.java Wed Apr 27 15:49:27 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2009, 2011, 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.sun.c1x.ir; - -import com.sun.c1x.*; -import com.sun.c1x.debug.*; -import com.sun.c1x.value.*; -import com.sun.cri.ci.*; -import com.sun.cri.ri.*; - -/** - * The {@code Intrinsic} instruction represents a call to a JDK method - * that has been made {@linkplain C1XIntrinsic intrinsic}. - * - * @author Ben L. Titzer - * @see C1XIntrinsic - */ -public final class Intrinsic extends StateSplit { - - final C1XIntrinsic intrinsic; - final RiMethod target; - final Value[] arguments; - final boolean canTrap; - - /** - * Creates a new Intrinsic instruction. - * @param kind the result type of the instruction - * @param intrinsic the actual intrinsic - * @param target the method for this intrinsic - * @param args the arguments to the call (including the receiver object) - * @param isStatic {@code true} if this method is static - * @param stateBefore the lock stack - * @param preservesState {@code true} if the implementation of this intrinsic preserves register state - * @param canTrap {@code true} if this intrinsic can cause a trap - */ - public Intrinsic(CiKind kind, C1XIntrinsic intrinsic, RiMethod target, Value[] args, boolean isStatic, - FrameState stateBefore, boolean preservesState, boolean canTrap) { - super(kind, stateBefore); - this.intrinsic = intrinsic; - int nonNullArgs = 0; - for (int i = 0; i < args.length; ++i) { - if (args[i] != null) { - nonNullArgs++; - } - } - this.arguments = new Value[nonNullArgs]; - int z = 0; - for (int i = 0; i < args.length; ++i) { - if (args[i] != null) { - arguments[z++] = args[i]; - } - } - this.target = target; - initFlag(Flag.IsStatic, isStatic); - // Preserves state means that the intrinsic preserves register state across all cases, - // including slow cases--even if it causes a trap. If so, it can still be a candidate - // for load elimination and common subexpression elimination - initFlag(Flag.PreservesState, preservesState); - this.canTrap = canTrap; - if (!isStatic && args[0].isNonNull()) { - eliminateNullCheck(); - } - } - - /** - * Gets the intrinsic represented by this instruction. - * @return the intrinsic - */ - public C1XIntrinsic intrinsic() { - return intrinsic; - } - - /** - * Gets the target method for this invocation instruction. - * @return the target method - */ - public RiMethod target() { - return target; - } - - /** - * Gets the list of instructions that produce input for this instruction. - * @return the list of instructions that produce input - */ - public Value[] arguments() { - return arguments; - } - - public boolean isStatic() { - return checkFlag(Flag.IsStatic); - } - - /** - * Checks whether this intrinsic has a receiver object. - * @return {@code true} if this intrinsic has a receiver object - */ - public boolean hasReceiver() { - return !isStatic(); - } - - /** - * Gets the instruction which produces the receiver object for this intrinsic. - * @return the instruction producing the receiver object - */ - public Value receiver() { - assert !isStatic(); - return arguments[0]; - } - - /** - * Checks whether this intrinsic preserves the state of registers across all cases. - * @return {@code true} if this intrinsic always preserves register state - */ - public boolean preservesState() { - return checkFlag(Flag.PreservesState); - } - - /** - * Checks whether this intrinsic can cause a trap. - * @return {@code true} if this intrinsic can cause a trap - */ - @Override - public boolean canTrap() { - return canTrap; - } - - @Override - public void inputValuesDo(ValueClosure closure) { - for (int i = 0; i < arguments.length; i++) { - arguments[i] = closure.apply(arguments[i]); - } - } - - @Override - public void accept(ValueVisitor v) { - v.visitIntrinsic(this); - } - - public Value argumentAt(int i) { - return arguments[i]; - } - - public int numberOfArguments() { - return arguments.length; - } - - @Override - public void print(LogStream out) { - out.print(intrinsic().className).print('.').print(intrinsic().name()).print('('); - for (int i = 0; i < arguments().length; i++) { - if (i > 0) { - out.print(", "); - } - out.print(arguments()[i]); - } - out.print(')'); - } -} diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/ir/RegisterFinalizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/RegisterFinalizer.java Wed Apr 27 16:25:32 2011 +0200 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011, 2011, 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.sun.c1x.ir; + +import com.sun.c1x.debug.*; +import com.sun.c1x.value.*; +import com.sun.cri.ci.*; + +public class RegisterFinalizer extends StateSplit { + + private Value object; + + public RegisterFinalizer(Value object, FrameState stateBefore) { + super(CiKind.Void, stateBefore); + this.object = object; + } + + public Value object() { + return object; + } + + @Override + public void inputValuesDo(ValueClosure closure) { + object = closure.apply(object); + super.inputValuesDo(closure); + } + + @Override + public void accept(ValueVisitor v) { + v.visitRegisterFinalizer(this); + } + + @Override + public boolean canTrap() { + return true; + } + + @Override + public void print(LogStream out) { + out.print("register finalizer ").print(object); + } +} diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java --- a/graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java Wed Apr 27 15:49:27 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/ir/ValueVisitor.java Wed Apr 27 16:25:32 2011 +0200 @@ -46,7 +46,6 @@ public abstract void visitIf(If i); public abstract void visitIfOp(IfOp i); public abstract void visitInstanceOf(InstanceOf i); - public abstract void visitIntrinsic(Intrinsic i); public abstract void visitInvoke(Invoke i); public abstract void visitLoadField(LoadField i); public abstract void visitLoadIndexed(LoadIndexed i); @@ -65,6 +64,7 @@ public abstract void visitNullCheck(NullCheck i); public abstract void visitOsrEntry(OsrEntry i); public abstract void visitPhi(Phi i); + public abstract void visitRegisterFinalizer(RegisterFinalizer i); public abstract void visitResolveClass(ResolveClass i); public abstract void visitReturn(Return i); public abstract void visitShiftOp(ShiftOp i); diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/opt/Canonicalizer.java --- a/graal/GraalCompiler/src/com/sun/c1x/opt/Canonicalizer.java Wed Apr 27 15:49:27 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/opt/Canonicalizer.java Wed Apr 27 16:25:32 2011 +0200 @@ -24,7 +24,6 @@ import static com.sun.cri.bytecode.Bytecodes.*; -import java.lang.reflect.*; import java.util.*; import com.sun.c1x.*; @@ -843,183 +842,6 @@ } @Override - public void visitIntrinsic(Intrinsic i) { - if (!C1XOptions.CanonicalizeIntrinsics) { - return; - } - if (!foldIntrinsic(i)) { - // folding did not work, try recognizing special intrinsics - reduceIntrinsic(i); - } - assert Util.archKindsEqual(i, canonical); - } - - private void reduceIntrinsic(Intrinsic i) { - Value[] args = i.arguments(); - C1XIntrinsic intrinsic = i.intrinsic(); - if (intrinsic == C1XIntrinsic.java_lang_Class$isInstance) { - // try to convert a call to Class.isInstance() into an InstanceOf - RiType type = getTypeOf(args[0]); - if (type != null) { - setCanonical(new InstanceOf(type, Constant.forObject(type.getEncoding(RiType.Representation.TypeInfo)), args[1], i.stateBefore())); - return; - } - } - if (intrinsic == C1XIntrinsic.java_lang_reflect_Array$newArray) { - // try to convert a call to Array.newInstance() into a NewObjectArray or NewTypeArray - RiType type = getTypeOf(args[0]); - if (type != null) { - if (type.kind() == CiKind.Object) { - setCanonical(new NewObjectArray(type, args[1], i.stateBefore())); - } else { - RiType elementType = runtime.asRiType(type.kind()); - setCanonical(new NewTypeArray(args[1], elementType, i.stateBefore())); - } - return; - } - } - assert Util.archKindsEqual(i, canonical); - } - - private boolean foldIntrinsic(Intrinsic i) { - Value[] args = i.arguments(); - for (Value arg : args) { - if (arg != null && !arg.isConstant()) { - // one input is not constant, give up - return true; - } - } - switch (i.intrinsic()) { - // do not use reflection here due to efficiency and potential bootstrap problems - case java_lang_Object$hashCode: { - Object object = argAsObject(args, 0); - if (object != null) { - setIntConstant(System.identityHashCode(object)); - } - return true; - } - case java_lang_Object$getClass: { - Object object = argAsObject(args, 0); - if (object != null) { - setObjectConstant(object.getClass()); - } - return true; - } - - // java.lang.Class - case java_lang_Class$isAssignableFrom: { - Class javaClass = argAsClass(args, 0); - Class otherClass = argAsClass(args, 1); - if (javaClass != null && otherClass != null) { - setBooleanConstant(javaClass.isAssignableFrom(otherClass)); - } - return true; - } - case java_lang_Class$isInstance: { - Class javaClass = argAsClass(args, 0); - Object object = argAsObject(args, 1); - if (javaClass != null && object != null) { - setBooleanConstant(javaClass.isInstance(object)); - } - return true; - } - case java_lang_Class$getModifiers: { - Class javaClass = argAsClass(args, 0); - if (javaClass != null) { - setIntConstant(javaClass.getModifiers()); - } - return true; - } - case java_lang_Class$isInterface: { - Class javaClass = argAsClass(args, 0); - if (javaClass != null) { - setBooleanConstant(javaClass.isInterface()); - } - return true; - } - case java_lang_Class$isArray: { - Class javaClass = argAsClass(args, 0); - if (javaClass != null) { - setBooleanConstant(javaClass.isArray()); - } - return true; - } - case java_lang_Class$isPrimitive: { - Class javaClass = argAsClass(args, 0); - if (javaClass != null) { - setBooleanConstant(javaClass.isPrimitive()); - } - return true; - } - case java_lang_Class$getSuperclass: { - Class javaClass = argAsClass(args, 0); - if (javaClass != null) { - setObjectConstant(javaClass.getSuperclass()); - } - return true; - } - case java_lang_Class$getComponentType: { - Class javaClass = argAsClass(args, 0); - if (javaClass != null) { - setObjectConstant(javaClass.getComponentType()); - } - return true; - } - - // java.lang.Math - case java_lang_Math$abs: setDoubleConstant(Math.abs(argAsDouble(args, 0))); return true; - case java_lang_Math$sin: setDoubleConstant(Math.sin(argAsDouble(args, 0))); return true; - case java_lang_Math$cos: setDoubleConstant(Math.cos(argAsDouble(args, 0))); return true; - case java_lang_Math$tan: setDoubleConstant(Math.tan(argAsDouble(args, 0))); return true; - case java_lang_Math$atan2: setDoubleConstant(Math.atan2(argAsDouble(args, 0), argAsDouble(args, 2))); return true; - case java_lang_Math$sqrt: setDoubleConstant(Math.sqrt(argAsDouble(args, 0))); return true; - case java_lang_Math$log: setDoubleConstant(Math.log(argAsDouble(args, 0))); return true; - case java_lang_Math$log10: setDoubleConstant(Math.log10(argAsDouble(args, 0))); return true; - case java_lang_Math$pow: setDoubleConstant(Math.pow(argAsDouble(args, 0), argAsDouble(args, 2))); return true; - case java_lang_Math$exp: setDoubleConstant(Math.exp(argAsDouble(args, 0))); return true; - case java_lang_Math$min: setIntConstant(Math.min(argAsInt(args, 0), argAsInt(args, 1))); return true; - case java_lang_Math$max: setIntConstant(Math.max(argAsInt(args, 0), argAsInt(args, 1))); return true; - - // java.lang.Float - case java_lang_Float$floatToRawIntBits: setIntConstant(Float.floatToRawIntBits(argAsFloat(args, 0))); return true; - case java_lang_Float$floatToIntBits: setIntConstant(Float.floatToIntBits(argAsFloat(args, 0))); return true; - case java_lang_Float$intBitsToFloat: setFloatConstant(Float.intBitsToFloat(argAsInt(args, 0))); return true; - - // java.lang.Double - case java_lang_Double$doubleToRawLongBits: setLongConstant(Double.doubleToRawLongBits(argAsDouble(args, 0))); return true; - case java_lang_Double$doubleToLongBits: setLongConstant(Double.doubleToLongBits(argAsDouble(args, 0))); return true; - case java_lang_Double$longBitsToDouble: setDoubleConstant(Double.longBitsToDouble(argAsLong(args, 0))); return true; - - // java.lang.Integer - case java_lang_Integer$bitCount: setIntConstant(Integer.bitCount(argAsInt(args, 0))); return true; - case java_lang_Integer$reverseBytes: setIntConstant(Integer.reverseBytes(argAsInt(args, 0))); return true; - - // java.lang.Long - case java_lang_Long$bitCount: setIntConstant(Long.bitCount(argAsLong(args, 0))); return true; - case java_lang_Long$reverseBytes: setLongConstant(Long.reverseBytes(argAsLong(args, 0))); return true; - - // java.lang.System - case java_lang_System$identityHashCode: { - Object object = argAsObject(args, 0); - if (object != null) { - setIntConstant(System.identityHashCode(object)); - } - return true; - } - - // java.lang.reflect.Array - case java_lang_reflect_Array$getLength: { - Object object = argAsObject(args, 0); - if (object != null && object.getClass().isArray()) { - setIntConstant(Array.getLength(object)); - } - return true; - } - } - return false; - } - - @Override public void visitIf(If i) { if (i.x().isConstant()) { // move constant to the right diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/opt/NullCheckEliminator.java --- a/graal/GraalCompiler/src/com/sun/c1x/opt/NullCheckEliminator.java Wed Apr 27 15:49:27 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/opt/NullCheckEliminator.java Wed Apr 27 16:25:32 2011 +0200 @@ -435,13 +435,6 @@ } @Override - public void visitIntrinsic(Intrinsic i) { - if (!i.isStatic()) { - processUse(i, i.receiver(), true); - } - } - - @Override public void visitIf(If i) { if (C1XOptions.OptFlowSensitiveNCE) { if (i.trueSuccessor() != i.falseSuccessor()) { diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java --- a/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java Wed Apr 27 15:49:27 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/target/amd64/AMD64LIRGenerator.java Wed Apr 27 16:25:32 2011 +0200 @@ -449,92 +449,6 @@ } @Override - protected void genCompareAndSwap(Intrinsic x, CiKind kind) { - assert x.numberOfArguments() == 5 : "wrong number of arguments: " + x.numberOfArguments(); - // Argument 0 is the receiver. - LIRItem obj = new LIRItem(x.argumentAt(1), this); // object - LIRItem offset = new LIRItem(x.argumentAt(2), this); // offset of field - LIRItem val = new LIRItem(x.argumentAt(4), this); // replace field with val if matches cmp - - assert obj.instruction.kind.isObject() : "invalid type"; - - assert val.instruction.kind == kind : "invalid type"; - - // get address of field - obj.loadItem(); - offset.loadNonconstant(); - CiAddress addr; - if (offset.result().isConstant()) { - addr = new CiAddress(kind, obj.result(), (int) ((CiConstant) offset.result()).asLong()); - } else { - addr = new CiAddress(kind, obj.result(), offset.result()); - } - - // Compare operand needs to be in RAX. - CiValue cmp = force(x.argumentAt(3), AMD64.rax.asValue(kind)); - val.loadItem(); - - CiValue pointer = newVariable(CiKind.Word); - lir.lea(addr, pointer); - - if (kind.isObject()) { // Write-barrier needed for Object fields. - // Do the pre-write barrier : if any. - preGCWriteBarrier(pointer, false, null); - } - - if (kind.isObject()) { - lir.casObj(pointer, cmp, val.result()); - } else if (kind.isInt()) { - lir.casInt(pointer, cmp, val.result()); - } else if (kind.isLong()) { - lir.casLong(pointer, cmp, val.result()); - } else { - Util.shouldNotReachHere(); - } - - // generate conditional move of boolean result - CiValue result = createResultVariable(x); - lir.cmove(Condition.EQ, CiConstant.INT_1, CiConstant.INT_0, result); - if (kind.isObject()) { // Write-barrier needed for Object fields. - // Seems to be precise - postGCWriteBarrier(pointer, val.result()); - } - } - - @Override - protected void genMathIntrinsic(Intrinsic x) { - assert x.numberOfArguments() == 1 : "wrong type"; - - CiValue calcInput = load(x.argumentAt(0)); - - switch (x.intrinsic()) { - case java_lang_Math$abs: - lir.abs(calcInput, createResultVariable(x), ILLEGAL); - break; - case java_lang_Math$sqrt: - lir.sqrt(calcInput, createResultVariable(x), ILLEGAL); - break; - case java_lang_Math$sin: - setResult(x, callRuntimeWithResult(CiRuntimeCall.ArithmeticSin, null, calcInput)); - break; - case java_lang_Math$cos: - setResult(x, callRuntimeWithResult(CiRuntimeCall.ArithmeticCos, null, calcInput)); - break; - case java_lang_Math$tan: - setResult(x, callRuntimeWithResult(CiRuntimeCall.ArithmeticTan, null, calcInput)); - break; - case java_lang_Math$log: - setResult(x, callRuntimeWithResult(CiRuntimeCall.ArithmeticLog, null, calcInput)); - break; - case java_lang_Math$log10: - setResult(x, callRuntimeWithResult(CiRuntimeCall.ArithmeticLog10, null, calcInput)); - break; - default: - Util.shouldNotReachHere("Unknown math intrinsic"); - } - } - - @Override public void visitConvert(Convert x) { CiValue input = load(x.value()); CiVariable result = newVariable(x.kind); diff -r a384fac3fd34 -r f6125fb5bfbc graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotTypeResolvedImpl.java --- a/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotTypeResolvedImpl.java Wed Apr 27 15:49:27 2011 +0200 +++ b/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotTypeResolvedImpl.java Wed Apr 27 16:25:32 2011 +0200 @@ -47,6 +47,8 @@ private RiType componentType; private HashMap fieldCache; private RiConstantPool pool; + private RiType superType; + private boolean superTypeSet; private HotSpotTypeResolvedImpl() { super(null); @@ -74,7 +76,11 @@ @Override public RiType superType() { - return compiler.getVMEntries().RiType_superType(this); + if (!superTypeSet) { + superType = compiler.getVMEntries().RiType_superType(this); + superTypeSet = true; + } + return superType; } @Override