Commit 2e3231a8 authored by Lukáš Marek's avatar Lukáš Marek

Added object free support

parent 831d11f0
#ifndef _BUFFER_H
#define _BUFFER_H
// 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;
// ******************* Buffer routines *******************
void buffer_init(buffer * b) {
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) {
// not enough free space - extend buffer
if(b->capacity - b->occupied < data_length) {
unsigned char * old_buff = b->buff;
// alloc as much as needed to be able to insert data
size_t new_capacity = 2 * b->capacity;
while(new_capacity - b->occupied < data_length) {
new_capacity *= 2;
}
b->buff = (unsigned char *) malloc(new_capacity);
memcpy(b->buff, old_buff, b->occupied);
}
memcpy(b->buff + b->occupied, data, data_length);
b->occupied += data_length;
}
void buffer_clean(buffer * b) {
// if capacity is higher then limit "reset" buffer
// should keep memory consumption in limits
if(b->capacity > MAX_BUFF_SIZE) {
buffer_free(b);
buffer_init(b);
}
b->occupied = 0;
}
#endif /* _BUFFER_H */
#ifndef _BUFFPACK_H
#define _BUFFPACK_H
void pack_boolean(buffer * buff, jboolean to_send) {
buffer_fill(buff, &to_send, sizeof(jboolean));
}
void pack_byte(buffer * buff, jbyte to_send) {
buffer_fill(buff, &to_send, sizeof(jbyte));
}
void pack_char(buffer * buff, jchar to_send) {
jchar nts = htons(to_send);
buffer_fill(buff, &nts, sizeof(jchar));
}
void pack_short(buffer * buff, jshort to_send) {
jshort nts = htons(to_send);
buffer_fill(buff, &nts, sizeof(jshort));
}
void pack_int(buffer * buff, jint to_send) {
jint nts = htonl(to_send);
buffer_fill(buff, &nts, sizeof(jint));
}
void pack_long(buffer * buff, jlong to_send) {
jlong nts = htobe64(to_send);
buffer_fill(buff, &nts, sizeof(jlong));
}
void pack_string_utf8(buffer * buff, const void * string_utf8,
uint16_t size_in_bytes) {
// send length first
uint16_t nsize = htons(size_in_bytes);
buffer_fill(buff, &nsize, sizeof(uint16_t));
buffer_fill(buff, string_utf8, size_in_bytes);
}
void pack_string_java(buffer * buff, jstring to_send, JNIEnv * jni_env) {
// get string length
jsize str_len = (*jni_env)->GetStringUTFLength(jni_env, to_send);
// get string data as utf-8
const char * str = (*jni_env)->GetStringUTFChars(jni_env, to_send, NULL);
check_std_error(str == NULL, TRUE, "Cannot get string from java");
// check if the size is sendable
int size_fits = str_len < UINT16_MAX;
check_std_error(size_fits, FALSE, "Java string is too big for sending");
// send string
pack_string_utf8(buff, str, str_len);
// release string
(*jni_env)->ReleaseStringUTFChars(jni_env, to_send, str);
}
void pack_object(buffer * buff, jobject to_send, JNIEnv * jni_env) {
jlong obj_tag;
enter_critical_section(jvmti_env, objectid_lock);
{
jvmtiError error;
// get object tag
error = (*jvmti_env)->GetTag(jvmti_env, to_send, &obj_tag);
check_jvmti_error(jvmti_env, error, "Cannot get object tag");
// set object tag
if(obj_tag == 0) {
obj_tag = avail_object_tag;
++avail_object_tag;
// TODO add class id - note that class can miss the class id
error = (*jvmti_env)->SetTag(jvmti_env, to_send, obj_tag);
check_jvmti_error(jvmti_env, error, "Cannot set object tag");
}
}
exit_critical_section(jvmti_env, objectid_lock);
pack_long(buff, obj_tag);
}
void pack_class(buffer * buff, jclass to_send, JNIEnv * jni_env) {
// TODO
// class id is set for jclass on the same spot as for object
// class id can have object id also
// TODO
// if class does not have id, you have to find it by name and class loader
pack_int(buff, 1);
}
void pack_bytes(buffer * buff, const void * data, jint size) {
buffer_fill(buff, data, size);
}
#endif /* _BUFFPACK_H */
This diff is collapsed.
#ifndef _MESSAGETYPE_H
#define _MESSAGETYPE_H
// Messages Types
// - should be in sync with java server
// closing connection
static const jint MSG_CLOSE = 0;
// sending analysis
static const jint MSG_ANALYZE = 1;
// sending analysis
static const jint MSG_OBJFREE = 2;
#endif /* _MESSAGETYPE_H */
......@@ -8,6 +8,7 @@ import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import ch.usi.dag.dislreserver.exception.DiSLREServerException;
import ch.usi.dag.dislreserver.reqdispatch.RequestDispatcher;
public abstract class DiSLREServer {
......
package ch.usi.dag.dislreserver;
package ch.usi.dag.dislreserver.exception;
public class DiSLREServerException extends Exception {
......
package ch.usi.dag.dislreserver.exception;
public class DiSLREServerFatalException extends RuntimeException {
private static final long serialVersionUID = -8431771285237240263L;
public DiSLREServerFatalException() {
}
public DiSLREServerFatalException(String message) {
super(message);
}
public DiSLREServerFatalException(Throwable cause) {
super(cause);
}
public DiSLREServerFatalException(String message, Throwable cause) {
super(message, cause);
}
public DiSLREServerFatalException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
......@@ -8,7 +8,7 @@ import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import ch.usi.dag.dislreserver.DiSLREServerException;
import ch.usi.dag.dislreserver.exception.DiSLREServerException;
import ch.usi.dag.dislreserver.msg.analyze.AnalysisResolver.AnalysisMethodHolder;
import ch.usi.dag.dislreserver.objectid.InvalidClass;
import ch.usi.dag.dislreserver.objectid.ObjectId;
......
......@@ -7,6 +7,7 @@ import java.util.Map;
import java.util.Set;
import ch.usi.dag.disl.test.dispatch.CodeExecuted;
import ch.usi.dag.dislreserver.exception.DiSLREServerFatalException;
import ch.usi.dag.dislreserver.remoteanalysis.RemoteAnalysis;
public class AnalysisResolver {
......@@ -43,8 +44,7 @@ public class AnalysisResolver {
AnalysisMethodHolder result = methodMap.get(methodId);
if(result == null) {
// TODO re - different except
throw new RuntimeException("Unknow method id");
throw new DiSLREServerFatalException("Unknow method id");
}
return result;
......
......@@ -6,7 +6,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import ch.usi.dag.dislreserver.DiSLREServerException;
import ch.usi.dag.dislreserver.exception.DiSLREServerException;
import ch.usi.dag.dislreserver.msg.instr.InstrMsgReader.InstrClassMessage;
import ch.usi.dag.dislreserver.reqdispatch.RequestHandler;
......
package ch.usi.dag.dislreserver.msg.objfree;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Set;
import ch.usi.dag.dislreserver.exception.DiSLREServerException;
import ch.usi.dag.dislreserver.msg.analyze.AnalysisResolver;
import ch.usi.dag.dislreserver.objectid.ObjectId;
import ch.usi.dag.dislreserver.remoteanalysis.RemoteAnalysis;
import ch.usi.dag.dislreserver.reqdispatch.RequestHandler;
public class ObjectFreeHandler implements RequestHandler {
public void handle(DataInputStream is, DataOutputStream os, boolean debug)
throws DiSLREServerException {
try {
ObjectId objectId = new ObjectId(is.readLong());
Set<RemoteAnalysis> raSet = AnalysisResolver.getAllAnalyses();
for(RemoteAnalysis ra : raSet) {
ra.objectFree(objectId);
}
} catch (IOException e) {
throw new DiSLREServerException(e);
}
}
}
package ch.usi.dag.dislreserver.remoteanalysis;
import ch.usi.dag.dislreserver.objectid.ObjectId;
/**
* Each analysis evaluated remotely have to implement this interface.
*
......@@ -21,4 +23,6 @@ package ch.usi.dag.dislreserver.remoteanalysis;
public abstract class RemoteAnalysis {
public abstract void atExit();
public abstract void objectFree(ObjectId objectId);
}
......@@ -5,9 +5,11 @@ import java.io.DataOutputStream;
import java.util.HashMap;
import java.util.Map;
import ch.usi.dag.dislreserver.DiSLREServerException;
import ch.usi.dag.dislreserver.exception.DiSLREServerException;
import ch.usi.dag.dislreserver.exception.DiSLREServerFatalException;
import ch.usi.dag.dislreserver.msg.analyze.AnalysisHandler;
import ch.usi.dag.dislreserver.msg.close.CloseHandler;
import ch.usi.dag.dislreserver.msg.objfree.ObjectFreeHandler;
public class RequestDispatcher {
......@@ -22,6 +24,8 @@ public class RequestDispatcher {
requestMap.put(0, new CloseHandler());
// analyze
requestMap.put(1, new AnalysisHandler());
// object free
requestMap.put(2, new ObjectFreeHandler());
}
public static boolean dispatch(int requestNo, DataInputStream is,
......@@ -33,6 +37,12 @@ public class RequestDispatcher {
if(debug) {
System.out.println("Dispatching " + rh.getClass().getName());
}
if(rh == null) {
throw new DiSLREServerFatalException("Message type (" + requestNo +
") not supported");
}
// process request
rh.handle(is, os, debug);
......
......@@ -3,7 +3,7 @@ package ch.usi.dag.dislreserver.reqdispatch;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import ch.usi.dag.dislreserver.DiSLREServerException;
import ch.usi.dag.dislreserver.exception.DiSLREServerException;
public interface RequestHandler {
......
......@@ -77,4 +77,9 @@ public class CodeExecuted extends RemoteAnalysis {
System.out.println("Total number of executed bytecodes: "
+ totalExecutedBytecodes);
}
public void objectFree(ObjectId objectId) {
System.out.println("Object free for id " + objectId.getId());
}
}
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