Commit 3c3628e6 authored by Vít Kabele's avatar Vít Kabele

SHVMContext added

parent b0ce5943
Pipeline #4429 failed with stages
in 9 seconds
/**
* This file is part of disl project
* Author: Vit Kabele <vit@kabele.me>
* Created on the 22/02/2019
*/
package ch.usi.dag.dislreserver;
import ch.usi.dag.dislreserver.shadow.ShadowClassTable;
import ch.usi.dag.dislreserver.shadow.ShadowObjectTable;
/**
* This class is meant to keep all the information about
* Shadow object and classes, remote analysis methods etc.
*/
public class SHVMContext {
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;
}
ShadowClassTable getShadowClassTable()
{
return __shadowClassTable;
}
ShadowObjectTable getShadowObjectTable()
{
return __shadowObjectTable;
}
AnalysisResolver getAnalysisResolver()
{
return __analysisResolver;
}
}
......@@ -21,7 +21,7 @@ import java.util.Set;
* the same name.
*
*/
public final class AnalysisResolver {
final class AnalysisResolver {
private static final String METHOD_DELIM = ".";
private static final Map <Short, AnalysisMethodHolder>
......@@ -33,7 +33,9 @@ public final class AnalysisResolver {
private static final Map <String, RemoteAnalysis>
analysisMap = new HashMap <String, RemoteAnalysis> ();
// for fast set access - contains all values from analysisMap
/**
* for fast set access - contains all values from analysisMap
*/
private static final Set <RemoteAnalysis>
analysisSet = new HashSet <RemoteAnalysis> ();
......@@ -42,27 +44,30 @@ public final class AnalysisResolver {
/**
* Holds the instance of analysis and the analysis method.
*/
public static final class AnalysisMethodHolder {
static final class AnalysisMethodHolder {
private final RemoteAnalysis analysisInstance;
private final Method analysisMethod;
public AnalysisMethodHolder(
AnalysisMethodHolder(
final RemoteAnalysis analysisInstance, final Method analysisMethod
) {
this.analysisInstance = analysisInstance;
this.analysisMethod = analysisMethod;
}
public RemoteAnalysis getAnalysisInstance() {
RemoteAnalysis getAnalysisInstance() {
return analysisInstance;
}
public Method getAnalysisMethod() {
Method getAnalysisMethod() {
return analysisMethod;
}
}
//
AnalysisResolver()
{
}
/**
* Resolve the analysis method by name.
......
package ch.usi.dag.dislreserver;
import ch.usi.dag.dislreserver.shadow.ShadowClassTable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
......@@ -9,6 +7,19 @@ import java.io.IOException;
public final class ClassInfoHandler implements RequestHandler {
/**
* Reference to the shadow VM context.
* This is used to retrieve/modify the global state
* of SHVM instead of relying on global variables.
*/
private final SHVMContext __shvmContext;
ClassInfoHandler(
final SHVMContext shvmContext
) {
__shvmContext = shvmContext;
}
@Override
public void handle (
final DataInputStream is, final DataOutputStream os,
......@@ -22,10 +33,12 @@ public final class ClassInfoHandler implements RequestHandler {
final long classLoaderNetReference = is.readLong ();
final long superclassNetReference = is.readLong ();
ShadowClassTable.registerClass (
netReference, typeDescriptor, classGenericStr,
classLoaderNetReference, superclassNetReference
);
__shvmContext
.getShadowClassTable ()
.registerClass (
netReference, typeDescriptor, classGenericStr,
classLoaderNetReference, superclassNetReference
);
} catch (final IOException e) {
throw new DiSLREServerException (e);
......
......@@ -15,17 +15,53 @@ import java.io.DataOutputStream;
*/
public final class CloseHandler implements RequestHandler {
/**
* Reference to the shadow VM context.
* This is used to retrieve/modify the global state
* of SHVM instead of relying on global variables.
*/
private final SHVMContext __shvmContext;
/**
* Reference to the request dispatcher.
*/
private final RequestDispatcher __requestDispatcher;
/**
* The default constructor.
*
* @param shvmContext Shadow VM Context
* @param requestDispatcher Request dispatcher instance
*/
CloseHandler(
final SHVMContext shvmContext,
final RequestDispatcher requestDispatcher
) {
__shvmContext = shvmContext;
__requestDispatcher = requestDispatcher;
}
/**
* Handle the Close request. This includes calling exit on each request handler
* and proper ending of all running analyses.
*
* @param is Input stream
* @param os Output stream
* @param debug Debug flag
*/
@Override
public void handle (
final DataInputStream is, final DataOutputStream os, final boolean debug
) {
// call exit on all request handlers - waits for all uncompleted actions
for (final RequestHandler handler : RequestDispatcher.getAllHandlers ()) {
for (final RequestHandler handler : __requestDispatcher.getAllHandlers ()) {
handler.exit ();
}
// invoke atExit on all analyses
for (final RemoteAnalysis analysis : AnalysisResolver.getAllAnalyses ()) {
for (final RemoteAnalysis analysis : __shvmContext.getAnalysisResolver ().getAllAnalyses ()) {
try {
analysis.atExit ();
......
......@@ -15,6 +15,19 @@ import java.io.IOException;
*/
public class NewClassHandler implements RequestHandler {
/**
* Reference to the shadow VM context.
* This is used to retrieve/modify the global state
* of SHVM instead of relying on global variables.
*/
private final SHVMContext __shvmContext;
NewClassHandler(
final SHVMContext shvmContext
) {
__shvmContext = shvmContext;
}
@Override
public void handle (
final DataInputStream is, final DataOutputStream os, final boolean debug
......@@ -27,7 +40,7 @@ public class NewClassHandler implements RequestHandler {
final byte [] classCode = new byte [classCodeLength];
is.readFully (classCode);
ShadowClassTable.loadClass (
__shvmContext.getShadowClassTable ().loadClass (
classInternalName, classLoaderNetReference, classCode
);
......
......@@ -9,6 +9,19 @@ import java.io.IOException;
public final class StringInfoHandler implements RequestHandler {
/**
* Reference to the shadow VM context.
* This is used to retrieve/modify the global state
* of SHVM instead of relying on global variables.
*/
private final SHVMContext __shvmContext;
StringInfoHandler(
final SHVMContext shvmContext
) {
__shvmContext = shvmContext;
}
@Override
public void handle (
final DataInputStream is, final DataOutputStream os,
......@@ -19,7 +32,7 @@ public final class StringInfoHandler implements RequestHandler {
final long netReference = is.readLong ();
final String value = is.readUTF ();
ShadowObjectTable.registerShadowString (netReference, value);
__shvmContext.getShadowObjectTable ().registerShadowString (netReference, value);
} catch (final IOException e) {
throw new DiSLREServerException (e);
......
......@@ -9,7 +9,7 @@ public class ThreadEndHandler implements RequestHandler {
final AnalysisHandler analysisHandler;
public ThreadEndHandler(AnalysisHandler anlHndl) {
ThreadEndHandler(AnalysisHandler anlHndl) {
analysisHandler = anlHndl;
}
......
......@@ -12,6 +12,19 @@ import java.io.IOException;
*/
public class ThreadInfoHandler implements RequestHandler {
/**
* Reference to the shadow VM context.
* This is used to retrieve/modify the global state
* of SHVM instead of relying on global variables.
*/
private final SHVMContext __shvmContext;
ThreadInfoHandler(
final SHVMContext shvmContext
) {
__shvmContext = shvmContext;
}
@Override
public void handle (
final DataInputStream is, final DataOutputStream os,
......@@ -23,7 +36,7 @@ public class ThreadInfoHandler implements RequestHandler {
final String name = is.readUTF ();
final boolean isDaemon = is.readBoolean ();
ShadowObjectTable.registerShadowThread (
__shvmContext.getShadowObjectTable ().registerShadowThread (
netReference, name, isDaemon
);
......
package ch.usi.dag.dislreserver;
import ch.usi.dag.dislreserver.shadow.ShadowClassTable;
import ch.usi.dag.dislreserver.shadow.ShadowObjectTable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.Collection;
......@@ -28,36 +31,43 @@ public final class RequestDispatcher {
//
private static RequestHandler [] __dispatchTable;
private static Collection <RequestHandler> __handlers;
private RequestHandler [] __dispatchTable;
//
private Collection <RequestHandler> __handlers;
private final SHVMContext __shvmContext;
/**
* Constructor
*/
RequestDispatcher() {
__shvmContext = new SHVMContext (
new ShadowClassTable (),
new ShadowObjectTable (),
new AnalysisResolver ()
);
static {
//
// Register request handlers.
// The indices should be in sync with the native agent.
//
final Map <Byte, RequestHandler> requestMap = new HashMap <Byte, RequestHandler> ();
requestMap.put (__REQUEST_ID_CLOSE__, new CloseHandler ());
requestMap.put (__REQUEST_ID_CLOSE__, new CloseHandler (__shvmContext, this));
AnalysisHandler anlHndl = new AnalysisHandler ();
requestMap.put (__REQUEST_ID_INVOKE_ANALYSIS__, anlHndl);
requestMap.put (__REQUEST_ID_OBJECT_FREE__, new ObjectFreeHandler (anlHndl));
requestMap.put (__REQUEST_ID_NEW_CLASS__, new NewClassHandler ());
requestMap.put (__REQUEST_ID_CLASS_INFO__, new ClassInfoHandler ());
requestMap.put (__REQUEST_ID_STRING_INFO__, new StringInfoHandler ());
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_THREAD_INFO__, new ThreadInfoHandler());
requestMap.put (__REQUEST_ID_THREAD_INFO__, new ThreadInfoHandler(__shvmContext));
requestMap.put (__REQUEST_ID_THREAD_END__, new ThreadEndHandler(anlHndl));
__handlers = Collections.unmodifiableCollection (requestMap.values ());
__dispatchTable = __createDispatchTable (requestMap);
}
/**
* Constructor
*/
RequestDispatcher() {}
}
private static RequestHandler [] __createDispatchTable (
final Map <Byte, RequestHandler> requestMap
......@@ -76,6 +86,16 @@ public final class RequestDispatcher {
//
/**
* Dispatch the request.
*
* @param requestId
* @param is Input stream
* @param os Output stream
* @param debug Debug flag
* @return True if request was of type __REQUEST_ID_CLOSE__, false otherwise
* @throws DiSLREServerException When there is no available request handler.
*/
public boolean dispatch (
final byte requestId, final DataInputStream is,
final DataOutputStream os, boolean debug
......@@ -104,7 +124,7 @@ public final class RequestDispatcher {
}
static Iterable <RequestHandler> getAllHandlers () {
Iterable <RequestHandler> getAllHandlers () {
return __handlers;
}
......
......@@ -13,10 +13,14 @@ import ch.usi.dag.util.logging.Logger;
public final class ShadowClassTable {
/**
* Logger instance
*/
private static final Logger __log = Logging.getPackageInstance ();
//
/**
* Initial size of both hash maps
*/
private static final int __INITIAL_SIZE__ = 10000;
//
......@@ -56,7 +60,10 @@ public final class ShadowClassTable {
classLoaderMap.put (BOOTSTRAP_CLASSLOADER, new ConcurrentHashMap <> ());
}
//
/**
* An empty constructor
*/
public ShadowClassTable(){}
public static void loadClass (
final String classInternalName, final long classLoaderNetReference,
......@@ -75,6 +82,12 @@ public final class ShadowClassTable {
}
}
/**
* Returns name of the classloader, or the default on if absent.
*
* @param classLoader ClassLoader shadow object
* @return ShadowObject of classloader.
*/
private static ShadowObject __safeClassLoader (final ShadowObject classLoader) {
return (classLoader != null) ? classLoader : BOOTSTRAP_CLASSLOADER;
}
......@@ -188,6 +201,12 @@ public final class ShadowClassTable {
}
/**
* Return shadow class for given classId or null for zero.
*
* @param classId
* @return ShadowClass
*/
static ShadowClass get (final int classId) {
if (classId == 0) {
// reserved for java.lang.Class
......
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