--- old/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java 2016-05-04 09:43:35.000000000 -1000 +++ /dev/null 2016-05-04 09:43:35.000000000 -1000 @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2011, 2016, 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 jdk.vm.ci.hotspot; - -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset; -import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale; -import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass; -import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; - -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.Executable; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -import jdk.vm.ci.code.CodeUtil; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.DeoptimizationAction; -import jdk.vm.ci.meta.DeoptimizationReason; -import jdk.vm.ci.meta.JavaConstant; -import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.meta.ResolvedJavaField; -import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.meta.Signature; - -// JaCoCo Exclude - -/** - * HotSpot implementation of {@link MetaAccessProvider}. - */ -public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotProxified { - - protected final HotSpotJVMCIRuntimeProvider runtime; - - public HotSpotMetaAccessProvider(HotSpotJVMCIRuntimeProvider runtime) { - this.runtime = runtime; - } - - public ResolvedJavaType lookupJavaType(Class clazz) { - if (clazz == null) { - throw new IllegalArgumentException("Class parameter was null"); - } - return runtime.fromClass(clazz); - } - - public HotSpotResolvedObjectType lookupJavaType(JavaConstant constant) { - if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) { - return null; - } - return ((HotSpotObjectConstant) constant).getType(); - } - - public Signature parseMethodDescriptor(String signature) { - return new HotSpotSignature(runtime, signature); - } - - public HotSpotSymbol lookupSymbol(String symbol) { - long pointer = runtime.getCompilerToVM().lookupSymbol(symbol); - if (pointer == 0) { - return null; - } else { - return new HotSpotSymbol(symbol, pointer); - } - } - - /** - * {@link Field} object of {@link Method#slot}. - */ - private Field reflectionMethodSlot = getReflectionSlotField(Method.class); - - /** - * {@link Field} object of {@link Constructor#slot}. - */ - private Field reflectionConstructorSlot = getReflectionSlotField(Constructor.class); - - private static Field getReflectionSlotField(Class reflectionClass) { - try { - Field field = reflectionClass.getDeclaredField("slot"); - field.setAccessible(true); - return field; - } catch (NoSuchFieldException | SecurityException e) { - throw new JVMCIError(e); - } - } - - public ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod) { - try { - Class holder = reflectionMethod.getDeclaringClass(); - Field slotField = reflectionMethod instanceof Constructor ? reflectionConstructorSlot : reflectionMethodSlot; - final int slot = slotField.getInt(reflectionMethod); - return runtime.getCompilerToVM().getResolvedJavaMethodAtSlot(holder, slot); - } catch (IllegalArgumentException | IllegalAccessException e) { - throw new JVMCIError(e); - } - } - - public ResolvedJavaField lookupJavaField(Field reflectionField) { - Class fieldHolder = reflectionField.getDeclaringClass(); - - HotSpotResolvedObjectType holder = fromObjectClass(fieldHolder); - if (Modifier.isStatic(reflectionField.getModifiers())) { - final long offset = UNSAFE.staticFieldOffset(reflectionField); - for (ResolvedJavaField field : holder.getStaticFields()) { - if (offset == ((HotSpotResolvedJavaField) field).offset()) { - return field; - } - } - } else { - final long offset = UNSAFE.objectFieldOffset(reflectionField); - for (ResolvedJavaField field : holder.getInstanceFields(false)) { - if (offset == ((HotSpotResolvedJavaField) field).offset()) { - return field; - } - } - } - - throw new JVMCIError("unresolved field %s", reflectionField); - } - - private static int intMaskRight(int n) { - assert n <= 32; - return n == 32 ? -1 : (1 << n) - 1; - } - - @Override - public JavaConstant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int debugId) { - HotSpotVMConfig config = runtime.getConfig(); - int actionValue = convertDeoptAction(action); - int reasonValue = convertDeoptReason(reason); - int debugValue = debugId & intMaskRight(config.deoptimizationDebugIdBits); - JavaConstant c = JavaConstant.forInt(~((debugValue << config.deoptimizationDebugIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift))); - assert c.asInt() < 0; - return c; - } - - public DeoptimizationReason decodeDeoptReason(JavaConstant constant) { - HotSpotVMConfig config = runtime.getConfig(); - int reasonValue = ((~constant.asInt()) >> config.deoptimizationReasonShift) & intMaskRight(config.deoptimizationReasonBits); - DeoptimizationReason reason = convertDeoptReason(reasonValue); - return reason; - } - - public DeoptimizationAction decodeDeoptAction(JavaConstant constant) { - HotSpotVMConfig config = runtime.getConfig(); - int actionValue = ((~constant.asInt()) >> config.deoptimizationActionShift) & intMaskRight(config.deoptimizationActionBits); - DeoptimizationAction action = convertDeoptAction(actionValue); - return action; - } - - public int decodeDebugId(JavaConstant constant) { - HotSpotVMConfig config = runtime.getConfig(); - return ((~constant.asInt()) >> config.deoptimizationDebugIdShift) & intMaskRight(config.deoptimizationDebugIdBits); - } - - public int convertDeoptAction(DeoptimizationAction action) { - HotSpotVMConfig config = runtime.getConfig(); - switch (action) { - case None: - return config.deoptActionNone; - case RecompileIfTooManyDeopts: - return config.deoptActionMaybeRecompile; - case InvalidateReprofile: - return config.deoptActionReinterpret; - case InvalidateRecompile: - return config.deoptActionMakeNotEntrant; - case InvalidateStopCompiling: - return config.deoptActionMakeNotCompilable; - default: - throw new JVMCIError("%s", action); - } - } - - public DeoptimizationAction convertDeoptAction(int action) { - HotSpotVMConfig config = runtime.getConfig(); - if (action == config.deoptActionNone) { - return DeoptimizationAction.None; - } - if (action == config.deoptActionMaybeRecompile) { - return DeoptimizationAction.RecompileIfTooManyDeopts; - } - if (action == config.deoptActionReinterpret) { - return DeoptimizationAction.InvalidateReprofile; - } - if (action == config.deoptActionMakeNotEntrant) { - return DeoptimizationAction.InvalidateRecompile; - } - if (action == config.deoptActionMakeNotCompilable) { - return DeoptimizationAction.InvalidateStopCompiling; - } - throw new JVMCIError("%d", action); - } - - public int convertDeoptReason(DeoptimizationReason reason) { - HotSpotVMConfig config = runtime.getConfig(); - switch (reason) { - case None: - return config.deoptReasonNone; - case NullCheckException: - return config.deoptReasonNullCheck; - case BoundsCheckException: - return config.deoptReasonRangeCheck; - case ClassCastException: - return config.deoptReasonClassCheck; - case ArrayStoreException: - return config.deoptReasonArrayCheck; - case UnreachedCode: - return config.deoptReasonUnreached0; - case TypeCheckedInliningViolated: - return config.deoptReasonTypeCheckInlining; - case OptimizedTypeCheckViolated: - return config.deoptReasonOptimizedTypeCheck; - case NotCompiledExceptionHandler: - return config.deoptReasonNotCompiledExceptionHandler; - case Unresolved: - return config.deoptReasonUnresolved; - case JavaSubroutineMismatch: - return config.deoptReasonJsrMismatch; - case ArithmeticException: - return config.deoptReasonDiv0Check; - case RuntimeConstraint: - return config.deoptReasonConstraint; - case LoopLimitCheck: - return config.deoptReasonLoopLimitCheck; - case Aliasing: - return config.deoptReasonAliasing; - case TransferToInterpreter: - return config.deoptReasonTransferToInterpreter; - default: - throw new JVMCIError("%s", reason); - } - } - - public DeoptimizationReason convertDeoptReason(int reason) { - HotSpotVMConfig config = runtime.getConfig(); - if (reason == config.deoptReasonNone) { - return DeoptimizationReason.None; - } - if (reason == config.deoptReasonNullCheck) { - return DeoptimizationReason.NullCheckException; - } - if (reason == config.deoptReasonRangeCheck) { - return DeoptimizationReason.BoundsCheckException; - } - if (reason == config.deoptReasonClassCheck) { - return DeoptimizationReason.ClassCastException; - } - if (reason == config.deoptReasonArrayCheck) { - return DeoptimizationReason.ArrayStoreException; - } - if (reason == config.deoptReasonUnreached0) { - return DeoptimizationReason.UnreachedCode; - } - if (reason == config.deoptReasonTypeCheckInlining) { - return DeoptimizationReason.TypeCheckedInliningViolated; - } - if (reason == config.deoptReasonOptimizedTypeCheck) { - return DeoptimizationReason.OptimizedTypeCheckViolated; - } - if (reason == config.deoptReasonNotCompiledExceptionHandler) { - return DeoptimizationReason.NotCompiledExceptionHandler; - } - if (reason == config.deoptReasonUnresolved) { - return DeoptimizationReason.Unresolved; - } - if (reason == config.deoptReasonJsrMismatch) { - return DeoptimizationReason.JavaSubroutineMismatch; - } - if (reason == config.deoptReasonDiv0Check) { - return DeoptimizationReason.ArithmeticException; - } - if (reason == config.deoptReasonConstraint) { - return DeoptimizationReason.RuntimeConstraint; - } - if (reason == config.deoptReasonLoopLimitCheck) { - return DeoptimizationReason.LoopLimitCheck; - } - if (reason == config.deoptReasonAliasing) { - return DeoptimizationReason.Aliasing; - } - if (reason == config.deoptReasonTransferToInterpreter) { - return DeoptimizationReason.TransferToInterpreter; - } - throw new JVMCIError("%x", reason); - } - - @Override - public long getMemorySize(JavaConstant constant) { - if (constant.getJavaKind() == JavaKind.Object) { - HotSpotResolvedObjectType lookupJavaType = lookupJavaType(constant); - - if (lookupJavaType == null) { - return 0; - } else { - if (lookupJavaType.isArray()) { - // TODO(tw): Add compressed pointer support. - int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object()); - ResolvedJavaType elementType = lookupJavaType.getComponentType(); - JavaKind elementKind = elementType.getJavaKind(); - final int headerSize = getArrayBaseOffset(elementKind); - TargetDescription target = runtime.getHostJVMCIBackend().getTarget(); - int sizeOfElement = getArrayIndexScale(elementKind); - int alignment = target.wordSize; - int log2ElementSize = CodeUtil.log2(sizeOfElement); - return computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize); - } - return lookupJavaType.instanceSize(); - } - } else { - return constant.getJavaKind().getByteCount(); - } - } - - /** - * Computes the size of the memory chunk allocated for an array. This size accounts for the - * array header size, body size and any padding after the last element to satisfy object - * alignment requirements. - * - * @param length the number of elements in the array - * @param alignment the object alignment requirement - * @param headerSize the size of the array header - * @param log2ElementSize log2 of the size of an element in the array - */ - public static int computeArrayAllocationSize(int length, int alignment, int headerSize, int log2ElementSize) { - int size = (length << log2ElementSize) + headerSize + (alignment - 1); - int mask = ~(alignment - 1); - return size & mask; - } -} --- /dev/null 2016-05-04 09:43:35.000000000 -1000 +++ new/src/jdk.vm.ci.hotspot/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java 2016-05-04 09:43:35.000000000 -1000 @@ -0,0 +1,352 @@ +/* + * Copyright (c) 2011, 2016, 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 jdk.vm.ci.hotspot; + +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset; +import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale; +import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass; +import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; + +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import jdk.vm.ci.code.CodeUtil; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.DeoptimizationAction; +import jdk.vm.ci.meta.DeoptimizationReason; +import jdk.vm.ci.meta.JavaConstant; +import jdk.vm.ci.meta.JavaKind; +import jdk.vm.ci.meta.MetaAccessProvider; +import jdk.vm.ci.meta.ResolvedJavaField; +import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; +import jdk.vm.ci.meta.Signature; + +// JaCoCo Exclude + +/** + * HotSpot implementation of {@link MetaAccessProvider}. + */ +public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotProxified { + + protected final HotSpotJVMCIRuntimeProvider runtime; + + public HotSpotMetaAccessProvider(HotSpotJVMCIRuntimeProvider runtime) { + this.runtime = runtime; + } + + public ResolvedJavaType lookupJavaType(Class clazz) { + if (clazz == null) { + throw new IllegalArgumentException("Class parameter was null"); + } + return runtime.fromClass(clazz); + } + + public HotSpotResolvedObjectType lookupJavaType(JavaConstant constant) { + if (constant.isNull() || !(constant instanceof HotSpotObjectConstant)) { + return null; + } + return ((HotSpotObjectConstant) constant).getType(); + } + + public Signature parseMethodDescriptor(String signature) { + return new HotSpotSignature(runtime, signature); + } + + public HotSpotSymbol lookupSymbol(String symbol) { + long pointer = runtime.getCompilerToVM().lookupSymbol(symbol); + if (pointer == 0) { + return null; + } else { + return new HotSpotSymbol(symbol, pointer); + } + } + + /** + * {@link Field} object of {@link Method#slot}. + */ + private Field reflectionMethodSlot = getReflectionSlotField(Method.class); + + /** + * {@link Field} object of {@link Constructor#slot}. + */ + private Field reflectionConstructorSlot = getReflectionSlotField(Constructor.class); + + private static Field getReflectionSlotField(Class reflectionClass) { + try { + Field field = reflectionClass.getDeclaredField("slot"); + field.setAccessible(true); + return field; + } catch (NoSuchFieldException | SecurityException e) { + throw new JVMCIError(e); + } + } + + public ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod) { + try { + Class holder = reflectionMethod.getDeclaringClass(); + Field slotField = reflectionMethod instanceof Constructor ? reflectionConstructorSlot : reflectionMethodSlot; + final int slot = slotField.getInt(reflectionMethod); + return runtime.getCompilerToVM().getResolvedJavaMethodAtSlot(holder, slot); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new JVMCIError(e); + } + } + + public ResolvedJavaField lookupJavaField(Field reflectionField) { + Class fieldHolder = reflectionField.getDeclaringClass(); + + HotSpotResolvedObjectType holder = fromObjectClass(fieldHolder); + if (Modifier.isStatic(reflectionField.getModifiers())) { + final long offset = UNSAFE.staticFieldOffset(reflectionField); + for (ResolvedJavaField field : holder.getStaticFields()) { + if (offset == ((HotSpotResolvedJavaField) field).offset()) { + return field; + } + } + } else { + final long offset = UNSAFE.objectFieldOffset(reflectionField); + for (ResolvedJavaField field : holder.getInstanceFields(false)) { + if (offset == ((HotSpotResolvedJavaField) field).offset()) { + return field; + } + } + } + + throw new JVMCIError("unresolved field %s", reflectionField); + } + + private static int intMaskRight(int n) { + assert n <= 32; + return n == 32 ? -1 : (1 << n) - 1; + } + + @Override + public JavaConstant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason, int debugId) { + HotSpotVMConfig config = runtime.getConfig(); + int actionValue = convertDeoptAction(action); + int reasonValue = convertDeoptReason(reason); + int debugValue = debugId & intMaskRight(config.deoptimizationDebugIdBits); + JavaConstant c = JavaConstant.forInt(~((debugValue << config.deoptimizationDebugIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift))); + assert c.asInt() < 0; + return c; + } + + public DeoptimizationReason decodeDeoptReason(JavaConstant constant) { + HotSpotVMConfig config = runtime.getConfig(); + int reasonValue = ((~constant.asInt()) >> config.deoptimizationReasonShift) & intMaskRight(config.deoptimizationReasonBits); + DeoptimizationReason reason = convertDeoptReason(reasonValue); + return reason; + } + + public DeoptimizationAction decodeDeoptAction(JavaConstant constant) { + HotSpotVMConfig config = runtime.getConfig(); + int actionValue = ((~constant.asInt()) >> config.deoptimizationActionShift) & intMaskRight(config.deoptimizationActionBits); + DeoptimizationAction action = convertDeoptAction(actionValue); + return action; + } + + public int decodeDebugId(JavaConstant constant) { + HotSpotVMConfig config = runtime.getConfig(); + return ((~constant.asInt()) >> config.deoptimizationDebugIdShift) & intMaskRight(config.deoptimizationDebugIdBits); + } + + public int convertDeoptAction(DeoptimizationAction action) { + HotSpotVMConfig config = runtime.getConfig(); + switch (action) { + case None: + return config.deoptActionNone; + case RecompileIfTooManyDeopts: + return config.deoptActionMaybeRecompile; + case InvalidateReprofile: + return config.deoptActionReinterpret; + case InvalidateRecompile: + return config.deoptActionMakeNotEntrant; + case InvalidateStopCompiling: + return config.deoptActionMakeNotCompilable; + default: + throw new JVMCIError("%s", action); + } + } + + public DeoptimizationAction convertDeoptAction(int action) { + HotSpotVMConfig config = runtime.getConfig(); + if (action == config.deoptActionNone) { + return DeoptimizationAction.None; + } + if (action == config.deoptActionMaybeRecompile) { + return DeoptimizationAction.RecompileIfTooManyDeopts; + } + if (action == config.deoptActionReinterpret) { + return DeoptimizationAction.InvalidateReprofile; + } + if (action == config.deoptActionMakeNotEntrant) { + return DeoptimizationAction.InvalidateRecompile; + } + if (action == config.deoptActionMakeNotCompilable) { + return DeoptimizationAction.InvalidateStopCompiling; + } + throw new JVMCIError("%d", action); + } + + public int convertDeoptReason(DeoptimizationReason reason) { + HotSpotVMConfig config = runtime.getConfig(); + switch (reason) { + case None: + return config.deoptReasonNone; + case NullCheckException: + return config.deoptReasonNullCheck; + case BoundsCheckException: + return config.deoptReasonRangeCheck; + case ClassCastException: + return config.deoptReasonClassCheck; + case ArrayStoreException: + return config.deoptReasonArrayCheck; + case UnreachedCode: + return config.deoptReasonUnreached0; + case TypeCheckedInliningViolated: + return config.deoptReasonTypeCheckInlining; + case OptimizedTypeCheckViolated: + return config.deoptReasonOptimizedTypeCheck; + case NotCompiledExceptionHandler: + return config.deoptReasonNotCompiledExceptionHandler; + case Unresolved: + return config.deoptReasonUnresolved; + case JavaSubroutineMismatch: + return config.deoptReasonJsrMismatch; + case ArithmeticException: + return config.deoptReasonDiv0Check; + case RuntimeConstraint: + return config.deoptReasonConstraint; + case LoopLimitCheck: + return config.deoptReasonLoopLimitCheck; + case Aliasing: + return config.deoptReasonAliasing; + case TransferToInterpreter: + return config.deoptReasonTransferToInterpreter; + default: + throw new JVMCIError("%s", reason); + } + } + + public DeoptimizationReason convertDeoptReason(int reason) { + HotSpotVMConfig config = runtime.getConfig(); + if (reason == config.deoptReasonNone) { + return DeoptimizationReason.None; + } + if (reason == config.deoptReasonNullCheck) { + return DeoptimizationReason.NullCheckException; + } + if (reason == config.deoptReasonRangeCheck) { + return DeoptimizationReason.BoundsCheckException; + } + if (reason == config.deoptReasonClassCheck) { + return DeoptimizationReason.ClassCastException; + } + if (reason == config.deoptReasonArrayCheck) { + return DeoptimizationReason.ArrayStoreException; + } + if (reason == config.deoptReasonUnreached0) { + return DeoptimizationReason.UnreachedCode; + } + if (reason == config.deoptReasonTypeCheckInlining) { + return DeoptimizationReason.TypeCheckedInliningViolated; + } + if (reason == config.deoptReasonOptimizedTypeCheck) { + return DeoptimizationReason.OptimizedTypeCheckViolated; + } + if (reason == config.deoptReasonNotCompiledExceptionHandler) { + return DeoptimizationReason.NotCompiledExceptionHandler; + } + if (reason == config.deoptReasonUnresolved) { + return DeoptimizationReason.Unresolved; + } + if (reason == config.deoptReasonJsrMismatch) { + return DeoptimizationReason.JavaSubroutineMismatch; + } + if (reason == config.deoptReasonDiv0Check) { + return DeoptimizationReason.ArithmeticException; + } + if (reason == config.deoptReasonConstraint) { + return DeoptimizationReason.RuntimeConstraint; + } + if (reason == config.deoptReasonLoopLimitCheck) { + return DeoptimizationReason.LoopLimitCheck; + } + if (reason == config.deoptReasonAliasing) { + return DeoptimizationReason.Aliasing; + } + if (reason == config.deoptReasonTransferToInterpreter) { + return DeoptimizationReason.TransferToInterpreter; + } + throw new JVMCIError("%x", reason); + } + + @Override + public long getMemorySize(JavaConstant constant) { + if (constant.getJavaKind() == JavaKind.Object) { + HotSpotResolvedObjectType lookupJavaType = lookupJavaType(constant); + + if (lookupJavaType == null) { + return 0; + } else { + if (lookupJavaType.isArray()) { + // TODO(tw): Add compressed pointer support. + int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object()); + ResolvedJavaType elementType = lookupJavaType.getComponentType(); + JavaKind elementKind = elementType.getJavaKind(); + final int headerSize = getArrayBaseOffset(elementKind); + TargetDescription target = runtime.getHostJVMCIBackend().getTarget(); + int sizeOfElement = getArrayIndexScale(elementKind); + int alignment = target.wordSize; + int log2ElementSize = CodeUtil.log2(sizeOfElement); + return computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize); + } + return lookupJavaType.instanceSize(); + } + } else { + return constant.getJavaKind().getByteCount(); + } + } + + /** + * Computes the size of the memory chunk allocated for an array. This size accounts for the + * array header size, body size and any padding after the last element to satisfy object + * alignment requirements. + * + * @param length the number of elements in the array + * @param alignment the object alignment requirement + * @param headerSize the size of the array header + * @param log2ElementSize log2 of the size of an element in the array + */ + public static int computeArrayAllocationSize(int length, int alignment, int headerSize, int log2ElementSize) { + int size = (length << log2ElementSize) + headerSize + (alignment - 1); + int mask = ~(alignment - 1); + return size & mask; + } +}