diff --git a/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp b/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp
index a2cc579..4583bb4 100644
--- a/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp
+++ b/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp
@@ -947,42 +947,42 @@ Opcode_LCMP(StackFrame& frame) {
static bool
ldc(StackFrame& frame, uint32 index) {
- Class *clazz = frame.method->get_class();
- Const_Pool *cp = clazz->const_pool;
+ Class* clazz = frame.method->get_class();
+ ConstantPool& cp = clazz->m_const_pool;
#ifndef NDEBUG
- switch(cp_tag(cp, index)) {
+ switch(cp.get_tag(index)) {
case CONSTANT_String:
- DEBUG_BYTECODE("#" << dec << (int)index << " String: \"" << cp[index].CONSTANT_String.string->bytes << "\"");
+ DEBUG_BYTECODE("#" << dec << (int)index << " String: \"" << cp.get_string_chars(index) << "\"");
break;
case CONSTANT_Integer:
- DEBUG_BYTECODE("#" << dec << (int)index << " Integer: " << (int)cp[index].int_value);
+ DEBUG_BYTECODE("#" << dec << (int)index << " Integer: " << (int)cp.get_int(index));
break;
case CONSTANT_Float:
- DEBUG_BYTECODE("#" << dec << (int)index << " Float: " << cp[index].float_value);
+ DEBUG_BYTECODE("#" << dec << (int)index << " Float: " << cp.get_float(index));
break;
case CONSTANT_Class:
DEBUG_BYTECODE("#" << dec << (int)index << " Class: \"" << const_pool_get_class_name(clazz, index) << "\"");
break;
default:
- DEBUG_BYTECODE("#" << dec << (int)index << " Unknown type = " << cp_tag(cp, index));
- DIE("ldc instruction: unexpected type (" << cp_tag(cp, index)
+ DEBUG_BYTECODE("#" << dec << (int)index << " Unknown type = " << cp.get_tag(index));
+ DIE("ldc instruction: unexpected type (" << cp.get_tag(index)
<< ") of constant pool entry [" << index << "]");
break;
}
#endif
frame.stack.push();
- if (cp_is_string(cp, index)) {
- // FIXME: is string reference is packed??
+ if(cp.is_string(index)) {
+ // FIXME: is string reference packed??
// possibly not
- String* str = (String*) cp[index].CONSTANT_String.string;
+ String* str = cp.get_string(index);
// FIXME: only compressed references
frame.stack.pick().cr = COMPRESS_REF(vm_instantiate_cp_string_resolved(str));
frame.stack.ref() = FLAG_OBJECT;
return !check_current_thread_exception();
}
- else if (cp_is_class(cp, index))
+ else if (cp.is_class(index))
{
Class *other_class = interp_resolve_class(clazz, index);
if (!other_class) {
@@ -996,7 +996,7 @@ #endif
return !exn_raised();
}
- frame.stack.pick().u = cp[index].int_value;
+ frame.stack.pick().u = cp.get_4byte(index);
return true;
}
@@ -1020,10 +1020,11 @@ Opcode_LDC2_W(StackFrame& frame) {
uint32 index = read_uint16(frame.ip + 1);
Class *clazz = frame.method->get_class();
- Const_Pool *cp = clazz->const_pool;
+ ConstantPool& cp = clazz->m_const_pool;
frame.stack.push(2);
Value2 val;
- val.u64 = ((uint64)cp[index].CONSTANT_8byte.high_bytes << 32) | cp[index].CONSTANT_8byte.low_bytes;
+ val.u64 = ((uint64)cp.get_8byte_high_word(index) << 32)
+ | cp.get_8byte_low_word(index);
frame.stack.setLong(0, val);
DEBUG_BYTECODE("#" << dec << (int)index << " (val = " << hex << val.d << ")");
frame.ip += 3;
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 ebb2b24..746d3f6 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
@@ -31,6 +31,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 6ef575b..92b39d6 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
@@ -24,6 +24,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 b4c7a80..65fa2cd 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
@@ -32,6 +32,7 @@ #include "open/vm_gc.h"
#include "open/gc.h"
#include "String_Pool.h"
#include "type.h"
+#include "vtable.h"
//
// forward declarations
@@ -40,46 +41,23 @@ 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
///////////////////////////////////////////////////////////////////////////////
-#define RAW_REFERENCE ManagedObject *
+#define RAW_REFERENCE ManagedObject*
#define COMPRESSED_REFERENCE uint32
VMEXPORT bool is_compressed_reference(COMPRESSED_REFERENCE value);
@@ -119,34 +97,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
@@ -167,28 +117,29 @@ #define CLASSFILE_MINOR 3
// Constant pool entries.
///////////////////////////////////////////////////////////////////////////////
-union Const_Pool {
- unsigned char *tags; // entry 0 of const pool only
+union ConstPoolEntry {
+ unsigned char* tags; // entry 0 of const pool only
struct { // CONSTANT_Class
union {
Class* klass; // resolved class
struct { // resolution error
- Const_Pool* next; // next resolution error in this constant pool
+ ConstPoolEntry* next; // next resolution error in this constant pool
ManagedObject* cause;
} error;
};
uint16 name_index;
} CONSTANT_Class;
struct { // CONSTANT_String
- String *string; // resolved entry
+ String* string; // resolved entry
uint16 string_index;
} CONSTANT_String;
struct { // CONSTANT_{Field,Method,InterfaceMethod}ref
union {
+ Class_Member* member; // generic class member for CONSTANT_*ref
Field* field; // resolved entry for CONSTANT_Fieldref
- Method* method; // resolved entry for CONSTANT_{Interface}Methodref
+ Method* method; // resolved entry for CONSTANT_[Interface]Methodref
struct { // resolution error
- Const_Pool* next; // next resolution error in this constant pool
+ ConstPoolEntry* next; // next resolution error in this constant pool
ManagedObject* cause;
} error;
};
@@ -197,7 +148,7 @@ union Const_Pool {
} CONSTANT_ref;
struct { // shortcut to resolution error in CONSTANT_Class and CONSTANT_ref
- Const_Pool* next; // next resolution error in this constant pool
+ ConstPoolEntry* next; // next resolution error in this constant pool
ManagedObject* cause;
} error;
@@ -210,94 +161,17 @@ union Const_Pool {
// Const_Pool element of the long/double unused)
} CONSTANT_8byte;
struct { // CONSTANT_NameAndType
- String *name; // resolved entry
- String *descriptor; // resolved entry
+ String* name; // resolved entry
+ String* descriptor; // resolved entry
uint16 name_index;
uint16 descriptor_index;
} CONSTANT_NameAndType;
struct {
- String *string; // CONSTANT_Utf8
+ String* string; // CONSTANT_Utf8
uint16 dummy;
} 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
@@ -318,112 +192,439 @@ enum Const_Pool_Tags {
CONSTANT_NameAndType = 12,
};
+
#define TAG_MASK 0x0F // 4 bits is sufficient for tag
#define RESOLVED_MASK 0x80 // msb is resolved flag
#define ERROR_MASK 0x40 // this entry contains resolution error information
-#define cp_tag(cp,i) (cp[0].tags[i] & TAG_MASK)
-#define cp_is_resolved(cp,i) (cp[0].tags[i] & RESOLVED_MASK)
-#define cp_set_resolved(cp,i) (cp[0].tags[i] |= RESOLVED_MASK)
-
-#define cp_in_error(cp, i) (cp[0].tags[i] & ERROR_MASK)
-#define cp_set_error(cp, i) (cp[0].tags[i] |= ERROR_MASK)
-
-#define cp_is_utf8(cp,i) (cp_tag(cp,i) == CONSTANT_Utf8)
-#define cp_is_class(cp,i) (cp_tag(cp,i) == CONSTANT_Class)
-#define cp_is_constant(cp,i) ((cp_tag(cp,i) >= CONSTANT_Integer \
- && cp_tag(cp,i) <= CONSTANT_Double) \
- || cp_tag(cp,i) == CONSTANT_String)
-
-#define cp_is_string(cp,i) (cp_tag(cp,i) == CONSTANT_String)
-#define cp_is_fieldref(cp,i) (cp_tag(cp,i) == CONSTANT_Fieldref)
-#define cp_is_methodref(cp,i) (cp_tag(cp,i) == CONSTANT_Methodref)
-#define cp_is_interfacemethodref(cp,i) (cp_tag(cp,i) == CONSTANT_InterfaceMethodref)
-
-#define cp_resolve_to_class(cp,i,c) cp_set_resolved(cp,i); cp[i].CONSTANT_Class.klass=c;
-
-#define cp_resolve_to_field(cp,i,f) cp_set_resolved(cp,i); cp[i].CONSTANT_ref.field=f;
-
-#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;
+struct ConstantPool {
+private:
+ // constant pool size
+ uint16 m_size;
+ // constant pool entries; 0-th entry contains array of constant pool tags
+ // for all entries
+ ConstPoolEntry* m_entries;
+ // List of constant pool entries, which resolution had failed
+ // Required for fast enumeration of error objects
+ ConstPoolEntry* m_failedResolution;
- // 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;
+public:
+ ConstantPool() : m_size(0), m_entries(NULL) {}
+ ~ConstantPool() {
+ clear();
+ }
- 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;
+ /// Checks that constant pool is not empty
+ /// @return true if constant pool contain some entries, false otherwise
+ bool available() const { return m_size != 0; }
+ /// Returns size of this constant pool
+ /// @return size of constant pool
+ uint16 get_size() const { return m_size; }
+
+ /// Checks that index is a valid index into this constant pool
+ /// @param index - index into constant pool
+ /// @return true if index is a valid index into constant pool, false
+ /// otherwise
+ bool is_valid_index(uint16 index) const {
+ return /*index > 0 && */index < m_size;
+ }
+ /// Checks that constant pool entry is resolved
+ /// @param index - index into constant pool
+ /// @return true if entry is already resolved, false otherwise
+ bool is_entry_resolved(uint16 index) const {
+ assert(is_valid_index(index));
+ return (m_entries[0].tags[index] & RESOLVED_MASK) != 0;
+ }
+ /// Checks that the resolution of constant pool entry had failed
+ /// @param index - index into constant pool
+ /// @return true if resolution error is recorded for the entry
+ bool is_entry_in_error(uint16 index) const {
+ assert(is_valid_index(index));
+ return (m_entries[0].tags[index] & ERROR_MASK) != 0;
+ }
+ /// Checks that the constant pool entry represents utf8 string
+ /// @param index - index into constant pool
+ /// @return true if this entry is utf8 string, false otherwise
+ bool is_utf8(uint16 index) const {
+ return get_tag(index) == CONSTANT_Utf8;
+ }
+ /// Checks that the constant pool entry refers to a class
+ /// @param index - index into constant pool
+ /// @return true if this entry is a class, false otherwise
+ bool is_class(uint16 index) const {
+ return get_tag(index) == CONSTANT_Class;
+ }
+ /// Checks that the constant pool entry contains constant
+ /// @param index - index into constant pool
+ /// @return true if this entry contains constant, false otherwise
+ bool is_constant(uint16 index) const {
+ return get_tag(index) == CONSTANT_Integer
+ || get_tag(index) == CONSTANT_Float
+ || get_tag(index) == CONSTANT_Long
+ || get_tag(index) == CONSTANT_Double
+ || get_tag(index) == CONSTANT_String
+ || get_tag(index) == CONSTANT_Class;
+ }
+ /// Checks that the constant pool entry is literal constant
+ /// @param index - index into constant pool
+ /// @return true if this entry contains string, false otherwise
+ bool is_string(uint16 index) const {
+ return get_tag(index) == CONSTANT_String;
+ }
+ bool is_name_and_type(uint16 index) const {
+ return get_tag(index) == CONSTANT_NameAndType;
+ }
+ /// Checks that the constant pool entry contains reference to a field
+ /// @param index - index into constant pool
+ /// @return true if this entry contains reference to field, false otherwise
+ bool is_fieldref(uint16 index) const {
+ return get_tag(index) == CONSTANT_Fieldref;
+ }
+ /// Checks that the constant pool entry contains reference to a method
+ /// @param index - index into constant pool
+ /// @return true if this entry contains reference to method, false otherwise
+ bool is_methodref(uint16 index) const {
+ return get_tag(index) == CONSTANT_Methodref;
+ }
+ /// Checks that the constant pool entry constains reference to an
+ /// interface method
+ /// @param index - index into constant pool
+ /// @return true if this entry contains reference to interface method,
+ /// false otherwise
+ bool is_interfacemethodref(uint16 index) const {
+ return get_tag(index) == CONSTANT_InterfaceMethodref;
+ }
+ /// Returns tag of referenced constant pool entry
+ /// @param index - index into constant pool
+ /// @return constant pool entry tag for a given index
+ unsigned char get_tag(uint16 index) const {
+ assert(is_valid_index(index));
+ return m_entries[0].tags[index] & TAG_MASK;
+ }
+ /// Returns characters from utf8 string stored in constant pool
+ /// @param index - index into constant pool
+ /// @return characters from utf8 string stored in constant pool
+ const char* get_utf8_chars(uint16 index) const {
+ return get_utf8_string(index)->bytes;
+ }
+ /// Returns utf8 string stored in constant pool
+ /// @param index - index into constant pool
+ /// @return utf8 string
+ String* get_utf8_string(uint16 index) const {
+ assert(is_utf8(index));
+ return m_entries[index].CONSTANT_Utf8.string;
+ }
+ /// Returns characters stored in utf8 string for CONSTANT_String entry
+ /// @param index - index into constant pool
+ /// @return utf8 string characters for this constant pool entry
+ const char* get_string_chars(uint16 index) const {
+ return get_string(index)->bytes;
+ }
+ /// Returns utf8 string stored for CONSTANT_String entry
+ /// @param index - index into constant pool
+ /// @return utf8 string stored in constant pool entry
+ String* get_string(uint16 index) const {
+ assert(is_string(index));
+ return m_entries[index].CONSTANT_String.string;
+ }
+ /// Returns utf8 string representing name part of name and type
+ /// constant pool entry
+ /// @param index - index into constant pool
+ /// @return utf8 string with name part
+ String* get_name_and_type_name(uint16 index) const {
+ assert(is_name_and_type(index));
+ assert(is_entry_resolved(index));
+ return m_entries[index].CONSTANT_NameAndType.name;
+ }
+ /// Returns utf8 string representing descriptor part of name and type
+ /// constant pool entry
+ /// @param index - index into constant pool
+ /// @return utf8 string with descriptor part
+ String* get_name_and_type_descriptor(uint16 index) const {
+ assert(is_name_and_type(index));
+ assert(is_entry_resolved(index));
+ return m_entries[index].CONSTANT_NameAndType.descriptor;
+ }
+ /// Returns generic class member for CONSTANT_*ref constant pool entry
+ /// @param index - index into constant pool
+ /// @return generic class member for this constant pool entry
+ Class_Member* get_ref_class_member(uint16 index) const {
+ assert(is_fieldref(index)
+ || is_methodref(index)
+ || is_interfacemethodref(index));
+ return m_entries[index].CONSTANT_ref.member;
+ }
+ /// Returns method from CONSTANT_Methodref or CONSTANT_InterfaceMethodref
+ /// constant pool entry
+ /// @param index - index into constant pool
+ /// @return method from this constant pool entry
+ Method* get_ref_method(uint16 index) const {
+ assert(is_methodref(index)
+ || is_interfacemethodref(index));
+ assert(is_entry_resolved(index));
+ return m_entries[index].CONSTANT_ref.method;
+ }
+ /// Returns field from CONSTANT_Fieldref constant pool entry
+ /// @param index - index into constant pool
+ /// @return field from this constant pool entry
+ Field* get_ref_field(uint16 index) const {
+ assert(is_fieldref(index));
+ assert(is_entry_resolved(index));
+ return m_entries[index].CONSTANT_ref.field;
+ }
+ /// Returns class for CONSTANT_Class constant pool entry
+ /// @param index - index into constant pool
+ /// @return class for this constant pool entry
+ Class* get_class_class(uint16 index) const {
+ assert(is_class(index));
+ assert(is_entry_resolved(index));
+ return m_entries[index].CONSTANT_Class.klass;
+ }
+ /// Returns integer value for constant stored in constant pool
+ /// @param index - index into constant pool
+ /// @return value of integer constant stored in constant pool
+ uint32 get_int(uint16 index) const {
+ assert(get_tag(index) == CONSTANT_Integer);
+ return m_entries[index].int_value;
+ }
+ /// Returns 32-bit value (either interger or float)
+ /// for constant stored in constant pool
+ /// @param index - index into constant pool
+ /// @return value of 32-bit constant stored in constant pool
+ uint32 get_4byte(uint16 index) const {
+ assert(get_tag(index) == CONSTANT_Integer
+ || get_tag(index) == CONSTANT_Float);
+ return m_entries[index].int_value;
+ }
+ /// Returns float value for constant stored in constant pool
+ /// @param index - index into constant pool
+ /// @return value of float constant stored in constant pool
+ float get_float(uint16 index) const {
+ assert(get_tag(index) == CONSTANT_Float);
+ return m_entries[index].float_value;
+ }
+ /// Returns low word of 64-bit constant (long or double) stored in constant pool
+ /// @param index - index into constant pool
+ /// @return value of low 32-bits of 64-bit constant
+ uint32 get_8byte_low_word(uint16 index) const {
+ assert(get_tag(index) == CONSTANT_Long
+ || get_tag(index) == CONSTANT_Double);
+ return m_entries[index].CONSTANT_8byte.low_bytes;
+ }
+ /// Returns high word of 64-bit constant (long or double) stored in constant pool
+ /// @param index - index into constant pool
+ /// @return value of high 32-bits of 64-bit constant
+ uint32 get_8byte_high_word(uint16 index) const {
+ assert(get_tag(index) == CONSTANT_Long
+ || get_tag(index) == CONSTANT_Double);
+ return m_entries[index].CONSTANT_8byte.high_bytes;
+ }
+ /// Returns address of constant stored in constant pool
+ /// @param index - index into constant pool
+ /// @return address of constant
+ void* get_address_of_constant(uint16 index) const {
+ assert(is_constant(index));
+ assert(!is_string(index));
+ return (void*)(m_entries + index);
+ }
+ /// Returns exception which has caused failure of
+ /// the referred constant pool entry
+ /// @param index - index into constant pool
+ /// @return exception object which is the cause of resolution failure
+ jthrowable get_error_cause(uint16 index) const {
+ assert(is_entry_in_error(index));
+ return (jthrowable)(&(m_entries[index].error.cause));
+ }
+ /// Returns head of single-linked list containing resolution errors
+ /// in this constant pool
+ /// @return head of signle-linked list of constant pool entries which
+ /// resolution had failed
+ ConstPoolEntry* get_error_chain() const {
+ return m_failedResolution;
+ }
-#define VTABLE_OVERHEAD (sizeof(VTable) - sizeof(void *))
-// The "- sizeof(void *)" part subtracts out the "unsigned char *methods[1]" contribution.
+ /// Returns index in constant pool where utf8 representation
+ /// for CONSTANT_String is stored
+ /// @param index - index into constant pool for CONSTANT_String entry
+ /// @return index in constant pool with utf8 representation of this string
+ uint16 get_string_index(uint16 index) const {
+ assert(is_string(index));
+ return m_entries[index].CONSTANT_String.string_index;
+ }
+ /// Returns index of constant pool entry containing utf8 string
+ /// with name part
+ /// @param index - index into constant pool
+ /// @return index in constant pool with utf8 string for name
+ uint16 get_name_and_type_name_index(uint16 index) const {
+ assert(is_name_and_type(index));
+ return m_entries[index].CONSTANT_NameAndType.name_index;
+ }
+ /// Returns index of constant pool entry containing utf8 string
+ /// with descriptor part
+ /// @param index - index into constant pool
+ /// @return index in constant pool with utf8 string for descriptor
+ uint16 get_name_and_type_descriptor_index(uint16 index) const {
+ assert(is_name_and_type(index));
+ return m_entries[index].CONSTANT_NameAndType.descriptor_index;
+ }
+ /// Returns index of constant pool entry containing class for
+ /// this CONSTANT_*ref entry
+ /// @param index - index into constant pool
+ /// @return index of class entry for this constant pool entry
+ uint16 get_ref_class_index(uint16 index) const {
+ assert(is_fieldref(index)
+ || is_methodref(index)
+ || is_interfacemethodref(index));
+ return m_entries[index].CONSTANT_ref.class_index;
+ }
+ /// Returns index of CONSTANT_NameAndType for this constant pool entry
+ /// @param index - index into constant pool
+ /// @return index of CONSTANT_NameAndType for this constant pool entry
+ uint16 get_ref_name_and_type_index(uint16 index) const {
+ assert(is_fieldref(index)
+ || is_methodref(index)
+ || is_interfacemethodref(index));
+ return m_entries[index].CONSTANT_ref.name_and_type_index;
+ }
+ /// Returns class name index in constant pool for CONSTANT_Class entry
+ /// @param index - index into constant pool
+ /// @return index of utf8 name of this class
+ uint16 get_class_name_index(uint16 index) const {
+ assert(is_class(index));
+ return m_entries[index].CONSTANT_Class.name_index;
+ }
-VTable *create_vtable(Class *p_class, unsigned n_vtable_entries);
+ /// Resolves entry to the class
+ /// @param index - index into constant pool
+ /// @param clss - class to resolve this entry to
+ void resolve_entry(uint16 index, Class* clss) {
+ // we do not want to resolve entry of different type
+ assert(is_class(index));
+ set_entry_resolved(index);
+ m_entries[index].CONSTANT_Class.klass = clss;
+ }
+ /// Resolves entry to the field
+ /// @param index - index into constant pool
+ /// @param field - field to resolve this entry to
+ void resolve_entry(uint16 index, Field* field) {
+ // we do not want to resolve entry of different type
+ assert(is_fieldref(index));
+ set_entry_resolved(index);
+ m_entries[index].CONSTANT_ref.field = field;
+ }
+ /// Resolves entry to the method
+ /// @param index - index into constant pool
+ /// @param method - method to resolve this entry to
+ void resolve_entry(uint16 index, Method* method) {
+ // we do not want to resolve entry of different type
+ assert(is_methodref(index) || is_interfacemethodref(index));
+ set_entry_resolved(index);
+ m_entries[index].CONSTANT_ref.method = method;
+ }
+ /// Records resolution error into constant pool entry
+ /// @param index - index into constant pool
+ /// @param exn - cause of resolution failure
+ /// @note suspension must be disabled during this operation
+ void resolve_as_error(uint16 index, jthrowable exn) {
+ assert(is_class(index)
+ || is_fieldref(index)
+ || is_methodref(index)
+ || is_interfacemethodref(index));
+ // 'if' clause is changed to 'assert' expression as this should never
+ // happen, i.e. class resolution should never try to resolve failing
+ // entry twice
+ // if(!cp.is_entry_in_error(cp_index)) {
+ assert(!is_entry_in_error(index));
+ set_entry_error_state(index);
+ m_entries[index].error.cause = *((ManagedObject**)exn);
+ m_entries[index].error.next = m_failedResolution;
+ assert(&(m_entries[index]) != m_failedResolution);
+ m_failedResolution = &(m_entries[index]);
+ // }
+ }
-} // extern "C"
+ /// Parses in constant pool for a class
+ /// @param clss - class, containing this constant pool
+ /// @param string_pool - reference to string pool to indern strings in
+ /// @param cfs - byte stream to parse constant pool from
+ /// @return true, if constant pool was parsed successfully, false, if
+ /// some error was discovered during parsing
+ bool parse(Class* clss, String_Pool& string_pool, ByteReader& cfs);
+
+ /// Checks consistency of constant pool. Makes sure all indices to other
+ /// constant pool entries are in range. Makes sure contents of constant
+ /// pool entries are of the right type. Sets CONSTANT_Class entries
+ /// to point directly to String representing internal form of
+ /// fully qualified name of Class. Sets CONSTANT_String entries to point
+ /// directly to String representation of String.
+ /// Preresolves CONSTANT_NameAndType entries to signatures
+ /// @param clss - class this constant pool belongs to
+ /// @return true if constant pool of this class is valid, false otherwise
+ bool check(Class* clss);
+
+ /// Clears content of constant pool: tags and entries arrays
+ void clear() {
+ if(m_size != 0) {
+ delete[] m_entries[0].tags;
+ delete[] m_entries;
+ }
+ init();
+ }
+ /// Initializes constant pool to initial values
+ void init() {
+ m_size = 0;
+ m_entries = NULL;
+ m_failedResolution = NULL;
+ }
+private:
+ /// Sets resolved flag in constant pool entry
+ /// @param index - index into constant pool
+ void set_entry_resolved(uint16 index) {
+ assert(is_valid_index(index));
+ // we do not want to resolve one entry twice
+ assert(!is_entry_resolved(index));
+ // we should not resolve failed entries
+ assert(!is_entry_in_error(index));
+ m_entries[0].tags[index] |= RESOLVED_MASK;
+ }
+ /// Sets error flag in constant pool entry thus marking it failed
+ /// @param index - index into constant pool
+ void set_entry_error_state(uint16 index) {
+ assert(is_valid_index(index));
+ // we do not want to reset resolved error
+ assert(!is_entry_resolved(index));
+ // we do not want to reset reason of the failure
+ assert(!is_entry_in_error(index));
+ m_entries[0].tags[index] |= ERROR_MASK;
+ }
+ /// Resolves CONSTANT_NameAndType constant pool entry to actual string values
+ /// @param index - index into constant pool
+ /// @param name - name-and-type name
+ /// @param descriptor - name-and-type type (descriptor)
+ void resolve_entry(uint16 index, String* name, String* descriptor) {
+ // we do not want to resolve entry of different type
+ assert(is_name_and_type(index));
+ set_entry_resolved(index);
+ m_entries[index].CONSTANT_NameAndType.name = name;
+ m_entries[index].CONSTANT_NameAndType.descriptor = descriptor;
+ }
+ /// Resolves CONSTANT_String constant pool entry to actual string value
+ /// @param index - index into constant pool
+ /// @param str - actual string
+ void resolve_entry(uint16 index, String* str) {
+ assert(is_string(index));
+ set_entry_resolved(index);
+ m_entries[index].CONSTANT_String.string = str;
+ }
+};
///////////////////////////////////////////////////////////////////////////////
// A Java class
///////////////////////////////////////////////////////////////////////////////
extern "C" {
-
//
// state of this class
//
@@ -562,7 +763,6 @@ typedef struct Class {
TypeDesc* array_element_type_desc;
uint16 access_flags;
- uint16 cp_size;
uint16 n_superinterfaces;
uint16 n_fields;
uint16 n_static_fields;
@@ -579,7 +779,7 @@ typedef struct Class {
// empty string if anonymous
String * simple_name;
- Const_Pool *const_pool; // constant pool array; size is cp_size
+ ConstantPool m_const_pool; // constant pool array
Field *fields; // array of fields; size is n_fields
Method *methods; // array of methods; size is n_methods
//
@@ -749,10 +949,6 @@ #endif
// class operations lock
Lock_Manager* m_lock;
- // List of constant pool entries, which resolution had failed
- // Required for fast enumeration of error objects
- Const_Pool* m_failedResolution;
-
// struct Class accessibility
unsigned m_markBit:1;
@@ -822,8 +1018,6 @@ VMEXPORT Class *class_resolve_class(Clas
Boolean check_member_access(Class_Member *member, Class *other_clss);
// Can "other_clss" access the "inner_clss"
Boolean check_inner_class_access(Global_Env *env, Class *inner_clss, Class *other_clss);
-// get class name from constant pool
-extern String *cp_check_class(Const_Pool *cp, unsigned cp_size, unsigned class_index);
//
// parses in class description from a class file format
@@ -882,808 +1076,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..50ae5a8
--- /dev/null
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/annotation.h
@@ -0,0 +1,91 @@
+/*
+ * 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
+
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..d148275
--- /dev/null
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
@@ -0,0 +1,740 @@
+/*
+ * 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"
+
+struct ConstantPool;
+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, 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, 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; // 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, 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(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_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 abaaa18..4afa066 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/jni_direct.h
@@ -28,7 +28,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 7555164..9d5101a 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/jvmti_direct.h
@@ -24,6 +24,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 935548a..2f3c70a 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/object_handles.h
@@ -43,6 +43,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 f6c7031..d924261 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/include/vm_log.h
+++ b/enhanced/drlvm/trunk/vm/vmcore/include/vm_log.h
@@ -22,8 +22,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 6600df9..7f35f14 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
@@ -32,6 +32,7 @@ #include "properties.h"
#include "open/hythread_ext.h"
#include "thread_manager.h"
+#include "cci.h"
#include "Verifier_stub.h"
#include "class_interface.h"
@@ -740,28 +741,10 @@ const char *class_get_source_file_name(C
} //class_get_source_file_name
-
-// If this function was exported through the public interface, we should
-// change the return type to something like String_Handle.
-String *class_get_const_string_handle(Class_Handle cl, unsigned index)
-{
- assert(cl);
- Class *clss = (Class *)cl;
- String *str = 0;
- assert(index < clss->cp_size);
- Const_Pool *cp = clss->const_pool;
- str = cp[index].CONSTANT_String.string;
- return str;
-} //class_get_const_string_handle
-
-
-
-const char *class_get_const_string(Class_Handle cl, unsigned index)
+const char* class_get_const_string(Class_Handle cl, unsigned index)
{
assert(cl);
- String *str = class_get_const_string_handle(cl, index);
- assert(str);
- return str->bytes;
+ return cl->m_const_pool.get_string_chars(index);
} //class_get_const_string
@@ -773,7 +756,7 @@ void *class_get_const_string_intern_addr
{
assert(cl);
Global_Env *env = VM_Global_State::loader_env;
- String *str = class_get_const_string_handle(cl, index);
+ String* str = cl->m_const_pool.get_string(index);
assert(str);
bool must_instantiate;
@@ -791,7 +774,6 @@ void *class_get_const_string_intern_addr
vm_instantiate_cp_string_resolved(str);
END_RAISE_AREA;
tmn_suspend_enable();
-
}
if (env->compress_references) {
@@ -805,23 +787,21 @@ void *class_get_const_string_intern_addr
const char* class_get_cp_entry_signature(Class_Handle src_class, unsigned short index)
{
Class* clss = (Class*)src_class;
- // TODO: check that index is valid for src_class; assert for now
- assert(index < clss->cp_size);
- assert(cp_is_methodref(clss->const_pool, index)
- || cp_is_interfacemethodref(clss->const_pool, index)
- || cp_is_fieldref(clss->const_pool, index));
-
- index = clss->const_pool[index].CONSTANT_ref.name_and_type_index;
- index = clss->const_pool[index].CONSTANT_NameAndType.descriptor_index;
- return clss->const_pool[index].CONSTANT_Utf8.string->bytes;
+ ConstantPool& cp = src_class->m_const_pool;
+
+ assert(cp.is_fieldref(index)
+ || cp.is_methodref(index)
+ || cp.is_interfacemethodref(index));
+
+ index = cp.get_ref_name_and_type_index(index);
+ index = cp.get_name_and_type_descriptor_index(index);
+ return cp.get_utf8_chars(index);
} // class_get_cp_entry_signature
VM_Data_Type class_get_cp_field_type(Class_Handle src_class, unsigned short cp_index)
{
- // TODO: check that cp_index is valid for src_class; assert for now
- assert(cp_index < ((Class*)src_class)->cp_size);
- assert(cp_is_fieldref(((Class*)src_class)->const_pool, cp_index));
+ assert(src_class->m_const_pool.is_fieldref(cp_index));
char class_id = (class_get_cp_entry_signature(src_class, cp_index))[0];
switch(class_id)
@@ -1047,148 +1027,148 @@ Class_Handle class_find_class_from_loade
// The following do not cause constant pools to be resolve, if they are not
// resolved already
//
-const char *const_pool_get_field_name(Class_Handle cl, unsigned index)
+const char* const_pool_get_field_name(Class_Handle cl, unsigned index)
{
assert(cl);
- Const_Pool *const_pool = ((Class *)cl)->const_pool;
- if (!cp_is_fieldref(const_pool,index)) {
+ ConstantPool& const_pool = cl->m_const_pool;
+ if(!const_pool.is_fieldref(index)) {
ABORT("Wrong index");
return 0;
}
- index = const_pool[index].CONSTANT_ref.name_and_type_index;
- index = const_pool[index].CONSTANT_NameAndType.name_index;
- return const_pool[index].CONSTANT_Utf8.string->bytes;
-} //const_pool_get_field_name
+ index = const_pool.get_ref_name_and_type_index(index);
+ index = const_pool.get_name_and_type_name_index(index);
+ return const_pool.get_utf8_chars(index);
+} // const_pool_get_field_name
-const char *const_pool_get_field_class_name(Class_Handle cl, unsigned index)
+const char* const_pool_get_field_class_name(Class_Handle cl, unsigned index)
{
assert(cl);
- Const_Pool *const_pool = ((Class *)cl)->const_pool;
- if (!cp_is_fieldref(const_pool,index)) {
+ ConstantPool& const_pool = cl->m_const_pool;
+ if(!const_pool.is_fieldref(index)) {
ABORT("Wrong index");
return 0;
}
- index = const_pool[index].CONSTANT_ref.class_index;
- return const_pool_get_class_name(cl,index);
+ index = const_pool.get_ref_class_index(index);
+ return const_pool_get_class_name(cl, index);
} //const_pool_get_field_class_name
-const char *const_pool_get_field_descriptor(Class_Handle cl, unsigned index)
+const char* const_pool_get_field_descriptor(Class_Handle cl, unsigned index)
{
assert(cl);
- Const_Pool *const_pool = ((Class *)cl)->const_pool;
- if (!cp_is_fieldref(const_pool,index)) {
+ ConstantPool& const_pool = cl->m_const_pool;
+ if (!const_pool.is_fieldref(index)) {
ABORT("Wrong index");
return 0;
}
- index = const_pool[index].CONSTANT_ref.name_and_type_index;
- index = const_pool[index].CONSTANT_NameAndType.descriptor_index;
- return const_pool[index].CONSTANT_Utf8.string->bytes;
-} //const_pool_get_field_descriptor
+ index = const_pool.get_ref_name_and_type_index(index);
+ index = const_pool.get_name_and_type_descriptor_index(index);
+ return const_pool.get_utf8_chars(index);
+} // const_pool_get_field_descriptor
-const char *const_pool_get_method_name(Class_Handle cl, unsigned index)
+const char* const_pool_get_method_name(Class_Handle cl, unsigned index)
{
assert(cl);
- Const_Pool *const_pool = ((Class *)cl)->const_pool;
- if (!cp_is_methodref(const_pool,index)) {
+ ConstantPool& const_pool = cl->m_const_pool;
+ if (!const_pool.is_methodref(index)) {
ABORT("Wrong index");
return 0;
}
- index = const_pool[index].CONSTANT_ref.name_and_type_index;
- index = const_pool[index].CONSTANT_NameAndType.name_index;
- return const_pool[index].CONSTANT_Utf8.string->bytes;
-} //const_pool_get_method_name
+ index = const_pool.get_ref_name_and_type_index(index);
+ index = const_pool.get_name_and_type_name_index(index);
+ return const_pool.get_utf8_chars(index);
+} // const_pool_get_method_name
const char *const_pool_get_method_class_name(Class_Handle cl, unsigned index)
{
assert(cl);
- Const_Pool *const_pool = ((Class *)cl)->const_pool;
- if (!cp_is_methodref(const_pool,index)) {
+ ConstantPool& const_pool = cl->m_const_pool;
+ if (!const_pool.is_methodref(index)) {
ABORT("Wrong index");
return 0;
}
- index = const_pool[index].CONSTANT_ref.class_index;
+ index = const_pool.get_ref_class_index(index);
return const_pool_get_class_name(cl,index);
} //const_pool_get_method_class_name
-const char *const_pool_get_interface_method_name(Class_Handle cl, unsigned index)
+const char* const_pool_get_interface_method_name(Class_Handle cl, unsigned index)
{
assert(cl);
- Const_Pool *const_pool = ((Class *)cl)->const_pool;
- if (!cp_is_interfacemethodref(const_pool,index)) {
+ ConstantPool& const_pool = cl->m_const_pool;
+ if(!const_pool.is_interfacemethodref(index)) {
ABORT("Wrong index");
return 0;
}
- index = const_pool[index].CONSTANT_ref.name_and_type_index;
- index = const_pool[index].CONSTANT_NameAndType.name_index;
- return const_pool[index].CONSTANT_Utf8.string->bytes;
-} //const_pool_get_interface_method_name
+ index = const_pool.get_ref_name_and_type_index(index);
+ index = const_pool.get_name_and_type_name_index(index);
+ return const_pool.get_utf8_chars(index);
+} // const_pool_get_interface_method_name
-const char *const_pool_get_interface_method_class_name(Class_Handle cl, unsigned index)
+const char* const_pool_get_interface_method_class_name(Class_Handle cl, unsigned index)
{
assert(cl);
- Const_Pool *const_pool = ((Class *)cl)->const_pool;
- if (!cp_is_interfacemethodref(const_pool,index)) {
+ ConstantPool& const_pool = cl->m_const_pool;
+ if (!const_pool.is_interfacemethodref(index)) {
ABORT("Wrong index");
return 0;
}
- index = const_pool[index].CONSTANT_ref.class_index;
+ index = const_pool.get_ref_class_index(index);
return const_pool_get_class_name(cl,index);
} //const_pool_get_interface_method_class_name
-const char *const_pool_get_method_descriptor(Class_Handle cl, unsigned index)
+const char* const_pool_get_method_descriptor(Class_Handle cl, unsigned index)
{
assert(cl);
- Const_Pool *const_pool = ((Class *)cl)->const_pool;
- if (!cp_is_methodref(const_pool,index)) {
+ ConstantPool& const_pool = cl->m_const_pool;
+ if (!const_pool.is_methodref(index)) {
ABORT("Wrong index");
return 0;
}
- index = const_pool[index].CONSTANT_ref.name_and_type_index;
- index = const_pool[index].CONSTANT_NameAndType.descriptor_index;
- return const_pool[index].CONSTANT_Utf8.string->bytes;
-} //const_pool_get_method_descriptor
+ index = const_pool.get_ref_name_and_type_index(index);
+ index = const_pool.get_name_and_type_descriptor_index(index);
+ return const_pool.get_utf8_chars(index);
+} // const_pool_get_method_descriptor
-const char *const_pool_get_interface_method_descriptor(Class_Handle cl, unsigned index)
+const char* const_pool_get_interface_method_descriptor(Class_Handle cl, unsigned index)
{
assert(cl);
- Const_Pool *const_pool = ((Class *)cl)->const_pool;
- if (!cp_is_interfacemethodref(const_pool,index)) {
+ ConstantPool& const_pool = cl->m_const_pool;
+ if (!const_pool.is_interfacemethodref(index)) {
ABORT("Wrong index");
return 0;
}
- index = const_pool[index].CONSTANT_ref.name_and_type_index;
- index = const_pool[index].CONSTANT_NameAndType.descriptor_index;
- return const_pool[index].CONSTANT_Utf8.string->bytes;
-} //const_pool_get_interface_method_descriptor
+ index = const_pool.get_ref_name_and_type_index(index);
+ index = const_pool.get_name_and_type_descriptor_index(index);
+ return const_pool.get_utf8_chars(index);
+} // const_pool_get_interface_method_descriptor
-const char *const_pool_get_class_name(Class_Handle cl, unsigned index)
+const char* const_pool_get_class_name(Class_Handle cl, unsigned index)
{
assert(cl);
- Const_Pool *const_pool = ((Class *)cl)->const_pool;
- if (!cp_is_class(const_pool,index)) {
+ ConstantPool& const_pool = cl->m_const_pool;
+ if (!const_pool.is_class(index)) {
ABORT("Wrong index");
return 0;
}
- return const_pool[const_pool[index].CONSTANT_Class.name_index].CONSTANT_Utf8.string->bytes;
-} //const_pool_get_class_name
+ return const_pool.get_utf8_chars(const_pool.get_class_name_index(index));
+} // const_pool_get_class_name
unsigned method_number_throws(Method_Handle m)
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 b5f1f1c..d28608f 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp
@@ -195,6 +195,14 @@ void* Field::get_address()
} // Field::get_address
+unsigned Field::calculate_size() {
+ static unsigned size = sizeof(Field) + sizeof(TypeDesc);
+ return size;
+}
+
+
+
+
Method::Method()
{
//
@@ -447,7 +455,8 @@ void set_struct_Class_field_in_java_lang
void class_report_failure(Class* target, uint16 cp_index, jthrowable exn)
{
- assert(cp_index > 0 && cp_index < target->cp_size);
+ ConstantPool& cp = target->m_const_pool;
+ assert(cp.is_valid_index(cp_index));
assert(hythread_is_suspend_enabled());
if (exn_raised()) {
TRACE2("classloader.error", "runtime exception in classloading");
@@ -458,13 +467,7 @@ void class_report_failure(Class* target,
tmn_suspend_disable();
target->m_lock->_lock();
// vvv - This should be atomic change
- if (!cp_in_error(target->const_pool, cp_index)) {
- cp_set_error(target->const_pool, cp_index);
- target->const_pool[cp_index].error.cause = ((ObjectHandle)exn)->object;
- target->const_pool[cp_index].error.next = target->m_failedResolution;
- assert(&(target->const_pool[cp_index]) != target->m_failedResolution);
- target->m_failedResolution = &(target->const_pool[cp_index]);
- }
+ cp.resolve_as_error(cp_index, exn);
// ^^^
target->m_lock->_unlock();
tmn_suspend_enable();
@@ -473,8 +476,8 @@ void class_report_failure(Class* target,
jthrowable class_get_linking_error(Class* clss, unsigned index)
{
- assert(cp_in_error(clss->const_pool, index));
- return (jthrowable)(&(clss->const_pool[index].error.cause));
+ assert(clss->m_const_pool.is_entry_in_error(index));
+ return clss->m_const_pool.get_error_cause(index);
}
String* class_get_java_name(Class* clss, Global_Env* env)
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp
index 7dfec71..1c2361e 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp
@@ -29,6 +29,7 @@ #include
#include "environment.h"
#include "classloader.h"
#include "Class.h"
+#include "class_member.h"
#include "vm_strings.h"
#include "open/vm_util.h"
#include "bytereader.h"
@@ -66,33 +67,29 @@ #define REPORT_FAILED_CLASS_FORMAT(klass
}
#define valid_cpi(clss, idx, type) \
- (idx < clss->cp_size && cp_tag(clss->const_pool, idx) == type)
+ (clss->m_const_pool.is_valid_index(idx) && clss->m_const_pool.get_tag(idx) == type)
-String *cp_check_utf8(Const_Pool *cp,
- unsigned cp_size,
- unsigned utf8_index)
+String* cp_check_utf8(ConstantPool& cp, unsigned utf8_index)
{
- if(utf8_index >= cp_size || !cp_is_utf8(cp, utf8_index)) {
+ if(!cp.is_valid_index(utf8_index) || !cp.is_utf8(utf8_index)) {
return NULL;
}
- return cp[utf8_index].CONSTANT_Utf8.string;
-} //cp_check_utf8
+ return cp.get_utf8_string(utf8_index);
+} // cp_check_utf8
-String *cp_check_class(Const_Pool *cp,
- unsigned cp_size,
- unsigned class_index)
+String* cp_check_class(ConstantPool& cp, unsigned class_index)
{
- if (class_index >= cp_size || !cp_is_class(cp,class_index)) {
+ if(!cp.is_valid_index(class_index) || !cp.is_class(class_index)) {
#ifdef _DEBUG
WARN("cp_check_class: illegal const pool class index" << class_index);
#endif
return NULL;
}
- return cp[cp[class_index].CONSTANT_Class.name_index].CONSTANT_Utf8.string;
+ return cp.get_utf8_string(cp.get_class_name_index(class_index));
} //cp_check_class
@@ -216,7 +213,7 @@ String* parse_signature_attr(ByteReader
"cannot parse Signature index");
return NULL;
}
- String* sig = cp_check_utf8(clss->const_pool, clss->cp_size, idx);
+ String* sig = cp_check_utf8(clss->m_const_pool, idx);
if(!sig) {
REPORT_FAILED_CLASS_FORMAT(clss, "invalid Signature index : " << idx);
}
@@ -225,8 +222,7 @@ String* parse_signature_attr(ByteReader
Attributes parse_attribute(ByteReader &cfs,
- Const_Pool *cp,
- unsigned cp_size,
+ ConstantPool& cp,
String *attr_strings[],
Attributes attrs[],
uint32 *attr_len,
@@ -243,7 +239,7 @@ Attributes parse_attribute(ByteReader &c
if (!result)
return ATTR_ERROR;
- String *attr_name = cp_check_utf8(cp,cp_size,attr_name_index);
+ String* attr_name = cp_check_utf8(cp, attr_name_index);
if (attr_name == NULL) {
#ifdef _DEBUG
WARN("parse_attribute: illegal const pool attr_name_index");
@@ -294,7 +290,7 @@ uint32 parse_annotation(Annotation** val
"cannot parse type index of annotation");
return 0;
}
- String* type = cp_check_utf8(clss->const_pool, clss->cp_size, type_idx);
+ String* type = cp_check_utf8(clss->m_const_pool, type_idx);
if (type == NULL) {
REPORT_FAILED_CLASS_FORMAT(clss,
"invalid type index of annotation : " << type_idx);
@@ -325,7 +321,7 @@ uint32 parse_annotation(Annotation** val
"cannot parse element_name_index of annotation element");
return 0;
}
- antn->elements[j].name = cp_check_utf8(clss->const_pool, clss->cp_size, name_idx);
+ antn->elements[j].name = cp_check_utf8(clss->m_const_pool, name_idx);
if (antn->elements[j].name == NULL) {
REPORT_FAILED_CLASS_FORMAT(clss,
"invalid element_name_index of annotation : " << name_idx);
@@ -354,8 +350,8 @@ uint32 parse_annotation_value(Annotation
value.tag = (AnnotationValueType)tag;
uint32 read_len = 1;
- Const_Pool *cp = clss->const_pool;
- unsigned cp_size = clss->cp_size;
+ ConstantPool& cp = clss->m_const_pool;
+ unsigned cp_size = cp.get_size();
char ctag = (char)tag;
switch(ctag) {
@@ -382,29 +378,29 @@ uint32 parse_annotation_value(Annotation
case AVT_CHAR:
case AVT_INT:
if (valid_cpi(clss, const_idx, CONSTANT_Integer)) {
- value.const_value.i = cp[const_idx].int_value;
+ value.const_value.i = cp.get_int(const_idx);
break;
}
case AVT_FLOAT:
if (valid_cpi(clss, const_idx, CONSTANT_Float)) {
- value.const_value.f = cp[const_idx].float_value;
+ value.const_value.f = cp.get_float(const_idx);
break;
}
case AVT_LONG:
if (valid_cpi(clss, const_idx, CONSTANT_Long)) {
- value.const_value.l.lo_bytes = cp[const_idx].CONSTANT_8byte.low_bytes;
- value.const_value.l.hi_bytes = cp[const_idx].CONSTANT_8byte.high_bytes;
+ value.const_value.l.lo_bytes = cp.get_8byte_low_word(const_idx);
+ value.const_value.l.hi_bytes = cp.get_8byte_high_word(const_idx);
break;
}
case AVT_DOUBLE:
if (valid_cpi(clss, const_idx, CONSTANT_Double)) {
- value.const_value.l.lo_bytes = cp[const_idx].CONSTANT_8byte.low_bytes;
- value.const_value.l.hi_bytes = cp[const_idx].CONSTANT_8byte.high_bytes;
+ value.const_value.l.lo_bytes = cp.get_8byte_low_word(const_idx);
+ value.const_value.l.hi_bytes = cp.get_8byte_high_word(const_idx);
break;
}
case AVT_STRING:
if (valid_cpi(clss, const_idx, CONSTANT_Utf8)) {
- value.const_value.string = cp[const_idx].CONSTANT_Utf8.string;
+ value.const_value.string = cp.get_utf8_string(const_idx);
break;
}
default:
@@ -425,7 +421,7 @@ uint32 parse_annotation_value(Annotation
"cannot parse class_info_index of annotation value");
return 0;
}
- value.class_name = cp_check_utf8(cp, cp_size, class_idx);
+ value.class_name = cp_check_utf8(cp, class_idx);
if (value.class_name == NULL) {
REPORT_FAILED_CLASS_FORMAT(clss,
"invalid class_info_index of annotation value: " << class_idx);
@@ -443,7 +439,7 @@ uint32 parse_annotation_value(Annotation
"cannot parse type_name_index of annotation enum value");
return 0;
}
- value.enum_const.type = cp_check_utf8(cp, cp_size, type_idx);
+ value.enum_const.type = cp_check_utf8(cp, type_idx);
if (value.enum_const.type == NULL) {
REPORT_FAILED_CLASS_FORMAT(clss,
"invalid type_name_index of annotation enum value: " << type_idx);
@@ -455,7 +451,7 @@ uint32 parse_annotation_value(Annotation
"cannot parse const_name_index of annotation enum value");
return 0;
}
- value.enum_const.name = cp_check_utf8(cp, cp_size, name_idx);
+ value.enum_const.name = cp_check_utf8(cp, name_idx);
if (value.enum_const.name == NULL) {
REPORT_FAILED_CLASS_FORMAT(clss,
"invalid const_name_index of annotation enum value: " << name_idx);
@@ -611,7 +607,7 @@ void* Class_Member::Alloc(size_t size) {
}
-bool Class_Member::parse(Class *clss, Const_Pool *cp, unsigned cp_size, ByteReader &cfs)
+bool Class_Member::parse(Class *clss, ByteReader &cfs)
{
if (!cfs.parse_u2_be(&_access_flags)) {
REPORT_FAILED_CLASS_FORMAT(clss, "cannot parse member access flags");
@@ -631,12 +627,13 @@ bool Class_Member::parse(Class *clss, Co
return false;
}
+ ConstantPool& cp = clss->m_const_pool;
//
// look up the name_index and descriptor_index
// utf8 string const pool entries
//
- String *name = cp_check_utf8(cp,cp_size,name_index);
- String *descriptor = cp_check_utf8(cp,cp_size,descriptor_index);
+ String* name = cp_check_utf8(cp, name_index);
+ String* descriptor = cp_check_utf8(cp, descriptor_index);
if (name == NULL || descriptor == NULL) {
REPORT_FAILED_CLASS_FORMAT(clss,
"some of member name or descriptor indexes is not CONSTANT_Utf8 entry : "
@@ -740,9 +737,9 @@ check_field_descriptor( const char *desc
// DIE( "unreachable code!" ); // exclude remark #111: statement is unreachable
}
-bool Field::parse(Class *clss, Const_Pool *cp, unsigned cp_size, ByteReader &cfs)
+bool Field::parse(Class *clss, ByteReader &cfs)
{
- if(!Class_Member::parse(clss, cp, cp_size, cfs))
+ if(!Class_Member::parse(clss, cfs))
return false;
if(!check_field_name(_name)) {
@@ -751,7 +748,7 @@ bool Field::parse(Class *clss, Const_Poo
}
// check field descriptor
- const char *next;
+ const char* next;
if(!check_field_descriptor(_descriptor->bytes, &next, false) || *next != '\0') {
REPORT_FAILED_CLASS_FORMAT(clss, "illegal field descriptor : " << _descriptor->bytes);
return false;
@@ -790,9 +787,11 @@ bool Field::parse(Class *clss, Const_Poo
uint32 attr_len = 0;
+ ConstantPool& cp = clss->m_const_pool;
+
for (unsigned j=0; j= cp_size) {
+ if(_const_value_index == 0 || _const_value_index >= cp.get_size()) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": invalid ConstantValue index for field " << get_name());
return false;
}
// type of constant must match field's type
- Const_Pool_Tags tag = (Const_Pool_Tags)cp_tag(cp, _const_value_index);
+ Const_Pool_Tags tag = (Const_Pool_Tags)cp.get_tag(_const_value_index);
Java_Type java_type = get_java_type();
@@ -838,8 +837,8 @@ bool Field::parse(Class *clss, Const_Poo
<< get_name());
return false;
}
- const_value.l.lo_bytes = cp[_const_value_index].CONSTANT_8byte.low_bytes;
- const_value.l.hi_bytes = cp[_const_value_index].CONSTANT_8byte.high_bytes;
+ const_value.l.lo_bytes = cp.get_8byte_low_word(_const_value_index);
+ const_value.l.hi_bytes = cp.get_8byte_high_word(_const_value_index);
break;
}
case CONSTANT_Float:
@@ -851,7 +850,7 @@ bool Field::parse(Class *clss, Const_Poo
<< get_name());
return false;
}
- const_value.f = cp[_const_value_index].float_value;
+ const_value.f = cp.get_float(_const_value_index);
break;
}
case CONSTANT_Double:
@@ -863,8 +862,8 @@ bool Field::parse(Class *clss, Const_Poo
<< get_name());
return false;
}
- const_value.l.lo_bytes = cp[_const_value_index].CONSTANT_8byte.low_bytes;
- const_value.l.hi_bytes = cp[_const_value_index].CONSTANT_8byte.high_bytes;
+ const_value.l.lo_bytes = cp.get_8byte_low_word(_const_value_index);
+ const_value.l.hi_bytes = cp.get_8byte_high_word(_const_value_index);
break;
}
case CONSTANT_Integer:
@@ -881,7 +880,7 @@ bool Field::parse(Class *clss, Const_Poo
<< get_name());
return false;
}
- const_value.i = cp[_const_value_index].int_value;
+ const_value.i = cp.get_int(_const_value_index);
break;
}
case CONSTANT_String:
@@ -893,7 +892,7 @@ bool Field::parse(Class *clss, Const_Poo
<< get_name());
return false;
}
- const_value.string = cp[_const_value_index].CONSTANT_String.string;
+ const_value.string = cp.get_string(_const_value_index);
break;
}
default:
@@ -942,8 +941,8 @@ bool Field::parse(Class *clss, Const_Poo
} //Field::parse
-bool Handler::parse(Const_Pool* cp, unsigned cp_size, unsigned code_length,
- ByteReader &cfs)
+bool Handler::parse(ConstantPool& cp, unsigned code_length,
+ ByteReader& cfs)
{
uint16 start = 0;
if(!cfs.parse_u2_be(&start))
@@ -982,7 +981,7 @@ bool Handler::parse(Const_Pool* cp, unsi
if (catch_index == 0) {
_catch_type = NULL;
} else {
- _catch_type = cp_check_class(cp,cp_size,catch_index);
+ _catch_type = cp_check_class(cp, catch_index);
if (_catch_type == NULL)
return false;
}
@@ -1038,8 +1037,8 @@ #define REPORT_FAILED_METHOD(msg) REPORT
<< _name->bytes << _descriptor->bytes);
-bool Method::_parse_exceptions(Const_Pool *cp, unsigned cp_size, unsigned attr_len,
- ByteReader &cfs)
+bool Method::_parse_exceptions(ConstantPool& cp, unsigned attr_len,
+ ByteReader& cfs)
{
if(!cfs.parse_u2_be(&_n_exceptions)) {
REPORT_FAILED_CLASS_CLASS(_class->class_loader, _class, "java/lang/ClassFormatError",
@@ -1059,7 +1058,7 @@ bool Method::_parse_exceptions(Const_Poo
return false;
}
- _exceptions[i] = cp_check_class(cp,cp_size,index);
+ _exceptions[i] = cp_check_class(cp, index);
if (_exceptions[i] == NULL) {
REPORT_FAILED_CLASS_CLASS(_class->class_loader, _class, "java/lang/ClassFormatError",
_class->name->bytes << ": exception class index "
@@ -1129,7 +1128,7 @@ bool Method::_parse_line_numbers(unsigne
bool Method::_parse_local_vars(const char* attr_name, Local_Var_Table** lvt_address,
- Const_Pool *cp, unsigned cp_size, unsigned attr_len, ByteReader &cfs)
+ ConstantPool& cp, unsigned attr_len, ByteReader &cfs)
{
uint16 n_local_vars;
if(!cfs.parse_u2_be(&n_local_vars)) {
@@ -1190,14 +1189,14 @@ bool Method::_parse_local_vars(const cha
return false;
}
- String* name = cp_check_utf8(cp,cp_size,name_index);
+ String* name = cp_check_utf8(cp, name_index);
if(name == NULL) {
REPORT_FAILED_METHOD("name index is not valid CONSTANT_Utf8 entry "
"in " << attr_name << " attribute");
return false;
}
- String* descriptor = cp_check_utf8(cp,cp_size,descriptor_index);
+ String* descriptor = cp_check_utf8(cp, descriptor_index);
if(descriptor == NULL) {
REPORT_FAILED_METHOD("descriptor index is not valid CONSTANT_Utf8 entry "
"in " << attr_name << " attribute");
@@ -1233,7 +1232,8 @@ bool Method::_parse_local_vars(const cha
} //Method::_parse_local_vars
-bool Method::_parse_code( Const_Pool *cp, unsigned cp_size, unsigned code_attr_len, ByteReader &cfs)
+bool Method::_parse_code(ConstantPool& cp, unsigned code_attr_len,
+ ByteReader& cfs)
{
unsigned real_code_attr_len = 0;
if(!cfs.parse_u2_be(&_max_stack)) {
@@ -1312,7 +1312,7 @@ bool Method::_parse_code( Const_Pool *cp
// ppervov: FIXME: should throw OOME
for (i=0; i<_n_handlers; i++) {
- if(!_handlers[i].parse(cp, cp_size, _byte_code_length, cfs)) {
+ if(!_handlers[i].parse(cp, _byte_code_length, cfs)) {
REPORT_FAILED_CLASS_CLASS(_class->class_loader, _class, "java/lang/ClassFormatError",
_class->name->bytes << ": could not parse exceptions for method "
<< _name->bytes << _descriptor->bytes);
@@ -1338,7 +1338,7 @@ bool Method::_parse_code( Const_Pool *cp
uint32 attr_len = 0;
for (i=0; im_const_pool;
for (unsigned j=0; jconst_pool, clss->cp_size, cfs))
+ if(!fd.parse(clss, cfs))
return false;
if(fd.is_static()) {
clss->fields[clss->n_static_fields] = fd;
@@ -1804,7 +1805,7 @@ static bool class_parse_methods(Class *c
_total_method_bytes += sizeof(Method)*clss->n_methods;
for (unsigned i=0; i < clss->n_methods; i++) {
- if (!clss->methods[i].parse(*env, clss, clss->const_pool, clss->cp_size, cfs))
+ if(!clss->methods[i].parse(*env, clss, cfs))
return false;
Method *m = &clss->methods[i];
@@ -1826,7 +1827,7 @@ static bool class_parse_methods(Class *c
} //class_parse_methods
-static String* const_pool_parse_utf8data(String_Pool& string_pool, ByteReader& cfs,
+static String* class_file_parse_utf8data(String_Pool& string_pool, ByteReader& cfs,
uint16 len)
{
// buffer ends before len
@@ -1847,38 +1848,38 @@ static String* const_pool_parse_utf8data
}
-static String* const_pool_parse_utf8(String_Pool& string_pool,
+static String* class_file_parse_utf8(String_Pool& string_pool,
ByteReader& cfs)
{
uint16 len;
if(!cfs.parse_u2_be(&len))
return false;
- return const_pool_parse_utf8data(string_pool, cfs, len);
+ return class_file_parse_utf8data(string_pool, cfs, len);
}
-static bool class_parse_const_pool(Class *clss,
- String_Pool& string_pool,
- ByteReader &cfs)
+bool ConstantPool::parse(Class* clss,
+ String_Pool& string_pool,
+ ByteReader& cfs)
{
- if(!cfs.parse_u2_be(&clss->cp_size)) {
+ if(!cfs.parse_u2_be(&m_size)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse constant pool size");
return false;
}
- unsigned char *cp_tags = new unsigned char[clss->cp_size];
+ unsigned char* cp_tags = new unsigned char[m_size];
// ppervov: FIXME: should throw OOME
- clss->const_pool = new Const_Pool[clss->cp_size];
+ m_entries = new ConstPoolEntry[m_size];
// ppervov: FIXME: should throw OOME
//
// 0'th constant pool entry is a pointer to the tags array
//
- clss->const_pool[0].tags = cp_tags;
+ m_entries[0].tags = cp_tags;
cp_tags[0] = CONSTANT_Tags;
- for (unsigned i=1; icp_size; i++) {
+ for(unsigned i = 1; i < m_size; i++) {
// parse tag into tag array
uint8 tag;
if(!cfs.parse_u1(&tag)) {
@@ -1887,9 +1888,9 @@ static bool class_parse_const_pool(Class
return false;
}
- switch (cp_tags[i] = tag) {
+ switch(cp_tags[i] = tag) {
case CONSTANT_Class:
- if(!cfs.parse_u2_be(&clss->const_pool[i].CONSTANT_Class.name_index)) {
+ if(!cfs.parse_u2_be(&m_entries[i].CONSTANT_Class.name_index)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse name index "
"for CONSTANT_Class entry");
@@ -1900,12 +1901,12 @@ static bool class_parse_const_pool(Class
case CONSTANT_Methodref:
case CONSTANT_Fieldref:
case CONSTANT_InterfaceMethodref:
- if(!cfs.parse_u2_be(&clss->const_pool[i].CONSTANT_ref.class_index)) {
+ if(!cfs.parse_u2_be(&m_entries[i].CONSTANT_ref.class_index)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse class index for CONSTANT_*ref entry");
return false;
}
- if(!cfs.parse_u2_be(&clss->const_pool[i].CONSTANT_ref.name_and_type_index)) {
+ if(!cfs.parse_u2_be(&m_entries[i].CONSTANT_ref.name_and_type_index)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse name-and-type index for CONSTANT_*ref entry");
return false;
@@ -1913,7 +1914,7 @@ static bool class_parse_const_pool(Class
break;
case CONSTANT_String:
- if(!cfs.parse_u2_be(&clss->const_pool[i].CONSTANT_String.string_index)) {
+ if(!cfs.parse_u2_be(&m_entries[i].CONSTANT_String.string_index)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse string index for CONSTANT_String entry");
return false;
@@ -1922,7 +1923,7 @@ static bool class_parse_const_pool(Class
case CONSTANT_Float:
case CONSTANT_Integer:
- if(!cfs.parse_u4_be(&clss->const_pool[i].int_value)) {
+ if(!cfs.parse_u4_be(&m_entries[i].int_value)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse value for "
<< (tag==CONSTANT_Integer?"CONSTANT_Integer":"CONSTANT_Float") << " entry");
@@ -1934,13 +1935,13 @@ static bool class_parse_const_pool(Class
case CONSTANT_Long:
// longs and doubles take up two entries
// on both IA32 & IPF, first constant pool element is used, second element - unused
- if(!cfs.parse_u4_be(&clss->const_pool[i].CONSTANT_8byte.high_bytes)) {
+ if(!cfs.parse_u4_be(&m_entries[i].CONSTANT_8byte.high_bytes)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse high four bytes for "
<< (tag==CONSTANT_Long?"CONSTANT_Integer":"CONSTANT_Float") << " entry");
return false;
}
- if(!cfs.parse_u4_be(&clss->const_pool[i].CONSTANT_8byte.low_bytes)) {
+ if(!cfs.parse_u4_be(&m_entries[i].CONSTANT_8byte.low_bytes)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse low four bytes for "
<< (tag==CONSTANT_Long?"CONSTANT_Long":"CONSTANT_Double") << " entry");
@@ -1952,13 +1953,13 @@ static bool class_parse_const_pool(Class
break;
case CONSTANT_NameAndType:
- if(!cfs.parse_u2_be(&clss->const_pool[i].CONSTANT_NameAndType.name_index)) {
+ if(!cfs.parse_u2_be(&m_entries[i].CONSTANT_NameAndType.name_index)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse name index "
"for CONSTANT_NameAndType entry");
return false;
}
- if(!cfs.parse_u2_be(&clss->const_pool[i].CONSTANT_NameAndType.descriptor_index)) {
+ if(!cfs.parse_u2_be(&m_entries[i].CONSTANT_NameAndType.descriptor_index)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse descriptor index "
"for CONSTANT_NameAndType entry");
@@ -1969,13 +1970,13 @@ static bool class_parse_const_pool(Class
case CONSTANT_Utf8:
{
// parse and insert string into string table
- String* str = const_pool_parse_utf8(string_pool, cfs);
+ String* str = class_file_parse_utf8(string_pool, cfs);
if(!str) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": could not parse CONTANT_Utf8 entry");
return false;
}
- clss->const_pool[i].CONSTANT_Utf8.string = str;
+ m_entries[i].CONSTANT_Utf8.string = str;
}
break;
default:
@@ -1985,36 +1986,18 @@ static bool class_parse_const_pool(Class
}
}
return true;
-} //class_parse_const_pool
+} // ConstantPool::parse
-//
-// check consistency of constant pool
-//
-// make sure all indices to other constant pool entries are in range
-// make sure contents of constant pool entries are of the right type
-//
-// Set CONSTANT_Class entries to point directly to String representing
-// internal form of fully qualified name of Class.
-//
-// Set CONSTANT_String entries to point directly to String representation
-// of String.
-//
-// Peresolve CONSTANT_NameAndType entries to signature
-//
-static bool check_const_pool(Class* clss,
- Const_Pool *cp,
- unsigned cp_size)
+bool ConstantPool::check(Class* clss)
{
- unsigned char *cp_tags = cp[0].tags;
- for (unsigned i=1; i= cp_size ||
- cp_tag(cp,name_index) != CONSTANT_Utf8) {
+ unsigned name_index = get_class_name_index(i);
+ if (!is_valid_index(name_index) || !is_utf8(name_index)) {
// illegal name index
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": wrong name index for CONSTANT_Class entry");
@@ -2026,16 +2009,14 @@ static bool check_const_pool(Class* clss
case CONSTANT_Fieldref:
case CONSTANT_InterfaceMethodref:
{
- unsigned class_index = cp[i].CONSTANT_ref.class_index;
- unsigned name_type_index = cp[i].CONSTANT_ref.name_and_type_index;
- if (class_index >= cp_size ||
- cp_tag(cp,class_index) != CONSTANT_Class) {
+ unsigned class_index = get_ref_class_index(i);
+ unsigned name_type_index = get_ref_name_and_type_index(i);
+ if (!is_valid_index(class_index) || !is_class(class_index)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": wrong class index for CONSTANT_*ref entry");
return false;
}
- if (name_type_index >= cp_size ||
- cp_tag(cp,name_type_index) != CONSTANT_NameAndType) {
+ if (!is_valid_index(name_type_index) || !is_name_and_type(name_type_index)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": wrong name-and-type index for CONSTANT_*ref entry");
return false;
@@ -2044,16 +2025,15 @@ static bool check_const_pool(Class* clss
}
case CONSTANT_String:
{
- unsigned string_index = cp[i].CONSTANT_String.string_index;
- if (string_index >= cp_size ||
- cp_tag(cp,string_index) != CONSTANT_Utf8) {
+ unsigned string_index = get_string_index(i);
+ if (!is_valid_index(string_index) || !is_utf8(string_index)) {
// illegal string index
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": wrong string index for CONSTANT_String entry");
return false;
}
// set entry to the actual string
- cp[i].CONSTANT_String.string = cp[string_index].CONSTANT_Utf8.string;
+ resolve_entry(i, get_utf8_string(string_index));
break;
}
case CONSTANT_Integer:
@@ -2064,23 +2044,19 @@ static bool check_const_pool(Class* clss
break;
case CONSTANT_NameAndType:
{
- unsigned name_index = cp[i].CONSTANT_NameAndType.name_index;
- unsigned descriptor_index = cp[i].CONSTANT_NameAndType.descriptor_index;
- if (name_index >= cp_size ||
- cp_tag(cp,name_index) != CONSTANT_Utf8) {
+ unsigned name_index = get_name_and_type_name_index(i);
+ unsigned descriptor_index = get_name_and_type_descriptor_index(i);
+ if(!is_valid_index(name_index) || !is_utf8(name_index)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": wrong name index for CONSTANT_NameAndType entry");
return false;
}
- if (descriptor_index >= cp_size ||
- cp_tag(cp,descriptor_index) != CONSTANT_Utf8) {
+ if (!is_valid_index(descriptor_index) || !is_utf8(descriptor_index)) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": wrong descriptor index for CONSTANT_NameAndType entry");
return false;
}
- cp[i].CONSTANT_NameAndType.name = cp[name_index].CONSTANT_Utf8.string;
- cp[i].CONSTANT_NameAndType.descriptor = cp[descriptor_index].CONSTANT_Utf8.string;
- cp_set_resolved(cp,i);
+ resolve_entry(i, get_utf8_string(name_index), get_utf8_string(descriptor_index));
break;
}
case CONSTANT_Utf8:
@@ -2088,12 +2064,12 @@ static bool check_const_pool(Class* clss
break;
default:
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
- clss->name->bytes << ": wrong constant pool tag");
+ clss->name->bytes << ": wrong constant pool tag " << get_tag(i));
return false;
}
}
return true;
-} //check_const_pool
+} // ConstantPool::check
static bool class_parse_interfaces(Class *clss, ByteReader &cfs)
@@ -2117,7 +2093,7 @@ static bool class_parse_interfaces(Class
//
// verify that entry in constant pool is of type CONSTANT_Class
//
- clss->superinterfaces[i].name = cp_check_class(clss->const_pool,clss->cp_size,interface_index);
+ clss->superinterfaces[i].name = cp_check_class(clss->m_const_pool, interface_index);
if (clss->superinterfaces[i].name == NULL) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": constant pool index " << i << " is not CONSTANT_Class entry"
@@ -2202,14 +2178,13 @@ bool class_parse(Global_Env* env,
/*
* allocate and parse constant pool
*/
- if (!class_parse_const_pool(clss, env->string_pool, cfs)) {
+ if(!clss->m_const_pool.parse(clss, env->string_pool, cfs))
return false;
- }
/*
* check and preprocess the constant pool
*/
- if (!check_const_pool(clss, clss->const_pool, clss->cp_size))
+ if(!clss->m_const_pool.check(clss))
return false;
if(!cfs.parse_u2_be(&clss->access_flags)) {
@@ -2236,7 +2211,7 @@ bool class_parse(Global_Env* env,
return false;
}
- String *name = cp_check_class(clss->const_pool, clss->cp_size, this_class);
+ String *name = cp_check_class(clss->m_const_pool, this_class);
if (name == NULL) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": this_class constant pool entry "
@@ -2262,7 +2237,7 @@ bool class_parse(Global_Env* env,
/*
* Mark the current class as resolved.
*/
- cp_resolve_to_class(clss->const_pool, this_class, clss);
+ clss->m_const_pool.resolve_entry(this_class, clss);
/*
* parse the super class name
@@ -2288,7 +2263,7 @@ bool class_parse(Global_Env* env,
}
clss->super_name = NULL;
} else {
- clss->super_name = cp_check_class(clss->const_pool, clss->cp_size, super_class);
+ clss->super_name = cp_check_class(clss->m_const_pool, super_class);
if (clss->super_name == NULL) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": super_class constant pool entry "
@@ -2332,7 +2307,7 @@ bool class_parse(Global_Env* env,
uint32 attr_len = 0;
for (unsigned i=0; iconst_pool, clss->cp_size, class_attr_strings, class_attrs, &attr_len);
+ Attributes cur_attr = parse_attribute(cfs, clss->m_const_pool, class_attr_strings, class_attrs, &attr_len);
switch(cur_attr){
case ATTR_SourceFile:
{
@@ -2360,7 +2335,7 @@ bool class_parse(Global_Env* env,
return false;
}
- clss->src_file_name = cp_check_utf8(clss->const_pool,clss->cp_size,filename_index);
+ clss->src_file_name = cp_check_utf8(clss->m_const_pool, filename_index);
if (clss->src_file_name == NULL) {
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": filename index points to incorrect constant pool entry"
@@ -2411,7 +2386,7 @@ bool class_parse(Global_Env* env,
return false;
}
if(inner_clss_info_idx
- && cp_tag(clss->const_pool,inner_clss_info_idx) != CONSTANT_Class)
+ && !valid_cpi(clss, inner_clss_info_idx, CONSTANT_Class))
{
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": inner class info index points to incorrect constant pool entry"
@@ -2420,7 +2395,7 @@ bool class_parse(Global_Env* env,
}
if(!found_myself){
- String *clssname = cp_check_class(clss->const_pool, clss->cp_size, inner_clss_info_idx);
+ String* clssname = cp_check_class(clss->m_const_pool, inner_clss_info_idx);
// Only handle this class
if(clss->name == clssname)
found_myself = 1;
@@ -2436,11 +2411,11 @@ bool class_parse(Global_Env* env,
return false;
}
if(outer_clss_info_idx
- && cp_tag(clss->const_pool,outer_clss_info_idx) != CONSTANT_Class)
+ && !valid_cpi(clss, outer_clss_info_idx, CONSTANT_Class))
{
REPORT_FAILED_CLASS_CLASS(clss->class_loader, clss, "java/lang/ClassFormatError",
clss->name->bytes << ": outer class info index points to incorrect constant pool entry"
- << " while parsing InnerClasses attribute");
+ << outer_clss_info_idx << " while parsing InnerClasses attribute");
return false;
}
if(found_myself == 1 && outer_clss_info_idx){
@@ -2462,7 +2437,7 @@ bool class_parse(Global_Env* env,
}
if(found_myself == 1 /*&& outer_clss_info_idx*/){
if (inner_name_idx) {
- clss->simple_name = clss->const_pool[inner_name_idx].CONSTANT_Utf8.string;
+ clss->simple_name = clss->m_const_pool.get_utf8_string(inner_name_idx);
} else {
//anonymous class
clss->simple_name = env->string_pool.lookup("");
@@ -2497,7 +2472,7 @@ bool class_parse(Global_Env* env,
// cfs is at debug_extension[] which is:
// The debug_extension array holds a string, which must be in UTF-8 format.
// There is no terminating zero byte.
- clss->sourceDebugExtension = const_pool_parse_utf8data(env->string_pool, cfs, attr_len);
+ clss->sourceDebugExtension = class_file_parse_utf8data(env->string_pool, cfs, attr_len);
if (!clss->sourceDebugExtension) {
REPORT_FAILED_CLASS_FORMAT(clss, "invalid SourceDebugExtension attribute");
return false;
@@ -2811,7 +2786,7 @@ const String* class_extract_name(Global_
if(!cfs.parse_u1(&tag) && tag != CONSTANT_Utf8)
return NULL;
// parse class name
- const String* class_name = const_pool_parse_utf8(env->string_pool, cfs);
+ const String* class_name = class_file_parse_utf8(env->string_pool, cfs);
return class_name;
}
@@ -2909,7 +2884,7 @@ unsigned class_calculate_size(const Clas
unsigned size = 0;
size += sizeof(Class);
size += klass->n_innerclasses*sizeof(uint16);
- size += klass->cp_size*sizeof(Const_Pool);
+ size += klass->m_const_pool.get_size()*sizeof(ConstPoolEntry);
for(unsigned i = 0; i < klass->n_fields; i++) {
size += klass->fields[i].calculate_size();
}
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Resolve.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Resolve.cpp
index c167b5c..5757126 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Resolve.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Resolve.cpp
@@ -19,8 +19,6 @@
* @version $Revision: 1.1.2.6.4.5 $
*/
-
-
//
// exceptions that can be thrown during class resolution:
//
@@ -134,27 +132,25 @@ static Class* _resolve_class(Global_Env
unsigned cp_index)
{
assert(hythread_is_suspend_enabled());
- Const_Pool *cp = clss->const_pool;
+ ConstantPool& cp = clss->m_const_pool;
clss->m_lock->_lock();
- if(cp_in_error(cp, cp_index)) {
+ if(cp.is_entry_in_error(cp_index)) {
TRACE2("resolve:testing", "Constant pool entry " << cp_index << " already contains error.");
clss->m_lock->_unlock();
return NULL;
}
- if(cp_is_resolved(cp, cp_index)) {
+ if(cp.is_entry_resolved(cp_index)) {
clss->m_lock->_unlock();
- return cp[cp_index].CONSTANT_Class.klass;
+ return cp.get_class_class(cp_index);
}
- String *classname = cp[cp[cp_index].CONSTANT_Class.name_index].CONSTANT_Utf8.string;
+ const String* classname = cp.get_utf8_string(cp.get_class_name_index(cp_index));
clss->m_lock->_unlock();
// load the class in
- Class *other_clss;
-
- other_clss = clss->class_loader->LoadVerifyAndPrepareClass(env, classname);
+ Class* other_clss = clss->class_loader->LoadVerifyAndPrepareClass(env, classname);
if(other_clss == NULL)
{
jthrowable exn = class_get_error(clss->class_loader, classname->bytes);
@@ -179,7 +175,7 @@ static Class* _resolve_class(Global_Env
|| clss->is_not_verified)
{
clss->m_lock->_lock();
- cp_resolve_to_class(cp, cp_index, other_clss);
+ cp.resolve_entry(cp_index, other_clss);
clss->m_lock->_unlock();
return other_clss;
}
@@ -190,7 +186,7 @@ static Class* _resolve_class(Global_Env
&& check_inner_class_access(env, other_clss, clss))
{
clss->m_lock->_lock();
- cp_resolve_to_class(cp, cp_index, other_clss);
+ cp.resolve_entry(cp_index, other_clss);
clss->m_lock->_unlock();
return other_clss;
}
@@ -392,44 +388,42 @@ check_inner_class_access(Global_Env *env
*/
static Field* _resolve_field(Global_Env *env, Class *clss, unsigned cp_index)
{
- Const_Pool *cp = clss->const_pool;
+ ConstantPool& cp = clss->m_const_pool;
clss->m_lock->_lock();
- if(cp_in_error(cp, cp_index)) {
+ if(cp.is_entry_in_error(cp_index)) {
TRACE2("resolve.testing", "Constant pool entry " << cp_index << " already contains error.");
clss->m_lock->_unlock();
return NULL;
}
- if (cp_is_resolved(cp, cp_index)) {
+ if (cp.is_entry_resolved(cp_index)) {
clss->m_lock->_unlock();
- return cp[cp_index].CONSTANT_ref.field;
+ return cp.get_ref_field(cp_index);
}
//
// constant pool entry hasn't been resolved yet
//
- unsigned other_index = cp[cp_index].CONSTANT_ref.class_index;
+ unsigned other_index = cp.get_ref_class_index(cp_index);
clss->m_lock->_unlock();
//
// check error condition from resolve class
//
- Class *other_clss = _resolve_class(env, clss, other_index);
+ Class* other_clss = _resolve_class(env, clss, other_index);
if(!other_clss) {
- if(cp_in_error(clss->const_pool, other_index)) {
- class_report_failure(clss, cp_index,
- (jthrowable)(&(clss->const_pool[other_index].error.cause)));
+ if(cp.is_entry_in_error(other_index)) {
+ class_report_failure(clss, cp_index,
+ cp.get_error_cause(other_index));
} else {
assert(exn_raised());
}
return NULL;
}
- String* name = cp[cp[cp_index].CONSTANT_ref.name_and_type_index]
- .CONSTANT_NameAndType.name;
- String* desc = cp[cp[cp_index].CONSTANT_ref.name_and_type_index]
- .CONSTANT_NameAndType.descriptor;
-
+ uint16 name_and_type_index = cp.get_ref_name_and_type_index(cp_index);
+ String* name = cp.get_name_and_type_name(name_and_type_index);
+ String* desc = cp.get_name_and_type_descriptor(name_and_type_index);
Field* field = class_lookup_field_recursive(other_clss, name, desc);
if (field == NULL)
{
@@ -460,7 +454,7 @@ static Field* _resolve_field(Global_Env
return NULL;
}
clss->m_lock->_lock();
- cp_resolve_to_field(cp, cp_index, field);
+ cp.resolve_entry(cp_index, field);
clss->m_lock->_unlock();
return field;
@@ -538,24 +532,24 @@ static Field* _resolve_nonstatic_field(G
*/
static Method* _resolve_method(Global_Env *env, Class *clss, unsigned cp_index)
{
- Const_Pool *cp = clss->const_pool;
+ ConstantPool& cp = clss->m_const_pool;
clss->m_lock->_lock();
- if(cp_in_error(cp, cp_index)) {
+ if(cp.is_entry_in_error(cp_index)) {
TRACE2("resolve:testing", "Constant pool entry " << cp_index << " already contains error.");
clss->m_lock->_unlock();
return NULL;
}
- if (cp_is_resolved(cp,cp_index)) {
+ if (cp.is_entry_resolved(cp_index)) {
clss->m_lock->_unlock();
- return cp[cp_index].CONSTANT_ref.method;
+ return cp.get_ref_method(cp_index);
}
//
// constant pool entry hasn't been resolved yet
//
unsigned other_index;
- other_index = cp[cp_index].CONSTANT_ref.class_index;
+ other_index = cp.get_ref_class_index(cp_index);
clss->m_lock->_unlock();
//
@@ -563,24 +557,22 @@ static Method* _resolve_method(Global_En
//
Class *other_clss = _resolve_class(env, clss, other_index);
if(!other_clss) {
- if(cp_in_error(clss->const_pool, other_index)) {
+ if(cp.is_entry_in_error(other_index)) {
class_report_failure(clss, cp_index,
- (jthrowable)(&(clss->const_pool[other_index].error.cause)));
+ cp.get_error_cause(other_index));
} else {
assert(exn_raised());
}
return NULL;
}
- String* name = cp[cp[cp_index].CONSTANT_ref.name_and_type_index].
- CONSTANT_NameAndType.name;
-
- String* desc = cp[cp[cp_index].CONSTANT_ref.name_and_type_index].
- CONSTANT_NameAndType.descriptor;
+ uint16 name_and_type_index = cp.get_ref_name_and_type_index(cp_index);
+ String* name = cp.get_name_and_type_name(name_and_type_index);
+ String* desc = cp.get_name_and_type_descriptor(name_and_type_index);
// CONSTANT_Methodref must refer to a class, not an interface, and
// CONSTANT_InterfaceMethodref must refer to an interface (vm spec 4.4.2)
- if (cp_is_methodref(cp, cp_index) && class_is_interface(other_clss)) {
+ if(cp.is_methodref(cp_index) && class_is_interface(other_clss)) {
CLASS_REPORT_FAILURE(clss, cp_index, "java/lang/IncompatibleClassChangeError",
other_clss->name->bytes
<< " while resolving constant pool entry " << cp_index
@@ -588,7 +580,7 @@ static Method* _resolve_method(Global_En
return NULL;
}
- if(cp_is_interfacemethodref(cp, cp_index) && !class_is_interface(other_clss)) {
+ if(cp.is_interfacemethodref(cp_index) && !class_is_interface(other_clss)) {
CLASS_REPORT_FAILURE(clss, cp_index, "java/lang/IncompatibleClassChangeError",
other_clss->name->bytes
<< " while resolving constant pool entry " << cp_index
@@ -628,7 +620,7 @@ static Method* _resolve_method(Global_En
}
clss->m_lock->_lock();
- cp_resolve_to_method(cp,cp_index,method);
+ cp.resolve_entry(cp_index, method);
clss->m_lock->_unlock();
return method;
@@ -771,9 +763,10 @@ static bool method_can_link_special(Clas
{
ASSERT_RAISE_AREA;
- unsigned class_idx = clss->const_pool[index].CONSTANT_ref.class_index;
- unsigned class_name_idx = clss->const_pool[class_idx].CONSTANT_Class.name_index;
- String* ref_class_name = clss->const_pool[class_name_idx].CONSTANT_String.string;
+ ConstantPool& cp = clss->m_const_pool;
+ unsigned class_idx = cp.get_ref_class_index(index);
+ unsigned class_name_idx = cp.get_class_name_index(class_idx);
+ String* ref_class_name = cp.get_utf8_string(class_name_idx);
if(method->get_name() == VM_Global_State::loader_env->Init_String
&& method->get_class()->name != ref_class_name)
@@ -918,46 +911,46 @@ void class_throw_linking_error(Class_Han
{
ASSERT_RAISE_AREA;
- Const_Pool* cp = ch->const_pool;
- if(cp_in_error(cp, index)) {
- exn_raise_object((jthrowable)(&(cp[index].error.cause)));
+ ConstantPool& cp = ch->m_const_pool;
+ if(cp.is_entry_in_error(index)) {
+ exn_raise_object(cp.get_error_cause(index));
return; // will return in interpreter mode
}
switch(opcode) {
case OPCODE_NEW:
- class_can_instantiate(cp[index].CONSTANT_Class.klass, LINK_THROW_ERRORS);
+ class_can_instantiate(cp.get_class_class(index), LINK_THROW_ERRORS);
break;
case OPCODE_PUTFIELD:
- field_can_link(ch, cp[index].CONSTANT_ref.field,
+ field_can_link(ch, cp.get_ref_field(index),
CAN_LINK_FROM_FIELD, LINK_WRITE_ACCESS, LINK_THROW_ERRORS);
break;
case OPCODE_GETFIELD:
- field_can_link(ch, cp[index].CONSTANT_ref.field,
+ field_can_link(ch, cp.get_ref_field(index),
CAN_LINK_FROM_FIELD, LINK_READ_ACCESS, LINK_THROW_ERRORS);
break;
case OPCODE_PUTSTATIC:
- field_can_link(ch, cp[index].CONSTANT_ref.field,
+ field_can_link(ch, cp.get_ref_field(index),
CAN_LINK_FROM_STATIC, LINK_WRITE_ACCESS, LINK_THROW_ERRORS);
break;
case OPCODE_GETSTATIC:
- field_can_link(ch, cp[index].CONSTANT_ref.field,
+ field_can_link(ch, cp.get_ref_field(index),
CAN_LINK_FROM_STATIC, LINK_READ_ACCESS, LINK_THROW_ERRORS);
break;
case OPCODE_INVOKEINTERFACE:
- method_can_link_interface(ch, index, cp[index].CONSTANT_ref.method,
+ method_can_link_interface(ch, index, cp.get_ref_method(index),
LINK_THROW_ERRORS);
break;
case OPCODE_INVOKESPECIAL:
- method_can_link_special(ch, index, cp[index].CONSTANT_ref.method,
+ method_can_link_special(ch, index, cp.get_ref_method(index),
LINK_THROW_ERRORS);
break;
case OPCODE_INVOKESTATIC:
- method_can_link_static(ch, index, cp[index].CONSTANT_ref.method,
+ method_can_link_static(ch, index, cp.get_ref_method(index),
LINK_THROW_ERRORS);
break;
case OPCODE_INVOKEVIRTUAL:
- method_can_link_virtual(ch, index, cp[index].CONSTANT_ref.method,
+ method_can_link_virtual(ch, index, cp.get_ref_method(index),
LINK_THROW_ERRORS);
break;
default:
@@ -1023,16 +1016,14 @@ Class_Handle class_get_array_of_class(Cl
} //class_get_array_of_class
-static bool resolve_const_pool_item(Global_Env *env, Class *clss, unsigned cp_index)
+static bool resolve_const_pool_item(Global_Env* env, Class* clss, unsigned cp_index)
{
- Const_Pool *cp = clss->const_pool;
- unsigned char *cp_tags = cp[0].tags;
+ ConstantPool& cp = clss->m_const_pool;
- if (cp_is_resolved(cp, cp_index)) {
+ if(cp.is_entry_resolved(cp_index))
return true;
- }
- switch (cp_tags[cp_index]) {
+ switch(cp.get_tag(cp_index)) {
case CONSTANT_Class:
return _resolve_class(env, clss, cp_index);
case CONSTANT_Fieldref:
@@ -1060,12 +1051,12 @@ static bool resolve_const_pool_item(Glob
* Resolve whole constant pool
*/
unsigned resolve_const_pool(Global_Env& env, Class *clss) {
- Const_Pool *cp = clss->const_pool;
+ ConstantPool& cp = clss->m_const_pool;
// It's possible that cp is null when defining class on the fly
- if (!cp) return true;
- unsigned cp_size = clss->cp_size;
+ if(!cp.available()) return true;
+ unsigned cp_size = cp.get_size();
for (unsigned i = 1; i < cp_size; i++) {
if(!resolve_const_pool_item(&env, clss, i)) {
return i;
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/class_impl.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/class_impl.cpp
index 1e44d49..ea2ddb6 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/class_impl.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/class_impl.cpp
@@ -203,9 +203,9 @@ class_get_method( class_handler klass, u
unsigned short
class_get_cp_size( class_handler klass )
{
- assert( klass );
- Class *clss = (Class*)klass;
- return clss->cp_size;
+ assert(klass);
+ Class* clss = (Class*)klass;
+ return clss->m_const_pool.get_size();
} // class_get_cp_size
/**
@@ -215,9 +215,9 @@ unsigned char
class_get_cp_tag( class_handler klass, unsigned short index )
{
assert( klass );
- Class *clss = (Class*)klass;
- assert( index < clss->cp_size );
- return (unsigned char)cp_tag( clss->const_pool, index );
+ Class* clss = (Class*)klass;
+ assert( index < clss->m_const_pool.get_size() );
+ return clss->m_const_pool.get_tag(index);
} // class_get_cp_tag
/**
@@ -227,10 +227,8 @@ unsigned short
class_get_cp_class_name_index( class_handler klass, unsigned short index )
{
assert( klass );
- Class *clss = (Class*)klass;
- assert( index < clss->cp_size );
- assert( cp_is_class( clss->const_pool, index ) );
- return clss->const_pool[index].CONSTANT_Class.name_index;
+ Class* clss = (Class*)klass;
+ return clss->m_const_pool.get_class_name_index(index);
} // class_get_cp_class_name_index
/**
@@ -241,11 +239,7 @@ class_get_cp_ref_class_index( class_hand
{
assert( klass );
Class *clss = (Class*)klass;
- assert( index < clss->cp_size );
- assert( cp_is_fieldref( clss->const_pool, index )
- || cp_is_methodref( clss->const_pool, index )
- || cp_is_interfacemethodref( clss->const_pool, index ) );
- return clss->const_pool[index].CONSTANT_ref.class_index;
+ return clss->m_const_pool.get_ref_class_index(index);
} // class_get_cp_ref_class_index
/**
@@ -256,24 +250,18 @@ class_get_cp_ref_name_and_type_index( cl
{
assert( klass );
Class *clss = (Class*)klass;
- assert( index < clss->cp_size );
- assert( cp_is_fieldref( clss->const_pool, index )
- || cp_is_methodref( clss->const_pool, index )
- || cp_is_interfacemethodref( clss->const_pool, index ) );
- return clss->const_pool[index].CONSTANT_ref.name_and_type_index;
+ return clss->m_const_pool.get_ref_name_and_type_index(index);
} // class_get_cp_ref_name_and_type_index
/**
* Function returns string entry index in constant pool.
*/
unsigned short
-class_get_cp_string_index( class_handler klass, unsigned short index )
+class_get_cp_string_index(class_handler klass, unsigned short index)
{
- assert( klass );
- Class *clss = (Class*)klass;
- assert( index < clss->cp_size );
- assert( cp_is_string( clss->const_pool, index ) );
- return clss->const_pool[index].CONSTANT_String.string_index;
+ assert(klass);
+ Class* clss = (Class*)klass;
+ return clss->m_const_pool.get_string_index(index);
} // class_get_cp_string_index
/**
@@ -283,10 +271,8 @@ unsigned short
class_get_cp_name_index( class_handler klass, unsigned short index )
{
assert( klass );
- Class *clss = (Class*)klass;
- assert( index < clss->cp_size );
- assert( cp_tag( clss->const_pool, index ) == CONSTANT_NameAndType );
- return clss->const_pool[index].CONSTANT_NameAndType.name_index;
+ Class* clss = (Class*)klass;
+ return clss->m_const_pool.get_name_and_type_name_index(index);
} // class_get_cp_name_index
/**
@@ -296,23 +282,19 @@ unsigned short
class_get_cp_descriptor_index( class_handler klass, unsigned short index )
{
assert( klass );
- Class *clss = (Class*)klass;
- assert( index < clss->cp_size );
- assert( cp_tag( clss->const_pool, index ) == CONSTANT_NameAndType );
- return clss->const_pool[index].CONSTANT_NameAndType.descriptor_index;
+ Class* clss = (Class*)klass;
+ return clss->m_const_pool.get_name_and_type_descriptor_index(index);
} // class_get_cp_descriptor_index
/**
* Function returns bytes for UTF8 constant pool entry.
*/
-const char *
+const char*
class_get_cp_utf8_bytes( class_handler klass, unsigned short index )
{
assert( klass );
- Class *clss = (Class*)klass;
- assert( index < clss->cp_size );
- assert( cp_tag( clss->const_pool, index ) == CONSTANT_Utf8 );
- return clss->const_pool[index].CONSTANT_Utf8.string->bytes;
+ Class* clss = (Class*)klass;
+ return clss->m_const_pool.get_utf8_chars(index);
} // class_get_cp_utf8_bytes
/**
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp
index 18c7498..81a9187 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp
@@ -479,8 +479,8 @@ bool ClassLoader::FinishLoadingClass(Glo
// super class was successfully loaded
clss->super_class = superClass;
- if( super_class_cp_index && *super_class_cp_index ) {
- cp_resolve_to_class( clss->const_pool, *super_class_cp_index, superClass );
+ if(super_class_cp_index && *super_class_cp_index) {
+ clss->m_const_pool.resolve_entry(*super_class_cp_index, superClass);
}
// if it's an interface, its superclass must be java/lang/Object
@@ -1150,6 +1150,9 @@ #endif
clss->id = class_next_id++;
clss->name = name;
clss->class_loader = this;
+
+ clss->m_const_pool.init();
+
clss->state = ST_Start;
clss->m_lock = new Lock_Manager();
@@ -1174,13 +1177,7 @@ void ClassLoader::ClassClearInternals(Cl
delete []clss->methods;
clss->methods = NULL;
}
- if (clss->const_pool != NULL)
- {
- if (clss->const_pool[0].tags)
- delete []clss->const_pool[0].tags;
- delete []clss->const_pool;
- clss->const_pool = NULL;
- }
+ clss->m_const_pool.clear();
if (clss->vtable_descriptors)
delete []clss->vtable_descriptors;
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 857e37d..38bf941 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp
@@ -31,6 +31,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 8e7452a..93f62d3 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
@@ -29,6 +29,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 55254e4..f8c53eb 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp
@@ -34,6 +34,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 3b5027a..4ea2e8f 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
@@ -42,6 +42,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 4809bfc..a4b21ea 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/gc/dll_gc.cpp
@@ -19,8 +19,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 e7f7f97..a7d7fb9 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
@@ -30,6 +30,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()
@@ -87,7 +88,7 @@ vm_enumerate_static_fields()
(void**)&c->p_error ,FALSE);
}
vm_enumerate_root_reference((void**)ppc, FALSE);
- Const_Pool* cp = c->m_failedResolution;
+ ConstPoolEntry* cp = c->m_const_pool.get_error_chain();
while(cp) {
vm_enumerate_root_reference((void**)(&(cp->error.cause)), FALSE);
cp = cp->error.next;
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/init/vm.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/init/vm.cpp
index 87b313c..c1cf2ac 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/init/vm.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/init/vm.cpp
@@ -121,8 +121,9 @@ Class *class_resolve_class(Class *clss,
// a constant of type Class, String, Integer, Float, Long or Double.
Java_Type class_get_cp_const_type(Class *clss, unsigned cp_index)
{
- Const_Pool *cp = clss->const_pool;
- switch(cp_tag(cp, cp_index)) {
+ ConstantPool& cp = clss->m_const_pool;
+ assert(cp.is_constant(cp_index));
+ switch(cp.get_tag(cp_index)) {
case CONSTANT_String:
return JAVA_TYPE_STRING;
case CONSTANT_Integer:
@@ -136,7 +137,7 @@ Java_Type class_get_cp_const_type(Class
case CONSTANT_Class:
return JAVA_TYPE_CLASS;
default:
- DIE("non-constant type is requested from constant pool : " << cp_tag(cp, cp_index));
+ DIE("non-constant type is requested from constant pool : " << cp.get_tag(cp_index));
}
return JAVA_TYPE_INVALID;
} //class_get_cp_const_type
@@ -144,13 +145,10 @@ Java_Type class_get_cp_const_type(Class
// Returns an address of an int, float, etc.
-// For a string it returns a pointer to the utf8 representation of the string.
-const void *class_get_addr_of_constant(Class *clss, unsigned cp_index)
+const void* class_get_addr_of_constant(Class* clss, unsigned cp_index)
{
- Const_Pool *cp = clss->const_pool;
- assert(cp_tag(cp, cp_index) != CONSTANT_String);
-
- return (void *)(cp + cp_index);
+ ConstantPool& cp = clss->m_const_pool;
+ return cp.get_address_of_constant(cp_index);
} //class_get_addr_of_constant
/////////////////////////////////////////////////////////////////
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp
index e6505af..709f1c0 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jit/compile.cpp
@@ -38,6 +38,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"
@@ -75,7 +76,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;
@@ -86,7 +86,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;
@@ -96,35 +95,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.
@@ -179,10 +180,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);
@@ -195,7 +196,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);
@@ -206,7 +207,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);
@@ -217,7 +218,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();
@@ -225,12 +226,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);
@@ -238,11 +239,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/jit/jit_runtime_support.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jit/jit_runtime_support.cpp
index db96a68..78865c3 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jit/jit_runtime_support.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jit/jit_runtime_support.cpp
@@ -71,6 +71,9 @@ #include "vm_stats.h"
#define OFFSET(Struct, Field) \
((POINTER_SIZE_SINT) (&(((Struct *) NULL)->Field) - NULL))
+#define OFFSET_INST(inst_ptr, Field) \
+ ((POINTER_SIZE_SINT) ((char*)inst_ptr->Field - (char*)inst_ptr))
+
// macro that gets the size of a field within a struct or class
#define SIZE(Struct, Field) \
(sizeof(((Struct *) NULL)->Field))
@@ -157,12 +160,12 @@ static NativeCodePtr rth_get_lil_multian
static ManagedObject * rth_ldc_ref_helper(Class *c, unsigned cp_index)
{
ASSERT_THROW_AREA;
- Const_Pool *cp = c->const_pool;
- if (cp_is_string(cp, cp_index))
+ ConstantPool& cp = c->m_const_pool;
+ if (cp.is_string(cp_index))
{
return vm_instantiate_cp_string_slow(c, cp_index);
}
- else if (cp_is_class(cp, cp_index))
+ else if (cp.is_class(cp_index))
{
assert(!hythread_is_suspend_enabled());
hythread_suspend_enable();
@@ -263,8 +266,9 @@ static LilCodeStub* rth_gen_lil_type_tes
}
// Fast sequence
- const POINTER_SIZE_INT is_fast_off = (POINTER_SIZE_INT)&((Class*)NULL)->is_suitable_for_fast_instanceof;
- const POINTER_SIZE_INT depth_off = (POINTER_SIZE_INT)&((Class*)NULL)->depth;
+ Class* dummy = NULL;
+ const POINTER_SIZE_INT is_fast_off = OFFSET_INST(dummy, is_suitable_for_fast_instanceof);
+ const POINTER_SIZE_INT depth_off = OFFSET_INST(dummy, depth);
const POINTER_SIZE_INT supertable_off = (POINTER_SIZE_INT)&((VTable*)NULL)->superclasses;
bool do_slow = true;
if (type) {
@@ -2410,12 +2414,13 @@ static LilCodeStub* gen_lil_typecheck_fa
object_get_vtable_offset());
}
+ Class* dummy = NULL;
cs2 = lil_parse_onto_end
(cs2,
"ld l1, [i1 + %0i: g4],zx;"
"ld l2, [l0 + %1i*l1 + %2i: pint];"
"jc i1 != l2, failed;",
- OFFSET(Class, depth),
+ OFFSET_INST(dummy, depth),
sizeof(Class*),
OFFSET(VTable, superclasses) - sizeof(Class*) + (vm_vtable_pointers_are_compressed() ? vm_get_vtable_base() : 0)
);
@@ -2483,6 +2488,7 @@ LilCodeStub *gen_lil_typecheck_stub(bool
Class::managed_null);
}
+ Class* dummy = NULL;
// check whether the fast or the slow path is appropriate
cs = lil_parse_onto_end
(cs,
@@ -2491,7 +2497,7 @@ LilCodeStub *gen_lil_typecheck_stub(bool
// check if super->is_suitable_for_fast_instanceof
"ld l0, [i1 + %0i: g4];"
"jc l0!=0:g4, fast;",
- OFFSET(Class, is_suitable_for_fast_instanceof));
+ OFFSET_INST(dummy, is_suitable_for_fast_instanceof));
// append the slow path right here
cs = gen_lil_typecheck_slowpath(cs, is_checkcast);
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 e7879aa..2c210d6 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp
@@ -28,6 +28,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_break_intf.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
index 8770425..6be7160 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break_intf.cpp
@@ -34,6 +34,8 @@ #include "exceptions.h"
#include "m2n.h"
#include "stack_iterator.h"
#include "open/bytecodes.h"
+#include "cci.h"
+
#include "jvmti_break_intf.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 85f194b..28fe55a 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
@@ -36,6 +36,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"
#include "stack_iterator.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 50a1b5c..3e8137a 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_locals.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_locals.cpp
@@ -36,6 +36,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 8b60f41..5fa263c 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
@@ -32,6 +32,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 ae9e0cd..c7a002a 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_stack.cpp
@@ -36,6 +36,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 d29ef32..64ef735 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp
@@ -28,6 +28,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"
@@ -316,13 +317,13 @@ jvmti_SingleStepLocation( VM_thread* thr
{
unsigned short index = jvmti_GetHalfWordValue( bytecode, location + 1 );
Class *klass = method_get_class( method );
- assert( cp_is_resolved(klass->const_pool, index) );
+ assert(klass->m_const_pool.is_entry_resolved(index));
- if( !method_is_native( klass->const_pool[index].CONSTANT_ref.method ) ) {
+ if(!method_is_native(klass->m_const_pool.get_ref_method(index))) {
*count = 1;
error = _allocate( sizeof(jvmti_StepLocation), (unsigned char**)next_step );
assert( error == JVMTI_ERROR_NONE );
- (*next_step)->method = klass->const_pool[index].CONSTANT_ref.method;
+ (*next_step)->method = klass->m_const_pool.get_ref_method(index);
(*next_step)->location = 0;
(*next_step)->native_location = NULL;
(*next_step)->no_event = false;
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 e229bd0..943d408 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_thread.cpp
@@ -42,6 +42,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 abf039b..190fc95 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
@@ -29,6 +29,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_VMClassRegistry.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp
index 60b9e79..6b91430 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp
@@ -604,15 +604,15 @@ (JNIEnv *jenv, jclass, jclass jclazz)
{
assert(jclazz);
Class* clazz = jclass_to_struct_Class(jclazz);
- unsigned m_idx = clazz->enclosing_method_index;
- if (m_idx) {
+ unsigned method_idx = clazz->enclosing_method_index;
+ if (method_idx) {
unsigned c_idx = clazz->enclosing_class_index;
ASSERT(c_idx, "No class for enclosing method");
Class* outer_clss = class_resolve_class(clazz, c_idx);
if (outer_clss)
{
- String* name = clazz->const_pool[m_idx].CONSTANT_NameAndType.name;
- String* desc = clazz->const_pool[m_idx].CONSTANT_NameAndType.descriptor;
+ String* name = clazz->m_const_pool.get_name_and_type_name(method_idx);
+ String* desc = clazz->m_const_pool.get_name_and_type_descriptor(method_idx);
TRACE("Looking for enclosing method: class="<name->bytes
<<"; name="<bytes<<"; desc="<bytes);
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 7bc1d02..d56fec8 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
@@ -36,6 +36,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 477a9b6..7027431 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/object/object_handles.cpp
@@ -37,6 +37,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 93aef97..d93b4c2 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_dump.cpp
@@ -25,7 +25,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 a4e2cf1..e051969 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_trace.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/stack/stack_trace.cpp
@@ -27,6 +27,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 3a5be10..2d3dcb0 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_dump.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_dump.cpp
@@ -30,9 +30,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"
diff --git a/enhanced/drlvm/trunk/vm/vmcore/src/util/vm_strings.cpp b/enhanced/drlvm/trunk/vm/vmcore/src/util/vm_strings.cpp
index 94374ec..f67e3c8 100644
--- a/enhanced/drlvm/trunk/vm/vmcore/src/util/vm_strings.cpp
+++ b/enhanced/drlvm/trunk/vm/vmcore/src/util/vm_strings.cpp
@@ -589,20 +589,17 @@ jstring String_to_interned_jstring(Strin
}
-Java_java_lang_String *
-vm_instantiate_cp_string_slow(Class *c, unsigned cp_index)
+Java_java_lang_String*
+vm_instantiate_cp_string_slow(Class* c, unsigned cp_index)
{
ASSERT_THROW_AREA;
#ifdef VM_STATS
VM_Statistics::get_vm_stats().num_instantiate_cp_string_slow++;
#endif
- Java_java_lang_String *result;
- assert(cp_index < c->cp_size);
- Const_Pool *cp = c->const_pool;
-
- String *str = cp[cp_index].CONSTANT_String.string;
- assert(cp_is_constant(cp, cp_index));
+ Java_java_lang_String* result;
+ ConstantPool& cp = c->m_const_pool;
+ String* str = cp.get_string(cp_index);
BEGIN_RAISE_AREA;
result = vm_instantiate_cp_string_resolved(str);