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"