Index: trunk/vm/include/interpreter.h =================================================================== --- trunk/vm/include/interpreter.h (revision 524729) +++ trunk/vm/include/interpreter.h (working copy) @@ -1,10 +1,10 @@ -/* +/** * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with + * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,10 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @author Ivan Volosyuk + +/** * @version $Revision: 1.1.2.1.4.3 $ - */ + */ + +/** + * @file + * The interpreter description. + * + * The interpreter component executes the bytecode and is used in the VM + * interchangeably with the JIT compiler. In the current implementation, + * the interpreter is mainly used to simplify debugging. The interpreter also + * enables VM portability, since most of its code is platform-independent.*/ #ifndef _INTERPRETER_H_ #define _INTERPRETER_H_ @@ -25,8 +34,12 @@ #include "stack_trace.h" #include "interpreter_exports.h" +/** Returns TRUE if the interpreter is enabled. + * + * @return TRUE on success.*/ extern bool interpreter_enabled(); +/** If the interpreter is enabled, aborts the execution.*/ #define ASSERT_NO_INTERPRETER assert(!interpreter_enabled()); #endif Index: trunk/vm/include/interpreter_exports.h =================================================================== --- trunk/vm/include/interpreter_exports.h (revision 524729) +++ trunk/vm/include/interpreter_exports.h (working copy) @@ -1,4 +1,4 @@ -/* +/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -15,6 +15,14 @@ * limitations under the License. */ +/** + * @file + * Export interfaces provided by the interpreter. + * + * The current DRLVM implementation describes how the interpreter exports its + * enumeration, stack trace generation and JVMTI support functions via a single + * method table, to create the Interpreter interface.*/ + #ifndef _INTERPRETER_EXPORTS_H_ #define _INTERPRETER_EXPORTS_H_ @@ -23,86 +31,299 @@ typedef struct FrameHandle FrameHandle; +/** + * @ingroup + * Interpreter table + */ + typedef struct { + +/** + * Fills the stack trace frame at the given depth for the current thread. + * + * @param[in] target_depth - the zero-based depth of the frame or inlined method, + * information about which will be stored at the given + * stack trace frame, stf + * @param[out] stf - the pointer to the StackTraceFrame + * structure that needs to be filled with the data on + * the frame or inlined method corresponding to the + * given depth + * @return TRUE on success, FALSE if the depth is greater than + * or equal to the current thread stack trace length.*/ bool (*interpreter_st_get_frame) (unsigned target_depth, struct StackTraceFrame* stf); + +/** + * Fills the stack trace frames for the specified number of frames of the specified thread. + * + * @param[in] thread - the pointer to the thread + * @param[in] res_depth - the number of frames including inlined methods, + * information about which should be stored + * @param[out] stfs - the pointer to the array of stack trace frames + * created by this function and returned via this pointer + * @note The caller is responsible for freeing the memory.*/ void (*interpreter_st_get_trace) (class VM_thread *thread, unsigned* res_depth, struct StackTraceFrame** stfs); + +/** + * Enumerates references associated with the thread. + * + * @param thread - the pointer to the thread*/ void (*interpreter_enumerate_thread) (class VM_thread *thread); +/** + * Returns the last frame. + * + * @param thread - the pointer to the thread + * @return The pointer to the last frame.*/ FrameHandle* (*interpreter_get_last_frame) (class VM_thread *thread); + +/** Returns the previous frame. + * + * @param frame - the pointer to the frame + * @return The pointer to the previous frame.*/ FrameHandle* (*interpreter_get_prev_frame) (FrameHandle* frame); + +/** + * Returns the frame method. + * + * @param frame - the pointer to the frame + * @return The pointer to the method.*/ Method_Handle (*interpreter_get_frame_method) (FrameHandle* frame); + +/** + * Returns the pointer to the bytecode. + * + * @param frame - the pointer to the frame + * @return The pointer to the bytecode.*/ uint8* (*interpreter_get_frame_bytecode_ptr) (FrameHandle* frame); // 'end' is not inclusive + +/** + * Returns TRUE if the frame is native. + * + * @param frame - the pointer to the frame + * @param begin - the pointer to the register + * @param end - the pointer to the register + * @return TRUE on success.*/ bool (*is_frame_in_native_frame) (struct FrameHandle* frame, void* begin, void* end); +/** + * Enumerates references associated with the thread. + * + * @param thread - the pointer to the thread + * @param jvmtiEnv - the pointer to the jvmti environment*/ void (*interpreter_ti_enumerate_thread) (jvmtiEnv*, class VM_thread *thread); #ifdef _IPF_ +/** + * Returns the stacked register address. + * + * @param bsp - the pointer to the register + * @param reg - the register + * @return The stacked register address.*/ uint64* (*interpreter_get_stacked_register_address) (uint64* bsp, unsigned reg); #endif +/** + * Returns the frame location. + * + * @param jvmtiEnv - the pointer to the jvmti environment + * @param thread - the pointer to the thread + * @param depth - the pointer to the depth + * @param _jmethodID - the pointer to the method + * @param jlocation - the pointer to the location + * @return JVMTI_ERROR_NONE - a successfully added notification
+ * JVMTI_ERROR_NO_MORE_FRAMES - depth is too large*/ jvmtiError (*interpreter_ti_getFrameLocation) ( jvmtiEnv*, class VM_thread*, int, struct _jmethodID * *, int64 *); + +/** + * Returns the value of the 32 bit local variable. + * + * @param jvmtiEnv - the pointer to the jvmti environment + * @param thread - the pointer to the thread + * @param depth - the pointer to the depth + * @param slot - the pointer to the slot + * @param value_ptr - the pointer to the value + * @return JVMTI_ERROR_NONE - a successfully added notification
+ * JVMTI_ERROR_NO_MORE_FRAMES - depth is too large
+ * JVMTI_ERROR_OPAQUE_FRAME - no frame
+ * JVMTI_ERROR_INVALID_SLOT - a bad slot
+ * JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type*/ jvmtiError (*interpreter_ti_getLocal32) ( jvmtiEnv*, class VM_thread*, int, int, int *); + +/** + * Returns the value of 64 bit local variable. + * + * @param jvmtiEnv - the pointer to the jvmti environment + * @param thread - the pointer to the thread + * @param depth - the pointer to the depth + * @param slot - the pointer to the slot + * @param value_ptr - the pointer to the value + * @return JVMTI_ERROR_NONE - a successfully added notification
+ * JVMTI_ERROR_NO_MORE_FRAMES - depth is too large
+ * JVMTI_ERROR_OPAQUE_FRAME - no frame
+ * JVMTI_ERROR_INVALID_SLOT - a bad slot
+ * JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type*/ jvmtiError (*interpreter_ti_getLocal64) ( jvmtiEnv*, class VM_thread*, int, int, int64 *); + +/** + * Returns the value of the Object type local variable. + * + * @param jvmtiEnv - the pointer to the jvmti environment + * @param thread - the pointer to the thread + * @param depth - the pointer to the depth + * @param slot - the pointer to the slot + * @param value_ptr - the pointer to the value + * @return JVMTI_ERROR_NONE - a successfully added notification
+ * JVMTI_ERROR_NO_MORE_FRAMES - depth is too large
+ * JVMTI_ERROR_OPAQUE_FRAME - no frame
+ * JVMTI_ERROR_INVALID_SLOT - a bad slot
+ * JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type*/ jvmtiError (*interpreter_ti_getObject) ( jvmtiEnv*, class VM_thread*, int, int, struct _jobject * *); + +/** + * Returns stack trace data. + * + * @param jvmtiEnv - the pointer to the jvmti environment + * @param thread - the pointer to the thread + * @param start_depth - the pointer to the depth + * @param max_frame_count - the pointer to max_frame_count + * @param frame_buffer - the pointer to frame_buffer + * @param count_ptr - the pointer to the count + * @return JVMTI_ERROR_NONE - a successfully added notification
+ * JVMTI_ERROR_ILLEGAL_ARGUMENT - bad arguments*/ jvmtiError (*interpreter_ti_getStackTrace) (jvmtiEnv*, class VM_thread*, int, int, jvmtiFrameInfo*, int *); + +/** + * Returns frame count. + * + * @param jvmtiEnv - the pointer to the jvmti environment + * @param thread - the pointer to the thread + * @param count_ptr[out] - the pointer to the count + * @return JVMTI_ERROR_NONE - a successfully added notification*/ jvmtiError (*interpreter_ti_get_frame_count) ( jvmtiEnv*, class VM_thread*, int *); + +/** + * Sets the value of 32 bit local variable. + * + * @param jvmtiEnv - the pointer to the jvmti environment + * @param thread - the pointer to the thread + * @param depth - the pointer to the depth + * @param slot - the pointer to the slot + * @param value_ptr - the pointer to the value + * @return JVMTI_ERROR_NONE - a successfully added notification
+ * JVMTI_ERROR_NO_MORE_FRAMES - depth is too large
+ * JVMTI_ERROR_OPAQUE_FRAME - no frame
+ * JVMTI_ERROR_INVALID_SLOT - a bad slot
+ * JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type*/ jvmtiError (*interpreter_ti_setLocal32) ( jvmtiEnv*, class VM_thread*, int, int, int); + +/** + * Sets the value of 64 bit local variable. + * + * @param jvmtiEnv - the pointer to the jvmti environment + * @param thread - the pointer to the thread + * @param depth - the pointer to the depth + * @param slot - the pointer to the slot + * @param value_ptr - the pointer to the value + * @return JVMTI_ERROR_NONE - a successfully added notification
+ * JVMTI_ERROR_NO_MORE_FRAMES - depth is too large
+ * JVMTI_ERROR_OPAQUE_FRAME - no frame
+ * JVMTI_ERROR_INVALID_SLOT - a bad slot
+ * JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type
*/ jvmtiError (*interpreter_ti_setLocal64) ( jvmtiEnv*, class VM_thread*, int, int, int64); + +/** + * Sets the value of the Object type local variable. + * + * @param jvmtiEnv - the pointer to the jvmti environment + * @param thread - the pointer to the thread + * @param depth - the pointer to the depth + * @param slot - the pointer to the slot + * @param value_ptr - the pointer to the value + * @return JVMTI_ERROR_NONE - a successfully added notification
+ * JVMTI_ERROR_NO_MORE_FRAMES - depth is too large
+ * JVMTI_ERROR_OPAQUE_FRAME - no frame
+ * JVMTI_ERROR_INVALID_SLOT - a bad slot
+ * JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type*/ jvmtiError (*interpreter_ti_setObject) ( jvmtiEnv*, class VM_thread*, int, int, struct _jobject *); + +/** + * Returns the interrupted method native bit. + * + * @param thread - the pointer to the thread + * @return The interrupted method native bit.*/ unsigned int (*interpreter_st_get_interrupted_method_native_bit) (class VM_thread *); +/** @defgroup open_interfaces Open Interfaces + * Open interfaces.*/ +/*@{*/ - // Open interfaces part begins - - /** - * The function is called when global TI event state is changed. This means - * that atleast one of jvmtiEnv's enabled the event or the event was - * disabled in all enviroments. - * - * @param event_type - jvmti to enable / disable - * @param enable - enable or disable the events in exe. - */ +/** + * The function is called when the global TI event state is changed. This means + * that at least one of jvmtiEnv's enabled the event or the event was + * disabled in all environments. + * + * @param event_type - jvmti to enable/disable + * @param enable - enable or disable the events in exe*/ void (*interpreter_ti_set_notification_mode)(jvmtiEvent event_type, bool enable); - /** - * Set breakpoint in place identified by method and location. - * No more then one breakpoint will be set at any specific place. Handling - * for multiple jvmti environments is done by jvmti framework. - * - * @return Bytecode has been replaced by instrumentation. - */ +/** + * Sets the breakpoint in the place identified by the method and location. + * No more than one breakpoint will be set at any specific place. Handling + * for multiple jvmti environments is done by the jvmti framework. + * + * @return The bytecode has been replaced by instrumentation.*/ jbyte (*interpreter_ti_set_breakpoint)(jmethodID method, jlocation location); - /** - * Clear breakpoint in place identified by method and location. - * Replaced bytecode (returned by interpreter_ti_set_breakpoint(..)) - * is also passed as a parameter. - */ +/** + * Clears the breakpoint in the place identified by the method and location. + * Replaced the bytecode, returned by interpreter_ti_set_breakpoint(..), + * is also passed as a parameter.*/ void (*interpreter_ti_clear_breakpoint)(jmethodID method, jlocation location, jbyte saved); - /** - * Set callback to notify JVMTI about frame pop event. - * - * @return JVMTI_ERROR_NONE - successfully added notification
- * JVMTI_ERROR_OPAQUE_FRAME - frame is native
- * JVMTI_ERROR_NO_MORE_FRAMES - depth too large
- */ +/** + * Sets a callback to notify JVMTI about the frame-pop event. + * + * @return JVMTI_ERROR_NONE - a successfully added notification
+ * JVMTI_ERROR_OPAQUE_FRAME - the frame is native
+ * JVMTI_ERROR_NO_MORE_FRAMES - depth is too large*/ jvmtiError (*interpreter_ti_notify_frame_pop) (jvmtiEnv*, VM_thread *thread, int depth); +/** + * Pops the frame. + * + * @param jvmtiEnv - the pointer to the jvmti environment + * @param thread - the pointer to the thread + * @return JVMTI_ERROR_NONE - a successfully added notification
+ * JVMTI_ERROR_OPAQUE_FRAME - no frame*/ jvmtiError (*interpreter_ti_pop_frame) (jvmtiEnv*, VM_thread *thread); +/** + * Dumps the stack. + * + * @param thread - the pointer to the thread*/ void (*stack_dump) (VM_thread*); } Interpreter; +/*@}*/ + +/** + * Returns the interpreter table. + * + * @return The interpreter table.*/ VMEXPORT Interpreter *interpreter_table(); #ifdef BUILDING_VM extern Interpreter interpreter; + +/** + * Returns TRUE if interpreter table. + * + * @return TRUE on success.*/ extern bool interpreter_enabled(); #endif Index: trunk/vm/include/interpreter_imports.h =================================================================== --- trunk/vm/include/interpreter_imports.h (revision 524729) +++ trunk/vm/include/interpreter_imports.h (working copy) @@ -1,10 +1,10 @@ -/* +/** * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with + * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,10 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @author Ivan Volosyuk + +/** * @version $Revision: 1.1.2.1.4.3 $ - */ + */ + +/** + * @file + * Import interfaces used by the interpreter. + * + * The current DRLVM implementation describes the following import interfaces: + * interpreter import locking, exceptions handling, JVMTI and JNI functionality.*/ + #ifndef _INTERPRETER_IMPORTS_H_ #define _INTERPRETER_IMPORTS_H_ @@ -27,18 +35,66 @@ struct ManagedObject; typedef struct ManagedObject ManagedObject; + +/** + * Gains ownership over a monitor. + * The current thread blocks, if the specified monitor is owned by another thread. + * + * @param[in] obj - the monitor object where the monitor is located*/ VMEXPORT void vm_monitor_enter_wrapper(ManagedObject *obj); + +/** + * Releases ownership over a monitor. + * + * @param[in] obj - the monitor object where the monitor is located*/ VMEXPORT void vm_monitor_exit_wrapper(ManagedObject *obj); + +/** + * Calls the class_throw_linking_error function that throws + * a linking error. + * + * @param[in] ch - the class handle + * @param[in] cp_index - the index in the constant pool + * @param[in] opcode - the opcode of bytecodes*/ VMEXPORT void class_throw_linking_error_for_interpreter(Class_Handle ch, unsigned cp_index, unsigned opcode); +/** + * Returns the JNI environment. + * + * @return The JNI environment associated with this thread.*/ VMEXPORT JNIEnv * get_jni_native_intf(); +/** + * A callback function for interpreter breakpoint processing. + * + * @param[in] method - the method ID + * @param[in] loc - the location*/ VMEXPORT jbyte jvmti_process_interpreter_breakpoint_event(jmethodID method, jlocation loc); + +/** + * Enables single-step event processing. + * + * @param[in] method - the method ID + * @param[in] location - the location*/ VMEXPORT void jvmti_process_single_step_event(jmethodID method, jlocation location); +/** + * Enables frame-pop event processing. + * + * @param[in] env - the jvmti environment + * @param[in] method - the method ID + * @param[in] was_popped_by_exception - if the frame was popped by exception*/ VMEXPORT void jvmti_process_frame_pop_event(jvmtiEnv *env, jmethodID method, jboolean was_popped_by_exception); + +/** + * Looks for a method in native libraries of a class loader. + * + * @param[in] method - a searching native-method structure + * @return The pointer to found a native function. + * @note The function raises UnsatisfiedLinkError with a method name + * in an exception message, if the specified method is not found.*/ VMEXPORT GenericFunctionPointer classloader_find_native(const Method_Handle method); #endif /* _INTERPRETER_IMPORTS_H_ */ Index: trunk/vm/interpreter/src/interp_defs.h =================================================================== --- trunk/vm/interpreter/src/interp_defs.h (revision 524729) +++ trunk/vm/interpreter/src/interp_defs.h (working copy) @@ -1,10 +1,10 @@ -/* +/** * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with + * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,11 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @author Ivan Volosyuk +/** * @version $Revision: 1.23.4.1.4.3 $ - */ + */ +/** + * @file + * Major interpreter-related definitions. + */ + #define LOG_DOMAIN "interpreter.unspecified" #include "cxxlog.h" @@ -30,29 +34,60 @@ #include "jvmti_types.h" //#define INTERPRETER_DEEP_DEBUG +/** \def DEBUG_PRINT(a) + * \brief Calls TRACE2 with the interpreter category.*/ #define DEBUG_PRINT(a) TRACE2("interpreter", a) +/** \def DEBUG(a) + * \brief Does nothing.*/ #define DEBUG(a) #ifdef NDEBUG +/** \def DEBUG_BYTECODE(a) + * \brief If DEBUG is off, does nothing.*/ # define DEBUG_BYTECODE(a) #else +/** \def DEBUG_BYTECODE(a) + * \brief If DEBUG is on, calls DEBUG_PRINT(a).*/ # define DEBUG_BYTECODE(a) { if (frame.dump_bytecodes) DEBUG_PRINT(a); } #endif + +/** \def DEBUG_GC(a) + * \brief Calls TRACE2 with the gc_interpreter + * category. + */ #define DEBUG_GC(a) TRACE2("gc_interpreter", a) +/** \def DEBUG2(a) + * \brief Calls INFO(a).*/ #define DEBUG2(a) INFO(a) +/** TRUE if the interpreter enables debug.*/ +extern bool interpreter_enable_debug; -extern bool interpreter_enable_debug; +/** \def DEBUG_TRACE_PLAIN(a) + * \brief Calls TRACE2 with the interpreter category.*/ #define DEBUG_TRACE_PLAIN(a) TRACE2("interpreter", a) + +/** \def DEBUG_TRACE(a) + * \brief Calls TRACE2 with the folded_interpreter + * category.*/ #define DEBUG_TRACE(a) TRACE2("folded_interpreter", a) +/** \def ASSERT_TAGS(a) + * \brief Does nothing.*/ #define ASSERT_TAGS(a) +/** \def ASSERT_OBJECT(a) + * \brief Checks the object.*/ #define ASSERT_OBJECT(a) assert((a == 0) || ((*((a)->vt()->clss->get_class_handle()))->vt()->clss == VM_Global_State::loader_env->JavaLangClass_Class)) #ifndef INTERPRETER_USE_MALLOC_ALLOCATION +/** \def ALLOC_FRAME(sz) + * \brief Calls alloca(sz).*/ #define ALLOC_FRAME(sz) alloca(sz) +/** \def FREE_FRAME(ptr) + * \brief If INTERPRETER_USE_MALLOC_ALLOCATION is on, does + * nothing.*/ #define FREE_FRAME(ptr) #else #define ALLOC_FRAME(sz) m_malloc(sz) @@ -76,158 +111,377 @@ # endif #else // no define for: COMPACT_FIELDS +/** The unsigned int value */ # define uword uint32 +/** The signed int value */ # define word int32 - +/** The compressed reference */ # define CREF uint32 # define PTR32 #endif #ifdef COMPRESS_MODE - +/** \def COMPRESS_REF(ref) + * \brief Calls compress_reference(ref).*/ #define COMPRESS_REF(ref) compress_reference(ref) +/** \def UNCOMPRESS_REF(cref) + * \brief Calls uncompress_compressed_reference(cref).*/ #define UNCOMPRESS_REF(cref) uncompress_compressed_reference(cref) #else /* ! COMPRESS_MODE */ +/** + * The fake compressed reference. + * + * @param[in] obj - the object to compress + * @return The compressed reference. + */ static inline CREF fake_compress_reference(ManagedObject *obj) { return (CREF) obj; } + +/** + * Uncompresses the compressed reference. + * + * @param[in] compressed_ref - the compressed reference + * @return The uncompressed reference. + */ static inline ManagedObject* fake_uncompress_compressed_reference(CREF compressed_ref) { return (ManagedObject*) compressed_ref; } +/** \def COMPRESS_REF(ref) + * \brief Calls fake_compress_reference(ref).*/ #define COMPRESS_REF(ref) fake_compress_reference(ref) +/** \def UNCOMPRESS_REF(cref) + * \brief Calls fake_uncompress_compressed_reference(cref).*/ #define UNCOMPRESS_REF(cref) fake_uncompress_compressed_reference(cref) #endif -// Defines byte ordering in Value2 in different situations -#define s0 1 // stack val, NOTE: Values on java stack placed in reversed order -#define s1 0 // so that reversed copy in function call to work correctly -#define l0 0 // local val +/** Defines byte ordering in Value2 in different situations.*/ + +/** The stack value. + * @note Values on the java stack are placed in the reversed order, so that the + * reversed copy in the function call works correctly.*/ +#define s0 1 +#define s1 0 +/** The local value.*/ +#define l0 0 +/** The local value.*/ #define l1 1 -#define c0 0 // const val +/** The constant value.*/ +#define c0 0 +/** The constant value.*/ #define c1 1 -#define a0 0 // arg val +/** The argument value.*/ +#define a0 0 +/** The argument value.*/ #define a1 1 -#define ar0 0 // array val +/** The array value.*/ +#define ar0 0 +/** The array value.*/ #define ar1 1 +/** The result value.*/ #define res0 1 +/** The result value.*/ #define res1 0 - +/** Holds 32-bit values.*/ union Value { +/** The unsigned integer value.*/ uint32 u; +/** The integer value.*/ int32 i; +/** The float value.*/ float f; +/** The compressed reference.*/ CREF cr; }; +/** Holds 64-bit values */ union Value2 { #ifdef PTR32 +/** Two 32-bit values */ Value v[2]; #else Value v0; #endif +/** The long-long value.*/ int64 i64; +/** The unsigned long-long value */ uint64 u64; +/** The double value */ double d; }; +/** The local variable types.*/ enum { +/** The element of stack or local variables that is not an object.*/ FLAG_NONE = 0, +/** The container for the return address from a subroutine.*/ FLAG_RET_ADDR = 2, +/** The containter for an object reference.*/ FLAG_OBJECT = 3 }; +/** The pop_frame states.*/ enum PopFrameState { +/** Indicates that the frame cannot be popped.*/ POP_FRAME_UNAVAILABLE, +/** Indicates that the frame can be popped.*/ POP_FRAME_AVAILABLE, +/** Indicates that the frame is being popped.*/ POP_FRAME_NOW }; +/** + * @brief %The stack for executing the Java method. + * + * This structure contains a set of operations specific for the Java stack. + */ + class Stack { +/** The stack element value.*/ Value *data; +/** The value to the object reference.*/ uint8 *refs; +/** The number of elements on the stack.*/ int32 index; +/** The stack size.*/ int32 size; public: +/** The empty constructor.*/ inline Stack() {} +/** The destructor.*/ inline ~Stack(); +/** + * Initializes the stack of a method. + * + * @param[in] ptr - the pointer to the data + * @param[in] size - the stack size + */ inline void init(void *ptr, int size); - // get reference to value on top of stack +/** + * Returns the reference to the value on the top of the stack. + * + * @param[in] offset - the offset value + * @return The reference to the value on the top of the stack. + */ inline Value& pick(int offset = 0); - // set/reset value to be object reference +/** + * Sets and resets the value to the object reference. + * + * @param[in] offset - the offset value + * @return The value to the object reference. + */ inline uint8& ref(int offset = 0); - - // just move stack pointer + +/** + * Only moves the stack pointer. + * + * @param[in] size - the size value + */ inline void push(int size = 1); + +/** + * Decreases the stack pointer. + * By default, decreases the pointer by one step or as specified in size. + * + * @param[in] size - the required size + */ inline void pop(int size = 1); + +/** + * Is similar to pop(). + * Does the same as pop() and clears the type value associated with + * every cleared stack element via the ref() function. + * + * @param[in] size - the required size + */ inline void popClearRef(int size = 1); +/** + * Sets the value of an object of the Long or Double type + * contained in two adjacent stack elements. + * + * @param[in] idx - the pointer to the stack depth of the Long value + * @param[in] val - the Long value + */ inline void setLong(int idx, Value2 val); + +/** + * Returns the Long value located at the depth specified by idx. + * + * @param[in] idx - the value identifier + * @return The Long value. + */ inline Value2 getLong(int idx); - // Clear stack +/** Clears the stack.*/ inline void clear(); +/** + * Returns the size of the allocated stack area by the elements' size. + * + * @param[in] size - the size in elements + * @return The size of the allocated area. + */ static inline int getStorageSize(int size); + +/** + * Returns the number of elements on the stack. + * + * @return The number of elements on the stack. + */ inline int getIndex() { return index + 1; } + +/** + * Enumerates references associated with the thread. + * + * @param[in] VM_thread - the pointer to the thread + */ friend void interp_enumerate_root_set_single_thread_on_stack(VM_thread*); + +/** + * Enumerates references associated with the thread. + * + * @param[in] ti_env - the pointer to the jvmti environment + * @param[in] VM_thread - the pointer to the thread + */ friend void interp_ti_enumerate_root_set_single_thread_on_stack(jvmtiEnv* ti_env, VM_thread *thread); }; +/** The storage for local variables of the executed Java method.*/ class Locals { + // local variable value Value *var; + // references to the local variable type uint8 *refs; + // locals size uint32 varNum; public: +/** The empty constructor.*/ inline Locals() {} +/** The desctructor.*/ inline ~Locals(); +/** + * Initializes the stack of a method. + * + * @param[in] ptr - the pointer to the data + * @param[in] size - the locals size value + */ inline void init(void *ptr, uint32 size); + +/** + * Returns the reference to the local variable of the specifie ID. + * + * @param[in] id - the local variable ID + * @return The reference to the requested local variable. + */ inline Value& operator () (uint32 id); + +/** + * Sets the value of an object of the Long or Double + * type contained in two adjacent elements. + * + * @param[in] idx - the local variable number + * @param[in] val - the local variable value + */ inline void setLong(int idx, Value2 val); + +/** + * Returns the value of an object of the Long or Double + * type contained in two adjacent elements. + * + * @param[in] idx - the local variable number + * @return The requested object value. + */ inline Value2 getLong(int idx); +/** + * Returns the reference to the type of the local variable. + * + * @param[in] idx - the local variable number + * @return The reference to the local variable type. + * @sa FLAG_NONE, FLAG_RET_ADDR, FLAG_OBJECT + */ inline uint8& ref(uint32 id); +/** + * Returns the size of the allocated locals area by its size in elements. + * + * @param[in] size - size of locals area in elements + * @return The size of the allocated area. + */ static inline int getStorageSize(int size); + +/** + * Returns the number of local variables in this object. + * + * @return The number of local variables.*/ inline uint32 getLocalsNumber() { return varNum; } +/** + * Enumerates references associated with the thread. + * + * @param[in] VM_thread - the pointer to the thread*/ friend void interp_enumerate_root_set_single_thread_on_stack(VM_thread*); + +/** + * Enumerates references associated with the thread. + * + * @param[in] ti_env - the pointer to the jvmti environment + * @param[in] VM_thread - the pointer to the thread */ friend void interp_ti_enumerate_root_set_single_thread_on_stack(jvmtiEnv* ti_env, VM_thread *thread); }; +/** The list of functions that listen for the PopFrame event.*/ struct FramePopListener { +/** The pointer to the listener.*/ void *listener; +/** The next element.*/ FramePopListener *next; }; +/** The list of monitors locked by this method.*/ struct MonitorList { +/** The pointer to the monitor.*/ ManagedObject *monitor; +/** The next element.*/ MonitorList *next; }; +/** The representation of the method being executed.*/ struct StackFrame { public: +/** The address of the bytecode being executed.*/ uint8 *ip; +/** The stack of this method.*/ Stack stack; +/** The local variables of this method.*/ Locals locals; +/** The pointer to the structure of this method.*/ Method *method; +/** The reference to the caller method.*/ StackFrame *prev; +/** The list of functions listening for the PopFrame event.*/ FramePopListener *framePopListener; +/** This pointer of the method being executed.*/ ManagedObject *This; +/** The list of locked monitors.*/ struct MonitorList *locked_monitors; +/** The auxiliary structure for storing available monitor structures.*/ struct MonitorList *free_monitors; +/** The method state: whether the JVMTI frame pop can be performed on it.*/ PopFrameState jvmti_pop_frame; #ifndef NDEBUG bool dump_bytecodes; @@ -236,54 +490,186 @@ uint8 last_bytecodes[8]; int n_last_bytecode; #endif +/** The Exception object that has been thrown and for which + * the JVMTI Exception (?) event has been sent.*/ ManagedObject *exc; +/** The Exception object that has been caught and for which + * the JVMTI ExceptionCaught (?) event has been sent.*/ ManagedObject *exc_catch; }; -/********* PROTOTYPES ********/ +/** + * \defgroup Prototypes Prototypes + */ +/*@{*/ + +/** + * The function for interpreter breakpoint processing. + * + * @param[in] frame - the method ID*/ extern uint8 Opcode_BREAKPOINT(StackFrame& frame); + +/** + * Enumerates references associated with the thread. + * + * @param[in] VM_thread - the pointer to the thread*/ extern void interp_enumerate_root_set_single_thread_on_stack(VM_thread*); + +/** + * Executes the native method. + * + * @param[in] method - the native-method structure pointer + * @param[out] return_value - the return value pointer + * @param[in] args - the method arguments pointer*/ extern void interpreter_execute_native_method( Method *method, jvalue *return_value, jvalue *args); + +/** + * Calls the static native method. + * + * @param[in] prevFrame - the previous frame pointer + * @param[in] frame - the frame pointer + * @param[in] method - the native-method structure pointer*/ extern void interpreterInvokeStaticNative( StackFrame& prevFrame, StackFrame& frame, Method *method); + +/** + * Calls the virtual native method. + * + * @param[in] prevFrame - the previous frame pointer + * @param[in] frame - the frame pointer + * @param[in] method - the method structure pointer*/ extern void interpreterInvokeVirtualNative( StackFrame& prevFrame, StackFrame& frame, Method *method, int sz); +/** + * Executes the method. + * + * @param[in] method - the method structure pointer + * @param[out] return_value - the return value pointer + * @param[in] args - the method arguments pointer*/ extern void interpreter_execute_method( Method *method, jvalue *return_value, jvalue *args); + +/** + * Processes method entry events. + * + * @param[in] method - the method structure pointer*/ void method_entry_callback(Method *method); + +/** + * Processes method exit events. + * + * @param[in] method - the method structure pointer + * @param[in] was_popped_by_exception - if was popped by exception + * @param[in] ret_val - the return value pointer*/ void method_exit_callback(Method *method, bool was_popped_by_exception, jvalue ret_val); + +/** + * Processes method exit events. + * + * @param[in] method - the method structure pointer + * @param[in] frame - the frame pointer*/ void method_exit_callback_with_frame(Method *method, StackFrame& frame); + +/** + * Processes the field modification event. + * + * @param[in] field - the field structure pointer + * @param[in] frame - the frame pointer*/ void putfield_callback(Field *field, StackFrame& frame); + +/** + * Processes the field modification event. + * + * @param[in] field - the field structure pointer + * @param[in] frame - the frame pointer*/ void getfield_callback(Field *field, StackFrame& frame); + +/** + * Processes the field modification event. + * + * @param[in] field - the field structure pointer + * @param[in] frame - the frame pointer*/ void putstatic_callback(Field *field, StackFrame& frame); + +/** + * Processes the field modification event. + * + * @param[in] field - the field structure pointer + * @param[in] frame - the frame pointer*/ void getstatic_callback(Field *field, StackFrame& frame); + +/** + * Processes the frame pop event. + * + * @param[in] l - the pointer to the list of functions that + * listen for the PopFrame event + * @param[in] method - the pointer to the method structure + * @param[in] was_popped_by_exception - if was_popped_by_exception*/ void frame_pop_callback(FramePopListener *l, Method *method, jboolean was_popped_by_exception); + +/** + * Processes the single step event. + * + * @param[in] frame - the frame pointer*/ void single_step_callback(StackFrame &frame); + +/** + * Finds the exception handler. + * + * @param[in] frame - the frame pointer + * @param[in] exception - the exception pointer + * @param[in] h - - the pointer to the representation of a catch block in + * a method's code array + * @return TRUE on success.*/ bool findExceptionHandler(StackFrame& frame, ManagedObject **exception, Handler **h); + +/** + * Loads method handled exceptions. + * + * @param[in] method - the method structure pointer + * @return TRUE on success.*/ bool load_method_handled_exceptions(Method *m); +/*@}*/ -/********* INLINE FUNCTIONS *******/ +/** + * \defgroup Inlines Inline Functions + */ +/*@{*/ + +/** + * Returns the last stack frame. + * + * @return The last stack frame.*/ static inline StackFrame* getLastStackFrame() { return (StackFrame*)get_thread_ptr()->lastFrame; } +/** + * Returns the last stack frame. + * + * @param[in] thread - the thread pointer + * @return The last stack frame.*/ static inline StackFrame* getLastStackFrame(VM_thread *thread) { return (StackFrame*)(thread->lastFrame); } - +/** The interpreter states.*/ enum interpreter_state { INTERP_STATE_STACK_OVERFLOW = 1 }; +/** + * Sets the last stack frame. + * + * @param[in] frame - the frame pointer*/ static inline void setLastStackFrame(StackFrame *frame) { get_thread_ptr()->lastFrame = frame; } - +/*@}*/ void Stack::init(void *ptr, int sz) { data = (Value*)ptr; @@ -413,7 +799,7 @@ return (size * (sizeof(Value) + sizeof(uint8)) + 7) & ~7; } -// Setup locals and stack on C stack. +/** Sets up locals and stack on the C stack.*/ #define SETUP_LOCALS_AND_STACK(frame,method) \ int max_stack = method->get_max_stack(); \ frame.stack.init(ALLOC_FRAME( \ @@ -422,20 +808,29 @@ frame.locals.init(ALLOC_FRAME( \ Locals::getStorageSize(max_locals)), max_locals) +/** The interpreter jvmti events.*/ enum interpreter_ti_events { +/** The method entry event.*/ INTERPRETER_TI_METHOD_ENTRY_EVENT = 1, +/** The method exit event.*/ INTERPRETER_TI_METHOD_EXIT_EVENT = 2, +/** The single step event.*/ INTERPRETER_TI_SINGLE_STEP_EVENT = 4, +/** The pop-frame event.*/ INTERPRETER_TI_POP_FRAME_EVENT = 8, +/** The field access event.*/ INTERPRETER_TI_FIELD_ACCESS = 16, +/** The field modification event.*/ INTERPRETER_TI_FIELD_MODIFICATION = 32, +/** For other events.*/ INTERPRETER_TI_OTHER = 64 /* EXCEPTION, EXCEPTION_CATCH */ }; /** - * Global flags section. + * The global flags' section. * - * Bitwise or of enabled interpreter_ti_events: + * Bitwise or of enabled interpreter_ti_events */ extern int interpreter_ti_notification_mode; + Index: trunk/vm/interpreter/src/interp_native.h =================================================================== --- trunk/vm/interpreter/src/interp_native.h (revision 524729) +++ trunk/vm/interpreter/src/interp_native.h (working copy) @@ -1,10 +1,10 @@ -/* +/** * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with + * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,10 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** +/** * @author Ivan Volosyuk * @version $Revision: 1.8.4.2.4.3 $ */ + +/** + * @file + * Defines native-related macros and functions used by the interpreter. + */ + #include "vm_core_types.h" #ifdef _IPF_ @@ -28,11 +34,23 @@ #include "../m2n_ia32_internal.h" #endif +/** + * Enumerates thread-assocciated references that are not stored on the + * thread's stack. + * + * @param[in] thread - the thread pointer + */ extern void vm_enumerate_root_set_single_thread_not_on_stack(VM_thread * thread); + +/** + * Frees and deletes all local object handles. + * + * @param[in] head - the object handles pointer + */ extern VMEXPORT void free_local_object_handles2(ObjectHandles * head); - +/** Allocates memory.*/ #define M2N_ALLOC_MACRO \ assert(!hythread_is_suspend_enabled()); \ M2nFrame m2n; \ @@ -49,11 +67,18 @@ handles.nw.next = 0; \ m2n_set_local_handles(&m2n, (ObjectHandles*)&handles) +/** Frees memory.*/ #define M2N_FREE_MACRO \ assert(!hythread_is_suspend_enabled()); \ free_local_object_handles2(m2n_get_local_handles(&m2n));\ m2n_set_last_frame(m2n_get_previous_frame(&m2n)) - +/** + * Looks up the implementation for the native method. + * + * @param[in] method - the searching native-method structure + * @return The pointer to find the native function. + */ GenericFunctionPointer interpreterGetNativeMethodAddr(Method*); + Index: trunk/vm/interpreter/src/interp_vm_helpers.h =================================================================== --- trunk/vm/interpreter/src/interp_vm_helpers.h (revision 524729) +++ trunk/vm/interpreter/src/interp_vm_helpers.h (working copy) @@ -1,10 +1,10 @@ -/* +/** * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with + * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 + * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * @@ -14,78 +14,144 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** +/** * @author Ivan Volosyuk * @version $Revision: 1.2.12.2.4.3 $ - */ + */ +/** + * @file + * Defines helper interfaces used by the interpreter. + * + * The current DRLVM implementation describes the following helper interfaces: + * + */ + #include "vm_core_types.h" #include "Class.h" /** - * Set thread-local exception with name 'exc'. + * Sets the thread-local exception with the name exc. + * + * @param[in] exc - the exception name */ void interp_throw_exception(const char* exc); /** - * Set thread-local exception with name 'exc' and 'message'. + * Sets the thread-local exception with the names exc and + * message. + * + * @param[in] exc - the exception name + * @param[in] message - the message */ void interp_throw_exception(const char* exc, const char *message); /** - * Looks up implementation for native method + * Looks up the implementation for the native method. + * + * @param[in] method - the searching native-method structure + * @return The pointer to find the native function. */ GenericFunctionPointer interp_find_native(Method_Handle method); /** - * Resolve class in constant pool of 'clazz' with index = 'classId'. Throw - * exception if resolution error. + * Resolves the class in the clazz constant pool with the index + * classId. Throws an exception if a resolution error occurs. + * + * @param[in] clazz - the class which constant pool contains the reference to + * the target class + * @param[in] classId - the constant-pool index + * @return A resolved class, if a resolution attempt succeeds. */ Class* interp_resolve_class(Class *clazz, int classId); /** - * Resolve class suitable for new operation in constant pool of 'clazz' with - * index = 'classId'. Throw exception if resolution error. + * Resolves the class suitable for a new operation in the clazz + * constant pool with the index classId. Throws an exception if + * a resolution error occurs. + * + * @param[in] clazz - the class which constant pool contains the reference to + * the target class + * @param[in] classId - the constant-pool index + * @return A resolved class, if a resolution attempt succeeds. */ Class* interp_resolve_class_new(Class *clazz, int classId); /** - * Resolve static field in constant pool of 'clazz' with index = 'fieldId'. - * Throw exception if resolution error. + * Resolves the static field in the clazz constant pool with the + * index fieldId. Throws an exception if a resolution error occurs. + * + * @param[in] clazz - the class which constant pool contains the reference + * to the target field + * @param[in] fieldId - the constant-pool index + * @param[in] putfield - location where to put/get the field + * @return A resolved field, if a resolution attempt succeeds. */ Field* interp_resolve_static_field(Class *clazz, int fieldId, bool putfield); /** - * Resolve nonstatic field in constant pool of 'clazz' with index = 'fieldId'. - * Throw exception if resolution error. + * Resolves the nonstatic field in the clazz constant pool with the + * index fieldId. Throws an exception if a resolution error occurs. + * + * @param[in] clazz - the class which constant pool contains the reference + * to the target field + * @param[in] fieldId - the constant-pool index + * @param[in] putfield - location where to put/get thee field + * @return A resolved field, if a resolution attempt succeeds. */ Field* interp_resolve_nonstatic_field(Class *clazz, int fieldId, bool putfield); /** - * Resolve virtual method in constant pool of 'clazz' with index = 'methodId'. - * Throw exception if resolution error. + * Resolves the virtual method in the clazz constant pool with the + * index methodId. Throws an exception if a resolution error occurs. + * + * @param[in] clazz - the class which constant pool contains the reference + * to the method + * @param[in] methodId - the constant-pool index + * @return A resolved method, if a resolution attempt succeeds. */ Method* interp_resolve_virtual_method(Class *clazz, int methodId); /** - * Resolve interface method in constant pool of 'clazz' with index = 'methodId'. - * Throw exception if resolution error. - */ + * Resolves the interface method in the clazz constant pool with + * the index methodId. Throws an exception if a resolution error + * occurs. + * + * @param[in] clazz - the class which constant pool contains the reference + * to the method + * @param[in] methodId - the constant-pool index + * @return A resolved method, if a resolution attempt succeeds.*/ Method* interp_resolve_interface_method(Class *clazz, int methodId); /** - * Resolve virtual method in constant pool of 'clazz' with index = 'methodId'. - * Throw exception if resolution error. + * Resolves the static method in the clazz constant pool with the + * index methodId. Throws an exception if a resolution error + * occurs. + * + * @param[in] clazz - the class which constant pool contains the reference + * to the method + * @param[in] methodId - the constant-pool index + * @return A resolved method, if a resolution attempt succeeds. */ Method* interp_resolve_static_method(Class *clazz, int methodId); /** - * Resolve virtual method in constant pool of 'clazz' with index = 'methodId'. - * Throw exception if resolution error. - */ + * Resolves the special method in the clazz constant pool with the + * index methodId. Throws an exception if a resolution error occurs. + * + * @param[in] clazz - the class which constant pool contains the reference + * to the method + * @param[in] methodId - the constant pool index + * @return A resolved method, if a resolution attempt succeeds.*/ Method* interp_resolve_special_method(Class *clazz, int methodId); /** - * Resolve array of class for specified objClass. + * Resolves the class array for specified objClass. + * + * @param[in] objClass - specified objClass + * @return A resolved array if a resolution attempt succeeds. */ Class* interp_class_get_array_of_class(Class *objClass);