package vm;
import reflect.ObjectInfo;
import icecaptools.IcecapCompileMe;
public class Process {
private ProcessLogic logic;
private int[] stack;
private ProcessExecutor processExecuter;
private SP sp;
private int runtime_data;
private static StackAnalyser stackAnalyser;
private boolean isFinished;
public boolean isFinished() {
return isFinished;
}
@IcecapCompileMe
public Process(ProcessLogic logic, int[] stack) {
this.logic = logic;
this.stack = stack;
this.isFinished = false;
processExecuter = new ProcessExecutor(this);
switch (Machine.architecture) {
case Machine.X86_64:
sp = new X86_64SP();
break;
case Machine.CR16_C:
case Machine.X86_32:
default:
sp = new X86_32SP();
break;
}
if (stackAnalyser != null)
{
stackAnalyser.addStack(stack);
}
}
@IcecapCompileMe
public void transferTo(Process nextProcess) {
transfer(this, nextProcess);
}
public final void initialize() {
executeWithStack(processExecuter, stack);
}
private static native void transfer(Process currentProcess,
Process nextProcess);
private static native void executeWithStack(Runnable runnable,
int[] schedulerStack);
private static class ProcessExecutor implements Runnable {
private Process thisProcess;
private boolean isStarted;
ProcessExecutor(Process thisProcess) {
this.thisProcess = thisProcess;
}
@Override
@IcecapCompileMe
public void run() {
isStarted = false;
thisProcess.transferTo(thisProcess);
if (!isStarted) {
isStarted = true;
} else {
try {
thisProcess.logic.run();
} catch (Throwable t) {
thisProcess.logic.catchError(t);
}
vm.ClockInterruptHandler.instance.yield();
thisProcess.isFinished = true;
for (;;)
;
}
}
}
private static abstract class SP {
public abstract int getCSP();
public abstract int getJSP();
}
private static class X86_32SP extends SP {
public int csp;
public int jsp;
@Override
public int getCSP() {
return csp;
}
@Override
public int getJSP() {
return jsp;
}
}
private static class X86_64SP extends SP {
public long csp;
public long jsp;
@Override
public int getCSP() {
return (int) csp;
}
@Override
public int getJSP() {
return (int) jsp;
}
}
public int[] getStack() {
return stack;
}
public short getJavaStackTop() {
int top = sp.getJSP();
return getIndex(top);
}
public int getCStackTop() {
int top = sp.getCSP();
return getIndex(top);
}
private short getIndex(int top) {
return (short) ((top - ObjectInfo.getAddress(stack)) >> 2);
}
public static void enableStackAnalysis()
{
stackAnalyser = new FullStackAnanlyser();
}
public static void reportStackUsage()
{
if (stackAnalyser != null)
{
stackAnalyser.reportStackUsage();
}
}
}