Commit 0d745e04 authored by Vít Kabele's avatar Vít Kabele

Shadow{Object|Class}Table is now instantiated. SHVM context in all the main classes.

parent 3c3628e6
Pipeline #4451 passed with stages
in 3 minutes and 2 seconds
......@@ -44,6 +44,13 @@ public class SHVM implements ISHVM {
*/
private final RequestDispatcher __requestDispatcher;
/**
* Shadow VM context. It's used in the request dispatcher,
* but since the name is {@link SHVMContext} it does make
* a sense to initialize the instance here.
*/
private final SHVMContext __shvmContext;
/**
* Public constructor
......@@ -61,7 +68,8 @@ public class SHVM implements ISHVM {
__log = logger;
__debug = debug;
__requestDispatcher = new RequestDispatcher ();
__shvmContext = new SHVMContext (__log);
__requestDispatcher = new RequestDispatcher (__shvmContext);
}
@Override
......
......@@ -7,43 +7,78 @@ package ch.usi.dag.dislreserver;
import ch.usi.dag.dislreserver.shadow.ShadowClassTable;
import ch.usi.dag.dislreserver.shadow.ShadowObjectTable;
import ch.usi.dag.util.logging.Logger;
/**
* This class is meant to keep all the information about
* Shadow object and classes, remote analysis methods etc.
*
* It's the main class that ties together the components
* of SHVM application.
*/
public class SHVMContext {
private final Logger __logger;
private final ShadowClassTable __shadowClassTable;
private final ShadowObjectTable __shadowObjectTable;
private final AnalysisResolver __analysisResolver;
SHVMContext(
final ShadowClassTable shadowClassTable,
final ShadowObjectTable shadowObjectTable,
final AnalysisResolver analysisResolver
) {
__shadowClassTable = shadowClassTable;
__shadowObjectTable = shadowObjectTable;
__analysisResolver = analysisResolver;
/**
* Default constructor. Creates the instances of
* dependent classes and provide them the reference
* to itself.
*
* This can be possibly extended to use some factory
* based magic if more complicated initialization
* will be required.
*/
SHVMContext(final Logger logger) {
__shadowClassTable = new ShadowClassTable (this);
__shadowObjectTable = new ShadowObjectTable (this);
__analysisResolver = new AnalysisResolver (this);
__logger = logger;
}
ShadowClassTable getShadowClassTable()
/**
* Gets the {@link ShadowClassTable}
* @return An registered instance of {@link ShadowClassTable}
*/
public ShadowClassTable getShadowClassTable()
{
return __shadowClassTable;
}
ShadowObjectTable getShadowObjectTable()
/**
* Gets the {@link ShadowObjectTable}
* @return An registered instance of {@link ShadowObjectTable}
*/
public ShadowObjectTable getShadowObjectTable()
{
return __shadowObjectTable;
}
AnalysisResolver getAnalysisResolver()
/**
* Gets the {@link AnalysisResolver}
* @return An registered instance of {@link AnalysisResolver}
*/
public AnalysisResolver getAnalysisResolver()
{
return __analysisResolver;
}
/**
* Gets the {@link Logger}
* @return An registered instance of {@link Logger}
*/
public Logger getLogger()
{
return __logger;
}
}
......@@ -15,17 +15,19 @@ public class AnalysisDispatcher {
protected final ATEManager ateManager = new ATEManager();
protected final ObjectFreeTaskExecutor oftExec =
new ObjectFreeTaskExecutor(ateManager);
protected final ObjectFreeTaskExecutor oftExec;
public AnalysisDispatcher() {
AnalysisDispatcher(final SHVMContext shvmContext) {
super();
oftExec =
new ObjectFreeTaskExecutor(ateManager, shvmContext);
// start object free thread
oftExec.start();
}
public void addTask(long orderingID,
void addTask(long orderingID,
List<AnalysisInvocation> invocations) {
// add task to the executor
......@@ -38,7 +40,7 @@ public class AnalysisDispatcher {
}
public void objectsFreedEvent(long[] objFreeIDs) {
void objectsFreedEvent(long[] objFreeIDs) {
// create object free task
ObjectFreeTask oft = new ObjectFreeTask(objFreeIDs, globalEpoch);
......
......@@ -9,19 +9,45 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* The executor for {@link ObjectFreeTask} tasks.
*/
class ObjectFreeTaskExecutor extends Thread {
protected final ATEManager ateManager;
final ATEManager ateManager;
protected final BlockingQueue<ObjectFreeTask> taskQueue =
final BlockingQueue<ObjectFreeTask> taskQueue =
new LinkedBlockingQueue<ObjectFreeTask>();
public ObjectFreeTaskExecutor(ATEManager ateManager) {
/**
* Current shadow VM context.
*/
final SHVMContext __shvmContext;
/**
* Default constructor.
*
* @param ateManager
* @param shvmContext Shadow VM context.
*/
ObjectFreeTaskExecutor(
final ATEManager ateManager,
final SHVMContext shvmContext
)
{
super();
this.ateManager = ateManager;
__shvmContext = shvmContext;
}
public void addTask(ObjectFreeTask oft) {
/**
* Enqueue new task to execute.
*
* @param oft
*/
void addTask(ObjectFreeTask oft) {
taskQueue.add(oft);
}
......@@ -29,11 +55,13 @@ class ObjectFreeTaskExecutor extends Thread {
// TODO free events should be sent to analysis that sees the shadow object
final ShadowObjectTable shadowObjectTable = __shvmContext.getShadowObjectTable ();
// retrieve shadow object
ShadowObject obj = ShadowObjectTable.get(objectFreeID);
ShadowObject obj = shadowObjectTable.get(objectFreeID);
// get all analysis objects
Set<RemoteAnalysis> raSet = AnalysisResolver.getAllAnalyses();
Set<RemoteAnalysis> raSet = __shvmContext.getAnalysisResolver ().getAllAnalyses();
// invoke object free
for (RemoteAnalysis ra : raSet) {
......@@ -55,9 +83,16 @@ class ObjectFreeTaskExecutor extends Thread {
}
// release shadow object
ShadowObjectTable.freeShadowObject(obj);
shadowObjectTable.freeShadowObject(obj);
}
/**
* Thread main method.
*
* Dequeue single {@link ObjectFreeTask} wait for all the analysis executors
* to finish the closing epoch, invoke
*/
public void run() {
try {
......
......@@ -19,12 +19,21 @@ import ch.usi.dag.dislreserver.shadow.ShadowObjectTable;
*/
public final class AnalysisHandler implements RequestHandler {
private AnalysisDispatcher dispatcher = new AnalysisDispatcher ();
private AnalysisDispatcher dispatcher;
public AnalysisDispatcher getDispatcher() {
return dispatcher;
}
private final SHVMContext __shvmContext;
AnalysisHandler(
final SHVMContext shvmContext
) {
__shvmContext = shvmContext;
dispatcher = new AnalysisDispatcher (__shvmContext);
}
@Override
public void handle (
final DataInputStream is, final DataOutputStream os, final boolean debug
......@@ -77,7 +86,7 @@ public final class AnalysisHandler implements RequestHandler {
// read method id from network and retrieve method
final short methodId = is.readShort ();
AnalysisMethodHolder amh = AnalysisResolver.getMethod (methodId);
AnalysisMethodHolder amh = __shvmContext.getAnalysisResolver ().getMethod (methodId);
// *** retrieve method argument values ***
......@@ -190,7 +199,7 @@ public final class AnalysisHandler implements RequestHandler {
if (ShadowObject.class.isAssignableFrom (argClass)) {
// zero tag means null
final long tag = is.readLong();
args [index] = (tag == 0) ? null : ShadowObjectTable.get (tag);
args [index] = (tag == 0) ? null : __shvmContext.getShadowObjectTable().get (tag);
return Long.SIZE / Byte.SIZE;
}
......
......@@ -24,22 +24,22 @@ import java.util.Set;
final class AnalysisResolver {
private static final String METHOD_DELIM = ".";
private static final Map <Short, AnalysisMethodHolder>
private final Map <Short, AnalysisMethodHolder>
methodMap = new HashMap <Short, AnalysisMethodHolder> ();
/**
* Cache the analysis classes
*/
private static final Map <String, RemoteAnalysis>
private final Map <String, RemoteAnalysis>
analysisMap = new HashMap <String, RemoteAnalysis> ();
/**
* for fast set access - contains all values from analysisMap
*/
private static final Set <RemoteAnalysis>
private final Set <RemoteAnalysis>
analysisSet = new HashSet <RemoteAnalysis> ();
//
private final SHVMContext __shvmContext;
/**
* Holds the instance of analysis and the analysis method.
......@@ -64,9 +64,15 @@ final class AnalysisResolver {
}
}
AnalysisResolver()
{
/**
* Default constructor.
*
* @param shvmContext Current shadow VM context
*/
AnalysisResolver(final SHVMContext shvmContext)
{
__shvmContext = shvmContext;
}
/**
......@@ -79,7 +85,7 @@ final class AnalysisResolver {
* @return
* @throws DiSLREServerException
*/
private static AnalysisMethodHolder resolveMethod (
private AnalysisMethodHolder resolveMethod (
String methodStr
) throws DiSLREServerException
{
......@@ -127,7 +133,7 @@ final class AnalysisResolver {
* @return Method
* @throws DiSLREServerException
*/
private static Method __getAnalysisMethod (
private Method __getAnalysisMethod (
final RemoteAnalysis analysis, final String methodName
) throws DiSLREServerException
{
......@@ -168,7 +174,7 @@ final class AnalysisResolver {
* @return Method handler
* @throws DiSLREServerException
*/
static AnalysisMethodHolder getMethod (final short methodId)
AnalysisMethodHolder getMethod (final short methodId)
throws DiSLREServerException
{
AnalysisMethodHolder result = methodMap.get (methodId);
......@@ -187,7 +193,7 @@ final class AnalysisResolver {
* @param methodString
* @throws DiSLREServerException
*/
public static void registerMethodId (
void registerMethodId (
final short methodId, String methodString
) throws DiSLREServerException
{
......@@ -200,7 +206,7 @@ final class AnalysisResolver {
*
* @return Set of all analyses
*/
public static Set <RemoteAnalysis> getAllAnalyses () {
Set <RemoteAnalysis> getAllAnalyses () {
return analysisSet;
}
}
......@@ -10,6 +10,20 @@ import java.io.IOException;
*/
public final class RegAnalysisHandler implements RequestHandler {
/**
* Current {@link SHVM} context.
*/
private final SHVMContext __shvmContext;
/**
* Default constructor.
*
* @param shvmContext
*/
RegAnalysisHandler(final SHVMContext shvmContext) {
__shvmContext = shvmContext;
}
@Override
public void handle(
final DataInputStream is,
......@@ -22,7 +36,7 @@ public final class RegAnalysisHandler implements RequestHandler {
String methodString = is.readUTF();
// register method
AnalysisResolver.registerMethodId(methodId, methodString);
__shvmContext.getAnalysisResolver ().registerMethodId(methodId, methodString);
if (debug) {
System.out.printf(
......
......@@ -35,18 +35,17 @@ public final class RequestDispatcher {
private Collection <RequestHandler> __handlers;
/**
* Current shadow VM context.
*/
private final SHVMContext __shvmContext;
/**
* Constructor
*/
RequestDispatcher() {
RequestDispatcher(final SHVMContext shvmContext) {
__shvmContext = new SHVMContext (
new ShadowClassTable (),
new ShadowObjectTable (),
new AnalysisResolver ()
);
__shvmContext = shvmContext;
//
// Register request handlers.
......@@ -54,13 +53,13 @@ public final class RequestDispatcher {
//
final Map <Byte, RequestHandler> requestMap = new HashMap <Byte, RequestHandler> ();
requestMap.put (__REQUEST_ID_CLOSE__, new CloseHandler (__shvmContext, this));
AnalysisHandler anlHndl = new AnalysisHandler ();
AnalysisHandler anlHndl = new AnalysisHandler (__shvmContext);
requestMap.put (__REQUEST_ID_INVOKE_ANALYSIS__, anlHndl);
requestMap.put (__REQUEST_ID_OBJECT_FREE__, new ObjectFreeHandler (anlHndl));
requestMap.put (__REQUEST_ID_NEW_CLASS__, new NewClassHandler (__shvmContext));
requestMap.put (__REQUEST_ID_CLASS_INFO__, new ClassInfoHandler (__shvmContext));
requestMap.put (__REQUEST_ID_STRING_INFO__, new StringInfoHandler (__shvmContext));
requestMap.put (__REQUEST_ID_REGISTER_ANALYSIS__, new RegAnalysisHandler ());
requestMap.put (__REQUEST_ID_REGISTER_ANALYSIS__, new RegAnalysisHandler (__shvmContext));
requestMap.put (__REQUEST_ID_THREAD_INFO__, new ThreadInfoHandler(__shvmContext));
requestMap.put (__REQUEST_ID_THREAD_END__, new ThreadEndHandler(anlHndl));
......
......@@ -5,6 +5,7 @@ import java.util.concurrent.atomic.AtomicReference;
import ch.usi.dag.dislreserver.DiSLREServerFatalException;
import ch.usi.dag.dislreserver.Logging;
import ch.usi.dag.dislreserver.SHVMContext;
import org.objectweb.asm.Type;
import ch.usi.dag.util.asm.ClassNodeHelper;
......@@ -39,7 +40,7 @@ public final class ShadowClassTable {
private static final Type __JAVA_LANG_CLASS_TYPE__;
//
private final SHVMContext __shvmContext;
private static final ConcurrentHashMap <Integer, ShadowClass> shadowClasses;
......@@ -61,16 +62,19 @@ public final class ShadowClassTable {
}
/**
* An empty constructor
* The default constructor.
* Receive the current shadow VM context.
*/
public ShadowClassTable(){}
public ShadowClassTable(final SHVMContext shvmContext){
__shvmContext = shvmContext;
}
public static void loadClass (
public void loadClass (
final String classInternalName, final long classLoaderNetReference,
final byte [] classCode
) {
final ConcurrentHashMap <Type, byte []> classNameMap = classLoaderMap.computeIfAbsent (
__safeClassLoader (ShadowObjectTable.get (classLoaderNetReference)),
__safeClassLoader (__shvmContext.getShadowObjectTable ().get (classLoaderNetReference)),
cl -> new ConcurrentHashMap <> ()
);
......@@ -94,7 +98,7 @@ public final class ShadowClassTable {
//
static ShadowClass newInstance (
ShadowClass newInstance (
final long classNetReference, final Type type,
final String classGenericStr, final ShadowObject classLoader,
final ShadowClass superClass
......@@ -118,7 +122,7 @@ public final class ShadowClassTable {
final ShadowClass previous = shadowClasses.putIfAbsent (classId, result);
if (previous == null) {
ShadowObjectTable.register (result);
__shvmContext.getShadowObjectTable ().register (result);
} else if (previous.equals (result)) {
result = previous;
......@@ -144,7 +148,7 @@ public final class ShadowClassTable {
}
private static ShadowClass __createShadowClass (
private ShadowClass __createShadowClass (
final long netReference, final Type type,
final ShadowClass superClass, ShadowObject classLoader
) {
......@@ -207,7 +211,7 @@ public final class ShadowClassTable {
* @param classId
* @return ShadowClass
*/
static ShadowClass get (final int classId) {
ShadowClass get (final int classId) {
if (classId == 0) {
// reserved for java.lang.Class
return null;
......@@ -224,7 +228,7 @@ public final class ShadowClassTable {
}
static void freeShadowObject (final ShadowObject object) {
void freeShadowObject (final ShadowObject object) {
if (object.isClassInstance ()) {
shadowClasses.remove (object.getClassId ());
......@@ -234,14 +238,16 @@ public final class ShadowClassTable {
}
public static void registerClass (
public void registerClass (
final long netReference, final String typeDescriptor,
final String classGenericStr, final long classLoaderNetReference,
final long superclassNetReference
) {
final ShadowObjectTable shadowObjectTable = __shvmContext.getShadowObjectTable ();
final Type type = Type.getType (typeDescriptor);
final ShadowObject classLoader = ShadowObjectTable.get (classLoaderNetReference);
final ShadowClass superClass = (ShadowClass) ShadowObjectTable.get (superclassNetReference);
final ShadowObject classLoader = shadowObjectTable.get (classLoaderNetReference);
final ShadowClass superClass = (ShadowClass) shadowObjectTable.get (superclassNetReference);
newInstance (netReference, type, classGenericStr, classLoader, superClass);
}
......
......@@ -6,6 +6,7 @@ import java.util.concurrent.ConcurrentHashMap;
import ch.usi.dag.dislreserver.DiSLREServerFatalException;
import ch.usi.dag.dislreserver.Logging;
import ch.usi.dag.dislreserver.SHVMContext;
import org.objectweb.asm.Type;
import ch.usi.dag.util.logging.Logger;
......@@ -15,16 +16,30 @@ public final class ShadowObjectTable {
private static final Logger __log = Logging.getPackageInstance ();
//
private final SHVMContext __shvmContext;
private static final int INITIAL_TABLE_SIZE = 10_000_000;
private static final ConcurrentHashMap <Long, ShadowObject>
private final ConcurrentHashMap <Long, ShadowObject> shadowObjects;
/**
* Default constructor.
*
* @param shvmContext The parent shadow VM context.
*/
public ShadowObjectTable(final SHVMContext shvmContext){
__shvmContext = shvmContext;
shadowObjects = new ConcurrentHashMap <> (INITIAL_TABLE_SIZE);
}
//
static void register (final ShadowObject object) {
/**
* Register new shadow object.
* @param object
*/
void register (final ShadowObject object) {
if (object == null) {
__log.warn ("attempting to register a null shadow object");
return;
......@@ -44,7 +59,7 @@ public final class ShadowObjectTable {
}
public static ShadowObject get (final long netReference) {
public ShadowObject get (final long netReference) {
final long objectId = NetReferenceHelper.getObjectId (netReference);
if (objectId == 0) {
// reserved for null
......@@ -80,10 +95,10 @@ public final class ShadowObjectTable {
private static final Type __THREAD_CLASS_TYPE__ = Type.getType (Thread.class);
private static final Type __STRING_CLASS_TYPE__ = Type.getType (String.class);
private static ShadowObject __createShadowObject (
private ShadowObject __createShadowObject (
final long netReference
) {
final ShadowClass shadowClass = ShadowClassTable.get (
final ShadowClass shadowClass = __shvmContext.getShadowClassTable ().get (
NetReferenceHelper.getClassId (netReference)
);
......@@ -99,18 +114,18 @@ public final class ShadowObjectTable {
}
public static void freeShadowObject (final ShadowObject object) {
public void freeShadowObject (final ShadowObject object) {
shadowObjects.remove (object.getId ());
ShadowClassTable.freeShadowObject (object);
__shvmContext.getShadowClassTable ().freeShadowObject (object);
}
//TODO: find a more elegant way to allow users to traverse the shadow object table
public static Iterator <Entry <Long, ShadowObject>> getIterator () {
public Iterator <Entry <Long, ShadowObject>> getIterator () {
return shadowObjects.entrySet ().iterator ();
}
public static Iterable <ShadowObject> objects () {
public Iterable <ShadowObject> objects () {
return new Iterable <ShadowObject> () {
@Override
public Iterator <ShadowObject> iterator () {
......@@ -122,11 +137,11 @@ public final class ShadowObjectTable {
// TODO LB: Make this interface per-shadow-world instead of static.
public static void registerShadowThread (
public void registerShadowThread (
final long netReference, final String name, final boolean isDaemon
) {
final int shadowClassId = NetReferenceHelper.getClassId (netReference);
final ShadowClass shadowClass = ShadowClassTable.get (shadowClassId);
final ShadowClass shadowClass = __shvmContext.getShadowClassTable ().get (shadowClassId);
final ShadowThread shadowThread = new ShadowThread (
netReference, shadowClass, name, isDaemon
);
......@@ -135,11 +150,11 @@ public final class ShadowObjectTable {
}
public static void registerShadowString (
public void registerShadowString (
final long netReference, final String value
) {
final int shadowClassId = NetReferenceHelper.getClassId (netReference);
final ShadowClass shadowClass = ShadowClassTable.get (shadowClassId);
final ShadowClass shadowClass = __shvmContext.getShadowClassTable ().get (shadowClassId);
final ShadowString shadowString = new ShadowString (
netReference, shadowClass, value
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment