You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by wj...@apache.org on 2007/07/30 21:07:40 UTC

svn commit: r561096 - in /harmony/enhanced/drlvm/trunk: build/make/components/vm/ build/make/targets/ vm/include/open/ vm/port/src/lil/em64t/pim/ vm/tests/smoke/thread/ vm/vmcore/include/ vm/vmcore/src/thread/ vm/vmcore/src/thread/helpers/ vm/vmcore/sr...

Author: wjwashburn
Date: Mon Jul 30 12:07:39 2007
New Revision: 561096

URL: http://svn.apache.org/viewvc?view=rev&rev=561096
Log:
H3231, 3397, 3415, 3972, 4489  committed.  These are
a collection of threading patches that do not interfere
with the threading redesign that is currently underway



Added:
    harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/SmallStackThreadTest.java
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_em64t.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp
Removed:
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers.cpp
Modified:
    harmony/enhanced/drlvm/trunk/build/make/components/vm/hythr.xml
    harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml
    harmony/enhanced/drlvm/trunk/build/make/targets/common_vm.xml
    harmony/enhanced/drlvm/trunk/vm/include/open/hythread.h
    harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
    harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/m2n_em64t.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/m2n_em64t_internal.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_ipf.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_monitors.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/compile_em64t.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/jit_runtime_support_em64t.cpp

Modified: harmony/enhanced/drlvm/trunk/build/make/components/vm/hythr.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/make/components/vm/hythr.xml?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/make/components/vm/hythr.xml (original)
+++ harmony/enhanced/drlvm/trunk/build/make/components/vm/hythr.xml Mon Jul 30 12:07:39 2007
@@ -102,7 +102,7 @@
             </select>
 
             <select os="lnx">
-                <syslibset libs="stdc++,rt" />
+                <syslibset libs="stdc++,rt,pthread" />
                 <linkerarg value="-Wl,-init" />
                 <linkerarg value="-Wl,hythread_library_init" />
                 <linkerarg value="-Wl,--version-script,${src}/thread/src/hythr.exp" />

Modified: harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml (original)
+++ harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml Mon Jul 30 12:07:39 2007
@@ -82,10 +82,8 @@
                 <include name="reflection/*.cpp" />
                 <include name="stack/*.cpp" />
                 <include name="thread/*.cpp" />
-                <select arch="ia32">
-                    <include name="thread/helpers/thread_helpers.cpp" />
-                    <include name="thread/helpers/thread_helpers_${build.arch}.cpp" />
-                </select>
+                <include name="thread/helpers/thread_helpers.cpp" />
+                <include name="thread/helpers/thread_helpers_${build.arch}.cpp" />
                 <include name="util/*.cpp" />
                 <include name="verifier/*.cpp" if="use_original_verifier"/>
                 <include name="verifier-3363/*.cpp" unless="use_original_verifier"/>

Modified: harmony/enhanced/drlvm/trunk/build/make/targets/common_vm.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/make/targets/common_vm.xml?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/make/targets/common_vm.xml (original)
+++ harmony/enhanced/drlvm/trunk/build/make/targets/common_vm.xml Mon Jul 30 12:07:39 2007
@@ -103,6 +103,10 @@
                 <defineset define="_REENTRANT" />
                 <defineset define="LINUX_TLS_OPT" />
 
+                <select arch="em64t">
+                    <compilerarg value="-ftls-model=initial-exec" /> 
+                </select>
+                
                 <select arch="ia32">
                     <defineset define="_LARGEFILE64_SOURCE" />
                 </select>

Modified: harmony/enhanced/drlvm/trunk/vm/include/open/hythread.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/hythread.h?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/hythread.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/hythread.h Mon Jul 30 12:07:39 2007
@@ -402,9 +402,20 @@
    
 
 
-#if (defined (_WIN32) && !defined (_WIN64))
-//use optimized asm monitor enter and exit helpers
-#define ASM_MONITOR_HELPER
+#ifdef _EM64T_
+#   ifdef _WIN64
+        //don't use optimized asm monitor enter and exit helpers
+#   else
+        //use optimized asm monitor enter and exit helpers
+#       define ASM_MONITOR_HELPER
+#   endif
+#else
+#ifdef _IPF_
+    //don't use optimized asm monitor enter and exit helpers
+#else
+    //use optimized asm monitor enter and exit helpers
+#   define ASM_MONITOR_HELPER
+#endif
 #endif
 
 #if defined (_WIN32)

Modified: harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h Mon Jul 30 12:07:39 2007
@@ -508,7 +508,6 @@
 // possible values for tm_status_t
 #define TM_OS_ERROR (TM_ERROR_START+1)
 
-#define TM_MAX_OWNED_MONITOR_NUMBER 200 //FIXME: switch to dynamic resize
 // if default stack size is not through -Xss parameter, it is 256kb
 #define TM_DEFAULT_STACKSIZE (512 * 1024)
 

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/m2n_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/m2n_em64t.cpp?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/m2n_em64t.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/m2n_em64t.cpp Mon Jul 30 12:07:39 2007
@@ -134,6 +134,12 @@
 
 /*    Internal Interface    */
 
+unsigned m2n_ts_to_register_size(unsigned num_std_need_to_save,
+                                 unsigned num_ret_need_to_save) {
+    return 13 + (6 * num_std_need_to_save) +
+            3 + (6 * num_ret_need_to_save);
+}
+
 // rsp should point to the bottom of the activation frame since push may occur
 // inputs should be preserved outside if required since we do a call
 // num_std_need_to_save registers will be preserved
@@ -264,6 +270,12 @@
     return buf;
 }
 
+unsigned m2n_push_m2n_size(unsigned num_callee_saves,
+                           unsigned num_std_need_to_save) {
+    return 82 - (5 * num_callee_saves) +
+            m2n_ts_to_register_size(num_std_need_to_save, 0);
+}
+
 // inputs should be preserved outside if required since we do a call
 // num_std_need_to_save registers will be preserved
 char * m2n_gen_push_m2n(char * buf, Method_Handle method, 
@@ -323,6 +335,11 @@
     return buf;
 }
 
+unsigned m2n_pop_m2n_size(bool handles, unsigned num_callee_saves, unsigned preserve_ret)
+{
+    return 56 - 5*num_callee_saves + (preserve_ret ? 4: 0);
+}
+
 static void m2n_pop_local_handles() {
     assert(!hythread_is_suspend_enabled());
     
@@ -399,8 +416,9 @@
             size_64);
         bytes_to_m2n_bottom += LcgEM64TContext::GR_SIZE;
     }
+
     return buf;
-}
+}//m2n_gen_pop_m2n
 
 // returns pointer to the registers used for jvmti PopFrame
 Registers* get_pop_frame_registers(M2nFrame* m2nf) {

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/m2n_em64t_internal.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/m2n_em64t_internal.h?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/m2n_em64t_internal.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/lil/em64t/pim/m2n_em64t_internal.h Mon Jul 30 12:07:39 2007
@@ -85,6 +85,7 @@
 char * m2n_gen_ts_to_register(char * buf, const R_Opnd * reg,
                               unsigned num_callee_saves_used, unsigned num_callee_saves_max,
                               unsigned num_std_need_to_save, unsigned num_ret_need_to_save);
+unsigned m2n_ts_to_register_size(unsigned num_std_need_to_save, unsigned num_ret_need_to_save);
 
 /**
  * Generate code to set the local handles of an M2nFrame.
@@ -107,6 +108,7 @@
  */
 char * m2n_gen_push_m2n(char * buf, Method_Handle method, frame_type current_frame_type, bool handles,
                         unsigned num_callee_saves, unsigned num_std_need_to_save, int32 bytes_to_m2n_top);
+unsigned m2n_push_m2n_size(unsigned num_callee_saves, unsigned num_std_need_to_save);
 
 /**
  * Generate code to pop an M2nFrame off the stack.
@@ -119,6 +121,7 @@
  */
 char * m2n_gen_pop_m2n(char * buf, bool handles, unsigned num_callee_saves,
                        int32 bytes_to_m2n_bottom, unsigned preserve_ret);
+unsigned m2n_pop_m2n_size(bool handles, unsigned num_callee_saves, unsigned preserve_ret);
 
 // returns top of the specified frame on the stack (it should point to return ip)
 void * m2n_get_frame_base(M2nFrame *);

Added: harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/SmallStackThreadTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/SmallStackThreadTest.java?view=auto&rev=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/SmallStackThreadTest.java (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/SmallStackThreadTest.java Mon Jul 30 12:07:39 2007
@@ -0,0 +1,88 @@
+/*
+ *  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.
+ *  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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package thread;
+
+public class SmallStackThreadTest implements Runnable
+{
+    private static final int MAX_THREADS = 4 * 1024;
+    private static final int STACK_SIZE = 256 * 1024;
+
+    private static int started = 0;
+    private static int finished = 0;
+    private static Object awake = new Object();
+    private static boolean awaked = false;
+
+    public static void main(String [] args) {
+        Thread[] threads = new Thread[MAX_THREADS];
+        for (int i = 0; i < MAX_THREADS; i++) {
+            threads[i] = new Thread( null,
+                                 new SmallStackThreadTest(),
+                                 "Test Thread " + i,
+                                 STACK_SIZE);
+            threads[i].start();
+
+            if ((i%100) == 0) {
+                System.out.println("Start Thread " + i);
+            }
+        }
+
+        synchronized(awake){
+            awaked = true;
+            awake.notifyAll();
+        }
+
+        for (int i = 0; i < MAX_THREADS; i++) {
+            try {
+                threads[i].join();
+            } catch (Throwable th) {
+                System.out.println("Was caught " + th);
+            }
+        }
+
+        synchronized(SmallStackThreadTest.class) {
+            if (started != MAX_THREADS) {
+                System.out.println("FAILED");
+            } else if (finished != MAX_THREADS) {
+                System.out.println("FAILED");
+            } else {
+                System.out.println("PASSED");
+            }
+        }
+    }
+
+    public void run() {
+        synchronized(SmallStackThreadTest.class) {
+            SmallStackThreadTest.started++;
+        }
+
+        try {
+            synchronized(awake){
+                if (!awaked) {
+                    awake.wait();
+                }
+            }
+        } catch (Throwable th) {
+            System.out.println("Was caught " + th);
+        }
+
+        synchronized(SmallStackThreadTest.class) {
+            SmallStackThreadTest.finished++;
+        }
+    }
+} 
+

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/thread_manager.h Mon Jul 30 12:07:39 2007
@@ -25,6 +25,7 @@
 #define GC_BYTES_IN_THREAD_LOCAL (20 * sizeof(void *))
 #define CONVERT_ERROR(stat)	(stat)
 #define TM_JVMTI_MAX_BUFFER_SIZE 50
+#define TM_INITIAL_OWNED_MONITOR_SIZE 32
 
 #ifdef __cplusplus
 extern "C"
@@ -94,6 +95,11 @@
      * owned monitors count.
      */
     int owned_monitors_nmb;
+
+    /**
+     * owned monitors array size.
+     */
+     int owned_monitors_size;
 
     /**
      * For support of JVMTI events: EXCEPTION, EXCEPTION_CATCH

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_em64t.cpp?view=auto&rev=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_em64t.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_em64t.cpp Mon Jul 30 12:07:39 2007
@@ -0,0 +1,275 @@
+/*
+ *  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.
+ *  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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @author Artem Aliev
+ * @version $Revision: 1.1.2.11 $
+ */
+
+/**
+ * @file thread_helpers.cpp
+ * @brief Set of VM helpers
+ *
+ * This file contains the set of "VM helpers" which help to optimize monitors performance
+ * in the code generated by JIT compiler. Typically, these functions will be called by JIT,
+ * but VM also could also use them with care.
+ */
+
+#include <open/hythread_ext.h>
+#include <open/thread_helpers.h>
+#include "open/thread_externals.h"
+#include "open/jthread.h"
+
+#include <assert.h>
+
+/**
+  *  Generates tmn_self() call.
+  *  The code should not contains safepoint.
+  *  The code uses and doesn't restore eax register.
+  *
+  *  @return tm_self() in eax register
+  */
+char* gen_hythread_self_helper(char *ss) {
+#ifdef HYTHREAD_FAST_TLS
+    // offset isn't too large so we can use 32-bit value
+    unsigned offset = hythread_get_hythread_offset_in_tls();
+    // fs register uses for tls acces on linux x86-32
+    //ss = mov(ss,  rdx_opnd,  M_Base_Opnd(fs_reg, 0x00));
+    *ss++ = (char)0x64;
+    *ss++ = (char)0x48;
+    *ss++ = (char)0x8b;
+    *ss++ = (char)0x14;
+    *ss++ = (char)0x25;
+    *ss++ = (char)0x00;
+    *ss++ = (char)0x00;
+    *ss++ = (char)0x00;
+    *ss++ = (char)0x00;
+    ss = mov(ss,  rax_opnd,  M_Base_Opnd(rdx_reg, offset));
+#else
+    ss = call(ss, (char *)hythread_self);
+#endif
+    return ss;
+}
+
+
+/**
+  *  Generates fast path of monitor enter
+  *  the code should not contains safepoint.
+  *
+  *  @param[in] ss buffer to put the assembly code to
+  *  @param[in] input_param1 register which should point to the object lockword.
+  *  If input_param1 == ecx it reduces one register mov.
+  *  the code use and do not restore ecx, edx, eax registers
+  *
+  *  @return 0 if success in eax register
+  */
+char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) {
+
+    if (&input_param1 != &rdi_opnd) {
+        ss = mov(ss, rdi_opnd,  input_param1);
+    }
+
+#ifdef ASM_MONITOR_HELPER
+
+    //get self_id
+    ss = push(ss, rdi_opnd);
+    ss = gen_hythread_self_helper(ss);
+    ss = pop(ss, rdi_opnd);
+
+    ss = mov(ss,  rdx_opnd,  M_Base_Opnd(rax_reg,
+            hythread_get_thread_id_offset()));                   //mov rdx,dword [rax+off]
+
+    ss = mov(ss, rax_opnd, M_Base_Opnd(rdi_reg, 2), size_16);    // mov ax,word[ecx+2]
+	ss = alu(ss, cmp_opc, rdx_opnd, rax_opnd, size_16);          // cmp dx,ax
+    ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0));         // jnz check_zero
+    char *check_zero = ((char *)ss) - 1;
+
+    //; ax==dx it's safe to do inc
+	ss = mov(ss, rax_opnd, M_Base_Opnd(rdi_reg, 1), size_8);     // mov al, byte[rdi+1]
+
+    //rec_inc:
+    ss = alu(ss, add_opc, rax_opnd,
+            Imm_Opnd(size_8, 0x8), size_8);                      // add al,0x8
+    ss = branch8(ss, Condition_C, Imm_Opnd(size_8, 0));          // jc failed
+    char *failed1 = ((char *)ss) - 1;
+
+    ss = mov(ss,  M_Base_Opnd(rdi_reg, 1), rax_opnd, size_8);    // mov byte[ecx+1],al
+    ss = alu(ss, add_opc, rsp_opnd, Imm_Opnd(size_8, 0x8));      // add rsp,0x8
+    ss = ret(ss);                                                // ret
+
+    //check_zero:
+    signed offset = (signed)ss - (signed)check_zero - 1;
+    *check_zero = (char)offset;
+
+    ss = test(ss, rax_opnd, rax_opnd, size_16);                  //  test ax,ax
+    ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0));         //  jnz failed
+    char *failed2 = ((char *)ss) - 1;
+
+    ss = prefix(ss, lock_prefix);                                //; here ax==0.
+    ss = cmpxchg(ss, M_Base_Opnd(rdi_reg, 2), rdx_opnd, size_16);//  lock cmpxchg16 [ecx+2],dx
+    ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0));         //  jnz failed
+    char *failed3 = ((char *)ss) - 1;
+
+#ifdef LOCK_RESERVATION
+	ss = mov(ss, rax_opnd, M_Base_Opnd(rdi_reg, 1), size_8);	 // mov al, byte[ecx+1]
+    ss = test(ss, rax_opnd, Imm_Opnd(size_8, 0x4), size_8);      // test al,0x4
+    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));        // jnz finish
+    char *finish = ((char *)ss) - 1;
+
+    ss = alu(ss, add_opc, rax_opnd, Imm_Opnd(size_8, 8), size_8);// add al,0x8
+	ss = mov(ss, M_Base_Opnd(rdi_reg, 1), rax_opnd, size_8);     // mov byte[ecx+1],al
+
+    //finish:
+    offset = (signed)ss - (signed)finish - 1;
+    *finish = (char)offset;
+#endif
+    ss = alu(ss, add_opc, rsp_opnd, Imm_Opnd(size_8, 0x8));      // add rsp,0x8
+    ss = ret(ss);                                                // ret
+
+    //failed:
+    offset = (signed)ss - (signed)failed1 - 1;
+    *failed1 = (char)offset;
+    offset = (signed)ss - (signed)failed2 - 1;
+    *failed2 = (char)offset;
+    offset = (signed)ss - (signed)failed3 - 1;
+    *failed3 = (char)offset;
+
+#endif //ASM_MONITOR_HELPER
+
+    // the second attempt to lock monitor
+    ss = call(ss, (char *)hythread_thin_monitor_try_enter);
+
+    return ss;
+}
+
+/**
+  *  Generates slow path of monitor enter.
+  *  This code could block on monitor and contains safepoint.
+  *  The appropriate m2n frame should be generated and
+  *
+  *  @param[in] ss buffer to put the assembly code to
+  *  @param[in] input_param1 register should point to the jobject(handle)
+  *  If input_param1 == eax it reduces one register mov.
+  *  the code use and do not restore ecx, edx, eax registers
+  *  @return 0 if success in eax register
+  */
+char* gen_monitorenter_slow_path_helper(char *ss, const R_Opnd & input_param1) {
+    if (&input_param1 != &rdi_opnd) {
+        ss = mov(ss, rdi_opnd,  input_param1);
+    }
+
+    ss = call(ss, (char *)jthread_monitor_enter);
+    return ss;
+}
+
+/**
+  *  Generates monitor exit.
+  *  The code should not contain safepoints.
+  *
+  *  @param[in] ss buffer to put the assembly code to
+  *  @param[in] input_param1 register should point to the lockword in object header.
+  *  If input_param1 == ecx it reduce one register mov.
+  *  The code use and do not restore eax registers.
+  *  @return 0 if success in eax register
+  */
+char* gen_monitor_exit_helper(char *ss, const R_Opnd & input_param1) {
+    if (&input_param1 != &rdi_opnd) {
+        ss = mov(ss, rdi_opnd,  input_param1);
+    }
+
+#ifdef ASM_MONITOR_HELPER
+	ss = mov(ss,  rax_opnd, M_Base_Opnd(rdi_reg, 0));            // mov rax,dword[rdi]
+	ss = test(ss, rax_opnd, Imm_Opnd(0x80000000), size_32);      // test rax,0x80000000
+	ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));        // jnz fat
+	char *fat = ((char *)ss) - 1;
+	ss = mov(ss, rax_opnd, M_Base_Opnd(rdi_reg, 1), size_8);     // mov al, byte[rdi+1]
+
+    ss = alu(ss, sub_opc, rax_opnd, Imm_Opnd(size_8,0x8),size_8);// sub al, 0x8
+	ss = branch8(ss, Condition_C,  Imm_Opnd(size_8, 0));         // jc zero_rec
+	char *zero_rec = ((char *)ss) - 1;
+	ss = mov(ss, M_Base_Opnd(rdi_reg, 1), rax_opnd, size_8);    // mov byte[rdi+1],al
+    ss = ret(ss);                                               // ret
+
+    //zero_rec:
+    signed offset = (signed)ss - (signed)zero_rec - 1;
+    *zero_rec = (char)offset;
+
+    ss = mov(ss, M_Base_Opnd(rdi_reg, 2),
+            Imm_Opnd(size_16, 0), size_16);                      // mov word[rdi+2],0
+	ss = ret(ss);                                                // ret
+
+    //fat:
+    offset = (signed)ss - (signed)fat - 1;
+    *fat = (char)offset;
+
+#endif
+
+    ss = call(ss, (char *)hythread_thin_monitor_exit);
+    return ss;
+}
+
+/**
+  *  Generates slow path of monitor exit.
+  *  This code could block on monitor and contains safepoint.
+  *  The appropriate m2n frame should be generated and
+  *
+  *  @param[in] ss buffer to put the assembly code to
+  *  @param[in] input_param1 register should point to the jobject(handle)
+  *  If input_param1 == eax it reduces one register mov.
+  *  the code use and do not restore ecx, edx, eax registers
+  *  @return 0 if success in eax register
+  */
+char* gen_monitorexit_slow_path_helper(char *ss, const R_Opnd & input_param1) {
+    if (&input_param1 != &rdi_opnd) {
+        ss = mov(ss, rdi_opnd,  input_param1);
+    }
+
+    ss = call(ss, (char *)jthread_monitor_exit);
+    return ss;
+}
+
+/**
+  * Generates fast accessor to the TLS for the given key.<br>
+  * Example:
+  * <pre><code>
+  * get_thread_ptr = get_tls_helper(vm_thread_block_key);
+  * ...
+  * self = get_thread_ptr();
+  * </code></pre>
+  *
+  * @param[in] key TLS key
+  * @return fast accessor to key, if one exist
+  */
+fast_tls_func* get_tls_helper(hythread_tls_key_t key) {
+    //     return tm_self_tls->thread_local_storage[key];
+    unsigned key_offset =
+        (unsigned) &(((HyThread_public *) (0))->thread_local_storage[key]);
+
+    const int stub_size = 126;
+    char *stub = (char *)malloc(stub_size);
+    memset(stub, 0xcc /*int 3*/, stub_size);
+
+    char *ss = stub;
+
+    ss = gen_hythread_self_helper(ss);
+    ss = mov(ss,  rax_opnd,  M_Base_Opnd(rax_reg, key_offset));
+    ss = ret(ss,  Imm_Opnd(0));
+
+    assert((ss - stub) < stub_size);
+
+    return (fast_tls_func*) stub;
+}

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp?view=auto&rev=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_ia32.cpp Mon Jul 30 12:07:39 2007
@@ -0,0 +1,274 @@
+/*
+ *  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.
+ *  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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @file thread_helpers.cpp
+ * @brief Set of VM helpers
+ *
+ * This file contains the set of "VM helpers" which help to optimize monitors performance
+ * in the code generated by JIT compiler. Typically, these functions will be called by JIT,
+ * but VM also could also use them with care.
+ */
+
+#include <open/hythread_ext.h>
+#include <open/thread_helpers.h>
+#include "open/thread_externals.h"
+#include "open/jthread.h"
+
+#include <assert.h>
+
+
+/**
+  *  Generates tmn_self() call.
+  *  The code should not contains safepoint.
+  *  The code uses and doesn't restore eax register.
+  *
+  *  @return tm_self() in eax register
+  */
+char* gen_hythread_self_helper(char *ss) {
+#ifdef HYTHREAD_FAST_TLS
+#   ifdef FS14_TLS_USE
+        //ss = mov(ss,  eax_opnd,  M_Base_Opnd(fs_reg, 0x14));
+        *ss++ = (char)0x64;
+        *ss++ = (char)0xa1;
+        *ss++ = (char)0x14;
+        *ss++ = (char)0x00;
+        *ss++ = (char)0x00;
+        *ss++ = (char)0x00;
+#   else
+        unsigned offset = hythread_get_hythread_offset_in_tls();
+        // gs register uses for tls acces on linux x86-32
+        //ss = mov(ss,  edx_opnd,  M_Base_Opnd(gs_reg, 0x00));
+        *ss++ = (char)0x65;
+        *ss++ = (char)0x8b;
+        *ss++ = (char)0x15;
+        *ss++ = (char)0x00;
+        *ss++ = (char)0x00;
+        *ss++ = (char)0x00;
+        *ss++ = (char)0x00;
+        ss = mov(ss,  eax_opnd,  M_Base_Opnd(edx_reg, offset));
+#   endif
+#else
+    ss = call(ss, (char *)hythread_self);
+#endif
+    return ss;
+}
+
+
+/**
+  *  Generates fast path of monitor enter
+  *  the code should not contains safepoint.
+  *
+  *  @param[in] ss buffer to put the assembly code to
+  *  @param[in] input_param1 register which should point to the object lockword.
+  *  If input_param1 == ecx it reduces one register mov.
+  *  the code use and do not restore ecx, edx, eax registers
+  *
+  *  @return 0 if success in eax register
+  */
+char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) {
+
+    if (&input_param1 != &ecx_opnd) {
+        ss = mov(ss, ecx_opnd,  input_param1);
+    }
+#ifdef ASM_MONITOR_HELPER
+
+    //get self_id
+    ss = gen_hythread_self_helper(ss);
+    ss = mov(ss,  edx_opnd,  M_Base_Opnd(eax_reg,
+            hythread_get_thread_id_offset()));                          // mov edx,dword [eax+off]
+
+    ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 2), size_16);           // mov ax,word[ecx+2]
+	ss = alu(ss, cmp_opc,  edx_opnd,  eax_opnd, size_16);           	// cmp dx,ax
+    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));               // jnz check_zero
+    char *check_zero = ((char *)ss) - 1;
+												                        //; ax==dx it's safe to do inc
+	ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 1), size_8);            // mov al, byte[ecx+1]
+	                                                                    //rec_inc:
+
+    ss = alu(ss, add_opc,  eax_opnd,  Imm_Opnd(size_8, 0x8), size_8);   // add al,0x8
+    ss = branch8(ss, Condition_C,  Imm_Opnd(size_8, 0));                // jc failed
+    char *failed1 = ((char *)ss) - 1;
+
+	ss = mov(ss,  M_Base_Opnd(ecx_reg, 1), eax_opnd, size_8);           // mov byte[ecx+1],al
+    ss = ret(ss,  Imm_Opnd(4));                                         // ret 4
+
+    signed offset = (signed)ss - (signed)check_zero - 1;
+    *check_zero = (char)offset;                                        //check_zero:
+
+    ss = test(ss,  eax_opnd,  eax_opnd, size_16);                      //  test ax,ax
+    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));              //  jnz failed
+    char *failed2 = ((char *)ss) - 1;
+
+    ss = prefix(ss, lock_prefix);                                      //; here ax==0.
+    ss = cmpxchg(ss,  M_Base_Opnd(ecx_reg, 2),  edx_opnd, size_16);    //  lock cmpxchg16 [ecx+2],dx
+    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));              //  jnz failed
+    char *failed3 = ((char *)ss) - 1;
+
+
+#ifdef LOCK_RESERVATION
+	ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 1), size_8);            //  mov al, byte[ecx+1]
+    ss = test(ss,  eax_opnd,  Imm_Opnd(size_8, 0x4), size_8);           //  test al,0x4
+    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));               //  jnz finish
+    char *finish = ((char *)ss) - 1;
+
+    ss = alu(ss, add_opc,  eax_opnd,  Imm_Opnd(size_8, 0x8), size_8);   // add al,0x8
+	ss = mov(ss,  M_Base_Opnd(ecx_reg, 1), eax_opnd, size_8);           // mov byte[ecx+1],al
+
+    offset = (signed)ss - (signed)finish - 1;
+    *finish = (char)offset;                            		            //finish:
+
+#endif
+    ss = ret(ss,  Imm_Opnd(4));                                         // ret 4
+
+    offset = (signed)ss - (signed)failed1 - 1;
+    *failed1 = (char)offset;                                 	        //failed:
+
+    offset = (signed)ss - (signed)failed2 - 1;
+    *failed2 = (char)offset;
+
+    offset = (signed)ss - (signed)failed3 - 1;
+    *failed3 = (char)offset;
+
+#endif //ASM_MONITOR_HELPER
+    // the second attempt to lock monitor
+    ss = push(ss,  ecx_opnd);
+    ss = call(ss, (char *)hythread_thin_monitor_try_enter);
+    ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters
+
+    return ss;
+}
+
+/**
+  *  Generates slow path of monitor enter.
+  *  This code could block on monitor and contains safepoint.
+  *  The appropriate m2n frame should be generated and
+  *
+  *  @param[in] ss buffer to put the assembly code to
+  *  @param[in] input_param1 register should point to the jobject(handle)
+  *  If input_param1 == eax it reduces one register mov.
+  *  the code use and do not restore ecx, edx, eax registers
+  *  @return 0 if success in eax register
+  */
+char* gen_monitorenter_slow_path_helper(char *ss, const R_Opnd & input_param1) {
+    if (&input_param1 != &eax_opnd) {
+        ss = mov(ss, eax_opnd,  input_param1);
+    }
+
+    ss = push(ss, eax_opnd); // push the address of the handle
+    ss = call(ss, (char *)jthread_monitor_enter);
+    ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters
+    return ss;
+}
+
+/**
+  *  Generates monitor exit.
+  *  The code should not contain safepoints.
+  *
+  *  @param[in] ss buffer to put the assembly code to
+  *  @param[in] input_param1 register should point to the lockword in object header.
+  *  If input_param1 == ecx it reduce one register mov.
+  *  The code use and do not restore eax registers.
+  *  @return 0 if success in eax register
+  */
+char* gen_monitor_exit_helper(char *ss, const R_Opnd & input_param1) {
+    if (&input_param1 != &ecx_opnd) {
+        ss = mov(ss, ecx_opnd,  input_param1);
+    }
+#ifdef ASM_MONITOR_HELPER
+	ss = mov(ss,  eax_opnd, M_Base_Opnd(ecx_reg, 0));               //  mov eax,dword[ecx]
+	ss = test(ss, eax_opnd, Imm_Opnd(0x80000000), size_32);         //  test eax,0x80000000
+	ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));           //  jnz fat
+	char *fat = ((char *)ss) - 1;
+	ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 1), size_8);        //  mov al, byte[ecx+1]
+
+    ss = alu(ss, sub_opc,  eax_opnd, Imm_Opnd(size_8,0x8),size_8);  //  sub al, 0x8
+	ss = branch8(ss, Condition_C,  Imm_Opnd(size_8, 0));            //  jc zero_rec
+	char *zero_rec = ((char *)ss) - 1;
+	ss = mov(ss,  M_Base_Opnd(ecx_reg, 1), eax_opnd, size_8);       //  mov byte[ecx+1],al
+    ss = ret(ss,  Imm_Opnd(4));                                     //  ret 4
+
+    signed offset = (signed)ss - (signed)zero_rec - 1;              //zero_rec:
+    *zero_rec = (char)offset;
+
+    ss = mov(ss, M_Base_Opnd(ecx_reg, 2), Imm_Opnd(size_16, 0), size_16);// mov word[ecx+2],0
+	ss = ret(ss,  Imm_Opnd(4));                                     // ret 4
+
+    offset = (signed)ss - (signed)fat - 1;                         //fat:
+    *fat = (char)offset;
+
+#endif
+
+    ss = push(ss,  ecx_opnd);
+    ss = call(ss, (char *)hythread_thin_monitor_exit);
+    ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters
+    return ss;
+}
+
+/**
+  *  Generates slow path of monitor exit.
+  *  This code could block on monitor and contains safepoint.
+  *  The appropriate m2n frame should be generated and
+  *
+  *  @param[in] ss buffer to put the assembly code to
+  *  @param[in] input_param1 register should point to the jobject(handle)
+  *  If input_param1 == eax it reduces one register mov.
+  *  the code use and do not restore ecx, edx, eax registers
+  *  @return 0 if success in eax register
+  */
+char* gen_monitorexit_slow_path_helper(char *ss, const R_Opnd & input_param1) {
+    if (&input_param1 != &eax_opnd) {
+        ss = mov(ss, eax_opnd,  input_param1);
+    }
+
+    ss = push(ss, eax_opnd); // push the address of the handle
+    ss = call(ss, (char *)jthread_monitor_exit);
+    ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters
+    return ss;
+}
+
+/**
+  * Generates fast accessor to the TLS for the given key.<br>
+  * Example:
+  * <pre><code>
+  * get_thread_ptr = get_tls_helper(vm_thread_block_key);
+  * ...
+  * self = get_thread_ptr();
+  * </code></pre>
+  *
+  * @param[in] key TLS key
+  * @return fast accessor to key, if one exist
+  */
+fast_tls_func* get_tls_helper(hythread_tls_key_t key) {
+    //     return tm_self_tls->thread_local_storage[key];
+    unsigned key_offset =
+        (unsigned) &(((HyThread_public *) (0))->thread_local_storage[key]);
+
+    const int stub_size = 126;
+    char *stub = (char *)malloc(stub_size);
+    memset(stub, 0xcc /*int 3*/, stub_size);
+
+    char *ss = stub;
+
+    ss = gen_hythread_self_helper(ss);
+    ss = mov(ss,  eax_opnd,  M_Base_Opnd(eax_reg, key_offset));
+    ss = ret(ss,  Imm_Opnd(0));
+
+    assert((ss - stub) < stub_size);
+
+    return (fast_tls_func*) stub;
+}

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_ipf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_ipf.cpp?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_ipf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/helpers/thread_helpers_ipf.cpp Mon Jul 30 12:07:39 2007
@@ -22,7 +22,6 @@
 
 #include <open/hythread_ext.h>
 #include <open/thread_helpers.h>
-#include "thread_private.h"
 #include "open/thread_externals.h"
 #include "open/jthread.h"
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_generic.cpp Mon Jul 30 12:07:39 2007
@@ -206,9 +206,10 @@
     gc_thread_init(&vm_thread->_gc_private_information);
 
     if (ti_is_enabled()) {
-        vm_thread->jvmti_thread.owned_monitors =
-            (jobject*)apr_palloc(vm_thread->pool,
-                sizeof(jobject) * TM_MAX_OWNED_MONITOR_NUMBER);
+        vm_thread->jvmti_thread.owned_monitors_size = TM_INITIAL_OWNED_MONITOR_SIZE;
+        vm_thread->jvmti_thread.owned_monitors = (jobject*)apr_palloc(vm_thread->pool,
+                TM_INITIAL_OWNED_MONITOR_SIZE * sizeof(jobject));
+
         vm_thread->jvmti_thread.jvmti_jit_breakpoints_handling_buffer =
             (jbyte*)apr_palloc(vm_thread->pool,
                 sizeof(jbyte) * TM_JVMTI_MAX_BUFFER_SIZE);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_monitors.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_monitors.cpp?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_monitors.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_monitors.cpp Mon Jul 30 12:07:39 2007
@@ -398,7 +398,19 @@
         jvmti_thread->wait_monitor = NULL;
     }
 
-    assert(jvmti_thread->owned_monitors_nmb < TM_MAX_OWNED_MONITOR_NUMBER);
+    if (jvmti_thread->owned_monitors_nmb >= jvmti_thread->owned_monitors_size) {
+        int new_size = jvmti_thread->owned_monitors_size * 2;
+
+        TRACE(("Increasing owned_monitors_size to: %d", new_size));
+        jobject* new_monitors = (jobject*)apr_palloc(vm_thread->pool,
+                new_size * sizeof(jobject));
+        assert(new_monitors);
+        memcpy(new_monitors, jvmti_thread->owned_monitors,
+                jvmti_thread->owned_monitors_size * sizeof(jobject));
+        jvmti_thread->owned_monitors = new_monitors;
+        jvmti_thread->owned_monitors_size = new_size;
+    }
+
     jvmti_thread->owned_monitors[jvmti_thread->owned_monitors_nmb]
         = vm_thread->jni_env->NewGlobalRef(monitor);
     jvmti_thread->owned_monitors_nmb++;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/compile_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/compile_em64t.cpp?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/compile_em64t.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/compile_em64t.cpp Mon Jul 30 12:07:39 2007
@@ -142,6 +142,27 @@
     }
 }
 
+// Convert a reference, if null, from a managed null
+// (represented by heap_base) to an unmanaged one (NULL/0). Uses %rdi.
+char * gen_convert_managed_to_unmanaged_null_em64t(char * ss,
+                                                  const R_Opnd & input_param1) {
+    if (&input_param1 != &rdi_opnd) {
+        ss = mov(ss, rdi_opnd,  input_param1);
+    }
+
+    if (VM_Global_State::loader_env->compress_references) {
+        ss = mov(ss, rcx_opnd, Imm_Opnd(size_64, (int64)VM_Global_State::loader_env->heap_base));
+        ss = alu(ss, cmp_opc, rdi_opnd, rcx_opnd);
+        ss = branch8(ss, Condition_NE, Imm_Opnd(size_8, 0));  // not null, branch around the mov 0
+        char *backpatch_address__not_managed_null = ((char *)ss) - 1;
+        ss = mov(ss, rdi_opnd, Imm_Opnd(0));
+        signed offset = (signed)ss - (signed)backpatch_address__not_managed_null - 1;
+        *backpatch_address__not_managed_null = (char)offset;
+    }
+    return ss;
+}
+
+
 /*    BEGIN COMPILE-ME STUBS    */
 
 // compile_me stack frame

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp Mon Jul 30 12:07:39 2007
@@ -26,10 +26,22 @@
 #include "environment.h"
 
 #include "open/hythread_ext.h"
+#include "open/jthread.h"
+#include "open/thread_helpers.h"
+
+#include "open/vm_util.h"
+#include "encoder.h"
+#include "nogc.h"
+#include "compile.h"
+
+#include "exceptions_jit.h"
 #include "lil.h"
 #include "lil_code_generator.h"
-#include "jit_runtime_support.h"
+#include "../m2n_em64t_internal.h"
+#include "object_handles.h"
 #include "Class.h"
+#include "jit_runtime_support.h"
+
 #include "mon_enter_exit.h"
 #include "exceptions.h"
 #include "exceptions_jit.h"
@@ -37,9 +49,266 @@
 #define LOG_DOMAIN "vm.helpers"
 #include "cxxlog.h"
 
-#include "vm_stats.h"
 #include "dump.h"
+#include "vm_stats.h"
+
+// Linix x86-64 fast helpers
+char * gen_convert_managed_to_unmanaged_null_em64t(char * ss,
+                                                  const R_Opnd & input_param1);
+#define INPUT_ARG_OFFSET 8
+char * gen_setup_j2n_frame(char * s);
+char * gen_pop_j2n_frame(char * s);
+
+
+// patch_addr_null_arg_ptr is the address of a variable holding the
+// address of a branch instruction byte to patch with the destination
+// to be taken if the struct Class* argument is NULL.
+static char * gen_convert_struct_class_to_object(char *ss, char **patch_addr_null_arg_ptr)
+{
+    // First make sure the struct Class* argument is non-NULL.
+    ss = test(ss,  rdi_opnd,   rdi_opnd);
+    ss = branch8(ss, Condition_Z,  Imm_Opnd(size_8, 0));
+    *patch_addr_null_arg_ptr = ((char *)ss) - 1;
+
+    // Convert the struct Class* argument to the corresponding java_lang_Class reference.
+    ss = call(ss, (char *)struct_Class_to_java_lang_Class);
+    ss = mov(ss,  rdi_opnd,  rax_opnd);  // overwrite the struct Class* with the raw java_lang_Class reference
+    return ss;
+} //gen_convert_struct_class_to_object
+
+// Helper for monenter intstruction
+static char * gen_restore_monitor_enter(char *ss, char *patch_addr_null_arg)
+{
+    // Obtain lockword offset for the given object
+    const unsigned header_offset = ManagedObject::header_offset();
+    signed offset;
+    assert(header_offset);
+#ifdef VM_STATS
+//    uint64* incr = &(VM_Statistics::get_vm_stats().num_monitor_enter);
+//    ss = inc(ss,  M_Opnd((int64)incr));
+#endif
+
+    ss = test(ss,  rdi_opnd,   rdi_opnd);
+    ss = branch8(ss, Condition_Z,  Imm_Opnd(size_8, 0));
+    char *backpatch_address__null_pointer = ((char *)ss) - 1;
+
+    // Fast path
+    ss = push(ss, rdi_opnd);
+    ss = alu(ss, add_opc, rdi_opnd, Imm_Opnd(header_offset)); // pop parameters
+    ss = gen_monitorenter_fast_path_helper(ss, rdi_opnd);
+    ss = pop(ss, rdi_opnd);
+
+    ss = test(ss,  rax_opnd,   rax_opnd);
+    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));
+    char *backpatch_address__fast_monitor_failed = ((char *)ss) - 1;
+    ss = ret(ss);
+
+    // Slow path: happens when the monitor is busy (contention case)
+    offset = (int64)ss - (int64)backpatch_address__fast_monitor_failed - 1;
+    *backpatch_address__fast_monitor_failed = (char)offset;
+
+    ss = gen_setup_j2n_frame(ss);
+
+    ss = call(ss, (char *)oh_convert_to_local_handle);
+    ss = gen_monitorenter_slow_path_helper(ss, rax_opnd);
+
+    ss = gen_pop_j2n_frame(ss);
+
+    ss = ret(ss);
+
+    // Handle NPE here
+    int64 npe_offset = (int64)ss - (int64)backpatch_address__null_pointer - 1;
+    *backpatch_address__null_pointer = (char)npe_offset;
+    if (patch_addr_null_arg != NULL) {
+        npe_offset = (int64)ss - (int64)patch_addr_null_arg - 1;
+        *patch_addr_null_arg = (char)npe_offset;
+    }
+
+    // Object is null so throw a null pointer exception
+    ss = jump(ss, (char*)exn_get_rth_throw_null_pointer());
+
+    return ss;
+} //gen_restore_monitor_enter
+
+void * getaddress__vm_monitor_enter_naked()
+{
+    static void *addr = NULL;
+    if (addr != NULL) {
+        return addr;
+    }
+
+    const int stub_size = 160;
+    char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_MAX/2, CAA_Allocate);
+#ifdef _DEBUG
+    memset(stub, 0xcc /*int 3*/, stub_size);
+#endif
+    char *ss = stub;
+
+#ifdef VM_STATS
+    int * value = VM_Statistics::get_vm_stats().rt_function_calls.lookup_or_add((void*)VM_RT_MONITOR_ENTER, 0, NULL);
+    ss = mov(ss,  rax_opnd,  Imm_Opnd(size_64, (int64)value));
+    ss = inc(ss,  M_Base_Opnd(rax_reg, 0));
+#endif
+
+    ss = gen_restore_monitor_enter(ss, /*patch_addr_null_arg*/ NULL);
+
+    addr = stub;
+    assert((ss - stub) < stub_size);
+
+    compile_add_dynamic_generated_code_chunk("vm_monitor_enter_naked", stub, stub_size);
+
+    // Put TI support here
+    DUMP_STUB(stub, "getaddress__vm_monitor_enter_naked", ss - stub);
+
+    return addr;
+}
+
+void * getaddress__vm_monitor_enter_static_naked()
+{
+    static void *addr = NULL;
+    if (addr != NULL) {
+        return addr;
+    }
+
+    const int stub_size = 176;
+    char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_MAX/2, CAA_Allocate);
+#ifdef _DEBUG
+    memset(stub, 0xcc /*int 3*/, stub_size);
+#endif
+    char *ss = stub;
+
+#ifdef VM_STATS
+    int * value = VM_Statistics::get_vm_stats().rt_function_calls.lookup_or_add((void*)VM_RT_MONITOR_ENTER_STATIC, 0, NULL);
+    ss = mov(ss,  rax_opnd,  Imm_Opnd(size_64, (int64)value));
+    ss = inc(ss,  M_Base_Opnd(rax_reg, 0));
+#endif
+
+    char *patch_addr_null_arg;
+    ss = gen_convert_struct_class_to_object(ss, &patch_addr_null_arg);
+    ss = gen_restore_monitor_enter(ss, patch_addr_null_arg);
+
+    addr = stub;
+    assert((ss - stub) < stub_size);
+
+    compile_add_dynamic_generated_code_chunk("vm_monitor_enter_static_naked", stub, stub_size);
+
+    if (VM_Global_State::loader_env->TI->isEnabled())
+        jvmti_send_dynamic_code_generated_event("vm_monitor_enter_static_naked", stub, stub_size);
+
+    DUMP_STUB(stub, "getaddress__vm_monitor_enter_static_naked", ss - stub);
+
+    return addr;
+} //getaddress__vm_monitor_enter_static_naked
+
+static char * gen_restore_monitor_exit(char *ss, char *patch_addr_null_arg)
+{
+
+    const unsigned header_offset = ManagedObject::header_offset();
+#ifdef VM_STATS
+//    uint64* incr = &(VM_Statistics::get_vm_stats().num_monitor_exit);
+//    ss = inc(ss,  M_Opnd((int64)incr));
+#endif
+
+    ss = test(ss, rdi_opnd, rdi_opnd);
+    ss = branch8(ss, Condition_Z,  Imm_Opnd(size_8, 0));
+    char *backpatch_address__null_pointer = ((char *)ss) - 1;
+
+    // Fast path only
+    ss = alu(ss, add_opc, rdi_opnd, Imm_Opnd(header_offset));
+    ss = gen_monitor_exit_helper(ss, rdi_opnd);
+
+    ss = test(ss,  rax_opnd,   rax_opnd);
+    ss = branch8(ss, Condition_NZ,  Imm_Opnd(size_8, 0));
+    char *backpatch_address__fast_monitor_failed = ((char *)ss) - 1;
+    ss = ret(ss);
+
+    signed offset = (signed)ss - (signed)backpatch_address__fast_monitor_failed - 1;
+    *backpatch_address__fast_monitor_failed = (char)offset;
+
+    //  Monitor illegal state happend
+    ss = jump(ss, (char*)exn_get_rth_throw_illegal_state_exception());
+
+    offset = (signed)ss - (signed)backpatch_address__null_pointer - 1;
+    *backpatch_address__null_pointer = (char)offset;
+    if (patch_addr_null_arg != NULL) {
+        offset = (signed)ss - (signed)patch_addr_null_arg - 1;
+        *patch_addr_null_arg = (char)offset;
+    }
+
+    // Object is null so throw a null pointer exception
+    ss = jump(ss, (char*)exn_get_rth_throw_null_pointer());
+
+    return ss;
+} //gen_restore_monitor_exit
+
+void * getaddress__vm_monitor_exit_naked()
+{
+    static void *addr = NULL;
+    if (addr != NULL) {
+        return addr;
+    }
+
+    const int stub_size = 112;
+    char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_MAX/2, CAA_Allocate);
+    char *ss = stub;
+
+#ifdef VM_STATS
+    int * value = VM_Statistics::get_vm_stats().rt_function_calls.lookup_or_add((void*)VM_RT_MONITOR_EXIT, 0, NULL);
+    ss = mov(ss,  rax_opnd,  Imm_Opnd(size_64, (int64)value));
+    ss = inc(ss,  M_Base_Opnd(rax_reg, 0));
+#endif
+
+    ss = gen_convert_managed_to_unmanaged_null_em64t((Emitter_Handle)ss, rdi_opnd);
+    ss = gen_restore_monitor_exit(ss, /*patch_addr_null_arg*/ NULL);
+
+    addr = stub;
+    assert((ss - stub) < stub_size);
+
+    compile_add_dynamic_generated_code_chunk("vm_monitor_exit_naked", stub, stub_size);
+
+    if (VM_Global_State::loader_env->TI->isEnabled())
+        jvmti_send_dynamic_code_generated_event("vm_monitor_exit_naked", stub, stub_size);
+
+    DUMP_STUB(stub, "getaddress__vm_monitor_exit_naked", ss - stub);
+
+    return addr;
+} //getaddress__vm_monitor_exit_naked
+
+void * getaddress__vm_monitor_exit_static_naked()
+{
+    static void *addr = NULL;
+    if (addr != NULL) {
+        return addr;
+    }
+
+    const int stub_size = 112;
+    char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_MAX/2, CAA_Allocate);
+    char *ss = stub;
+
+#ifdef VM_STATS
+    int * value = VM_Statistics::get_vm_stats().rt_function_calls.lookup_or_add((void*)VM_RT_MONITOR_EXIT_STATIC, 0, NULL);
+    ss = mov(ss,  rax_opnd,  Imm_Opnd(size_64, (int64)value));
+    ss = inc(ss,  M_Base_Opnd(rax_reg, 0));
+#endif
+
+    char *patch_addr_null_arg;
+    ss = gen_convert_struct_class_to_object(ss, &patch_addr_null_arg);
+    ss = gen_restore_monitor_exit(ss, patch_addr_null_arg);
+
+    addr = stub;
+    assert((ss - stub) < stub_size);
+
+    compile_add_dynamic_generated_code_chunk("vm_monitor_exit_static_naked", stub, stub_size);
+
+    if (VM_Global_State::loader_env->TI->isEnabled())
+        jvmti_send_dynamic_code_generated_event("vm_monitor_exit_static_naked", stub, stub_size);
+
+    DUMP_STUB(stub, "getaddress__vm_monitor_exit_static_naked", ss - stub);
+
+    return addr;
+} //getaddress__vm_monitor_exit_static_naked
 
+// Windows x86-64 helpers
 static LilCodeStub * rth_get_lil_monitor_enter_generic(LilCodeStub * cs) {
     if(VM_Global_State::loader_env->TI->isEnabled() &&
             VM_Global_State::loader_env->TI->get_global_capability(

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/jit_runtime_support_em64t.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/jit_runtime_support_em64t.cpp?view=diff&rev=561096&r1=561095&r2=561096
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/jit_runtime_support_em64t.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/em64t/base/jit_runtime_support_em64t.cpp Mon Jul 30 12:07:39 2007
@@ -27,6 +27,8 @@
 #include "port_general.h"
 #include "heap.h"
 #include "vm_threads.h"
+#include "nogc.h"
+#include "compile.h"
 
 #include "lil.h"
 #include "lil_code_generator.h"
@@ -170,6 +172,118 @@
     return vm_rt_multianewarray_recursive(c, lens, dims);
 }
 
+static void* getaddress__setup_java_to_native_frame()
+{
+    static void *addr = 0;
+    if (addr) {
+        return addr;
+    }
+
+    const int stub_size = 32 + m2n_push_m2n_size(1, 0);
+    char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_MAX/2, CAA_Allocate);
+
+#ifdef _DEBUG
+    memset(stub, 0xcc /*int 3*/, stub_size);
+#endif
+    char *ss = stub;
+
+    // Stack changes
+    //    prev        new
+    //
+    //    ...         ...
+    //  --------    --------   ------------
+    //    ret         ret
+    //  --------    --------
+    //    ret         r12
+    //  --------    --------    m2n frame
+    //
+    //                ...
+    //
+    //              --------   ------------
+    //                ret
+    //              --------
+
+    ss = alu(ss, sub_opc, rsp_opnd, Imm_Opnd(m2n_sizeof_m2n_frame - 8));
+    ss = mov(ss, r11_opnd, M_Base_Opnd(rsp_reg, m2n_sizeof_m2n_frame - 8));
+    ss = mov(ss, M_Base_Opnd(rsp_reg, m2n_sizeof_m2n_frame - 8), r12_opnd);
+    ss = mov(ss, M_Base_Opnd(rsp_reg, 0), r11_opnd);
+    ss = mov(ss, r12_opnd, rdi_opnd);
+
+    ss = m2n_gen_push_m2n(ss, NULL, FRAME_UNKNOWN, false, 1, 0,
+            m2n_sizeof_m2n_frame);
+    ss = mov(ss,  rdi_opnd, r12_opnd);
+    ss = ret(ss);
+
+    assert((ss - stub) <= stub_size);
+    addr = stub;
+
+    compile_add_dynamic_generated_code_chunk("setup_java_to_native_frame", stub, stub_size);
+
+    // Put TI support here.
+    DUMP_STUB(stub, "getaddress__setup_java_to_native_frame", ss - stub);
+
+    return addr;
+} //getaddress__setup_java_to_native_frame
+
+VMEXPORT char *gen_setup_j2n_frame(char *s)
+{
+    s = call(s, (char *)getaddress__setup_java_to_native_frame() );
+    return s;
+} //setup_j2n_frame
+
+static void m2n_free_local_handles() {
+    assert(!hythread_is_suspend_enabled());
+
+    if (exn_raised()) {
+        exn_rethrow();
+    }
+
+    M2nFrame * m2n = m2n_get_last_frame();
+    free_local_object_handles3(m2n->local_object_handles);
+}
+
+static void* getaddress__pop_java_to_native_frame()
+{
+    static void *addr = 0;
+    if (addr) {
+        return addr;
+    }
+
+    const int stub_size = 32 + m2n_pop_m2n_size(false, 1, 0);
+    char *stub = (char *)malloc_fixed_code_for_jit(stub_size, DEFAULT_CODE_ALIGNMENT, CODE_BLOCK_HEAT_MAX/2, CAA_Allocate);
+#ifdef _DEBUG
+    memset(stub, 0xcc /*int 3*/, stub_size);
+#endif
+    char *ss = stub;
+
+    ss = mov(ss, r12_opnd, rax_opnd);
+
+    ss = m2n_gen_pop_m2n(ss, false, 1, 8, 0);
+
+    ss = mov(ss, rax_opnd, r12_opnd);
+    ss = mov(ss, r11_opnd, M_Base_Opnd(rsp_reg, 0));
+    ss = mov(ss, r12_opnd, M_Base_Opnd(rsp_reg, m2n_sizeof_m2n_frame - 8));
+    ss = mov(ss, M_Base_Opnd(rsp_reg, m2n_sizeof_m2n_frame - 8), r11_opnd);
+    ss = alu(ss, add_opc, rsp_opnd, Imm_Opnd(m2n_sizeof_m2n_frame - 8));
+    ss = ret(ss);
+
+    assert((ss - stub) <= stub_size);
+    addr = stub;
+
+    compile_add_dynamic_generated_code_chunk("pop_java_to_native_frame", stub, stub_size);
+
+    // Put TI support here.
+    DUMP_STUB(stub, "getaddress__pop_java_to_native_frame", ss - stub);
+
+    return addr;
+} //getaddress__pop_java_to_native_frame
+
+VMEXPORT char *gen_pop_j2n_frame(char *s)
+{
+    s = call(s, (char *)getaddress__pop_java_to_native_frame() );
+    return s;
+} //setup_j2n_frame
+
 
 // see jit_lock_rt_support.cpp for the implementation
 NativeCodePtr rth_get_lil_monitor_enter_static();
@@ -180,6 +294,11 @@
 NativeCodePtr rth_get_lil_monitor_exit();
 NativeCodePtr rth_get_lil_monitor_exit_non_null();
 
+void * getaddress__vm_monitor_enter_naked();
+void * getaddress__vm_monitor_enter_static_naked();
+void * getaddress__vm_monitor_exit_naked();
+void * getaddress__vm_monitor_exit_static_naked();
+
 void * vm_get_rt_support_addr(VM_RT_SUPPORT f) {
 
 #ifdef VM_STATS
@@ -188,8 +307,9 @@
 
     NativeCodePtr res = rth_get_lil_helper(f);
     if (res) return res;
-    
+
     switch(f) {
+#ifdef _WIN64
     // Monitor enter runtime helpers
     case VM_RT_MONITOR_ENTER_STATIC:
         return rth_get_lil_monitor_enter_static();
@@ -205,6 +325,23 @@
         return rth_get_lil_monitor_exit();
     case VM_RT_MONITOR_EXIT_NON_NULL:
         return rth_get_lil_monitor_exit_non_null();
+#else
+    // Monitor enter runtime helpers
+    case VM_RT_MONITOR_ENTER_STATIC:
+        return getaddress__vm_monitor_enter_static_naked();
+    case VM_RT_MONITOR_ENTER:
+        return getaddress__vm_monitor_enter_naked();
+    case VM_RT_MONITOR_ENTER_NON_NULL:
+        return getaddress__vm_monitor_enter_naked();
+
+   // Monitor exit runtime helpers
+    case VM_RT_MONITOR_EXIT_STATIC:
+        return getaddress__vm_monitor_exit_static_naked();
+    case VM_RT_MONITOR_EXIT:
+        return getaddress__vm_monitor_exit_naked();
+    case VM_RT_MONITOR_EXIT_NON_NULL:
+        return getaddress__vm_monitor_exit_naked();
+#endif
 
     // Object creation helper
     case VM_RT_NEW_RESOLVED_USING_VTABLE_AND_SIZE: