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

Working but not well tested class information (API for accessing detailed...

Working but not well tested class information (API for accessing detailed information still missing)
parent 5b891d46
......@@ -239,29 +239,33 @@ static void close_connection(int conn) {
// HIGHEST (1 bit spec, 23 bits class id, 40 bits object id)
// bit field not used because there is no guarantee of alignment
// NOTE you have to update masks in functions also
static const u_int8_t OBJECT_ID_POS = 0;
static const u_int8_t CLASS_ID_POS = 40;
static const u_int8_t SPEC_POS = 63;
// get bits from "from" with size "pos_mask" lowest bit starting on position
static const u_int64_t OBJECT_ID_MASK = 0xFFFFFFFFFF;
static const u_int64_t CLASS_ID_MASK = 0x7FFFFF;
static const u_int64_t SPEC_MASK = 0x1;
// get bits from "from" with pattern "bit_mask" lowest bit starting on position
// "low_start" (from 0)
static inline u_int64_t get_bits(u_int64_t from, u_int64_t pos_mask,
static inline u_int64_t get_bits(u_int64_t from, u_int64_t bit_mask,
u_int8_t low_start) {
// shift it
u_int64_t bits_shifted = from >> low_start;
// mask it
u_int64_t bits_only = from & pos_mask;
// move it to proper position
return bits_only >> low_start;
return bits_shifted & bit_mask;
}
// set bits "bits" to "to" with max length "len_mask" lowest bit starting on
// set bits "bits" to "to" with pattern "bit_mask" lowest bit starting on
// position "low_start" (from 0)
static inline void set_bits(u_int64_t * to, u_int64_t bits,
u_int64_t len_mask, u_int8_t low_start) {
u_int64_t bit_mask, u_int8_t low_start) {
// enforce length
u_int64_t bits_len = bits & len_mask;
// mask it
u_int64_t bits_len = bits & bit_mask;
// move it to position
u_int64_t bits_pos = bits_len << low_start;
// set
......@@ -270,38 +274,32 @@ static inline void set_bits(u_int64_t * to, u_int64_t bits,
static inline jlong net_ref_get_object_id(jlong net_ref) {
static const u_int64_t OBJECT_ID_POS_MASK = 0xFFFFFFFFFF;
return get_bits(net_ref, OBJECT_ID_POS_MASK, OBJECT_ID_POS);
return get_bits(net_ref, OBJECT_ID_MASK, OBJECT_ID_POS);
}
static inline jint net_ref_get_class_id(jlong net_ref) {
static const u_int64_t CLASS_ID_POS_MASK = 0x7FFFFF0000000000;
return get_bits(net_ref, CLASS_ID_POS_MASK, CLASS_ID_POS);
return get_bits(net_ref, CLASS_ID_MASK, CLASS_ID_POS);
}
static inline unsigned char net_ref_get_spec(jlong net_ref) {
static const u_int64_t SPEC_POS_MASK = 0x8000000000000000;
return get_bits(net_ref, SPEC_POS_MASK, SPEC_POS);
return get_bits(net_ref, SPEC_MASK, SPEC_POS);
}
static inline void net_ref_set_object_id(jlong * net_ref, jlong object_id) {
static const u_int64_t OBJECT_ID_LEN_MASK = 0xFFFFFFFFFF;
set_bits((u_int64_t *)net_ref, object_id, OBJECT_ID_LEN_MASK, OBJECT_ID_POS);
set_bits((u_int64_t *)net_ref, object_id, OBJECT_ID_MASK, OBJECT_ID_POS);
}
static inline void net_ref_set_class_id(jlong * net_ref, jint class_id) {
static const u_int64_t CLASS_ID_LEN_MASK = 0x7FFFFF;
set_bits((u_int64_t *)net_ref, class_id, CLASS_ID_LEN_MASK, CLASS_ID_POS);
set_bits((u_int64_t *)net_ref, class_id, CLASS_ID_MASK, CLASS_ID_POS);
}
static inline void net_ref_set_spec(jlong * net_ref, unsigned char spec) {
static const u_int64_t SPEC_LEN_MASK = 0x1;
set_bits((u_int64_t *)net_ref, spec, SPEC_LEN_MASK, SPEC_POS);
set_bits((u_int64_t *)net_ref, spec, SPEC_MASK, SPEC_POS);
}
// ******************* Net reference routines *******************
......
......@@ -38,7 +38,7 @@ public abstract class DiSLREServer {
+ socket.getInetAddress().toString());
}
analysisLoop(socket);
requestLoop(socket);
socket.close();
......@@ -55,7 +55,7 @@ public abstract class DiSLREServer {
}
}
private static void analysisLoop(Socket sock) throws DiSLREServerException {
private static void requestLoop(Socket sock) throws DiSLREServerException {
try {
......
package ch.usi.dag.dislreserver.classinfo;
import ch.usi.dag.dislreserver.netreference.NetReference;
public class ClassInfo extends ExtractedClassInfo {
private int classId;
private String classSignature;
private String classGenericStr;
private NetReference classLoaderNR;
private ClassInfo superClassInfo;
public ClassInfo(int classId, String classSignature,
String classGenericStr, NetReference classLoaderNR,
ClassInfo superClassInfo, ExtractedClassInfo eci) {
super(eci);
this.classId = classId;
this.classSignature = classSignature;
this.classGenericStr = classGenericStr;
this.classLoaderNR = classLoaderNR;
this.superClassInfo = superClassInfo;
}
public int getClassId() {
return classId;
}
public String getClassSignature() {
return classSignature;
}
public String getClassGenericStr() {
return classGenericStr;
}
public NetReference getClassLoaderNR() {
return classLoaderNR;
}
public ClassInfo getSuperClassInfo() {
return superClassInfo;
}
}
......@@ -3,55 +3,71 @@ package ch.usi.dag.dislreserver.classinfo;
import java.util.HashMap;
import java.util.Map;
import org.objectweb.asm.Type;
import ch.usi.dag.dislreserver.exception.DiSLREServerFatalException;
import ch.usi.dag.dislreserver.netreference.NetReference;
public class ClassInfoResolver {
// TODO re ! change object
static Map<Long, Map<String, Object>> classLoaderMap =
new HashMap<Long, Map<String, Object>>();
static Map<Long, Map<String, ExtractedClassInfo>> classLoaderMap =
new HashMap<Long, Map<String, ExtractedClassInfo>>();
// TODO re ! change object
static Map<Integer, Object> classIdMap =
new HashMap<Integer, Object>();
static Map<Integer, ClassInfo> classIdMap =
new HashMap<Integer, ClassInfo>();
// TODO re ! complete holder
public static void addNewClass(String className, long classLoderId, byte[] classCode) {
public static void addNewClass(String className, NetReference classLoaderNR,
byte[] classCode) {
// TODO re ! change object
Map<String, Object> classNameMap = classLoaderMap.get(classLoderId);
Map<String, ExtractedClassInfo> classNameMap =
classLoaderMap.get(classLoaderNR.getObjectId());
if(classNameMap == null) {
// TODO re ! change object
classNameMap = new HashMap<String, Object>();
classNameMap = new HashMap<String, ExtractedClassInfo>();
classLoaderMap.put(classLoaderNR.getObjectId(), classNameMap);
}
// TODO re ! change object
classNameMap.put(className, new Object());
classNameMap.put(className, new ExtractedClassInfo(classCode));
}
public static void createHierarchy(String className, long classLoderId, int classId, int superId) {
// TODO re ! change object
Map<String, Object> classNameMap = classLoaderMap.get(classLoderId);
public static void createHierarchy(String classSignature,
String classGenericStr, NetReference classLoaderNR, int classId,
int superClassId) {
Map<String, ExtractedClassInfo> classNameMap =
classLoaderMap.get(classLoaderNR.getObjectId());
if(classNameMap == null) {
throw new DiSLREServerFatalException("Class loader not known");
}
// TODO re ! change object
Object obj = classNameMap.get(className);
// create asm type to get class name
Type classASMType = Type.getType(classSignature);
ExtractedClassInfo eci =
classNameMap.get(classASMType.getInternalName());
if(obj == null) {
throw new DiSLREServerFatalException("Class not known");
if(eci == null) {
// TODO re ! should not be needed when class loader tagging is fixed
classNameMap = classLoaderMap.get(new Long(0)); // something will be there
eci = classNameMap.get(classASMType.getInternalName());
if(eci == null) {
throw new DiSLREServerFatalException("Class not known");
}
// TODO re ! replace with this
//throw new DiSLREServerFatalException("Class not known");
}
// TODO re ! register hierarchy
// resolve super class
ClassInfo superClassInfo = classIdMap.get(superClassId);
classIdMap.put(classId, new ClassInfo(classId, classSignature,
classGenericStr, classLoaderNR, superClassInfo, eci));
}
// TODO re ! change object
public static Object getClass(int classId) {
public static ClassInfo getClass(int classId) {
return classIdMap.get(classId);
}
}
package ch.usi.dag.dislreserver.classinfo;
public class ExtractedClassInfo {
private byte[] classCodeAsBytes;
public ExtractedClassInfo(byte[] classCodeAsBytes) {
super();
this.classCodeAsBytes = classCodeAsBytes;
}
public ExtractedClassInfo(ExtractedClassInfo eci) {
this.classCodeAsBytes = eci.classCodeAsBytes;
}
public byte[] getClassCodeAsBytes() {
return classCodeAsBytes;
}
}
......@@ -4,6 +4,7 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import ch.usi.dag.dislreserver.classinfo.ClassInfoResolver;
import ch.usi.dag.dislreserver.exception.DiSLREServerException;
import ch.usi.dag.dislreserver.netreference.NetReference;
import ch.usi.dag.dislreserver.reqdispatch.RequestHandler;
......@@ -21,16 +22,7 @@ public class ClassInfoHandler implements RequestHandler {
NetReference classLoaderNR = new NetReference(is.readLong());
int superClassId = is.readInt();
// TODO re ! process class info
// TODO re ! remove
/*
System.out.println("* Class info *");
System.out.println("Class id: " + classId);
System.out.println("Class sig: " + classSignature);
System.out.println("Class gen: " + classGenericStr);
System.out.println("Class loader id: " + classLoaderNR.getObjectId());
System.out.println("Super class id: " + superClassId);
*/
ClassInfoResolver.createHierarchy(classSignature, classGenericStr, classLoaderNR, classId, superClassId);
}
catch (IOException e) {
throw new DiSLREServerException(e);
......
......@@ -6,6 +6,7 @@ import java.io.IOException;
import ch.usi.dag.dislreserver.classinfo.ClassInfoResolver;
import ch.usi.dag.dislreserver.exception.DiSLREServerException;
import ch.usi.dag.dislreserver.netreference.NetReference;
import ch.usi.dag.dislreserver.reqdispatch.RequestHandler;
public class NewClassHandler implements RequestHandler {
......@@ -16,12 +17,12 @@ public class NewClassHandler implements RequestHandler {
try {
String className = is.readUTF();
long classLoderId = is.readLong();
NetReference classLoaderNR = new NetReference(is.readLong());
int classCodeLength = is.readInt();
byte[] classCode = new byte[classCodeLength];
is.readFully(classCode);
ClassInfoResolver.addNewClass(className, classLoderId, classCode);
ClassInfoResolver.addNewClass(className, classLoaderNR, classCode);
}
catch (IOException e) {
throw new DiSLREServerException(e);
......
......@@ -24,6 +24,8 @@ public class ObjectFreeHandler implements RequestHandler {
for(RemoteAnalysis ra : raSet) {
ra.objectFree(netRef);
}
// TODO re ! free for special objects
} catch (IOException e) {
throw new DiSLREServerException(e);
......
package ch.usi.dag.dislreserver.netreference;
// should be in sync with net_reference on the client
import ch.usi.dag.dislreserver.classinfo.ClassInfo;
import ch.usi.dag.dislreserver.classinfo.ClassInfoResolver;
public class NetReference {
// TODO re ! rename
long id;
final private long netRefeference;
final private long objectId;
final private int classId;
final private short spec;
public NetReference(long id) {
public NetReference(long netReference) {
super();
this.id = id;
this.netRefeference = netReference;
// initialize inner fields
this.objectId = net_ref_get_object_id(netReference);
this.classId = net_ref_get_class_id(netReference);
this.spec = net_ref_get_spec(netReference);
}
public long getNetRefeference() {
return netRefeference;
}
public long getObjectId() {
// TODO re ! should contain only object id
return id;
return objectId;
}
public int getClassId() {
return classId;
}
// TODO re ! should hash only object id
@Override
public short getSpec() {
return spec;
}
public ClassInfo getClassInfo() {
return ClassInfoResolver.getClass(classId);
}
// only object id considered
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (id ^ (id >>> 32));
result = prime * result + (int) (objectId ^ (objectId >>> 32));
return result;
}
// TODO re ! should equal only object id
@Override
// only object id considered
public boolean equals(Object obj) {
if (this == obj)
return true;
......@@ -35,8 +57,53 @@ public class NetReference {
if (getClass() != obj.getClass())
return false;
NetReference other = (NetReference) obj;
if (id != other.id)
if (objectId != other.objectId)
return false;
return true;
}
// ************* special bit mask handling methods **********
// NOTE names of the methods are unusual for reason
// you can find almost identical methods in agent
// should be in sync with net_reference functions on the client
// format of net reference looks like this
// HIGHEST (1 bit spec, 23 bits class id, 40 bits object id)
// bit field not used because there is no guarantee of alignment
private final short OBJECT_ID_POS = 0;
private final short CLASS_ID_POS = 40;
private final short SPEC_POS = 63;
private final long OBJECT_ID_MASK = 0xFFFFFFFFFFL;
private final long CLASS_ID_MASK = 0x7FFFFFL;
private final long SPEC_MASK = 0x1L;
// get bits from "from" with pattern "bit_mask" lowest bit starting on position
// "low_start" (from 0)
private long get_bits(long from, long bit_mask, short low_start) {
// shift it
long bits_shifted = from >> low_start;
// mask it
return bits_shifted & bit_mask;
}
private long net_ref_get_object_id(long net_ref) {
return get_bits(net_ref, OBJECT_ID_MASK, OBJECT_ID_POS);
}
private int net_ref_get_class_id(long net_ref) {
return (int)get_bits(net_ref, CLASS_ID_MASK, CLASS_ID_POS);
}
private short net_ref_get_spec(long net_ref) {
return (short)get_bits(net_ref, SPEC_MASK, SPEC_POS);
}
}
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