/*
* Copyright (c) 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.oracle.max.vm.ext.t1x;
import static com.sun.max.vm.compiler.CallEntryPoint.*;
import static com.sun.max.vm.stack.JVMSFrameLayout.*;
import com.oracle.max.cri.intrinsics.*;
import com.sun.max.annotate.*;
import com.sun.max.unsafe.*;
import com.sun.max.vm.actor.holder.*;
import com.sun.max.vm.actor.member.*;
import com.sun.max.vm.runtime.*;
/**
* Collection of methods called from (or inlined by) T1X templates.
* They may be annotated with {@link NEVER_INLINE} to keep the
* template code small or to work around these constraints:
* <ul>
* <li>T1X templates cannot contain scalar literals</li>
* <li>T1X templates cannot contain calls to {@link CompilerStub compiler stubs}</li>
* </ul>
*/
public class T1XRuntime {
// ==========================================================================================================
// == Resolution routines ===================================================================================
// ==========================================================================================================
public static Address resolveAndSelectVirtualMethod(Object receiver, ResolutionGuard.InPool guard) {
final VirtualMethodActor virtualMethodActor = Snippets.resolveVirtualMethod(guard);
Address vtableEntryPoint = Snippets.selectNonPrivateVirtualMethod(receiver, virtualMethodActor).asAddress();
return vtableEntryPoint.plus(BASELINE_ENTRY_POINT.offset() - VTABLE_ENTRY_POINT.offset());
}
public static Address resolveAndSelectInterfaceMethod(ResolutionGuard.InPool guard, final Object receiver) {
final InterfaceMethodActor declaredInterfaceMethod = Snippets.resolveInterfaceMethod(guard);
final Address vtableEntryPoint = Snippets.selectInterfaceMethod(receiver, declaredInterfaceMethod).asAddress();
return vtableEntryPoint.plus(BASELINE_ENTRY_POINT.offset() - VTABLE_ENTRY_POINT.offset());
}
public static Address resolveSpecialMethod(ResolutionGuard.InPool guard) {
final VirtualMethodActor virtualMethod = Snippets.resolveSpecialMethod(guard);
return Snippets.makeEntrypoint(virtualMethod, BASELINE_ENTRY_POINT);
}
public static Address resolveStaticMethod(ResolutionGuard.InPool guard) {
final StaticMethodActor staticMethod = Snippets.resolveStaticMethod(guard);
Snippets.makeHolderInitialized(staticMethod);
return Snippets.makeEntrypoint(staticMethod, BASELINE_ENTRY_POINT);
}
public static Object resolveClassForNewAndCreate(ResolutionGuard guard) {
final ClassActor classActor = Snippets.resolveClassForNew(guard);
Snippets.makeClassInitialized(classActor);
final Object tuple = Snippets.createTupleOrHybrid(classActor);
return tuple;
}
// ==========================================================================================================
// == Field access ================================================================================
// ==========================================================================================================
/**
* Inserts any necessary memory barriers before a volatile read as required by the JMM.
*/
@INLINE
public static void preVolatileRead() {
MemoryBarriers.barrier(MemoryBarriers.JMM_PRE_VOLATILE_READ);
}
/**
* Inserts any necessary memory barriers after a volatile read as required by the JMM.
*/
@INLINE
public static void postVolatileRead() {
MemoryBarriers.barrier(MemoryBarriers.JMM_POST_VOLATILE_READ);
}
/**
* Inserts any necessary memory barriers before a volatile read as required by the JMM.
*/
@INLINE
public static void preVolatileWrite() {
MemoryBarriers.barrier(MemoryBarriers.JMM_PRE_VOLATILE_WRITE);
}
/**
* Inserts any necessary memory barriers after a volatile read as required by the JMM.
*/
@INLINE
public static void postVolatileWrite() {
MemoryBarriers.barrier(MemoryBarriers.JMM_POST_VOLATILE_WRITE);
}
// ==========================================================================================================
// == Misc routines =========================================================================================
// ==========================================================================================================
public static int[] createMultianewarrayDimensions(Pointer sp, int n) {
int[] dims = new int[n];
for (int i = 0; i < n; i++) {
int len;
if (T1X.isAMD64()) {
int offset = (n - i - 1) * JVMS_SLOT_SIZE;
len = sp.readInt(offset);
} else {
throw T1X.unimplISA();
}
Snippets.checkArrayDimension(len);
dims[i] = len;
}
return dims;
}
@NEVER_INLINE("T1X code cannot call compiler stubs")
public static int f2i(float value) {
return (int) value;
}
@NEVER_INLINE("T1X code cannot call compiler stubs")
public static long f2l(float value) {
return (long) value;
}
@NEVER_INLINE("T1X code cannot call compiler stubs")
public static int d2i(double value) {
return (int) value;
}
@NEVER_INLINE("T1X code cannot call compiler stubs")
public static long d2l(double value) {
return (long) value;
}
}