Commit a7504c05 authored by Lukáš Marek's avatar Lukáš Marek

Remote evaluation supports all basic types

parent 37cb40f9
......@@ -32,10 +32,16 @@ static const int FALSE = 0;
static const char * DEFAULT_HOST = "localhost";
static const char * DEFAULT_PORT = "11218";
// initial buffer size
static const size_t INIT_BUFF_SIZE = 512;
// max limit buffer size
static const size_t MAX_BUFF_SIZE = 8192;
typedef struct {
unsigned char * buff;
size_t occupied;
size_t capacity;
volatile int available;
} buffer;
// Messages - should be in sync with java server
......@@ -55,17 +61,34 @@ static jrawMonitorID global_lock;
// access must be protected by monitor
static int connection = 0;
// TODO remove
static buffer redispatch_buff;
// this number decides maximum number of threads writing
// also it determines memory consumption because buffers are left allocated
// DISP_BUFF_COUNT * MAX_BUFF_SIZE says max memory occupation
// cannot be static const :(
#define DISP_BUFF_COUNT 512
static volatile buffer redispatch_buffs[DISP_BUFF_COUNT];
// ******************* Buffer routines *******************
void buffer_init(buffer * b) {
const size_t INIT_BUFF_SIZE = 1024;
b->buff = (unsigned char *) malloc(INIT_BUFF_SIZE);
b->capacity = INIT_BUFF_SIZE;
b->occupied = 0;
b->available = TRUE;
}
void buffer_free(buffer * b) {
free(b->buff);
b->buff = NULL;
b->capacity = 0;
b->occupied = 0;
b->available = TRUE;
}
void buffer_fill(buffer * b, const void * data, size_t data_length) {
......@@ -92,14 +115,14 @@ void buffer_fill(buffer * b, const void * data, size_t data_length) {
void buffer_clean(buffer * b) {
b->occupied = 0;
}
// if capacity is higher then limit "reset" buffer
// should keep memory consumption in limits
if(b->capacity > MAX_BUFF_SIZE) {
void buffer_free(buffer * b) {
buffer_free(b);
buffer_init(b);
}
free(b->buff);
b->buff = NULL;
b->capacity = 0;
b->occupied = 0;
}
......@@ -561,8 +584,6 @@ JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved)
// ******************* Sending helper methods *******************
// TODO if you add buffer as param it can server for other functions also
void pack_boolean(buffer * buff, jboolean to_send) {
buffer_fill(buff, &to_send, sizeof(jboolean));
......@@ -597,18 +618,6 @@ void pack_long(buffer * buff, jlong to_send) {
buffer_fill(buff, &nts, sizeof(jlong));
}
void pack_float(buffer * buff, jfloat to_send) {
jfloat nts = htonl(to_send);
buffer_fill(buff, &nts, sizeof(jfloat));
}
void pack_double(buffer * buff, jdouble to_send) {
jdouble nts = htobe64(to_send);
buffer_fill(buff, &nts, sizeof(jdouble));
}
void pack_string_utf8(buffer * buff, const void * string_utf8,
uint16_t size_in_bytes) {
......@@ -662,88 +671,118 @@ void analysis_start(buffer * buff, jint analysis_method_id) {
void analysis_end(buffer * buff) {
// TODO should send the buffer with critical section
// TODO you can easily buffer messages
// - don't send buffer after flush but wait for other fushes
// - send remaining in shutdown
// TODO you don't need to necessarily send the buffer
// it is possible to put it into the bigger shared buffer and send it
// when it is full
enter_critical_section(jvmti_env, global_lock);
{
send_data(connection, buff->buff, buff->occupied);
}
exit_critical_section(jvmti_env, global_lock);
buffer_clean(buff);
}
jint acquire_redispatch_buff() {
// TODO find buffer with available FALSE
return 0;
}
void release_redispatch_buff(jint buff_pos) {
// TODO set available to TRUE
}
// ******************* REDispatch methods *******************
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_analysisStart
// TODO add session id buffers
JNIEXPORT jint JNICALL Java_ch_usi_dag_dislre_REDispatch_analysisStart
(JNIEnv * jni_env, jclass this_class, jint analysis_method_id) {
// get session id - free buffer pos
jint sid = acquire_redispatch_buff();
analysis_start(&redispatch_buff, analysis_method_id);
// find free buffer
return sid;
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_analysisEnd
(JNIEnv * jni_env, jclass this_class) {
(JNIEnv * jni_env, jclass this_class, jint sid) {
analysis_end(&redispatch_buff);
release_redispatch_buff(sid);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendBoolean
(JNIEnv * jni_env, jclass this_class, jboolean to_send) {
(JNIEnv * jni_env, jclass this_class, jint sid, jboolean to_send) {
pack_boolean(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendByte
(JNIEnv * jni_env, jclass this_class, jbyte to_send) {
(JNIEnv * jni_env, jclass this_class, jint sid, jbyte to_send) {
pack_byte(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendChar
(JNIEnv * jni_env, jclass this_class, jchar to_send) {
(JNIEnv * jni_env, jclass this_class, jint sid, jchar to_send) {
pack_char(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendShort
(JNIEnv * jni_env, jclass this_class, jshort to_send) {
(JNIEnv * jni_env, jclass this_class, jint sid, jshort to_send) {
pack_short(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendInt
(JNIEnv * jni_env, jclass this_class, jint to_send) {
(JNIEnv * jni_env, jclass this_class, jint sid, jint to_send) {
pack_int(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendLong
(JNIEnv * jni_env, jclass this_class, jlong to_send) {
(JNIEnv * jni_env, jclass this_class, jint sid, jlong to_send) {
pack_long(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendFloat
(JNIEnv * jni_env, jclass this_class, jfloat to_send) {
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendFloatAsInt
(JNIEnv * jni_env, jclass this_class, jint sid, jint to_send) {
pack_float(&redispatch_buff, to_send);
pack_int(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendDouble
(JNIEnv * jni_env, jclass this_class, jdouble to_send) {
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendDoubleAsLong
(JNIEnv * jni_env, jclass this_class, jint sid, jlong to_send) {
pack_double(&redispatch_buff, to_send);
pack_long(&redispatch_buff, to_send);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendString
(JNIEnv * jni_env, jclass this_class, jstring to_send) {
(JNIEnv * jni_env, jclass this_class, jint sid, jstring to_send) {
pack_string_java(&redispatch_buff, to_send, jni_env);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendObject
(JNIEnv * jni_env, jclass this_class, jobject to_send) {
(JNIEnv * jni_env, jclass this_class, jint sid, jobject to_send) {
pack_object(&redispatch_buff, to_send, jni_env);
}
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendClass
(JNIEnv * jni_env, jclass this_class, jclass to_send) {
(JNIEnv * jni_env, jclass this_class, jint sid, jclass to_send) {
pack_class(&redispatch_buff, to_send, jni_env);
}
......@@ -9,118 +9,112 @@ extern "C" {
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved);
#ifdef __cplusplus
}
#endif
// ******************* REDispatch methods *******************
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: analysisStart
* Signature: (I)V
* Signature: (I)I
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_analysisStart
JNIEXPORT jint JNICALL Java_ch_usi_dag_dislre_REDispatch_analysisStart
(JNIEnv *, jclass, jint);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: analysisEnd
* Signature: ()V
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_analysisEnd
(JNIEnv *, jclass);
(JNIEnv *, jclass, jint);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendBoolean
* Signature: (Z)V
* Signature: (IZ)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendBoolean
(JNIEnv *, jclass, jboolean);
(JNIEnv *, jclass, jint, jboolean);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendByte
* Signature: (B)V
* Signature: (IB)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendByte
(JNIEnv *, jclass, jbyte);
(JNIEnv *, jclass, jint, jbyte);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendChar
* Signature: (C)V
* Signature: (IC)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendChar
(JNIEnv *, jclass, jchar);
(JNIEnv *, jclass, jint, jchar);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendShort
* Signature: (S)V
* Signature: (IS)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendShort
(JNIEnv *, jclass, jshort);
(JNIEnv *, jclass, jint, jshort);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendInt
* Signature: (I)V
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendInt
(JNIEnv *, jclass, jint);
(JNIEnv *, jclass, jint, jint);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendLong
* Signature: (J)V
* Signature: (IJ)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendLong
(JNIEnv *, jclass, jlong);
(JNIEnv *, jclass, jint, jlong);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendFloat
* Signature: (F)V
* Method: sendFloatAsInt
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendFloat
(JNIEnv *, jclass, jfloat);
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendFloatAsInt
(JNIEnv *, jclass, jint, jint);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendDouble
* Signature: (D)V
* Method: sendDoubleAsLong
* Signature: (IJ)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendDouble
(JNIEnv *, jclass, jdouble);
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendDoubleAsLong
(JNIEnv *, jclass, jint, jlong);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendString
* Signature: (Ljava/lang/String;)V
* Signature: (ILjava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendString
(JNIEnv *, jclass, jstring);
(JNIEnv *, jclass, jint, jstring);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendObject
* Signature: (Ljava/lang/Object;)V
* Signature: (ILjava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendObject
(JNIEnv *, jclass, jobject);
(JNIEnv *, jclass, jint, jobject);
/*
* Class: ch_usi_dag_dislre_REDispatch
* Method: sendClass
* Signature: (Ljava/lang/Class;)V
* Signature: (ILjava/lang/Class;)V
*/
JNIEXPORT void JNICALL Java_ch_usi_dag_dislre_REDispatch_sendClass
(JNIEnv *, jclass, jclass);
(JNIEnv *, jclass, jint, jclass);
#ifdef __cplusplus
}
......
......@@ -7,25 +7,43 @@ public class REDispatch {
*
* @param analysisID remote analysis id
* @param methodID remote method id
*
* @return session id for consequent send
*/
// TODO re - allow strings with remote string cache support?
public static native void analysisStart(int analysisMethodID);
public static native int analysisStart(int analysisMethodID);
/**
* Announce end of an analysis transmission
*/
public static native void analysisEnd();
public static native void analysisEnd(int id);
// allows transmitting types
public static native void sendBoolean(boolean booleanToSend);
public static native void sendByte(byte byteToSend);
public static native void sendChar(char charToSend);
public static native void sendShort(short shortToSend);
public static native void sendInt(int intToSend);
public static native void sendLong(long longToSend);
public static native void sendFloat(float floatToSend);
public static native void sendDouble(double doubleToSend);
public static native void sendString(String stringToSend);
public static native void sendObject(Object objToSend);
public static native void sendClass(Class<?> classToSend);
public static native void sendBoolean(int sid, boolean booleanToSend);
public static native void sendByte(int sid, byte byteToSend);
public static native void sendChar(int sid, char charToSend);
public static native void sendShort(int sid, short shortToSend);
public static native void sendInt(int sid, int intToSend);
public static native void sendLong(int sid, long longToSend);
public static native void sendFloatAsInt(int sid, int floatAsIntToSend);
public static native void sendDoubleAsLong(int sid, long doubleAsLongToSend);
public static native void sendString(int sid, String stringToSend);
public static native void sendObject(int sid, Object objToSend);
public static native void sendClass(int sid, Class<?> classToSend);
// helper methods for sending float and double
// for proper conversion, we would still need to call ...Bits methods
// it is faster to call them here then call it from native code
// faster would be to do it native code all - be my guest :)
public static void sendFloat(int sid, float floatToSend) {
sendFloatAsInt(sid, Float.floatToIntBits(floatToSend));
}
// helper method for sending double
public static void sendDouble(int sid, double doubleToSend) {
sendDoubleAsLong(sid, Double.doubleToLongBits(doubleToSend));
}
}
......@@ -81,7 +81,7 @@ public abstract class DiSLREServer {
Throwable cause = e.getCause();
while (cause != null) {
while (cause != null && cause.getMessage() != null) {
System.err.println(" Inner error: " + cause.getMessage());
cause = cause.getCause();
}
......
......@@ -3,6 +3,7 @@ package ch.usi.dag.dislreserver.msg.analyze;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
......@@ -64,13 +65,23 @@ public class AnalysisHandler implements RequestHandler {
// *** invoke method ***
try {
// TODO re - support static methods
// TODO re ! support static methods
analysisMethod.invoke(amh.getAnalysisInstance(), args.toArray());
}
catch(Exception e) {
catch(InvocationTargetException e) {
// report analysis error
Throwable cause = e.getCause();
System.err.println("DiSL-RE analysis exception: "
+ e.getMessage());
e.printStackTrace();
+ cause.getMessage());
cause.printStackTrace();
}
catch(Exception e) {
throw new DiSLREServerException(e);
}
}
......
......@@ -11,39 +11,39 @@ public class CodeExecutedRE {
public static void bytecodesExecuted(int count) {
REDispatch.analysisStart(1);
int sid = REDispatch.analysisStart(1);
REDispatch.sendInt(count);
REDispatch.sendInt(sid, count);
REDispatch.analysisEnd();
REDispatch.analysisEnd(sid);
}
public static void testingBasic(boolean b, byte by, char c, short s, int i,
long l, float f, double d) {
REDispatch.analysisStart(2);
int sid = REDispatch.analysisStart(2);
REDispatch.sendBoolean(b);
REDispatch.sendByte(by);
REDispatch.sendChar(c);
REDispatch.sendShort(s);
REDispatch.sendInt(i);
REDispatch.sendLong(l);
REDispatch.sendFloat(f);
REDispatch.sendDouble(d);
REDispatch.sendBoolean(sid, b);
REDispatch.sendByte(sid, by);
REDispatch.sendChar(sid, c);
REDispatch.sendShort(sid, s);
REDispatch.sendInt(sid, i);
REDispatch.sendLong(sid, l);
REDispatch.sendFloat(sid, f);
REDispatch.sendDouble(sid, d);
REDispatch.analysisEnd();
REDispatch.analysisEnd(sid);
}
public static void testingAdvanced(String s, Object o, Class<?> c, int classID) {
REDispatch.analysisStart(3);
int sid = REDispatch.analysisStart(3);
REDispatch.sendString(s);
REDispatch.sendObject(o);
REDispatch.sendClass(c);
REDispatch.sendString(sid, s);
REDispatch.sendObject(sid, o);
REDispatch.sendClass(sid, c);
// class_id ignored
REDispatch.analysisEnd();
REDispatch.analysisEnd(sid);
}
}
......@@ -12,7 +12,7 @@ public class DiSLClass {
CodeExecutedRE.bytecodesExecuted(clsc.codeSize());
}
@After(marker = BodyMarker.class, scope = "TargetClass.main()")
@After(marker = BodyMarker.class, scope = "TargetClass.main")
public static void testing() {
CodeExecutedRE.testingBasic(true, (byte) 125, 'š', (short) 50000,
......
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