/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.vm.facade;
import gnu.java.lang.VMClassHelper;
import java.io.PrintWriter;
import org.jnode.annotation.Inline;
import org.jnode.annotation.KernelSpace;
import org.jnode.annotation.NoInline;
import org.jnode.annotation.SharedStatics;
import org.jnode.annotation.Uninterruptible;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.objects.Counter;
import org.jnode.vm.objects.Statistic;
/**
* Utility class to share some Vm features.
* For now, it's especially used to know how native methods are implemented in JNode.
*
* @author Fabien DUMINY (fduminy at jnode.org)
*/
@SharedStatics
public class VmUtils {
private static Vm VM_INSTANCE;
/**
* Should assertions be verified?
*/
private static final boolean VERIFY_ASSERTIONS = true;
private static final String NATIVE_CLASSNAME_PREFIX = "Native";
public static boolean couldImplementNativeMethods(String className) {
String clsName = VMClassHelper.getClassNamePortion(className);
return clsName.startsWith(NATIVE_CLASSNAME_PREFIX);
}
public static String getNativeClassName(String className) {
final String pkg = VMClassHelper.getPackagePortion(className);
final String nativeClassName = pkg + ((pkg.length() > 0) ? "." : "")
+ NATIVE_CLASSNAME_PREFIX + VMClassHelper.getClassNamePortion(className);
return nativeClassName;
}
public static boolean allowNatives(String className, String architectureName) {
boolean allowNatives = false;
allowNatives |= className.equals("org.jnode.vm.Unsafe");
/*
allowNatives |= className.equals("org.jnode.vm." + architectureName + ".Unsafe"
+ architectureName.toUpperCase());
*/
allowNatives |= className.contains("org.jnode.vm.") && className.contains(".Unsafe");
return allowNatives;
}
/**
* @return Returns the {@link org.jnode.vm.facade.Vm} instance.
*/
@KernelSpace
@Uninterruptible
public static final Vm getVm() {
return VM_INSTANCE;
}
/**
*
*/
@KernelSpace
@Uninterruptible
public static final void setVm(Vm vm) {
if (VM_INSTANCE != null) {
throw new SecurityException("Vm instance already set");
}
VM_INSTANCE = vm;
}
/**
* Is JNode currently running.
*
* @return true or false
*/
public static final boolean isRunningVm() {
return ((VM_INSTANCE != null) && !VM_INSTANCE.isBootstrap());
}
/**
* Is the bootimage being written?
*
* @return true or false.
*/
public static final boolean isWritingImage() {
return ((VM_INSTANCE == null) || VM_INSTANCE.isBootstrap());
}
/**
* A new type has been resolved by the VM. Create a new MM type to reflect
* the VM type, and associate the MM type with the VM type.
*
* @param vmType The newly resolved type
*/
@Inline
public static void notifyClassResolved(VmType<?> vmType) {
if (VM_INSTANCE != null) {
final VmHeapManager hm = VM_INSTANCE.getHeapManager();
if (hm != null) {
hm.notifyClassResolved(vmType);
}
}
}
public static boolean verifyAssertions() {
return VERIFY_ASSERTIONS;
}
/**
* Assert the given value to be true.
*
* @param value
*/
public static void _assert(boolean value) {
if (!value) {
assertionFailed(null, null);
}
}
/**
* Assert the given value to be true.
*
* @param value
*/
public static void _assert(boolean value, String msg) {
if (!value) {
assertionFailed(msg, null);
}
}
/**
* Assert the given value to be true.
*
* @param value
*/
public static void _assert(boolean value, String msg, String msg2) {
if (!value) {
assertionFailed(msg, msg2);
}
}
/**
* Throw an AssertionError with the given messages.
*
* @param msg
* @param msg2
*/
@NoInline
private static void assertionFailed(String msg, String msg2) {
if ((msg == null) && (msg2 == null)) {
msg = "Assertion failed";
} else if (msg2 != null) {
msg = msg + ": " + msg2;
}
throw new AssertionError(msg);
}
/**
* Dump VM's statistics to the given {@link PrintWriter}.
*
* @param out
*/
public static void dumpStatistics(PrintWriter out) {
final Statistic[] stats = VM_INSTANCE.getStatistics();
for (Statistic stat : stats) {
out.println(stat);
}
}
/**
* Reset VM's counters.
*/
public static void resetCounters() {
final Statistic[] stats = VM_INSTANCE.getStatistics();
for (final Statistic s : stats) {
if (s instanceof Counter) {
((Counter) s).reset();
}
}
}
}