You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by wj...@apache.org on 2006/11/09 05:58:58 UTC

svn commit: r472773 - in /incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include: annotation.h cci.h class_member.h vtable.h

Author: wjwashburn
Date: Wed Nov  8 20:58:58 2006
New Revision: 472773

URL: http://svn.apache.org/viewvc?view=rev&rev=472773
Log:
HARMONY-1558, Class.h cleanup
tested on windowsxp and Linux w/ gcc 4.0.2  (forgot to "svn add" these files)

Added:
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/annotation.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/cci.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vtable.h

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/annotation.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/annotation.h?view=auto&rev=472773
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/annotation.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/annotation.h Wed Nov  8 20:58:58 2006
@@ -0,0 +1,93 @@
+/*
+ *  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__
+
+struct String;
+
+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
+

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/cci.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/cci.h?view=auto&rev=472773
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/cci.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/cci.h Wed Nov  8 20:58:58 2006
@@ -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

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h?view=auto&rev=472773
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h Wed Nov  8 20:58:58 2006
@@ -0,0 +1,761 @@
+/*
+ *  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 "annotation.h"
+#include "Class.h"
+#include "jit_intf.h"
+
+struct String;
+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.
+///////////////////////////////////////////////////////////////////////////////
+class 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_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, not used, always zero
+    //   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, 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(unsigned off) { _offset = off; _offset_computed = 1; }
+
+    // For static fields
+    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, 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(ConstantPool& cp, 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;
+    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];
+};
+
+
+struct Method : public Class_Member {
+    friend void add_new_fake_method(Class* clss, Class* example, unsigned* next);
+    friend void add_any_fake_methods(Class* clss);
+    //-----------------------
+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() const { return _n_handlers; }
+    Handler* get_bc_exception_handler_info(unsigned eh_number) {
+        assert(eh_number < _n_handlers);
+        return _handlers + 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() {
+        return initialize_arg_list_iterator(_descriptor->bytes);
+    }
+
+    // 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() const { return _arguments_size; }
+
+    // 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() {
+        const char *descr = get_descriptor()->bytes;
+        while(*descr != ')') descr++;
+        return (Java_Type)*(descr + 1);
+    }
+
+    // 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 <code>NULL</code> 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; }
+
+    /// Sets index in vtable and offset from the base of vtable for this method
+    /// @param index - index in vtable
+    /// @param offset - for instance methods: offset from the base of vtable
+    void set_position_in_vtable(unsigned index, unsigned offset) {
+        assert(!is_static());
+        _index = index;
+        _offset = offset;
+    }
+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, ByteReader& cfs);
+
+    void calculate_arguments_size();
+
+    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;
+    }
+
+    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
+    unsigned _arguments_size;   // size of method arguments on the stack
+    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(ConstantPool& cp, unsigned code_attr_len, ByteReader &cfs);
+
+    bool _parse_line_numbers(unsigned attr_len, ByteReader &cfs);
+
+    bool _parse_exceptions(ConstantPool& cp, 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,
+        ConstantPool& cp, 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) {
+        if(!_line_number_table) return -1;
+        Line_Number_Table* lnt = _line_number_table;
+        for(int i = 0; i < lnt->length - 1; i++) {
+            if(bc >= lnt->table[i].start_pc && bc < lnt->table[i+1].start_pc)
+                return lnt->table[i].line_number;
+        }
+        if(bc >= lnt->table[lnt->length-1].start_pc && bc < _byte_code_length)
+            return lnt->table[lnt->length-1].line_number;
+        return -1;
+    }
+
+    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

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vtable.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vtable.h?view=auto&rev=472773
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vtable.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vtable.h Wed Nov  8 20:58:58 2006
@@ -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 methods
+} 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