diff --git a/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp b/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
index 858c10b..8ddb3da 100644
--- a/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
+++ b/enhanced/drlvm/trunk/vm/port/src/lil/ia32/pim/stack_iterator_ia32.cpp
@@ -30,6 +30,7 @@ #include "vm_stats.h"
#include "open/types.h"
#include "encoder.h"
#include "interpreter.h"
+#include "cci.h"
#include "clog.h"
diff --git a/enhanced/drlvm/trunk/vm/port/src/lil/pim/stack_iterator.cpp b/enhanced/drlvm/trunk/vm/port/src/lil/pim/stack_iterator.cpp
index 94cf175..4364f0b 100644
--- a/enhanced/drlvm/trunk/vm/port/src/lil/pim/stack_iterator.cpp
+++ b/enhanced/drlvm/trunk/vm/port/src/lil/pim/stack_iterator.cpp
@@ -23,6 +23,7 @@ #include "interpreter.h"
#include "jit_intf_cpp.h"
#include "m2n.h"
#include "stack_iterator.h"
+#include "cci.h"
Method_Handle si_get_method(StackIterator* si)
{
diff --git a/enhanced/drlvm/trunk/vm/vmcore/include/Class.h b/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
index 067cba9..a7fb0e5 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
@@ -31,6 +31,7 @@ #include "open/vm_gc.h"
#include "open/gc.h"
#include "String_Pool.h"
#include "type.h"
+#include "vtable.h"
//
// forward declarations
@@ -39,41 +40,18 @@ class Class_Member;
struct Field;
struct Method;
struct Method_Signature;
-class Package;
typedef struct Class Class;
-class JIT;
-struct ClassLoader;
-class ByteReader;
struct Class_Extended_Notification_Record;
-class DynoptInfo;
-class Lock_Manager;
-//
// external declarations
-//
+class CodeChunkInfo;
+class Lock_Manager;
+class ByteReader;
+struct ClassLoader;
+class JIT;
struct Global_Env; // defined in Environment.h
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Constant Java values
-///////////////////////////////////////////////////////////////////////////////
-union Const_Java_Value {
- uint32 i;
- int64 j;
- struct {
- uint32 lo_bytes;
- uint32 hi_bytes;
- } l;
- float f;
- double d;
- String *string;
- void *object;
- //Const_Java_Value() {l.lo_bytes=l.hi_bytes=0;}
-};
-
-
+class Package;
+struct AnnotationTable;
///////////////////////////////////////////////////////////////////////////////
// Raw and compressed reference pointers
@@ -118,34 +96,6 @@ #define STORE_GLOBAL_REFERENCE(SLOT_ADDR
}
-
-///////////////////////////////////////////////////////////////////////////////
-// class file attributes
-///////////////////////////////////////////////////////////////////////////////
-enum Attributes {
- ATTR_SourceFile, // Class (no more than 1 in each class file)
- ATTR_InnerClasses, // Class
- ATTR_ConstantValue, // Field (no more than 1 for each field)
- ATTR_Code, // Method
- ATTR_Exceptions, // Method
- ATTR_LineNumberTable, // Code
- ATTR_LocalVariableTable, // Code
- ATTR_Synthetic, // Class/Field/Method
- ATTR_Deprecated, // Class/Field/Method
- ATTR_SourceDebugExtension, // Class (no more than 1 in each class file)
- ATTR_Signature, // Class/Field/Method (spec does not limit number???)
- ATTR_EnclosingMethod, // Class (1 at most)
- ATTR_LocalVariableTypeTable, // Code
- ATTR_RuntimeVisibleAnnotations, // Class/Field/Method (at most 1 per entity)
- ATTR_RuntimeInvisibleAnnotations, // Class/Field/Method
- ATTR_RuntimeVisibleParameterAnnotations, // Method
- ATTR_RuntimeInvisibleParameterAnnotations, // Method
- ATTR_AnnotationDefault, // Method (spec does not limit number???)
- N_ATTR,
- ATTR_UNDEF,
- ATTR_ERROR
-};
-
#define N_COMMON_ATTR 5
#define N_FIELD_ATTR 1
#define N_METHOD_ATTR 5
@@ -220,84 +170,6 @@ union Const_Pool {
} CONSTANT_Utf8;
};
-enum AnnotationValueType {
- // 'B', 'C', 'D', 'F', 'I', 'J', 'S', and 'Z' 's' 'e' 'c' '@' '['
- AVT_BYTE = 'B',
- AVT_CHAR = 'C',
- AVT_DOUBLE = 'D',
- AVT_FLOAT = 'F',
- AVT_INT = 'I',
- AVT_LONG = 'J',
- AVT_SHORT = 'S',
- AVT_BOOLEAN = 'Z',
- AVT_STRING = 's',
- AVT_ENUM = 'e',
- AVT_CLASS = 'c',
- AVT_ANNOTN = '@',
- AVT_ARRAY = '['
-};
-
-struct Annotation; // forward declaration
-
-// element-value pair of an annotation
-struct AnnotationValue {
- union {
- Const_Java_Value const_value;
- String* class_name;
- Annotation * nested;
- struct {
- String* type;
- String* name;
- } enum_const;
- struct {
- AnnotationValue* items;
- uint16 length;
- } array;
- };
- AnnotationValueType tag;
-};
-
-struct AnnotationElement {
- String* name;
- AnnotationValue value;
-};
-
-struct Annotation {
- String* type;
- AnnotationElement* elements;
- uint16 num_elements;
-};
-
-struct AnnotationTable {
- uint16 length;
- Annotation * table[1];
-};
-
-struct Line_Number_Entry {
- uint16 start_pc;
- uint16 line_number;
-};
-
-struct Line_Number_Table {
- uint16 length;
- Line_Number_Entry table[1];
-};
-
-struct Local_Var_Entry {
- uint16 start_pc;
- uint16 length;
- uint16 index;
- String* name;
- String* type;
- String* generic_type;
-};
-
-struct Local_Var_Table {
- uint16 length;
- Local_Var_Entry table[1];
-};
-
-
///////////////////////////////////////////////////////////////////////////////
// Types of constant pool entries. These are defined by a seperate byte array
// pointed to by the first constant pool entry.
@@ -345,79 +217,6 @@ #define cp_resolve_to_field(cp,i,f) cp_s
#define cp_resolve_to_method(cp,i,m) cp_set_resolved(cp,i); cp[i].CONSTANT_ref.method=m;
-#define MAX_FAST_INSTOF_DEPTH 5
-
-///////////////////////////////////////////////////////////////////////////////
-// virtual method table of a class
-///////////////////////////////////////////////////////////////////////////////
-extern "C" {
-
-typedef struct {
- unsigned char **table;// pointer into methods array of VTable below
- unsigned intfc_id; // id of interface
-} Intfc_Table_Entry;
-
-typedef struct Intfc_Table {
-#ifdef POINTER64
- // see INTFC_TABLE_OVERHEAD
- uint32 dummy; // padding
-#endif
- uint32 n_entries;
- Intfc_Table_Entry entry[1];
-} Intfc_Table;
-
-
-#define INTFC_TABLE_OVERHEAD (sizeof(void *))
-
-
-#ifdef POINTER64
-#define OBJECT_HEADER_SIZE 0
-// The size of an object reference. Used by arrays of object to determine
-// the size of an element.
-#define OBJECT_REF_SIZE 8
-#else // POINTER64
-#define OBJECT_HEADER_SIZE 0
-#define OBJECT_REF_SIZE 4
-#endif // POINTER64
-
-
-#define GC_BYTES_IN_VTABLE (sizeof(void *))
-
-typedef struct VTable {
-
- Byte _gc_private_information[GC_BYTES_IN_VTABLE];
-
- Class *clss; // the class - see above before change
- //
- // See the masks in vm_for_gc.h.
- //
- uint32 class_properties;
-
-
- // Offset from the top by CLASS_ALLOCATED_SIZE_OFFSET
- // The number of bytes allocated for this object. It is the same as
- // instance_data_size with the constraint bit cleared. This includes
- // the OBJECT_HEADER_SIZE as well as the OBJECT_VTABLE_POINTER_SIZE
- unsigned int allocated_size;
-
- unsigned short array_element_size;
- unsigned short array_element_shift;
- Intfc_Table *intfc_table; // interface table; NULL if no intfc table
-//#ifdef FAST_INSTOF
- Class *superclasses[MAX_FAST_INSTOF_DEPTH]; //::
-//#endif
- unsigned char *methods[1]; // code for method
-} VTable;
-
-
-#define VTABLE_OVERHEAD (sizeof(VTable) - sizeof(void *))
-// The "- sizeof(void *)" part subtracts out the "unsigned char *methods[1]" contribution.
-
-VTable *create_vtable(Class *p_class, unsigned n_vtable_entries);
-
-} // extern "C"
-
-
///////////////////////////////////////////////////////////////////////////////
// A Java class
///////////////////////////////////////////////////////////////////////////////
@@ -881,808 +680,8 @@ VMEXPORT void class_initialize(Class *cl
void class_register_jit_extended_class_callback(Class *clss, JIT *jit_to_be_notified, void *callback_data);
void do_jit_extended_class_callbacks(Class *clss, Class *new_subclass);
-///////////////////////////////////////////////////////////////////////////////
-// A class' members are its fields and methods. Class_Member is the base
-// class for Field and Method, and factors out the commonalities in these
-// two classes.
-///////////////////////////////////////////////////////////////////////////////
-// VMEXPORT // temporary solution for interpreter unplug
-class VMEXPORT Class_Member {
-public:
- //
- // access modifiers
- //
- bool is_public() {return (_access_flags&ACC_PUBLIC)?true:false;}
- bool is_private() {return (_access_flags&ACC_PRIVATE)?true:false;}
- bool is_protected() {return (_access_flags&ACC_PROTECTED)?true:false;}
- bool is_package_private() {return !(is_public()||is_protected()||is_public())?true:false;}
- bool is_static() {return (_access_flags&ACC_STATIC)?true:false;}
- bool is_final() {return (_access_flags&ACC_FINAL)?true:false;}
- bool is_strict() {return (_access_flags&ACC_STRICT)?true:false;}
- bool is_synthetic() {return (_access_flags&ACC_SYNTHETIC)?true:_synthetic;}
- bool is_deprecated() {return _deprecated;}
- unsigned get_access_flags() {return _access_flags;}
-
- //
- // field get/set methods
- //
- unsigned get_offset() const {return _offset;}
- Class *get_class() const {return _class;}
- String *get_name() const {return _name;}
-
- // Get the type descriptor (Sec. 4.3.2)
- String *get_descriptor() const {return _descriptor;}
- String *get_signature() const {return _signature;}
-
- AnnotationTable* get_declared_annotations() const {return _annotations;}
-
- friend void assign_instance_field_offset(Class *clss, Field *field, bool do_field_compaction);
- friend void assign_offsets_to_static_fields(Class *clss, Field **field_ptrs, bool do_field_compaction);
- friend void assign_offsets_to_class_fields(Class *);
- friend void add_new_fake_method(Class *clss, Class *example, unsigned *next);
- friend void add_any_fake_methods(Class *);
-
- /**
- * Allocate a memory from a class loader pool using the class
- * loader lock.
- */
- void* Alloc(size_t size);
-
-protected:
- Class_Member()
- {
- _access_flags = 0;
- _class = NULL;
- _offset = 0;
-#ifdef VM_STATS
- num_accesses = 0;
- num_slow_accesses = 0;
-#endif
- _synthetic = _deprecated = false;
- _annotations = NULL;
- _signature = NULL;
- }
-
- // offset of class member;
- // for virtual methods, the method's offset within the vtable
- // for static methods, the method's offset within the class' static method table
- // for instance data, offset within the instance's data block
- // for static data, offset within the class' static data block
- unsigned _offset;
-
- bool _synthetic;
- bool _deprecated;
- AnnotationTable * _annotations;
-
- uint16 _access_flags;
- String * _name;
- String * _descriptor;
- String * _signature;
- Class * _class;
-
- bool parse(Class* clss, Const_Pool* cp, unsigned cp_size, ByteReader& cfs);
-
- /*
- * returns ATTR_ERROR if attribute was recognized but parsing failed;
- * returns ATTR_UNDEF if attribute was not recognized
- * otherwise returns passed attr value
- */
- Attributes process_common_attribute(Attributes attr, uint32 attr_len, ByteReader& cfs);
-
-public:
-#ifdef VM_STATS
- uint64 num_accesses;
- uint64 num_slow_accesses;
-#endif
-}; // Class_Member
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Fields within Class structures.
-///////////////////////////////////////////////////////////////////////////////
-struct Field : public Class_Member{
-public:
- //-----------------------
-
- // For all fields
- bool is_offset_computed() { return (_offset_computed != 0); }
- void set_offset_computed(bool is_computed) { _offset_computed = is_computed? 1 : 0; }
-
- // For static fields
- VMEXPORT void* get_address();
-
- // Return the type of this field.
- Java_Type get_java_type() {
- return (Java_Type)(get_descriptor()->bytes[0]);
- };
-
- Const_Java_Value get_const_value() { return const_value; };
- uint16 get_const_value_index() { return _const_value_index; };
-
- //-----------------------
-
- Field() {
- _const_value_index = 0;
- _field_type_desc = 0;
- _offset_computed = 0;
- _is_injected = 0;
- track_access = 0;
- track_modification = 0;
- }
-
- void Reset() { }
-
- void set(Class *cl, String* name, String* desc, unsigned short af) {
- _class = cl; _access_flags = af; _name = name; _descriptor = desc;
- }
- Field& operator = (const Field& fd) {
- // copy Class_Member fields
- _access_flags = fd._access_flags;
- _class = fd._class;
- _offset = fd._offset;
- _name = fd._name;
- _descriptor = fd._descriptor;
- _deprecated = fd._deprecated;
- _synthetic = fd._synthetic;
- _annotations = fd._annotations;
- _signature = fd._signature;
-
- // copy Field fields
- _const_value_index = fd._const_value_index;
- _field_type_desc = fd._field_type_desc;
- _is_injected = fd._is_injected;
- _offset_computed = fd._offset_computed;
- const_value = fd.const_value;
- track_access = fd.track_access;
- track_modification = fd.track_modification;
-
- return *this;
- }
- //
- // access modifiers
- //
- unsigned is_volatile() {return (_access_flags&ACC_VOLATILE);}
- unsigned is_transient() {return (_access_flags&ACC_TRANSIENT);}
- bool is_enum() {return (_access_flags&ACC_ENUM)?true:false;}
-
- bool parse(Class* clss, Const_Pool* cp, unsigned cp_size, ByteReader& cfs);
-
- unsigned calculate_size() {
- unsigned size = sizeof(Class_Member) + sizeof(Field);
- size += sizeof(TypeDesc);
- return size;
- }
-
- TypeDesc* get_field_type_desc() { return _field_type_desc; }
- void set_field_type_desc(TypeDesc* td) { _field_type_desc = td; }
-
- Boolean is_injected() {return _is_injected;}
- void set_injected() { _is_injected = 1; }
-
- void set_track_access(bool value) {
- track_access = value ? 1 : 0 ;
- }
-
- void set_track_modification(bool value) {
- track_modification = value ? 1 : 0 ;
- }
-
- void get_track_access_flag(char** address, char* mask) {
- *address = &track_access;
- *mask = TRACK_ACCESS_MASK;
- }
-
- void get_track_modification_flag(char** address, char* mask) {
- *address = &track_modification;
- *mask = TRACK_MODIFICATION_MASK;
- }
-
-private:
- //
- // The initial values of static fields. This is defined by the
- // ConstantValue attribute in the class file.
- //
- // If there was not ConstantValue attribute for that field then _const_value_index==0
- //
- uint16 _const_value_index;
- Const_Java_Value const_value;
- TypeDesc* _field_type_desc;
- unsigned _is_injected : 1;
- unsigned _offset_computed : 1;
-
- /** Turns on sending FieldAccess events on access to this field */
- char track_access;
- const static char TRACK_ACCESS_MASK = 1;
-
- /** Turns on sending FieldModification events on modification of this field */
- char track_modification;
- const static char TRACK_MODIFICATION_MASK = 1;
-
- //union {
- // char bit_flags;
- // struct {
-
- // /** Turns on sending FieldAccess events on access to this field */
- // char track_access : 1;
- // const static char TRACK_ACCESS_MASK = 4;
-
- // /** Turns on sending FieldModification events on modification of this field */
- // char track_modification : 1;
- // const static char TRACK_MODIFICATION_MASK = 8;
- // };
- //};
-}; // Field
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Handler represents a catch block in a method's code array
-///////////////////////////////////////////////////////////////////////////////
-class Handler {
-public:
- Handler();
- bool parse(Const_Pool *cp, unsigned cp_size,
- unsigned code_length, ByteReader &cfs);
- uint32 get_start_pc() {return _start_pc;}
- uint32 get_end_pc() {return _end_pc;}
- uint32 get_handler_pc() {return _handler_pc;}
- uint32 get_catch_type_index() {return _catch_type_index;}
-
-
-private:
- uint32 _start_pc;
- uint32 _end_pc;
- uint32 _handler_pc;
- uint32 _catch_type_index; // CP idx
- String *_catch_type;
-
-}; //Handler
-
-
-
-// Representation of target handlers in the generated code.
-class Target_Exception_Handler {
-public:
- Target_Exception_Handler(NativeCodePtr start_ip, NativeCodePtr end_ip, NativeCodePtr handler_ip, Class_Handle exn_class, bool exn_is_dead);
-
- NativeCodePtr get_start_ip();
- NativeCodePtr get_end_ip();
- NativeCodePtr get_handler_ip();
- Class_Handle get_exc();
- bool is_exc_obj_dead();
-
- bool is_in_range(NativeCodePtr eip, bool is_ip_past);
- bool is_assignable(Class_Handle exn_class);
-
- void update_catch_range(NativeCodePtr new_start_ip, NativeCodePtr new_end_ip);
- void update_handler_address(NativeCodePtr new_handler_ip);
-
-private:
- NativeCodePtr _start_ip;
- NativeCodePtr _end_ip;
- NativeCodePtr _handler_ip;
- Class_Handle _exc;
- bool _exc_obj_is_dead;
-}; //Target_Exception_Handler
-
-typedef Target_Exception_Handler *Target_Exception_Handler_Ptr;
-
-
-#define MAX_VTABLE_PATCH_ENTRIES 10
-
-class VTable_Patches {
-public:
- void *patch_table[MAX_VTABLE_PATCH_ENTRIES];
- VTable_Patches *next;
-};
-
-
-
-/////////////////////////////////////////////////////////////////
-// begin multiple-JIT support
-
int get_index_of_jit(JIT *jit);
-
-struct JIT_Data_Block {
- JIT_Data_Block *next;
- char bytes[1];
-};
-
-
-// Each callee for a given code chunk can have multiple Callee_Info structures, one for each call site in the caller.
-typedef struct Callee_Info {
- void *caller_ip; // the IP in the caller where the call was made
- CodeChunkInfo *callee; // which code chunk was called
- uint64 num_calls;
-} Callee_Info;
-
-
-#define NUM_STATIC_CALLEE_ENTRIES 8
-
-
-class CodeChunkInfo {
- friend struct Method;
-public:
- CodeChunkInfo();
-
- void set_jit(JIT *jit) { _jit = jit; }
- JIT *get_jit() { return _jit; }
-
- void set_method(Method *m) { _method = m; }
- Method *get_method() { return _method; }
-
- void set_id(int id) { _id = id; }
- int get_id() { return _id; }
-
- void set_relocatable(Boolean r) { _relocatable = r; }
- Boolean get_relocatable() { return _relocatable; }
-
- void set_heat(unsigned heat) { _heat = heat; }
- unsigned get_heat() { return _heat; }
-
- void *get_code_block_addr() { return _code_block; }
- void set_code_block_addr(void *addr) { _code_block = addr; }
-
- size_t get_code_block_size() { return _code_block_size; }
- size_t get_code_block_alignment() { return _code_block_alignment; }
-
- void set_loaded_for_vtune(bool v) { _has_been_loaded_for_vtune = v; }
- bool get_loaded_for_vtune() { return _has_been_loaded_for_vtune; }
-
- unsigned get_num_callees() { return _num_callees; }
- Callee_Info *get_callees() { return _callee_info; }
-
- int get_jit_index() { return get_index_of_jit(_jit); }
-
- // Note: _data_blocks can only be used for inline info for now
- Boolean has_inline_info() { return _data_blocks != NULL; }
- void *get_inline_info() { return &_data_blocks->bytes[0]; }
-
- unsigned get_num_target_exception_handlers();
- Target_Exception_Handler_Ptr get_target_exception_handler_info(unsigned eh_num);
-
- void record_call_to_callee(CodeChunkInfo *callee, void *caller_return_ip);
- uint64 num_calls_to(CodeChunkInfo *other_chunk);
-
- void print_name();
- void print_name(FILE *file);
- void print_info(bool print_ellipses=false); // does not print callee information; see below
- void print_callee_info(); // prints the callee information; usually called after print_info()
-
- static void initialize_code_chunk(CodeChunkInfo *chunk);
-
-public:
- // The section id of the main code chunk for a method. Using an enum avoids a VC++ bug on Windows.
- enum {main_code_chunk_id = 0};
-
- // A predicate that returns true iff this is the main code chunk for a method: i.e, it 1) contains the method's entry point,
- // and 2) contains the various flavors of JIT data for that method.
- static bool is_main_code_chunk(CodeChunkInfo *chunk) { assert(chunk); return (chunk->get_id() == main_code_chunk_id); }
-
- // A predicate that returns true iff "id" is the section id of the main code chunk for a method.
- static bool is_main_code_chunk_id(int id) { return (id == main_code_chunk_id); }
-
-private:
- // The triple (_jit, _method, _id) uniquely identifies a CodeChunkInfo.
- JIT *_jit;
- Method *_method;
- int _id;
- bool _relocatable;
-
- // "Target" handlers.
- unsigned _num_target_exception_handlers;
- Target_Exception_Handler_Ptr *_target_exception_handlers;
-
- bool _has_been_loaded_for_vtune;
-
- // 20040224 This records information about the methods (actually, CodeChunkInfo's) called by this CodeChunkInfo.
- // 20040405 This now records for each callee, the number of times it was called by each call IP in the caller.
- // That is, this is a list of Callee_Info structures, each giving a call IP
- Callee_Info *_callee_info; // points to an array of max_callees Callee_Info entries for this code chunk
- unsigned _num_callees;
- unsigned _max_callees;
- Callee_Info _static_callee_info[NUM_STATIC_CALLEE_ENTRIES]; // Array used if a small number of callers to avoid mallocs & frees
-
-public:
- unsigned _heat;
- void *_code_block;
- void *_jit_info_block;
- size_t _code_block_size;
- size_t _jit_info_block_size;
- size_t _code_block_alignment;
- JIT_Data_Block *_data_blocks;
- DynoptInfo *_dynopt_info;
- CodeChunkInfo *_next;
-
-#ifdef VM_STATS
- uint64 num_throws;
- uint64 num_catches;
- uint64 num_unwind_java_frames_gc;
- uint64 num_unwind_java_frames_non_gc;
-#endif
-}; //CodeChunkInfo
-
-
-// end multiple-JIT support
-/////////////////////////////////////////////////////////////////
-
-
-
-// Used to notify interested JITs whenever a method is changed: overwritten, recompiled,
-// or initially compiled.
-struct Method_Change_Notification_Record {
- Method *method_of_interest;
- JIT *jit;
- void *callback_data;
- Method_Change_Notification_Record *next;
-
- bool equals(Method *method_of_interest_, JIT *jit_, void *callback_data_) {
- if ((method_of_interest == method_of_interest_) &&
- (jit == jit_) &&
- (callback_data == callback_data_)) {
- return true;
- }
- return false;
- }
- // Optimized equals method. Most callbacks know method of interest, so we could skip one check.
- inline bool equals(JIT *jit_, void *callback_data_) {
- if ((callback_data == callback_data_) &&
- (jit == jit_)) {
- return true;
- }
- return false;
- }
-};
-
-
-struct Inline_Record;
-
-
-// 20020222 This is only temporary to support the new JIT interface.
-// We will reimplement the signature support.
-struct Method_Signature {
-public:
- TypeDesc* return_type_desc;
- unsigned num_args;
- TypeDesc** arg_type_descs;
- Method *method;
- String *sig;
-
-
- void initialize_from_method(Method *method);
- void reset();
-
-private:
- void initialize_from_java_method(Method *method);
-};
-
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Methods defined in a class.
-///////////////////////////////////////////////////////////////////////////////
-
-// VMEXPORT // temporary solution for interpreter unplug
-struct VMEXPORT Method : public Class_Member {
- //-----------------------
-public:
- //
- // state of this method
- //
- enum State {
- ST_NotCompiled, // initial state
- ST_NotLinked = ST_NotCompiled, // native not linked to implementation
- ST_Compiled, // compiled by JIT
- ST_Linked = ST_Compiled // native linked to implementation
- };
- State get_state() {return _state;}
- void set_state(State st) {_state=st;}
-
- // "Bytecode" exception handlers, i.e., those from the class file
- unsigned num_bc_exception_handlers();
- Handler *get_bc_exception_handler_info(unsigned eh_number);
-
- // "Target" exception handlers, i.e., those in the code generated by the JIT.
- void set_num_target_exception_handlers(JIT *jit, unsigned n);
- unsigned get_num_target_exception_handlers(JIT *jit);
-
- // Arguments:
- // ...
- // catch_clss -- class of the exception or null (for "catch-all")
- // ...
- void set_target_exception_handler_info(JIT *jit,
- unsigned eh_number,
- void *start_ip,
- void *end_ip,
- void *handler_ip,
- Class *catch_clss,
- bool exc_obj_is_dead = false);
-
- Target_Exception_Handler_Ptr get_target_exception_handler_info(JIT *jit, unsigned eh_num);
-
- unsigned num_exceptions_method_can_throw();
- String *get_exception_name (int n);
-
- // Address of the memory block containing bytecodes. For best performance
- // the bytecodes should not be destroyed even after the method has been
- // jitted to allow re-compilation. However the interface allows for such
- // deallocation. The effect would be that re-optimizing JITs would not
- // show their full potential, but that may be acceptable for low-end systems
- // where memory is at a premium.
- // The value returned by getByteCodeAddr may be NULL in which case the
- // bytecodes are not available (presumably they have been garbage collected by VM).
- const Byte *get_byte_code_addr() {return _byte_codes;}
- size_t get_byte_code_size() {return _byte_code_length;}
-
- // From the class file (Sec. 4.7.4)
- unsigned get_max_stack() { return _max_stack; }
- unsigned get_max_locals() { return _max_locals; }
-
- // Returns an iterator for the argument list.
- Arg_List_Iterator get_argument_list();
-
- // Returns number of bytes of arguments pushed on the stack.
- // This value depends on the descriptor and the calling convention.
- unsigned get_num_arg_bytes();
-
- // Returns number of arguments. For non-static methods, the this pointer
- // is included in this number
- unsigned get_num_args();
-
- // Number of arguments which are references.
- unsigned get_num_ref_args();
-
-
- // Return the return type of this method.
- Java_Type get_return_java_type();
-
- // For non-primitive types (i.e., classes) get the class type information.
- Class *get_return_class_type();
-
- // Address of the memory location containing the address of the code.
- // Used for static and special methods which have been resolved but not jitted.
- // The call would be:
- // call dword ptr [addr]
- void *get_indirect_address() { return &_code; }
-
- // Entry address of the method. Points to an appropriate stub or directly
- // to the code if no stub is necessary.
- void *get_code_addr() { return _code; }
- void set_code_addr(void *code_addr) { _code = code_addr; }
-
- void add_vtable_patch(void *);
- void apply_vtable_patches();
-
- /**
- * This returns a block for jitted code. It is not used for native methods.
- * It is safe to call this function from multiple threads.
- */
- void *allocate_code_block_mt(size_t size, size_t alignment, JIT *jit, unsigned heat,
- int id, Code_Allocation_Action action);
-
- void *allocate_rw_data_block(size_t size, size_t alignment, JIT *jit);
-
- // The JIT can store some information in a JavaMethod object.
- void *allocate_jit_info_block(size_t size, JIT *jit);
-
- // JIT-specific data blocks.
- // Access should be protected with _lock.
- // FIXME
- // Think about moving lock aquisition inside public methods.
- void *allocate_JIT_data_block(size_t size, JIT *jit, size_t alignment);
- CodeChunkInfo *get_first_JIT_specific_info() { return _jits; };
- CodeChunkInfo *get_JIT_specific_info_no_create(JIT *jit);
- /**
- * Find a chunk info for specific JIT. If no chunk exist for this JIT,
- * create and return one. This method is safe to call
- * from multiple threads.
- */
- CodeChunkInfo *get_chunk_info_mt(JIT *jit, int id);
-
- /**
- * Find a chunk info for specific JIT, or NULL if
- * no chunk info is created for this JIT. This method is safe to call
- * from multiple threads.
- */
- CodeChunkInfo *get_chunk_info_no_create_mt(JIT *jit, int id);
-
- /**
- * Allocate a new chunk info. This method is safe to call
- * from multiple threads.
- */
- CodeChunkInfo *create_code_chunk_info_mt();
-
- // Notify JITs whenever this method is overridden by a newly loaded class.
- void register_jit_overridden_method_callback(JIT *jit_to_be_notified, void *callback_data);
- void do_jit_overridden_method_callbacks(Method *overriding_method);
-
- // Notify JITs whenever this method is recompiled or initially compiled.
- void register_jit_recompiled_method_callback(JIT *jit_to_be_notified, void *callback_data);
- void do_jit_recompiled_method_callbacks();
-
- Method_Side_Effects get_side_effects() { return _side_effects; };
- void set_side_effects(Method_Side_Effects mse) { _side_effects = mse; };
-
- Method_Signature *get_method_sig() { return _method_sig; };
- void set_method_sig(Method_Signature *msig) { _method_sig = msig; };
-
-private:
- State _state;
- void *_code;
- VTable_Patches *_vtable_patch;
-
- NativeCodePtr _counting_stub;
-
- CodeChunkInfo *_jits;
-
- Method_Side_Effects _side_effects;
- Method_Signature *_method_sig;
-
-public:
- Method();
- // destructor should be instead of this function, but it's not allowed to use it because copy for Method class is
- // done with memcpy, and old value is destroyed with delete operator.
- void MethodClearInternals();
-
- //
- // access modifiers
- //
- bool is_synchronized() {return (_access_flags&ACC_SYNCHRONIZED)?true:false;}
- bool is_native() {return (_access_flags&ACC_NATIVE)?true:false;}
- bool is_abstract() {return (_access_flags&ACC_ABSTRACT)?true:false;}
- bool is_varargs() {return (_access_flags&ACC_VARARGS)?true:false;}
- bool is_bridge() {return (_access_flags&ACC_BRIDGE)?true:false;}
-
- // method flags
- bool is_init() {return _flags.is_init?true:false;}
- bool is_clinit() {return _flags.is_clinit?true:false;}
- bool is_finalize() {return _flags.is_finalize?true:false;}
- bool is_overridden() {return _flags.is_overridden?true:false;}
- bool is_registered() {return _flags.is_registered?true:false;}
- Boolean is_nop() {return _flags.is_nop;}
-
- void set_registered( bool flag ) { _flags.is_registered = flag; }
-
- unsigned get_index() {return _index;}
-
- // Fake methods are interface methods inherited by an abstract class that are not (directly or indirectly)
- // implemented by that class. They are added to the class to ensure they have thecorrect vtable offset.
- // These fake methods point to the "real" interface method for which they are surrogates; this information
- // is used by reflection methods.
- bool is_fake_method() {return (_intf_method_for_fake_method != NULL);}
- Method *get_real_intf_method() {return _intf_method_for_fake_method;}
-
- bool parse(Global_Env& env, Class* clss,
- Const_Pool* cp, unsigned cp_size, ByteReader& cfs);
-
- unsigned calculate_size() {
- unsigned size = sizeof(Class_Member) + sizeof(Method);
- if(_local_vars_table)
- size += sizeof(uint16) + _local_vars_table->length*sizeof(Local_Var_Entry);
- if(_line_number_table)
- size += sizeof(uint16) + _line_number_table->length*sizeof(Line_Number_Entry);
- size += _n_exceptions*sizeof(String*);
- size += _n_handlers*sizeof(Handler);
- size += _byte_code_length;
- return size;
- }
-
- friend void assign_offsets_to_class_methods(Class* clss);
- friend void add_new_fake_method(Class* clss, Class* example, unsigned* next);
- friend void add_any_fake_methods(Class* clss);
-
- unsigned get_num_param_annotations() {return _num_param_annotations;}
- AnnotationTable * get_param_annotations(unsigned index) {
- return index < _num_param_annotations ? _param_annotations[index] : NULL;
- }
- AnnotationValue * get_default_value() {return _default_value; }
-
-private:
- uint8 _num_param_annotations;
- AnnotationTable ** _param_annotations;
- AnnotationValue * _default_value;
-
- unsigned _index; // index in method table
- uint16 _max_stack;
- uint16 _max_locals;
- uint16 _n_exceptions; // num exceptions method can throw
- uint16 _n_handlers; // num exception handlers in byte codes
- String **_exceptions; // array of exceptions method can throw
- uint32 _byte_code_length; // num bytes of byte code
- Byte *_byte_codes; // method's byte codes
- Handler *_handlers; // array of exception handlers in code
- Method *_intf_method_for_fake_method;
- struct {
- unsigned is_init : 1;
- unsigned is_clinit : 1;
- unsigned is_finalize : 1; // is finalize() method
- unsigned is_overridden : 1; // has this virtual method been overridden by a loaded subclass?
- unsigned is_nop : 1;
- unsigned is_registered : 1; // the method is registred native method
- } _flags;
-
- //
- // private methods for parsing methods
- //
- bool _parse_code(Const_Pool *cp, unsigned cp_size, unsigned code_attr_len, ByteReader &cfs);
-
- bool _parse_line_numbers(unsigned attr_len, ByteReader &cfs);
-
- bool _parse_exceptions(Const_Pool *cp, unsigned cp_size, unsigned attr_len,
- ByteReader &cfs);
-
- void _set_nop();
-
- //
- // debugging info
- //
- Line_Number_Table *_line_number_table;
- Local_Var_Table *_local_vars_table;
-
- bool _parse_local_vars(const char* attr_name, Local_Var_Table** lvt_address,
- Const_Pool *cp, unsigned cp_size, unsigned attr_len, ByteReader &cfs);
-
- // This is the number of breakpoints which should be set in the
- // method when it is compiled. This number does not reflect
- // multiple breakpoints that are set in the same location by
- // different environments, it counts only unique locations
- uint32 pending_breakpoints;
-public:
-
- unsigned get_line_number_table_size() {
- return (_line_number_table) ? _line_number_table->length : 0;
- }
-
- bool get_line_number_entry(unsigned index, jlong* pc, jint* line);
-
- unsigned get_local_var_table_size() {
- return (_local_vars_table) ? _local_vars_table->length : 0;
- }
-
- bool get_local_var_entry(unsigned index, jlong* pc,
- jint* length, jint* slot, String** name, String** type,
- String** generic_type);
-
- // XXX
- //bool get_local_var_entry(unsigned index, jlong* pc,
- // jint* length, jint* slot, String** name, String** type);
-
-
- // Returns number of line in the source file, to which the given bytecode offset
- // corresponds, or -1 if it is unknown.
- int get_line_number(uint16 bc_offset);
-
- Inline_Record *inline_records;
- void set_inline_assumption(JIT *jit, Method *caller);
- void method_was_overridden();
-
- Method_Change_Notification_Record *_notify_override_records;
-
- // Records JITs to be notified when a method is recompiled or initially compiled.
- Method_Change_Notification_Record *_notify_recompiled_records;
-
- void lock();
- void unlock();
-
- uint32 get_pending_breakpoints()
- {
- return pending_breakpoints;
- }
-
- void insert_pending_breakpoint()
- {
- pending_breakpoints++;
- }
-
- void remove_pending_breakpoint()
- {
- pending_breakpoints--;
- }
-}; // Method
-
-
VMEXPORT Class* load_class(Global_Env *env, const String *classname);
Class* find_loaded_class(Global_Env *env, const String *classname);
diff --git a/enhanced/drlvm/trunk/vm/vmcore/include/annotation.h b/enhanced/drlvm/trunk/vm/vmcore/include/annotation.h
new file mode 100644
index 0000000..d305b35
--- /dev/null
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/annotation.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __ANNOTATION_H__
+#define __ANNOTATION_H__
+
+enum AnnotationValueType {
+ // 'B', 'C', 'D', 'F', 'I', 'J', 'S', and 'Z' 's' 'e' 'c' '@' '['
+ AVT_BYTE = 'B',
+ AVT_CHAR = 'C',
+ AVT_DOUBLE = 'D',
+ AVT_FLOAT = 'F',
+ AVT_INT = 'I',
+ AVT_LONG = 'J',
+ AVT_SHORT = 'S',
+ AVT_BOOLEAN = 'Z',
+ AVT_STRING = 's',
+ AVT_ENUM = 'e',
+ AVT_CLASS = 'c',
+ AVT_ANNOTN = '@',
+ AVT_ARRAY = '['
+};
+
+// forward declarations
+struct Annotation;
+
+///////////////////////////////////////////////////////////////////////////////
+// Constant Java values
+///////////////////////////////////////////////////////////////////////////////
+union Const_Java_Value {
+ uint32 i;
+ int64 j;
+ struct {
+ uint32 lo_bytes;
+ uint32 hi_bytes;
+ } l;
+ float f;
+ double d;
+ String *string;
+ void *object;
+};
+
+
+// element-value pair of an annotation
+struct AnnotationValue {
+ union {
+ Const_Java_Value const_value;
+ String* class_name;
+ Annotation* nested;
+ struct {
+ String* type;
+ String* name;
+ } enum_const;
+ struct {
+ AnnotationValue* items;
+ uint16 length;
+ } array;
+ };
+ AnnotationValueType tag;
+};
+
+struct AnnotationElement {
+ String* name;
+ AnnotationValue value;
+};
+
+struct Annotation {
+ String* type;
+ AnnotationElement* elements;
+ uint16 num_elements;
+};
+
+struct AnnotationTable {
+ uint16 length;
+ Annotation* table[1];
+};
+
+#endif
\ No newline at end of file
diff --git a/enhanced/drlvm/trunk/vm/vmcore/include/cci.h b/enhanced/drlvm/trunk/vm/vmcore/include/cci.h
new file mode 100644
index 0000000..68ae947
--- /dev/null
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/cci.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __CCI_H__
+#define __CCI_H__
+
+// forward declarations
+class CodeChunkInfo;
+
+// external declarations
+class JIT;
+typedef class Target_Exception_Handler* Target_Exception_Handler_Ptr;
+
+struct JIT_Data_Block {
+ JIT_Data_Block *next;
+ char bytes[1];
+};
+
+// Each callee for a given code chunk can have multiple Callee_Info structures,
+// one for each call site in the caller.
+typedef struct Callee_Info {
+ void* caller_ip; // the IP in the caller where the call was made
+ CodeChunkInfo* callee; // which code chunk was called
+ uint64 num_calls; // number of calls to that chunk
+} Callee_Info;
+
+#define NUM_STATIC_CALLEE_ENTRIES 8
+
+class CodeChunkInfo {
+ friend struct Method;
+public:
+ CodeChunkInfo();
+
+ void set_jit(JIT* jit) { _jit = jit; }
+ JIT* get_jit() const { return _jit; }
+
+ void set_method(Method* m) { _method = m; }
+ Method* get_method() const { return _method; }
+
+ void set_id(int id) { _id = id; }
+ int get_id() const { return _id; }
+
+ void set_relocatable(Boolean r) { _relocatable = r; }
+ Boolean get_relocatable() const { return _relocatable; }
+
+ void set_heat(unsigned heat) { _heat = heat; }
+ unsigned get_heat() const { return _heat; }
+
+ void set_code_block_addr(void* addr) { _code_block = addr; }
+ void* get_code_block_addr() const { return _code_block; }
+
+ size_t get_code_block_size() const { return _code_block_size; }
+ size_t get_code_block_alignment() const { return _code_block_alignment; }
+
+ unsigned get_num_callees() const { return _num_callees; }
+ Callee_Info* get_callees() const { return _callee_info; }
+
+ int get_jit_index() const;
+
+ // Note: _data_blocks can only be used for inline info for now
+ Boolean has_inline_info() const { return _data_blocks != NULL; }
+ void* get_inline_info() const { return &_data_blocks->bytes[0]; }
+
+ unsigned get_num_target_exception_handlers() const;
+ Target_Exception_Handler_Ptr get_target_exception_handler_info(unsigned eh_num) const;
+
+ void record_call_to_callee(CodeChunkInfo *callee, void *caller_return_ip);
+ uint64 num_calls_to(CodeChunkInfo* other_chunk) const;
+
+ void print_name() const;
+ void print_name(FILE* file) const;
+ void print_info(bool print_ellipses=false) const; // does not print callee information; see below
+ void print_callee_info() const; // prints the callee information; usually called after print_info()
+
+ static void initialize_code_chunk(CodeChunkInfo* chunk) {
+ memset(chunk, 0, sizeof(CodeChunkInfo));
+ chunk->_callee_info = chunk->_static_callee_info;
+ chunk->_max_callees = NUM_STATIC_CALLEE_ENTRIES;
+ chunk->_relocatable = TRUE;
+ }
+
+public:
+ // The section id of the main code chunk for a method. Using an enum avoids a VC++ bug on Windows.
+ enum {main_code_chunk_id = 0};
+
+ // Returns true if this is the main code chunk
+ // for a method: i.e, it
+ // 1) contains the method's entry point, and
+ // 2) contains the various flavors of JIT data for that method.
+ static bool is_main_code_chunk(CodeChunkInfo* chunk) {
+ assert(chunk);
+ return (chunk->get_id() == main_code_chunk_id);
+ }
+
+ // Returns true if "id" is the section id of the main code chunk for a method.
+ static bool is_main_code_chunk_id(int id) {
+ return (id == main_code_chunk_id);
+ }
+
+private:
+ // The triple (_jit, _method, _id) uniquely identifies a CodeChunkInfo
+ JIT* _jit;
+ Method* _method;
+ int _id;
+
+ bool _relocatable;
+
+ // "Target" handlers
+ unsigned _num_target_exception_handlers;
+ Target_Exception_Handler_Ptr* _target_exception_handlers;
+
+ // This records for each callee, the number of times it was called
+ // by each call IP in the caller. That is, this is a list of Callee_Info
+ // structures, each giving a call IP
+ // Points to an array of max_callees Callee_Info entries for this code chunk
+ Callee_Info* _callee_info;
+ unsigned _num_callees;
+ unsigned _max_callees;
+ // Array used if a small number of callers to avoid mallocs & frees
+ Callee_Info _static_callee_info[NUM_STATIC_CALLEE_ENTRIES];
+
+public:
+ unsigned _heat;
+ void* _code_block;
+ void* _jit_info_block;
+ size_t _code_block_size;
+ size_t _jit_info_block_size;
+ size_t _code_block_alignment;
+ JIT_Data_Block* _data_blocks;
+ CodeChunkInfo* _next;
+
+#ifdef VM_STATS
+ uint64 num_throws;
+ uint64 num_catches;
+ uint64 num_unwind_java_frames_gc;
+ uint64 num_unwind_java_frames_non_gc;
+#endif
+}; // CodeChunkInfo
+
+#endif
diff --git a/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h b/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
new file mode 100644
index 0000000..b0e3186
--- /dev/null
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
@@ -0,0 +1,743 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __CLASS_MEMBER_H__
+#define __CLASS_MEMBER_H__
+
+#include "String_Pool.h"
+#include "annotation.h"
+#include "jit_intf.h"
+
+union Const_Pool;
+class ByteReader;
+class JIT;
+class CodeChunkInfo;
+struct Global_Env;
+
+///////////////////////////////////////////////////////////////////////////////
+// class file attributes
+///////////////////////////////////////////////////////////////////////////////
+enum Attributes {
+ ATTR_SourceFile, // Class (no more than 1 in each class file)
+ ATTR_InnerClasses, // Class
+ ATTR_ConstantValue, // Field (no more than 1 for each field)
+ ATTR_Code, // Method
+ ATTR_Exceptions, // Method
+ ATTR_LineNumberTable, // Code
+ ATTR_LocalVariableTable, // Code
+ ATTR_Synthetic, // Class/Field/Method
+ ATTR_Deprecated, // Class/Field/Method
+ ATTR_SourceDebugExtension, // Class (no more than 1 in each class file)
+ ATTR_Signature, // Class/Field/Method (spec does not limit number???)
+ ATTR_EnclosingMethod, // Class (1 at most)
+ ATTR_LocalVariableTypeTable, // Code
+ ATTR_RuntimeVisibleAnnotations, // Class/Field/Method (at most 1 per entity)
+ ATTR_RuntimeInvisibleAnnotations, // Class/Field/Method
+ ATTR_RuntimeVisibleParameterAnnotations, // Method
+ ATTR_RuntimeInvisibleParameterAnnotations, // Method
+ ATTR_AnnotationDefault, // Method (spec does not limit number???)
+ N_ATTR,
+ ATTR_UNDEF,
+ ATTR_ERROR
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// A class' members are its fields and methods. Class_Member is the base
+// class for Field and Method, and factors out the commonalities in these
+// two classes.
+///////////////////////////////////////////////////////////////////////////////
+// VMEXPORT // temporary solution for interpreter unplug
+class VMEXPORT Class_Member {
+public:
+ //
+ // access modifiers
+ //
+ bool is_public() {return (_access_flags&ACC_PUBLIC)?true:false;}
+ bool is_private() {return (_access_flags&ACC_PRIVATE)?true:false;}
+ bool is_protected() {return (_access_flags&ACC_PROTECTED)?true:false;}
+ bool is_package_private() {return !(is_public()||is_protected()||is_public())?true:false;}
+ bool is_static() {return (_access_flags&ACC_STATIC)?true:false;}
+ bool is_final() {return (_access_flags&ACC_FINAL)?true:false;}
+ bool is_strict() {return (_access_flags&ACC_STRICT)?true:false;}
+ bool is_synthetic() {return (_access_flags&ACC_SYNTHETIC)?true:_synthetic;}
+ bool is_deprecated() {return _deprecated;}
+ unsigned get_access_flags() {return _access_flags;}
+
+ //
+ // field get/set methods
+ //
+ unsigned get_offset() const {return _offset;}
+ Class *get_class() const {return _class;}
+ String *get_name() const {return _name;}
+
+ // Get the type descriptor (Sec. 4.3.2)
+ String *get_descriptor() const {return _descriptor;}
+ String *get_signature() const {return _signature;}
+
+ AnnotationTable* get_declared_annotations() const {return _annotations;}
+
+ friend void assign_instance_field_offset(Class *clss, Field *field, bool do_field_compaction);
+ friend void assign_offsets_to_static_fields(Class *clss, Field **field_ptrs, bool do_field_compaction);
+ friend void assign_offsets_to_class_fields(Class *);
+ friend void add_new_fake_method(Class *clss, Class *example, unsigned *next);
+ friend void add_any_fake_methods(Class *);
+
+ /**
+ * Allocate a memory from a class loader pool using the class
+ * loader lock.
+ */
+ void* Alloc(size_t size);
+
+protected:
+ Class_Member()
+ {
+ _access_flags = 0;
+ _class = NULL;
+ _offset = 0;
+#ifdef VM_STATS
+ num_accesses = 0;
+ num_slow_accesses = 0;
+#endif
+ _synthetic = _deprecated = false;
+ _annotations = NULL;
+ _signature = NULL;
+ }
+
+ // offset of class member;
+ // for virtual methods, the method's offset within the vtable
+ // for static methods, the method's offset within the class' static method table
+ // for instance data, offset within the instance's data block
+ // for static data, offset within the class' static data block
+ unsigned _offset;
+
+ bool _synthetic;
+ bool _deprecated;
+ AnnotationTable* _annotations;
+
+ uint16 _access_flags;
+ String* _name;
+ String* _descriptor;
+ String* _signature;
+ Class* _class;
+
+ bool parse(Class* clss, Const_Pool* cp, unsigned cp_size, ByteReader& cfs);
+
+ /*
+ * returns ATTR_ERROR if attribute was recognized but parsing failed;
+ * returns ATTR_UNDEF if attribute was not recognized
+ * otherwise returns passed attr value
+ */
+ Attributes process_common_attribute(Attributes attr, uint32 attr_len, ByteReader& cfs);
+
+public:
+#ifdef VM_STATS
+ uint64 num_accesses;
+ uint64 num_slow_accesses;
+#endif
+}; // Class_Member
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Fields within Class structures.
+///////////////////////////////////////////////////////////////////////////////
+struct Field : public Class_Member{
+public:
+ //-----------------------
+
+ // For all fields
+ bool is_offset_computed() { return (_offset_computed != 0); }
+ void set_offset_computed(bool is_computed) { _offset_computed = is_computed? 1 : 0; }
+
+ // For static fields
+ VMEXPORT void* get_address();
+
+ // Return the type of this field.
+ Java_Type get_java_type() {
+ return (Java_Type)(get_descriptor()->bytes[0]);
+ };
+
+ Const_Java_Value get_const_value() { return const_value; };
+ uint16 get_const_value_index() { return _const_value_index; };
+
+ //-----------------------
+
+ Field() {
+ _const_value_index = 0;
+ _field_type_desc = 0;
+ _offset_computed = 0;
+ _is_injected = 0;
+ track_access = 0;
+ track_modification = 0;
+ }
+
+ void Reset() { }
+
+ void set(Class *cl, String* name, String* desc, unsigned short af) {
+ _class = cl; _access_flags = af; _name = name; _descriptor = desc;
+ }
+ Field& operator = (const Field& fd) {
+ // copy Class_Member fields
+ _access_flags = fd._access_flags;
+ _class = fd._class;
+ _offset = fd._offset;
+ _name = fd._name;
+ _descriptor = fd._descriptor;
+ _deprecated = fd._deprecated;
+ _synthetic = fd._synthetic;
+ _annotations = fd._annotations;
+ _signature = fd._signature;
+
+ // copy Field fields
+ _const_value_index = fd._const_value_index;
+ _field_type_desc = fd._field_type_desc;
+ _is_injected = fd._is_injected;
+ _offset_computed = fd._offset_computed;
+ const_value = fd.const_value;
+ track_access = fd.track_access;
+ track_modification = fd.track_modification;
+
+ return *this;
+ }
+ //
+ // access modifiers
+ //
+ unsigned is_volatile() {return (_access_flags&ACC_VOLATILE);}
+ unsigned is_transient() {return (_access_flags&ACC_TRANSIENT);}
+ bool is_enum() {return (_access_flags&ACC_ENUM)?true:false;}
+
+ bool parse(Class* clss, Const_Pool* cp, unsigned cp_size, ByteReader& cfs);
+
+ unsigned calculate_size();
+
+ TypeDesc* get_field_type_desc() { return _field_type_desc; }
+ void set_field_type_desc(TypeDesc* td) { _field_type_desc = td; }
+
+ Boolean is_injected() {return _is_injected;}
+ void set_injected() { _is_injected = 1; }
+
+ void set_track_access(bool value) {
+ track_access = value ? 1 : 0 ;
+ }
+
+ void set_track_modification(bool value) {
+ track_modification = value ? 1 : 0 ;
+ }
+
+ void get_track_access_flag(char** address, char* mask) {
+ *address = &track_access;
+ *mask = TRACK_ACCESS_MASK;
+ }
+
+ void get_track_modification_flag(char** address, char* mask) {
+ *address = &track_modification;
+ *mask = TRACK_MODIFICATION_MASK;
+ }
+
+private:
+ //
+ // The initial values of static fields. This is defined by the
+ // ConstantValue attribute in the class file.
+ //
+ // If there was not ConstantValue attribute for that field then _const_value_index==0
+ //
+ uint16 _const_value_index;
+ Const_Java_Value const_value;
+ TypeDesc* _field_type_desc;
+ unsigned _is_injected : 1;
+ unsigned _offset_computed : 1;
+
+ /** Turns on sending FieldAccess events on access to this field */
+ char track_access;
+ const static char TRACK_ACCESS_MASK = 1;
+
+ /** Turns on sending FieldModification events on modification of this field */
+ char track_modification;
+ const static char TRACK_MODIFICATION_MASK = 1;
+
+ //union {
+ // char bit_flags;
+ // struct {
+
+ // /** Turns on sending FieldAccess events on access to this field */
+ // char track_access : 1;
+ // const static char TRACK_ACCESS_MASK = 4;
+
+ // /** Turns on sending FieldModification events on modification of this field */
+ // char track_modification : 1;
+ // const static char TRACK_MODIFICATION_MASK = 8;
+ // };
+ //};
+}; // Field
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Handler represents a catch block in a method's code array
+///////////////////////////////////////////////////////////////////////////////
+class Handler {
+public:
+ Handler();
+ bool parse(Const_Pool *cp, unsigned cp_size,
+ unsigned code_length, ByteReader &cfs);
+ uint32 get_start_pc() {return _start_pc;}
+ uint32 get_end_pc() {return _end_pc;}
+ uint32 get_handler_pc() {return _handler_pc;}
+ uint32 get_catch_type_index() {return _catch_type_index;}
+
+
+private:
+ uint32 _start_pc;
+ uint32 _end_pc;
+ uint32 _handler_pc;
+ uint32 _catch_type_index; // CP idx
+ String *_catch_type;
+
+}; //Handler
+
+
+
+// Representation of target handlers in the generated code.
+class Target_Exception_Handler {
+public:
+ Target_Exception_Handler(NativeCodePtr start_ip, NativeCodePtr end_ip, NativeCodePtr handler_ip, Class_Handle exn_class, bool exn_is_dead);
+
+ NativeCodePtr get_start_ip();
+ NativeCodePtr get_end_ip();
+ NativeCodePtr get_handler_ip();
+ Class_Handle get_exc();
+ bool is_exc_obj_dead();
+
+ bool is_in_range(NativeCodePtr eip, bool is_ip_past);
+ bool is_assignable(Class_Handle exn_class);
+
+ void update_catch_range(NativeCodePtr new_start_ip, NativeCodePtr new_end_ip);
+ void update_handler_address(NativeCodePtr new_handler_ip);
+
+private:
+ NativeCodePtr _start_ip;
+ NativeCodePtr _end_ip;
+ NativeCodePtr _handler_ip;
+ Class_Handle _exc;
+ bool _exc_obj_is_dead;
+}; //Target_Exception_Handler
+
+typedef class Target_Exception_Handler* Target_Exception_Handler_Ptr;
+
+#define MAX_VTABLE_PATCH_ENTRIES 10
+
+class VTable_Patches {
+public:
+ void *patch_table[MAX_VTABLE_PATCH_ENTRIES];
+ VTable_Patches *next;
+};
+
+// Used to notify interested JITs whenever a method is changed: overwritten, recompiled,
+// or initially compiled.
+struct Method_Change_Notification_Record {
+ Method *method_of_interest;
+ JIT *jit;
+ void *callback_data;
+ Method_Change_Notification_Record *next;
+
+ bool equals(Method *method_of_interest_, JIT *jit_, void *callback_data_) {
+ if ((method_of_interest == method_of_interest_) &&
+ (jit == jit_) &&
+ (callback_data == callback_data_)) {
+ return true;
+ }
+ return false;
+ }
+ // Optimized equals method. Most callbacks know method of interest, so we could skip one check.
+ inline bool equals(JIT *jit_, void *callback_data_) {
+ if ((callback_data == callback_data_) &&
+ (jit == jit_)) {
+ return true;
+ }
+ return false;
+ }
+};
+
+
+struct Inline_Record;
+
+
+// 20020222 This is only temporary to support the new JIT interface.
+// We will reimplement the signature support.
+struct Method_Signature {
+public:
+ TypeDesc* return_type_desc;
+ unsigned num_args;
+ TypeDesc** arg_type_descs;
+ Method *method;
+ String *sig;
+
+
+ void initialize_from_method(Method *method);
+ void reset();
+
+private:
+ void initialize_from_java_method(Method *method);
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Methods defined in a class.
+///////////////////////////////////////////////////////////////////////////////
+
+struct Line_Number_Entry {
+ uint16 start_pc;
+ uint16 line_number;
+};
+
+struct Line_Number_Table {
+ uint16 length;
+ Line_Number_Entry table[1];
+};
+
+struct Local_Var_Entry {
+ uint16 start_pc;
+ uint16 length;
+ uint16 index;
+ String* name;
+ String* type;
+ String* generic_type;
+};
+
+struct Local_Var_Table {
+ uint16 length;
+ Local_Var_Entry table[1];
+};
+
+
+// VMEXPORT // temporary solution for interpreter unplug
+struct VMEXPORT Method : public Class_Member {
+ //-----------------------
+public:
+ //
+ // state of this method
+ //
+ enum State {
+ ST_NotCompiled, // initial state
+ ST_NotLinked = ST_NotCompiled, // native not linked to implementation
+ ST_Compiled, // compiled by JIT
+ ST_Linked = ST_Compiled // native linked to implementation
+ };
+ State get_state() {return _state;}
+ void set_state(State st) {_state=st;}
+
+ // "Bytecode" exception handlers, i.e., those from the class file
+ unsigned num_bc_exception_handlers();
+ Handler *get_bc_exception_handler_info(unsigned eh_number);
+
+ // "Target" exception handlers, i.e., those in the code generated by the JIT.
+ void set_num_target_exception_handlers(JIT *jit, unsigned n);
+ unsigned get_num_target_exception_handlers(JIT *jit);
+
+ // Arguments:
+ // ...
+ // catch_clss -- class of the exception or null (for "catch-all")
+ // ...
+ void set_target_exception_handler_info(JIT *jit,
+ unsigned eh_number,
+ void *start_ip,
+ void *end_ip,
+ void *handler_ip,
+ Class *catch_clss,
+ bool exc_obj_is_dead = false);
+
+ Target_Exception_Handler_Ptr get_target_exception_handler_info(JIT *jit, unsigned eh_num);
+
+ unsigned num_exceptions_method_can_throw();
+ String *get_exception_name (int n);
+
+ // Address of the memory block containing bytecodes. For best performance
+ // the bytecodes should not be destroyed even after the method has been
+ // jitted to allow re-compilation. However the interface allows for such
+ // deallocation. The effect would be that re-optimizing JITs would not
+ // show their full potential, but that may be acceptable for low-end systems
+ // where memory is at a premium.
+ // The value returned by getByteCodeAddr may be NULL in which case the
+ // bytecodes are not available (presumably they have been garbage collected by VM).
+ const Byte *get_byte_code_addr() {return _byte_codes;}
+ size_t get_byte_code_size() {return _byte_code_length;}
+
+ // From the class file (Sec. 4.7.4)
+ unsigned get_max_stack() { return _max_stack; }
+ unsigned get_max_locals() { return _max_locals; }
+
+ // Returns an iterator for the argument list.
+ Arg_List_Iterator get_argument_list();
+
+ // Returns number of bytes of arguments pushed on the stack.
+ // This value depends on the descriptor and the calling convention.
+ unsigned get_num_arg_bytes();
+
+ // Returns number of arguments. For non-static methods, the this pointer
+ // is included in this number
+ unsigned get_num_args();
+
+ // Number of arguments which are references.
+ unsigned get_num_ref_args();
+
+
+ // Return the return type of this method.
+ Java_Type get_return_java_type();
+
+ // For non-primitive types (i.e., classes) get the class type information.
+ Class *get_return_class_type();
+
+ // Address of the memory location containing the address of the code.
+ // Used for static and special methods which have been resolved but not jitted.
+ // The call would be:
+ // call dword ptr [addr]
+ void *get_indirect_address() { return &_code; }
+
+ // Entry address of the method. Points to an appropriate stub or directly
+ // to the code if no stub is necessary.
+ void *get_code_addr() { return _code; }
+ void set_code_addr(void *code_addr) { _code = code_addr; }
+
+ void add_vtable_patch(void *);
+ void apply_vtable_patches();
+
+ /**
+ * This returns a block for jitted code. It is not used for native methods.
+ * It is safe to call this function from multiple threads.
+ */
+ void *allocate_code_block_mt(size_t size, size_t alignment, JIT *jit, unsigned heat,
+ int id, Code_Allocation_Action action);
+
+ void *allocate_rw_data_block(size_t size, size_t alignment, JIT *jit);
+
+ // The JIT can store some information in a JavaMethod object.
+ void *allocate_jit_info_block(size_t size, JIT *jit);
+
+ // JIT-specific data blocks.
+ // Access should be protected with _lock.
+ // FIXME
+ // Think about moving lock aquisition inside public methods.
+ void *allocate_JIT_data_block(size_t size, JIT *jit, size_t alignment);
+ CodeChunkInfo *get_first_JIT_specific_info() { return _jits; };
+ CodeChunkInfo *get_JIT_specific_info_no_create(JIT *jit);
+ /**
+ * Find a chunk info for specific JIT. If no chunk exist for this JIT,
+ * create and return one. This method is safe to call
+ * from multiple threads.
+ */
+ CodeChunkInfo *get_chunk_info_mt(JIT *jit, int id);
+
+ /**
+ * Find a chunk info for specific JIT, or NULL if
+ * no chunk info is created for this JIT. This method is safe to call
+ * from multiple threads.
+ */
+ CodeChunkInfo *get_chunk_info_no_create_mt(JIT *jit, int id);
+
+ /**
+ * Allocate a new chunk info. This method is safe to call
+ * from multiple threads.
+ */
+ CodeChunkInfo *create_code_chunk_info_mt();
+
+ // Notify JITs whenever this method is overridden by a newly loaded class.
+ void register_jit_overridden_method_callback(JIT *jit_to_be_notified, void *callback_data);
+ void do_jit_overridden_method_callbacks(Method *overriding_method);
+
+ // Notify JITs whenever this method is recompiled or initially compiled.
+ void register_jit_recompiled_method_callback(JIT *jit_to_be_notified, void *callback_data);
+ void do_jit_recompiled_method_callbacks();
+
+ Method_Side_Effects get_side_effects() { return _side_effects; };
+ void set_side_effects(Method_Side_Effects mse) { _side_effects = mse; };
+
+ Method_Signature *get_method_sig() { return _method_sig; };
+ void set_method_sig(Method_Signature *msig) { _method_sig = msig; };
+
+private:
+ State _state;
+ void *_code;
+ VTable_Patches *_vtable_patch;
+
+ NativeCodePtr _counting_stub;
+
+ CodeChunkInfo *_jits;
+
+ Method_Side_Effects _side_effects;
+ Method_Signature *_method_sig;
+
+public:
+ Method();
+ // destructor should be instead of this function, but it's not allowed to use it because copy for Method class is
+ // done with memcpy, and old value is destroyed with delete operator.
+ void MethodClearInternals();
+
+ //
+ // access modifiers
+ //
+ bool is_synchronized() {return (_access_flags&ACC_SYNCHRONIZED)?true:false;}
+ bool is_native() {return (_access_flags&ACC_NATIVE)?true:false;}
+ bool is_abstract() {return (_access_flags&ACC_ABSTRACT)?true:false;}
+ bool is_varargs() {return (_access_flags&ACC_VARARGS)?true:false;}
+ bool is_bridge() {return (_access_flags&ACC_BRIDGE)?true:false;}
+
+ // method flags
+ bool is_init() {return _flags.is_init?true:false;}
+ bool is_clinit() {return _flags.is_clinit?true:false;}
+ bool is_finalize() {return _flags.is_finalize?true:false;}
+ bool is_overridden() {return _flags.is_overridden?true:false;}
+ bool is_registered() {return _flags.is_registered?true:false;}
+ Boolean is_nop() {return _flags.is_nop;}
+
+ void set_registered( bool flag ) { _flags.is_registered = flag; }
+
+ unsigned get_index() {return _index;}
+
+ // Fake methods are interface methods inherited by an abstract class that are not (directly or indirectly)
+ // implemented by that class. They are added to the class to ensure they have thecorrect vtable offset.
+ // These fake methods point to the "real" interface method for which they are surrogates; this information
+ // is used by reflection methods.
+ bool is_fake_method() {return (_intf_method_for_fake_method != NULL);}
+ Method *get_real_intf_method() {return _intf_method_for_fake_method;}
+
+ bool parse(Global_Env& env, Class* clss,
+ Const_Pool* cp, unsigned cp_size, ByteReader& cfs);
+
+ unsigned calculate_size() {
+ unsigned size = sizeof(Class_Member) + sizeof(Method);
+ if(_local_vars_table)
+ size += sizeof(uint16) + _local_vars_table->length*sizeof(Local_Var_Entry);
+ if(_line_number_table)
+ size += sizeof(uint16) + _line_number_table->length*sizeof(Line_Number_Entry);
+ size += _n_exceptions*sizeof(String*);
+ size += _n_handlers*sizeof(Handler);
+ size += _byte_code_length;
+ return size;
+ }
+
+ friend void assign_offsets_to_class_methods(Class* clss);
+ friend void add_new_fake_method(Class* clss, Class* example, unsigned* next);
+ friend void add_any_fake_methods(Class* clss);
+
+ unsigned get_num_param_annotations() {return _num_param_annotations;}
+ AnnotationTable * get_param_annotations(unsigned index) {
+ return index < _num_param_annotations ? _param_annotations[index] : NULL;
+ }
+ AnnotationValue * get_default_value() {return _default_value; }
+
+private:
+ uint8 _num_param_annotations;
+ AnnotationTable ** _param_annotations;
+ AnnotationValue * _default_value;
+
+ unsigned _index; // index in method table
+ uint16 _max_stack;
+ uint16 _max_locals;
+ uint16 _n_exceptions; // num exceptions method can throw
+ uint16 _n_handlers; // num exception handlers in byte codes
+ String **_exceptions; // array of exceptions method can throw
+ uint32 _byte_code_length; // num bytes of byte code
+ Byte *_byte_codes; // method's byte codes
+ Handler *_handlers; // array of exception handlers in code
+ Method *_intf_method_for_fake_method;
+ struct {
+ unsigned is_init : 1;
+ unsigned is_clinit : 1;
+ unsigned is_finalize : 1; // is finalize() method
+ unsigned is_overridden : 1; // has this virtual method been overridden by a loaded subclass?
+ unsigned is_nop : 1;
+ unsigned is_registered : 1; // the method is registred native method
+ } _flags;
+
+ //
+ // private methods for parsing methods
+ //
+ bool _parse_code(Const_Pool *cp, unsigned cp_size, unsigned code_attr_len, ByteReader &cfs);
+
+ bool _parse_line_numbers(unsigned attr_len, ByteReader &cfs);
+
+ bool _parse_exceptions(Const_Pool *cp, unsigned cp_size, unsigned attr_len,
+ ByteReader &cfs);
+
+ void _set_nop();
+
+ //
+ // debugging info
+ //
+ Line_Number_Table *_line_number_table;
+ Local_Var_Table *_local_vars_table;
+
+ bool _parse_local_vars(const char* attr_name, Local_Var_Table** lvt_address,
+ Const_Pool *cp, unsigned cp_size, unsigned attr_len, ByteReader &cfs);
+
+ // This is the number of breakpoints which should be set in the
+ // method when it is compiled. This number does not reflect
+ // multiple breakpoints that are set in the same location by
+ // different environments, it counts only unique locations
+ uint32 pending_breakpoints;
+public:
+
+ unsigned get_line_number_table_size() {
+ return (_line_number_table) ? _line_number_table->length : 0;
+ }
+
+ bool get_line_number_entry(unsigned index, jlong* pc, jint* line);
+
+ unsigned get_local_var_table_size() {
+ return (_local_vars_table) ? _local_vars_table->length : 0;
+ }
+
+ bool get_local_var_entry(unsigned index, jlong* pc,
+ jint* length, jint* slot, String** name, String** type,
+ String** generic_type);
+
+ // XXX
+ //bool get_local_var_entry(unsigned index, jlong* pc,
+ // jint* length, jint* slot, String** name, String** type);
+
+
+ // Returns number of line in the source file, to which the given bytecode offset
+ // corresponds, or -1 if it is unknown.
+ int get_line_number(uint16 bc_offset);
+
+ Inline_Record *inline_records;
+ void set_inline_assumption(JIT *jit, Method *caller);
+ void method_was_overridden();
+
+ Method_Change_Notification_Record *_notify_override_records;
+
+ // Records JITs to be notified when a method is recompiled or initially compiled.
+ Method_Change_Notification_Record *_notify_recompiled_records;
+
+ void lock();
+ void unlock();
+
+ uint32 get_pending_breakpoints()
+ {
+ return pending_breakpoints;
+ }
+
+ void insert_pending_breakpoint()
+ {
+ pending_breakpoints++;
+ }
+
+ void remove_pending_breakpoint()
+ {
+ pending_breakpoints--;
+ }
+}; // Method
+
+#endif
diff --git a/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h b/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h
index f254cf5..1c0efac 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h
@@ -27,7 +27,7 @@ #define _JNI_DIRECT_H_
#include "jni.h"
#include "open/types.h"
-#include "Class.h"
+#include "class_member.h"
struct _jfieldID : public Field {
};
diff --git a/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h b/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
index b6855f0..aac640a 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
@@ -23,6 +23,7 @@ #define _JVMTI_DIRECT_H_
#include "jni_direct.h"
#include "jvmti.h"
+#include "vm_core_types.h"
struct TIEventThread
{
diff --git a/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h b/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h
index 8b9e174..1979b3c 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h
@@ -42,6 +42,12 @@ #include "object_layout.h"
#include "vm_core_types.h"
#include "jni.h"
+#ifndef NDEBUG
+// FIXME: this is for managed object sanity checks
+// (used in monitor enter/exit functions)
+#include "Class.h"
+#endif
+
/**
* GC frames store memory locations which contain managed pointers, so they are updated
* during garbage collection. Note, GC suspension must be disabled when created or deleting
diff --git a/enhanced/drlvm/trunk/vm/vmcore/include/vm_log.h b/enhanced/drlvm/trunk/vm/vmcore/include/vm_log.h
index b0b80e6..a119be5 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/include/vm_log.h
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/vm_log.h
@@ -21,8 +21,11 @@ #ifndef _VM_LOG_H_
#define _VM_LOG_H_
#include "loggerstring.h"
-#include "Class.h"
+#include "object_layout.h"
#include "object_handles.h"
+#include "vtable.h"
+#include "String_Pool.h"
+#include "class_member.h"
/**
* @file
diff --git a/enhanced/drlvm/trunk/vm/vmcore/include/vtable.h b/enhanced/drlvm/trunk/vm/vmcore/include/vtable.h
new file mode 100644
index 0000000..c38d7d6
--- /dev/null
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/vtable.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __VTABLE_H__
+#define __VTABLE_H__
+
+/**
+ * @file
+ * virtual method table of a class
+ */
+extern "C" {
+
+typedef struct {
+ unsigned char** table; // pointer into methods array of Intfc_Table below
+ unsigned intfc_id; // id of interface
+} Intfc_Table_Entry;
+
+typedef struct Intfc_Table {
+#ifdef POINTER64
+ // see INTFC_TABLE_OVERHEAD
+ uint32 dummy; // padding
+#endif
+ uint32 n_entries;
+ Intfc_Table_Entry entry[1];
+} Intfc_Table;
+
+#define INTFC_TABLE_OVERHEAD (sizeof(void*))
+
+#ifdef POINTER64
+#define OBJECT_HEADER_SIZE 0
+// The size of an object reference. Used by arrays of object to determine
+// the size of an element.
+#define OBJECT_REF_SIZE 8
+#else // POINTER64
+#define OBJECT_HEADER_SIZE 0
+#define OBJECT_REF_SIZE 4
+#endif // POINTER64
+
+#define GC_BYTES_IN_VTABLE (sizeof(void*))
+#define MAX_FAST_INSTOF_DEPTH 5
+
+typedef struct VTable {
+ Byte _gc_private_information[GC_BYTES_IN_VTABLE];
+ Class* clss;
+
+ // See the masks in vm_for_gc.h.
+ uint32 class_properties;
+
+ // Offset from the top by CLASS_ALLOCATED_SIZE_OFFSET
+ // The number of bytes allocated for this object. It is the same as
+ // instance_data_size with the constraint bit cleared. This includes
+ // the OBJECT_HEADER_SIZE as well as the OBJECT_VTABLE_POINTER_SIZE
+ unsigned int allocated_size;
+
+ unsigned short array_element_size;
+ unsigned short array_element_shift;
+ Intfc_Table* intfc_table; // interface table; NULL if no intfc table
+ Class *superclasses[MAX_FAST_INSTOF_DEPTH];
+ unsigned char* methods[1]; // code for method
+} VTable;
+#define VTABLE_OVERHEAD (sizeof(VTable) - sizeof(void *))
+// The "- sizeof(void *)" part subtracts out the "unsigned char *methods[1]" contribution.
+
+VTable *create_vtable(Class *p_class, unsigned n_vtable_entries);
+
+} // extern "C"
+
+
+#endif
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp
index 6f95054..6b45512 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp
@@ -31,6 +31,7 @@ #include "properties.h"
#include "open/hythread_ext.h"
#include "thread_manager.h"
+#include "cci.h"
#include "Verifier_stub.h"
#include "class_interface.h"
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp
index 0a19b18..4f6b51d 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp
@@ -194,6 +194,14 @@ void* Field::get_address()
} // Field::get_address
+unsigned Field::calculate_size() {
+ static unsigned size = sizeof(Field) + sizeof(TypeDesc);
+ return size;
+}
+
+
+
+
Method::Method()
{
//
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp
index c27f2ac..03f3988 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp
@@ -30,6 +30,7 @@ #include "nogc.h"
#include "open/vm_util.h"
#include "jit_intf_cpp.h"
#include "atomics.h"
+#include "cci.h"
#ifdef _IPF_
#include "vm_ipf.h"
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method_lookup.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method_lookup.cpp
index 80eb205..d45fcfb 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method_lookup.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method_lookup.cpp
@@ -28,6 +28,8 @@ #include
#include "lock_manager.h"
#include "nogc.h"
#include "vm_stats.h"
+#include "cci.h"
+#include "class_member.h"
#include "method_lookup.h"
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp
index cd43454..400dee2 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp
@@ -33,6 +33,7 @@ #include "m2n.h"
#include "object_handles.h"
#include "vm_arrays.h"
#include "vm_strings.h"
+#include "cci.h"
bool exn_raised()
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
index 15344ca..680fe68 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
@@ -41,6 +41,7 @@ #include "mon_enter_exit.h"
#include "stack_iterator.h"
#include "vm_stats.h"
#include "jvmti_break_intf.h"
+#include "cci.h"
#ifdef _IPF_
#elif defined _EM64T_
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp
index 47f936b..70c9838 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp
@@ -18,8 +18,6 @@
* @version $Revision: 1.1.2.2.4.3 $
*/
-
-
#define LOG_DOMAIN "vm.core"
#include "cxxlog.h"
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/gc/root_set_enum_common.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/gc/root_set_enum_common.cpp
index f913249..b809b1e 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/gc/root_set_enum_common.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/gc/root_set_enum_common.cpp
@@ -29,6 +29,7 @@ #include "vm_stats.h"
#include "m2n.h"
#include "open/vm_util.h"
#include "finalize.h"
+#include "cci.h"
static void
vm_enumerate_interned_strings()
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp
index e68cfae..2368ad3 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp
@@ -37,6 +37,7 @@ #include "lil_code_generator.h"
#include "stack_iterator.h"
#include "interpreter.h"
#include "jvmti_break_intf.h"
+#include "cci.h"
#include "vm_stats.h"
#include "dump.h"
@@ -74,7 +75,6 @@ CodeChunkInfo::CodeChunkInfo()
_relocatable = TRUE;
_num_target_exception_handlers = 0;
_target_exception_handlers = NULL;
- _has_been_loaded_for_vtune = false;
_callee_info = _static_callee_info;
_max_callees = NUM_STATIC_CALLEE_ENTRIES;
_num_callees = 0;
@@ -85,7 +85,6 @@ CodeChunkInfo::CodeChunkInfo()
_jit_info_block_size = 0;
_code_block_alignment = 0;
_data_blocks = NULL;
- _dynopt_info = NULL;
_next = NULL;
#ifdef VM_STATS
num_throws = 0;
@@ -95,35 +94,37 @@ #ifdef VM_STATS
#endif
} //CodeChunkInfo::CodeChunkInfo
-
-void CodeChunkInfo::initialize_code_chunk(CodeChunkInfo *chunk)
+int CodeChunkInfo::get_jit_index() const
{
- memset(chunk, 0, sizeof(CodeChunkInfo));
- chunk->_callee_info = chunk->_static_callee_info;
- chunk->_max_callees = NUM_STATIC_CALLEE_ENTRIES;
- chunk->_relocatable = TRUE;
-} //CodeChunkInfo::initialize_code_chunk
-
-
+ return get_index_of_jit(_jit);
+}
-unsigned CodeChunkInfo::get_num_target_exception_handlers()
+unsigned CodeChunkInfo::get_num_target_exception_handlers() const
{
if (_id==0) {
return _num_target_exception_handlers;
} else {
return _method->get_num_target_exception_handlers(_jit);
}
-} //get_num_target_exception_handlers
-
+}
-Target_Exception_Handler_Ptr CodeChunkInfo::get_target_exception_handler_info(unsigned eh_num)
+Target_Exception_Handler_Ptr CodeChunkInfo::get_target_exception_handler_info(unsigned eh_num) const
{
if (_id==0) {
return _target_exception_handlers[eh_num];
} else {
return _method->get_target_exception_handler_info(_jit, eh_num);
}
-} //get_target_exception_handler_info
+}
+
+
+//void CodeChunkInfo::initialize_code_chunk(CodeChunkInfo *chunk)
+//{
+// memset(chunk, 0, sizeof(CodeChunkInfo));
+// chunk->_callee_info = chunk->_static_callee_info;
+// chunk->_max_callees = NUM_STATIC_CALLEE_ENTRIES;
+// chunk->_relocatable = TRUE;
+//} //CodeChunkInfo::initialize_code_chunk
// 20040224 Support for recording which methods (actually, CodeChunkInfo's) call which other methods.
@@ -178,10 +179,10 @@ void CodeChunkInfo::record_call_to_calle
} //CodeChunkInfo::record_call_to_callee
-uint64 CodeChunkInfo::num_calls_to(CodeChunkInfo *other_chunk)
+uint64 CodeChunkInfo::num_calls_to(CodeChunkInfo *other_chunk) const
{
assert(other_chunk);
- for (unsigned i = 0; i < _num_callees; i++) {
+ for (unsigned i = 0; i < _num_callees; i++) {
Callee_Info *info = &(_callee_info[i]);
CodeChunkInfo *callee = info->callee;
assert(callee);
@@ -194,7 +195,7 @@ uint64 CodeChunkInfo::num_calls_to(CodeC
} //CodeChunkInfo::num_calls_to
-void CodeChunkInfo::print_name()
+void CodeChunkInfo::print_name() const
{
Method *meth = get_method();
assert(meth);
@@ -205,7 +206,7 @@ void CodeChunkInfo::print_name()
} //CodeChunkInfo::print_name
-void CodeChunkInfo::print_name(FILE *file)
+void CodeChunkInfo::print_name(FILE *file) const
{
Method *meth = get_method();
assert(meth);
@@ -216,7 +217,7 @@ void CodeChunkInfo::print_name(FILE *fil
} //CodeChunkInfo::print_name
-void CodeChunkInfo::print_info(bool print_ellipses)
+void CodeChunkInfo::print_info(bool print_ellipses) const
{
size_t code_size = get_code_block_size();
print_name();
@@ -224,12 +225,12 @@ void CodeChunkInfo::print_info(bool prin
} //CodeChunkInfo::print_info
-void CodeChunkInfo::print_callee_info()
+void CodeChunkInfo::print_callee_info() const
{
- for (unsigned i = 0; i < _num_callees; i++) {
+ for (unsigned i = 0; i < _num_callees; i++) {
Callee_Info *info = &(_callee_info[i]);
- // Don't print the "back edges" (e.g., b calls a whenever a calls b) added to make the graph symmetric
- if (info->caller_ip != NULL) {
+ // Don't print the "back edges" (e.g., b calls a whenever a calls b) added to make the graph symmetric
+ if (info->caller_ip != NULL) {
CodeChunkInfo *callee = info->callee;
assert(callee);
unsigned call_offset = (unsigned)((char *)info->caller_ip - (char *)_code_block);
@@ -237,11 +238,10 @@ void CodeChunkInfo::print_callee_info()
printf("%10" FMT64 "u calls at %u to ", info->num_calls, call_offset);
callee->print_name();
printf("\n");
- }
+ }
}
} //CodeChunkInfo::print_callee_info
-
// end CodeChunkInfo
////////////////////////////////////////////////////////////////////////
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp
index d8d47f4..953d64a 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp
@@ -27,6 +27,7 @@ #include "jvmti_internal.h"
#include "environment.h"
#include "Class.h"
#include "cxxlog.h"
+#include "cci.h"
#include "suspend_checker.h"
#include "interpreter_exports.h"
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
index 3cb412e..eb39c67 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
@@ -35,6 +35,7 @@ #include "open/jthread.h"
#include "suspend_checker.h"
#include "jit_intf_cpp.h"
#include "vm_log.h"
+#include "cci.h"
#include "compile.h"
#include "jvmti_break_intf.h"
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_locals.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_locals.cpp
index 306b76a..bfd5cdb 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_locals.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_locals.cpp
@@ -35,6 +35,8 @@ #include "suspend_checker.h"
#include "stack_iterator.h"
#include "stack_trace.h"
#include "jit_intf_cpp.h"
+#include "cci.h"
+#include "Class.h"
/*
* Local Variable functions:
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp
index 0dc470a..abac203 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp
@@ -31,6 +31,7 @@ #include "m2n.h"
#include "mon_enter_exit.h"
#include "stack_iterator.h"
#include "jvmti_break_intf.h"
+#include "cci.h"
#include "clog.h"
static void jvmti_pop_frame_callback()
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp
index 558992b..42b1823 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp
@@ -35,6 +35,7 @@ #include "stack_trace.h"
#include "stack_iterator.h"
#include "jit_intf_cpp.h"
#include "thread_manager.h"
+#include "cci.h"
static JNIEnv * jvmti_test_jenv = jni_native_intf;
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp
index 9dbc470..595426a 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp
@@ -27,6 +27,7 @@ #include "jit_intf_cpp.h"
#include "stack_iterator.h"
#include "interpreter.h"
#include "method_lookup.h"
+#include "cci.h"
#include "open/bytecodes.h"
#include "open/jthread.h"
#include "jvmti_break_intf.h"
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp
index c29ee24..d7e40a8 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp
@@ -41,6 +41,8 @@ #include "suspend_checker.h"
#include "stack_iterator.h"
+#include "Class.h" // FIXME: this is for Class::heap_base and Class::heap_end
+
#define MAX_JVMTI_ENV_NUMBER 10
static JNIEnv * jvmti_test_jenv = jni_native_intf;
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp
index 01052ce..0b9dbfd 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread_group.cpp
@@ -28,6 +28,7 @@ #include "open/vm_util.h"
#include "cxxlog.h"
#include "suspend_checker.h"
#include "environment.h"
+#include "Class.h"
static JNIEnv_Internal * jvmti_test_jenv = jni_native_intf;
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_lang_reflect_VMReflection.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_lang_reflect_VMReflection.cpp
index a7dc5a3..0d602db 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_lang_reflect_VMReflection.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_lang_reflect_VMReflection.cpp
@@ -35,6 +35,7 @@ #include "exceptions.h"
#include "vm_strings.h"
#include "primitives_support.h"
#include "jni_utils.h"
+#include "Class.h"
#include "java_lang_VMClassRegistry.h"
#include "java_lang_reflect_VMReflection.h"
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp
index 29debdc..f8dd60c 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp
@@ -36,6 +36,7 @@ #include "vm_threads.h"
#include "thread_manager.h"
#include "open/types.h"
#include "open/vm_util.h"
+#include "vtable.h"
static ObjectHandlesOld* oh_allocate_object_handle();
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
index e0eb5cf..88bbc52 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
@@ -24,7 +24,9 @@ #include "vm_threads.h"
#include "port_malloc.h"
#include "jit_intf_cpp.h"
#include "Class.h"
+#include "class_member.h"
#include "stack_trace.h"
+#include "cci.h"
#ifdef PLATFORM_NT
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_trace.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_trace.cpp
index d883533..ca3a00b 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_trace.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_trace.cpp
@@ -26,6 +26,8 @@ #include "interpreter.h"
#include "jit_intf_cpp.h"
#include "method_lookup.h"
+#include "cci.h"
+#include "class_member.h"
void get_file_and_line(Method_Handle mh, void *ip, bool is_ip_past, const char **file, int *line) {
Method *method = (Method*)mh;
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_dump.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_dump.cpp
index 5fda9e2..af72e03 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_dump.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_dump.cpp
@@ -29,9 +29,12 @@ #include "jit_intf_cpp.h"
#include "dll_jit_intf.h"
#include "object_generic.h"
+#include "Class.h"
+#include "vtable.h"
#include "root_set_enum_internal.h"
#include "lock_manager.h"
#include "open/gc.h"
+#include "cci.h"
#define LOG_DOMAIN "thread_dump"
#include "cxxlog.h"