harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gshiman...@apache.org
Subject svn commit: r597138 [13/15] - in /harmony/enhanced/drlvm/trunk: build/make/ build/make/components/vm/ vm/include/ vm/include/open/ vm/jitrino/src/codegenerator/ia32/ vm/port/src/encoder/ia32_em64t/ vm/port/src/lil/ia32/pim/ vm/tests/ncai/ vm/tests/ncai...
Date Wed, 21 Nov 2007 16:29:54 GMT
Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/NCAI.html
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/NCAI.html?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/NCAI.html (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/NCAI.html Wed Nov 21 08:29:40 2007
@@ -0,0 +1,2221 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+    <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8" LANG="en-US">
+    <TITLE>This document describes specific support required from the VM</TITLE>
+    <style type="text/css">
+    <!--
+        body {  color: #000000; background: #ffffff; font-family: verdana, helvetica;
+                font-weight: normal; font-style: normal; font-size: 12pt;
+                margin-left: 0.4in; margin-right: 0.4in }
+        code { font-family: monospace; color: #000000; margin-top: 0.5in; margin-bottom: 0.04in }
+        .indent { margin-left: 0.5in }
+        .smallindent { margin-left: 0.1in }
+        .novmargin { margin-top: 0.01in; margin-bottom: 0.01in }
+        table { border-collapse: collapse }
+        tr { vertical-align: top }
+        td { left: 0; background: #ffffff; font-size: 11pt }
+        td.header { font-weight: bold; background: #cccccc }
+        td.bold { font-weight: bold }
+        td.italic { font-style: italic }
+        p { margin-bottom: 0.04in; direction: ltr; color: #000000; widows: 2; orphans: 2 }
+        h1 { margin-bottom: 0.04in }
+        h2 { margin-bottom: 0.04in; font-style: italic }
+        h3 { margin-bottom: 0.04in }
+        a:link { color: #0000ff }
+    -->
+    </style>
+</HEAD>
+
+<BODY>
+
+<h2><a name="1.1. Native Code Access Interface"></a>Native Code Access Interface</h2>
+
+<p><i>Revision 0.1</i></p>
+<br>
+
+<table border="0">
+<tr>
+<td colspan="2"><a href="#1.1. Native Code Access Interface">Native Code Access Interface</a></td>
+<tr>
+<td colspan="2"><a href="#1.4. Overview">Overview</a></td>
+<tr>
+<td colspan="2"><a href="#1.5. Data types">Data types</a></td>
+<tr>
+<td colspan="2"><a href="#1.6. Modules">Modules</a></td>
+<tr>
+<td colspan="2"><a href="#1.7. Methods">Methods</a></td>
+<tr>
+<td colspan="2"><a href="#1.8. Threads">Threads</a></td>
+<tr>
+<td colspan="2"><a href="#1.9. Frames">Frames</a></td>
+<tr>
+<td colspan="2"><a href="#1.10. Registers">Registers</a></td>
+<tr>
+<td colspan="2"><a href="#1.11. Memory">Memory</a></td>
+<tr>
+<td colspan="2"><a href="#1.12. Signals">Signals</a></td>
+<tr>
+<td colspan="2"><a href="#1.13. Miscellaneous">Miscellaneous</a></td>
+<tr>
+<td colspan="2"><a href="#1.14. Capabilities">Capabilities</a></td>
+<tr>
+<td colspan="2"><a href="#1.15. Event Management">Event Management</a></td>
+<tr>
+<td colspan="2"><a href="#1.16. Event Callbacks">Event Callbacks</a></td>
+<tr>
+<td colspan="2"><a href="#1.17. Error codes">Error codes</a></td>
+<tr><td>&nbsp;</td>
+<td><a href="#1.17.1. Universal errors">Universal errors</a></td>
+<tr><td>
+<td><a href="#1.17.2. Function specific errors">Function specific errors</a></td>
+<tr>
+<td colspan="2"><a href="#1.18. Appendix 1. Priorities">Appendix 1. Priorities</a></td>
+</table>
+
+
+<h2><a name="1.4. Overview"></a>Overview</h2>
+
+<p>This document describes VM debug interface which extends JVMTI to support the debugging of
+mixed managed and native code, namely Native Code Access Interface - NCAI.</p>
+
+<p>The following cannot be done without knowing VM internals:</p>
+<ul>
+    <li><p>mapping of native thread to java thread</p>
+    <li><p>mapping of native frame to java frame</p>
+    <li><p>mapping of native code to java code</p>
+    <li><p>mapping of native register or memory to java field</p>
+</ul>
+
+<p>The following can be done behind the VM:</p>
+<ul>
+    <li><p>tracking of modules loaded into the VM process</p>
+    <li><p>mapping of native virtual address/register/stack offset to address/offset within a
+    module, and finally to symbol (class, method, variable)</p>
+</ul>
+
+<p>
+Processing of breakpoints/watchpoints/signals can be done behind the VM, but if
+VM use the same methods to implement java breakpoints/watchpoints
+over jitted code we get a conflict of interests, so we need common
+approach.</p>
+
+<p>
+NCAI features can be accessed via an interface pointer just like it can be
+done with JNI and JVMTI interface pointers. It is used to call it
+environment pointer, or briefly environment. A NCAI environment can
+be obtained via  the following JVMTI extension function:</p>
+
+<p class="indent">
+<code>
+jvmtiError JNICALL GetExtensionEnv<br>
+&nbsp;&nbsp;&nbsp;
+(jvmtiEnv* jvmti_env, void** ncai_env_ptr, jint version);
+</code>
+</p>
+
+<p>where version is a NCAI version number like NCAI_VERSION_1_0.</p>
+
+<p>
+The function is provided by a standard JVMTI extension mechanism where it
+is identified as <code>org.apache.harmony.vm.GetExtensionEnv</code>. For
+example:</p>
+
+<p class="indent"><code>
+static const char* const GET_EXTENTION_ENV_FUNC =
+<br>
+&nbsp;&nbsp;&nbsp;
+&quot;org.apache.harmony.vm.GetExtensionEnv&quot;;
+<br>
+jint extCount = 0;
+<br>
+jvmtiExtensionFunctionInfo* extensions = 0;
+<br>
+jvmtiError err = jvmti-&gt;GetExtensionFunctions(&amp;extCount, &amp;extensions);
+<br>
+jvmtiExtensionFunction
+<br>
+func = 0;
+<br>
+for (jint i = 0; i &lt; extCount; i++) {
+<br>
+&nbsp;&nbsp;&nbsp;
+if (strcmp(extensions[i].id, GET_EXTENTION_ENV_FUNC) == 0) {
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+func = extensions[i].func;
+<br>
+&nbsp;&nbsp;&nbsp;
+}
+<br>
+&nbsp;&nbsp;&nbsp;
+jvmti-&gt;Deallocate(extensions[i].id);
+<br>
+&nbsp;&nbsp;&nbsp;
+jvmti-&gt;Deallocate(extensions[i].short_description);
+<br>
+&nbsp;&nbsp;&nbsp;
+for (jint j = 0; j &lt; extensions[i].param_count; j++) {
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+jvmti-&gt;Deallocate(extensions[i].params[j].name);
+<br>
+&nbsp;&nbsp;&nbsp;
+}
+<br>
+&nbsp;&nbsp;&nbsp;
+jvmti-&gt;Deallocate(extensions[i].params);
+<br>
+&nbsp;&nbsp;&nbsp;
+jvmti-&gt;Deallocate(extensions[i].errors);
+<br>
+}
+<br>
+ncaiEnv* ncai = 0;
+<br>
+if (func != NULL) {
+<br>
+&nbsp;&nbsp;&nbsp;
+err = func(jvmti, &amp;ncai, NCAI_VERSION_1_0);
+<br>
+}
+</code></p>
+
+<h2><a name="1.5. Data types"></a>Data types</h2>
+
+<p><code>
+struct _ncai;
+<br>
+typedef _ncai* ncaiEnv;
+</code></p>
+
+<p class="indent">Interface pointer to structure containing the NCAI function table
+just like JNI and JVMTI do.</p>
+
+<p><code>
+typedef enum {...} ncaiError;
+</code></p>
+
+<p class="indent">An error code which every NCAI function returns.</p>
+
+<p><code>
+struct _ncaiModule;
+<br>
+typedef _ncaiModule* ncaiModule;
+</code></p>
+
+<p class="indent">Opaque reference to VM
+internal data structure which represents a loadable module.</p>
+
+<p><code>
+struct ncaiModuleInfo;
+<br>
+struct ncaiSegmentInfo;
+</code></p>
+
+<p class="indent">Structures containing module information. See the GetModuleInfo function.</p>
+
+<p><code>
+typedef enum {} ncaiModuleKind;
+</code></p>
+
+<p class="indent">An identifier for a module type. See the GetModuleInfo function.</p>
+
+<p><code>
+typedef enum {} ncaiSegmentKind;
+</code></p>
+
+<p class="indent">An identifier for a segment type. See the GetModuleInfo function.</p>
+
+<p><code>
+struct _ncaiThread;
+<br>
+typedef _ncaiThread* ncaiThread;
+</code></p>
+
+<p class="indent">Opaque reference to VM internal data structure
+which represents a thread attached to the VM process.</p>
+
+<p><code>
+struct ncaiThreadInfo;
+</code></p>
+
+<p class="indent">Structure containing thread information. See the GetThreadInfo function.</p>
+
+<p><code>
+typedef enum {} ncaiThreadKind;
+</code></p>
+
+<p class="indent">An identifier for a thread type. See the GetThreadInfo function.</p>
+
+<p><code>
+struct ncaiFrameInfo;
+</code></p>
+
+<p class="indent">Structure containing frame information. See the GetStackTrace function.</p>
+
+<p><code>
+struct ncaiRegisterInfo;
+</code></p>
+
+<p class="indent">Structure containing register information. See the GetRegisterInfo function.</p>
+
+<p><code>
+struct ncaiSignalInfo;
+</code></p>
+
+<p class="indent">Structure containing signal information. See the GetSignalInfo function.</p>
+
+<p><code>
+struct ncaiCapabilities;
+</code></p>
+
+<p class="indent">Capabilities of a NCAI environment. TBD.</p>
+
+<p><code>
+struct ncaiEventCallbacks;
+</code></p>
+
+<p class="indent">Structure containing the list of event callback functions.</p>
+
+<p><code>
+typedef enum {} ncaiEventMode;<br>
+<br>
+typedef enum {} ncaiEventKind;
+</code></p>
+
+<p class="indent">Identifiers for event mode and type. See the SetEventNotificationMode function.</p>
+
+<p><code>
+typedef enum {} ncaiWatchpointMode;
+</code></p>
+
+<p class="indent">An identifier for the Watchpoint event mode. See the SetWatchpoint function.</p>
+
+<p><code>
+typedef enum {} ncaiStepMode;
+</code></p>
+
+<p class="indent">An identifier for the Step event mode. See the SetStepMode function.</p>
+
+
+
+<h2><a name="1.6. Modules"></a>Modules</h2>
+
+<p><code>ncaiError JNICALL GetAllLoadedModules
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jint* count_ptr, ncaiModule** modules_ptr);
+</code></p>
+
+<p>
+Get a list of all modules which are loaded to the
+VM process. <i>All the returned module pointers remain valid at least
+till the next function call.</i></p>
+
+<p class="indent"></p>
+Parameters:
+<ul>
+    <li class="indent">count_ptr -
+    pointer to a jint which will be set on return with number of
+    modules.
+    <li class="indent">modules_ptr -
+    pointer to a ncaiModule* which will be set on return with
+    address of a newly allocated array of ncaiModule's. The array
+    should be freed by JVMTI function Deallocate.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors
+</ul>
+
+<p><code>
+ncaiError JNICALL GetModuleInfo
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiModule module, ncaiModuleInfo* info_ptr);
+</code></p>
+
+<p>
+Get the module information. Fills the following
+structure:</p>
+
+<p class="indent"><code>
+typedef enum {
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_MODULE _JNI_LIBRARY,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_MODULE _VM_INTERNAL,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_MODULE _OTHER
+<br>
+} ncaiModuleKind;
+</code></p>
+
+<p class="indent"><code>
+typedef struct {
+<br>
+&nbsp;&nbsp;&nbsp;
+ncaiModuleKind kind;
+<br>
+&nbsp;&nbsp;&nbsp;
+char* name;
+<br>
+&nbsp;&nbsp;&nbsp;
+char* filename;
+<br>
+&nbsp;&nbsp;&nbsp;
+ncaiSegmentInfo* segments;
+<br>
+&nbsp;&nbsp;&nbsp;
+size_t segment_count;
+<br>
+} ncaiModuleInfo;
+</code></p>
+
+<p>The
+kind field determines the module kind from the point of view of VM.
+The segments field will be set on return with a pointer to array of
+the following structures:</p>
+
+<p class="indent"><code>
+typedef enum {
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_SEGMENT_UNKNOWN,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_SEGMENT_CODE,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_SEGMENT_DATA
+<br>
+} ncaiSegmentKind;
+</code></p>
+
+<p class="indent"><code>
+typedef struct {
+<br>
+&nbsp;&nbsp;&nbsp;
+ncaiSegmentKind kind;
+<br>
+&nbsp;&nbsp;&nbsp;
+void* base_address;
+<br>
+&nbsp;&nbsp;&nbsp;
+size_t size;
+<br>
+} ncaiSegmentInfo;
+</code></p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">module - the module to analyze.
+    <li class="indent">info_ptr -
+    pointer to a ncaiModuleInfo whose fields will be set on return
+    with information which includes module kind and newly allocated
+    arrays of name, filename and segments. The arrays of name, filename
+    and segments should be freed by JVMTI function Deallocate.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li><p class="indent">NCAI_ERROR_INVALID_MODULE - module is not a valid ncaiModule.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetModuleClassLoader
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiModule module, jobject* classloader_ptr);
+</code></p>
+
+<p>
+Get the JNI library module class loader. Returns
+NULL if the module was loaded by the bootstrap class loader. If the
+module is not of NCAI_MODULE _JNI_LIBRARY kind the function returns
+an error.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">module - the module to analyze.
+    <li class="indent">classloader_ptr - pointer to a jobject
+    which will be set on return with class loader object.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_MODULE - module is not a valid ncaiModule.
+</ul>
+</p>
+
+
+
+<h2><a name="1.7. Methods"></a>Methods</h2>
+
+<p><code>
+ncaiError JNICALL IsMethodCompiled
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jmethodID method, jboolean* is_compiled_ptr);
+</code></p>
+
+<p>
+Indicates if the java method is actually in
+compiled form.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">method - the method to analyze.
+    <li class="indent">is_compiled_ptr - pointer to a jboolean which will be set on return.
+</ul>
+
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_METHOD - method is not a valid java method id.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetMethodLocation
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jmethodID method, void** address_ptr, size_t* size_ptr);
+</code></p>
+
+<p>Get a native address where compiled method is loaded and the size of
+compiled code. <i>This is a convenience method corresponding to the
+CompiledMethodLoad event callback of JVMTI. So, the values returning
+in address_ptr and size_ptr should be the same as  code_addr and
+code_size parameters of  the callback.</i></p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">method - the method to analyze.
+    <li class="indent">address_ptr - pointer to a void* which will be set on return
+    with starting address of compiled code.
+    <li class="indent">size_ptr - pointer to a zise_t which will be set on return
+    with size of compiled code.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_METHOD - method is not a valid java method id.
+    <li class="indent">NCAI_ERROR_NOT_COMPILED - method is not compiled yet.
+</ul>
+
+<p><code>
+ncaiError JNICALL FindJavaMethod
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, void* address, jmethodID* method_ptr);
+</code></p>
+
+<p>Finds a compiled java
+method which corresponds to the given native address.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">address - the native address to analyze.
+    <li class="indent">method_ptr - pointer to a jmethodID which will be set on return with java
+    method id or 0 if such method does not exist.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_ADDRESS - address is not located inside a compiled java method.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetBytecodeLocation
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, void* address, jmethodID method, jlocation* location_ptr);
+</code></p>
+
+<p>Get a bytecode location in compiled java method which corresponds to the
+given native address.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">address - the native address inside a compiled java method.
+    <li class="indent">method - the java method to analyze.
+    <li class="indent">location_ptr - pointer to a jlocation which will be set on return with index of
+    bytecode instruction corresponding to the native address.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_METHOD - method is not a valid java method id.
+    <li class="indent">NCAI_ERROR_INVALID_ADDRESS - address is not located inside the compiled java method.
+    <li class="indent">NCAI_ERROR_NOT_COMPILED - method is not compiled yet.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetNativeLocation
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jmethodID method, jlocation location, void** address_ptr);
+</code></p>
+
+<p>Get a native address which corresponds to the given bytecode location in
+compiled method. <i>This is a convenience method corresponding to the
+CompiledMethodLoad event callback of JVMTI. So, the value returning
+in address_ptr should be the same as start_address corresponding to
+the location in map parameter of  the callback.</i></p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">method - the java method to analyze.
+    <li class="indent">location - the index of the bytecode instruction inside the method.
+    <li class="indent">address_ptr - pointer to a void* which will be set on return with native address
+    of compiled code corresponding to the location.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_METHOD - method is not a valid java method id.
+    <li class="indent">NCAI_ERROR_INVALID_LOCATION - location is not a valid location.
+    <li class="indent">NCAI_ERROR_NOT_COMPILED - method is not compiled yet.
+</ul>
+
+
+
+<h2><a name="1.8. Threads"></a>Threads</h2>
+
+<p><code>
+ncaiError JNICALL GetAllThreads
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jint* count_ptr, ncaiThread** threads_ptr);
+</code></p>
+
+<p>Get a list of all known threads. <i>All the returned thread pointers
+remain valid at least till the next function call.</i></p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">count_ptr - pointer to a jint which will be set on return with number of threads.
+    <li class="indent">threads_ptr - pointer to a ncaiThread * which will be set on return with address
+    of a newly allocated array of ncaiThread’s. The array should be freed by JVMTI function Deallocate.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetThreadInfo
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, ncaiThreadInfo* info_ptr);
+</code></p>
+
+<p>
+Get the thread information. Fills the following structure:</p>
+
+<p><code>
+typedef enum {
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_THREAD_JAVA,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_THREAD_VM_INTERNAL,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_THREAD_OTHER
+<br>
+} ncaiThreadKind;
+</code></p>
+
+<p><code>
+typedef struct {
+<br>
+&nbsp;&nbsp;&nbsp;
+ncaiThreadKind kind;
+<br>
+&nbsp;&nbsp;&nbsp;
+char* name;
+<br>
+} ncaiThreadInfo;
+</code></p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">thread - the thread to analyze.
+    <li class="indent">info_ptr - pointer to a ncaiThreadInfo whose fields will be set on return
+    with information which includes thread kind and newly allocated
+    array of name. The array of name should be freed by JVMTI function Deallocate.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid ncaiThread.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetThreadHandle
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jthread thread, ncaiThread* thread_ptr);
+</code></p>
+
+<p>
+Get a thread handle for the given java thread
+object (0, if such object does not exist).</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">thread - the thread to analyze.
+    <li class="indent">thread_ptr - pointer to a ncaiThread which will be set on return with appropriate value.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid jthread.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetThreadObject
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, jthread* thread_ptr);
+</code></p>
+
+<p>
+Get a java thread object for the given thread
+handle (0, if such object does not exist).</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">thread - the ncaiThread to analyze.
+    <li class="indent">thread_ptr - pointer to a jthread which will be set on return with appropriate value.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid ncaiThread.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_ALIVE - the thread is not alive.
+</ul>
+
+<p><code>
+ncaiError JNICALL SuspendThread
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread);
+</code></p>
+
+<p>
+Suspend the given thread. <i>This is really a hard
+suspend which means one should take care about possible deadlock if
+some thread will try to enter a monitor acquired by the suspended
+thread.</i></p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">thread - the thread to suspend.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid ncaiThread.
+    <li class="indent">NCAI_ERROR_THREAD_SUSPENDED - thread is already suspended.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_ALIVE - the thread is not alive.
+</ul>
+
+<p><code>
+ncaiError JNICALL ResumeThread
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread);
+</code></p>
+
+<p>Resume the given thread.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">thread - the thread to resume.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid ncaiThread.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_SUSPENDED - thread is not suspended.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_ALIVE - the thread is not alive.
+</ul>
+
+<p><code>
+ncaiError JNICALL TerminateThread
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread);
+</code></p>
+
+<p>
+Terminate the given thread. Not all acquired locks
+and owned JVMTI monitors could be released, so care must be taken to
+prevent a possible deadlock.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">thread - the thread to terminate.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid ncaiThread.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_ALIVE - the thread is not alive.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetThreadState
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jthread thread, jint* state_ptr);
+</code></p>
+
+<p>Get a state for the given thread. <i>TBD</i>.</p>
+
+
+
+<h2><a name="1.9. Frames"></a>Frames</h2>
+
+<p><code>
+ncaiError JNICALL GetFrameCount
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, jint* count_ptr);
+</code></p>
+
+<p>
+Get the total number of frames in the given
+thread. The thread needs to be either suspended or the current thread
+in breakpoint or step callback.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">thread - the thread to analyze.
+    <li class="indent">count_ptr - pointer to a jint which will be set on return with number of stack frames.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid ncaiThread.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_SUSPENDED - thread is not suspended or current.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetStackTrace
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, jint depth, ncaiFrameInfo* frame_buffer, jint* count_ptr);
+</code></p>
+
+<p>
+Get the stack frame information for the given
+thread. The depth specifies capacity of the frame_buffer. The thread
+needs to be either suspended or the current thread in breakpoint or
+step callback.</p>
+
+
+<p><code>
+typedef struct {
+<br>
+&nbsp;&nbsp;&nbsp;
+jint java_frame_depth;
+<br>
+&nbsp;&nbsp;&nbsp;
+void* pc_address;
+<br>
+&nbsp;&nbsp;&nbsp;
+void* return_address;
+<br>
+&nbsp;&nbsp;&nbsp;
+void* frame_address;
+<br>
+&nbsp;&nbsp;&nbsp;
+void* stack_address;
+<br>
+} ncaiFrameInfo;
+</code></p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">thread - the thread to analyze.
+    <li class="indent">depth - the maximum number of stack frames to retrieve.
+    <li class="indent">frame_buffer - preallocated buffer large enough to hold depth ncaiFrameInfo
+    objects which fields will be set on return with appropriate values.
+    <li class="indent">count_ptr - pointer to a jint which will be set on return with number of stack
+    frames passed to the buffer.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid ncaiThread.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_SUSPENDED - thread is not suspended or current.
+</ul>
+
+
+
+<h2><a name="1.10. Registers"></a>Registers</h2>
+
+<p><code>
+ncaiError JNICALL GetRegisterCount
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jint* count_ptr);
+</code></p>
+
+<p>Get a number of native registers.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">count_ptr - pointer to a jint which will be set on return with number of registers.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.</p>
+</ul>
+
+<p><code>
+ncaiError JNICALL GetRegisterlInfo
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jint reg_number, ncaiRegisterInfo* info_ptr);
+</code></p>
+
+<p>Get the register information. Fills the following structure:</p>
+
+<p><code>
+typedef struct {
+<br>
+&nbsp;&nbsp;&nbsp;
+char* name;
+<br>
+&nbsp;&nbsp;&nbsp;
+jint size;
+<br>
+} ncaiRegisterInfo;
+</code></p>
+
+<p>
+Field name is the register name and size is the
+register size in bits.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">reg_number - the number of register to analyze.
+    <li class="indent">info_ptr - pointer to a ncaiRegisterInfo whose fields
+    will be set on return with information.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_ILLEGAL_ARGUMENT - reg_number is not a valid register number.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetRegisterValue
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, jint reg_number, void* buf);
+</code></p>
+
+<p>
+Get the register value for the given thread. The
+thread needs to be either suspended or the current thread in
+breakpoint or step callback.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">reg_number - the number of register.
+    <li class="indent">buf - preallocated buffer large enough to hold register value
+    which will be set on return.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_ILLEGAL_ARGUMENT - reg_number is not a valid register number.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_SUSPENDED - thread is not suspended or current.
+</ul>
+
+<p><code>
+ncaiError JNICALL SetRegisterValue
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, jint reg_number, void* buf);
+</code></p>
+
+<p>
+Set the register value for the given thread. The
+thread needs to be either suspended or the current thread in
+breakpoint or step callback.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">reg_number - the number of register.
+    <li class="indent">buf - buffer which contains a register value.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_ILLEGAL_ARGUMENT - reg_number is not a valid register number.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_SUSPENDED - thread is not suspended or current.
+</ul>
+
+
+
+<h2><a name="1.11. Memory"></a>Memory</h2>
+
+<p>The following functions
+should hide/preserve any instrumentation of a native code done by the
+VM</p>
+
+<p><code>
+ncaiError JNICALL ReadMemory
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, void* addr, size_t size, void* buf);
+</code></p>
+
+<p>Read the memory block.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">addr - the address of memory block
+    <li class="indent">size - the size of memory block in bytes.
+    <li class="indent">buf - preallocated buffer large enough to hold a copy of memory block.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_ACCESS_DENIED - access to the memory block is denied.
+</ul>
+
+<p><code>
+ncaiError JNICALL WriteMemory
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, void* addr, size_t size, void* buf);
+</code></p>
+
+<p>Write the memory block.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">addr - the address of memory block.
+    <li class="indent">size - the size of memory block in bytes.
+    <li class="indent">buf - buffer which contains values which will be copied to memory block.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_ACCESS_DENIED - access to the memory block is denied.
+</ul>
+
+
+
+<h2><a name="1.12. Signals"></a>Signals</h2>
+
+<p><code>
+ncaiError JNICALL GetSignalCount
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jint* count_ptr);
+</code></p>
+
+<p>Get a number of signals supported by the platform.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">count_ptr - pointer to a jint which will be set on return with number of signals.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetSignalInfo
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jint signal, ncaiSignalInfo* info_ptr);
+</code></p>
+
+<p>Get the signal information. Fills the following structure:</p>
+
+<p><code>
+typedef struct {
+<br>
+&nbsp;&nbsp;&nbsp;
+char* name;
+<br>
+} ncaiSignalInfo;
+</code></p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">signal - the number of signal.
+    <li class="indent">info_ptr - pointer to a ncaiSignalInfo whose fields will be set on return with information.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_ILLEGAL_ARGUMENT - signal is not a valid signal number.
+</ul>
+
+
+
+<h2><a name="1.13. Miscellaneous"></a>Miscellaneous</h2>
+
+<p><code>
+ncaiError JNICALL GetJvmtiEnv
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jvmtiEnv** jvmti_env_ptr);
+</code></p>
+
+<p>Get JVMTI environment which NCAI environment extends.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">jvmti_env_ptr - pointer to a jvmtiEnv* which will be set on return with
+    appropriate JVMTI environment.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetVersion
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, jint* version_ptr);
+</code></p>
+
+<p>Get the NCAI version number. The version number
+consists of major, minor and micro parts just like the JVMTI version
+identifier.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">version_ptr - pointer to a jint which will be set on return with actual version of
+    NCAI implementation.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetErrorName
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiError err, const char** name_ptr);
+</code></p>
+
+<p>Get symbolic representation for the given error code.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">name_ptr - pointer to a char* which will be set on return with address of a
+    newly allocated array of characters. The array should be freed by
+    JVMTI function Deallocate.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_ILLEGAL_ARGUMENT - err is not a valid ncaiError.
+</ul>
+
+
+
+<h2><a name="1.14. Capabilities"></a>Capabilities</h2>
+
+<p><code>
+typedef struct {
+<br>
+&nbsp;&nbsp;&nbsp;
+// ...
+<br>
+} ncaiCapabilities;
+</code></p>
+
+<p><code>
+ncaiError JNICALL GetPotentialCapabilities
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiCapabilities* caps_ptr);
+</code></p>
+
+<p>Get capabilities which the NCAI environment can potentially possess.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">caps_ptr - pointer to ncaiCapabilities which will be set on return with
+    potential capabilities.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.
+</ul>
+
+<p><code>
+ncaiError JNICALL GetCapabilities
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiCapabilities* caps_ptr);
+</code></p>
+
+<p>Get currently possessed capabilities.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">caps_ptr - pointer to ncaiCapabilities which will be set on return with
+    possessed capabilities.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.
+</ul>
+
+<p><code>
+ncaiError JNICALL AddCapabilities
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiCapabilities* caps_ptr);
+</code></p>
+
+<p>Add the specified capabilities.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">caps_ptr - pointer to ncaiCapabilities to add.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.
+</ul>
+
+<p><code>
+ncaiError JNICALL RelinquishCapabilities
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiCapabilities* caps_ptr);
+</code></p>
+
+<p>Relinquish the specified capabilities.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">caps_ptr - pointer to ncaiCapabilities to relinquish.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.
+</ul>
+
+
+
+<h2><a name="1.15. Event Management"></a>Event Management</h2>
+
+<p><code>
+ncaiError JNICALL GetEventCallbacks
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiEventCallbacks* callbacks, size_t size);
+</code></p>
+
+<p>Get the event callbacks.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">callbacks - pointer to ncaiEventCallbacks which will be set on return with
+    current event callbacks.
+    <li class="indent">size - the size of callbacks.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.
+</ul>
+
+<p><code>
+ncaiError JNICALL SetEventCallbacks
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiEventCallbacks* callbacks, size_t size);
+</code></p>
+
+<p>Set the event callbacks.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">callbacks - pointer to ncaiEventCallbacks to set.
+    <li class="indent">size - the size of callbacks.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">no function specific errors.
+</ul>
+
+<p><code>
+ncaiError JNICALL SetEventNotificationMode
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiEventMode mode, ncaiEventKind event, ncaiThread thread);
+</code></p>
+
+<p>
+Set the event notification mode for the given
+thread. If thread is NULL, the mode is set for all the known threads.
+The ncaiEventMode and ncaiEventKind are the following:</p>
+
+<p class="indent"><code>
+typedef enum {
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_ENABLE = 1,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_DISABLE = 0
+<br>
+} ncaiEventMode;
+</code></p>
+
+
+<p class="indent"><code>
+typedef enum {
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_THREAD_START = 1,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_THREAD_END,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_BREAKPOINT,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_STEP,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_WATCHPOINT,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_METHOD_ENTRY,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_METHOD_EXIT,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_FRAME_POP,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_SIGNAL,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_EXCEPTION,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_MODULE_LOAD,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_MODULE_UNLOAD,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_CONSOLE_INPUT,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_CONSOLE_OUTPUT,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_EVENT_DEBUG_OUTPUT
+<br>
+} ncaiEventKind;
+</code></p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">mode - the mode to set.
+    <li class="indent">event - the event to control.
+    <li class="indent">thread - the thread to control.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_ILLEGAL_ARGUMENT - mode or event is not valid.
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid ncaiThread.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_ALIVE - the thread is not alive.
+</ul>
+
+<p><code>
+ncaiError JNICALL SetBreakpoint
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, void* code_addr);
+</code></p>
+
+<p>Set a breakpoint at the given address code_addr.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">code_addr - the native address of the breakpoint.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_DUPLICATE - the designated breakpoint is already set.
+</ul>
+
+<p><code>
+ncaiError JNICALL ClearBreakpoint
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, void* code_addr);
+</code></p>
+
+<p>Clear a breakpoint at the given address code_addr.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">code_addr - the native address of the breakpoint.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_NOT_FOUND - the designated breakpoint is not found.
+</ul>
+
+<p><code>
+ncaiError JNICALL SetWatchpoint
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, void* data_addr, size_t len, ncaiWatchpointMode mode);
+</code></p>
+
+<p>Set a watchpoint starting at the given address data_addr for len bytes.</p>
+
+<p class="indent"><code>
+typedef enum {
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_WATCHPOINT_READ,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_WATCHPOINT_WRITE,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_WATCHPOINT_ACCESS
+<br>
+} ncaiWatchpointMode;
+</code></p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">data_addr - the starting address of memory block to watch.
+    <li class="indent">len - the length in bytes of the memory block.
+    <li class="indent">mode - the mode to watch.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_DUPLICATE - the designated watchpoint is already set.
+</ul>
+
+<p><code>
+ncaiError JNICALL ClearWatchpoint
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, void* data_addr);
+</code></p>
+
+<p>Clear a watchpoint starting at the given address data_addr.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">data_addr - the starting address of watching memory block.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_NOT_FOUND - the designated watchpoint is not found.
+</ul>
+
+<p><code>
+ncaiError JNICALL SetStepMode
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, ncaiStepMode mode);
+</code></p>
+
+<p>Set the step mode for the given thread. If thread is NULL, the mode is set for all the known threads.</p>
+
+<p class="indent"><code>
+typedef enum {
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_STEP_OFF,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_STEP_INTO,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_STEP_OVER,
+<br>
+&nbsp;&nbsp;&nbsp;
+NCAI_STEP_OUT
+<br>
+} ncaiStepMode;
+</code></p>
+
+<p>NCAI_STEP_OFF disables generating step events for the given thread, NCAI_STEP_INTO
+enables generating step event for each CPU instruction,
+NCAI_STEP_OVER enables generating step event for each CPU instruction
+skipping function calls, NCAI_STEP_OUT disables generating step
+event untill the function returns.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">thread - the thread to control.
+    <li class="indent">mode - the mode to set.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_ILLEGAL_ARGUMENT - mode is not valid.
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid ncaiThread.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_ALIVE - the thread is not alive.
+</ul>
+
+<p><code>
+ncaiError JNICALL NotifyFramePop
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, void* frame_address);
+</code></p>
+
+<p>Set a trigger to notify when the frame of the given address is popped from the given thread stack.</p>
+
+<p class="indent">Parameters:</p>
+<ul>
+    <li class="indent">thread - the thread to watch.
+    <li class="indent">frame_addr - the address of frame to watch.
+</ul>
+
+<p class="indent">Errors:</p>
+<ul>
+    <li class="indent">NCAI_ERROR_INVALID_THREAD - thread is not a valid ncaiThread.
+    <li class="indent">NCAI_ERROR_THREAD_NOT_ALIVE - the thread is not alive.
+    <li class="indent">NCAI_ERROR_NOT_FOUND - the designated frame is not found.
+</ul>
+
+
+
+<h2><a name="1.16. Event Callbacks"></a>Event Callbacks</h2>
+
+<p>The following callbacks are called from within an appropriate application thread
+and are not queued by the VM.</p>
+
+<p><code>
+void JNICALL ThreadStart
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread);
+</code></p>
+
+<p>This callback is invoked when the thread is about to enter its initial method.</p>
+
+<p><code>
+void JNICALL ThreadEnd
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread);
+</code></p>
+
+<p>This callback is invoked just after the thread exits its initial method.</p>
+
+<p><code>
+void JNICALL Step
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, void* addr);
+</code></p>
+
+<p>This callback is invoked when the native thread specified in SetStepMode
+request reaches a new native instruction address according to the
+specified step mode.</p>
+
+
+<p><code>
+void JNICALL Breakpoint
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, void* addr);
+</code></p>
+
+<p>
+This callback is invoked when the native thread
+specified in SetBreakpoint request reaches the specified native
+instruction address.</p>
+
+<p><code>
+void JNICALL Watchpoint
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, void* code_addr, void* data_addr);
+</code></p>
+
+<p>
+This callback is invoked when the native thread
+specified in SetWatchpoint request accesses the specified native data
+address according to the specified watchpoint mode.</p>
+
+<p><code>
+void JNICALL Signal
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, void* addr, jint signal, jboolean is_internal, jboolean* is_handled);
+</code></p>
+
+<p>
+This callback is invoked when OS notifies the VM
+process about a raised signal. is_internal indicates whether the VM
+raises the signal for internal use. is_handled is in/out flag which
+indicates whether the VM will handle the signal or not. The actual
+set of possible signals depends on platform.</p>
+
+<p><code>
+void JNICALL Exception
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, void* addr, void* exception);
+</code></p>
+
+<p>This callback is invoked when C++ exception is thrown. <i>TBD</i>.</p>
+
+<p><code>
+void JNICALL ModuleLoad
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, ncaiModule module);
+</code></p>
+
+<p>This callback is invoked when the VM process loads an executable module.</p>
+
+<p><code>
+void JNICALL ModuleUnload
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, ncaiModule module);
+</code></p>
+
+<p>This callback is invoked when the VM process is about to unload an executable module.</p>
+
+<p><code>
+void JNICALL MethodEntry
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, void* addr);
+</code></p>
+
+<p>This callback is invoked when the thread is about to enter a method.</p>
+
+<p><code>
+void JNICALL MethodExit
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, void* addr);
+</code></p>
+
+<p>This callback is invoked when the thread is about to exit a method.</p>
+
+<p><code>
+void JNICALL FramePop
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, ncaiThread thread, void* addr);
+</code></p>
+
+<p>This callback is invoked when the thread is about to exit a frame
+specified in NotifyFramePop request.</p>
+
+<p><code>
+void JNICALL ConsoleInput
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, char** message);
+</code></p>
+
+<p> This callback is invoked when the VM process tries to read data from standard input. <i>TBD</i>.</p>
+
+<p><code>
+void JNICALL ConsoleOutput
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, char* message);
+</code></p>
+
+<p>This callback is invoked when the VM process is about to write a message to standard output. <i>TBD</i>.</p>
+
+<p><code>
+void JNICALL DebugMessage
+<br>
+&nbsp;&nbsp;&nbsp;
+(ncaiEnv* env, char* message);
+</code></p>
+
+<p>This callback is invoked when the VM process sends a debug message. <i>TBD</i>.</p>
+
+
+
+<h2><a name="1.17. Error codes"></a>Error codes</h2>
+
+<p>The following is a list of possible error codes which can be returned by
+NCAI functions. <i>Universal errors</i> can be returned by any
+function and so they are not specified in the above function error
+lists. On the contrary <i>function specific errors</i> can be
+returned only by the functions which include them in the function
+errors specification.</p>
+
+
+<h3><a name="1.17.1. Universal errors"></a>Universal errors</h3>
+
+<p>
+NCAI_ERROR_NONE
+<br>
+<span class="indent">Indicates a successful completion of the function.</span>
+</p>
+
+<p>
+NCAI_ERROR_NULL_POINTER
+<br>
+<span class="indent">A pointer argument is equal to 0 which is not acceptable for the function.</span>
+</p>
+
+<p>NCAI_ERROR_OUT_OF_MEMORY
+<br>
+<span class="indent">Not enough allocatable memory available to process the function.</span>
+</p>
+
+<p>NCAI_ERROR_ACCESS_DENIED
+<br>
+<span class="indent">Access is denied.</span>
+</p>
+
+<p>NCAI_ERROR_UNATTACHED_THREAD
+<br>
+<span class="indent">The calling thread is not attached to the VM.</span>
+</p>
+
+<p>NCAI_ERROR_INVALID_ENVIRONMENT
+<br>
+<span class="indent">The NCAI environment is not valid.</span>
+</p>
+
+<p>NCAI_ERROR_INTERNAL
+<br>
+<span class="indent">An unexpected internal error.</span>
+</p>
+
+<p>NCAI_ERROR_ILLEGAL_ARGUMENT
+<br>
+<span class="indent">Illegal value of argument.</span>
+</p>
+
+
+<h3><a name="1.17.2. Function specific errors"></a>Function specific errors</h3>
+
+<p>NCAI_ERROR_NOT_AVAILABLE
+<br>
+<span class="indent">Function is not implemented.</span>
+</p>
+
+<p>NCAI_ERROR_INVALID_MODULE
+<br>
+<span class="indent">The module specified by argument is not a valid ncaiModule.</span>
+</p>
+
+<p>NCAI_ERROR_INVALID_METHOD
+<br>
+<span class="indent">The method specified by argument is not a valid jmethodID.</span>
+</p>
+
+<p>NCAI_ERROR_INVALID_LOCATION
+<br>
+<span class="indent">The location specified by argument is not a valid location.</span>
+</p>
+
+<p>NCAI_ERROR_INVALID_ADDRESS
+<br>
+<span class="indent">The address specified by argument is not valid.</span>
+</p>
+
+<p>NCAI_ERROR_INVALID_THREAD
+<br>
+<span class="indent">The thread specified by argument is not a valid ncaiThread.</span>
+</p>
+
+<p>NCAI_ERROR_THREAD_SUSPENDED
+<br>
+<span class="indent">The thread specified by argument is suspended.</span>
+</p>
+
+<p>NCAI_ERROR_THREAD_NOT_SUSPENDED
+<br>
+<span class="indent">The thread specified by argument is not suspended.</span>
+</p>
+
+<p>NCAI_ERROR_THREAD_NOT_ALIVE
+<br>
+<span class="indent">The thread specified by argument is not alive.</span>
+</p>
+
+<p>NCAI_ERROR_INTERPRETER_USED
+<br>
+<span class="indent">VM was started in interpreter mode.</span>
+</p>
+
+<p>NCAI_ERROR_NOT_COMPILED
+<br>
+<span class="indent">The method is not compiled yet.</span>
+</p>
+
+<p>NCAI_ERROR_DUPLICATE
+<br>
+<span class="indent">The designated breakpoint is already set.</span>
+</p>
+
+<p>NCAI_ERROR_NOT_FOUND
+<br>
+<span class="indent">The designated breakpoint is not found.</span>
+</p>
+
+
+
+<h2><a name="1.18. Appendix 1. Priorities"></a>Appendix 1. Priorities</h2>
+
+<p>The following table reflects our view on implementation priorities.</p>
+
+<table width=450 border="1" bordercolor="#000000" cellpadding="3" cellspacing="0">
+    <col width="40%">
+    <col width="16%">
+    <col width="24%">
+    <col width="20%">
+    <tr>
+        <td class="header">
+            Function Name
+        <td class="header">
+            Priority
+        <td class="header">
+            Comments
+        <td class="header">
+            Capability
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            Modules
+    </tr>
+    <tr>
+        <td>GetAllLoadedModules
+        <td>High
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>GetModuleInfo
+        <td>High
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>GetModuleClassLoader
+        <td>Low
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            <B>Methods
+    </tr>
+    <tr>
+        <td>IsMethodCompiled
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>GetMethodLocation
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>FindJavaMethod
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>GetBytecodeLocation
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>GetNativeLocation
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            Threads
+    </tr>
+    <tr>
+        <td>GetAllThreads
+        <td>High
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>GetThreadInfo
+        <td>Medium
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>GetThreadHandle
+        <td>Medium
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>GetThreadObject
+        <td>Medium
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>SuspendThread
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>ResumeThread
+        <td>High
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>TerminateThread
+        <td>Low
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>GetThreadState
+        <td>Medium
+        <td><i>TBD</i>
+        <td>Required
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            Frames
+    </tr>
+    <tr>
+        <td>GetFrameCount
+        <td>High
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>GetStackTrace
+        <td>High
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            Registers
+    </tr>
+    <tr>
+        <td>GetRegisterCount
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>GetRegisterInfo
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>GetRegisterValue
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>SetRegisterValue
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            Memory
+    </tr>
+    <tr>
+        <td>ReadMemory
+        <td>High
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>WriteMemory
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            Signals
+    </tr>
+    <tr>
+        <td>GetSignalCount
+        <td>Low
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>GetSignalInfo
+        <td>Low
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            Miscellaneous
+    </tr>
+    <tr>
+        <td>GetJvmtiEnv
+        <td>Low
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>GetVersion
+        <td>Low
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>GetErrorName
+        <td>Low
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            Capabilities
+    </tr>
+    <tr>
+        <td>GetPotentialCapabilities
+        <td>Medium
+        <td><i>TBD</i>
+        <td>Required
+    </tr>
+    <tr>
+        <td>AddCapabilities
+        <td>Medium
+        <td><i>TBD</i>
+        <td>Required
+    </tr>
+    <tr>
+        <td>RelinquishCapabilities
+        <td>Medium
+        <td><i>TBD</i>
+        <td>Required
+    </tr>
+    <tr>
+        <td>GetCapabilities
+        <td>Medium
+        <td><i>TBD</i>
+        <td>Required
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            Event Management
+    </tr>
+    <tr>
+        <td>GetEventCallbacks
+        <td>High
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>SetEventCallbacks
+        <td>High
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>SetEventNotificationMode
+        <td>High
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>SetBreakpoint
+        <td>High
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>ClearBreakpoint
+        <td>High
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>SetWatchpoint
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>ClearWatchpoint
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>SetStepMode
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>NotifyFramePop
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td colspan="4" class="bold">
+            Event Callbacks
+    </tr>
+    <tr>
+        <td>ThreadStart
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>ThreadEnd
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>Step
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>Breakpoint
+        <td>High
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>Watchpoint
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>Signal
+        <td>Medium
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>Exception
+        <td>Low
+        <td><i>TBD</i>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>ModuleLoad
+        <td>Medium
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>ModuleUnload
+        <td>Medium
+        <td>
+        <td>Required
+    </tr>
+    <tr>
+        <td>MethodEntry
+        <td>Low
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>MethodExit
+        <td>Low
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>FramePop
+        <td>Low
+        <td>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>ConsoleInput
+        <td>Low
+        <td><i>TBD</i>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>ConsoleOutput
+        <td>Low
+        <td><i>TBD</i>
+        <td>Optional
+    </tr>
+    <tr>
+        <td>DebugMessage
+        <td>Low
+        <td><i>TBD</i>
+        <td>Optional
+    </tr>
+</table>
+
+
+</BODY>
+</HTML>

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/NCAI.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/README
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/README?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/README (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/README Wed Nov 21 08:29:40 2007
@@ -0,0 +1,119 @@
+
+NCAI (Native Code Access Interface)
+--------------------------------------
+
+This directory contains the source code of Native Code Access Interface
+(NCAI) implementation in the VM core component, which is the important part of
+NCAI implementation. Additionally, NCAI involves other components, such as
+the thread manager (TM) and the interpreter.
+
+
+Implementation notes
+------------------------
+
+This section describes differences between the current NCAI implementation and
+the NCAI interface description (see NCAI.html document).
+
+Notes are divided into functional groups, as in NCAI interface description.
+
+General
+-------
+1. NCAI interface is not fully implemented now. Unimplemented features
+are listed below.
+2. Most features are implemented for IA-32 architecture only.
+
+Threads
+-------
+1. In the current NCAI implementation, threads are only TM threads.
+The GetAllThreads() function returns only threads attached to the thread
+manager, including Java threads, JVMTI agent threads, VM special threads
+or native threads attached to VM with the AttachCurrentThread() function.
+Native threads created using OS API and not attached to the VM are not
+reported.
+
+2. The thread list obtained with GetAllThreads() is not preserved until
+the next GetAllThreads() call, as specified in the interface description.
+That is, the GetThreadInfo() function can return NCAI_ERROR_THREAD_NOT_ALIVE
+if the corresponding thread was terminated after the last call to
+GetAllThreads() where thread handle was obtained.
+
+3. The NCAI suspend mechanism makes use of the suspend count: user code can
+suspend a thread many times but must resume it the same number of times.
+Therefore, a call to SuspendThread() never returns NCAI_ERROR_THREAD_SUSPENDED,
+as specified in the NCAI interface description.
+
+Frames
+------
+Stack walking algorithms for GetStackTrace() and GetFrameCount() functions
+are heuristic: these functions can return a partial stack trace if the stack
+walking algorithm is unable to unwind the stack any more, especially for code
+compiled with optimizations.
+
+Registers
+---------
+Functions GetRegisterValue() and SetRegisterValue() operate with register
+context saved while executing SuspendThread(). Thus, these functions work only
+for suspended threads and not for threads that are in a breakpoint or a step
+callback.
+
+Capabilities
+------------
+Capabilities are not implemented in the current version. All implemented
+features are enabled.
+
+Single Step
+------------
+Single stepping uses disassembling to predict the following instructions.
+Unlike JITted code that uses limited set of instructions, native code generated
+by common compilers may contain any instructions allowed in particular processor
+architecture. Thus the decoder used for disassembling should be extended to
+the whole set of processor instructions.
+Currently the decoder is extended with most frequently used instructions, but
+it does not cover the whole IA-32 instruction set. Therefore some errors may
+occur during single stepping through the native code if the decoder meets
+an unrecognized processor instruction.
+
+Event Callbacks
+---------------
+1. The signal callback can be called when VM is stopped, which imposes certain
+restrictions on event handler code: the event handler must not use JNI
+and JVMTI functions except in special cases (see GarbageCollectionStart and
+GarbageCollectionFinish events in JVMTI spec.)
+
+2. Although GetAllLoadedModules() returns all modules loaded into the VM process,
+ModuleLoad() and ModuleUnload() callbacks are called only for modules loaded by
+VM itself, which are JNI libraries loaded by Java code, including VM-internal
+JNI libraries.
+
+
+Unimplemented features
+--------------------------
+
+The list of unimplemented functions:
+
+GetModuleClassLoader
+FindJavaMethod
+GetBytcodeLocation
+GetThreadState
+GetVersion
+GetErrorName
+GetPotentialCapabilities
+GetCapabilities
+AddCapabilities
+RelinquishCapabilities
+SetWatchpoint
+ClearWatchpoint
+NotifyFramePop
+
+The list of unimplemented event callbacks:
+
+ThreadStart
+ThreadEnd
+Watchpoint
+Exception
+MethodEntry
+MethodExit
+FramePop
+ConsoleInput
+ConsoleOutput
+DebugMessage

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/README
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,208 @@
+/**
+ * @author Intel, Petr Ivanov
+ * @version $Revision$
+ */
+
+#define LOG_DOMAIN "ncai"
+#include "cxxlog.h"
+#include "jvmti_internal.h"
+#include "suspend_checker.h"
+#include "environment.h"
+#include "jvmti_break_intf.h"
+#include "ncai_direct.h"
+#include "ncai_internal.h"
+
+#include "ncai.h"
+
+//////////////////////////////////////////////////////////////////////////////
+// Stubs for functions which are not implemented yet
+// FIXME: Possibly will be not needed after Capabilities implementation
+static ncaiError JNICALL ncaiGetModuleClassLoaderStub(ncaiEnv*,ncaiModule,jobject*)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiFindJavaMethodStub(ncaiEnv*,void*,jmethodID*)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiGetBytcodeLocationStub(ncaiEnv* env, void* address, jmethodID* method, jlocation* location_ptr)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiGetThreadStateStub(ncaiEnv*,ncaiThread,jint*)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiGetVersionStub(ncaiEnv*,jint*)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiGetErrorNameStub(ncaiEnv*,ncaiError,const char**)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiGetPotentialCapabilitiesStub(ncaiEnv*,ncaiCapabilities*)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiGetCapabilitiesStub(ncaiEnv*,ncaiCapabilities*)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiAddCapabilitiesStub(ncaiEnv*,ncaiCapabilities*)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiRelinquishCapabilitiesStub(ncaiEnv*,ncaiCapabilities*)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiSetWatchpointStub(ncaiEnv*,void*,size_t,ncaiWatchpointMode)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiClearWatchpointStub(ncaiEnv*,void*)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+static ncaiError JNICALL ncaiNotifyFramePopStub(ncaiEnv*,ncaiThread,void*)
+{ return NCAI_ERROR_NOT_AVAILABLE; }
+
+// Function table
+const struct _ncai ncai_table =
+{
+    ncaiGetAllLoadedModules,
+    ncaiGetModuleInfo,
+    ncaiGetModuleClassLoaderStub,       //ncaiGetModuleClassLoader,
+    ncaiIsMethodCompiled,
+    ncaiGetMethodLocation,
+    ncaiFindJavaMethodStub,             //ncaiFindJavaMethod,
+    ncaiGetBytcodeLocationStub,         //ncaiGetBytcodeLocation,
+    ncaiGetNativeLocation,
+    ncaiGetAllThreads,
+    ncaiGetThreadInfo,
+    ncaiGetThreadHandle,
+    ncaiGetThreadObject,
+    ncaiSuspendThread,
+    ncaiResumeThread,
+    ncaiTerminateThread,
+    ncaiGetThreadStateStub,             //ncaiGetThreadState,
+    ncaiGetFrameCount,
+    ncaiGetStackTrace,
+    ncaiGetRegisterCount,
+    ncaiGetRegisterInfo,
+    ncaiGetRegisterValue,
+    ncaiSetRegisterValue,
+    ncaiReadMemory,
+    ncaiWriteMemory,
+    ncaiGetSignalCount,
+    ncaiGetSignalInfo,
+    ncaiGetJvmtiEnv,
+    ncaiGetVersionStub,                 //ncaiGetVersion,
+    ncaiGetErrorNameStub,               //ncaiGetErrorName,
+    ncaiGetPotentialCapabilitiesStub,   //ncaiGetPotentialCapabilities,
+    ncaiGetCapabilitiesStub,            //ncaiGetCapabilities,
+    ncaiAddCapabilitiesStub,            //ncaiAddCapabilities,
+    ncaiRelinquishCapabilitiesStub,     //ncaiRelinquishCapabilities,
+    ncaiGetEventCallbacks,
+    ncaiSetEventCallbacks,
+    ncaiSetEventNotificationMode,
+    ncaiSetBreakpoint,
+    ncaiClearBreakpoint,
+    ncaiSetWatchpointStub,              //ncaiSetWatchpoint,
+    ncaiClearWatchpointStub,            //ncaiClearWatchpoint,
+    ncaiSetStepMode,
+    ncaiNotifyFramePopStub,             //ncaiNotifyFramePop,
+};
+
+jvmtiError create_ncai_environment(jvmtiEnv* jvmti_env, NCAIEnv** penv)
+{
+    TRACE2("jvmti.ncai", "create_ncai_environment called");
+
+    TIEnv *ti_env = (TIEnv *)jvmti_env;
+    NCAIEnv *newenv;
+    jvmtiError error_code;
+
+    error_code = _allocate(sizeof(NCAIEnv), (unsigned char**)&newenv);
+    if (error_code != JVMTI_ERROR_NONE)
+    {
+        *penv = NULL;
+        return error_code;
+    }
+
+    newenv->functions = &ncai_table;
+    newenv->ti_env = ti_env;
+    newenv->modules = NULL;
+    ti_env->ncai_env = newenv;
+    memset(&newenv->event_table, 0, sizeof(ncaiEventCallbacks));
+    memset(&newenv->global_events, 0, sizeof(newenv->global_events));
+    memset(&newenv->event_threads, 0, sizeof(newenv->event_threads));
+
+    newenv->env_lock = new Lock_Manager();
+    assert(newenv->env_lock);
+
+    // Acquire interface for breakpoint handling
+    newenv->brpt_intf =
+        VM_Global_State::loader_env->TI->vm_brpt->new_intf(ti_env,
+            ncai_process_breakpoint_event, PRIORITY_NCAI_BREAKPOINT, false);
+    assert(newenv->brpt_intf);
+
+    *penv = newenv;
+    TRACE2("jvmti.ncai", "New NCAI environment created: " << newenv);
+    return JVMTI_ERROR_NONE;
+}
+
+
+jvmtiError JNICALL jvmtiGetNCAIEnvironment(jvmtiEnv* jvmti_env, ...)
+{
+    TRACE2("jvmti.ncai", "GetNCAIEnvironment called");
+    SuspendEnabledChecker sec;
+
+    va_list args;
+    va_start(args, jvmti_env);
+    // GetExtensionEnv function has following prototype:
+    // GetExtensionEnv(jvmtiEnv* jvmti_env, void** ncai_env_ptr, jint version);
+    NCAIEnv** penv = (NCAIEnv**)va_arg(args, void**);
+    jint version = (jint)va_arg(args, jint);
+    va_end(args);
+
+    if (penv == NULL)
+        return JVMTI_ERROR_NULL_POINTER;
+
+    jint vmajor = (version & NCAI_VERSION_MASK_MAJOR) >> NCAI_VERSION_SHIFT_MAJOR;
+    jint vminor = (version & NCAI_VERSION_MASK_MINOR) >> NCAI_VERSION_SHIFT_MINOR;
+    jint vmicro = (version & NCAI_VERSION_MASK_MICRO) >> NCAI_VERSION_SHIFT_MICRO;
+    if (vmajor > NCAI_VERSION_MAJOR ||
+        vminor > NCAI_VERSION_MINOR ||
+        vmicro > NCAI_VERSION_MICRO)
+    {
+        *penv = NULL;
+        return JVMTI_ERROR_NOT_AVAILABLE;
+    }
+
+    GlobalNCAI* ncai = VM_Global_State::loader_env->NCAI;
+
+    TIEnv* ti_env = (TIEnv*)jvmti_env;
+    if (ti_env->ncai_env != NULL)
+    {
+        *penv = ti_env->ncai_env;
+        ncai->enabled = true;
+        return JVMTI_ERROR_NONE;
+    }
+
+    jvmtiError err = create_ncai_environment(jvmti_env, penv);
+
+    if (err == JVMTI_ERROR_NONE)
+        ncai->enabled = true;
+
+    return err;
+}
+
+ncaiError JNICALL ncaiGetJvmtiEnv(ncaiEnv *env, jvmtiEnv** jvmti_env_ptr)
+{
+    if (env == NULL)
+        return NCAI_ERROR_INVALID_ENVIRONMENT;
+
+    if (jvmti_env_ptr == NULL)
+        return NCAI_ERROR_NULL_POINTER;
+
+    *jvmti_env_ptr = (jvmtiEnv*)((NCAIEnv*)env)->ti_env;
+
+    return NCAI_ERROR_NONE;
+}
+
+GlobalNCAI::GlobalNCAI():
+    enabled(false),
+    modules(NULL),
+    step_enabled(false),
+    step_mode(NCAI_STEP_INTO)
+{
+}
+
+GlobalNCAI::~GlobalNCAI()
+{
+    // Clean modules list
+    clean_all_modules(&modules);
+}
+
+bool GlobalNCAI::isEnabled()
+{
+    return VM_Global_State::loader_env->NCAI &&
+           VM_Global_State::loader_env->NCAI->enabled;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_break.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_break.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_break.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_break.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,152 @@
+/**
+ * @author Ilya Berezhniuk
+ * @version $Revision$
+ */
+
+//#include <memory.h>
+//#include <string.h>
+//#include <stdio.h>
+
+#define LOG_DOMAIN "ncai.break"
+#include "cxxlog.h"
+#include "suspend_checker.h"
+#include "jvmti_break_intf.h"
+
+#include "ncai_utils.h"
+#include "ncai_direct.h"
+#include "ncai_internal.h"
+
+
+// Callback function for NCAI breakpoint processing
+bool ncai_process_breakpoint_event(TIEnv *env, const VMBreakPoint* bp,
+                                    const POINTER_SIZE_INT data)
+{
+    TRACE2("ncai.break", "BREAKPOINT occured, location = " << bp->addr);
+
+    VM_thread* vm_thread = p_TLS_vmthread;
+    if (!vm_thread)
+        return false;
+
+    jvmti_thread_t jvmti_thread = &vm_thread->jvmti_thread;
+
+    // This check works for current thread only
+    if (jvmti_thread->flag_ncai_handler) // Recursion
+        return true;
+
+    jvmti_thread->flag_ncai_handler = true;
+
+    NCAIEnv* ncai_env = env->ncai_env;
+    void* addr = (void*)bp->addr;
+
+    bool suspend_enabled = hythread_is_suspend_enabled();
+
+    if (!suspend_enabled)
+        hythread_suspend_enable();
+
+    hythread_t hythread = hythread_self();
+    ncaiThread thread = reinterpret_cast<ncaiThread>(hythread);
+
+    ncaiBreakpoint func =
+        (ncaiBreakpoint)ncai_env->get_event_callback(NCAI_EVENT_BREAKPOINT);
+
+    if (NULL != func)
+    {
+        if (ncai_env->global_events[NCAI_EVENT_BREAKPOINT - NCAI_MIN_EVENT_TYPE_VAL])
+        {
+            TRACE2("ncai.break", "Calling global breakpoint callback, address = " << addr);
+
+            func((ncaiEnv*)ncai_env, thread, addr);
+
+            TRACE2("ncai.break", "Finished global breakpoint callback, address = " << addr);
+        }
+        else
+        {
+
+            ncaiEventThread* next_et;
+            ncaiEventThread* first_et =
+                ncai_env->event_threads[NCAI_EVENT_BREAKPOINT - NCAI_MIN_EVENT_TYPE_VAL];
+
+            for (ncaiEventThread* et = first_et; NULL != et; et = next_et)
+            {
+                next_et = et->next;
+
+                if (et->thread == thread)
+                {
+                    TRACE2("ncai.break", "Calling local breakpoint callback, address = " << addr);
+
+                    func((ncaiEnv*)ncai_env, thread, addr);
+
+                    TRACE2("ncai.break", "Finished local breakpoint callback, address = " << addr);
+                }
+
+                et = next_et;
+            }
+        }
+    }
+
+    if (!suspend_enabled)
+        hythread_suspend_disable();
+
+    jvmti_thread->flag_ncai_handler = false;
+    return true;
+}
+
+
+ncaiError JNICALL
+ncaiSetBreakpoint(ncaiEnv *env, void* code_addr)
+{
+    TRACE2("ncai.break", "SetBreakpoint called");
+    SuspendEnabledChecker sec;
+
+    if (env == NULL)
+        return NCAI_ERROR_INVALID_ENVIRONMENT;
+
+    if (code_addr == NULL)
+        return NCAI_ERROR_INVALID_ADDRESS;
+
+    NCAIEnv *p_env = (NCAIEnv*)env;
+    VMBreakInterface* brpt_intf = p_env->brpt_intf;
+    VMBreakPoints *vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+    LMAutoUnlock lock(vm_breaks->get_lock());
+
+    VMBreakPointRef* bp_ref = brpt_intf->find_reference(code_addr);
+
+    if (NULL != bp_ref)
+        return NCAI_ERROR_DUPLICATE;
+
+    if (!brpt_intf->add_reference(code_addr, 0))
+        return NCAI_ERROR_INTERNAL;
+
+    TRACE2("ncai.break", "SetBreakpoint is successfull");
+    return NCAI_ERROR_NONE;
+}
+
+
+ncaiError JNICALL
+ncaiClearBreakpoint(ncaiEnv *env, void* code_addr)
+{
+    TRACE2("ncai.break", "ClearBreakpoint called");
+    SuspendEnabledChecker sec;
+
+    if (env == NULL)
+        return NCAI_ERROR_INVALID_ENVIRONMENT;
+
+    if (code_addr == NULL)
+        return NCAI_ERROR_INVALID_ADDRESS;
+
+    NCAIEnv *p_env = (NCAIEnv*)env;
+    VMBreakInterface* brpt_intf = p_env->brpt_intf;
+    VMBreakPoints *vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+    LMAutoUnlock lock(vm_breaks->get_lock());
+
+    VMBreakPointRef* bp_ref = brpt_intf->find_reference(code_addr);
+
+    if (NULL == bp_ref)
+        return NCAI_ERROR_NOT_FOUND;
+
+    if (!brpt_intf->remove_reference(bp_ref))
+        return NCAI_ERROR_INTERNAL;
+
+    TRACE2("ncai.break", "ClearBreakpoint is successfull");
+    return NCAI_ERROR_NONE;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_break.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_event.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_event.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_event.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_event.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,359 @@
+/**
+ * @author Intel, Petr Ivanov
+ * @version $Revision$
+ */
+
+/**
+ * NCAI event management
+ *
+ */
+
+#define LOG_DOMAIN "ncai.events"
+#include "cxxlog.h"
+
+#include "suspend_checker.h"
+#include "thread_generic.h"
+#include "environment.h"
+#include "jvmti_internal.h"
+#include "jvmti_break_intf.h"
+#include "open/ncai_thread.h"
+#include "ncai_direct.h"
+#include "ncai_internal.h"
+#include "ncai_utils.h"
+
+
+static ncaiError ncai_add_event_to_thread(ncaiEnv *, ncaiEventKind, ncaiThread);
+static void ncai_remove_event_from_thread(ncaiEnv *, ncaiEventKind, ncaiThread);
+static void ncai_add_event_to_global(ncaiEnv *, ncaiEventKind);
+static void ncai_remove_event_from_global(ncaiEnv *, ncaiEventKind);
+static ncaiError ncai_check_start_single_step(NCAIEnv* env);
+static ncaiError ncai_check_stop_single_step(NCAIEnv* env);
+
+/*
+ * Set Event Callbacks
+ *
+ * Set the functions to be called for each event.
+ *
+ */
+
+ncaiError JNICALL
+ncaiSetEventCallbacks(ncaiEnv* env,
+                       ncaiEventCallbacks* callbacks,
+                       size_t size)
+{
+    TRACE2("ncai.events", "SetEventCallbacks called");
+    SuspendEnabledChecker sec;
+
+    if (size <= 0)
+        return NCAI_ERROR_ILLEGAL_ARGUMENT;
+
+    if (callbacks != NULL)
+        memcpy(&(((NCAIEnv*)env)->event_table), callbacks, sizeof(ncaiEventCallbacks));
+    else
+        memset(&(((NCAIEnv*)env)->event_table), 0, sizeof(ncaiEventCallbacks));
+
+    return NCAI_ERROR_NONE;
+}
+
+/*
+ * Set Event Callbacks
+ *
+ * Get the list od functions to be called for each event.
+ *
+ */
+ncaiError JNICALL
+ncaiGetEventCallbacks(ncaiEnv* env,
+                       ncaiEventCallbacks* callbacks,
+                       size_t size)
+{
+    TRACE2("ncai.events", "GetEventCallbacks called");
+    SuspendEnabledChecker sec;
+
+    if (size <= 0)
+        return NCAI_ERROR_ILLEGAL_ARGUMENT;
+
+    if (callbacks == NULL)
+        return NCAI_ERROR_NULL_POINTER;
+
+    memcpy(callbacks, &(((NCAIEnv*)env)->event_table), sizeof(ncaiEventCallbacks));
+
+    return NCAI_ERROR_NONE;
+}
+
+/*
+ * Set Event Notification Mode
+ *
+ * Control the generation of events.
+ */
+ncaiError JNICALL
+ncaiSetEventNotificationMode(ncaiEnv* env,
+                              ncaiEventMode mode,
+                              ncaiEventKind event_type,
+                              ncaiThread event_thread)
+{
+    TRACE2("ncai.event", "SetEventNotificationMode called," <<
+        "event type = " << event_type << " mode = " << mode);
+    SuspendEnabledChecker sec;
+
+    if (mode == NCAI_ENABLE)
+    {
+        if (event_thread == NULL)
+            ncai_add_event_to_global(env, event_type);
+        else
+        {
+            ncaiError result = ncai_add_event_to_thread(env, event_type, event_thread);
+            if (result != NCAI_ERROR_NONE)
+                return result;
+        }
+
+        if (event_type == NCAI_EVENT_STEP)
+        {
+            ncaiError result = ncai_check_start_single_step((NCAIEnv*)env);
+
+            if (result != NCAI_ERROR_NONE)
+                return result;
+        }
+    }
+    else if (mode == NCAI_DISABLE)
+    {
+        if (event_thread == NULL)
+            ncai_remove_event_from_global(env, event_type);
+        else
+            ncai_remove_event_from_thread(env, event_type, event_thread);
+
+        if (event_type == NCAI_EVENT_STEP)
+        {
+            ncaiError result = ncai_check_stop_single_step((NCAIEnv*)env);
+
+            if (result != NCAI_ERROR_NONE)
+                return result;
+        }
+    }
+    else
+    {
+        return NCAI_ERROR_ILLEGAL_ARGUMENT;
+    }
+
+    return NCAI_ERROR_NONE;
+}
+
+/*
+ * Set Step Mode for given thread
+ * If thread is NULL, set mode for all known threads
+ */
+ncaiError JNICALL
+ncaiSetStepMode(ncaiEnv* env,
+                ncaiThread thread,
+                ncaiStepMode mode)
+{
+    TRACE2("ncai.event", "SetStepMode called," <<
+        "thread = " << thread << " mode = " << mode);
+    SuspendEnabledChecker sec;
+
+    if (mode < NCAI_STEP_OFF || mode > NCAI_STEP_OUT)
+        return NCAI_ERROR_ILLEGAL_ARGUMENT;
+
+    GlobalNCAI* ncai = VM_Global_State::loader_env->NCAI;
+    hythread_t hythread = reinterpret_cast<hythread_t>(thread);
+    VMBreakPoints* vm_brpt = ((NCAIEnv*)env)->ti_env->vm->vm_env->TI->vm_brpt;
+    vm_thread_t vm_thread = jthread_get_vm_thread(hythread);
+
+    assert(vm_thread);
+    if (vm_thread == NULL)
+        return NCAI_ERROR_INTERNAL;
+
+    jvmti_thread_t jvmti_thread = &vm_thread->jvmti_thread;
+
+    LMAutoUnlock lock(vm_brpt->get_lock());
+
+    if (thread)
+    {
+        ncai_check_alloc_ss_data(jvmti_thread);
+        jvmti_thread->ncai_ss->use_local_mode = true;
+        jvmti_thread->ncai_ss->step_mode = mode;
+        jvmti_thread->ncai_ss->flag_out = false;
+        return NCAI_ERROR_NONE;
+    }
+
+    ncaiThread* threads;
+    jint thread_count;
+
+    ncaiError err = ncaiGetAllThreads((ncaiEnv*)env, &thread_count, &threads);
+
+    if (err != NCAI_ERROR_NONE)
+        return err;
+
+    assert(thread_count > 0);
+
+    for (jint i = 0; i < thread_count; i++)
+    {
+        hythread = (hythread_t)threads[i];
+        vm_thread = jthread_get_vm_thread(hythread);
+
+        if (!vm_thread)
+            continue;
+
+        ncai_check_alloc_ss_data(&vm_thread->jvmti_thread);
+        vm_thread->jvmti_thread.ncai_ss->use_local_mode = false;
+        vm_thread->jvmti_thread.ncai_ss->flag_out = false;
+    }
+
+    ncai->step_mode = mode;
+
+    return NCAI_ERROR_NONE;
+}
+
+
+//////////////////////
+// Helper Functions
+//////////////////////
+
+// Must be called under breakpoint lock
+ncaiStepMode ncai_get_thread_ss_mode(jvmti_thread_t jvmti_thread)
+{
+    assert(jvmti_thread->ncai_ss);
+
+    if (jvmti_thread->ncai_ss->use_local_mode)
+        return jvmti_thread->ncai_ss->step_mode;
+
+    return VM_Global_State::loader_env->NCAI->step_mode;
+}
+
+ncaiError ncai_add_event_to_thread(ncaiEnv *env, ncaiEventKind event_type,
+                                   ncaiThread event_thread)
+{
+    NCAIEnv *p_env = (NCAIEnv *)env;
+    ncaiEventThread *et =p_env->event_threads[event_type - NCAI_MIN_EVENT_TYPE_VAL];
+
+    // Find out if this environment is already registered
+    // on this thread on this event type
+    while (et != NULL)
+    {
+        if (et->thread == event_thread)
+            return NCAI_ERROR_NONE;
+
+        et = et->next;
+    }
+
+    ncaiEventThread *newet;
+    newet = (ncaiEventThread *) ncai_alloc(sizeof(ncaiEventThread));
+
+    if (newet == NULL)
+        return NCAI_ERROR_OUT_OF_MEMORY;
+
+    newet->thread = event_thread;
+
+    LMAutoUnlock aulock(p_env->env_lock); //ncai env general lock
+
+    newet->next = p_env->event_threads[event_type - NCAI_MIN_EVENT_TYPE_VAL];
+    p_env->event_threads[event_type - NCAI_MIN_EVENT_TYPE_VAL] = newet;
+    return NCAI_ERROR_NONE;
+}
+
+void ncai_remove_event_from_thread(ncaiEnv *env, ncaiEventKind event_type,
+                                   ncaiThread event_thread)
+{
+    NCAIEnv *p_env = (NCAIEnv *)env;
+    ncaiEventThread *et =
+        p_env->event_threads[event_type - NCAI_MIN_EVENT_TYPE_VAL];
+
+    LMAutoUnlock aulock(p_env->env_lock); //ncai env general lock
+
+    // Address of 'next' in previous list item or address of list root
+    // Is a place where current->next must be placed when removing item
+    ncaiEventThread **plast_next = &(p_env->event_threads[event_type - NCAI_MIN_EVENT_TYPE_VAL]);
+
+    // Find out if this environment is already registered
+    // on this thread on this event type
+    for (ncaiEventThread* current = et; current != NULL; current = current->next)
+    {
+        if (current->thread == event_thread)
+        {
+            *plast_next = current->next;
+            ncai_free(current);
+            return;
+        }
+        plast_next = &current->next;
+    }
+}
+
+void ncai_add_event_to_global(ncaiEnv *env, ncaiEventKind event_type)
+{
+    NCAIEnv *p_env = (NCAIEnv *)env;
+    p_env->global_events[event_type - NCAI_MIN_EVENT_TYPE_VAL] = true;
+}
+
+void ncai_remove_event_from_global(ncaiEnv *env, ncaiEventKind event_type)
+{
+    NCAIEnv *p_env = (NCAIEnv *)env;
+    p_env->global_events[event_type - NCAI_MIN_EVENT_TYPE_VAL] = false;
+}
+
+static ncaiError ncai_check_start_single_step(NCAIEnv* env)
+{
+    if (env->ti_env->vm->vm_env->NCAI->step_enabled)
+        return NCAI_ERROR_NONE;
+
+    return ncai_start_single_step(env);
+}
+
+static ncaiError ncai_check_stop_single_step(NCAIEnv* env)
+{
+    DebugUtilsTI* ti = env->ti_env->vm->vm_env->TI;
+    GlobalNCAI* ncai = env->ti_env->vm->vm_env->NCAI;
+
+    if (!ncai->step_enabled)
+        return NCAI_ERROR_NONE;
+
+    // Check that no environment has SingleStep enabled
+    LMAutoUnlock lock(&ti->TIenvs_lock);
+    bool disable = true;
+
+    for (TIEnv *ti_env = ti->getEnvironments(); ti_env;
+         ti_env = ti_env->next)
+    {
+        if (!ti_env->ncai_env)
+            continue;
+
+        if (ti_env->ncai_env->global_events[NCAI_EVENT_STEP - NCAI_MIN_EVENT_TYPE_VAL] ||
+            ti_env->ncai_env->event_threads[NCAI_EVENT_STEP - NCAI_MIN_EVENT_TYPE_VAL])
+        {
+            disable = false;
+            break;
+        }
+    }
+
+    return disable ? ncai_stop_single_step(env) : NCAI_ERROR_NONE;
+}
+
+void ncai_report_method_entry(jmethodID method)
+{
+    GlobalNCAI* ncai = VM_Global_State::loader_env->NCAI;
+
+    if (!GlobalNCAI::isEnabled())
+        return;
+
+    assert(method);
+
+    Method* m = reinterpret_cast<Method*>(method);
+    bool is_native = m->is_native();
+
+    if (is_native && ncai->step_enabled)
+        ncai_step_native_method_entry(m);
+}
+
+void ncai_report_method_exit(jmethodID method, jboolean exc_popped, jvalue ret_val)
+{
+    GlobalNCAI* ncai = VM_Global_State::loader_env->NCAI;
+
+    if (!GlobalNCAI::isEnabled())
+        return;
+
+    assert(method);
+
+    Method* m = reinterpret_cast<Method*>(method);
+    bool is_native = m->is_native();
+
+    if (is_native && ncai->step_enabled)
+        ncai_step_native_method_exit(m);
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_event.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_memory.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_memory.cpp?rev=597138&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_memory.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_memory.cpp Wed Nov 21 08:29:40 2007
@@ -0,0 +1,168 @@
+/**
+ * @author Petr Ivanov
+ * @version $Revision$
+ */
+#define LOG_DOMAIN "ncai.memory"
+#include "cxxlog.h"
+#include "jvmti_break_intf.h"
+#include "environment.h"
+#include "jvmti_internal.h"
+#include "ncai_direct.h"
+#include "ncai_internal.h"
+
+
+struct BreakListItem
+{
+    VMBreakPoint*   bp;
+    BreakListItem*  next;
+};
+
+struct RewriteArray
+{
+    BreakListItem*  array;
+    BreakListItem*  list;
+    size_t          size;
+    size_t          count;
+};
+
+static void add_rewrite_address(RewriteArray* prwa, VMBreakPoint* bp);
+
+
+ncaiError JNICALL ncaiReadMemory(ncaiEnv* env,
+        void* addr, size_t size, void* buf)
+{
+    TRACE2("ncai.memory", "ReadMemory called");
+
+    if (!env)
+        return NCAI_ERROR_INVALID_ENVIRONMENT;
+
+    ncaiError err = ncai_read_memory(addr, size, buf);
+
+    if (err != NCAI_ERROR_NONE)
+        return err;
+
+    // Restore bytes changed by JVMTI/NCAI breakpoints
+    VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+    LMAutoUnlock lock(vm_breaks->get_lock());
+
+    void* end_addr = (char*)addr + size;
+    jbyte* cbuf = (jbyte*)buf;
+
+    for (VMBreakPoint* cur = vm_breaks->get_first_breakpoint(); cur;
+         cur = vm_breaks->get_next_breakpoint(cur))
+    {
+        if (cur->addr >= addr && cur->addr < end_addr)
+        {
+            size_t offset = (size_t)cur->addr - (size_t)addr;
+            cbuf[offset] = cur->saved_byte;
+        }
+    }
+
+    return NCAI_ERROR_NONE;
+}
+
+ncaiError JNICALL ncaiWriteMemory(ncaiEnv* env,
+        void* addr, size_t size, void* buf)
+{
+    TRACE2("ncai.memory", "WriteMemory called");
+
+    if (!env)
+        return NCAI_ERROR_INVALID_ENVIRONMENT;
+
+    VMBreakPoints* vm_breaks = VM_Global_State::loader_env->TI->vm_brpt;
+    LMAutoUnlock lock(vm_breaks->get_lock());
+
+    jbyte* end_addr = (jbyte*)addr + size;
+    VMBreakPoint* cur;
+    size_t rewrite_count = 0;
+
+    // Count addresses in given range
+    for (cur = vm_breaks->get_first_breakpoint(); cur;
+         cur = vm_breaks->get_next_breakpoint(cur))
+    {
+        if (cur->addr >= addr && cur->addr < end_addr)
+            ++rewrite_count;
+    }
+
+    // Simple case: there are no breakpoints in specified address range
+    if (rewrite_count == 0)
+        return ncai_write_memory(addr, size, buf);
+
+    // Allocate array for address sorting
+    RewriteArray rwa;
+    rwa.array = (BreakListItem*)STD_MALLOC(rewrite_count*sizeof(BreakListItem));
+
+    if (!rwa.array)
+        return NCAI_ERROR_OUT_OF_MEMORY;
+
+    memset(rwa.array, 0, rewrite_count*sizeof(BreakListItem));
+    rwa.list = NULL;
+    rwa.size = rewrite_count;
+    rwa.count = 0;
+
+    // Add matching addresses to sorted list
+    for (cur = vm_breaks->get_first_breakpoint(); cur;
+         cur = vm_breaks->get_next_breakpoint(cur))
+    {
+        if (cur->addr >= addr && cur->addr < end_addr)
+            add_rewrite_address(&rwa, cur);
+    }
+
+    // Write memory
+    size_t remain = size;
+    BreakListItem* cur_bla = rwa.list;
+    assert(cur_bla);
+    jbyte* cbuf = (jbyte*)buf;
+    jbyte* cur_addr = (jbyte*)addr;
+    ncaiError err = NCAI_ERROR_NONE;
+
+    while (remain)
+    {
+        if (!cur_bla || cur_bla->bp->addr > cur_addr)
+        { // Write buffer to memory
+            size_t offset = (size_t)cur_addr - (size_t)addr;
+            size_t chunk_size = cur_bla ? ((jbyte*)cur_bla->bp->addr - cur_addr)
+                                        : (end_addr - cur_addr);
+            err = ncai_write_memory(cur_addr, chunk_size, cbuf + offset);
+
+            if (err != NCAI_ERROR_NONE)
+                break;
+
+            cur_addr += chunk_size;
+            remain -= chunk_size;
+        }
+
+        if (cur_bla)
+        { // Write byte from buffer to 'saved_byte' field in breakpoint
+            assert(cur_addr == cur_bla->bp->addr);
+
+            size_t offset = (size_t)cur_addr - (size_t)addr;
+            cur_bla->bp->saved_byte = cbuf[offset];
+            cur_bla = cur_bla->next;
+            ++cur_addr;
+            --remain;
+        }
+    }
+
+    STD_FREE(rwa.array);
+    return err;
+}
+
+// Adding sorted item into rewrite list
+static void add_rewrite_address(RewriteArray* prwa, VMBreakPoint* bp)
+{
+    assert(prwa && prwa->array && prwa->size && bp);
+
+    BreakListItem** pcur = &prwa->list;
+
+    // Look for place for insertion
+    while (*pcur && (*pcur)->bp->addr < bp->addr)
+        pcur = &((*pcur)->next);
+
+    BreakListItem* freeitem = prwa->array + prwa->count++;
+    assert(prwa->count <= prwa->size);
+
+    freeitem->next = *pcur;
+    *pcur = freeitem;
+    freeitem->bp = bp;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/ncai/ncai_memory.cpp
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message