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