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; ...@@ -21,7 +21,7 @@ import java.util.Set;
* the same name. * the same name.
* *
*/ */
public final class AnalysisResolver { final class AnalysisResolver {
private static final String METHOD_DELIM = "."; private static final String METHOD_DELIM = ".";
private static final Map <Short, AnalysisMethodHolder> private static final Map <Short, AnalysisMethodHolder>
...@@ -33,7 +33,9 @@ public final class AnalysisResolver { ...@@ -33,7 +33,9 @@ public final class AnalysisResolver {
private static final Map <String, RemoteAnalysis> private static final Map <String, RemoteAnalysis>
analysisMap = new HashMap <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> private static final Set <RemoteAnalysis>
analysisSet = new HashSet <RemoteAnalysis> (); analysisSet = new HashSet <RemoteAnalysis> ();
...@@ -42,27 +44,30 @@ public final class AnalysisResolver { ...@@ -42,27 +44,30 @@ public final class AnalysisResolver {
/** /**
* Holds the instance of analysis and the analysis method. * Holds the instance of analysis and the analysis method.
*/ */
public static final class AnalysisMethodHolder { static final class AnalysisMethodHolder {
private final RemoteAnalysis analysisInstance; private final RemoteAnalysis analysisInstance;
private final Method analysisMethod; private final Method analysisMethod;
public AnalysisMethodHolder( AnalysisMethodHolder(
final RemoteAnalysis analysisInstance, final Method analysisMethod final RemoteAnalysis analysisInstance, final Method analysisMethod
) { ) {
this.analysisInstance = analysisInstance; this.analysisInstance = analysisInstance;
this.analysisMethod = analysisMethod; this.analysisMethod = analysisMethod;
} }
public RemoteAnalysis getAnalysisInstance() { RemoteAnalysis getAnalysisInstance() {
return analysisInstance; return analysisInstance;
} }
public Method getAnalysisMethod() { Method getAnalysisMethod() {
return analysisMethod; return analysisMethod;
} }
} }
// AnalysisResolver()
{
}
/** /**
* Resolve the analysis method by name. * Resolve the analysis method by name.
......
package ch.usi.dag.dislreserver; package ch.usi.dag.dislreserver;
import ch.usi.dag.dislreserver.shadow.ShadowClassTable;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
...@@ -9,6 +7,19 @@ import java.io.IOException; ...@@ -9,6 +7,19 @@ import java.io.IOException;
public final class ClassInfoHandler implements RequestHandler { 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 @Override
public void handle ( public void handle (
final DataInputStream is, final DataOutputStream os, final DataInputStream is, final DataOutputStream os,
...@@ -22,10 +33,12 @@ public final class ClassInfoHandler implements RequestHandler { ...@@ -22,10 +33,12 @@ public final class ClassInfoHandler implements RequestHandler {
final long classLoaderNetReference = is.readLong (); final long classLoaderNetReference = is.readLong ();
final long superclassNetReference = is.readLong (); final long superclassNetReference = is.readLong ();
ShadowClassTable.registerClass ( __shvmContext
netReference, typeDescriptor, classGenericStr, .getShadowClassTable ()
classLoaderNetReference, superclassNetReference .registerClass (
); netReference, typeDescriptor, classGenericStr,
classLoaderNetReference, superclassNetReference
);
} catch (final IOException e) { } catch (final IOException e) {
throw new DiSLREServerException (e); throw new DiSLREServerException (e);
......
...@@ -15,17 +15,53 @@ import java.io.DataOutputStream; ...@@ -15,17 +15,53 @@ import java.io.DataOutputStream;
*/ */
public final class CloseHandler implements RequestHandler { 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 @Override
public void handle ( public void handle (
final DataInputStream is, final DataOutputStream os, final boolean debug final DataInputStream is, final DataOutputStream os, final boolean debug
) { ) {
// call exit on all request handlers - waits for all uncompleted actions // 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 (); handler.exit ();
} }
// invoke atExit on all analyses // invoke atExit on all analyses
for (final RemoteAnalysis analysis : AnalysisResolver.getAllAnalyses ()) { for (final RemoteAnalysis analysis : __shvmContext.getAnalysisResolver ().getAllAnalyses ()) {
try { try {
analysis.atExit (); analysis.atExit ();
......
...@@ -15,6 +15,19 @@ import java.io.IOException; ...@@ -15,6 +15,19 @@ import java.io.IOException;
*/ */
public class NewClassHandler implements RequestHandler { 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 @Override
public void handle ( public void handle (
final DataInputStream is, final DataOutputStream os, final boolean debug final DataInputStream is, final DataOutputStream os, final boolean debug
...@@ -27,7 +40,7 @@ public class NewClassHandler implements RequestHandler { ...@@ -27,7 +40,7 @@ public class NewClassHandler implements RequestHandler {
final byte [] classCode = new byte [classCodeLength]; final byte [] classCode = new byte [classCodeLength];
is.readFully (classCode); is.readFully (classCode);
ShadowClassTable.loadClass ( __shvmContext.getShadowClassTable ().loadClass (
classInternalName, classLoaderNetReference, classCode classInternalName, classLoaderNetReference, classCode
); );
......
...@@ -9,6 +9,19 @@ import java.io.IOException; ...@@ -9,6 +9,19 @@ import java.io.IOException;
public final class StringInfoHandler implements RequestHandler { 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 @Override
public void handle ( public void handle (
final DataInputStream is, final DataOutputStream os, final DataInputStream is, final DataOutputStream os,
...@@ -19,7 +32,7 @@ public final class StringInfoHandler implements RequestHandler { ...@@ -19,7 +32,7 @@ public final class StringInfoHandler implements RequestHandler {
final long netReference = is.readLong (); final long netReference = is.readLong ();
final String value = is.readUTF (); final String value = is.readUTF ();
ShadowObjectTable.registerShadowString (netReference, value); __shvmContext.getShadowObjectTable ().registerShadowString (netReference, value);
} catch (final IOException e) { } catch (final IOException e) {
throw new DiSLREServerException (e); throw new DiSLREServerException (e);
......
...@@ -9,7 +9,7 @@ public class ThreadEndHandler implements RequestHandler { ...@@ -9,7 +9,7 @@ public class ThreadEndHandler implements RequestHandler {
final AnalysisHandler analysisHandler; final AnalysisHandler analysisHandler;
public ThreadEndHandler(AnalysisHandler anlHndl) { ThreadEndHandler(AnalysisHandler anlHndl) {
analysisHandler = anlHndl; analysisHandler = anlHndl;
} }
......
...@@ -12,6 +12,19 @@ import java.io.IOException; ...@@ -12,6 +12,19 @@ import java.io.IOException;
*/ */
public class ThreadInfoHandler implements RequestHandler { 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 @Override
public void handle ( public void handle (
final DataInputStream is, final DataOutputStream os, final DataInputStream is, final DataOutputStream os,
...@@ -23,7 +36,7 @@ public class ThreadInfoHandler implements RequestHandler { ...@@ -23,7 +36,7 @@ public class ThreadInfoHandler implements RequestHandler {
final String name = is.readUTF (); final String name = is.readUTF ();
final boolean isDaemon = is.readBoolean (); final boolean isDaemon = is.readBoolean ();
ShadowObjectTable.registerShadowThread ( __shvmContext.getShadowObjectTable ().registerShadowThread (
netReference, name, isDaemon netReference, name, isDaemon
); );
......
package ch.usi.dag.dislreserver; 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.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.util.Collection; import java.util.Collection;
...@@ -28,36 +31,43 @@ public final class RequestDispatcher { ...@@ -28,36 +31,43 @@ public final class RequestDispatcher {
// //
private static RequestHandler [] __dispatchTable; private RequestHandler [] __dispatchTable;
private static Collection <RequestHandler> __handlers;
// private Collection <RequestHandler> __handlers;
private final SHVMContext __shvmContext;
/**
* Constructor
*/
RequestDispatcher() {
__shvmContext = new SHVMContext (
new ShadowClassTable (),
new ShadowObjectTable (),
new AnalysisResolver ()
);
static {
// //
// Register request handlers. // Register request handlers.
// The indices should be in sync with the native agent. // The indices should be in sync with the native agent.
// //
final Map <Byte, RequestHandler> requestMap = new HashMap <Byte, RequestHandler> (); 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 (); AnalysisHandler anlHndl = new AnalysisHandler ();
requestMap.put (__REQUEST_ID_INVOKE_ANALYSIS__, anlHndl); requestMap.put (__REQUEST_ID_INVOKE_ANALYSIS__, anlHndl);
requestMap.put (__REQUEST_ID_OBJECT_FREE__, new ObjectFreeHandler (anlHndl)); requestMap.put (__REQUEST_ID_OBJECT_FREE__, new ObjectFreeHandler (anlHndl));
requestMap.put (__REQUEST_ID_NEW_CLASS__, new NewClassHandler ()); requestMap.put (__REQUEST_ID_NEW_CLASS__, new NewClassHandler (__shvmContext));
requestMap.put (__REQUEST_ID_CLASS_INFO__, new ClassInfoHandler ()); requestMap.put (__REQUEST_ID_CLASS_INFO__, new ClassInfoHandler (__shvmContext));
requestMap.put (__REQUEST_ID_STRING_INFO__, new StringInfoHandler ()); 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 ());
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)); requestMap.put (__REQUEST_ID_THREAD_END__, new ThreadEndHandler(anlHndl));
__handlers = Collections.unmodifiableCollection (requestMap.values ()); __handlers = Collections.unmodifiableCollection (requestMap.values ());
__dispatchTable = __createDispatchTable (requestMap); __dispatchTable = __createDispatchTable (requestMap);
}
/** }
* Constructor
*/
RequestDispatcher() {}
private static RequestHandler [] __createDispatchTable ( private static RequestHandler [] __createDispatchTable (
final Map <Byte, RequestHandler> requestMap final Map <Byte, RequestHandler> requestMap
...@@ -76,6 +86,16 @@ public final class RequestDispatcher { ...@@ -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 ( public boolean dispatch (
final byte requestId, final DataInputStream is, final byte requestId, final DataInputStream is,
final DataOutputStream os, boolean debug final DataOutputStream os, boolean debug
...@@ -104,7 +124,7 @@ public final class RequestDispatcher { ...@@ -104,7 +124,7 @@ public final class RequestDispatcher {
} }
static Iterable <RequestHandler> getAllHandlers () { Iterable <RequestHandler> getAllHandlers () {
return __handlers; return __handlers;
} }
......
...@@ -13,10 +13,14 @@ import ch.usi.dag.util.logging.Logger; ...@@ -13,10 +13,14 @@ import ch.usi.dag.util.logging.Logger;
public final class ShadowClassTable { public final class ShadowClassTable {
/**
* Logger instance
*/
private static final Logger __log = Logging.getPackageInstance (); private static final Logger __log = Logging.getPackageInstance ();
// /**
* Initial size of both hash maps
*/
private static final int __INITIAL_SIZE__ = 10000; private static final int __INITIAL_SIZE__ = 10000;
// //
...@@ -56,7 +60,10 @@ public final class ShadowClassTable { ...@@ -56,7 +60,10 @@ public final class ShadowClassTable {
classLoaderMap.put (BOOTSTRAP_CLASSLOADER, new ConcurrentHashMap <> ()); classLoaderMap.put (BOOTSTRAP_CLASSLOADER, new ConcurrentHashMap <> ());
} }
// /**
* An empty constructor
*/
public ShadowClassTable(){}
public static void loadClass ( public static void loadClass (
final String classInternalName, final long classLoaderNetReference, final String classInternalName, final long classLoaderNetReference,
...@@ -75,6 +82,12 @@ public final class ShadowClassTable { ...@@ -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) { private static ShadowObject __safeClassLoader (final ShadowObject classLoader) {
return (classLoader != null) ? classLoader : BOOTSTRAP_CLASSLOADER; return (classLoader != null) ? classLoader : BOOTSTRAP_CLASSLOADER;
} }
...@@ -188,6 +201,12 @@ public final class ShadowClassTable { ...@@ -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) { static ShadowClass get (final int classId) {
if (classId == 0) { if (classId == 0) {
// reserved for java.lang.Class // 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