Index: build/make/components/vm.xml =================================================================== --- build/make/components/vm.xml (revision 430048) +++ build/make/components/vm.xml (working copy) @@ -63,6 +63,8 @@ vm.vmstart" /> + + Index: build/make/components/vm/vmstart.xml =================================================================== --- build/make/components/vm/vmstart.xml (revision 430048) +++ build/make/components/vm/vmstart.xml (working copy) @@ -33,7 +33,8 @@ vm.port, extra.apr, extra.aprutil, - extra.log4cxx" /> + extra.log4cxx, + vm.hythr" /> @@ -48,6 +49,7 @@ + Index: build/make/components/vm/interpreter.xml =================================================================== --- build/make/components/vm/interpreter.xml (revision 430048) +++ build/make/components/vm/interpreter.xml (working copy) @@ -29,7 +29,7 @@ + vm.vmcore,vm.hythr" /> @@ -160,6 +160,7 @@ + Index: build/make/components/vm/port.xml =================================================================== --- build/make/components/vm/port.xml (revision 430048) +++ build/make/components/vm/port.xml (working copy) @@ -51,6 +51,7 @@ + Index: build/make/components/vm/gc.xml =================================================================== --- build/make/components/vm/gc.xml (revision 430048) +++ build/make/components/vm/gc.xml (working copy) @@ -27,7 +27,7 @@ - + @@ -95,7 +95,7 @@ - + Index: build/make/components/vm/vmcore.xml =================================================================== --- build/make/components/vm/vmcore.xml (revision 430048) +++ build/make/components/vm/vmcore.xml (working copy) @@ -32,7 +32,8 @@ extra.log4cxx, extra.zlib, vm.encoder, - vm.port" /> + vm.port, vm.hythr, vm.jthread" /> + @@ -44,7 +45,19 @@ + + + + + + + + + + + + @@ -148,6 +161,7 @@ + @@ -269,5 +289,17 @@ + + + + + + + + + + + + Index: build/make/components/vm/hythr.xml =================================================================== --- build/make/components/vm/hythr.xml (revision 430048) +++ build/make/components/vm/hythr.xml (working copy) @@ -27,34 +27,26 @@ - + - - - - + - - - - - - - - - + + + + + - + + + - + + + + + + + + + + - + - - Index: build/make/targets/common_vm.xml =================================================================== --- build/make/targets/common_vm.xml (revision 430048) +++ build/make/targets/common_vm.xml (working copy) @@ -1,5 +1,5 @@ - - \ No newline at end of file + + + Index: vm/em/src/EBProfileCollector.cpp =================================================================== --- vm/em/src/EBProfileCollector.cpp (revision 430048) +++ vm/em/src/EBProfileCollector.cpp (working copy) @@ -50,6 +50,8 @@ <<" mode:"<<(mode == EB_PCMODE_ASYNC? "ASYNC": "SYNC"); INFO2(catName.c_str(), msg.str().c_str()); } + + hymutex_create(&profilesLock, TM_MUTEX_NESTED); } Method_Profile_Handle eb_profiler_create_profile(PC_Handle ph, Method_Handle mh) { @@ -108,6 +110,8 @@ EBMethodProfile* profile = it->second; delete profile; } + + hymutex_destroy(profilesLock); } MethodProfile* EBProfileCollector::getMethodProfile(Method_Handle mh) const { @@ -121,7 +125,7 @@ EBMethodProfile* EBProfileCollector::createProfile(Method_Handle mh) { EBMethodProfile* profile = new EBMethodProfile(this, mh); - profilesLock.lock(); + hymutex_lock(profilesLock); assert(profilesByMethod.find(mh) == profilesByMethod.end()); profilesByMethod[mh] = profile; @@ -129,7 +133,7 @@ newProfiles.push_back(profile); } - profilesLock.unlock(); + hymutex_unlock(profilesLock); return profile; } @@ -150,10 +154,10 @@ void EBProfileCollector::onTimeout() { assert(mode == EB_PCMODE_ASYNC); if(!newProfiles.empty()) { - profilesLock.lock(); + hymutex_lock(profilesLock); greenProfiles.insert(greenProfiles.end(), newProfiles.begin(), newProfiles.end()); newProfiles.clear(); - profilesLock.unlock(); + hymutex_unlock(profilesLock); } for (std::vector::iterator it = greenProfiles.begin(), end = greenProfiles.end(); it!=end; ++it) { Index: vm/em/src/EBProfileCollector.h =================================================================== --- vm/em/src/EBProfileCollector.h (revision 430048) +++ vm/em/src/EBProfileCollector.h (working copy) @@ -87,7 +87,7 @@ // preallocated mem for temporary (method-local) needs std::vector tmpProfiles; - CriticalSection profilesLock; + hymutex_t profilesLock; }; class EBMethodProfile : public MethodProfile { Index: vm/em/src/DrlEMImpl.cpp =================================================================== --- vm/em/src/DrlEMImpl.cpp (revision 430048) +++ vm/em/src/DrlEMImpl.cpp (working copy) @@ -100,6 +100,7 @@ nMethodsCompiled=0; nMethodsRecompiled=0; tick=0; + hymutex_create(&recompilationLock, TM_MUTEX_NESTED); #ifndef _EM64T_ initProfileAccess(); #endif @@ -107,6 +108,7 @@ DrlEMImpl::~DrlEMImpl() { deallocateResources(); + hymutex_destroy(recompilationLock); } void DrlEMImpl::initProfileAccess() { @@ -628,15 +630,15 @@ void DrlEMImpl::methodProfileIsReady(MethodProfile* mp) { - recompilationLock.lock(); + hymutex_lock(recompilationLock); if (methodsInRecompile.find((Method_Profile_Handle)mp)!=methodsInRecompile.end()) { //method is already recompiling by another thread or by this thread(recursion) - recompilationLock.unlock(); + hymutex_unlock(recompilationLock); return; } methodsInRecompile.insert((Method_Profile_Handle)mp); nMethodsRecompiled++; - recompilationLock.unlock(); + hymutex_unlock(recompilationLock); const char* methodName = NULL; const char* className = NULL; @@ -677,9 +679,9 @@ } } } - recompilationLock.lock(); + hymutex_lock(recompilationLock); methodsInRecompile.erase((Method_Profile_Handle)mp); - recompilationLock.unlock(); + hymutex_unlock(recompilationLock); } ProfileCollector* DrlEMImpl::getProfileCollector(EM_PCTYPE type, JIT_Handle jh, EM_JIT_PC_Role jitRole) const { Index: vm/em/src/DrlEMImpl.h =================================================================== --- vm/em/src/DrlEMImpl.h (revision 430048) +++ vm/em/src/DrlEMImpl.h (working copy) @@ -125,7 +125,7 @@ uint32 tick; - CriticalSection recompilationLock; + hymutex_t recompilationLock; std::set methodsInRecompile; }; Index: vm/tests/smoke/StackTest.java =================================================================== --- vm/tests/smoke/StackTest.java (revision 430048) +++ vm/tests/smoke/StackTest.java (working copy) @@ -13,6 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +/** + * @keyword XXX_fails + */ public class StackTest { static int depth = 0; Index: vm/include/open/types.h =================================================================== --- vm/include/open/types.h (revision 430048) +++ vm/include/open/types.h (working copy) @@ -37,7 +37,7 @@ #else // !PLATFORM_POSIX -#if defined(BUILDING_VM) +#if defined(BUILDING_VM) && !defined(STATIC_BUILD) #define VMEXPORT __declspec(dllexport) #define JITEXPORT __declspec(dllimport) #define EMEXPORT __declspec(dllimport) Index: vm/include/open/thread.h =================================================================== --- vm/include/open/thread.h (revision 430048) +++ vm/include/open/thread.h (working copy) @@ -1,377 +0,0 @@ -/* - * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * @author Sergey Petrovsky - * @version $Revision: 1.1.2.1.4.3 $ - */ -#ifndef _OPEN_THREAD_H_ -#define _OPEN_THREAD_H_ - -#include "open/types.h" -#include "jvmti_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @file thread_generic.h - * - * This module describes VM interfaces to work with Java threads. - * - */ - -//---------------------- Object ------------------------------------- - -/** - * Just one thread from the set of threads - * waiting on the object object's monitor is waked up. - * - * Nothing happens if the set is empty. - * - * @param object - */ -void thread_object_notify(jobject object); - -/** - * Each thread from the set of threads waiting on the - * object object's monitor is waked up. - * - * Nothing happens if the set is empty. - * - * @param object - */ -void thread_object_notify_all(jobject object); - -/** - * Current thread gets waiting on the object object's monitor. - * - * The thread object waiting on object - * object's monitor is waked up if: - *
    - *
  • another thread invokes thread_notify(object) - * and VM chooses this thread to wake up; - *
  • another thread invokes thread_notifyAll(object); - *
  • another thread invokes thread_interrupt(thread); - *
  • real time elapsed from the wating begin is - * greater or equal the time specified. - *
- * - * @param object - * @param millis - */ -void thread_object_wait (jobject object, int64 millis); - -/** - * Current thread gets waiting on the object object's monitor. - * - * The thread object waiting on object - * object's monitor is waked up if: - *
    - *
  • another thread invokes thread_notify(object) - * and VM chooses this thread to wake up; - *
  • another thread invokes thread_notifyAll(object); - *
  • another thread invokes thread_interrupt(thread); - *
  • real time elapsed from the wating begin is - * greater or equal the time specified. - *
- * - * @param object - * @param millis - * @param nanos - */ -void thread_object_wait_nanos (jobject object, int64 millis, int nanos); - -//---------------------- Thread ------------------------------------- -/** - * Returns the monitor the thread thread is contended for. - * - * Returns NULL if there's no such monitor. - * - * @param thread - * @return monitor the thread thread is contended for. - */ -jobject thread_contends_for_lock(jobject thread); - -/** - * Returns current thread. - */ -jobject thread_current_thread(); - -/** - * Safe point. - */ -VMEXPORT void tmn_safe_point(); - -/** - * Disables suspend for the current thread. - */ -VMEXPORT void tmn_suspend_disable(); - -/** - * Disables suspend for the current thread and increments the recursion counter. - */ -void tmn_suspend_disable_recursive(); - -/** - * Checks if suspend enabled, if so calls thread_disable suspend and returns true; - * otherwise returns false. - */ -//VMEXPORT bool tmn_suspend_disable_and_return_old_value(); - -/** - * Notify that it's safe to suspend thread. - * - * After a call of this function and till thread_disable_suspend() - * is called any call of thread_is_suspend_enabled() - * returns true. - */ -VMEXPORT void tmn_suspend_enable(); - -/** - * Decrements a recursion counter. - * - * If the counter value becomes zero, - * after a call of this function and till thread_disable_suspend() - * is called any call of thread_is_suspend_enabled() - * returns true. - */ -void tmn_suspend_enable_recursive(); - -/** - * Returns true if it's safe to suspend the thread thread. - * - * Otherwise returns false. - * - * @return true if it's safe to suspend the thread thread; - * false otherwise. - */ -VMEXPORT bool tmn_is_suspend_enabled(); - -/** - * Returns a set of of all existig alive threads. - * - * The set is returned as an array of jthread pointers. - * The value returned is the number of alive threads. - * No array is returned if threads == NULL. - * - * @param threads - * @return the number of alive threads. - */ -int thread_get_all_threads(jthread** threads); - -/** - * Gets thread thread's local storage. - * - * @param env - * @param thread - * @param data_ptr - */ -int thread_get_jvmti_thread_local_storage(jvmtiEnv* env, - jthread thread, void** data_ptr); -/** - * Gets all monitors owned by the thread thread. - * - * @param thread - * @param monitors - */ -int thread_get_owned_monitor_info(jthread thread, jobject ** monitors); - -/** - * Returns the thread thread's state according - * JVM TI specification. - * - * @param thread - * @return the thread thread's state. - */ -int thread_get_thread_state(jthread thread); - -/** - * Returns true if the thread thread - * holds monitor monitor. - * - * Otherwise returns false. - * - * @param thread - * @param monitor - * @return true if the thread thread - * holds monitor monitor; false otherwise. - */ -bool thread_holds_lock(jthread thread, jobject monitor); - -/** - * Returns a set of monitors the thread thread holds. - * - * The set is returned as an array of jobject pointers. - * The value returned is the number of monitors the thread holds. - * No array is returned if monitors == NULL. - * - * @param thread - * @param monitors - * @return the number of monitors the thread thread holds. - */ -int thread_holds_locks(jthread thread, jobject* monitors); - -/** - * Wakes up the thread thread or marks it as 'interrupted'. - * - * If the thread thread is wating due to - * thread_wait(...) or thread_sleep(...) - * function call it's waked up. - * - * Else thread thread's state is changed so that - * thread.isInterrupted() returns true. - * - * @param thread - */ -void thread_interrupt(jthread thread); - -/** - * Returns true if the thread thread is alive. - * - * Otherwise returns false. - * A thread gets alive just after it has been started - * and is alive till it has died. - * - * @param thread - * @return true if the thread thread - * is alive; false otherwise. - */ -bool thread_is_alive(jthread thread); - -/** - * Returns true if the thread thread is interrupted. - * - * Otherwise returns false. - * - * @param thread - * @param clear - * @return true if the thread thread - * is interrupted; false otherwise. - */ -bool thread_is_interrupted(jthread thread, bool clear); - -/** - * Waits till the thread thread is dead or time specified is expired. - * - * Precisely, the function is returned if the thread thread - * is dead or real time elapsed from wating begin - * is greater or equal the time specified. - * - * @param thread - * @param millis - * @param nanos - */ -void thread_join(jthread thread, long millis, int nanos); - -/** - * Resumes suspended thread thread execution. - * - * Precisely, cancels the effect of all previous < - * code>thread_suspend(thread) calls. - *

So, the thread thread may proceed execution. - * - * @param thread - */ -void thread_resume(jthread thread); - -/** - * Sets thread thread's local storage. - * - * @param env - * @param thread - * @param data - */ -int thread_set_jvmt_thread_local_storage(jvmtiEnv* env, - jthread thread, const void* data); -/** - * Sets thread thread's priority. - * - * The thread thread's priority gets - * equal to newPriority. - * - * @param thread - * @param newPriority - */ -void thread_set_priority(jthread thread, int newPriority); - -/** - * Makes thread thread to sleep for specified time. - * - * Thread thread gets sleeping till another thread - * invokes the thread_interrupt(thread) method or real time - * elapsed from sleeping begin is greater or equal the time specified. - * - * @param thread - * @param millis - * @param nanos - */ -void thread_sleep(jthread thread, long millis, int nanos); - -/** - * Thread thread execution begins. - * - * The thread thread's run() method is called. - * - * @param thread - */ -VMEXPORT void thread_start(JNIEnv*, jthread thread); - -/** - * Forces thread thread termination. - * - * Precisely, makes the thread thread to throw - * threadDeathException from the current execution point. - * - * @param thread - * @param threadDeathException - */ -void thread_stop(jthread thread, jobject threadDeathException); - -// GC can only be disabled in native code. In jitted code GC is always -// "enabled." Of course it doesn't mean that GC can happen at any point -// in jitted code -- only at GC-safe points. - -/** - * Suspends the thread thread execution. - * - * The thread thread's execution is suspended till - * thread_resume(thread) is called from another thread. - * - * @param thread - */ -void thread_suspend(jthread thread); - -/** - * Suspends the thread thread execution for a while. - * - * So, the other threads have possibility to be executed. - * - * @param thread - */ -void thread_yield(jthread thread); -//------------------------------------------------------------ -//------------------------------------------------------------ - -/** - * Get the current thread's interrupt event. - */ -VMEXPORT void* thread_get_interrupt_event(); - -#ifdef __cplusplus -} -#endif -#endif // _OPEN_THREAD_H_ Index: vm/include/open/vm_util.h =================================================================== --- vm/include/open/vm_util.h (revision 430048) +++ vm/include/open/vm_util.h (working copy) @@ -26,18 +26,18 @@ #include "port_malloc.h" #include "open/types.h" -class CriticalSection -{ -public: - VMEXPORT CriticalSection(); - VMEXPORT ~CriticalSection(); - VMEXPORT void lock(); - VMEXPORT void unlock(); - VMEXPORT bool tryLock(); -private: - /*CRITICAL_SECTION*/ void *m_cs; -}; +#include "hythread_ext.h" +inline IDATA wait_for_multiple_semaphores(int num, hysem_t *sems) { + for (int i = 0; i < num; i ++) { + IDATA stat = hysem_wait(sems[i]); + if (stat !=TM_ERROR_NONE) { + return stat; + } + } + return TM_ERROR_NONE; +} + typedef struct String String; // #include "String_Pool.h" @@ -66,22 +66,6 @@ void *_pcontext; // this would be a pointer to CONTEXT on NT }; -/** - * Low level thread and sync primitives. Should be replaced - * with java threading analogues during refactoring. - */ -VmThreadHandle vm_beginthreadex( void * security, unsigned stack_size, unsigned(__stdcall *start_address)(void *), void *arglist, unsigned initflag, pthread_t *thrdaddr); -VmThreadHandle vm_beginthread(void(__cdecl *start_address)(void *), unsigned stack_size, void *arglist); -void vm_endthreadex(int); -void vm_endthread(void); - -VmEventHandle vm_create_event(int *, unsigned int, unsigned int, char *); -BOOL vm_reset_event(VmEventHandle hEvent); -BOOL vm_set_event(VmEventHandle hEvent); -DWORD vm_wait_for_single_object(VmEventHandle hHandle, DWORD dwMilliseconds); -DWORD vm_wait_for_multiple_objects(DWORD num, const VmEventHandle * handle, BOOL flag, DWORD dwMilliseconds); - - VMEXPORT void vm_exit(int exit_code); unsigned sizeof_java_lang_class(); Index: vm/include/jvmti_types.h =================================================================== --- vm/include/jvmti_types.h (revision 430048) +++ vm/include/jvmti_types.h (working copy) @@ -42,8 +42,7 @@ typedef jobject jthread; typedef jlong jlocation; typedef jobject jthreadGroup; - struct jrawMonitorID_struct; - typedef struct jrawMonitorID_struct *jrawMonitorID; + typedef int jrawMonitorID; typedef struct JNINativeInterface_ jniNativeInterface; Index: vm/include/jni.h =================================================================== --- vm/include/jni.h (revision 430048) +++ vm/include/jni.h (working copy) @@ -20,7 +20,7 @@ /** * @file This file describes the JNI interface as per the JNI - * specification 1.4 available from Sun. + * specification 1.5 available from Sun. */ #ifndef _JNI_H_ Index: vm/interpreter/src/interpreter_ti.cpp =================================================================== --- vm/interpreter/src/interpreter_ti.cpp (revision 430048) +++ vm/interpreter/src/interpreter_ti.cpp (working copy) @@ -23,7 +23,7 @@ #include "interp_defs.h" #include "interp_native.h" #include "port_malloc.h" -#include "open/thread.h" + #include "thread_generic.h" static jint skip_old_frames(VM_thread *thread) @@ -38,14 +38,14 @@ Class *clss = method_get_class(first_frame->method); assert(clss); - if (strcmp(method_get_name(first_frame->method), "run") == 0 && + if (strcmp(method_get_name(first_frame->method), "runImpl") == 0 && strcmp(class_get_name(clss), "java/lang/VMStart$MainThread") == 0) { return 3; } } - return 0; + return 1; } jvmtiError @@ -174,7 +174,7 @@ return JVMTI_ERROR_TYPE_MISMATCH; } - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); ManagedObject *obj = UNCOMPRESS_REF(frame->locals(slot).cr); if (NULL == obj) { @@ -397,15 +397,15 @@ #endif - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(interpreter_ti_notification_mode & INTERPRETER_TI_METHOD_ENTRY_EVENT); jvmti_process_method_entry_event((jmethodID) method); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); } void method_exit_callback(Method *method, bool was_popped_by_exception, jvalue ret_val) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(interpreter_ti_notification_mode & INTERPRETER_TI_METHOD_EXIT_EVENT); jvmti_process_method_exit_event((jmethodID) method, @@ -414,7 +414,7 @@ void frame_pop_callback(FramePopListener *l, Method *method, jboolean was_popped_by_exception) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); tmn_suspend_enable(); while (l) { @@ -429,7 +429,7 @@ jvmtiError interpreter_ti_pop_frame(jvmtiEnv * UNREF env, VM_thread *thread) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); StackFrame *frame = getLastStackFrame(thread); if (frame->jvmti_pop_frame == POP_FRAME_AVAILABLE) { frame->jvmti_pop_frame = POP_FRAME_NOW; @@ -445,7 +445,7 @@ VM_thread *thread, int depth) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); StackFrame *frame = getLastStackFrame(thread); // skip depth of frames Index: vm/interpreter/src/interpreter.cpp =================================================================== --- vm/interpreter/src/interpreter.cpp (revision 430048) +++ vm/interpreter/src/interpreter.cpp (working copy) @@ -29,7 +29,7 @@ #include "interp_vm_helpers.h" #include "ini.h" #include "compile.h" -#include "open/thread.h" + #include "thread_manager.h" // ppervov: HACK: allows using STL modifiers (dec/hex) and special constants (endl) @@ -882,7 +882,7 @@ #define DEF_OPCODE_CMP(CMP,check) \ static inline void \ Opcode_##CMP(StackFrame& frame) { \ - tmn_safe_point(); \ + hythread_safe_point(); \ int32 val = frame.stack.pick().i; \ frame.stack.ref() = FLAG_NONE; /* for OPCODE_IFNULL */ \ DEBUG_BYTECODE("val = " << (int)val); \ @@ -906,7 +906,7 @@ #define DEF_OPCODE_IF_ICMPXX(NAME,cmp) \ static inline void \ Opcode_IF_ICMP ## NAME(StackFrame& frame) { \ - tmn_safe_point(); \ + hythread_safe_point(); \ int32 val0 = frame.stack.pick(1).i; \ int32 val1 = frame.stack.pick(0).i; \ frame.stack.ref(1) = FLAG_NONE; \ @@ -987,7 +987,7 @@ if (!other_class) { return false; } - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); frame.stack.pick().cr = COMPRESS_REF(*(other_class->class_handle)); frame.stack.ref() = FLAG_OBJECT; @@ -2004,7 +2004,7 @@ << method->get_name()->bytes << "/" << method->get_descriptor()->bytes<< endl); - tmn_safe_point(); + hythread_safe_point(); interpreterInvokeVirtual(frame, method); } @@ -2020,7 +2020,7 @@ << method->get_name()->bytes << "/" << method->get_descriptor()->bytes << endl); - tmn_safe_point(); + hythread_safe_point(); interpreterInvokeInterface(frame, method); } @@ -2042,7 +2042,7 @@ return; } - tmn_safe_point(); + hythread_safe_point(); interpreterInvokeStatic(frame, method); } @@ -2058,7 +2058,7 @@ << method->get_name()->bytes << "/" << method->get_descriptor()->bytes << endl); - tmn_safe_point(); + hythread_safe_point(); interpreterInvokeSpecial(frame, method); } @@ -2108,14 +2108,14 @@ static inline void Opcode_GOTO(StackFrame& frame) { - tmn_safe_point(); + hythread_safe_point(); DEBUG_BYTECODE("going to instruction"); frame.ip += read_int16(frame.ip + 1); } static inline void Opcode_GOTO_W(StackFrame& frame) { - tmn_safe_point(); + hythread_safe_point(); DEBUG_BYTECODE("going to instruction"); frame.ip += read_int32(frame.ip + 1); } @@ -2256,14 +2256,14 @@ return; } DEBUG_BYTECODE(" " << obj->vt()->clss->name->bytes << endl); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); set_current_thread_exception(obj); } bool findExceptionHandler(StackFrame& frame, ManagedObject **exception, Handler **hh) { assert(!exn_raised()); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Method *m = frame.method; DEBUG_BYTECODE("Searching for exception handler:"); @@ -2387,13 +2387,16 @@ static inline void UNUSED dump_all_java_stacks() { - tm_iterator_t * iterator = tm_iterator_create(); - VM_thread *thread = tm_iterator_next(iterator); + hythread_iterator_t iterator; + hythread_suspend_all(&iterator, NULL); + VM_thread *thread = get_vm_thread (hythread_iterator_next(&iterator)); while(thread) { stack_dump(thread); - thread = tm_iterator_next(iterator); + thread = get_vm_thread (hythread_iterator_next(&iterator)); } - tm_iterator_release(iterator); + + hythread_resume_all( NULL); + INFO("****** END OF JAVA STACKS *****\n"); } @@ -2407,9 +2410,9 @@ val.j = 0; if (exc) { - tmn_suspend_enable(); + hythread_suspend_enable(); method_exit_callback(method, true, val); - tmn_suspend_disable(); + hythread_suspend_disable(); return; } @@ -2447,9 +2450,9 @@ ABORT("Unexpected java type"); } - tmn_suspend_enable(); + hythread_suspend_enable(); method_exit_callback(method, false, val); - tmn_suspend_disable(); + hythread_suspend_disable(); } void @@ -2461,15 +2464,15 @@ M2N_ALLOC_MACRO; assert(!exn_raised()); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); - uint8 *first = (uint8*) p_TLS_vmthread->firstFrame; + uint8 *first = (uint8*) get_thread_ptr()->firstFrame; int stackLength = ((uint8*)first) - ((uint8*)&frame); if (stackLength > 500000) { // FIXME: hardcoded stack limit - if (!(p_TLS_vmthread->interpreter_state & INTERP_STATE_STACK_OVERFLOW)) { - p_TLS_vmthread->interpreter_state |= INTERP_STATE_STACK_OVERFLOW; + if (!(get_thread_ptr()->interpreter_state & INTERP_STATE_STACK_OVERFLOW)) { + get_thread_ptr()->interpreter_state |= INTERP_STATE_STACK_OVERFLOW; interp_throw_exception("java/lang/StackOverflowError"); - p_TLS_vmthread->interpreter_state &= ~INTERP_STATE_STACK_OVERFLOW; + get_thread_ptr()->interpreter_state &= ~INTERP_STATE_STACK_OVERFLOW; if (frame.framePopListener) frame_pop_callback(frame.framePopListener, frame.method, true); @@ -2481,9 +2484,9 @@ if (interpreter_ti_notification_mode & INTERPRETER_TI_METHOD_ENTRY_EVENT) { M2N_ALLOC_MACRO; - tmn_suspend_enable(); + hythread_suspend_enable(); method_entry_callback(frame.method); - tmn_suspend_disable(); + hythread_suspend_disable(); M2N_FREE_MACRO; } @@ -2528,7 +2531,7 @@ frame.last_bytecodes[(frame.n_last_bytecode++) & 7] = ip0; #endif - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); switch(ip0) { case OPCODE_NOP: Opcode_NOP(frame); break; @@ -2889,12 +2892,12 @@ exc = get_current_thread_exception(); if (exc == 0) continue; got_exception: - if (p_TLS_vmthread->ti_exception_callback_pending) { + if (get_thread_ptr()->ti_exception_callback_pending) { assert(exn_raised()); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); jvmti_interpreter_exception_event_callback_call(); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); exc = get_current_thread_exception(); @@ -2928,7 +2931,7 @@ if (frame.framePopListener) frame_pop_callback(frame.framePopListener, frame.method, true); M2N_FREE_MACRO; - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return; } } @@ -2939,7 +2942,7 @@ jvalue *return_value, jvalue *args) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); StackFrame frame; memset(&frame, 0, sizeof(frame)); @@ -2951,7 +2954,7 @@ frame.This = args[0].l->object; } if (frame.prev == 0) { - p_TLS_vmthread->firstFrame = (void*) &frame; + get_thread_ptr()->firstFrame = (void*) &frame; } setLastStackFrame(&frame); Index: vm/interpreter/src/interp_native_ipf.cpp =================================================================== --- vm/interpreter/src/interp_native_ipf.cpp (revision 430048) +++ vm/interpreter/src/interp_native_ipf.cpp (working copy) @@ -27,8 +27,8 @@ #include "interp_defs.h" #include "ini.h" -#include "open/thread.h" + // ppervov: HACK: allows using STL modifiers (dec/hex) and special constants (endl) using namespace std; @@ -71,7 +71,7 @@ Method *method, jvalue *return_value, jvalue *args) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); DEBUG_TRACE("\n<<< interpreter_invoke_native: " << method->get_class()->name->bytes << " " @@ -167,8 +167,8 @@ method_entry_callback(method); if (method->is_synchronized()) { - assert(tmn_is_suspend_enabled()); - vm_monitor_enter_slow_handle(_this); + assert(hythread_is_suspend_enabled()); + jthread_monitor_enter(_this); } int frameSize = 0; Index: vm/interpreter/src/interp_defs.h =================================================================== --- vm/interpreter/src/interp_defs.h (revision 430048) +++ vm/interpreter/src/interp_defs.h (working copy) @@ -260,7 +260,7 @@ /********* INLINE FUNCTIONS *******/ static inline StackFrame* getLastStackFrame() { - return (StackFrame*)p_TLS_vmthread->lastFrame; + return (StackFrame*)get_thread_ptr()->lastFrame; } static inline StackFrame* @@ -273,7 +273,7 @@ }; static inline void setLastStackFrame(StackFrame *frame) { - p_TLS_vmthread->lastFrame = frame; + get_thread_ptr()->lastFrame = frame; } void Index: vm/interpreter/src/interp_native.h =================================================================== --- vm/interpreter/src/interp_native.h (revision 430048) +++ vm/interpreter/src/interp_native.h (working copy) @@ -31,7 +31,7 @@ #define M2N_ALLOC_MACRO \ - assert(!tmn_is_suspend_enabled()); \ + assert(!hythread_is_suspend_enabled()); \ M2nFrame m2n; \ memset((void*)&m2n, 0, sizeof(M2nFrame)); \ m2n.prev_m2nf = m2n_get_last_frame(); \ @@ -47,7 +47,7 @@ m2n_set_local_handles(&m2n, (ObjectHandles*)&handles) #define M2N_FREE_MACRO \ - assert(!tmn_is_suspend_enabled()); \ + assert(!hythread_is_suspend_enabled()); \ free_local_object_handles2(m2n_get_local_handles(&m2n));\ m2n_set_last_frame(m2n_get_previous_frame(&m2n)) Index: vm/interpreter/src/interp_native_ia32.cpp =================================================================== --- vm/interpreter/src/interp_native_ia32.cpp (revision 430048) +++ vm/interpreter/src/interp_native_ia32.cpp (working copy) @@ -26,7 +26,7 @@ #include "interp_native.h" #include "interp_defs.h" #include "ini.h" -#include "open/thread.h" +#include "open/jthread.h" using namespace std; @@ -80,7 +80,7 @@ Method *method, jvalue *return_value, jvalue *args) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); DEBUG_TRACE("\n<<< interpreter_invoke_native: " << method->get_class()->name->bytes << " " @@ -160,8 +160,8 @@ if (method->is_synchronized()) { - assert(tmn_is_suspend_enabled()); - vm_monitor_enter_slow_handle(_this); + assert(hythread_is_suspend_enabled()); + jthread_monitor_enter(_this); } Index: vm/interpreter/src/interp_vm_helpers.cpp =================================================================== --- vm/interpreter/src/interp_vm_helpers.cpp (revision 430048) +++ vm/interpreter/src/interp_vm_helpers.cpp (working copy) @@ -27,9 +27,9 @@ void interp_throw_exception(const char* exc) { M2N_ALLOC_MACRO; - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); tmn_suspend_enable(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); throw_java_exception(exc); tmn_suspend_disable(); M2N_FREE_MACRO; @@ -37,9 +37,9 @@ void interp_throw_exception(const char* exc, const char *message) { M2N_ALLOC_MACRO; - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); tmn_suspend_enable(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); throw_java_exception(exc, message); tmn_suspend_disable(); M2N_FREE_MACRO; @@ -56,7 +56,7 @@ Class* interp_resolve_class(Class *clazz, int classId) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Compilation_Handle handle; handle.env = VM_Global_State::loader_env; handle.jit = 0; @@ -73,7 +73,7 @@ } Class* interp_resolve_class_new(Class *clazz, int classId) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Compilation_Handle handle; handle.env = VM_Global_State::loader_env; handle.jit = 0; @@ -91,7 +91,7 @@ Field* interp_resolve_static_field(Class *clazz, int fieldId, bool putfield) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Compilation_Handle handle; handle.env = VM_Global_State::loader_env; handle.jit = 0; @@ -109,7 +109,7 @@ } Field* interp_resolve_nonstatic_field(Class *clazz, int fieldId, bool putfield) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Compilation_Handle handle; handle.env = VM_Global_State::loader_env; handle.jit = 0; @@ -128,13 +128,13 @@ Method* interp_resolve_virtual_method(Class* clazz, int methodId) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Compilation_Handle handle; handle.env = VM_Global_State::loader_env; handle.jit = 0; tmn_suspend_enable(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Method *method = resolve_virtual_method( (Compile_Handle*)&handle, clazz, methodId); tmn_suspend_disable(); @@ -146,13 +146,13 @@ } Method* interp_resolve_interface_method(Class* clazz, int methodId) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Compilation_Handle handle; handle.env = VM_Global_State::loader_env; handle.jit = 0; tmn_suspend_enable(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Method *method = resolve_interface_method( (Compile_Handle*)&handle, clazz, methodId); tmn_suspend_disable(); @@ -164,7 +164,7 @@ } Method *interp_resolve_static_method(Class *clazz, int methodId) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Compilation_Handle handle; handle.env = VM_Global_State::loader_env; handle.jit = 0; @@ -181,7 +181,7 @@ } Method *interp_resolve_special_method(Class *clazz, int methodId) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Compilation_Handle handle; handle.env = VM_Global_State::loader_env; handle.jit = 0; Index: vm/interpreter/src/interp_native_em64t.cpp =================================================================== --- vm/interpreter/src/interp_native_em64t.cpp (revision 430048) +++ vm/interpreter/src/interp_native_em64t.cpp (working copy) @@ -22,6 +22,7 @@ #include "interpreter_exports.h" #include "interpreter_imports.h" +#include "find_natives.h" #include "exceptions.h" #include "mon_enter_exit.h" @@ -29,8 +30,8 @@ #include "interp_defs.h" #include "ini.h" -#include "open/thread.h" + // ppervov: HACK: allows using STL modifiers (dec/hex) and special constants (endl) using namespace std; @@ -70,7 +71,7 @@ Method *method, jvalue *return_value, jvalue *args) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); DEBUG_TRACE("\n<<< interpreter_invoke_native: " << method->get_class()->name->bytes << " " @@ -181,8 +182,8 @@ method_entry_callback(method); if (method->is_synchronized()) { - assert(tmn_is_suspend_enabled()); - vm_monitor_enter_slow_handle(_this); + assert(hythread_is_suspend_enabled()); + jthread_monitor_enter(_this); } jvalue *resultPtr = return_value; Index: vm/interpreter/src/interp_vm_helpers.h =================================================================== --- vm/interpreter/src/interp_vm_helpers.h (revision 430048) +++ vm/interpreter/src/interp_vm_helpers.h (working copy) @@ -18,9 +18,9 @@ * @version $Revision: 1.2.12.2.4.3 $ */ #include "Class.h" -#include "open/thread.h" + /** * Set thread-local exception with name 'exc'. */ Index: vm/port/include/port_atomic.h =================================================================== --- vm/port/include/port_atomic.h (revision 430048) +++ vm/port/include/port_atomic.h (working copy) @@ -27,8 +27,15 @@ #ifdef __cplusplus extern "C" { #endif - - +#ifdef __cplusplus +#define INLINE inline +#else +#ifdef WIN32 +#define INLINE __forceinline +#else +#define INLINE static +#endif +#endif /** * All atomic operrations are perfomance critical, * thus they are defined as inlined for most platforms in this file @@ -36,7 +43,8 @@ #if defined(_IPF_) - /** + +/** * Atomic compare and exchange operation * @data[in, out] * @value[in] new value @@ -65,10 +73,10 @@ */ APR_DECLARE(uint64) port_atomic_cas64(volatile uint64 * data, uint64 value, uint64 comp); - + #elif defined( WIN32 ) -inline uint8 port_atomic_cas8(volatile uint8 * data , uint8 value, uint8 comp) { +INLINE uint8 port_atomic_cas8(volatile uint8 * data , uint8 value, uint8 comp) { __asm { mov al, comp mov dl, value @@ -79,7 +87,7 @@ return comp; } -inline uint16 port_atomic_cas16(volatile uint16 * data , uint16 value, uint16 comp) { +INLINE uint16 port_atomic_cas16(volatile uint16 * data , uint16 value, uint16 comp) { __asm { mov ax, comp mov dx, value @@ -90,7 +98,7 @@ return comp; } -inline uint64 port_atomic_cas64(volatile uint64 * data , uint64 value, uint64 comp) { +INLINE uint64 port_atomic_cas64(volatile uint64 * data , uint64 value, uint64 comp) { __asm { lea esi, comp mov eax, [esi] @@ -112,7 +120,7 @@ #elif defined (PLATFORM_POSIX) -inline uint8 port_atomic_cas8(volatile uint8 * data , uint8 value, uint8 comp) { +INLINE uint8 port_atomic_cas8(volatile uint8 * data , uint8 value, uint8 comp) { #if defined(_IA32_) || defined(_EM64T_) __asm__ __volatile__( "lock cmpxchgb %1, (%2)" @@ -125,20 +133,22 @@ #endif } -inline uint16 port_atomic_cas16(volatile uint16 * data , uint16 value, uint16 comp) { +INLINE uint16 port_atomic_cas16(volatile uint16 * data , uint16 value, uint16 comp) { + uint16 ret; #if defined(_IA32_) || defined(_EM64T_) __asm__ __volatile__( - "lock cmpxchgw %1, (%2)" - :"=a"(comp) - :"d"(value), "r"(data), "0"(comp) + "lock cmpxchgw %w1, %2" + :"=a"(ret) + :"q"(value), "m"(*data), "0"(comp) + : "memory" ); - return comp; + return ret; #else ABORT("Not supported"); #endif } -inline uint64 port_atomic_cas64(volatile uint64 * data , uint64 value, uint64 comp) { +INLINE uint64 port_atomic_cas64(volatile uint64 * data , uint64 value, uint64 comp) { #if defined(_IA32_) __asm__ __volatile__( "lea %0, %%esi;\n\t" @@ -169,7 +179,7 @@ #endif } -inline void * port_atomic_compare_exchange_pointer(volatile void ** data, void * value, const void * comp) { +INLINE void * port_atomic_compare_exchange_pointer(volatile void ** data, void * value, const void * comp) { #if defined(_IA32_) //return (void *) port_atomic_compare_exchange32((uint32 *)data, (uint32)value, (uint32)comp); uint32 Exchange = (uint32)value; @@ -199,6 +209,8 @@ #endif //defined (POSIX) + + #ifdef __cplusplus } #endif Index: vm/port/src/encoder/ia32_em64t/encoder.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/encoder.cpp (revision 430048) +++ vm/port/src/encoder/ia32_em64t/encoder.cpp (working copy) @@ -130,10 +130,10 @@ const Mnemonic map_of_shift_opcode_2_mnemonic[] = { //shld_opc, shrd_opc, - // shl_opc, shr_opc, sar_opc, max_shift_opcode=5, - //n_shift = 5 + // shl_opc, shr_opc, sar_opc, ror_opc, max_shift_opcode=6, + //n_shift = 6 Mnemonic_SHLD, Mnemonic_SHRD, - Mnemonic_SHL, Mnemonic_SHR, Mnemonic_SAR, + Mnemonic_SHL, Mnemonic_SHR, Mnemonic_SAR, Mnemonic_ROR }; #ifdef _DEBUG Index: vm/port/src/encoder/ia32_em64t/encoder.inl =================================================================== --- vm/port/src/encoder/ia32_em64t/encoder.inl (revision 430048) +++ vm/port/src/encoder/ia32_em64t/encoder.inl (working copy) @@ -720,12 +720,12 @@ } ENCODER_DECLARE_EXPORT char * scas( char * stream, unsigned char prefix ) { + EncoderBase::Operands args; if (prefix != no_prefix) { assert(prefix == prefix_repnz || prefix == prefix_repz); *stream = prefix; ++stream; } - EncoderBase::Operands args; return (char*)EncoderBase::encode(stream, Mnemonic_SCAS, args); } @@ -735,6 +735,7 @@ *stream = prefix; ++stream; } + EncoderBase::Operands args; return (char*)EncoderBase::encode(stream, Mnemonic_STOS, args); } Index: vm/port/src/encoder/ia32_em64t/encoder.h =================================================================== --- vm/port/src/encoder/ia32_em64t/encoder.h (revision 430048) +++ vm/port/src/encoder/ia32_em64t/encoder.h (working copy) @@ -102,7 +102,7 @@ // enum Shift_Opcode { shld_opc, shrd_opc, shl_opc, shr_opc, - sar_opc, max_shift_opcode=5, n_shift = 5 + sar_opc, ror_opc, max_shift_opcode=6, n_shift = 6 }; enum ConditionCode { @@ -454,7 +454,7 @@ ENCODER_DECLARE_EXPORT char * test(char * stream, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf); ENCODER_DECLARE_EXPORT char * test(char * stream, const RM_Opnd & rm, const R_Opnd & r, Opnd_Size sz = size_platf); -// shift instructions: shl, shr, sar, shld, shrd +// shift instructions: shl, shr, sar, shld, shrd, ror ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, const Imm_Opnd & imm, Opnd_Size sz = size_platf); ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, Opnd_Size sz = size_platf); ENCODER_DECLARE_EXPORT char * shift(char * stream, Shift_Opcode opc, const RM_Opnd & rm, const R_Opnd & r, const Imm_Opnd & imm, Opnd_Size sz = size_platf); Index: vm/port/src/encoder/ia32_em64t/enc_tabl.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (revision 430048) +++ vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (working copy) @@ -1111,6 +1111,7 @@ DEFINE_SHIFT_MNEMONIC(SAL, _4) DEFINE_SHIFT_MNEMONIC(SAR, _7) DEFINE_SHIFT_MNEMONIC(SHR, _5) +DEFINE_SHIFT_MNEMONIC(ROR, _1) #undef DEFINE_SHIFT_MNEMONIC BEGIN_MNEMONIC(SHLD, true, false, false, false, N ) Index: vm/port/src/encoder/ia32_em64t/enc_defs.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_defs.h (revision 430048) +++ vm/port/src/encoder/ia32_em64t/enc_defs.h (working copy) @@ -527,6 +527,7 @@ Mnemonic_SAL, Mnemonic_SHL=Mnemonic_SAL,// Shift left Mnemonic_SAR, // Unsigned shift right +Mnemonic_ROR, // rotate right Mnemonic_SHR, // Signed shift right Mnemonic_SHRD, // Double Precision Shift Right Mnemonic_SHLD, // Double Precision Shift Left Index: vm/port/src/lil/ia32/pim/m2n_ia32.cpp =================================================================== --- vm/port/src/lil/ia32/pim/m2n_ia32.cpp (revision 430048) +++ vm/port/src/lil/ia32/pim/m2n_ia32.cpp (working copy) @@ -136,16 +136,11 @@ unsigned m2n_ts_to_register_size() { -#ifdef PLATFORM_POSIX return 22; -#else //!PLATFORM_POSIX - return 7; -#endif //!PLATFORM_POSIX } char* m2n_gen_ts_to_register(char* buf, R_Opnd* reg) { -#ifdef PLATFORM_POSIX if (reg!=&eax_opnd) buf = push(buf, eax_opnd); buf = push(buf, ecx_opnd); @@ -157,10 +152,6 @@ buf = mov(buf, *reg, eax_opnd); buf = pop(buf, eax_opnd); } -#else //!PLATFORM_POSIX - buf = prefix(buf, prefix_fs); - buf = mov(buf, *reg, M_Opnd(0x14)); -#endif //!PLATFORM_POSIX return buf; } Index: vm/port/src/lil/ipf/pim/m2n_ipf.cpp =================================================================== --- vm/port/src/lil/ipf/pim/m2n_ipf.cpp (revision 430048) +++ vm/port/src/lil/ipf/pim/m2n_ipf.cpp (working copy) @@ -33,8 +33,8 @@ #include "stub_code_utils.h" #include "open/vm_util.h" // For vm_get_boolean_property_value_with_default #include "interpreter.h" -#include "open/thread.h" + ////////////////////////////////////////////////////////////////////////// // Utilities @@ -98,7 +98,7 @@ void m2n_set_last_frame(M2nFrame* lm2nf) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); p_TLS_vmthread->last_m2n_frame = lm2nf; } @@ -222,7 +222,7 @@ void free_local_object_handles2(ObjectHandles* head); void m2n_pop_local_handles() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); M2nFrame *m2n = m2n_get_last_frame(); free_local_object_handles3(m2n_get_local_handles(m2n)); } Index: vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp =================================================================== --- vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp (revision 430048) +++ vm/port/src/lil/ipf/pim/stack_iterator_ipf.cpp (working copy) @@ -39,8 +39,8 @@ #include "stub_code_utils.h" #include "root_set_enum_internal.h" -#include "open/thread.h" + #include #include Index: vm/gc/src/garbage_collector.h =================================================================== --- vm/gc/src/garbage_collector.h (revision 430048) +++ vm/gc/src/garbage_collector.h (working copy) @@ -28,6 +28,7 @@ // Portlib interface header files #include "port_atomic.h" +#include "open/hythread_ext.h" // GC header files #include "hash_table.h" @@ -483,7 +484,7 @@ // set of blocks that contain at least one pinned root std::set m_pinned_blocks; - HANDLE *_gc_thread_work_finished_event_handles; + hysem_t *_gc_thread_work_finished_event_handles; Work_Packet_Manager *_mark_scan_pool; Index: vm/gc/src/work_packet_manager.cpp =================================================================== --- vm/gc/src/work_packet_manager.cpp (revision 430048) +++ vm/gc/src/work_packet_manager.cpp (working copy) @@ -26,6 +26,7 @@ #include #include #include +#include // VM interface header files @@ -299,7 +300,7 @@ } } - Sleep(0); + hythread_sleep(0); #ifndef _IPF_ #ifndef PLATFORM_POSIX Index: vm/gc/src/gc_header.h =================================================================== --- vm/gc/src/gc_header.h (revision 430048) +++ vm/gc/src/gc_header.h (working copy) @@ -29,6 +29,7 @@ #include "open/vm_gc.h" #include "open/vm.h" #include "gc_cout.h" +#include "open/hythread_ext.h" #include "hash_table.h" // @@ -578,7 +579,7 @@ // we still haven't got the lock // spin & yield until we grabbed the lock while (apr_atomic_cas32((volatile uint32 *)lock, 1, 0) == 1) { - Sleep(1); + hythread_yield(); } } } Index: vm/gc/src/block_store.cpp =================================================================== --- vm/gc/src/block_store.cpp (revision 430048) +++ vm/gc/src/block_store.cpp (working copy) @@ -345,7 +345,7 @@ while (apr_atomic_casptr((volatile void **)&block_store_lock, (void *)1, (void *)0) == (void *)1) { while (block_store_lock == (void *)1) { - Sleep(1); + hythread_yield(); } } } Index: vm/gc/src/gc_v4.cpp =================================================================== --- vm/gc/src/gc_v4.cpp (revision 430048) +++ vm/gc/src/gc_v4.cpp (working copy) @@ -26,8 +26,9 @@ using namespace std; // VM interface header files -#include "platform_lowlevel.h" +#include "open/vm_util.h" #include "open/vm_gc.h" +#include "open/hythread_ext.h" // GC header files #include "gc_cout.h" @@ -100,7 +101,7 @@ _p_block_store = new Block_Store(initial_heap_size, final_heap_size, block_size_bytes); - _gc_thread_work_finished_event_handles = (HANDLE *) STD_MALLOC(sizeof(HANDLE) * get_num_worker_threads()); + _gc_thread_work_finished_event_handles = (hysem_t *) STD_MALLOC(sizeof(hysem_t ) * get_num_worker_threads()); if (mark_scan_load_balanced) { _mark_scan_pool = new Work_Packet_Manager(); @@ -721,8 +722,8 @@ for (unsigned int y = 0; y < get_num_worker_threads(); y++) { _gc_threads[y]->set_task_to_do(task); - Boolean UNUSED sstat = SetEvent(_gc_threads[y]->get_gc_thread_start_work_event_handle()); - assert(sstat); + IDATA UNUSED sstat = hysem_post(_gc_threads[y]->get_gc_thread_start_work_event_handle()); + assert(sstat == TM_ERROR_NONE); } } @@ -730,9 +731,8 @@ void Garbage_Collector::wait_for_gc_threads_to_complete_assigned_task() { - DWORD UNUSED ret = WaitForMultipleObjects( (DWORD) get_num_worker_threads(), (const HANDLE *)_gc_thread_work_finished_event_handles, TRUE, INFINITE); - assert(ret != WAIT_TIMEOUT); - assert(ret != WAIT_FAILED); + IDATA UNUSED sstat = wait_for_multiple_semaphores( get_num_worker_threads(), _gc_thread_work_finished_event_handles); + assert(sstat == TM_ERROR_NONE); } #undef LOG_DOMAIN Index: vm/gc/src/gc_threads.cpp =================================================================== --- vm/gc/src/gc_threads.cpp (revision 430048) +++ vm/gc/src/gc_threads.cpp (working copy) @@ -62,8 +62,7 @@ extern bool sweeps_during_gc; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// -unsigned int __stdcall gc_thread_func (void *); - +int __cdecl gc_thread_func (void *arg); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// GC_Mark_Activity::GC_Mark_Activity(Garbage_Collector *p_gc) { @@ -88,7 +87,17 @@ assert(_input_packet == NULL); } -GC_Thread::GC_Thread(Garbage_Collector *p_gc, pthread_t gc_thread_id) + +hythread_group_t gc_thread_group = NULL; +hythread_group_t get_thread_group () { + if (!gc_thread_group) { + IDATA UNUSED stat = hythread_group_create(&gc_thread_group); + assert(stat == TM_ERROR_NONE); + } + return gc_thread_group; +} + +GC_Thread::GC_Thread(Garbage_Collector *p_gc, int gc_thread_id) : GC_Mark_Activity(p_gc) { @@ -106,37 +115,15 @@ } ////////////////// - _gc_thread_start_work_event = CreateEvent( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - NULL // pointer to event-object name - ); - assert(_gc_thread_start_work_event); - Boolean rstat = ResetEvent(_gc_thread_start_work_event); - assert(rstat); + IDATA stat = hysem_create(&_gc_thread_start_work_event, 0, 1); + assert(stat == TM_ERROR_NONE); - ////////////////// - _gc_thread_work_done_event = CreateEvent( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - NULL // pointer to event-object name - ); - assert(_gc_thread_work_done_event); - - rstat = ResetEvent(_gc_thread_work_done_event); - assert(rstat); - - _thread_handle = vm_beginthreadex(NULL, - 0, - gc_thread_func, - (LPVOID) this, - 0, - &(_thread_id)); - - if (!_thread_handle) { + stat = hysem_create(&_gc_thread_work_done_event, 0, 1); + assert(stat == TM_ERROR_NONE); + _thread_handle=NULL; + stat = hythread_create_with_group(&_thread_handle, get_thread_group(), 0, 0, 0, gc_thread_func, this); + if (stat != TM_ERROR_NONE) { DIE("GC_Thread::GC_Thread(..): CreateThread() failed...exiting..."); } @@ -151,8 +138,8 @@ GC_Thread::~GC_Thread() { - vm_destroy_event(_gc_thread_start_work_event); - vm_destroy_event(_gc_thread_work_done_event); + hysem_destroy(_gc_thread_start_work_event); + hysem_destroy(_gc_thread_work_done_event); } @@ -170,10 +157,10 @@ #endif } - Boolean rstat = ResetEvent(_gc_thread_start_work_event); - assert(rstat); - rstat = ResetEvent(_gc_thread_work_done_event); - assert(rstat); + IDATA rstat = hysem_set(_gc_thread_start_work_event,0); + assert(rstat == TM_ERROR_NONE); + rstat = hysem_set(_gc_thread_work_done_event,0); + assert(rstat == TM_ERROR_NONE); _num_bytes_recovered_by_sweep = 0; //////////////////////////////// @@ -187,8 +174,8 @@ void GC_Thread::wait_for_work() { - DWORD UNUSED wstat = WaitForSingleObject(_gc_thread_start_work_event, INFINITE); - assert(wstat != WAIT_FAILED); + IDATA UNUSED wstat = hysem_wait(_gc_thread_start_work_event); + assert(wstat == TM_ERROR_NONE); } @@ -197,15 +184,15 @@ GC_Thread::signal_work_is_done() { // I am done with my job. SIGNAL MASTER THREAD - Boolean UNUSED sstat = SetEvent(_gc_thread_work_done_event); - assert(sstat); + IDATA UNUSED sstat = hysem_post(_gc_thread_work_done_event); + assert(sstat == TM_ERROR_NONE); } volatile POINTER_SIZE_INT dummy_for_good_cache_performance = 0; -unsigned int __stdcall gc_thread_func (void *arg) +int __cdecl gc_thread_func (void *arg) { GC_Thread *p_gc_thread = (GC_Thread *) arg; assert(p_gc_thread); Index: vm/gc/src/gc_thread.h =================================================================== --- vm/gc/src/gc_thread.h (revision 430048) +++ vm/gc/src/gc_thread.h (working copy) @@ -25,6 +25,7 @@ #include "gc_cout.h" #include "faststack.h" #include "work_packet_manager.h" +#include "open/hythread_ext.h" class Garbage_Collector; @@ -107,7 +108,7 @@ public: - GC_Thread(Garbage_Collector *, pthread_t); + GC_Thread(Garbage_Collector *, int); virtual ~GC_Thread(); @@ -125,15 +126,15 @@ _task_to_do = task; } - VmThreadHandle get_thread_handle() { + hythread_t get_thread_handle() { return _thread_handle; } - inline HANDLE get_gc_thread_work_done_event_handle() { + inline hysem_t get_gc_thread_work_done_event_handle() { return _gc_thread_work_done_event; } - inline HANDLE get_gc_thread_start_work_event_handle() { + inline hysem_t get_gc_thread_start_work_event_handle() { return _gc_thread_start_work_event; } @@ -200,14 +201,12 @@ #ifdef _DEBUG chunk_sweep_stats _sweep_stats[GC_MAX_CHUNKS]; #endif - VmThreadHandle _thread_handle; + hythread_t _thread_handle; - pthread_t _thread_id; + hysem_t _gc_thread_start_work_event; - HANDLE _gc_thread_start_work_event; + hysem_t _gc_thread_work_done_event; - HANDLE _gc_thread_work_done_event; - gc_thread_action _task_to_do; unsigned int _clear_mark_start_index ; Index: vm/vmcore/include/object_generic.h =================================================================== --- vm/vmcore/include/object_generic.h (revision 430048) +++ vm/vmcore/include/object_generic.h (working copy) @@ -29,7 +29,7 @@ void java_lang_Object_notifyAll(jobject); -int +jint java_lang_Object_wait(jobject, jlong); void Index: vm/vmcore/include/vm_log.h =================================================================== --- vm/vmcore/include/vm_log.h (revision 430048) +++ vm/vmcore/include/vm_log.h (working copy) @@ -72,7 +72,7 @@ * The convenience method for logging managed objects. */ inline LoggerString& operator<<(LoggerString& log, /*const*/ ManagedObject* object) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); if (object) { log << object->vt()->clss << "@" << (void*) object; } else { @@ -85,13 +85,13 @@ * The convenience method for logging JNI object handles. */ inline LoggerString& operator<<(LoggerString& log, const jobject jobj) { - tmn_suspend_disable_recursive(); + hythread_suspend_disable(); if (jobj) { log << jobj->object; } else { log << ""; } - tmn_suspend_enable_recursive(); + hythread_suspend_enable(); return log; } Index: vm/vmcore/include/dll_jit_intf.h =================================================================== --- vm/vmcore/include/dll_jit_intf.h (revision 430048) +++ vm/vmcore/include/dll_jit_intf.h (working copy) @@ -27,7 +27,6 @@ #include "jit_export_jpda.h" #include #include -#include "open/thread.h" bool vm_is_a_jit_dll(const char *dll_filename); Index: vm/vmcore/include/thread_generic.h =================================================================== --- vm/vmcore/include/thread_generic.h (revision 430048) +++ vm/vmcore/include/thread_generic.h (working copy) @@ -29,34 +29,12 @@ extern "C" { #endif -#define MAX_VM_THREADS 2048 - -#define java_lang_Thread_NORM_PRIORITY 5L - -VM_thread *get_vm_thread_ptr(void *p_ref); - -void Java_java_lang_Thread_setPriority_generic(VM_thread *p_thr, long pty); -jint Java_java_lang_Thread_countStackFrames_generic(VM_thread *p_thr); - VMEXPORT VM_thread *get_vm_thread_ptr_safe(JNIEnv *, jobject); - ///////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////// -void Java_java_lang_Thread_start_generic(JNIEnv *, jobject, - jvmtiEnv * jvmtiEnv, jvmtiStartFunction proc, - const void* arg, jint priority); - -void Java_java_lang_Thread_interrupt_generic(VM_thread *) ; - -void Java_java_lang_Thread_sleep_generic(JNIEnv *, VM_thread *, int64); - -void set_interrupt_flag_in_thread_object(JNIEnv *, jobject ); - -void wait_until_non_daemon_threads_are_dead(); - #ifdef __cplusplus } #endif Index: vm/vmcore/include/object_layout.h =================================================================== --- vm/vmcore/include/object_layout.h (revision 430048) +++ vm/vmcore/include/object_layout.h (working copy) @@ -33,7 +33,7 @@ #include #include "open/types.h" -#include "open/thread.h" +#include "open/hythread_ext.h" #include "jni.h" #include "open/vm.h" typedef struct VTable VTable; @@ -87,14 +87,14 @@ return ((ManagedObjectUncompressedVtablePtr *)this)->vt_unsafe(); } VTable *vt() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); if (are_vtable_pointers_compressed()) return ((ManagedObjectCompressedVtablePtr *)this)->vt(); else return ((ManagedObjectUncompressedVtablePtr *)this)->vt(); } uint32 get_obj_info() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); if (are_vtable_pointers_compressed()) return ((ManagedObjectCompressedVtablePtr *)this)->get_obj_info(); else @@ -103,7 +103,7 @@ uint32 *get_obj_info_addr() { return (uint32 *)((char *)this + header_offset()); } void set_obj_info(uint32 value) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); if (are_vtable_pointers_compressed()) ((ManagedObjectCompressedVtablePtr *)this)->set_obj_info(value); else Index: vm/vmcore/include/jvmti_direct.h =================================================================== --- vm/vmcore/include/jvmti_direct.h (revision 430048) +++ vm/vmcore/include/jvmti_direct.h (working copy) @@ -24,11 +24,9 @@ #include "jni_direct.h" #include "jvmti.h" -class VM_thread; - struct TIEventThread { - VM_thread *thread; + hythread_t thread; TIEventThread *next; }; @@ -81,11 +79,17 @@ /* Events functions */ +#ifdef __cplusplus +extern "C" { +#endif + void jvmti_send_vm_start_event(Global_Env *env, JNIEnv *jni_env); void jvmti_send_vm_init_event(Global_Env *env); void jvmti_send_compiled_method_load_event(Method *method); void jvmti_send_dynamic_code_generated_event(const char *name, const void *address, jint length); -void jvmti_send_contended_enter_or_entered_monitor_event(jobject obj, bool isEnter); +VMEXPORT void jvmti_send_contended_enter_or_entered_monitor_event(jobject obj, int isEnter); +VMEXPORT void jvmti_send_wait_monitor_event(jobject obj, jlong timeout); +VMEXPORT void jvmti_send_waited_monitor_event(jobject obj, jboolean is_timed_out); void jvmti_send_exception_event(jthrowable exn_object, Method *method, jlocation location, Method *catch_method, jlocation catch_location); @@ -96,9 +100,13 @@ int classlen, unsigned char* classbytes, int* newclasslen, unsigned char** newclass); void jvmti_send_class_prepare_event(Class* clss); -void jvmti_send_thread_start_end_event(int is_start); +VMEXPORT void jvmti_send_thread_start_end_event(int is_start); void jvmti_send_vm_death_event(); +#ifdef __cplusplus +} +#endif + /* External events functions */ VMEXPORT void jvmti_interpreter_exception_event_callback_call(void); ManagedObject *jvmti_jit_exception_event_callback_call(ManagedObject *exn_object, Index: vm/vmcore/include/classloader.h =================================================================== --- vm/vmcore/include/classloader.h (revision 430048) +++ vm/vmcore/include/classloader.h (working copy) @@ -82,7 +82,7 @@ WaitingThread* m_waitingThreads; // this event is signaled when class loader finishes // (successfully or unsuccessfully) loading this class - VmEventHandle m_loadWaitEvent; + int m_loadWaitFlag; // thread which owns class definition VM_thread* m_defineOwner; // thread which first started loading this class @@ -94,7 +94,7 @@ #endif m_threadsPool(NULL), m_waitingThreads(NULL), - m_loadWaitEvent(0), + m_loadWaitFlag(0), m_defineOwner(NULL), m_initiatingThread(NULL) {} LoadingClass(const LoadingClass& lc) { @@ -103,7 +103,7 @@ #endif m_threadsPool = lc.m_threadsPool; m_waitingThreads = lc.m_waitingThreads; - m_loadWaitEvent = lc.m_loadWaitEvent; + m_loadWaitFlag = lc.m_loadWaitFlag; m_defineOwner = lc.m_defineOwner; m_initiatingThread = lc.m_initiatingThread; } @@ -113,7 +113,7 @@ #endif m_threadsPool = lc.m_threadsPool; m_waitingThreads = lc.m_waitingThreads; - m_loadWaitEvent = lc.m_loadWaitEvent; + m_loadWaitFlag = lc.m_loadWaitFlag; m_defineOwner = lc.m_defineOwner; m_initiatingThread = lc.m_initiatingThread; @@ -124,20 +124,16 @@ apr_pool_destroy(m_threadsPool); m_threadsPool = NULL; } - if(m_loadWaitEvent != 0) { - vm_destroy_event(m_loadWaitEvent); - m_loadWaitEvent = 0; - } + m_loadWaitFlag = 0; } - bool CreateWaitingEvent(const String* className); void WaitLoading() { - assert(m_loadWaitEvent != 0); - vm_wait_for_single_object(m_loadWaitEvent, INFINITE); + while(!m_loadWaitFlag) { + hythread_yield(); + } } void SignalLoading() { - if(m_loadWaitEvent != 0) - vm_set_event(m_loadWaitEvent); + m_loadWaitFlag = 1; } bool IsDefiner(VM_thread* thread) { return m_defineOwner == thread; } bool HasDefiner() { return m_defineOwner != NULL; } @@ -153,6 +149,7 @@ // this operation should be synchronized void RemoveWaitingThread(VM_thread* thread, ClassLoader* cl, const String* clsname); bool HasWaitingThreads() { return (m_waitingThreads != NULL); } + }; public: Index: vm/vmcore/include/vm_threads.h =================================================================== --- vm/vmcore/include/vm_threads.h (revision 430048) +++ vm/vmcore/include/vm_threads.h (working copy) @@ -31,28 +31,22 @@ #endif #include "open/types.h" +#include "open/hythread.h" +#include "open/ti_thread.h" #include "vm_core_types.h" #include "object_layout.h" #include "open/vm_gc.h" #include "jvmti.h" -#define GC_BYTES_IN_THREAD_LOCAL (20 * sizeof(void *)) -#define MAX_OWNED_MONITORS 100 +// +#define tmn_suspend_disable assert(hythread_is_suspend_enabled());hythread_suspend_disable +#define tmn_suspend_enable assert(!hythread_is_suspend_enabled());hythread_suspend_enable +#define tmn_suspend_disable_recursive hythread_suspend_disable +#define tmn_suspend_enable_recursive hythread_suspend_enable -// for SMP use the below -#define vm_lock_prefix lock +#define GC_BYTES_IN_THREAD_LOCAL (20 * sizeof(void *)) -enum java_state { - zip = 0, - thread_is_sleeping, - thread_is_waiting, - thread_is_timed_waiting, - thread_is_birthing, - thread_is_running, - thread_is_blocked, - thread_is_dying -}; // These are thread level gc states. enum gc_state { zero = 0, @@ -61,27 +55,7 @@ gc_enumeration_done }; -#if defined(PLATFORM_POSIX) && defined(_IPF_) -enum register_state { - NOT_VALID = (uint64)-1, -}; -enum suspend_state { - NOT_SUSPENDED = 0, - SUSPENDED_IN_SIGNAL_HANDLER = 1, - SUSPENDED_IN_DISABLE_GC_FOR_THREAD = 2, -}; -#endif - -typedef struct _thread_array { - VM_thread *p_vmthread; -} thread_array; - -typedef struct { - jvmtiEnv * env; - void * data; -} JVMTILocalStorage; - struct jvmti_frame_pop_listener; class VmRegisterContext; @@ -93,10 +67,6 @@ // has corrupted list of modules and no debug info at all. void* system_private_data; - // Pointer to java.lang.Thread associated with this VM_thread - // TODO: replace with jthread? - volatile Java_java_lang_Thread* p_java_lang_thread; - // In case exception is thrown, Exception object is put here // TODO: Needs to be replaced with jobject! volatile ManagedObject* p_exception_object; @@ -110,30 +80,12 @@ // Should JVMTI code be notified about exception in p_exception_object bool ti_exception_callback_pending; - VM_thread* p_free; - - // Next active thread in the global tread list - VM_thread* p_active; - // ?? - java_state app_status; - - // ?? gc_state gc_status; - - // Thread states as specified by JVMTI (alive, running, e.t.c.) - unsigned jvmti_thread_state; - + int finalize_thread_flags; // Flag indicating whether thread stopped. Duplicate of thread_state? bool is_stoped; - // ?? - bool interrupt_a_waiting_thread; - - - // JVMTI support. Seems to be duplicate. - jobject jvmti_owned_monitors[MAX_OWNED_MONITORS]; - int jvmti_owned_monitor_count; JVMTILocalStorage jvmti_local_storage; jvmti_frame_pop_listener *frame_pop_listener; @@ -154,41 +106,7 @@ bool gc_wait_for_enumeration; bool restore_context_after_gc_and_resume; - int finalize_thread_flags; - - VmEventHandle event_handle_monitor; - VmEventHandle event_handle_sleep; - VmEventHandle event_handle_interrupt; - VmThreadHandle thread_handle; - VmEventHandle jvmti_resume_event_handle; - pthread_t thread_id; - - VmEventHandle park_event; - // OS specifics goes below - // ============== new SUSPEND related variables: ===================== - volatile int suspend_enabled_status; // reentrant implementation - // 0 --enable, >0 disable - volatile int suspend_request; // request to suspend the thread, countable - // should relplace suspend_count - - VmEventHandle suspended_event; // set when thread is suspended - // should replace is_suspended - - VmEventHandle resume_event; - //sem_t sem_resume; // post it to resume - // should replace suspend_sem - //old suspend related variables - // How many times thread was suspended? Need to be resumed same amount of time. - int suspend_count; - - // Flag indicating whether thread suspended. Duplicate of thread_state? - bool is_suspended; - -#if defined(PLATFORM_POSIX) - sem_t yield_other_sem; -#endif - #if defined(PLATFORM_POSIX) && defined(_IPF_) // Linux/IPF sem_t suspend_sem; // To suspend thread in signal handler @@ -202,195 +120,32 @@ // t[0] <= rnat, t[1] <= bsp for other thread context #endif - // ?? - int thread_index; - - // object wait/notify event - int notify_recursion_count; - VmEventHandle event_handle_notify_or_interrupt; - - unsigned short stack_key; - // ?? void *lastFrame; void *firstFrame; int interpreter_state; + void** stack_end; /// The upper boundary of the stack to scan when verifying stack enumeration void* get_ip_from_regs() { return regs.get_ip(); } void reset_regs_ip() { return regs.reset_ip(); } - // TODO: need to be moved from here to the right place - int setPriority(int priority); - // is it used?? - void * jvmtiLocalStorage; - // JVMTI support. Also needs to be moved somewhere. - jint get_jvmti_thread_state(jthread thread); - void set_jvmti_thread_state(int one_bit_state); - - // dead-lock checks code -#define MAX_THREAD_LOCKS 256 -#ifdef _DEBUG - void* locks[MAX_THREAD_LOCKS]; - int locks_size; - void* contendent_lock; - void** stack_end; /// The upper boundary of the stack to scan when verifying stack enumeration -#endif //_DEBUG - }; - // dead-lock checks code +typedef VM_thread *vm_thread_accessor(); +VMEXPORT extern vm_thread_accessor *get_thread_ptr; -#ifdef _DEBUG -void push_lock(VM_thread *thread, void* lock); -void pop_lock(VM_thread *thread, void* lock); -void contends_lock(VM_thread *thread, void* lock); -#define JAVA_CODE_PSEUDO_LOCK ((void*)-2) +VMEXPORT VM_thread *get_vm_thread(hythread_t thr); -#define DEBUG_PUSH_LOCK(lock) push_lock(p_TLS_vmthread, lock) -#define DEBUG_POP_LOCK(lock) pop_lock(p_TLS_vmthread, lock) -#define DEBUG_CONTENDS_LOCK(lock) contends_lock(p_TLS_vmthread, lock) -#else //_DEBUG -#define DEBUG_PUSH_LOCK(lock) -#define DEBUG_POP_LOCK(lock) -#define DEBUG_CONTENDS_LOCK(lock) -#endif //_DEBUG +VMEXPORT void init_TLS_data(); - -extern int next_thread_index; - -#if defined(PLATFORM_POSIX) || defined(_IPF_) || defined (_IPF) || defined (WIN64) -#define USE_TLS_API -#endif - -#ifdef USE_TLS_API -#ifdef PLATFORM_POSIX -extern __thread VM_thread *p_TLS_vmthread; -//#define p_TLS_vmthread ((VM_thread *)pthread_getspecific(TLS_key_pvmthread)) -#define init_TLS_data() //pthread_key_create(&TLS_key_pvmthread, NULL) -#define set_TLS_data(pvmthread) do { \ - /*pthread_setspecific(TLS_key_pvmthread, (const void *)pvmthread);*/ \ - p_TLS_vmthread = pvmthread; \ - if (pvmthread != (void*)NULL) \ - ((VM_thread *)pvmthread)->stack_key = \ - (unsigned short)((VM_thread *)pvmthread)->thread_index; \ - } while(0); -#else //PLATFORM_POSIX -extern __declspec( thread ) VM_thread *p_TLS_vmthread; -#define set_TLS_data(pvmthread) do { \ - p_TLS_vmthread = pvmthread;\ - if (pvmthread != (void*)NULL) \ - ((VM_thread *)pvmthread)->stack_key = \ - ((VM_thread *)pvmthread)->thread_index; \ - } while(0); -#endif //!PLATFORM_POSIX +VMEXPORT void set_TLS_data(VM_thread *thread) ; uint16 get_self_stack_key(); -VM_thread *get_thread_ptr(); -#else //USE_TLS_API - -#pragma warning(push) -#pragma warning(disable:4035) -inline VM_thread *get_thread_ptr() -{ - VM_thread *p_thr; - _asm{ mov eax, fs:[0x14] - mov p_thr, eax - } - return p_thr; - -} -#pragma warning(pop) -inline void set_TLS_data(VM_thread *pvmthread) -{ - _asm{ - mov eax, pvmthread - mov fs:[0x14], eax - } - if (pvmthread != (void*)NULL) - pvmthread->stack_key = pvmthread->thread_index; -} #define p_TLS_vmthread (get_thread_ptr()) -uint16 get_self_stack_key(); -#endif //!USE_TLS_API -#ifdef PLATFORM_POSIX -bool SuspendThread(unsigned tid); -bool ResumeThread(unsigned tid); -#define SUSPEND_THREAD(vmthread) SuspendThread((vmthread)->thread_id) -#define RESUME_THREAD(vmthread) ResumeThread((vmthread)->thread_id) - -#else //PLATFORM_POSIX - -#define SUSPEND_THREAD(vmthread) SuspendThread((vmthread)->thread_handle) -#define RESUME_THREAD(vmthread) ResumeThread((vmthread)->thread_handle) -#endif //!PLATFORM_POSIX - - -bool thread_suspend_generic(VM_thread *thread); -bool thread_resume_generic(VM_thread *thread); - -void suspend_all_threads_except_current_generic(); -void resume_all_threads_generic(); - -VMEXPORT void suspend_all_threads_except_current(); - -VMEXPORT void resume_all_threads(); - -void jvmti_thread_resume(VM_thread *thread); - -void object_locks_init(); - -void __cdecl call_the_run_method( void * p_xx ); - -/* - * Thread park/unpark methods for java.util.concurrent.LockSupport; - */ -int park(void); -int parktimed(jlong milis, jint nanos); -int parkuntil(jlong milis, jint nanos); -int unpark(VM_thread *thread); - - - -void thread_gc_suspend_one(VM_thread *); -uint32 thread_gc_number_of_threads(); -VM_thread *thread_gc_enumerate_one(); Registers *thread_gc_get_context(VM_thread *, VmRegisterContext &); void thread_gc_set_context(VM_thread *); struct Global_Env; -#ifdef __cplusplus -extern "C" { -#endif - -void vm_thread_shutdown(); -void vm_thread_init(Global_Env *p_env); - -VM_thread * get_a_thread_block(); - -void free_this_thread_block(VM_thread *); - -extern VM_thread *p_free_thread_blocks; -extern VM_thread *p_active_threads_list; -extern VM_thread *p_threads_iterator; - -extern volatile VM_thread *p_the_safepoint_control_thread; // only set when a gc is happening -extern volatile safepoint_state global_safepoint_status; - -extern unsigned non_daemon_thread_count; - -extern VmEventHandle non_daemon_threads_dead_handle; -extern VmEventHandle new_thread_started_handle; - -extern VmEventHandle non_daemon_threads_are_all_dead; - -extern thread_array quick_thread_id[]; -extern POINTER_SIZE_INT hint_free_quick_thread_id; - -#ifdef __cplusplus -} -#endif - - #endif //!_VM_THREADS_H_ Index: vm/vmcore/include/verify_stack_enumeration.h =================================================================== --- vm/vmcore/include/verify_stack_enumeration.h (revision 430048) +++ vm/vmcore/include/verify_stack_enumeration.h (working copy) @@ -29,7 +29,7 @@ * BEWARE! This code is used in _DEBUG configuration only */ -#include "open/thread.h" +#include "vm_threads.h" extern int verify_stack_enumeration_period; extern int verify_stack_enumeration_counter; @@ -42,7 +42,7 @@ { // We verify stack enumeration only when the thread // is about to enable suspend, or just disabled it - if (p_TLS_vmthread->suspend_enabled_status != 1) return; + if (hythread_is_suspend_enabled()) return; // NB: safepoints in suspend enabled mode are ignored // such safepoints are used in suspend.cpp to avoid deadlocks Index: vm/vmcore/include/suspend_checker.h =================================================================== --- vm/vmcore/include/suspend_checker.h (revision 430048) +++ vm/vmcore/include/suspend_checker.h (working copy) @@ -22,19 +22,19 @@ #ifndef _SUSPEND_CHECKER_H_ #define _SUSPEND_CHECKER_H_ -#include "open/thread.h" +#include "open/hythread_ext.h" class SuspendEnabledChecker { public: inline SuspendEnabledChecker() { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); } inline ~SuspendEnabledChecker() { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); } }; @@ -43,12 +43,12 @@ public: inline SuspendDisabledChecker() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); } inline ~SuspendDisabledChecker() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); } }; Index: vm/vmcore/include/lock_manager.h =================================================================== --- vm/vmcore/include/lock_manager.h (revision 430048) +++ vm/vmcore/include/lock_manager.h (working copy) @@ -24,8 +24,7 @@ #ifndef _lock_manager_H_ #define _lock_manager_H_ -#include "open/vm_util.h" // for CriticalSection - +#include "open/vm_util.h" #include "open/types.h" #ifdef __cplusplus @@ -50,7 +49,7 @@ bool _lock_enum_or_null (bool return_null_on_fail); private: - /*CRITICAL_SECTION*/ CriticalSection _critical_section; + hymutex_t lock; }; @@ -70,11 +69,9 @@ extern Lock_Manager *p_jit_a_method_lock; extern Lock_Manager *p_vtable_patch_lock; extern Lock_Manager *p_meth_addr_table_lock; -extern Lock_Manager *p_thread_lock; // 20040224 Support for recording which methods (actually, CodeChunkInfo's) call which other methods. extern Lock_Manager *p_method_call_lock; -VMEXPORT extern Lock_Manager *p_gc_lock; -extern Lock_Manager *p_tm_lock; +extern Lock_Manager *p_handle_lock; #endif // __cplusplus #endif // _lock_manager_H_ Index: vm/vmcore/include/thread_manager.h =================================================================== --- vm/vmcore/include/thread_manager.h (revision 430048) +++ vm/vmcore/include/thread_manager.h (working copy) @@ -27,45 +27,21 @@ extern "C" { #endif -struct tm_iterator_t{ - bool init; - VM_thread * current; -}; - -void tm_acquire_tm_lock(); -void tm_release_tm_lock(); -bool tm_try_acquire_tm_lock(); - -tm_iterator_t * tm_iterator_create(); -int tm_iterator_release(tm_iterator_t *); -int tm_iterator_reset(tm_iterator_t *); -VM_thread * tm_iterator_next(tm_iterator_t *); void vm_thread_shutdown(); void vm_thread_init(Global_Env *p_env); -VM_thread * get_a_thread_block(); -void tmn_thread_attach(); +void vm_thread_attach(); +void vm_thread_detach(); void free_this_thread_block(VM_thread *); +VM_thread * get_a_thread_block(); -extern VM_thread *p_free_thread_blocks; -extern VM_thread *p_active_threads_list; -extern VM_thread *p_threads_iterator; extern volatile VM_thread *p_the_safepoint_control_thread; // only set when a gc is happening extern volatile safepoint_state global_safepoint_status; -extern unsigned non_daemon_thread_count; -extern VmEventHandle non_daemon_threads_dead_handle; -extern VmEventHandle new_thread_started_handle; - -extern VmEventHandle non_daemon_threads_are_all_dead; - -extern thread_array quick_thread_id[]; -extern POINTER_SIZE_INT hint_free_quick_thread_id; - #ifdef __cplusplus } #endif Index: vm/vmcore/include/mon_enter_exit.h =================================================================== --- vm/vmcore/include/mon_enter_exit.h (revision 430048) +++ vm/vmcore/include/mon_enter_exit.h (working copy) @@ -31,104 +31,18 @@ extern "C" { #endif - -// object header bits layout -// -// 31..............16 15......8 7......0 -// stack_key recursion_count ^^^^^^^7-bit hash -// ^contention_bit - -#define FREE_MONITOR 0 - #define P_HASH_CONTENTION_BYTE(x) ( (uint8 *)(x->get_obj_info_addr()) ) -#define P_STACK_KEY_SHORT(x) ( (uint16 *)((((ManagedObject*)x)->get_obj_info_addr())) + 1 ) +#define P_HASH_CONTENTION(x) ((POINTER_SIZE_INT)P_HASH_CONTENTION_BYTE(x)) -#define P_HASH_CONTENTION(x) P_HASH_CONTENTION_BYTE(x) -#define P_RECURSION(x) P_RECURSION_BYTE(x) -#define P_STACK_KEY(x) P_STACK_KEY_SHORT(x) - -#define HASH_CONTENTION(x) ( *P_HASH_CONTENTION(x) ) -#define RECURSION(x) ( *P_RECURSION(x) ) -#define STACK_KEY(x) ( *P_STACK_KEY(x) ) - - - // This is called once at startup, before any classes are loaded, // and after arguments are parsed. It should set function pointers // to the appropriate values. void vm_monitor_init(); - -// Tries to acquire the lock, but will not block or allow GC to -// happen if it is already locked by another thread. -// It is only called from block_on_mon_enter() which is called -// from vm_monitor_enter_slow() and thread_object_wait(), -// which basically means that it is not part of the general -// locking interface. -Boolean vm_try_monitor_enter(ManagedObject *p_obj); - // Does a monitorexit operation. extern void (*vm_monitor_exit)(ManagedObject *p_obj); -extern void (*vm_monitor_exit_handle)(jobject jobj); - -// Does a monitorenter, possibly blocking if the object is already -// locked. -void vm_monitor_enter_slow(ManagedObject *p_obj); -VMEXPORT void vm_monitor_enter_slow_handle (jobject jobj); - extern void (*vm_monitor_enter)(ManagedObject *p_obj); - -// Called only from vm_monitor_enter_slow() and thread_object_wait(), -// which basically means that it is not part of the general -// locking interface. -void block_on_mon_enter(jobject obj); - -// Tries to find a thread that is waiting on the lock for p_obj. -// If one is found, it is unblocked so that it can try again to -// acquire the lock. -void find_an_interested_thread(ManagedObject *p_obj); - -#define RECURSION_OFFSET 1 -#define STACK_KEY_OFFSET 2 -#define INPUT_ARG_OFFSET 4 -#define HASH_CONTENTION_AND_RECURSION_OFFSET 0 -#define CONTENTION_MASK 0x80 #define HASH_MASK 0x7e -#define SPIN_LOOP_COUNT 0x2 - -void set_hash_bits(ManagedObject *p_obj); - -typedef struct mon_enter_fields { - ManagedObject *p_obj; - VM_thread *p_thr; -} mon_enter_fields; - -extern mon_enter_fields mon_enter_array[]; -extern ManagedObject *obj_array[]; - -typedef struct mon_wait_fields { - ManagedObject *p_obj; - VM_thread *p_thr; -} mon_wait_fields; - -extern mon_wait_fields mon_wait_array[]; - -#ifdef _DEBUG -extern VM_thread *thread_array_for_debugging_only[]; -extern int max_notifyAll; -extern int max_recursion; -extern int total_sleep_timeouts; -extern int total_sleep_interrupts; -extern int total_wait_timeouts; -extern int total_wait_interrupts; -extern int total_illegal_mon_state_exceptions; -extern int iterations_per_thread[]; -extern int max_block_on_mon_enter_loops; -#endif - -extern volatile int active_thread_count; - - #ifdef __cplusplus } #endif Index: vm/vmcore/include/exceptions.h =================================================================== --- vm/vmcore/include/exceptions.h (revision 430048) +++ vm/vmcore/include/exceptions.h (working copy) @@ -243,6 +243,8 @@ // rth_throw_incompatible_class_change_exception throws an incompatible class change exception (lazily) NativeCodePtr exn_get_rth_throw_incompatible_class_change_exception(); +NativeCodePtr exn_get_rth_throw_illegal_state_exception(); + //**** Various standard exception types Class_Handle exn_get_class_cast_exception_type(); Index: vm/vmcore/src/jni/jni_array.cpp =================================================================== --- vm/vmcore/src/jni/jni_array.cpp (revision 430048) +++ vm/vmcore/src/jni/jni_array.cpp (working copy) @@ -28,7 +28,7 @@ #include "object_handles.h" #include "open/vm_util.h" #include "vm_threads.h" -#include "open/thread.h" + #include "ini.h" #include "vm_arrays.h" #include "nogc.h" @@ -41,7 +41,7 @@ jarray array) { TRACE2("jni", "GetArrayLength called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //-----------------v @@ -65,7 +65,7 @@ jobject initialElement) { TRACE2("jni", "NewObjectArray called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle elem_handle = (ObjectHandle)initialElement; Class* clss = jclass_to_struct_Class(elementClass); @@ -136,7 +136,7 @@ jobject JNICALL GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index) { TRACE2("jni", "GetObjectArrayElement called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (array == NULL) { // This should not happen. ASSERT(0, "Input parameter 'array' is NULL"); @@ -176,7 +176,7 @@ jobject value) { TRACE2("jni", "SetObjectArrayElement called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (array == NULL) { // This should not happen. ASSERT(0, "Input parameter 'array' is NULL"); @@ -235,7 +235,7 @@ jbooleanArray JNICALL NewBooleanArray(JNIEnv * UNREF env, jsize length) { TRACE2("jni", "NewBooleanArray called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *clss = VM_Global_State::loader_env->ArrayOfBoolean_Class; unsigned sz = vm_array_size(clss->vtable, length); @@ -267,7 +267,7 @@ jbyteArray JNICALL NewByteArray(JNIEnv * UNREF env, jsize length) { TRACE2("jni", "NewByteArray called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *clss = VM_Global_State::loader_env->ArrayOfByte_Class; assert(clss); @@ -300,7 +300,7 @@ jcharArray JNICALL NewCharArray(JNIEnv * UNREF env, jsize length) { TRACE2("jni", "NewCharArray called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *clss = VM_Global_State::loader_env->ArrayOfChar_Class; unsigned sz = vm_array_size(clss->vtable, length); @@ -332,7 +332,7 @@ jshortArray JNICALL NewShortArray(JNIEnv * UNREF env, jsize length) { TRACE2("jni", "NewShortArray called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *clss = VM_Global_State::loader_env->ArrayOfShort_Class; unsigned sz = vm_array_size(clss->vtable, length); @@ -365,7 +365,7 @@ jintArray JNICALL NewIntArray(JNIEnv * UNREF env, jsize length) { TRACE2("jni", "NewIntArray called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *clss = VM_Global_State::loader_env->ArrayOfInt_Class; unsigned sz = vm_array_size(clss->vtable, length); tmn_suspend_disable(); //---------------------------------v @@ -396,7 +396,7 @@ jlongArray JNICALL NewLongArray(JNIEnv * UNREF env, jsize length) { TRACE2("jni", "NewLongArray called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *clss = VM_Global_State::loader_env->ArrayOfLong_Class; unsigned sz = vm_array_size(clss->vtable, length); tmn_suspend_disable(); //---------------------------------v @@ -427,7 +427,7 @@ jfloatArray JNICALL NewFloatArray(JNIEnv * UNREF env, jsize length) { TRACE2("jni", "NewFloatArray called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *clss = VM_Global_State::loader_env->ArrayOfFloat_Class; unsigned sz = vm_array_size(clss->vtable, length); tmn_suspend_disable(); //---------------------------------v @@ -458,7 +458,7 @@ jdoubleArray JNICALL NewDoubleArray(JNIEnv * UNREF env, jsize length) { TRACE2("jni", "NewDoubleArray called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *clss = VM_Global_State::loader_env->ArrayOfDouble_Class; unsigned sz = vm_array_size(clss->vtable, length); tmn_suspend_disable(); //---------------------------------v @@ -499,7 +499,7 @@ jboolean *isCopy) { TRACE2("jni", "GetBooleanArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -539,7 +539,7 @@ jboolean *isCopy) { TRACE2("jni", "GetByteArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -579,7 +579,7 @@ jboolean *isCopy) { TRACE2("jni", "GetCharArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -619,7 +619,7 @@ jboolean *isCopy) { TRACE2("jni", "GetShortArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -659,7 +659,7 @@ jboolean *isCopy) { TRACE2("jni", "GetIntArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -700,7 +700,7 @@ jboolean *isCopy) { TRACE2("jni", "GetLongArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -740,7 +740,7 @@ jboolean *isCopy) { TRACE2("jni", "GetFloatArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -781,7 +781,7 @@ jboolean *isCopy) { TRACE2("jni", "GetDoubleArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -831,7 +831,7 @@ jint mode) { TRACE2("jni", "ReleaseBooleanArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -881,7 +881,7 @@ jint mode) { TRACE2("jni", "ReleaseByteArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -931,7 +931,7 @@ jint mode) { TRACE2("jni", "ReleaseCharArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -981,7 +981,7 @@ jint mode) { TRACE2("jni", "ReleaseShortArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -1031,7 +1031,7 @@ jint mode) { TRACE2("jni", "ReleaseIntArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -1081,7 +1081,7 @@ jint mode) { TRACE2("jni", "ReleaseLongArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -1131,7 +1131,7 @@ jint mode) { TRACE2("jni", "ReleaseFloatArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -1182,7 +1182,7 @@ jint mode) { TRACE2("jni", "ReleaseDoubleArrayElements called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)array; tmn_suspend_disable(); //---------------------------------v @@ -1242,7 +1242,7 @@ jboolean *buf) { TRACE2("jni", "GetBooleanArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1272,7 +1272,7 @@ jbyte *buf) { TRACE2("jni", "GetByteArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1302,7 +1302,7 @@ jchar *buf) { TRACE2("jni", "GetCharArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1332,7 +1332,7 @@ jshort *buf) { TRACE2("jni", "GetShortArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1362,7 +1362,7 @@ jint *buf) { TRACE2("jni", "GetIntArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1392,7 +1392,7 @@ jlong *buf) { TRACE2("jni", "GetLongArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1422,7 +1422,7 @@ jfloat *buf) { TRACE2("jni", "GetFloatArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1452,7 +1452,7 @@ jdouble *buf) { TRACE2("jni", "GetDoubleArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1490,7 +1490,7 @@ jboolean *buf) { TRACE2("jni", "SetBooleanArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1522,7 +1522,7 @@ jbyte *buf) { TRACE2("jni", "SetByteArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); if (len == 0) //don't need to do set exactly return; @@ -1556,7 +1556,7 @@ jchar *buf) { TRACE2("jni", "SetCharArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1588,7 +1588,7 @@ jshort *buf) { TRACE2("jni", "SetShortArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1620,7 +1620,7 @@ jint *buf) { TRACE2("jni", "SetIntArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1652,7 +1652,7 @@ jlong *buf) { TRACE2("jni", "SetLongArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1684,7 +1684,7 @@ jfloat *buf) { TRACE2("jni", "SetFloatArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; @@ -1716,7 +1716,7 @@ jdouble *buf) { TRACE2("jni", "SetDoubleArrayRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(len >= 0); jsize length = GetArrayLength(env, array); jsize end = start + len; Index: vm/vmcore/src/jni/jni.cpp =================================================================== --- vm/vmcore/src/jni/jni.cpp (revision 430048) +++ vm/vmcore/src/jni/jni.cpp (working copy) @@ -32,7 +32,8 @@ #include "open/types.h" #include "open/vm_util.h" #include "vm_threads.h" -#include "open/thread.h" +#include "open/jthread.h" + #include "vm_synch.h" #include "exceptions.h" #include "reflection.h" @@ -376,7 +377,7 @@ jsize len) { TRACE2("jni", "DefineClass called, name = " << name); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Global_Env* env = VM_Global_State::loader_env; ClassLoader* cl; if (loader != NULL) @@ -404,7 +405,7 @@ if(clss && ld_result) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return struct_Class_to_jclass(clss); } else @@ -431,6 +432,7 @@ jclass JNICALL FindClass(JNIEnv* env_ext, const char* name) { + if (exn_raised()) return NULL; TRACE2("jni", "FindClass called, name = " << name); char *ch = strchr(name, '.'); @@ -442,12 +444,13 @@ String* cls_name = VM_Global_State::loader_env->string_pool.lookup(name); return FindClass(env_ext, cls_name); + } //FindClass jclass JNICALL GetSuperclass(JNIEnv * UNREF env, jclass clazz) { TRACE2("jni", "GetSuperclass called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class* clss = jclass_to_struct_Class(clazz); if(clss) { if(class_is_interface(clss)) { @@ -455,7 +458,7 @@ } else { Class *super_class = clss->super_class; if(super_class) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return struct_Class_to_jclass(super_class); } else { return 0; @@ -471,7 +474,7 @@ jclass clazz2) { TRACE2("jni", "IsAssignableFrom called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class* clss1 = jclass_to_struct_Class(clazz1); Class* clss2 = jclass_to_struct_Class(clazz2); @@ -486,7 +489,7 @@ jint JNICALL Throw(JNIEnv * UNREF env, jthrowable obj) { TRACE2("jni", "Throw called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if(obj) { tmn_suspend_disable(); //---------------------------------v set_current_thread_exception(((ObjectHandle)obj)->object); @@ -500,7 +503,7 @@ jint JNICALL ThrowNew(JNIEnv *env, jclass clazz, const char *message) { TRACE2("jni", "ThrowNew called, message = " << (message ? message : "")); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (!clazz) return -1; jstring str = (jstring)0; @@ -544,7 +547,7 @@ jthrowable JNICALL ExceptionOccurred(JNIEnv * UNREF env) { TRACE2("jni", "ExceptionOccurred called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); #ifdef _DEBUG tmn_suspend_disable(); ManagedObject *obj = get_current_thread_exception(); @@ -569,7 +572,7 @@ void JNICALL ExceptionDescribe(JNIEnv * UNREF env) { TRACE2("jni", "ExceptionDescribe called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (exn_raised()) { tmn_suspend_disable(); //---------------------------------v ManagedObject* exn = get_current_thread_exception(); @@ -583,7 +586,7 @@ void JNICALL ExceptionClear(JNIEnv * UNREF env) { TRACE2("jni", "ExceptionClear called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); #ifdef _DEBUG ManagedObject *obj = get_current_thread_exception(); @@ -603,7 +606,7 @@ void JNICALL FatalError(JNIEnv * UNREF env, const char *msg) { TRACE2("jni", "FatalError called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); fprintf(stderr, "\nFATAL error occurred in a JNI native method:\n\t%s\n", msg); vm_exit(109); } //FatalError @@ -611,12 +614,12 @@ jobject JNICALL NewGlobalRef(JNIEnv * UNREF env, jobject obj) { TRACE2("jni", "NewGlobalRef called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if(!obj) { return 0; } - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle new_handle = oh_allocate_global_handle(); ObjectHandle old_handle = (ObjectHandle)obj; @@ -633,7 +636,7 @@ void JNICALL DeleteGlobalRef(JNIEnv * UNREF env, jobject globalRef) { TRACE2("jni", "DeleteGlobalRef called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); #ifdef _DEBUG tmn_suspend_disable(); ObjectHandle h = (ObjectHandle)globalRef; @@ -648,7 +651,7 @@ jobject JNICALL NewLocalRef(JNIEnv *env, jobject ref) { TRACE2("jni", "NewLocalRef called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (NULL == ref) return NULL; @@ -671,7 +674,7 @@ void JNICALL DeleteLocalRef(JNIEnv * UNREF env, jobject localRef) { TRACE2("jni", "DeleteLocalRef called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); #ifdef _DEBUG tmn_suspend_disable(); ObjectHandle h = (ObjectHandle)localRef; @@ -688,7 +691,7 @@ jobject ref2) { TRACE2("jni-same", "IsSameObject called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if(ref1 == ref2) { return JNI_TRUE; } @@ -718,7 +721,7 @@ VMEXPORT jint JNICALL PushLocalFrame(JNIEnv * UNREF env, jint UNREF cap) { TRACE2("jni", "PushLocalFrame called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // 20020904: Not good for performance, but we can ignore local frames for now return 0; } @@ -726,7 +729,7 @@ VMEXPORT jobject JNICALL PopLocalFrame(JNIEnv * UNREF env, jobject res) { TRACE2("jni", "PopLocalFrame called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // 20020904: Not good for performance, but we can ignore local frames for now return res; } @@ -735,7 +738,7 @@ jint JNICALL EnsureLocalCapacity(JNIEnv* UNREF env, jint UNREF cap) { TRACE2("jni", "EnsureLocalCapacity called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return 0; } @@ -744,7 +747,7 @@ jclass clazz) { TRACE2("jni", "AllocObject called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(clazz); Class* clss = jclass_to_struct_Class(clazz); @@ -776,7 +779,7 @@ ...) { TRACE2("jni", "NewObject called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return NewObjectV(env, clazz, methodID, args); @@ -788,7 +791,7 @@ va_list args) { TRACE2("jni", "NewObjectV called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jobject result = NewObjectA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -801,7 +804,7 @@ jvalue *args) { TRACE2("jni", "NewObjectA called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // Allocate the object. jobject new_handle = AllocObject(env, clazz); @@ -821,7 +824,7 @@ jobject obj) { TRACE2("jni", "GetObjectClass called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // The spec guarantees that the reference is not null. assert(obj); ObjectHandle h = (ObjectHandle)obj; @@ -845,7 +848,7 @@ jclass clazz) { TRACE2("jni", "IsInstanceOf called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if(!obj) { return JNI_TRUE; } @@ -869,7 +872,7 @@ jsize length) { TRACE2("jni", "NewString called, length = " << length); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return (jstring)string_create_from_unicode_h(unicodeChars, length); } //NewString @@ -877,7 +880,7 @@ jstring string) { TRACE2("jni", "GetStringLength called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if(!string) return 0; return string_get_length_h((ObjectHandle)string); } //GetStringLength @@ -887,7 +890,7 @@ jboolean *isCopy) { TRACE2("jni", "GetStringChars called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(string); tmn_suspend_disable(); @@ -903,7 +906,7 @@ const jchar *chars) { TRACE2("jni", "ReleaseStringChars called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); STD_FREE((void*)chars); } //ReleaseStringChars @@ -911,7 +914,7 @@ const char *bytes) { TRACE2("jni", "NewStringUTF called, bytes = " << bytes); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return (jstring)string_create_from_utf8_h(bytes, (unsigned)strlen(bytes)); } //NewStringUTF @@ -919,7 +922,7 @@ jstring string) { TRACE2("jni", "GetStringUTFLength called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return string_get_utf8_length_h((ObjectHandle)string); } //GetStringUTFLength @@ -928,7 +931,7 @@ jboolean *isCopy) { TRACE2("jni", "GetStringUTFChars called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if(!string) return 0; const char* res = string_get_utf8_chars_h((ObjectHandle)string); @@ -941,7 +944,7 @@ const char *utf) { TRACE2("jni", "ReleaseStringUTFChars called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); STD_FREE((void*)utf); } //ReleaseStringUTFChars @@ -951,7 +954,7 @@ jint nMethods) { TRACE2("jni", "RegisterNatives called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class_Handle clss = jclass_to_struct_Class(clazz); class_register_methods(clss, methods, nMethods); return class_register_methods(clss, methods, nMethods) ? -1 : 0; @@ -960,7 +963,7 @@ jint JNICALL UnregisterNatives(JNIEnv * UNREF env, jclass clazz) { TRACE2("jni", "UnregisterNatives called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class* clss = jclass_to_struct_Class(clazz); return class_unregister_methods(clss) ? -1 : 0; } //UnregisterNatives @@ -968,8 +971,8 @@ jint JNICALL MonitorEnter(JNIEnv * UNREF env, jobject obj) { TRACE2("jni", "MonitorEnter called"); - assert(tmn_is_suspend_enabled()); - vm_monitor_enter_slow_handle(obj); + assert(hythread_is_suspend_enabled()); + jthread_monitor_enter(obj); return exn_raised() ? -1 : 0; } //MonitorEnter @@ -978,8 +981,8 @@ jint JNICALL MonitorExit(JNIEnv * UNREF env, jobject obj) { TRACE2("jni", "MonitorExit called"); - assert(tmn_is_suspend_enabled()); - vm_monitor_exit_handle(obj); + assert(hythread_is_suspend_enabled()); + jthread_monitor_exit(obj); return exn_raised() ? -1 : 0; } //MonitorExit @@ -988,7 +991,7 @@ jint JNICALL GetJavaVM(JNIEnv *env_ext, JavaVM **vm) { TRACE2("jni", "GetJavaVM called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); JNIEnv_Internal *env = (JNIEnv_Internal *)env_ext; *vm = env->vm; return JNI_OK; @@ -998,7 +1001,7 @@ void JNICALL GetStringRegion(JNIEnv * UNREF env, jstring s, jsize off, jsize len, jchar *b) { TRACE2("jni", "GetStringRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(s); string_get_unicode_region_h((ObjectHandle)s, off, len, b); @@ -1007,14 +1010,14 @@ void JNICALL GetStringUTFRegion(JNIEnv * UNREF env, jstring s, jsize off, jsize len, char *b) { TRACE2("jni", "GetStringUTFRegion called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); string_get_utf8_region_h((ObjectHandle)s, off, len, b); } VMEXPORT void* JNICALL GetPrimitiveArrayCritical(JNIEnv* jenv, jarray array, jboolean* isCopy) { TRACE2("jni", "GetPrimitiveArrayCritical called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); Class* array_clss = ((ObjectHandle)array)->object->vt()->clss; tmn_suspend_enable(); @@ -1038,7 +1041,7 @@ VMEXPORT void JNICALL ReleasePrimitiveArrayCritical(JNIEnv* jenv, jarray array, void* carray, jint mode) { TRACE2("jni", "ReleasePrimitiveArrayCritical called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); Class* array_clss = ((ObjectHandle)array)->object->vt()->clss; tmn_suspend_enable(); @@ -1063,35 +1066,35 @@ const jchar* JNICALL GetStringCritical(JNIEnv *env, jstring s, jboolean* isCopy) { TRACE2("jni", "GetStringCritical called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return GetStringChars(env, s, isCopy); } void JNICALL ReleaseStringCritical(JNIEnv *env, jstring s, const jchar* cstr) { TRACE2("jni", "ReleaseStringCritical called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ReleaseStringChars(env, s, cstr); } VMEXPORT jweak JNICALL NewWeakGlobalRef(JNIEnv *env, jobject obj) { TRACE2("jni", "NewWeakGlobalRef called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return NewGlobalRef(env, obj); } VMEXPORT void JNICALL DeleteWeakGlobalRef(JNIEnv *env, jweak obj) { TRACE2("jni", "DeleteWeakGlobalRef called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); DeleteGlobalRef(env, obj); } jboolean JNICALL ExceptionCheck(JNIEnv * UNREF env) { TRACE2("jni", "ExceptionCheck called, exception status = " << exn_raised()); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (exn_raised()) return JNI_TRUE; else @@ -1262,7 +1265,7 @@ VMEXPORT jint JNICALL GetEnv(JavaVM* vm, void** penv, jint ver) { TRACE2("jni", "GetEnv called, ver = " << ver); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (p_TLS_vmthread == NULL) return JNI_EDETACHED; @@ -1347,7 +1350,7 @@ static void check_for_unexpected_exception(){ - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); ManagedObject * exc; if ((exc = get_current_thread_exception())) { @@ -1419,10 +1422,10 @@ gh_jldouble->object = struct_Class_to_java_lang_Class(jldouble); h_jlt->object= struct_Class_to_java_lang_Class(env->java_lang_Throwable_Class); tmn_suspend_enable(); //-------------------------------------------------------^ - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); gid_throwable_traceinfo = jenv->GetFieldID((jclass)h_jlt, "vm_stacktrace", "[J"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); gid_boolean_value = jenv->GetFieldID((jclass)gh_jlboolean, "value", "Z"); gid_byte_value = jenv->GetFieldID((jclass)gh_jlbyte, "value", "B"); @@ -1432,7 +1435,7 @@ gid_long_value = jenv->GetFieldID((jclass)gh_jllong, "value", "J"); gid_float_value = jenv->GetFieldID((jclass)gh_jlfloat, "value", "F"); gid_double_value = jenv->GetFieldID((jclass)gh_jldouble, "value", "D"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); gid_doubleisNaN = jenv->GetStaticMethodID((jclass)gh_jldouble, "isNaN", "(D)Z"); @@ -1440,37 +1443,37 @@ gid_string_field_value = jenv->GetFieldID((jclass)gh_jls, "value", "[C"); if(env->strings_are_compressed) gid_string_field_bvalue = jenv->GetFieldID((jclass)gh_jls, "bvalue", "[B"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); gid_string_field_offset = jenv->GetFieldID((jclass)gh_jls, "offset", "I"); gid_string_field_count = jenv->GetFieldID((jclass)gh_jls, "count", "I"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); oh_deallocate_global_handle(h_jlt); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); #ifdef USE_NATIVE_ISARRAY field_name = env->string_pool.lookup("isArray"); field_descr = env->string_pool.lookup("()Z"); gsig_ClassisArray = env->sig_table.lookup(field_name, field_descr); #endif //#ifndef USE_NATIVE_ISARRAY - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); } void unsafe_global_object_handles_init(){ - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); tmn_suspend_enable(); JNIEnv_Internal *jenv = jni_native_intf; jfieldID POSITIVE_INFINITY_id = jenv->GetStaticFieldID((jclass)gh_jldouble, "POSITIVE_INFINITY", "D"); gc_double_POSITIVE_INFINITY = jenv->GetStaticDoubleField((jclass)gh_jldouble, POSITIVE_INFINITY_id); check_for_unexpected_exception(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jfieldID NEGATIVE_INFINITY_id = jenv->GetStaticFieldID((jclass)gh_jldouble, "NEGATIVE_INFINITY", "D"); gc_double_NEGATIVE_INFINITY = jenv->GetStaticDoubleField((jclass)gh_jldouble, NEGATIVE_INFINITY_id); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); check_for_unexpected_exception(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); } Index: vm/vmcore/src/jni/jni_method.cpp =================================================================== --- vm/vmcore/src/jni/jni_method.cpp (revision 430048) +++ vm/vmcore/src/jni/jni_method.cpp (working copy) @@ -34,13 +34,13 @@ #include "object_handles.h" #include "open/vm_util.h" #include "vm_threads.h" -#include "open/thread.h" + #include "ini.h" #include "nogc.h" static bool ensure_initialised(JNIEnv* env, Class* clss) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if(clss->state != ST_Initialized) { class_initialize_from_jni(clss); if(clss->state == ST_Error) { @@ -64,7 +64,7 @@ const char *descr) { TRACE2("jni", "GetMethodID called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(clazz); Class* clss = jclass_to_struct_Class(clazz); @@ -97,7 +97,7 @@ const char *descr) { TRACE2("jni", "GetStaticMethodID called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class* clss = jclass_to_struct_Class(clazz); Method *method; @@ -152,7 +152,7 @@ jvalue *result, int non_virtual) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Method *method = (Method *)methodID; if ( !non_virtual && !method_is_private(method) ) { @@ -189,7 +189,7 @@ void JNICALL CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { TRACE2("jni", "CallVoidMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); CallVoidMethodV(env, obj, methodID, args); @@ -200,7 +200,7 @@ void JNICALL CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { TRACE2("jni", "CallVoidMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); CallVoidMethodA(env, obj, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -214,7 +214,7 @@ jvalue *args) { TRACE2("jni", "CallVoidMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); call_method_no_ref_result(env, obj, methodID, args, 0, FALSE); } //CallVoidMethodA @@ -223,7 +223,7 @@ jobject JNICALL CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { TRACE2("jni", "CallObjectMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallObjectMethodV(env, obj, methodID, args); @@ -234,7 +234,7 @@ jobject JNICALL CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { TRACE2("jni", "CallObjectMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jobject result = CallObjectMethodA(env, obj, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -249,7 +249,7 @@ jvalue *args) { TRACE2("jni", "CallObjectMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; Method *method = (Method *)methodID; // resolve to actual vtable entry below @@ -289,7 +289,7 @@ jboolean JNICALL CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { TRACE2("jni", "CallBooleanMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallBooleanMethodV(env, obj, methodID, args); @@ -300,7 +300,7 @@ jboolean JNICALL CallBooleanMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { TRACE2("jni", "CallBooleanMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jboolean result = CallBooleanMethodA(env, obj, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -315,7 +315,7 @@ jvalue *args) { TRACE2("jni", "CallBooleanMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, FALSE); return result.z; @@ -326,7 +326,7 @@ jbyte JNICALL CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { TRACE2("jni", "CallByteMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallByteMethodV(env, obj, methodID, args); @@ -337,7 +337,7 @@ jbyte JNICALL CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { TRACE2("jni", "CallByteMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jbyte result = CallByteMethodA(env, obj, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -352,7 +352,7 @@ jvalue *args) { TRACE2("jni", "CallByteMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, FALSE); return result.b; @@ -364,7 +364,7 @@ jchar JNICALL CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { TRACE2("jni", "CallCharMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallCharMethodV(env, obj, methodID, args); @@ -375,7 +375,7 @@ jchar JNICALL CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { TRACE2("jni", "CallCharMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jchar result = CallCharMethodA(env, obj, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -390,7 +390,7 @@ jvalue *args) { TRACE2("jni", "CallCharMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, FALSE); return result.c; @@ -402,7 +402,7 @@ jshort JNICALL CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { TRACE2("jni", "CallShortMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallShortMethodV(env, obj, methodID, args); @@ -413,7 +413,7 @@ jshort JNICALL CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { TRACE2("jni", "CallShortMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jshort result = CallShortMethodA(env, obj, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -428,7 +428,7 @@ jvalue *args) { TRACE2("jni", "CallShortMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, FALSE); return result.s; @@ -440,7 +440,7 @@ jint JNICALL CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { TRACE2("jni", "CallIntMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallIntMethodV(env, obj, methodID, args); @@ -451,7 +451,7 @@ jint JNICALL CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { TRACE2("jni", "CallIntMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jint result = CallIntMethodA(env, obj, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -466,7 +466,7 @@ jvalue *args) { TRACE2("jni", "CallIntMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, FALSE); return result.i; @@ -478,7 +478,7 @@ jlong JNICALL CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { TRACE2("jni", "CallLongMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallLongMethodV(env, obj, methodID, args); @@ -489,7 +489,7 @@ jlong JNICALL CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { TRACE2("jni", "CallLongMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jlong result = CallLongMethodA(env, obj, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -504,7 +504,7 @@ jvalue *args) { TRACE2("jni", "CallLongMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, FALSE); return result.j; @@ -516,7 +516,7 @@ jfloat JNICALL CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { TRACE2("jni", "CallFloatMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallFloatMethodV(env, obj, methodID, args); @@ -527,7 +527,7 @@ jfloat JNICALL CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { TRACE2("jni", "CallFloatMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jfloat result = CallFloatMethodA(env, obj, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -542,7 +542,7 @@ jvalue *args) { TRACE2("jni", "CallFloatMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, FALSE); return result.f; @@ -554,7 +554,7 @@ jdouble JNICALL CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...) { TRACE2("jni", "CallDoubleMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallDoubleMethodV(env, obj, methodID, args); @@ -565,7 +565,7 @@ jdouble JNICALL CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args) { TRACE2("jni", "CallDoubleMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jdouble result = CallDoubleMethodA(env, obj, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -580,7 +580,7 @@ jvalue *args) { TRACE2("jni", "CallDoubleMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, FALSE); return result.d; @@ -605,7 +605,7 @@ ...) { TRACE2("jni", "CallNonvirtualVoidMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); CallNonvirtualVoidMethodV(env, obj, clazz, methodID, args); @@ -620,7 +620,7 @@ va_list args) { TRACE2("jni", "CallNonvirtualVoidMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); CallNonvirtualVoidMethodA(env, obj, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -635,7 +635,7 @@ jvalue *args) { TRACE2("jni", "CallNonvirtualVoidMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); call_method_no_ref_result(env, obj, methodID, args, 0, TRUE); } //CallNonvirtualVoidMethodA @@ -648,7 +648,7 @@ ...) { TRACE2("jni", "CallNonvirtualObjectMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallNonvirtualObjectMethodV(env, obj, clazz, methodID, args); @@ -663,7 +663,7 @@ va_list args) { TRACE2("jni", "CallNonvirtualObjectMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jobject result = CallNonvirtualObjectMethodA(env, obj, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -679,7 +679,7 @@ jvalue *args) { TRACE2("jni", "CallNonvirtualObjectMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; Method *method = (Method *)methodID; if (!ensure_initialised(env, method->get_class())) @@ -706,7 +706,7 @@ ...) { TRACE2("jni", "CallNonvirtualBooleanMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallNonvirtualBooleanMethodV(env, obj, clazz, methodID, args); @@ -721,7 +721,7 @@ va_list args) { TRACE2("jni", "CallNonvirtualBooleanMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jboolean result = CallNonvirtualBooleanMethodA(env, obj, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -737,7 +737,7 @@ jvalue *args) { TRACE2("jni", "CallNonvirtualBooleanMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, TRUE); return result.z; @@ -752,7 +752,7 @@ ...) { TRACE2("jni", "CallNonvirtualByteMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallNonvirtualByteMethodV(env, obj, clazz, methodID, args); @@ -767,7 +767,7 @@ va_list args) { TRACE2("jni", "CallNonvirtualByteMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jbyte result = CallNonvirtualByteMethodA(env, obj, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -783,7 +783,7 @@ jvalue *args) { TRACE2("jni", "CallNonvirtualByteMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, TRUE); return result.b; @@ -798,7 +798,7 @@ ...) { TRACE2("jni", "CallNonvirtualCharMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallNonvirtualCharMethodV(env, obj, clazz, methodID, args); @@ -813,7 +813,7 @@ va_list args) { TRACE2("jni", "CallNonvirtualCharMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jchar result = CallNonvirtualCharMethodA(env, obj, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -829,7 +829,7 @@ jvalue *args) { TRACE2("jni", "CallNonvirtualCharMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, TRUE); return result.c; @@ -844,7 +844,7 @@ ...) { TRACE2("jni", "CallNonvirtualShortMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallNonvirtualShortMethodV(env, obj, clazz, methodID, args); @@ -859,7 +859,7 @@ va_list args) { TRACE2("jni", "CallNonvirtualShortMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jshort result = CallNonvirtualShortMethodA(env, obj, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -875,7 +875,7 @@ jvalue *args) { TRACE2("jni", "CallNonvirtualShortMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, TRUE); return result.s; @@ -890,7 +890,7 @@ ...) { TRACE2("jni", "CallNonvirtualIntMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallNonvirtualIntMethodV(env, obj, clazz, methodID, args); @@ -905,7 +905,7 @@ va_list args) { TRACE2("jni", "CallNonvirtualIntMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jint result = CallNonvirtualIntMethodA(env, obj, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -921,7 +921,7 @@ jvalue *args) { TRACE2("jni", "CallNonvirtualIntMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, TRUE); return result.i; @@ -936,7 +936,7 @@ ...) { TRACE2("jni", "CallNonvirtualLongMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallNonvirtualLongMethodV(env, obj, clazz, methodID, args); @@ -951,7 +951,7 @@ va_list args) { TRACE2("jni", "CallNonvirtualLongMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jlong result = CallNonvirtualLongMethodA(env, obj, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -967,7 +967,7 @@ jvalue *args) { TRACE2("jni", "CallNonvirtualLongMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, TRUE); return result.j; @@ -982,7 +982,7 @@ ...) { TRACE2("jni", "CallNonvirtualFloatMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallNonvirtualFloatMethodV(env, obj, clazz, methodID, args); @@ -997,7 +997,7 @@ va_list args) { TRACE2("jni", "CallNonvirtualFloatMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jfloat result = CallNonvirtualFloatMethodA(env, obj, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1013,7 +1013,7 @@ jvalue *args) { TRACE2("jni", "CallNonvirtualFloatMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, TRUE); return result.f; @@ -1028,7 +1028,7 @@ ...) { TRACE2("jni", "CallNonvirtualDoubleMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallNonvirtualDoubleMethodV(env, obj, clazz, methodID, args); @@ -1043,7 +1043,7 @@ va_list args) { TRACE2("jni", "CallNonvirtualDoubleMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jdouble result = CallNonvirtualDoubleMethodA(env, obj, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1059,7 +1059,7 @@ jvalue *args) { TRACE2("jni", "CallNonvirtualDoubleMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_method_no_ref_result(env, obj, methodID, args, &result, TRUE); return result.d; @@ -1082,7 +1082,7 @@ jvalue *args, jvalue *result) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Method *method = (Method *)methodID; if (!ensure_initialised(env, method->get_class())) return; @@ -1096,7 +1096,7 @@ jobject JNICALL CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { TRACE2("jni", "CallStaticObjectMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallStaticObjectMethodV(env, clazz, methodID, args); @@ -1107,7 +1107,7 @@ jobject JNICALL CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { TRACE2("jni", "CallStaticObjectMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jobject result = CallStaticObjectMethodA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1122,7 +1122,7 @@ jvalue *args) { TRACE2("jni", "CallStaticObjectMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; Method *method = (Method *)methodID; if (!ensure_initialised(env, method->get_class())) @@ -1143,7 +1143,7 @@ jboolean JNICALL CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { TRACE2("jni", "CallStaticBooleanMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallStaticBooleanMethodV(env, clazz, methodID, args); @@ -1154,7 +1154,7 @@ jboolean JNICALL CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { TRACE2("jni", "CallStaticBooleanMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jboolean result = CallStaticBooleanMethodA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1169,7 +1169,7 @@ jvalue *args) { TRACE2("jni", "CallStaticBooleanMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_static_method_no_ref_result(env, clazz, methodID, args, &result); return result.z; @@ -1180,7 +1180,7 @@ jbyte JNICALL CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { TRACE2("jni", "CallStaticByteMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallStaticByteMethodV(env, clazz, methodID, args); @@ -1191,7 +1191,7 @@ jbyte JNICALL CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { TRACE2("jni", "CallStaticByteMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jbyte result = CallStaticByteMethodA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1206,7 +1206,7 @@ jvalue *args) { TRACE2("jni", "CallStaticByteMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_static_method_no_ref_result(env, clazz, methodID, args, &result); return result.b; @@ -1217,7 +1217,7 @@ jchar JNICALL CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { TRACE2("jni", "CallStaticCharMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallStaticCharMethodV(env, clazz, methodID, args); @@ -1228,7 +1228,7 @@ jchar JNICALL CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { TRACE2("jni", "CallStaticCharMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jchar result = CallStaticCharMethodA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1243,7 +1243,7 @@ jvalue *args) { TRACE2("jni", "CallStaticCharMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_static_method_no_ref_result(env, clazz, methodID, args, &result); return result.c; @@ -1254,7 +1254,7 @@ jshort JNICALL CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { TRACE2("jni", "CallStaticShortMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallStaticShortMethodV(env, clazz, methodID, args); @@ -1265,7 +1265,7 @@ jshort JNICALL CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { TRACE2("jni", "CallStaticShortMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jshort result = CallStaticShortMethodA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1280,7 +1280,7 @@ jvalue *args) { TRACE2("jni", "CallStaticShortMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_static_method_no_ref_result(env, clazz, methodID, args, &result); return result.s; @@ -1291,7 +1291,7 @@ jint JNICALL CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { TRACE2("jni", "CallStaticIntMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallStaticIntMethodV(env, clazz, methodID, args); @@ -1302,7 +1302,7 @@ jint JNICALL CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { TRACE2("jni", "CallStaticIntMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jint result = CallStaticIntMethodA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1317,7 +1317,7 @@ jvalue *args) { TRACE2("jni", "CallStaticIntMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_static_method_no_ref_result(env, clazz, methodID, args, &result); return result.i; @@ -1328,7 +1328,7 @@ jlong JNICALL CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { TRACE2("jni", "CallStaticLongMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallStaticLongMethodV(env, clazz, methodID, args); @@ -1339,7 +1339,7 @@ jlong JNICALL CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { TRACE2("jni", "CallStaticLongMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jlong result = CallStaticLongMethodA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1354,7 +1354,7 @@ jvalue *args) { TRACE2("jni", "CallStaticLongMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_static_method_no_ref_result(env, clazz, methodID, args, &result); return result.j; @@ -1365,7 +1365,7 @@ jfloat JNICALL CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { TRACE2("jni", "CallStaticFloatMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallStaticFloatMethodV(env, clazz, methodID, args); @@ -1376,7 +1376,7 @@ jfloat JNICALL CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { TRACE2("jni", "CallStaticFloatMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jfloat result = CallStaticFloatMethodA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1391,7 +1391,7 @@ jvalue *args) { TRACE2("jni", "CallStaticFloatMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_static_method_no_ref_result(env, clazz, methodID, args, &result); return result.f; @@ -1402,7 +1402,7 @@ jdouble JNICALL CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { TRACE2("jni", "CallStaticDoubleMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); return CallStaticDoubleMethodV(env, clazz, methodID, args); @@ -1413,7 +1413,7 @@ jdouble JNICALL CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { TRACE2("jni", "CallStaticDoubleMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); jdouble result = CallStaticDoubleMethodA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1428,7 +1428,7 @@ jvalue *args) { TRACE2("jni", "CallStaticDoubleMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue result; call_static_method_no_ref_result(env, clazz, methodID, args, &result); return result.d; @@ -1439,7 +1439,7 @@ void JNICALL CallStaticVoidMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...) { TRACE2("jni", "CallStaticVoidMethod called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); va_list args; va_start(args, methodID); CallStaticVoidMethodV(env, clazz, methodID, args); @@ -1450,7 +1450,7 @@ void JNICALL CallStaticVoidMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) { TRACE2("jni", "CallStaticVoidMethodV called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvalue *jvalue_args = get_jvalue_arg_array((Method *)methodID, args); CallStaticVoidMethodA(env, clazz, methodID, jvalue_args); STD_FREE(jvalue_args); @@ -1464,7 +1464,7 @@ jvalue *args) { TRACE2("jni", "CallStaticVoidMethodA called, id = " << methodID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); call_static_method_no_ref_result(env, clazz, methodID, args, 0); } //CallStaticVoidMethodA Index: vm/vmcore/src/jni/jni_utils.cpp =================================================================== --- vm/vmcore/src/jni/jni_utils.cpp (revision 430048) +++ vm/vmcore/src/jni/jni_utils.cpp (working copy) @@ -39,8 +39,8 @@ #include "method_lookup.h" #include "nogc.h" #include "m2n.h" -#include "open/thread.h" + #include "exception.h" #include "stack_trace.h" @@ -52,7 +52,7 @@ jclass jni_class_from_handle(JNIEnv* UNREF jenv, Class_Handle clss) { if (!clss) return NULL; - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return struct_Class_to_jclass((Class*)clss); } @@ -452,7 +452,7 @@ //We'd better use this routine jclass SignatureToClass (JNIEnv* env_ext, const char* sig, ClassLoader *class_loader) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); JNIEnv_Internal *env = (JNIEnv_Internal *)env_ext; assert (sig); @@ -614,7 +614,7 @@ jclass FindClassWithClassLoader(JNIEnv* jenv, String *name, ClassLoader *loader) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class* c = loader->LoadVerifyAndPrepareClass( VM_Global_State::loader_env, name); assert(!exn_raised()); @@ -696,7 +696,7 @@ #endif JNIEnv_Internal *env = (JNIEnv_Internal *)env_ext; - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // Determine loader StackTraceFrame stf; bool res = st_get_frame(0, &stf); @@ -711,7 +711,7 @@ if(clss) { class_initialize_from_jni(clss); if (exn_raised()) return NULL; - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return struct_Class_to_jclass(clss); } else { // The JNI spec says that we should throw one of: ClassFormatError, @@ -730,7 +730,7 @@ jobject CreateNewThrowable(JNIEnv* jenv, Class* clazz, const char * message, jthrowable cause = 0) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (!clazz) { return NULL; @@ -773,7 +773,7 @@ initArgs[1].l = cause; jvalue res; - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); vm_execute_java_method_array((jmethodID) initCause, &res, initArgs); tmn_suspend_enable(); Index: vm/vmcore/src/jni/jni_field.cpp =================================================================== --- vm/vmcore/src/jni/jni_field.cpp (revision 430048) +++ vm/vmcore/src/jni/jni_field.cpp (working copy) @@ -31,14 +31,14 @@ #include "object_handles.h" #include "open/vm_util.h" #include "vm_threads.h" -#include "open/thread.h" + #include "ini.h" #include "exceptions.h" static bool ensure_initialised(JNIEnv* env, Class* clss) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if(clss->state != ST_Initialized) { class_initialize_from_jni(clss); if(clss->state == ST_Error) { @@ -60,7 +60,7 @@ const char *sig) { TRACE2("jni", "GetFieldID called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class* clss = jclass_to_struct_Class(clazz); Field *field = class_lookup_field_recursive(clss, name, sig); if (NULL == field || field->is_static()) @@ -82,9 +82,9 @@ const char *field_name, const char *sig) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); String *class_string = VM_Global_State::loader_env->string_pool.lookup(class_name); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *clss = class_load_verify_prepare_from_jni(VM_Global_State::loader_env, class_string); if(!clss) { @@ -100,7 +100,7 @@ const char *sig) { TRACE2("jni", "GetStaticFieldID called"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class* clss = jclass_to_struct_Class(clazz); Field *field = class_lookup_field_recursive(clss, name, sig); @@ -121,7 +121,7 @@ jobject JNICALL GetObjectFieldOffset(JNIEnv* UNREF env, jobject obj, jint offset) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -145,7 +145,7 @@ jfieldID fieldID) { TRACE2("jni", "GetObjectField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -158,7 +158,7 @@ jboolean JNICALL GetBooleanFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -176,7 +176,7 @@ jfieldID fieldID) { TRACE2("jni", "GetBooleanField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return 0; @@ -187,7 +187,7 @@ jbyte JNICALL GetByteFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -205,7 +205,7 @@ jfieldID fieldID) { TRACE2("jni", "GetByteField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -218,7 +218,7 @@ jchar JNICALL GetCharFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -236,7 +236,7 @@ jfieldID fieldID) { TRACE2("jni", "GetCharField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -249,7 +249,7 @@ jshort JNICALL GetShortFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -267,7 +267,7 @@ jfieldID fieldID) { TRACE2("jni", "GetShortField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -280,7 +280,7 @@ jint JNICALL GetIntFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -298,7 +298,7 @@ jfieldID fieldID) { TRACE2("jni", "GetIntField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -311,7 +311,7 @@ jlong JNICALL GetLongFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -329,7 +329,7 @@ jfieldID fieldID) { TRACE2("jni", "GetLongField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -342,7 +342,7 @@ jfloat JNICALL GetFloatFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -360,7 +360,7 @@ jfieldID fieldID) { TRACE2("jni", "GetFloatField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -373,7 +373,7 @@ jdouble JNICALL GetDoubleFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -391,7 +391,7 @@ jfieldID fieldID) { TRACE2("jni", "GetDoubleField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -414,7 +414,7 @@ void JNICALL SetObjectFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset, jobject value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; ObjectHandle v = (ObjectHandle)value; @@ -441,7 +441,7 @@ jobject value) { TRACE2("jni", "SetObjectField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -454,7 +454,7 @@ void JNICALL SetBooleanFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset, jboolean value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -471,7 +471,7 @@ jboolean value) { TRACE2("jni", "SetBooleanField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return; @@ -482,7 +482,7 @@ void JNICALL SetByteFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset, jbyte value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -502,7 +502,7 @@ jbyte value) { TRACE2("jni", "SetByteField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -515,7 +515,7 @@ void JNICALL SetCharFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset, jchar value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -532,7 +532,7 @@ jchar value) { TRACE2("jni", "SetCharField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -545,7 +545,7 @@ void JNICALL SetShortFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset, jshort value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -565,7 +565,7 @@ jshort value) { TRACE2("jni", "SetShortField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -578,7 +578,7 @@ void JNICALL SetIntFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset, jint value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -595,7 +595,7 @@ jint value) { TRACE2("jni", "SetIntField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -608,7 +608,7 @@ void JNICALL SetLongFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset, jlong value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -625,7 +625,7 @@ jlong value) { TRACE2("jni", "SetLongField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -637,7 +637,7 @@ void JNICALL SetFloatFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset, jfloat value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -654,7 +654,7 @@ jfloat value) { TRACE2("jni", "SetFloatField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -667,7 +667,7 @@ void JNICALL SetDoubleFieldOffset(JNIEnv * UNREF env, jobject obj, jint offset, jdouble value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ObjectHandle h = (ObjectHandle)obj; tmn_suspend_disable(); //---------------------------------v @@ -684,7 +684,7 @@ jdouble value) { TRACE2("jni", "SetDoubleField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); assert(IsInstanceOf(env, obj, struct_Class_to_jclass(f->get_class()))); @@ -713,7 +713,7 @@ jfieldID fieldID) { TRACE2("jni", "GetStaticObjectField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return 0; @@ -741,7 +741,7 @@ jfieldID fieldID) { TRACE2("jni", "GetStaticBooleanField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return 0; @@ -755,7 +755,7 @@ jfieldID fieldID) { TRACE2("jni", "GetStaticByteField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return 0; @@ -769,7 +769,7 @@ jfieldID fieldID) { TRACE2("jni", "GetStaticCharField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return 0; @@ -783,7 +783,7 @@ jfieldID fieldID) { TRACE2("jni", "GetStaticShortField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return 0; @@ -797,7 +797,7 @@ jfieldID fieldID) { TRACE2("jni", "GetStaticIntField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return 0; @@ -811,7 +811,7 @@ jfieldID fieldID) { TRACE2("jni", "GetStaticLongField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return 0; @@ -825,7 +825,7 @@ jfieldID fieldID) { TRACE2("jni", "GetStaticFloatField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return 0; @@ -839,7 +839,7 @@ jfieldID fieldID) { TRACE2("jni", "GetStaticDoubleField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return 0; @@ -866,7 +866,7 @@ jobject value) { TRACE2("jni", "SetStaticObjectField called, id = " << fieldID); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return; @@ -892,7 +892,7 @@ jboolean value) { TRACE2("jni", "SetStaticBooleanField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return; @@ -908,7 +908,7 @@ jbyte value) { TRACE2("jni", "SetStaticByteField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return; @@ -928,7 +928,7 @@ jchar value) { TRACE2("jni", "SetStaticCharField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return; @@ -944,7 +944,7 @@ jshort value) { TRACE2("jni", "SetStaticShortField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return; @@ -964,7 +964,7 @@ jint value) { TRACE2("jni", "SetStaticIntField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return; @@ -981,7 +981,7 @@ jlong value) { TRACE2("jni", "SetStaticLongField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return; @@ -997,7 +997,7 @@ jfloat value) { TRACE2("jni", "SetStaticFloatField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return; @@ -1013,7 +1013,7 @@ jdouble value) { TRACE2("jni", "SetStaticDoubleField called, id = " << fieldID << " value = " << value); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Field *f = (Field *)fieldID; assert(f); if (!ensure_initialised(env, f->get_class())) return; Index: vm/vmcore/src/jit/ini.cpp =================================================================== --- vm/vmcore/src/jit/ini.cpp (revision 430048) +++ vm/vmcore/src/jit/ini.cpp (working copy) @@ -25,22 +25,19 @@ #include "ini.h" #include "environment.h" #include "open/em_vm.h" -#include "open/thread.h" + void vm_execute_java_method_array(jmethodID method, jvalue *result, jvalue *args) { // TODO: select jit which compiled the method - assert(!tmn_is_suspend_enabled()); - int tmn_suspend_disable_count(); - assert(tmn_suspend_disable_count()==1); - DEBUG_PUSH_LOCK(JAVA_CODE_PSEUDO_LOCK); + assert(!hythread_is_suspend_enabled()); + //FIXME integration + //DEBUG_PUSH_LOCK(JAVA_CODE_PSEUDO_LOCK); assert(NULL != VM_Global_State::loader_env); assert(NULL != VM_Global_State::loader_env->em_interface); assert(NULL != VM_Global_State::loader_env->em_interface->ExecuteMethod); VM_Global_State::loader_env->em_interface->ExecuteMethod(method, result, args); - DEBUG_POP_LOCK(JAVA_CODE_PSEUDO_LOCK); - int tmn_suspend_disable_count(); - assert(tmn_suspend_disable_count()==1); + //DEBUG_POP_LOCK(JAVA_CODE_PSEUDO_LOCK); } Index: vm/vmcore/src/jit/jit_runtime_support.cpp =================================================================== --- vm/vmcore/src/jit/jit_runtime_support.cpp (revision 430048) +++ vm/vmcore/src/jit/jit_runtime_support.cpp (working copy) @@ -59,7 +59,7 @@ #include "open/types.h" #include "open/bytecodes.h" #include "open/vm_util.h" -#include "open/thread.h" + #include "jvmti_interface.h" #include "compile.h" @@ -173,10 +173,10 @@ } else if (cp_is_class(cp, cp_index)) { - assert(!tmn_is_suspend_enabled()); - tmn_suspend_enable(); + assert(!hythread_is_suspend_enabled()); + hythread_suspend_enable(); Class *objClass = class_resolve_class(c, cp_index); - tmn_suspend_disable(); + hythread_suspend_disable(); if (objClass) { return struct_Class_to_java_lang_Class(objClass); } @@ -696,7 +696,7 @@ vm_stats_total.num_is_class_initialized++; clss->num_class_init_checks++; #endif // VM_STATS - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return clss->state == ST_Initialized; } //is_class_initialized @@ -1494,7 +1494,7 @@ if (addr) { return addr; } - void (*tmn_safe_point_ptr)() = tmn_safe_point; + void (*hythread_safe_point_ptr)() = hythread_safe_point; LilCodeStub* cs = lil_parse_code_stub("entry 0:managed::void;"); assert(cs); if (dyn_count) { @@ -1507,7 +1507,7 @@ "call %0i;" "pop_m2n;" "ret;", - tmn_safe_point_ptr); + hythread_safe_point_ptr); assert(cs && lil_is_valid(cs)); addr = LilCodeGenerator::get_platform()->compile(cs, "rth_gc_safe_point", dump_stubs); lil_free_code_stub(cs); @@ -1515,7 +1515,7 @@ } static NativeCodePtr rth_get_lil_gc_thread_suspend_flag_ptr(int * dyn_count) { - static NativeCodePtr addr = NULL; + /*static NativeCodePtr addr = NULL; if (addr) { return addr; } @@ -1536,7 +1536,9 @@ addr = LilCodeGenerator::get_platform()->compile(cs, "rth_get_lil_gc_thread_suspend_flag_ptr", dump_stubs); lil_free_code_stub(cs); - return addr; + */ + //assert(0); + return (NativeCodePtr)hythread_self; } static void * rth_resolve(Class_Handle klass, unsigned cp_idx, @@ -1548,7 +1550,7 @@ Compile_Handle ch = (Compile_Handle)&comp_handle; void * ret = NULL; - tmn_suspend_enable(); + hythread_suspend_enable(); switch(opcode) { case OPCODE_INVOKEINTERFACE: ret = resolve_interface_method(ch, klass, cp_idx); @@ -1582,7 +1584,7 @@ opcode == OPCODE_PUTSTATIC); if (ret != NULL) { Class_Handle that_class = method_get_class((Method_Handle)ret); - tmn_suspend_disable(); + hythread_suspend_disable(); if (class_needs_initialization(that_class)) { assert(!exn_raised()); class_initialize_ex(that_class); @@ -1594,7 +1596,7 @@ ret = resolve_static_method(ch, klass, cp_idx); if (ret != NULL) { Class_Handle that_class = method_get_class((Method_Handle)ret); - tmn_suspend_disable(); + hythread_suspend_disable(); if (class_needs_initialization(that_class)) { assert(!exn_raised()); class_initialize_ex(that_class); @@ -1605,7 +1607,7 @@ default: assert(false); } // ~switch(opcode) - tmn_suspend_disable(); + hythread_suspend_disable(); if (ret == NULL) { class_throw_linking_error(klass, cp_idx, opcode); assert(false); // must be unreachanble @@ -1831,7 +1833,7 @@ */ void *vm_malloc_with_thread_pointer( unsigned size, Allocation_Handle ah, void *tp) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); void *result = gc_alloc(size,ah,tp); if (!result) { exn_throw(VM_Global_State::loader_env->java_lang_OutOfMemoryError); @@ -1851,8 +1853,8 @@ ManagedObject *class_alloc_new_object(Class *c) { - assert(!tmn_is_suspend_enabled()); - //tmn_suspend_disable(); + assert(!hythread_is_suspend_enabled()); + //hythread_suspend_disable(); assert(strcmp(c->name->bytes, "java/lang/Class")); #ifdef VM_STATS vm_stats_total.num_class_alloc_new_object++; @@ -1865,17 +1867,17 @@ if (!o) { exn_throw( VM_Global_State::loader_env->java_lang_OutOfMemoryError); - //tmn_suspend_enable(); + //hythread_suspend_enable(); return 0; // whether this return is reached or not is solved via is_unwindable state } - //tmn_suspend_enable(); + //hythread_suspend_enable(); return o; } //class_alloc_new_object ManagedObject *class_alloc_new_object_using_vtable(VTable *vtable) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(strcmp(vtable->clss->name->bytes, "java/lang/Class")); #ifdef VM_STATS vm_stats_total.num_class_alloc_new_object++; @@ -1909,7 +1911,7 @@ Method *constructor, uint8 *constructor_args) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(strcmp(clss->name->bytes, "java/lang/Class")); ObjectHandle obj = oh_allocate_local_handle(); @@ -1993,7 +1995,7 @@ arg_num++; assert(arg_num <= num_args_estimate); } - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); vm_execute_java_method_array((jmethodID) constructor, 0, args); if (exn_raised()) { @@ -2520,7 +2522,7 @@ VMEXPORT // temporary solution for interpreter unplug int __stdcall vm_instanceof(ManagedObject *obj, Class *c) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); #ifdef VM_STATS vm_stats_total.num_instanceof++; @@ -2680,13 +2682,13 @@ "entry 0:stdcall:pint:pint;" // the single argument is 'void*' "push_m2n 0, 0;" // create m2n frame "out stdcall::void;" - "call %0i;" // call tmn_suspend_enable() - "in2out stdcall:pint;" // reload input arg into output + "call %0i;" // call hythread_suspend_enable() + "in2out stdcall:pint;" // reloads input arg into output "call %1i;" // call the foo "locals 2;" // "l0 = r;" // save result "out stdcall::void;" - "call %2i;" // call tmn_suspen_disable() + "call %2i;" // call hythread_suspend_disable() "l1 = ts;" "ld l1, [l1 + %3i:ref];" "jc l1 != 0,_exn_raised;" // test whether an exception happened @@ -2698,8 +2700,8 @@ "call.noret %4i;"; // re-throw exception void * fptr_rethrow = (void*)&rethrow_current_thread_exception; - void * fptr_suspend_enable = (void*)&tmn_suspend_enable; - void * fptr_suspend_disable = (void*)&tmn_suspend_disable; + void * fptr_suspend_enable = (void*)&hythread_suspend_enable; + void * fptr_suspend_disable = (void*)&hythread_suspend_disable; LilCodeStub* cs = lil_parse_code_stub( lil_stub, Index: vm/vmcore/src/jit/compile.cpp =================================================================== --- vm/vmcore/src/jit/compile.cpp (revision 430048) +++ vm/vmcore/src/jit/compile.cpp (working copy) @@ -29,9 +29,11 @@ #include "jit_intf_cpp.h" #include "em_intf.h" #include "heap.h" -#include "open/thread.h" + + #include "vm_stats.h" #include "vm_strings.h" + #include "compile.h" #include "jit_runtime_support.h" #include "lil_code_generator.h" @@ -421,7 +423,7 @@ cs = lil_parse_onto_end(cs, "out platform::void;" "call %0i;", - tmn_suspend_enable); + hythread_suspend_enable); assert(cs); //***** Part 5: Set up arguments @@ -502,7 +504,7 @@ cs = lil_parse_onto_end(cs, "out platform::void;" "call %0i;", - tmn_suspend_disable); + hythread_suspend_disable); assert(cs); //***** Part 9: Synchronise @@ -733,7 +735,7 @@ // Assumes that GC is disabled, but a GC-safe point static JIT_Result compile_do_compilation(Method* method, JIT_Flags flags) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); class_initialize_ex(method->get_class()); tmn_suspend_enable(); @@ -777,7 +779,7 @@ static ManagedObject* compile_make_exception(const char* name, Method* method) { // FIXME: prototype should be changed to getrid of managed objects as parameters. // Now it works in gc disabled mode because of prototype. - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); ObjectHandle old_exn = oh_allocate_local_handle(); old_exn->object = get_current_thread_exception(); clear_current_thread_exception(); @@ -834,9 +836,7 @@ NativeCodePtr compile_jit_a_method(Method* method) { { // Start of block with GcFrames - int tmn_suspend_disable_count(); - TRACE2("compile", "compile_jit_a_method " << method << " sus_copunt:" << tmn_suspend_disable_count()); - assert(tmn_suspend_disable_count()==1); + TRACE2("compile", "compile_jit_a_method " << method ); ASSERT_NO_INTERPRETER; @@ -851,7 +851,6 @@ tmn_suspend_enable(); JIT_Result res = compile_do_compilation(method, flags); tmn_suspend_disable(); - if (res == JIT_SUCCESS) { assert(&gc == p_TLS_vmthread->gc_frames); NativeCodePtr entry_point = method->get_code_addr(); @@ -861,11 +860,12 @@ return entry_point; } - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); INFO2("compile", "Could not compile " << method); - const char* exn_class; + + ManagedObject *cause = get_current_thread_exception(); if (!cause) { if (method->is_native()) { Index: vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp =================================================================== --- vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp (revision 430048) +++ vm/vmcore/src/gc/stop_the_world_root_set_enum.cpp (working copy) @@ -55,12 +55,12 @@ vm_enumerate_the_current_thread() { // Process roots for the current thread - assert(p_TLS_vmthread->gc_status == zero); - p_TLS_vmthread->gc_status = gc_at_safepoint; + //assert(p_TLS_vmthread->gc_status == zero); + //p_TLS_vmthread->gc_status = gc_at_safepoint; vm_enumerate_thread(p_TLS_vmthread); // Enumeration for this thread is complete. - p_TLS_vmthread->gc_status = gc_enumeration_done; + //p_TLS_vmthread->gc_status = gc_enumeration_done; } // vm_enumerate_the_current_thread @@ -84,28 +84,33 @@ INFO2("threads","Start thread suspension "); vm_time_start_hook(&_start_time); //thread suspension time measurement - suspend_all_threads_except_current(); + + hythread_iterator_t iterator; + hythread_suspend_all(&iterator, NULL); + thread_suspend_time = vm_time_end_hook(&_start_time, &_end_time); - INFO2("threads","Thread suspension time: "<< thread_suspend_time <<" mksec"); + INFO2("tm.suspend","Thread suspension time: "<< thread_suspend_time <<" mksec"); class_unloading_clear_mark_bits(); // Run through list of active threads and enumerate each one of them. - tmn_suspend_enable(); // to make tm_iterator_create()happy: it uses assert(tmn_is_suspend_enabled()); - tm_iterator_t * iterator = tm_iterator_create(); - tmn_suspend_disable(); - VM_thread *thread = tm_iterator_next(iterator); - while(thread) { - if (thread != p_TLS_vmthread) { + hythread_t tm_thread = hythread_iterator_next(&iterator); + + //VM_thread *thread = get_vm_thread (hythread_iterator_next(&iterator)); + while(tm_thread) { + VM_thread *thread = get_vm_thread(tm_thread); + if (thread && thread != p_TLS_vmthread) { vm_enumerate_thread(thread); // Enumeration for this thread is complete. - thread->gc_status = gc_enumeration_done; + //thread->gc_status = gc_enumeration_done; + //assert(thread->gc_status==gc_enumeration_done); + //thread->gc_status=gc_enumeration_done; } - thread = tm_iterator_next(iterator); + tm_thread = hythread_iterator_next(&iterator); } - tm_iterator_release(iterator); vm_enumerate_the_current_thread(); + // finally, process all the global refs vm_enumerate_root_set_global_refs(); @@ -121,7 +126,7 @@ void vm_enumerate_root_set_all_threads() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // it is convenient to have gc_enabled_status == disabled // during the enumeration -salikh @@ -135,14 +140,7 @@ stop_the_world_root_set_enumeration(); - // ASSERT that enumeration is done for all threads... - int n_threads = thread_gc_number_of_threads(); - for(int i = 0; i < n_threads; i++) { - VM_thread * UNUSED thread = (VM_thread *) thread_gc_enumerate_one(); - assert (thread->gc_status == gc_enumeration_done); - } - - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // vm_gc_unlock_enum expects suspend enabled, enable it here } //vm_enumerate_root_set_all_threads @@ -161,7 +159,7 @@ class_unloading_start(); // Run through list of active threads and resume each one of them. - resume_all_threads(); + hythread_resume_all( NULL); // Make sure register stack is up-to-date with the potentially updated backing store si_reload_registers(); @@ -174,10 +172,10 @@ // which itself operates either with // gc_enabled_status == disabled, e.g. from managed code, // but at the GC-safe point (because the collection was done) - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); tmn_suspend_enable(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // Finalizers and reference enqueuing is performed from vm_hint_finalize(), // GC guarantees to call this function after the completion of collection, @@ -212,8 +210,7 @@ } StackIterator* si; TRACE2("enumeration", "Enumerating thread " << thread << - (thread == p_TLS_vmthread ? ", this thread" : ", suspended in native code") - << ", GCEnabled=" << (thread -> suspend_enabled_status)); + (thread == p_TLS_vmthread ? ", this thread" : ", suspended in native code")); si = si_create_from_native(thread); vm_enumerate_root_set_single_thread_on_stack(si); // Enumerate references associated with a thread that are not stored on the thread's stack. Index: vm/vmcore/src/gc/dll_gc.cpp =================================================================== --- vm/vmcore/src/gc/dll_gc.cpp (revision 430048) +++ vm/vmcore/src/gc/dll_gc.cpp (working copy) @@ -26,6 +26,7 @@ #ifndef USE_GC_STATIC #include +#include #include "dll_gc.h" #include "open/gc.h" #include "open/vm_util.h" @@ -284,15 +285,21 @@ apr_dso_handle_t *handle; bool result = false; - if (apr_dso_load(&handle, dll_filename, pool) == APR_SUCCESS) + apr_status_t stat; + if ((stat = apr_dso_load(&handle, dll_filename, pool)) == APR_SUCCESS) { apr_dso_handle_sym_t tmp; if (apr_dso_sym(&tmp, handle, "gc_init") == APR_SUCCESS) { result = true; } apr_dso_unload(handle); + } else { + char buf[1024]; + apr_dso_error(handle, buf, 1024); + WARN("Loading error" << buf); + //apr_strerror(stat, buf, 1024); + //printf("error %s, is %d, expected %d\n", buf, stat, APR_SUCCESS); } - return result; } //vm_is_a_gc_dll Index: vm/vmcore/src/gc/root_set_enum_common.cpp =================================================================== --- vm/vmcore/src/gc/root_set_enum_common.cpp (revision 430048) +++ vm/vmcore/src/gc/root_set_enum_common.cpp (working copy) @@ -227,9 +227,6 @@ void vm_enumerate_root_set_single_thread_not_on_stack(VM_thread *thread) { assert(thread); - if (thread->p_java_lang_thread != NULL) { - vm_enumerate_root_reference((void **)&(thread->p_java_lang_thread), FALSE); - } if (thread->p_exception_object != NULL) { vm_enumerate_root_reference((void **)&(thread->p_exception_object), FALSE); } Index: vm/vmcore/src/jvmti/jvmti_rawmon.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_rawmon.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_rawmon.cpp (working copy) @@ -30,97 +30,10 @@ #include "vm_threads.h" #include "vm_process.h" #include "cxxlog.h" -#include "open/thread.h" +#include "open/ti_thread.h" #include "suspend_checker.h" -#define JVMTI_RAW_MONITOR_TABLE_SIZE 100 -/** - * Struct of raw monitor - */ -struct jvmtiRawMonitor -{ - // lock monitor object - Lock_Manager m_owner_lock; - // lock wait lock object - Lock_Manager m_wait_lock; - // owner thread - VM_thread *m_owner_thread; - // wait event - VmEventHandle m_wait_event; - // wait notify event - VmEventHandle m_notify_event; - // recursive enter counter - unsigned m_owned_count; - // monitor entry counter - unsigned m_enter_count; - // monitor waters count - unsigned m_wait_count; - // flag for notify - bool m_leave; - // flag for notifyAll - bool m_notifyall; - // constructor - jvmtiRawMonitor(): m_owner_thread(NULL), - m_wait_event(0), m_notify_event(0), - m_owned_count(0), m_enter_count(0), m_wait_count(0), - m_leave(false), m_notifyall(false) {} -}; - -/** - * Raw monitor table entry - */ -struct jvmtiRawMonitorTableEntry { - // pointer for raw monitor - jvmtiRawMonitor *m_monitor; - // index of next free entry of table - int m_nextFree; - // constructor - jvmtiRawMonitorTableEntry(): m_monitor(NULL), m_nextFree(-1) {} -}; - -/** - * Raw monitor table - */ -static jvmtiRawMonitorTableEntry g_rawMonitors[JVMTI_RAW_MONITOR_TABLE_SIZE]; - -/** - * Free entry in raw monitor table - */ -static unsigned g_freeMonitor = 1; - -/** - * Global entry locker for raw monitor - */ -static Lock_Manager jvmtiRawMonitorLock; - -/** - * Function checks valid monitor in raw monitor table - * and checks monitor owner for thread. - */ -static jvmtiError -jvmtiCheckValidMonitor( jrawMonitorID monitor ) -{ - jvmtiRawMonitor *rawmonitor; - unsigned index; - - /** - * Check valid monitor in raw monitor table - */ - if( (index=(unsigned)((POINTER_SIZE_INT)monitor)) >= JVMTI_RAW_MONITOR_TABLE_SIZE - || ( (rawmonitor = g_rawMonitors[index].m_monitor) == NULL ) ) - { - return JVMTI_ERROR_INVALID_MONITOR; - } - /** - * Check monitor owner for thread - */ - if( rawmonitor->m_owner_thread != get_thread_ptr() ) { - return JVMTI_ERROR_NOT_MONITOR_OWNER; - } - return JVMTI_ERROR_NONE; -} // jvmtiCheckValidMonitor - /* * Create Raw Monitor * @@ -137,88 +50,11 @@ * Monitor trace */ TRACE2("jvmti.monitor", "CreateRawMonitor called, name = " << name); - SuspendEnabledChecker sec; - - /** - * Check given env & current phase. - */ - jvmtiPhase phases[] = {JVMTI_PHASE_ONLOAD, JVMTI_PHASE_LIVE}; - - CHECK_EVERYTHING(); - - /** - * Check valid name and monitor_ptr - */ - if( !name || !monitor_ptr ) { + if (name == NULL || monitor_ptr == NULL){ return JVMTI_ERROR_NULL_POINTER; } - *monitor_ptr = 0; - /** - * Check valid index in raw monitor table - */ - if( g_freeMonitor >= JVMTI_RAW_MONITOR_TABLE_SIZE ) { - return JVMTI_ERROR_OUT_OF_MEMORY; - } - /** - * Only one thread can run next block - * another will be stopped at global raw monitor lock - */ - { - VmEventHandle handle; - /** - * Lock global monitor lock - */ - LMAutoUnlock aulock( &jvmtiRawMonitorLock ); - /** - * Create monitor - */ - jvmtiRawMonitor *rawmonitor = new jvmtiRawMonitor; - if( rawmonitor == NULL ) { - return JVMTI_ERROR_OUT_OF_MEMORY; - } - /** - * Create wait event handle - */ - handle = vm_create_event( NULL, TRUE, FALSE, NULL ); - if( handle == 0 ) { - // FIXME - What do we have to do if we cannot create event object? - return JVMTI_ERROR_INTERNAL; - } - rawmonitor->m_wait_event = handle; - /** - * Create notify event handle - */ - handle = vm_create_event( NULL, TRUE, FALSE, NULL ); - if( handle == 0 ) { - // FIXME - What do we have to do if we cannot create event object? - return JVMTI_ERROR_INTERNAL; - } - rawmonitor->m_notify_event = handle; - /** - * Set monitor into raw monitor table and - * set monitor_ptr as index in raw monitor table - */ - g_rawMonitors[g_freeMonitor].m_monitor = rawmonitor; - *monitor_ptr = (jrawMonitorID)((POINTER_SIZE_INT)g_freeMonitor); - /** - * Change raw monitor table free - */ - if( g_rawMonitors[g_freeMonitor].m_nextFree == -1 ) { - // created monitor is the last in raw monitor table - g_freeMonitor++; - } else { - // get next free monitor from raw monitor table entry - g_freeMonitor = g_rawMonitors[g_freeMonitor].m_nextFree; - } - } - - /** - * Monitor trace - */ - TRACE2("jvmti.monitor", "CreateRawMonitor finished, name = " - << name << " id = " << *monitor_ptr); - - return JVMTI_ERROR_NONE; + //FIXME: integration, add name. + return (jvmtiError)jthread_raw_monitor_create(monitor_ptr); } // jvmtiCreateRawMonitor /* @@ -236,64 +72,7 @@ jvmtiDestroyRawMonitor(jvmtiEnv* env, jrawMonitorID monitor) { - unsigned index; - jvmtiRawMonitor *rawmonitor; - - /** - * Monitor trace - */ - TRACE2("jvmti.monitor", "DestroyRawMonitor called, id = " << monitor); - SuspendEnabledChecker sec; - - /** - * Check given env & current phase. - */ - jvmtiPhase phases[] = {JVMTI_PHASE_ONLOAD, JVMTI_PHASE_LIVE}; - - CHECK_EVERYTHING(); - - /** - * Check valid monitor in raw monitor table - */ - if( (index = (unsigned)((POINTER_SIZE_INT)monitor)) >= JVMTI_RAW_MONITOR_TABLE_SIZE - || ( (rawmonitor = g_rawMonitors[index].m_monitor) == NULL ) ) - { - return JVMTI_ERROR_INVALID_MONITOR; - } - - /** - * Lock global raw monitor enter lock - * It cannot allow enter monitor and stop on monitor lock - */ - LMAutoUnlock aulock( &jvmtiRawMonitorLock ); - - /** - * Check monitor owner for thread - */ - if( rawmonitor->m_owner_thread != get_thread_ptr() - && !(rawmonitor->m_owned_count == 0 && rawmonitor->m_enter_count == 0) ) - { - return JVMTI_ERROR_NOT_MONITOR_OWNER; - } - - /** - * Check monitor has only 1 enter, the owner enter - * and monitor owner has no recursion - */ - if( (rawmonitor->m_owned_count == 1 && rawmonitor->m_enter_count == 1) || - (rawmonitor->m_owned_count == 0 && rawmonitor->m_enter_count == 0)) { - // delete monitor from raw monitor raw table - delete rawmonitor; - // null pointer to deleted monitor in the table - g_rawMonitors[index].m_monitor = NULL; - // set free element in table - g_rawMonitors[index].m_nextFree = g_freeMonitor; - // modify next free monitor variable - g_freeMonitor = index; - return JVMTI_ERROR_NONE; - } else { // monitor cannot be destroyed - return JVMTI_ERROR_NOT_MONITOR_OWNER; - } + return (jvmtiError)jthread_raw_monitor_destroy(monitor); } // jvmtiDestroyRawMonitor /* @@ -308,81 +87,7 @@ jvmtiRawMonitorEnter(jvmtiEnv* env, jrawMonitorID monitor) { - unsigned index; - jvmtiRawMonitor *rawmonitor; - - /** - * Monitor trace - */ - TRACE2("jvmti.monitor", "RawMonitorEnter called, id = " << monitor); - SuspendEnabledChecker sec; - - /** - * Check given env & current phase. - */ - jvmtiPhase* phases = NULL; - - CHECK_EVERYTHING(); - - /** - * Check valid monitor - */ - if( (index = (unsigned)((POINTER_SIZE_INT)monitor)) >= JVMTI_RAW_MONITOR_TABLE_SIZE - || ( (rawmonitor = g_rawMonitors[index].m_monitor) == NULL ) ) - { - return JVMTI_ERROR_INVALID_MONITOR; - } - // set monitor pointer - rawmonitor = g_rawMonitors[index].m_monitor; - - /** - * If current thread isn't owner of monitor try to lock monitor - */ - if( rawmonitor->m_owner_thread != get_thread_ptr() ) { - /** - * Increase monitor enter count - * Only 1 thread can execute this block - */ - { - // lock global raw monitor enter lock - jvmtiRawMonitorLock._lock(); - // during lock monitor monitor can be destroyed - if( (rawmonitor = g_rawMonitors[index].m_monitor) == NULL ) { - // monitor was destroyed - return JVMTI_ERROR_INVALID_MONITOR; - } - // increase monitor enter count - rawmonitor->m_enter_count++; - // unlock global raw monitor enter lock - jvmtiRawMonitorLock._unlock(); - } - - /** - * Try to lock monitor - * This is stop point for all thread, only 1 thread can pass it - */ - // set suspend thread flag - assert(tmn_is_suspend_enabled()); - p_TLS_vmthread->is_suspended = true; - tmn_safe_point(); - // all thread stoped at this point trying to lock monitor - rawmonitor->m_owner_lock._lock(); - // only owner of monitor can execute in the following instructions - - // set monitor owner - rawmonitor->m_owner_thread = get_thread_ptr(); - // lock wait lock object - rawmonitor->m_wait_lock._lock(); - // suspend thread if needed - //tmn_suspend_disable(); - //tmn_suspend_enable(); - // remove suspend thread flag - p_TLS_vmthread->is_suspended = false; - } - // increase monitor recursion - rawmonitor->m_owned_count++; - - return JVMTI_ERROR_NONE; + return (jvmtiError)jthread_raw_monitor_enter(monitor); } // jvmtiRawMonitorEnter /* @@ -396,54 +101,7 @@ jvmtiRawMonitorExit(jvmtiEnv* env, jrawMonitorID monitor) { - jvmtiRawMonitor *rawmonitor; - jvmtiError result; - - /** - * Monitor trace - */ - TRACE2("jvmti.monitor", "RawMonitorExit called, id = " << monitor); - SuspendEnabledChecker sec; - - /* - * Check given env & current phase. - */ - jvmtiPhase* phases = NULL; - - CHECK_EVERYTHING(); - - /** - * Check valid monitor - */ - if( ( result = jvmtiCheckValidMonitor( monitor ) ) != JVMTI_ERROR_NONE ) { - return result; - } - // set monitor pointer - rawmonitor = g_rawMonitors[(unsigned)((POINTER_SIZE_INT)monitor)].m_monitor; - - /** - * Only ower of monitor can execute this block - */ - { - // decrease monitor recursion - rawmonitor->m_owned_count--; - - /** - * If there is no monitor recurtion, release monitor - */ - if( !rawmonitor->m_owned_count ) { - // decrease monitor enter count - rawmonitor->m_enter_count--; - // remove monitor owner - rawmonitor->m_owner_thread = NULL; - // unlock wait lock object - rawmonitor->m_wait_lock._unlock(); - // unlock owner lock object - rawmonitor->m_owner_lock._unlock(); - } - } - - return JVMTI_ERROR_NONE; + return (jvmtiError)jthread_raw_monitor_exit(monitor); } // jvmtiRawMonitorExit /* @@ -458,245 +116,11 @@ jrawMonitorID monitor, jlong millis) { - int old_owned_count; - int64 timer; - DWORD stat; - VM_thread *old_owner_thread; - jvmtiRawMonitor *rawmonitor; - jvmtiError result; - - /** - * Monitor trace - */ - TRACE2("jvmti.monitor", "RawMonitorWait called, id = " << monitor << " timeout = " << millis); - SuspendEnabledChecker sec; - - /** - * Check given env & current phase. - */ - jvmtiPhase* phases = NULL; - - CHECK_EVERYTHING(); - - /** - * Check valid monitor - */ - if( ( result = jvmtiCheckValidMonitor( monitor ) ) != JVMTI_ERROR_NONE ) { - return result; - } - // set monitor pointer - rawmonitor = g_rawMonitors[(unsigned)((POINTER_SIZE_INT)monitor)].m_monitor; - - /** - * Set old monitor values to reset monitor before wait state - * Only owner of monitor can execute this block - */ - { - old_owned_count = rawmonitor->m_owned_count; - old_owner_thread = rawmonitor->m_owner_thread; - // reset monitor recursion - rawmonitor->m_owned_count = 0; - // reset monitor ower - rawmonitor->m_owner_thread = 0; - // increase count of waiters - rawmonitor->m_wait_count++; - // disallow leave wait state without notify - rawmonitor->m_leave = false; - // disallow leave wait state without notifyAll - rawmonitor->m_notifyall = false; - // reset wait event - vm_reset_event( rawmonitor->m_wait_event ); - // unlock wait lock object - rawmonitor->m_wait_lock._unlock(); - // unlock monitor lock object - rawmonitor->m_owner_lock._unlock(); - // set thread suspend flag - assert(tmn_is_suspend_enabled()); - p_TLS_vmthread->is_suspended = true; - } - - /** - * Wait state for all threads loop in this block - */ - { - while( true ) { - // get timer - timer = apr_time_now(); - // wait for event -#if defined (__INTEL_COMPILER) -#pragma warning( push ) -#pragma warning (disable:1683) // to get rid of remark #1683: explicit conversion of a 64-bit integral type to a smaller integral type -#endif - stat = vm_wait_for_single_object( rawmonitor->m_wait_event, - millis == 0 ? INFINITE : (DWORD)millis ); - -#if defined (__INTEL_COMPILER) -#pragma warning( pop ) -#endif - // get waiting time - timer = apr_time_now() - timer; - // check for timeout - if( millis != 0 && stat != WAIT_TIMEOUT ) { - millis -= timer/1000; - if( millis <= 0 ) { - // set timeout state - stat = WAIT_TIMEOUT; - millis = 1; - } - } - if( stat == WAIT_FAILED ) { - // wait state was interapted - result = JVMTI_ERROR_INTERRUPT; - } - // check wait object result - if( millis != 0 && stat == WAIT_TIMEOUT ) { - // lock wait lock object - rawmonitor->m_wait_lock._lock(); - break; - } else { - // check monitor notify set - if( rawmonitor->m_leave ) { - // monitor has notify, try to lock wait lock object - if( rawmonitor->m_wait_lock._tryLock() ) { - // wait lock object was locked - // check monitor notifyAll set - if( !rawmonitor->m_notifyall ) { - // notifyAll don't set, remove monitor notify set - rawmonitor->m_leave = false; - } - break; - } - } - } - } - } - - /** - * Only owner of wait lock object can execute this block - */ - { - // decrease count of monitor waiters - rawmonitor->m_wait_count--; - // if wait was interupted - if( stat != WAIT_TIMEOUT ) { - if( rawmonitor->m_notifyall ) { - // wait was interupted by notifyAll call - if( rawmonitor->m_wait_count == 0 ) { - // last waiter sets notify event - vm_set_event( rawmonitor->m_notify_event ); - } - } else { - // wait was interupted by notify - // reset wait event if RawMonitorNotify is called - vm_reset_event( rawmonitor->m_wait_event ); - // waiter sets notify event - vm_set_event( rawmonitor->m_notify_event ); - } - } else { - // if someone waits notify event - if( rawmonitor->m_wait_count == 0 && rawmonitor->m_leave ) { - // last waiter sets notify event - vm_set_event( rawmonitor->m_notify_event ); - } - } - // unlock wait object - rawmonitor->m_wait_lock._unlock(); - } - - /** - * This is stop point for all thread, only 1 thread can pass it - * All thread stoped at this point trying to lock monitor - * Only owner of monitor can execute this block - */ - { - // suspend thread if needed - p_TLS_vmthread->is_suspended = true; - tmn_safe_point(); - // lock owner lock object - rawmonitor->m_owner_lock._lock(); - // lock wait lock object - rawmonitor->m_wait_lock._lock(); - // restore monitor threa owner - rawmonitor->m_owner_thread = old_owner_thread; - // restore value of monitor recurtion - rawmonitor->m_owned_count = old_owned_count; - // remove suspend thread flag - p_TLS_vmthread->is_suspended = false; - } - - return result; + return (jvmtiError)jthread_raw_monitor_wait(monitor, millis); } // jvmtiRawMonitorWait -/* - * Internal Raw Monitor Notify - */ -static inline jvmtiError -InternalRawMonitorNotify(jvmtiEnv* env, - jrawMonitorID monitor, - bool notifyAll) -{ - jvmtiRawMonitor *rawmonitor; - jvmtiError result; - /* - * Check given env & current phase. - */ - jvmtiPhase phases[] = {JVMTI_PHASE_ONLOAD, JVMTI_PHASE_LIVE}; - CHECK_EVERYTHING(); - - /** - * Check valid monitor - */ - if( ( result = jvmtiCheckValidMonitor( monitor ) ) != JVMTI_ERROR_NONE ) { - return result; - } - // set monitor pointer - rawmonitor = g_rawMonitors[(unsigned)((POINTER_SIZE_INT)monitor)].m_monitor; - - /** - * Only owner of monitor can execute following block - */ - { - // set notifyAll for waiters to allow waters to leave wait state - rawmonitor->m_notifyall = notifyAll; - // set notify for waiters to allow a waiter to leave wait state - rawmonitor->m_leave = true; - // reset notify event - vm_reset_event( rawmonitor->m_notify_event ); - // signal event - vm_set_event( rawmonitor->m_wait_event ); - // unlock wait lock object - rawmonitor->m_wait_lock._unlock(); - - /** - * Wait until a waiter leaves wait state - * It decrease number of waiter by 1 - * after which will stop on monitor lock - */ - if( rawmonitor->m_wait_count ) { - // set suspend thread flag - assert(tmn_is_suspend_enabled()); - p_TLS_vmthread -> is_suspended = true; - // wait notify event - vm_wait_for_single_object( rawmonitor->m_notify_event, INFINITE ); - // suspend thread if needed - tmn_suspend_disable(); - tmn_suspend_enable(); - // remove suspend thread flag - p_TLS_vmthread->is_suspended = false; - } - - // lock wait lock object back - rawmonitor->m_wait_lock._lock(); - // reset notify event - vm_reset_event( rawmonitor->m_notify_event ); - } - - return JVMTI_ERROR_NONE; -} // InternalRawMonitorNotify - - /* * Raw Monitor Notify * @@ -712,16 +136,7 @@ * Monitor trace */ TRACE2("jvmti.monitor", "RawMonitorNotify called, id = " << monitor); - SuspendEnabledChecker sec; - - /** - * Check given env & current phase. - */ - jvmtiPhase phases[] = {JVMTI_PHASE_ONLOAD, JVMTI_PHASE_LIVE}; - - CHECK_EVERYTHING(); - - return InternalRawMonitorNotify( env, monitor, false ); + return (jvmtiError)jthread_raw_monitor_notify(monitor); } // jvmtiRawMonitorNotify /* @@ -739,14 +154,6 @@ * Monitor trace */ TRACE2("jvmti.monitor", "RawMonitorNotifyAll called, id = " << monitor); - SuspendEnabledChecker sec; - - /** - * Check given env & current phase. - */ - jvmtiPhase phases[] = {JVMTI_PHASE_ONLOAD, JVMTI_PHASE_LIVE}; - - CHECK_EVERYTHING(); - - return InternalRawMonitorNotify( env, monitor, true ); + return (jvmtiError)jthread_raw_monitor_notify_all(monitor); } // jvmtiRawMonitorNotifyAll + Index: vm/vmcore/src/jvmti/jvmti_class.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_class.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_class.cpp (working copy) @@ -33,7 +33,7 @@ #include "vm_strings.h" #include "environment.h" #include "classloader.h" -#include "open/thread.h" + #include "suspend_checker.h" /* @@ -54,7 +54,7 @@ static inline Class* get_class_from_handle(jvmtiEnv* UNREF env, jvmtiPhase UNREF phase_mask, jclass handle, void* p1, void *p2, jvmtiError* errorCode) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (NULL == handle || p1 == NULL || p2 == NULL) { Index: vm/vmcore/src/jvmti/jvmti_stack.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_stack.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_stack.cpp (working copy) @@ -29,7 +29,7 @@ #include "Class.h" #include "cxxlog.h" #include "thread_generic.h" -#include "open/thread.h" +#include "open/jthread.h" #include "suspend_checker.h" #include "stack_trace.h" #include "stack_iterator.h" @@ -41,7 +41,7 @@ jthread getCurrentThread() { tmn_suspend_disable(); ObjectHandle hThread = oh_allocate_local_handle(); - hThread->object = (Java_java_lang_Thread *)p_TLS_vmthread->p_java_lang_thread; + hThread->object = (Java_java_lang_Thread *)jthread_get_java_thread(hythread_self())->object; tmn_suspend_enable(); return (jthread) hThread; } @@ -69,10 +69,10 @@ Class *clss = method_get_class(method); assert(clss); - if (strcmp(method_get_name(method), "run") == 0 && + if (strcmp(method_get_name(method), "runImpl") == 0 && strcmp(class_get_name(clss), "java/lang/VMStart$MainThread") == 0) { - skip = 3; + skip = 4; } } @@ -153,7 +153,7 @@ // Check that this thread is not current if (vm_thread != p_TLS_vmthread) { - thread_suspend(thread); + jthread_suspend(thread); thread_suspended = true; } } @@ -176,7 +176,7 @@ if (start < 0) { if (thread_suspended) - thread_resume(thread); + jthread_resume(thread); return JVMTI_ERROR_ILLEGAL_ARGUMENT; } } @@ -264,7 +264,7 @@ } if (thread_suspended) - thread_resume(thread); + jthread_resume(thread); return errStack; } @@ -311,12 +311,12 @@ // FIXME: new threads can be created before all threads are suspended // event handler for thread_creating should block creation new threads // at this moment - assert(tmn_is_suspend_enabled()); - tm_acquire_tm_lock(); + assert(hythread_is_suspend_enabled()); + hythread_global_lock(); res = jvmtiGetAllThreads(env, &count, &threads); if (res != JVMTI_ERROR_NONE) { - tm_release_tm_lock(); + hythread_global_unlock(); return res; } @@ -345,7 +345,7 @@ if (info[i].state != JVMTI_THREAD_STATE_SUSPENDED) { if (IsSameObject(jvmti_test_jenv, currentThread, threads[i])) continue; - thread_suspend(threads[i]); + jthread_suspend(threads[i]); } } @@ -365,10 +365,10 @@ // unsuspend suspended threads. for(i = 0; i < count; i++) { if (info[i].state != JVMTI_THREAD_STATE_SUSPENDED) - thread_resume(threads[i]); + jthread_resume(threads[i]); } - tm_release_tm_lock(); + hythread_global_unlock(); * thread_count_ptr = count; *stack_info_ptr = info; return JVMTI_ERROR_NONE; @@ -439,7 +439,7 @@ if (info[i].state != JVMTI_THREAD_STATE_SUSPENDED) { if (IsSameObject(jvmti_test_jenv, currentThread, threads[i])) continue; - thread_suspend(threads[i]); + jthread_suspend(threads[i]); } } @@ -459,7 +459,7 @@ // unsuspend suspended threads. for(i = 0; i < count; i++) { if (info[i].state != JVMTI_THREAD_STATE_SUSPENDED) - thread_resume(threads[i]); + jthread_resume(threads[i]); } *stack_info_ptr = info; @@ -521,7 +521,7 @@ // Check that this thread is not current if (vm_thread != p_TLS_vmthread) { - thread_suspend(thread); + jthread_suspend(thread); thread_suspended = true; } } @@ -540,7 +540,7 @@ } if (thread_suspended) - thread_resume(thread); + jthread_resume(thread); return errStack; } @@ -668,7 +668,7 @@ // Check that this thread is not current if (vm_thread != p_TLS_vmthread) { - thread_suspend(thread); + jthread_suspend(thread); thread_suspended = true; } } @@ -760,7 +760,7 @@ } if (thread_suspended) - thread_resume(thread); + jthread_resume(thread); return errStack; } Index: vm/vmcore/src/jvmti/jvmti_object.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_object.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_object.cpp (working copy) @@ -27,7 +27,7 @@ #include "object_handles.h" #include "object_generic.h" #include "mon_enter_exit.h" -#include "open/thread.h" + #include "thread_manager.h" #include "suspend_checker.h" #include "open/vm.h" @@ -144,6 +144,7 @@ /* * Check given env & current phase. */ + jvmtiPhase phases[] = {JVMTI_PHASE_LIVE}; CHECK_EVERYTHING(); CHECK_CAPABILITY(can_get_monitor_info); @@ -153,63 +154,67 @@ if (NULL == info_ptr) return JVMTI_ERROR_NULL_POINTER; - ManagedObject * obj; int enter_wait_count = 0; int notify_wait_count = 0; - tm_iterator_t * iterator = tm_iterator_create(); - VM_thread *thread = tm_iterator_next(iterator); + jthread_iterator_t iterator = jthread_iterator_create(); + jthread thread = jthread_iterator_next(&iterator); + jobject monitor = NULL; assert(thread); while (thread) { - obj = mon_enter_array[thread->thread_index].p_obj; - if (obj == object->object) + jthread_get_contended_monitor(thread, &monitor); + if (monitor && monitor->object == object->object) enter_wait_count++; - obj = mon_wait_array[thread->thread_index].p_obj; - if (obj == object->object) + jthread_get_wait_monitor(thread, &monitor); + if (monitor && monitor->object == object->object) notify_wait_count++; - thread = tm_iterator_next(iterator); + + thread = jthread_iterator_next(&iterator); } jthread* enter_wait_array = NULL; - jvmtiError jvmti_error = _allocate(sizeof(jthread*) * - enter_wait_count, (unsigned char **)&enter_wait_array); - if (JVMTI_ERROR_NONE != jvmti_error) - { - tm_iterator_release(iterator); - return jvmti_error; - } + if (enter_wait_count > 0){ + jvmtiError jvmti_error = _allocate(sizeof(jthread*) * + enter_wait_count, (unsigned char **)&enter_wait_array); + if (JVMTI_ERROR_NONE != jvmti_error) + { + jthread_iterator_release(&iterator); + return jvmti_error; + } + } jthread* notify_wait_array = NULL; - jvmti_error = _allocate(sizeof(jthread*) * - notify_wait_count, (unsigned char **)¬ify_wait_array); - if (JVMTI_ERROR_NONE != jvmti_error) - { - tm_iterator_release(iterator); - return jvmti_error; - } + if (notify_wait_count > 0){ + jvmtiError jvmti_error = _allocate(sizeof(jthread*) * + notify_wait_count, (unsigned char **)¬ify_wait_array); + if (JVMTI_ERROR_NONE != jvmti_error) + { + jthread_iterator_release(&iterator); + return jvmti_error; + } + } - extern jobject get_jobject(VM_thread * thread); int ii = 0, jj = 0; - int stack_key = STACK_KEY(object->object); info_ptr->owner = NULL; - tm_iterator_reset(iterator); - thread = tm_iterator_next(iterator); + jthread_iterator_reset(&iterator); + thread = jthread_iterator_next(&iterator); while (thread) { - if (stack_key == thread->thread_index) - info_ptr->owner = get_jobject(thread); - obj = mon_enter_array[thread->thread_index].p_obj; - if (obj == object->object) - enter_wait_array[ii++] = get_jobject(thread); - obj = mon_wait_array[thread->thread_index].p_obj; - if (obj == object->object) - notify_wait_array[jj++] = get_jobject(thread); - thread = tm_iterator_next(iterator); + jthread_get_contended_monitor(thread, &monitor); + if (monitor && monitor->object == object->object) + enter_wait_array[ii++] = thread; + + jthread_get_wait_monitor(thread, &monitor); + if (monitor && monitor->object == object->object) + notify_wait_array[jj++] = thread; + + thread = jthread_iterator_next(&iterator); } - tm_iterator_release(iterator); + jthread_iterator_release(&iterator); - info_ptr->entry_count = RECURSION(object->object) + (info_ptr->owner != NULL); + jthread_get_lock_owner(object, &info_ptr->owner); + info_ptr->entry_count = jthread_get_lock_recursion(object, info_ptr->owner) + 1; info_ptr->waiter_count = enter_wait_count; info_ptr->waiters = enter_wait_array; info_ptr->notify_waiter_count = notify_wait_count; Index: vm/vmcore/src/jvmti/jvmti_thread.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_thread.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_thread.cpp (working copy) @@ -27,28 +27,27 @@ #include "jvmti_utils.h" #include "vm_threads.h" #include "thread_generic.h" -#include "open/thread.h" + +#include "open/ti_thread.h" +#include "open/jthread.h" #include "thread_manager.h" #include "object_handles.h" #include "open/vm_util.h" #include "platform_lowlevel.h" #include "mon_enter_exit.h" -#include "mon_enter_exit.h" #include "interpreter_exports.h" #include "environment.h" #include "suspend_checker.h" + #define MAX_JVMTI_ENV_NUMBER 10 -// jvmti_local_storage_static is used to store local storage for thread == NULL -static JVMTILocalStorage jvmti_local_storage_static[MAX_JVMTI_ENV_NUMBER]; static JNIEnv * jvmti_test_jenv = jni_native_intf; -extern VM_thread * get_vm_thread_ptr_safe(JNIEnv * env, jobject thread); -jobject get_jobject(VM_thread * thread); Boolean is_valid_thread_object(jthread thread) { - if (NULL == thread) + if (NULL == thread){ return false; + } tmn_suspend_disable(); //---------------------------------v ObjectHandle h = (ObjectHandle)thread; @@ -56,15 +55,13 @@ // Check that reference pointer points to the heap if (mo < (ManagedObject *)Class::heap_base || - mo > (ManagedObject *)Class::heap_end) - { + mo > (ManagedObject *)Class::heap_end){ tmn_suspend_enable(); return false; } // Check that object is an instance of java.lang.Thread or extends it - if (mo->vt() == NULL) - { + if (mo->vt() == NULL){ tmn_suspend_enable(); return false; } @@ -104,22 +101,14 @@ return JVMTI_ERROR_INVALID_THREAD; } else - thread = thread_current_thread(); + thread = jthread_self(); - if (thread_state_ptr == NULL) - { + if (thread_state_ptr == NULL){ return JVMTI_ERROR_NULL_POINTER; } + IDATA UNUSED status = jthread_get_state(thread, thread_state_ptr); + assert(status == TM_ERROR_NONE); - int state = thread_get_thread_state(thread); - - if (state == -1) - { - return JVMTI_ERROR_THREAD_NOT_ALIVE; // non-existant thread - } - - * thread_state_ptr = state; - return JVMTI_ERROR_NONE; } @@ -140,6 +129,10 @@ jint* threads_count_ptr, jthread** threads_ptr) { + jthread_iterator_t iterator; + int i,java_thread_count; + jthread* java_threads; + jvmtiError err; TRACE2("jvmti.thread", "GetAllThreads called"); SuspendEnabledChecker sec; /* @@ -149,13 +142,25 @@ CHECK_EVERYTHING(); - if (threads_count_ptr == NULL || threads_ptr == NULL) - { + if (threads_count_ptr == NULL || threads_ptr == NULL){ return JVMTI_ERROR_NULL_POINTER; } - *threads_count_ptr = thread_get_all_threads(threads_ptr); + //jthread_get_all_threads(threads_ptr, threads_count_ptr); + iterator=jthread_iterator_create(); + java_thread_count = jthread_iterator_size(iterator); + //allocate memory + err=jvmtiAllocate(env,java_thread_count*sizeof(jthread),(unsigned char**)&java_threads); + if (err != JVMTI_ERROR_NONE){ + return err; + } + for (i=0;i GetCapabilities(&capa); - if (err != JVMTI_ERROR_NONE) - { + if (err != JVMTI_ERROR_NONE){ return err; } - if (capa.can_suspend == 0) - { + if (capa.can_suspend == 0){ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; } @@ -201,24 +204,25 @@ return JVMTI_ERROR_INVALID_THREAD; } else - thread = thread_current_thread(); + thread = jthread_self(); jint state; err = jvmtiGetThreadState(env, thread, &state); - if (err != JVMTI_ERROR_NONE) + if (err != JVMTI_ERROR_NONE){ return err; + } // check error condition: JVMTI_ERROR_THREAD_NOT_ALIVE if ((state & JVMTI_THREAD_STATE_ALIVE) == 0) return JVMTI_ERROR_THREAD_NOT_ALIVE; - if ((state & JVMTI_THREAD_STATE_SUSPENDED) != 0) + if (state & JVMTI_THREAD_STATE_SUSPENDED) return JVMTI_ERROR_THREAD_SUSPENDED; - thread_suspend(thread); - return JVMTI_ERROR_NONE; + + return (jvmtiError)jthread_suspend(thread); } /* @@ -254,27 +258,20 @@ jvmtiError err = env -> GetCapabilities(&capa); - if (err != JVMTI_ERROR_NONE) - { + if (err != JVMTI_ERROR_NONE){ return err; } - if (capa.can_suspend == 0) - { + if (capa.can_suspend == 0){ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; } - - if (request_count < 0) - { + if (request_count < 0){ return JVMTI_ERROR_ILLEGAL_ARGUMENT; } - - if (request_list == NULL || results == NULL) - { + if (request_list == NULL || results == NULL){ return JVMTI_ERROR_NULL_POINTER; } - for (int i = 0; i < request_count; i++) - { + for (int i = 0; i < request_count; i++){ results[i] = jvmtiSuspendThread(env, request_list[i]); } @@ -308,17 +305,16 @@ jvmtiError err = jvmtiGetCapabilities(env, &capa); - if (err != JVMTI_ERROR_NONE) - { + if (err != JVMTI_ERROR_NONE){ return err; } - if (capa.can_suspend == 0) - { + if (capa.can_suspend == 0){ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; } - - if (false) - { // TBD + if (!is_valid_thread_object(thread)){ + return JVMTI_ERROR_INVALID_THREAD; + } + if (false){ // TBD return JVMTI_ERROR_INVALID_TYPESTATE; } @@ -326,20 +322,19 @@ return JVMTI_ERROR_INVALID_THREAD; jint state; - // check error condition: JVMTI_ERROR_INVALID_THREAD + err = jvmtiGetThreadState(env, thread, &state); if (err != JVMTI_ERROR_NONE) return err; - // check error condition: JVMTI_ERROR_THREAD_NOT_ALIVE if ((state & JVMTI_THREAD_STATE_ALIVE) == 0) return JVMTI_ERROR_THREAD_NOT_ALIVE; if ((state & JVMTI_THREAD_STATE_SUSPENDED) == 0) return JVMTI_ERROR_THREAD_NOT_SUSPENDED; - thread_resume(thread); + jthread_resume(thread); return JVMTI_ERROR_NONE; } @@ -373,27 +368,20 @@ jvmtiError err = env -> GetCapabilities(&capa); - if (err != JVMTI_ERROR_NONE) - { + if (err != JVMTI_ERROR_NONE){ return err; } - if (capa.can_suspend == 0) - { + if (capa.can_suspend == 0){ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; } - - if (request_count < 0) - { + if (request_count < 0){ return JVMTI_ERROR_ILLEGAL_ARGUMENT; } - - if (request_list == NULL || results == NULL) - { + if (request_list == NULL || results == NULL){ return JVMTI_ERROR_NULL_POINTER; } - for (int i = 0; i < request_count; i++) - { + for (int i = 0; i < request_count; i++){ results[i] = jvmtiResumeThread(env, request_list[i]); } @@ -413,7 +401,7 @@ jvmtiError JNICALL jvmtiStopThread(jvmtiEnv* env, jthread thread, - jobject UNREF exception) + jobject exception) { TRACE2("jvmti.thread", "StopThread called"); SuspendEnabledChecker sec; @@ -428,19 +416,17 @@ jvmtiError err = env -> GetCapabilities(&capa); - if (err != JVMTI_ERROR_NONE) - { + if (err != JVMTI_ERROR_NONE){ return err; } - if (capa.can_signal_thread == 0) - { + if (capa.can_signal_thread == 0){ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; } - - if (!is_valid_thread_object(thread)) + if (!is_valid_thread_object(thread)){ return JVMTI_ERROR_INVALID_THREAD; + } - thread_stop(thread, NULL); + jthread_exception_stop(thread, exception); return JVMTI_NYI; } @@ -470,28 +456,17 @@ jvmtiError err = env -> GetCapabilities(&capa); - if (err != JVMTI_ERROR_NONE) - { + if (err != JVMTI_ERROR_NONE){ return err; } - if (capa.can_signal_thread == 0) - { + if (capa.can_signal_thread == 0){ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; } - - if (!is_valid_thread_object(thread)) + if (!is_valid_thread_object(thread)){ return JVMTI_ERROR_INVALID_THREAD; - - VM_thread * vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); - - if (!vm_thread) - { - return JVMTI_ERROR_THREAD_NOT_ALIVE; // non-existant thread } - thread_interrupt(thread); - - return JVMTI_ERROR_NONE; + return (jvmtiError)jthread_interrupt(thread); } /* @@ -525,7 +500,7 @@ return JVMTI_ERROR_INVALID_THREAD; } else - thread = thread_current_thread(); + thread = jthread_self(); jclass cl = GetObjectClass(jvmti_test_jenv, thread); jmethodID id = jvmti_test_jenv -> GetMethodID(cl, "getName","()Ljava/lang/String;"); @@ -573,42 +548,36 @@ jvmtiError err = env -> GetCapabilities(&capa); - if (err != JVMTI_ERROR_NONE) - { + if (err != JVMTI_ERROR_NONE){ return err; } - if (capa.can_get_owned_monitor_info == 0) - { + if (capa.can_get_owned_monitor_info == 0){ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; } - if (NULL != thread) { if (!is_valid_thread_object(thread)) return JVMTI_ERROR_INVALID_THREAD; } else - thread = thread_current_thread(); - - VM_thread * vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); - - if (!vm_thread) - { - return JVMTI_ERROR_THREAD_NOT_ALIVE; // non-existant thread - } - - if (owned_monitor_count_ptr == NULL || owned_monitors_ptr == NULL) - { + thread = jthread_self(); + if (owned_monitor_count_ptr == NULL || owned_monitors_ptr == NULL){ return JVMTI_ERROR_NULL_POINTER; } - int count = thread_get_owned_monitor_info(thread, owned_monitors_ptr); + jint state; - if (count == -1){ - return JVMTI_ERROR_NULL_POINTER; + err = jvmtiGetThreadState(env, thread, &state); + + if (err != JVMTI_ERROR_NONE){ + return err; } + if ((state & JVMTI_THREAD_STATE_ALIVE) == 0){ + return JVMTI_ERROR_THREAD_NOT_ALIVE; + } - *owned_monitor_count_ptr = count; + IDATA UNUSED status = jthread_get_owned_monitors(thread, owned_monitor_count_ptr, owned_monitors_ptr); + assert(status == TM_ERROR_NONE); return JVMTI_ERROR_NONE; } @@ -639,37 +608,32 @@ jvmtiError err = env -> GetCapabilities(&capa); - if (err != JVMTI_ERROR_NONE) - { + if (err != JVMTI_ERROR_NONE){ return err; } - if (capa.can_get_current_contended_monitor == 0) - { + if (capa.can_get_current_contended_monitor == 0){ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; } - - if (monitor_ptr == NULL) - { + if (monitor_ptr == NULL){ return JVMTI_ERROR_NULL_POINTER; } - if (NULL == thread) - thread = thread_current_thread(); + thread = jthread_self(); jint state; - // check error condition: JVMTI_ERROR_INVALID_THREAD + err = jvmtiGetThreadState(env, thread, &state); - if (err != JVMTI_ERROR_NONE) + if (err != JVMTI_ERROR_NONE){ return err; - - // check error condition: JVMTI_ERROR_THREAD_NOT_ALIVE - if ((state & JVMTI_THREAD_STATE_ALIVE) == 0) + } + if ((state & JVMTI_THREAD_STATE_ALIVE) == 0){ return JVMTI_ERROR_THREAD_NOT_ALIVE; + } - *monitor_ptr = thread_contends_for_lock(thread); + IDATA status = jthread_get_contended_monitor(thread, monitor_ptr); - return JVMTI_ERROR_NONE; + return (jvmtiError)status; } /* @@ -696,16 +660,13 @@ CHECK_EVERYTHING(); - if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) - { + if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY){ return JVMTI_ERROR_INVALID_PRIORITY; } - - if (!is_valid_thread_object(thread)) + if (!is_valid_thread_object(thread)){ return JVMTI_ERROR_INVALID_THREAD; - - if (proc == NULL) - { + } + if (proc == NULL){ return JVMTI_ERROR_NULL_POINTER; } @@ -716,7 +677,14 @@ assert(set_daemon); CallVoidMethod(jvmti_test_jenv, thread, set_daemon, JNI_TRUE); // Run new thread - Java_java_lang_Thread_start_generic(jvmti_test_jenv, thread, env, proc, arg, priority); + // FIXME TM integration, pass arguments correctly + //Java_java_lang_Thread_start_generic(jvmti_test_jenv, thread, env, proc, arg, priority); + jthread_threadattr_t attrs; + attrs.priority = priority; + attrs.stacksize = 0; + attrs.daemon = JNI_TRUE; + attrs.jvmti_env = env; + jthread_create_with_function(jvmti_test_jenv, thread, &attrs, proc, arg); return JVMTI_ERROR_NONE; } @@ -749,33 +717,38 @@ if (NULL != thread) { - if (!is_valid_thread_object(thread)) + if (!is_valid_thread_object(thread)){ return JVMTI_ERROR_INVALID_THREAD; } + } else - thread = thread_current_thread(); + thread = jthread_self(); - VM_thread* vm_thread = thread != NULL ? - get_vm_thread_ptr_safe(jvmti_test_jenv, thread) : p_TLS_vmthread; + jint state; - if (!vm_thread) - { - return JVMTI_ERROR_THREAD_NOT_ALIVE; // non-existant thread + jvmtiError err = jvmtiGetThreadState(env, thread, &state); + + if (err != JVMTI_ERROR_NONE){ + return err; } + if ((state & JVMTI_THREAD_STATE_ALIVE) == 0){ + return JVMTI_ERROR_THREAD_NOT_ALIVE; + } + JVMTILocalStorage* aa = NULL; - JVMTILocalStorage* lstg = &vm_thread -> jvmti_local_storage; + JVMTILocalStorage* lstg = jthread_get_jvmti_local_storage(thread); if (lstg -> env == NULL) { if (lstg -> data == NULL) { // we have no records stored; // so, we put our first record into vm_thread -> jvmti_local_storage - vm_thread -> jvmti_local_storage.env = (data == NULL) ? NULL : env; - vm_thread -> jvmti_local_storage.data = (void *)data; + lstg -> env = (data == NULL) ? NULL : env; + lstg -> data = (void *)data; return JVMTI_ERROR_NONE; } else { // we have more than one record stored; // so, they are stored in array which is pointed at by // vm_thread -> jvmti_local_storage -> data - aa = (JVMTILocalStorage*)vm_thread -> jvmti_local_storage.data; + aa = (JVMTILocalStorage*)lstg -> data; } } else { // we have just one record stored; @@ -793,21 +766,25 @@ aa[0].env = NULL; aa[0].data = NULL; } - aa[0].env = vm_thread -> jvmti_local_storage.env; - aa[0].data = vm_thread -> jvmti_local_storage.data; - vm_thread -> jvmti_local_storage.env = NULL; - vm_thread -> jvmti_local_storage.data = (void *) aa; + aa[0].env = lstg -> env; + aa[0].data = lstg -> data; + lstg -> env = NULL; + lstg -> data = (void *)aa; } } // array look up for existing env or for free record + int ii = -1; for (int i = 0; i < MAX_JVMTI_ENV_NUMBER; i++){ - if (aa[i].env == env || aa[i].env == NULL ) { - aa[i].env = (data == NULL) ? NULL : env; - aa[i].data = (void *)data; - return JVMTI_ERROR_NONE; + if (aa[i].env == env){ + ii = i; + break; + } else if (aa[i].env == NULL && ii < 0){ + ii = i; } } - ASSERT(0, "Array is full"); + assert(ii > -1); // ii == -1 => array is full + aa[ii].env = (data == NULL) ? NULL : env; + aa[ii].data = (void *)data; return JVMTI_ERROR_NONE; } @@ -834,329 +811,35 @@ CHECK_EVERYTHING(); - if (data_ptr == NULL) + if (data_ptr == NULL){ return JVMTI_ERROR_NULL_POINTER; + } if (NULL != thread) { - if (!is_valid_thread_object(thread)) + if (!is_valid_thread_object(thread)){ return JVMTI_ERROR_INVALID_THREAD; } + } else - thread = thread_current_thread(); + thread = jthread_self(); - *data_ptr = NULL; + jint state; + jvmtiError err = jvmtiGetThreadState(env, thread, &state); - VM_thread* vm_thread = thread != NULL ? - get_vm_thread_ptr_safe(jvmti_test_jenv, thread) : p_TLS_vmthread; - - if (!vm_thread) - return JVMTI_ERROR_THREAD_NOT_ALIVE; // non-existant thread - - JVMTILocalStorage* lstg = &vm_thread -> jvmti_local_storage; - if (lstg -> env == NULL) { - if (lstg -> data != NULL) { - // we have more than one record stored; - // so, they are stored in array which is pointed at by - // vm_thread -> jvmti_local_storage -> data - JVMTILocalStorage* aa = (JVMTILocalStorage* )lstg -> data; - for (int i = 0; i < MAX_JVMTI_ENV_NUMBER; i++){ - if (aa[i].env == env) { - *data_ptr = aa[i].data; - break; - } - } - } - } else { - // we have just one record stored; - // so, it's stored in vm_thread -> jvmti_local_storage - if (lstg -> env == env) { - *data_ptr = lstg -> data; - } + if (err != JVMTI_ERROR_NONE){ + return err; } - - return JVMTI_ERROR_NONE; + if ((state & JVMTI_THREAD_STATE_ALIVE) == 0){ + return JVMTI_ERROR_THREAD_NOT_ALIVE; } -/* - * ------------------------------------------------------------------------------- - * ------------------------------------------------------------------------------- - */ - -jobject get_jobject(VM_thread * thread) { - ObjectHandle hThread = oh_allocate_global_handle(); - tmn_suspend_disable(); - hThread->object = (struct ManagedObject *)thread->p_java_lang_thread; - tmn_suspend_enable(); - return (jthread)hThread; -} - -int thread_get_thread_state(jthread thread) { - - VM_thread * vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); - - if ( !vm_thread) - { - jclass cl = GetObjectClass(jvmti_test_jenv, thread); - jfieldID id = jvmti_test_jenv -> GetFieldID(cl, "started", "Z"); - jboolean started = jvmti_test_jenv -> GetBooleanField(thread, id); - return started ? JVMTI_THREAD_STATE_TERMINATED : 0; // 0 - New thread - } - return vm_thread -> get_jvmti_thread_state(thread); -} - -jint VM_thread::get_jvmti_thread_state(jthread thread){ - - // see: thread_is_alive(jobject jThreadObj) - jint jvmti_thread_state = 0; - if ( app_status == zip) { - return JVMTI_ERROR_THREAD_NOT_ALIVE; // non-existant thread - } - java_state as = this->app_status; - switch (as) { - case thread_is_sleeping: - jvmti_thread_state |= JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_SLEEPING | - JVMTI_THREAD_STATE_WAITING; - break; - case thread_is_waiting: - jvmti_thread_state |= JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | - JVMTI_THREAD_STATE_IN_OBJECT_WAIT | - JVMTI_THREAD_STATE_WAITING_INDEFINITELY; - break; - case thread_is_timed_waiting: - jvmti_thread_state |= JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_WAITING | - JVMTI_THREAD_STATE_IN_OBJECT_WAIT | - JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT; - break; - case thread_is_blocked: - jvmti_thread_state |= JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; - break; - case thread_is_birthing: - case thread_is_running: - jvmti_thread_state |= JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE; - break; - case thread_is_dying: - jvmti_thread_state |= JVMTI_THREAD_STATE_TERMINATED; - break; - default: - ABORT("Unexpected thread state"); - break; - } - // end see - jvmti_thread_state |= this -> jvmti_thread_state & JVMTI_THREAD_STATE_WAITING_INDEFINITELY; - jvmti_thread_state |= this -> jvmti_thread_state & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT; - jvmti_thread_state |= this -> jvmti_thread_state & JVMTI_THREAD_STATE_SUSPENDED; - if (thread_is_alive(thread)){ - jvmti_thread_state |= JVMTI_THREAD_STATE_ALIVE; - } - if (thread_is_interrupted(thread, JNI_FALSE)){ - jvmti_thread_state |= JVMTI_THREAD_STATE_INTERRUPTED; - } - unsigned nnn = interpreter.interpreter_st_get_interrupted_method_native_bit(this); - if (nnn) { - jvmti_thread_state |= JVMTI_THREAD_STATE_IN_NATIVE; - } - return jvmti_thread_state; -} - -int thread_get_all_threads(jthread** threads_ptr){ - - jthread * all_jthreads = NULL; - int num_active_threads = 0; - - tm_iterator_t * iterator = tm_iterator_create(); - VM_thread *thread = tm_iterator_next(iterator); - assert(thread); - while (thread) - { - num_active_threads++; - thread = tm_iterator_next(iterator); - } - - jvmtiError jvmti_error = _allocate(sizeof(jthread*) * - num_active_threads, (unsigned char **)&all_jthreads); - - if (JVMTI_ERROR_NONE != jvmti_error) - { - tm_iterator_release(iterator); - return jvmti_error; - } - - int ii = 0; - - tm_iterator_reset(iterator); - thread = tm_iterator_next(iterator); - while (thread) - { - all_jthreads[ii] = get_jobject(thread); - ii++; - thread = tm_iterator_next(iterator); - } - tm_iterator_release(iterator); - - *threads_ptr = all_jthreads; - return num_active_threads; -} - -jobject thread_contends_for_lock(jthread thread) -{ - SuspendEnabledChecker sec; - VM_thread *vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); - - assert(vm_thread); - - tmn_suspend_disable(); - ManagedObject *p_obj = mon_enter_array[vm_thread->thread_index].p_obj; - if (NULL == p_obj) - { - tmn_suspend_enable(); - return NULL; - } - - ObjectHandle oh = oh_allocate_local_handle(); - oh->object = p_obj; - tmn_suspend_enable(); - - return (jobject)oh; -} - -int thread_get_owned_monitor_info(jthread thread, jobject ** owned_monitors_ptr) { - - VM_thread * vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); - - //assert(vm_thread); - if (!vm_thread) - { - return -1; // non-existant thread - } - - jint count = vm_thread -> jvmti_owned_monitor_count; - jobject* pp = NULL; - jvmtiError jvmti_error = _allocate(sizeof(jobject*) * count, (unsigned char **)&pp); - - if (jvmti_error != JVMTI_ERROR_NONE) - { - return -1; - } - - int i; - for(i = 0; i < count; i++) - { - pp[i] = vm_thread -> jvmti_owned_monitors[i]; - } - *owned_monitors_ptr = pp; - return count; -} - - -void thread_stop(jthread thread, jobject UNREF threadDeathException) { - - VM_thread * vm_thread = get_vm_thread_ptr_safe(jni_native_intf, thread); - - vm_thread -> is_stoped = true; -} - - -int thread_set_jvmt_thread_local_storage(jvmtiEnv* env, - jthread thread, - const void* data) -{ - if (thread == NULL) - { - for (int i = 0; i < MAX_JVMTI_ENV_NUMBER; i++){ - if (jvmti_local_storage_static[i].env == env || - jvmti_local_storage_static[i].env == NULL ) { - - jvmti_local_storage_static[i].env = (data == NULL) ? NULL : env; - jvmti_local_storage_static[i].data = (void *)data; - return 0; - } - } - ABORT("Can't find appropriate local storage for the thread"); - return -1; - } - - VM_thread* vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); - - if (!vm_thread) - { - return -1; // non-existant thread - } - JVMTILocalStorage* aa = NULL; - JVMTILocalStorage* lstg = &vm_thread -> jvmti_local_storage; - if (lstg -> env == NULL) { - if (lstg -> data == NULL) { - // we have no records stored; - // so, we put our first record into vm_thread -> jvmti_local_storage - vm_thread -> jvmti_local_storage.env = (data == NULL) ? NULL : env; - vm_thread -> jvmti_local_storage.data = (void *)data; - return JVMTI_ERROR_NONE; - } else { - // we have more than one record stored; - // so, they are stored in array which is pointed at by - // vm_thread -> jvmti_local_storage -> data - aa = (JVMTILocalStorage*)vm_thread -> jvmti_local_storage.data; - } - } else { - // we have just one record stored; - // so, it's stored in vm_thread -> jvmti_local_storage - if (lstg -> env == env) { - // override data in this record - lstg -> data = (void *)data; - return 0; - } else if (data != NULL){ - // we have just one record stored and we have to add another one; - // so, array is created and record is copied there - aa = (JVMTILocalStorage*)STD_MALLOC(sizeof(JVMTILocalStorage)* - MAX_JVMTI_ENV_NUMBER); - for (int i = 0; i < MAX_JVMTI_ENV_NUMBER; i++){ - aa[0].env = NULL; - aa[0].data = NULL; - } - aa[0].env = vm_thread -> jvmti_local_storage.env; - aa[0].data = vm_thread -> jvmti_local_storage.data; - vm_thread -> jvmti_local_storage.env = NULL; - vm_thread -> jvmti_local_storage.data = (void *) aa; - } - } - // array look up for existing env or for free record - for (int i = 0; i < MAX_JVMTI_ENV_NUMBER; i++){ - if (aa[i].env == env || aa[i].env == NULL ) { - aa[i].env = (data == NULL) ? NULL : env; - aa[i].data = (void *)data; - return 0; - } - } - ABORT("Array is full"); - - return 0; -} - -int thread_get_jvmti_thread_local_storage(jvmtiEnv* env, - jthread thread, - void** data_ptr) -{ *data_ptr = NULL; - if (thread == NULL) // for compatibility with other Java VM - { - for (int i = 0; i < MAX_JVMTI_ENV_NUMBER; i++){ - if (jvmti_local_storage_static[i].env == env) { - *data_ptr = jvmti_local_storage_static[i].data; - break; - } - } - return 0; - } + //if (!vm_thread) + // return JVMTI_ERROR_THREAD_NOT_ALIVE; // non-existant thread - VM_thread* vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); - - if (!vm_thread) - { - return -1; // non-existant thread - } - - JVMTILocalStorage* lstg = &vm_thread -> jvmti_local_storage; + JVMTILocalStorage* lstg = jthread_get_jvmti_local_storage(thread); if (lstg -> env == NULL) { if (lstg -> data != NULL) { // we have more than one record stored; @@ -1177,5 +860,6 @@ *data_ptr = lstg -> data; } } - return 0; + + return JVMTI_ERROR_NONE; } Index: vm/vmcore/src/jvmti/jvmti_locals.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_locals.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_locals.cpp (working copy) @@ -30,7 +30,7 @@ #include "open/vm_util.h" #include "cxxlog.h" #include "thread_generic.h" -#include "open/thread.h" +#include "open/jthread.h" #include "suspend_checker.h" #include "stack_iterator.h" #include "stack_trace.h" @@ -113,7 +113,7 @@ if (si_is_native(si)) \ { \ if (thread_suspended) \ - thread_resume(thread); \ + jthread_resume(thread); \ si_free(si); \ return JVMTI_ERROR_OPAQUE_FRAME; \ } \ @@ -121,7 +121,7 @@ if (si_is_past_end(si)) \ { \ if (thread_suspended) \ - thread_resume(thread); \ + jthread_resume(thread); \ si_free(si); \ return JVMTI_ERROR_NO_MORE_FRAMES; \ } \ @@ -166,7 +166,7 @@ vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); if (vm_thread != p_TLS_vmthread) { - thread_suspend(thread); + jthread_suspend(thread); thread_suspended = true; } } @@ -202,7 +202,7 @@ } if (thread_suspended) - thread_resume(thread); + jthread_resume(thread); return err; } @@ -242,7 +242,7 @@ vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); if (vm_thread != p_TLS_vmthread) { - thread_suspend(thread); + jthread_suspend(thread); thread_suspended = true; } } @@ -270,7 +270,7 @@ } if (thread_suspended) - thread_resume(thread); + jthread_resume(thread); return err; } @@ -310,7 +310,7 @@ vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); if (vm_thread != p_TLS_vmthread) { - thread_suspend(thread); + jthread_suspend(thread); thread_suspended = true; } } @@ -338,7 +338,7 @@ } if (thread_suspended) - thread_resume(thread); + jthread_resume(thread); return err; } @@ -423,7 +423,7 @@ vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); if (vm_thread != p_TLS_vmthread) { - thread_suspend(thread); + jthread_suspend(thread); thread_suspended = true; } } @@ -459,7 +459,7 @@ } if (thread_suspended) - thread_resume(thread); + jthread_resume(thread); return err; } @@ -499,7 +499,7 @@ vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); if (vm_thread != p_TLS_vmthread) { - thread_suspend(thread); + jthread_suspend(thread); thread_suspended = true; } } @@ -527,7 +527,7 @@ } if (thread_suspended) - thread_resume(thread); + jthread_resume(thread); return err; } @@ -567,7 +567,7 @@ vm_thread = get_vm_thread_ptr_safe(jvmti_test_jenv, thread); if (vm_thread != p_TLS_vmthread) { - thread_suspend(thread); + jthread_suspend(thread); thread_suspended = true; } } @@ -595,7 +595,7 @@ } if (thread_suspended) - thread_resume(thread); + jthread_resume(thread); return err; } Index: vm/vmcore/src/jvmti/jvmti_heap.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_heap.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_heap.cpp (working copy) @@ -26,7 +26,7 @@ #include "cxxlog.h" #include "open/gc.h" -#include "open/thread.h" + #include "suspend_checker.h" /* @@ -108,7 +108,7 @@ CHECK_EVERYTHING(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // no matter how counter-intuitive, // gc_force_gc() expects gc_enabled_status == disabled, // but, obviously, at a GC safepoint. Index: vm/vmcore/src/jvmti/jvmti_method.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_method.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_method.cpp (working copy) @@ -29,7 +29,7 @@ #include "object_handles.h" #include "jvmti_utils.h" #include "cxxlog.h" -#include "open/thread.h" + #include "jvmti_interface.h" #include "suspend_checker.h" #include "jvmti_internal.h" Index: vm/vmcore/src/jvmti/jvmti.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti.cpp (working copy) @@ -33,7 +33,7 @@ #include "environment.h" #include #include "properties.h" -#include "open/thread.h" + #include "port_filepath.h" #include "port_dso.h" #include Index: vm/vmcore/src/jvmti/jvmti_event.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_event.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_event.cpp (working copy) @@ -27,12 +27,11 @@ #include "jvmti_direct.h" #include "jvmti_internal.h" #include "jvmti_utils.h" -#include "thread_generic.h" #include "environment.h" #include "interpreter_exports.h" #include "interpreter_imports.h" #include "classloader.h" -#include "open/thread.h" +#include "open/jthread.h" #include "suspend_checker.h" #include "jit_intf_cpp.h" #include "vm_log.h" @@ -76,8 +75,8 @@ jvmtiError add_event_to_thread(jvmtiEnv *env, jvmtiEvent event_type, jthread event_thread) { TIEnv *p_env = (TIEnv *)env; - JNIEnv *jni_env = jni_native_intf; - VM_thread *p_thread = get_vm_thread_ptr_safe(jni_env, event_thread); + //JNIEnv *jni_env = jni_native_intf; + hythread_t p_thread = jthread_get_native_thread(event_thread); TIEventThread *et = p_env->event_threads[event_type - JVMTI_MIN_EVENT_TYPE_VAL]; // Find out if this environment is already registered on this thread on this event type @@ -103,8 +102,8 @@ void remove_event_from_thread(jvmtiEnv *env, jvmtiEvent event_type, jthread event_thread) { TIEnv *p_env = (TIEnv *)env; - JNIEnv *jni_env = jni_native_intf; - VM_thread *p_thread = get_vm_thread_ptr_safe(jni_env, event_thread); + // JNIEnv *jni_env = jni_native_intf; + hythread_t p_thread = jthread_get_native_thread(event_thread); TIEventThread *et = p_env->event_threads[event_type - JVMTI_MIN_EVENT_TYPE_VAL]; if (NULL == et) @@ -199,7 +198,9 @@ if (!is_valid_thread_object(event_thread)) return JVMTI_ERROR_INVALID_THREAD; - jint thread_state = thread_get_thread_state(event_thread); + jint thread_state; + IDATA UNUSED status = jthread_get_state(event_thread, &thread_state); + assert(status == TM_ERROR_NONE); if (!(thread_state & JVMTI_THREAD_STATE_ALIVE)) return JVMTI_ERROR_THREAD_NOT_ALIVE; @@ -352,7 +353,7 @@ void jvmti_send_vm_init_event(Global_Env *env) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // Switch phase to VM_Live event DebugUtilsTI *ti = env->TI; if (!ti->isEnabled()) @@ -362,7 +363,7 @@ ti->nextPhase(JVMTI_PHASE_LIVE); tmn_suspend_disable(); ObjectHandle hThread = oh_allocate_local_handle(); - hThread->object = (Java_java_lang_Thread *)p_TLS_vmthread->p_java_lang_thread; + hThread->object = (Java_java_lang_Thread *)jthread_get_java_thread(hythread_self())->object; tmn_suspend_enable(); // Send VM_INIT TI events TIEnv *ti_env = ti->getEnvironments(); @@ -383,7 +384,7 @@ } ti_env = next_env; } - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); oh_discard_local_handle(hThread); } @@ -583,7 +584,8 @@ return; jvmtiEvent event_type = JVMTI_EVENT_METHOD_ENTRY; - VM_thread *curr_thread = p_TLS_vmthread; + hythread_t curr_thread = hythread_self(); + TIEnv *ti_env = ti->getEnvironments(); TIEnv *next_env; while (NULL != ti_env) @@ -631,7 +633,8 @@ return; jvmtiEvent event_type = JVMTI_EVENT_METHOD_EXIT; - VM_thread *curr_thread = p_TLS_vmthread; + hythread_t curr_native_thread = hythread_self(); + TIEnv *ti_env = ti->getEnvironments(); TIEnv *next_env; while (NULL != ti_env) @@ -640,10 +643,8 @@ // check that event is enabled in this environment. if (!ti_env->global_events[event_type - JVMTI_MIN_EVENT_TYPE_VAL]) { TIEventThread *thr = ti_env->event_threads[event_type - JVMTI_MIN_EVENT_TYPE_VAL]; - while (thr) - { - if (thr->thread == curr_thread) - break; + while (thr) { + if (thr->thread == curr_native_thread) break; thr = thr->next; } @@ -667,9 +668,10 @@ if (interpreter_enabled()) return; + if (!ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_FRAME_POP_NOTIFICATION)) return; - + VM_thread *curr_thread = p_TLS_vmthread; jvmti_frame_pop_listener *fpl = curr_thread->frame_pop_listener; jvmti_frame_pop_listener **prev_fpl = &curr_thread->frame_pop_listener; jint skip = 0; @@ -722,7 +724,8 @@ return; jvmtiEvent event_type = JVMTI_EVENT_SINGLE_STEP; - VM_thread *curr_thread = p_TLS_vmthread; + hythread_t curr_thread = hythread_self(); + TIEnv *ti_env = ti->getEnvironments(); TIEnv *next_env; while (NULL != ti_env) @@ -764,20 +767,20 @@ Method *catch_method, jlocation catch_location) { assert(!exn_raised()); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); + VM_thread *curr_thread = p_TLS_vmthread; + hythread_t curr_native_thread=hythread_self(); + curr_thread->ti_exception_callback_pending = false; + DebugUtilsTI *ti = VM_Global_State::loader_env->TI; assert(ti->isEnabled()); - VM_thread *curr_thread = p_TLS_vmthread; - - curr_thread->ti_exception_callback_pending = false; - // Create local handles frame JNIEnv *jni_env = (JNIEnv *)jni_native_intf; ObjectHandle hThread = oh_allocate_local_handle(); - hThread->object = (Java_java_lang_Thread *)curr_thread->p_java_lang_thread; + hThread->object = (Java_java_lang_Thread *)jthread_get_java_thread(curr_native_thread)->object; TIEnv *ti_env = ti->getEnvironments(); TIEnv *next_env; @@ -790,10 +793,9 @@ TIEventThread *thr = ti_env->event_threads[JVMTI_EVENT_EXCEPTION - JVMTI_MIN_EVENT_TYPE_VAL]; - while (thr) { - if (thr->thread == curr_thread) + if (thr->thread == curr_native_thread) break; thr = thr->next; } @@ -809,7 +811,7 @@ if (NULL != func) { tmn_suspend_enable(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); func((jvmtiEnv *)ti_env, jni_env, reinterpret_cast(hThread), @@ -857,7 +859,7 @@ jvmti_send_exception_event(exn_object, method, location, catch_method, catch_location); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); if (!exn_raised()) set_current_thread_exception(exn_object->object); @@ -921,60 +923,13 @@ jvmti_send_exception_event(exception, method, location, catch_method, catch_location); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return exception->object; } -void jvmti_send_contended_enter_or_entered_monitor_event(jobject obj, - bool isEnter) -{ - assert(tmn_is_suspend_enabled()); - DebugUtilsTI *ti = VM_Global_State::loader_env->TI; - if (!ti->isEnabled()) { - return; - } - - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; - - tmn_suspend_disable(); - // Create local handles frame - NativeObjectHandles lhs; - ObjectHandle hThread = oh_allocate_local_handle(); - hThread->object = (Java_java_lang_Thread *)p_TLS_vmthread->p_java_lang_thread; - tmn_suspend_enable(); - - TIEnv *ti_env = ti->getEnvironments(); - TIEnv *next_env; - while (NULL != ti_env) - { - next_env = ti_env->next; - if (isEnter && ti_env->global_events[JVMTI_EVENT_MONITOR_CONTENDED_ENTER - - JVMTI_MIN_EVENT_TYPE_VAL]) - { - jvmtiEventMonitorContendedEnter func = (jvmtiEventMonitorContendedEnter) - ti_env->get_event_callback(JVMTI_EVENT_MONITOR_CONTENDED_ENTER); - if (NULL != func) - { - func((jvmtiEnv*)ti_env, jni_env, (jthread)hThread, obj); - } - } - else if (! isEnter && ti_env->global_events[JVMTI_EVENT_MONITOR_CONTENDED_ENTERED - - JVMTI_MIN_EVENT_TYPE_VAL]) - { - jvmtiEventMonitorContendedEntered func = (jvmtiEventMonitorContendedEntered) - ti_env->get_event_callback(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED); - if (NULL != func) - { - func((jvmtiEnv*)ti_env, jni_env, (jthread)hThread, obj); - } - } - ti_env = next_env; - } -} - void jvmti_send_class_load_event(const Global_Env* env, Class* clss) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if( clss->is_array || clss->is_primitive ) { // array class creation and creation of a primitive class // do not generate a class load event. @@ -995,7 +950,7 @@ tmn_suspend_disable(); ObjectHandle hThread = oh_allocate_local_handle(); ObjectHandle hClass = oh_allocate_local_handle(); - hThread->object = (Java_java_lang_Thread *)p_TLS_vmthread->p_java_lang_thread; + hThread->object = (Java_java_lang_Thread *)jthread_get_java_thread(hythread_self())->object; hClass->object = struct_Class_to_java_lang_Class(clss); tmn_suspend_enable(); @@ -1020,12 +975,12 @@ // fire local events for( TIEventThread* ti_et = ti_env->event_threads[JVMTI_EVENT_CLASS_LOAD - JVMTI_MIN_EVENT_TYPE_VAL]; ti_et != NULL; ti_et = ti_et->next ) - if (ti_et->thread == p_TLS_vmthread) + if (ti_et->thread == hythread_self()) { TRACE2("jvmti.class.cl", "Class load event, class name = " << clss->name->bytes); tmn_suspend_disable(); ObjectHandle hThreadLocal = oh_allocate_local_handle(); - hThreadLocal->object = (Java_java_lang_Thread *)ti_et->thread->p_java_lang_thread; + hThreadLocal->object = (Java_java_lang_Thread *)jthread_get_java_thread(ti_et->thread)->object; tmn_suspend_enable(); func((jvmtiEnv *)ti_env, jni_env, (jthread)hThreadLocal, (jclass)hClass); oh_discard_local_handle( hThreadLocal ); @@ -1044,7 +999,7 @@ int classlen, unsigned char* classbytes, int* newclasslen, unsigned char** newclass) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // Send Class Load event DebugUtilsTI* ti = env->TI; if (!ti->isEnabled()) @@ -1091,7 +1046,7 @@ // fire local events for( TIEventThread* ti_et = ti_env->event_threads[JVMTI_EVENT_CLASS_FILE_LOAD_HOOK - JVMTI_MIN_EVENT_TYPE_VAL]; ti_et != NULL; ti_et = ti_et->next ) - if (ti_et->thread == p_TLS_vmthread) + if (ti_et->thread == hythread_self()) { // free memory from previous redefinition if( last_redef && last_redef != input_class ) { @@ -1118,7 +1073,7 @@ void jvmti_send_class_prepare_event(Class* clss) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if( clss->is_array || clss->is_primitive ) { // class prepare events are not generated for primitive classes // and arrays @@ -1139,7 +1094,7 @@ tmn_suspend_disable(); // -----------vv ObjectHandle hThread = oh_allocate_local_handle(); ObjectHandle hClass = oh_allocate_local_handle(); - hThread->object = (Java_java_lang_Thread *)p_TLS_vmthread->p_java_lang_thread; + hThread->object = (Java_java_lang_Thread *)jthread_get_java_thread(hythread_self())->object; hClass->object = struct_Class_to_java_lang_Class(clss); tmn_suspend_enable(); // ------------^^ @@ -1164,12 +1119,12 @@ // fire local events for(TIEventThread* ti_et = ti_env->event_threads[JVMTI_EVENT_CLASS_PREPARE - JVMTI_MIN_EVENT_TYPE_VAL]; ti_et != NULL; ti_et = ti_et->next ) - if (ti_et->thread == p_TLS_vmthread) + if (ti_et->thread == hythread_self()) { TRACE2("jvmti.class.cp", "Class prepare event, class name = " << clss->name->bytes); tmn_suspend_disable(); // -------------------------------vv ObjectHandle hThreadLocal = oh_allocate_local_handle(); - hThreadLocal->object = (Java_java_lang_Thread *)ti_et->thread->p_java_lang_thread; + hThreadLocal->object = (Java_java_lang_Thread *)jthread_get_java_thread(hythread_self())->object; tmn_suspend_enable(); // --------------------------------^^ func((jvmtiEnv *)ti_env, jni_env, (jthread)hThreadLocal, (jclass)hClass); oh_discard_local_handle( hThreadLocal ); @@ -1179,47 +1134,105 @@ } oh_discard_local_handle(hThread); oh_discard_local_handle(hClass); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); } -void jvmti_send_thread_start_end_event(int is_start) -{ - assert(tmn_is_suspend_enabled()); +static void call_callback(jvmtiEvent event_type, JNIEnv *jni_env, TIEnv *ti_env, + void *callback_func, va_list args) { + assert(hythread_is_suspend_enabled()); + switch(event_type) { + case JVMTI_EVENT_THREAD_START: + case JVMTI_EVENT_THREAD_END: { + ((jvmtiEventThreadStart)callback_func)((jvmtiEnv*)ti_env, jni_env, + jthread_get_java_thread(hythread_self())); + break; + } + case JVMTI_EVENT_MONITOR_CONTENDED_ENTER: + case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED: { + jobject monitor = va_arg(args, jobject); + ((jvmtiEventMonitorContendedEnter) callback_func)((jvmtiEnv*)ti_env, + jni_env, jthread_get_java_thread(hythread_self()), monitor); - DebugUtilsTI *ti = VM_Global_State::loader_env->TI; - if (! ti->isEnabled()) return; + break; + } - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + case JVMTI_EVENT_MONITOR_WAIT: { + jobject monitor = va_arg(args, jobject); + jlong timeout = va_arg(args, jlong); + ((jvmtiEventMonitorWait)callback_func)((jvmtiEnv*)ti_env, jni_env, + jthread_get_java_thread(hythread_self()), monitor, timeout); + break; + } - tmn_suspend_disable(); - ObjectHandle hThread = oh_allocate_local_handle(); - hThread->object = (Java_java_lang_Thread *)p_TLS_vmthread->p_java_lang_thread; - tmn_suspend_enable(); + case JVMTI_EVENT_MONITOR_WAITED: { + jobject monitor = va_arg(args, jobject); + jboolean is_timed_out = va_arg(args, jint); //jboolean); + ((jvmtiEventMonitorWait)callback_func)((jvmtiEnv*)ti_env, jni_env, + jthread_get_java_thread(hythread_self()), monitor, is_timed_out); + break; + } + default: + break; + } + assert(hythread_is_suspend_enabled()); +} - TIEnv *ti_env = ti->getEnvironments(); - TIEnv *next_env; - while (NULL != ti_env) - { +static int is_interested_thread(TIEnv *ti_env, jvmtiEvent event_type) { + for( TIEventThread* ti_et = ti_env->event_threads[event_type - JVMTI_MIN_EVENT_TYPE_VAL]; + ti_et != NULL; ti_et = ti_et->next) { + if (ti_et->thread == hythread_self()) return 1; + } + + return 0; +} + +static void process_jvmti_event(jvmtiEvent event_type, int per_thread, ...) { + va_list args; + JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + TIEnv *ti_env, *next_env; + DebugUtilsTI *ti = VM_Global_State::loader_env->TI; + void *callback_func; + + if (! ti->isEnabled()) return; + ti_env = ti->getEnvironments(); + va_start(args, per_thread); + while(ti_env) { next_env = ti_env->next; - if (is_start && ti_env->global_events[JVMTI_EVENT_THREAD_START - JVMTI_MIN_EVENT_TYPE_VAL]) - { - jvmtiEventThreadStart func = (jvmtiEventThreadStart)ti_env->get_event_callback(JVMTI_EVENT_THREAD_START); - if (NULL != func) - { - func((jvmtiEnv*)ti_env, jni_env, (jthread)hThread); + if (!ti_env->global_events[event_type - JVMTI_MIN_EVENT_TYPE_VAL] + && (!per_thread || !is_interested_thread(ti_env, event_type))) { + ti_env = ti_env->next; + continue; } + + callback_func = ti_env->get_event_callback(event_type); + if (callback_func) call_callback(event_type, jni_env, ti_env, callback_func, args); + ti_env = next_env; + } + va_end(args); + } - else if (! is_start && ti_env->global_events[JVMTI_EVENT_THREAD_END - JVMTI_MIN_EVENT_TYPE_VAL]) - { - jvmtiEventThreadEnd func = (jvmtiEventThreadEnd)ti_env->get_event_callback(JVMTI_EVENT_THREAD_END); - if (NULL != func) - { - func((jvmtiEnv*)ti_env, jni_env, (jthread)hThread); + +void jvmti_send_thread_start_end_event(int is_start) { + is_start ? process_jvmti_event(JVMTI_EVENT_THREAD_START, 0, 0) + :process_jvmti_event(JVMTI_EVENT_THREAD_END, 1, 0); } + +void jvmti_send_wait_monitor_event(jobject monitor, jlong timeout) { + TRACE2("jvmti.monitor.wait", "Monitor wait event, monitor = " << monitor); + process_jvmti_event(JVMTI_EVENT_MONITOR_WAIT, 1, monitor, timeout); } - ti_env = next_env; + +void jvmti_send_waited_monitor_event(jobject monitor, jboolean is_timed_out) { + TRACE2("jvmti.monitor.waited", "Monitor wait event, monitor = " << monitor); + process_jvmti_event(JVMTI_EVENT_MONITOR_WAITED, 1, monitor, is_timed_out); } - assert(tmn_is_suspend_enabled()); + + +void jvmti_send_contended_enter_or_entered_monitor_event(jobject monitor, + int isEnter) { + TRACE2("jvmti.monitor.enter", "Monitor enter event, monitor = " << monitor << " is enter= " << isEnter); + (isEnter)?process_jvmti_event(JVMTI_EVENT_MONITOR_CONTENDED_ENTER, 1, monitor) + :process_jvmti_event(JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, 1, monitor); } void jvmti_send_vm_death_event() Index: vm/vmcore/src/jvmti/jvmti_field.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_field.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_field.cpp (working copy) @@ -27,7 +27,7 @@ #include "vm_strings.h" #include "jvmti_utils.h" #include "cxxlog.h" -#include "open/thread.h" + #include "suspend_checker.h" /* Index: vm/vmcore/src/jvmti/jvmti_thread_group.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_thread_group.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_thread_group.cpp (working copy) @@ -23,13 +23,13 @@ #include "jvmti_utils.h" #include "vm_threads.h" +#include #include "open/vm_util.h" #include "cxxlog.h" #include "suspend_checker.h" #include "environment.h" static JNIEnv_Internal * jvmti_test_jenv = jni_native_intf; -jobject get_jobject(VM_thread * thread); /* * Get Top Thread Groups @@ -60,7 +60,7 @@ jclass cl = struct_Class_to_java_lang_Class_Handle(VM_Global_State::loader_env->java_lang_Thread_Class); jmethodID id = jvmti_test_jenv -> GetMethodID(cl, "getThreadGroup","()Ljava/lang/ThreadGroup;"); - jobject current_thread = get_jobject(p_TLS_vmthread); + jobject current_thread = (jobject)jthread_self(); jobject group = jvmti_test_jenv -> CallObjectMethod (current_thread, id); cl = struct_Class_to_java_lang_Class_Handle(VM_Global_State::loader_env->java_lang_ThreadGroup_Class); Index: vm/vmcore/src/jvmti/jvmti_break.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_break.cpp (revision 430048) +++ vm/vmcore/src/jvmti/jvmti_break.cpp (working copy) @@ -27,11 +27,15 @@ #include "environment.h" #include "Class.h" #include "cxxlog.h" -#include "open/thread.h" + #include "interpreter_exports.h" #include "interpreter_imports.h" #include "suspend_checker.h" + +#include "open/jthread.h" +#include "open/hythread_ext.h" + // Called when current thread reached breakpoint. // Returns breakpoint ID received from executing engine on creating of the // breakpoint @@ -41,7 +45,7 @@ TRACE2("jvmti-break", "BREAKPOINT occured, location = " << location); NativeObjectHandles handles; ObjectHandle hThread = oh_allocate_local_handle(); - hThread->object = (Java_java_lang_Thread *)p_TLS_vmthread->p_java_lang_thread; + hThread->object = (Java_java_lang_Thread *)jthread_get_java_thread(hythread_self())->object; tmn_suspend_enable(); // FIXME: lock breakpoint table @@ -76,7 +80,7 @@ NULL != et; et = next_et) { next_et = et->next; - if (et->thread == p_TLS_vmthread) + if (et->thread == hythread_self()) { jvmtiEventBreakpoint func = (jvmtiEventBreakpoint)env->get_event_callback(JVMTI_EVENT_BREAKPOINT); if (NULL != func) Index: vm/vmcore/src/reflection/reflection.cpp =================================================================== --- vm/vmcore/src/reflection/reflection.cpp (revision 430048) +++ vm/vmcore/src/reflection/reflection.cpp (working copy) @@ -29,7 +29,7 @@ #include "vm_strings.h" #include "reflection.h" #include "port_malloc.h" -#include "open/thread.h" + #include "exceptions.h" #include "heap.h" #include "primitives_support.h" Index: vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp (revision 430048) +++ vm/vmcore/src/kernel_classes/native/java_lang_VMClassRegistry.cpp (working copy) @@ -33,7 +33,7 @@ #include "jni_utils.h" #include "reflection.h" #include "stack_trace.h" -#include "open/thread.h" + #include "vm_strings.h" #include "java_lang_VMClassRegistry.h" Index: vm/vmcore/src/kernel_classes/native/java_lang_VMMemoryManager.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/java_lang_VMMemoryManager.cpp (revision 430048) +++ vm/vmcore/src/kernel_classes/native/java_lang_VMMemoryManager.cpp (working copy) @@ -26,12 +26,13 @@ * java.lang.VMMemoryManager class. */ -#include "open/thread.h" + #include "open/gc.h" #include "jni_utils.h" #include "object.h" #include "finalize.h" #include "cxxlog.h" +#include "vm_threads.h" #include "java_lang_VMMemoryManager.h" @@ -126,7 +127,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMMemoryManager_runGC (JNIEnv *, jclass) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // no matter how counter-intuitive, // gc_force_gc() expects gc_enabled_status == disabled, // but, obviously, at a GC safepoint. Index: vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.h =================================================================== --- vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.h (revision 430048) +++ vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.h (working copy) @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -/** +/** * @author Andrey Chernyshev - * @version $Revision: 1.1.2.1.4.5 $ - */ + * @version $Revision: 1.1.2.1.2.2 $ + */ /* * THE FILE HAS BEEN AUTOGENERATED BY INTEL IJH TOOL. @@ -26,150 +25,132 @@ */ #include - - /* Header for class java.lang.VMThreadManager */ #ifndef _JAVA_LANG_VMTHREADMANAGER_H #define _JAVA_LANG_VMTHREADMANAGER_H - #ifdef __cplusplus extern "C" { #endif - /* Native methods */ /* - * Method: java.lang.VMThreadManager.countStackFrames(Ljava/lang/Thread;)I + * Method: java.lang.VMThreadManager.currentThread()Ljava/lang/Thread; */ -JNIEXPORT jint JNICALL -Java_java_lang_VMThreadManager_countStackFrames(JNIEnv *, jclass, - jobject); +JNIEXPORT jobject JNICALL Java_java_lang_VMThreadManager_currentThread + (JNIEnv *, jclass); /* - * Method: java.lang.VMThreadManager.currentThread()Ljava/lang/Thread; + * Method: java.lang.VMThreadManager.holdsLock(Ljava/lang/Object;)Z */ -JNIEXPORT jobject JNICALL -Java_java_lang_VMThreadManager_currentThread(JNIEnv *, jclass); +JNIEXPORT jboolean JNICALL Java_java_lang_VMThreadManager_holdsLock + (JNIEnv *, jclass, jobject); /* - * Method: java.lang.VMThreadManager.holdsLock(Ljava/lang/Object;)Z + * Method: java.lang.VMThreadManager.interrupt(Ljava/lang/Thread;)I */ -JNIEXPORT jboolean JNICALL -Java_java_lang_VMThreadManager_holdsLock(JNIEnv *, jclass, - jobject); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_interrupt + (JNIEnv *, jclass, jobject); /* - * Method: java.lang.VMThreadManager.interrupt(Ljava/lang/Thread;)V + * Method: java.lang.VMThreadManager.isInterrupted()Z */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_interrupt(JNIEnv *, jclass, - jobject); +JNIEXPORT jboolean JNICALL Java_java_lang_VMThreadManager_isInterrupted__ + (JNIEnv *, jclass); /* - * Method: java.lang.VMThreadManager.isDead(Ljava/lang/Thread;)Z + * Method: java.lang.VMThreadManager.isInterrupted(Ljava/lang/Thread;)Z */ -JNIEXPORT jboolean JNICALL -Java_java_lang_VMThreadManager_isDead(JNIEnv *, jclass, - jobject); +JNIEXPORT jboolean JNICALL Java_java_lang_VMThreadManager_isInterrupted__Ljava_lang_Thread_2 + (JNIEnv *, jclass, jobject); /* - * Method: java.lang.VMThreadManager.isInterrupted()Z + * Method: java.lang.VMThreadManager.notify(Ljava/lang/Object;)I */ -JNIEXPORT jboolean JNICALL -Java_java_lang_VMThreadManager_isInterrupted__(JNIEnv *, jclass); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_notify + (JNIEnv *, jclass, jobject); /* - * Method: java.lang.VMThreadManager.isInterrupted(Ljava/lang/Thread;)Z + * Method: java.lang.VMThreadManager.notifyAll(Ljava/lang/Object;)I */ -JNIEXPORT jboolean JNICALL -Java_java_lang_VMThreadManager_isInterrupted__Ljava_lang_Thread_2(JNIEnv *, jclass, - jobject); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_notifyAll + (JNIEnv *, jclass, jobject); /* - * Method: java.lang.VMThreadManager.join(Ljava/lang/Thread;JI)V - * Throws: java.lang.InterruptedException + * Method: java.lang.VMThreadManager.resume(Ljava/lang/Thread;)I */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_join(JNIEnv *, jclass, - jobject, jlong, jint); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_resume + (JNIEnv *, jclass, jobject); /* - * Method: java.lang.VMThreadManager.notify(Ljava/lang/Object;)V + * Method: java.lang.VMThreadManager.setPriority(Ljava/lang/Thread;I)I */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_notify(JNIEnv *, jclass, - jobject); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_setPriority + (JNIEnv *, jclass, jobject, jint); /* - * Method: java.lang.VMThreadManager.notifyAll(Ljava/lang/Object;)V + * Method: java.lang.VMThreadManager.sleep(JI)I */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_notifyAll(JNIEnv *, jclass, - jobject); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_sleep + (JNIEnv *, jclass, jlong, jint); /* - * Method: java.lang.VMThreadManager.resume(Ljava/lang/Thread;)V + * Method: java.lang.VMThreadManager.start(Ljava/lang/Thread;JZI)I */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_resume(JNIEnv *, jclass, - jobject); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_start + (JNIEnv *, jclass, jobject, jlong, jboolean, jint); /* - * Method: java.lang.VMThreadManager.setPriority(Ljava/lang/Thread;I)V + * Method: java.lang.VMThreadManager.stop(Ljava/lang/Thread;Ljava/lang/Throwable;)I */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_setPriority(JNIEnv *, jclass, - jobject, jint); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_stop + (JNIEnv *, jclass, jobject, jthrowable); /* - * Method: java.lang.VMThreadManager.sleep(JI)V - * Throws: java.lang.InterruptedException + * Method: java.lang.VMThreadManager.suspend(Ljava/lang/Thread;)I */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_sleep(JNIEnv *, jclass, - jlong, jint); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_suspend + (JNIEnv *, jclass, jobject); /* - * Method: java.lang.VMThreadManager.start(Ljava/lang/Thread;J)V + * Method: java.lang.VMThreadManager.wait(Ljava/lang/Object;JI)I */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_start(JNIEnv *, jclass, - jobject, jlong); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_wait + (JNIEnv *, jclass, jobject, jlong, jint); /* - * Method: java.lang.VMThreadManager.stop(Ljava/lang/Thread;Ljava/lang/Throwable;)V + * Method: java.lang.VMThreadManager.yield()I */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_stop(JNIEnv *, jclass, - jobject, jthrowable); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_yield + (JNIEnv *, jclass); /* - * Method: java.lang.VMThreadManager.suspend(Ljava/lang/Thread;)V + * Method: java.lang.VMThreadManager.attach()V */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_suspend(JNIEnv *, jclass, - jobject); +JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_attach + (JNIEnv *, jclass, jobject); + /* - * Method: java.lang.VMThreadManager.wait(Ljava/lang/Object;JI)V - * Throws: java.lang.InterruptedException + * Method: java.lang.VMThreadManager.isDead(Ljava/lang/Thread;)Z */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_wait(JNIEnv *, jclass, - jobject, jlong, jint); +JNIEXPORT jboolean JNICALL Java_java_lang_VMThreadManager_isAlive + (JNIEnv *, jclass, jobject); /* - * Method: java.lang.VMThreadManager.yield()V + * Method: java.lang.VMThreadManager.join(Ljava/lang/Thread;JI)I + * Throws: java.lang.InterruptedException */ -JNIEXPORT void JNICALL -Java_java_lang_VMThreadManager_yield(JNIEnv *, jclass); +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_join + (JNIEnv *, jclass, jobject, jlong, jint); - +/* + * Method: java.lang.VMThreadManager.init(Ljava/lang/Thread;)V + */ +JNIEXPORT jlong JNICALL Java_java_lang_VMThreadManager_init + (JNIEnv *, jclass, jobject, jobject, jlong); #ifdef __cplusplus } #endif - -#endif /* _JAVA_LANG_VMTHREADMANAGER_H */ - +#endif Index: vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp (revision 430048) +++ vm/vmcore/src/kernel_classes/native/org_apache_harmony_vm_VMStack.cpp (working copy) @@ -29,7 +29,6 @@ #define LOG_DOMAIN "kernel.stack" #include "cxxlog.h" -#include "open/thread.h" #include "stack_trace.h" #include "jni_direct.h" #include "jni_utils.h" @@ -61,7 +60,7 @@ if (!res) return NULL; // obtain and return class of the frame - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return struct_Class_to_jclass((Class*)method_get_class(frame.method)); } @@ -128,7 +127,7 @@ unsigned maxSize = signedMaxSize; - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); unsigned size; StackTraceFrame* frames; st_get_trace(&size, &frames); @@ -152,7 +151,7 @@ length ++; } - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jclass ste = struct_Class_to_java_lang_Class_Handle(VM_Global_State::loader_env->JavaLangClass_Class); assert(ste); @@ -162,7 +161,7 @@ if (arr == NULL) { // OutOfMemoryError core_free(frames); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return NULL; } @@ -183,7 +182,7 @@ } core_free(frames); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return arr; } @@ -282,16 +281,18 @@ } } } + // skip Thread.runImpl() + size--; // skip the VMStart$MainThread if one exits from the bottom of the stack // along with 2 reflection frames used to invoke method main static String* starter_String = genv->string_pool.lookup("java/lang/VMStart$MainThread"); - Method_Handle method = frames[size-1].method; + Method_Handle method = frames[size].method; assert(method); // skip only for main application thread - if (!strcmp(method_get_name(method), "run") + if (!strcmp(method_get_name(method), "runImpl") && method->get_class()->name == starter_String) { - int rem = size - skip; + int rem = size - skip-1; size -= rem < 3 ? rem : 3; } @@ -299,7 +300,7 @@ << " frames but there are only " << size << " frames in stack"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jclass ste = struct_Class_to_java_lang_Class_Handle(genv->java_lang_StackTraceElement_Class); assert(ste); Index: vm/vmcore/src/kernel_classes/native/java_lang_VMStart.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/java_lang_VMStart.cpp (revision 430048) +++ vm/vmcore/src/kernel_classes/native/java_lang_VMStart.cpp (working copy) @@ -18,15 +18,16 @@ * @version $Revision: 1.1.2.1.4.4 $ */ #include "thread_generic.h" -#include "open/thread.h" +#include "open/hythread_ext.h" + #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_java_lang_VMStart_joinAllNonDaemonThreads (JNIEnv * UNREF jenv, jclass UNREF starter) { - wait_until_non_daemon_threads_are_dead(); + hythread_wait_for_all_nondaemon_threads(); } #ifdef __cplusplus Index: vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.cpp (revision 430048) +++ vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.cpp (working copy) @@ -21,12 +21,10 @@ #define LOG_DOMAIN "kernel" #include "cxxlog.h" -#include "thread_generic.h" -#include "object_handles.h" -#include "mon_enter_exit.h" -#include "open/thread.h" - #include "java_lang_VMThreadManager.h" +#include "open/hythread_ext.h" +#include "open/jthread.h" +#include "open/thread_externals.h" /* * Class: java_lang_VMThreadManager @@ -34,9 +32,9 @@ * Signature: ()Ljava/lang/Thread; */ JNIEXPORT jobject JNICALL Java_java_lang_VMThreadManager_currentThread - (JNIEnv * UNREF jenv, jclass) + (JNIEnv * UNREF jenv, jclass clazz) { - return thread_current_thread(); + return jthread_self(); } /* @@ -45,31 +43,20 @@ * Signature: (Ljava/lang/Object;)Z */ JNIEXPORT jboolean JNICALL Java_java_lang_VMThreadManager_holdsLock - (JNIEnv * UNREF jenv, jclass, jobject lock) + (JNIEnv * UNREF jenv, jclass clazz, jobject monitor) { - //ToDo: the following code will be used. - //return thread_holds_lock(thread_current_thread(), lock); - - VM_thread * vm_thread = get_thread_ptr(); - tmn_suspend_disable(); //---------------------------------v - - ManagedObject *p_obj = (ManagedObject *)(((ObjectHandle)lock)->object); - uint16 stack_key = STACK_KEY(p_obj); - - tmn_suspend_enable(); //---------------------------------^ - - return (jboolean)((vm_thread -> thread_index == stack_key) ? JNI_TRUE : JNI_FALSE); + return false;//jthread_holds_lock(jthread_self(), monitor); } /* * Class: java_lang_VMThreadManager * Method: interrupt - * Signature: (Ljava/lang/Thread;)V + * Signature: (Ljava/lang/Thread;)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_interrupt - (JNIEnv * UNREF jenv, jclass, jobject jthread) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_interrupt + (JNIEnv * UNREF jenv, jclass clazz, jobject jthread) { - thread_interrupt(jthread); + return jthread_interrupt(jthread); } /* @@ -78,10 +65,9 @@ * Signature: ()Z */ JNIEXPORT jboolean JNICALL Java_java_lang_VMThreadManager_isInterrupted__ - (JNIEnv * UNREF jenv, jclass) + (JNIEnv * UNREF jenv, jclass clazz) { - jobject thread = thread_current_thread(); - return thread_is_interrupted(thread, JNI_TRUE); + return jthread_is_interrupted(jthread_self()); } /* @@ -90,198 +76,193 @@ * Signature: (Ljava/lang/Thread;)Z */ JNIEXPORT jboolean JNICALL Java_java_lang_VMThreadManager_isInterrupted__Ljava_lang_Thread_2 - (JNIEnv * UNREF jenv, jclass, jobject jthread) + (JNIEnv * UNREF jenv, jclass clazz, jobject thread) { - return thread_is_interrupted(jthread, JNI_FALSE); + return jthread_is_interrupted(thread); } /* * Class: java_lang_VMThreadManager * Method: notify - * Signature: (Ljava/lang/Object;)V + * Signature: (Ljava/lang/Object;)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_notify - (JNIEnv * UNREF jenv, jclass, jobject obj) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_notify + (JNIEnv * UNREF jenv, jclass clazz, jobject monitor) { - thread_object_notify(obj); + return jthread_monitor_notify(monitor); } /* * Class: java_lang_VMThreadManager * Method: notifyAll - * Signature: (Ljava/lang/Object;)V + * Signature: (Ljava/lang/Object;)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_notifyAll - (JNIEnv * UNREF jenv, jclass, jobject obj) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_notifyAll + (JNIEnv * UNREF jenv, jclass clazz, jobject monitor) { - thread_object_notify_all(obj); + return jthread_monitor_notify_all(monitor); } /* * Class: java_lang_VMThreadManager * Method: resume - * Signature: (Ljava/lang/Thread;)V + * Signature: (Ljava/lang/Thread;)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_resume - (JNIEnv * UNREF jenv, jclass, jobject jthread) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_resume + (JNIEnv * UNREF jenv, jclass clazz, jobject thread) { - thread_resume(jthread); + return jthread_resume(thread); } /* * Class: java_lang_VMThreadManager * Method: setPriority - * Signature: (Ljava/lang/Thread;I)V + * Signature: (Ljava/lang/Thread;I)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_setPriority - (JNIEnv * UNREF jenv, jclass, jobject UNREF jthread, jint UNREF priority) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_setPriority + (JNIEnv * UNREF jenv, jclass clazz, jobject UNREF thread, jint UNREF priority) { - //ToDo: the following code will be used. - //thread_set_priority(jthread, priority); + return jthread_set_priority(thread, priority); } /* * Class: java_lang_VMThreadManager * Method: sleep - * Signature: (JI)V + * Signature: (JI)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_sleep - (JNIEnv * UNREF jenv, jclass, jlong millis, jint nanos) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_sleep + (JNIEnv * UNREF jenv, jclass clazz, jlong millis, jint nanos) { -#if defined (__INTEL_COMPILER) // intel compiler - #pragma warning( push ) - #pragma warning (disable:1682) // explicit conversion of a 64-bit integral type to a smaller integral type -#elif defined (_MSC_VER) // MS compiler - #pragma warning( push ) - #pragma warning (disable:4244) // conversion from 'jlong' to 'long', possible loss of data -#endif + return jthread_sleep(millis, nanos); +} - thread_sleep(thread_current_thread(), millis, nanos); - -#if defined (__INTEL_COMPILER) || defined (_MSC_VER) - #pragma warning( pop ) -#endif +/* + * Class: java_lang_VMThreadManager + * Method: init + * Signature: (JI)V + */ +JNIEXPORT jlong JNICALL Java_java_lang_VMThreadManager_init + (JNIEnv *jenv, jclass clazz, jobject thread, jobject ref, jlong oldThread) +{ + return jthread_thread_init(NULL, jenv, thread, ref, oldThread); } /* * Class: java_lang_VMThreadManager * Method: start - * Signature: (Ljava/lang/Thread;J)V + * Signature: (Ljava/lang/Thread;JZI)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_start - (JNIEnv *jenv, jclass, jobject thread, jlong UNREF stackSize) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_start + (JNIEnv *jenv, jclass clazz, jobject thread, jlong stackSize, jboolean daemon, jint priority) { - thread_start(jenv, thread); + jthread_threadattr_t attrs; + attrs.daemon = daemon; + attrs.priority = priority; + attrs.stacksize = (jint)stackSize; + return (jint)jthread_create(jenv, thread, &attrs); } /* * Class: java_lang_VMThreadManager * Method: stop - * Signature: (Ljava/lang/Thread;Ljava/lang/Throwable;)V + * Signature: (Ljava/lang/Thread;Ljava/lang/Throwable;)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_stop - (JNIEnv *, jclass, jobject UNREF thread, jthrowable UNREF threadDeathException) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_stop + (JNIEnv *env, jclass clazz, jobject UNREF thread, jthrowable UNREF threadDeathException) { - //ToDo: the following code will be used. - //thread_stop(thread, threadDeathException); + return jthread_exception_stop(thread, threadDeathException); } /* * Class: java_lang_VMThreadManager * Method: suspend - * Signature: (Ljava/lang/Thread;)V + * Signature: (Ljava/lang/Thread;)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_suspend - (JNIEnv * UNREF jenv, jclass, jobject jthread) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_suspend + (JNIEnv * UNREF jenv, jclass clazz, jobject jthread) { - thread_suspend(jthread); + return jthread_suspend(jthread); } /* * Class: java_lang_VMThreadManager * Method: wait - * Signature: (Ljava/lang/Object;JI)V + * Signature: (Ljava/lang/Object;JI)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_wait - (JNIEnv *, jclass, jobject object, jlong millis, jint nanos) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_wait + (JNIEnv *env, jclass clazz, jobject monitor, jlong millis, jint UNREF nanos) { - thread_object_wait_nanos (object, millis, nanos); + return jthread_monitor_timed_wait(monitor, millis, nanos); } /* * Class: java_lang_VMThreadManager * Method: yield - * Signature: ()V + * Signature: ()I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_yield - (JNIEnv * UNREF jenv, jclass) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_yield + (JNIEnv * UNREF jenv, jclass clazz) { - //ToDo: the following code will be used. - //thread_yield(thread_current_thread()); + return jthread_yield(); +} - SleepEx(0, false); +/* + * Class: java_lang_VMThreadManager + * Method: attach + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_attach + (JNIEnv * UNREF jenv, jclass clazz, jobject java_thread) +{ + jthread_attach(jenv, java_thread); } /* * Class: java_lang_VMThreadManager - * Method: isDead + * Method: isAlive * Signature: (Ljava/lang/Thread;)Z */ -JNIEXPORT jboolean JNICALL Java_java_lang_VMThreadManager_isDead - (JNIEnv *jenv, jclass, jobject thread) +JNIEXPORT jboolean JNICALL Java_java_lang_VMThreadManager_isAlive + (JNIEnv *jenv, jclass clazz, jobject thread) { - //return ! thread_is_alive(thread); + hythread_t tm_native_thread; - VM_thread *p_vmthread = get_vm_thread_ptr_safe(jenv, thread); - if ( !p_vmthread ) { - return 1; // don't try to isAlive() non-existant thread - } - - java_state as = p_vmthread->app_status; - // According to JAVA spec, this method should return true, if and - // only if the thread has been died. - switch (as) { - case thread_is_sleeping: - case thread_is_waiting: - case thread_is_timed_waiting: - case thread_is_blocked: - case thread_is_running: - case thread_is_birthing: - return 0; - //break; - case thread_is_dying: - case zip: - return 1; - //break; - default: - ABORT("Unexpected thread state"); - return 1; - //break; + tm_native_thread = (hythread_t )vm_jthread_get_tm_data((jthread)thread); + assert(tm_native_thread); + if (hythread_is_alive(tm_native_thread)) + { + printf("isAlive\n"); + return true; } - // must return from inside the switch statement //remark #111: statement is unreachable + printf ("isnot\n"); + return false; } /* * Class: java_lang_VMThreadManager * Method: join - * Signature: (Ljava/lang/Thread;JI)V + * Signature: (Ljava/lang/Thread;JI)I */ -JNIEXPORT void JNICALL Java_java_lang_VMThreadManager_join - (JNIEnv * UNREF jenv, jclass, jobject thread, jlong millis, jint nanos) +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_join + (JNIEnv * UNREF jenv, jclass clazz, jobject thread, jlong millis, jint nanos) { -#if defined (__INTEL_COMPILER) // intel compiler - #pragma warning( push ) - #pragma warning (disable:1682) // explicit conversion of a 64-bit integral type to a smaller integral type -#elif defined (_MSC_VER) // MS compiler - #pragma warning( push ) - #pragma warning (disable:4244) // conversion from 'jlong' to 'long', possible loss of data -#endif + return jthread_timed_join(thread, millis, nanos); +} - thread_join(thread, millis, nanos); -#if defined (__INTEL_COMPILER) || defined (_MSC_VER) -#pragma warning( pop ) -#endif -} +/* + * Class: java_lang_VMThreadManager + * Method: yield + * Signature: ()I + */ + +/* + * ???? +JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_initVMThreadManager + (JNIEnv * UNREF jenv, jclass clazz) +{ + return hythread_init(); +} +*/ Index: vm/vmcore/src/kernel_classes/native/java_lang_FinalizerThread.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/java_lang_FinalizerThread.cpp (revision 430048) +++ vm/vmcore/src/kernel_classes/native/java_lang_FinalizerThread.cpp (working copy) @@ -28,9 +28,10 @@ #include "java_lang_FinalizerThread.h" #include "open/gc.h" -#include "open/thread.h" +#include "open/hythread_ext.h" #include "finalize.h" #include "port_sysinfo.h" +#include "vm_threads.h" /** * Implements getObject(..) method. Index: vm/vmcore/src/kernel_classes/native/java_util_concurrent_locks_LockSupport.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/java_util_concurrent_locks_LockSupport.cpp (revision 430048) +++ vm/vmcore/src/kernel_classes/native/java_util_concurrent_locks_LockSupport.cpp (working copy) @@ -21,22 +21,21 @@ #include "thread_generic.h" #include "java_util_concurrent_locks_LockSupport.h" #include "jni.h" +#include "open/jthread.h" - /* Inaccessible static: parked */ /* * Method: java.util.concurrent.locks.LockSupport.unpark(Ljava/lang/Thread;)V */ JNIEXPORT void JNICALL Java_java_util_concurrent_locks_LockSupport_unpark (JNIEnv *jenv, jclass, jobject thread) { - if (!thread) return; - unpark(get_vm_thread_ptr_safe(jenv, thread)); + jthread_unpark(thread); } /* * Method: java.util.concurrent.locks.LockSupport.park()V */ JNIEXPORT void JNICALL Java_java_util_concurrent_locks_LockSupport_park (JNIEnv * UNREF jenv, jclass) { - park(); + jthread_park(); } /* @@ -49,7 +48,7 @@ #endif JNIEXPORT void JNICALL Java_java_util_concurrent_locks_LockSupport_parkNanos(JNIEnv * UNREF jenv, jclass, jlong nanos) { - parktimed(nanos/((jlong)1000000), (jint)(nanos%((jlong)1000000))); + jthread_timed_park(0,(jint)nanos); } #if defined (__INTEL_COMPILER) @@ -60,6 +59,7 @@ * Method: java.util.concurrent.locks.LockSupport.parkUntil(J)V */ JNIEXPORT void JNICALL Java_java_util_concurrent_locks_LockSupport_parkUntil(JNIEnv * UNREF jenv, jclass UNREF thread, jlong milis) { - parkuntil(milis, 0); + //FIXME integration should be parkUntil + jthread_timed_park((jlong)milis, 0); } Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/VMStart.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/VMStart.java (revision 430048) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/VMStart.java (working copy) @@ -51,6 +51,7 @@ // create main thread in new thread group MainThread mainThread = new MainThread(mainClassName, args); mainThread.start(); + //startHelperThreads(); //System.out.println("Join Group " + Thread.currentThread().getThreadGroup()); } catch (Throwable e) { e.printStackTrace(System.err); @@ -103,8 +104,10 @@ this.args = args; } - public void run() { + } + + void runImpl() { // prevent access from user classes to run() method if(started) { return; @@ -137,10 +140,20 @@ } catch (Throwable e) { exitCode = 1; e.printStackTrace(System.err); - } - } + } finally { + group.remove(this); + synchronized(lock) { + this.isAlive = false; + lock.notifyAll(); + } + } + } } + static void mainThreadInit() { + Thread theFirstThread = new Thread(true); + } + native static void joinAllNonDaemonThreads(); } Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/VMThreadManager.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/VMThreadManager.java (revision 430048) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/VMThreadManager.java (working copy) @@ -37,6 +37,13 @@ final class VMThreadManager { /** + * Thread Manager functions error codes. + */ + public static final int TM_ERROR_NONE = 0; + public static final int TM_ERROR_INTERRUPT = 52; + public static final int TM_ERROR_ILLEGAL_STATE = 51; + + /** * This class is not supposed to be instantiated. */ private VMThreadManager() { @@ -79,7 +86,7 @@ * {@link Thread#interrupt() Thread.interrupt()} method. * @api2vm */ - static native void interrupt(Thread thread); + static native int interrupt(Thread thread); /** * Checks if the specified thread is dead. @@ -91,7 +98,7 @@ * @return true if the thread has died already, false otherwise. * @api2vm */ - static native boolean isDead(Thread thread); + static native boolean isAlive(Thread thread); /** * This method satisfies the requirements of the specification for the @@ -115,29 +122,28 @@ * must be valid. * @api2vm */ - static native void join(Thread thread, long millis, int nanos) - throws InterruptedException; + static native int join(Thread thread, long millis, int nanos); /** * This method satisfies the requirements of the specification for the * {@link Object#notify() Object.notify()} method. * @api2vm */ - static native void notify(Object object); + static native int notify(Object object); /** * This method satisfies the requirements of the specification for the * {@link Object#notifyAll() Object.notifyAll()} method. * @api2vm */ - static native void notifyAll(Object object); + static native int notifyAll(Object object); /** * This method satisfies the requirements of the specification for the * {@link Thread#resume() Thread.resume()} method. * @api2vm */ - static native void resume(Thread thread); + static native int resume(Thread thread); /** * Changes the priority of the specified thread. @@ -149,7 +155,7 @@ * @param priority new priority value * @api2vm */ - static native void setPriority(Thread thread, int priority); + static native int setPriority(Thread thread, int priority); /** * This method satisfies the requirements of the specification for the @@ -159,8 +165,7 @@ * must be valid. * @api2vm */ - static native void sleep(long millis, int nanos) - throws InterruptedException; + static native int sleep(long millis, int nanos); /** * Starts the specified thread. Causes JVM to start executing @@ -177,7 +182,7 @@ * @param size the desired stack size in bytes or zero to be ignored * @api2vm */ - static native void start(Thread thread, long size); + static native int start(Thread thread, long stackSize, boolean daemon, int priority); /** * This method satisfies the requirements of the specification for the @@ -186,14 +191,14 @@ * exception. The throwable argument must not be null. * @api2vm */ - static native void stop(Thread thread, Throwable throwable); + static native int stop(Thread thread, Throwable throwable); /** * This method satisfies the requirements of the specification for the * {@link Thread#suspend() Thread.suspend()} method. * @api2vm */ - static native void suspend(Thread thread); + static native int suspend(Thread thread); /** * This method satisfies the requirements of the specification for the @@ -203,7 +208,7 @@ * must be valid. * @api2vm */ - static native void wait(Object object, long millis, int nanos) + static native int wait(Object object, long millis, int nanos) throws InterruptedException; /** @@ -211,5 +216,20 @@ * {@link Thread#yield() Thread.yield()} method. * @api2vm */ - static native void yield(); + static native int yield(); + + /** + * This method initialize native thread structure as well as inter dependencies + * between java thread and native thread. + * @api2vm + */ + static native long init(Thread thread, ThreadWeakRef ref, long oldAddr); + + /** + * This method attches current thread to vm. Required for main thread construction. + * @api2vm + */ + static native int attach(java.lang.Thread thread); + } + Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/Object.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/Object.java (revision 430048) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/Object.java (working copy) @@ -26,6 +26,10 @@ */ public class Object { + private static final int TM_ERROR_NONE = 0; + private static final int TM_ERROR_INTERRUPT = 52; + private static final int TM_ERROR_ILLEGAL_STATE = 118; + public final Class getClass() { return VMClassRegistry.getClass(this); } @@ -51,18 +55,38 @@ } public final void notify() { - VMThreadManager.notify(this); + int status = VMThreadManager.notify(this); + if (status == VMThreadManager.TM_ERROR_ILLEGAL_STATE) { + throw new IllegalMonitorStateException(); + } else if (status != VMThreadManager.TM_ERROR_NONE) { + throw new InternalError( + "Thread Manager internal error " + status); + } } public final void notifyAll() { - VMThreadManager.notifyAll(this); + int status = VMThreadManager.notifyAll(this); + if (status == VMThreadManager.TM_ERROR_ILLEGAL_STATE) { + throw new IllegalMonitorStateException(); + } else if (status != VMThreadManager.TM_ERROR_NONE) { + throw new InternalError( + "Thread Manager internal error " + status); + } } public final void wait(long millis, int nanos) throws InterruptedException { if(millis < 0 || nanos < 0 || nanos > 999999 ){ throw new IllegalArgumentException("Arguments don't match the expected range!"); } - VMThreadManager.wait(this, millis, nanos); + int status = VMThreadManager.wait(this, millis, nanos); + if (status == VMThreadManager.TM_ERROR_INTERRUPT) { + throw new InterruptedException(); + } else if (status == VMThreadManager.TM_ERROR_ILLEGAL_STATE) { + throw new IllegalMonitorStateException(); + } else if (status != VMThreadManager.TM_ERROR_NONE) { + // throw new InternalError( + // "Thread Manager internal error " + status); + } } public final void wait(long millis) throws InterruptedException { @@ -70,7 +94,15 @@ } public final void wait() throws InterruptedException { - VMThreadManager.wait(this, 0, 0); + int status = VMThreadManager.wait(this, 0, 0); + if (status == VMThreadManager.TM_ERROR_INTERRUPT) { + throw new InterruptedException(); + } else if (status == VMThreadManager.TM_ERROR_ILLEGAL_STATE) { + throw new IllegalMonitorStateException(); + } else if (status != VMThreadManager.TM_ERROR_NONE) { + // throw new InternalError( + // "Thread Manager internal error " + status); + } } protected void finalize() throws Throwable { Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java (revision 430048) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/Thread.java (working copy) @@ -94,7 +94,13 @@ */ boolean started = false; + /** + * Indicates if the thread is alive. + */ + boolean isAlive = false; + + /** * Thread's target - a Runnable object whose run * method should be invoked */ @@ -130,7 +136,7 @@ /** * Synchronization is done using internal lock. */ - private Object lock = new Object(); + Object lock = new Object(); /** * generates a unique thread ID @@ -195,21 +201,6 @@ Thread currentThread = VMThreadManager.currentThread(); SecurityManager securityManager = System.getSecurityManager(); - // If currentThread == this we suppose that the constructor was called - // by VM to create a Thread instance representing the Main Thread - if (currentThread == this) { - this.name = "main"; - this.group = new ThreadGroup(); - this.group.add(this); - this.priority = NORM_PRIORITY; - this.daemon = false; - this.target = null; - this.stackSize = 0; - this.started = true; - // initialize the system class loader and set it as context - // classloader - ClassLoader.getSystemClassLoader(); - } else { ThreadGroup threadGroup = null; if (group != null) { if (securityManager != null) { @@ -227,15 +218,47 @@ // throws NullPointerException if the given name is null this.name = (name != THREAD) ? this.name = name.toString() : THREAD + threadCounter++; - setPriority(currentThread.priority); this.daemon = currentThread.daemon; this.contextClassLoader = currentThread.contextClassLoader; this.target = target; this.stackSize = stackSize; + this.priority = currentThread.priority; initializeInheritableLocalValues(currentThread); + + checkGCWatermark(); + + ThreadWeakRef oldRef = ThreadWeakRef.poll(); + ThreadWeakRef newRef = new ThreadWeakRef(this); + + long oldPointer = (oldRef == null)? 0 : oldRef.getNativeAddr(); + long newPointer = VMThreadManager.init(this, newRef, oldPointer); + if (newPointer == 0) { + throw new OutOfMemoryError("Failed to create new thread"); } + newRef.setNativeAddr(newPointer); + this.threadId = getNextThreadId(); SecurityUtils.putContext(this, AccessController.getContext()); + checkAccess(); + } + + /** + * @com.intel.drl.spec_ref + */ + Thread(boolean nativeThread) { + VMThreadManager.attach(this); + this.name = "System thread"; + this.group = new ThreadGroup(); + this.group.add(this); + this.daemon = false; + this.started = true; + this.priority = NORM_PRIORITY; + // initialize the system class loader and set it as context + // classloader + ClassLoader.getSystemClassLoader(); + + this.threadId = getNextThreadId(); + SecurityUtils.putContext(this, AccessController.getContext()); } /** @@ -310,14 +333,24 @@ throw new IllegalArgumentException( "Arguments don't match the expected range!"); } - VMThreadManager.sleep(millis, nanos); + int status = VMThreadManager.sleep(millis, nanos); + if (status == VMThreadManager.TM_ERROR_INTERRUPT) { + throw new InterruptedException(); + } else if (status != VMThreadManager.TM_ERROR_NONE) { + throw new InternalError( + "Thread Manager internal error " + status); + } } /** * @com.intel.drl.spec_ref */ public static void yield() { - VMThreadManager.yield(); + int status = VMThreadManager.yield(); + if (status != VMThreadManager.TM_ERROR_NONE) { + throw new InternalError( + "Thread Manager internal error " + status); + } } /** @@ -465,7 +498,11 @@ public void interrupt() { synchronized (lock) { checkAccess(); - VMThreadManager.interrupt(this); + int status = VMThreadManager.interrupt(this); + if (status != VMThreadManager.TM_ERROR_NONE) { + throw new InternalError( + "Thread Manager internal error " + status); + } } } @@ -474,25 +511,10 @@ */ public final boolean isAlive() { synchronized (lock) { - if (!started || group == null) { - return false; - } - return true; + return this.isAlive; } } - /** - * The method is called by VM implementation after run() so that Thread - * could make some cleanup. Thread removes itself from ThreadGroup. It - * automatically means that thread is not alive anymore. - */ - void kill() { - synchronized (lock) { - // will set group = null. - group.remove(this); - lock.notifyAll(); - } - } /** * @com.intel.drl.spec_ref @@ -567,7 +589,11 @@ public final void resume() { synchronized (lock) { checkAccess(); - VMThreadManager.resume(this); + int status = VMThreadManager.resume(this); + if (status != VMThreadManager.TM_ERROR_NONE) { + throw new InternalError( + "Thread Manager internal error " + status); + } } } @@ -629,7 +655,11 @@ ThreadGroup threadGroup = group; this.priority = (priority > threadGroup.maxPriority) ? threadGroup.maxPriority : priority; - VMThreadManager.setPriority(this, this.priority); + int status = VMThreadManager.setPriority(this, this.priority); + if (status != VMThreadManager.TM_ERROR_NONE) { + // throw new InternalError( + // "Thread Manager internal error " + status); + } } /** @@ -642,11 +672,37 @@ throw new IllegalThreadStateException( "This thread was already started!"); } + + this.isAlive = true; + + if (VMThreadManager.start(this, stackSize, daemon, priority) != 0) { + throw new OutOfMemoryError("Failed to create new thread"); + } + started = true; - VMThreadManager.start(this, stackSize); } } + /* + * This method serves as a wrapper around Thread.run() method to meet + * specification requirements in regard to ucaught exception catching. + */ + void runImpl() { + try { + run(); + } catch (Throwable e) { + getUncaughtExceptionHandler().uncaughtException(this, e); + } finally { + group.remove(this); + synchronized(lock) { + this.isAlive = false; + lock.notifyAll(); + } + } + } + + + // for 5.0 /* public enum State { NEW, @@ -687,7 +743,11 @@ .checkPermission(RuntimePermissionCollection.STOP_THREAD_PERMISSION); } } - VMThreadManager.stop(this, throwable); + int status = VMThreadManager.stop(this, throwable); + if (status != VMThreadManager.TM_ERROR_NONE) { + throw new InternalError( + "Thread Manager internal error " + status); + } } } @@ -697,7 +757,11 @@ public final void suspend() { synchronized (lock) { checkAccess(); - VMThreadManager.suspend(this); + int status = VMThreadManager.suspend(this); + if (status != VMThreadManager.TM_ERROR_NONE) { + throw new InternalError( + "Thread Manager internal error " + status); + } } } @@ -835,4 +899,25 @@ */ void uncaughtException(Thread t, Throwable e); } + + /* + * Number of threads that was created w/o garbage collection. + */ + private static int currentGCWatermarkCount = 0; + + /* + * Max number of threads to be created w/o GC, required collect dead Thread + * references. + */ + private static final int GC_WATERMARK_MAX_COUNT = 700; + + /* + * Checks if more then GC_WATERMARK_MAX_COUNT threads was created and calls + * System.gc() to ensure that dead thread references was callected. + */ + private void checkGCWatermark() { + if (++currentGCWatermarkCount % GC_WATERMARK_MAX_COUNT == 0) { + System.gc(); + } + } } Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/Runtime.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/Runtime.java (revision 430048) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/Runtime.java (working copy) @@ -104,9 +104,9 @@ // In the first phase all registered shutdown hooks, if any, are started in some // unspecified order and allowed to run concurrently until they finish. synchronized (Synchro.class) { + try { if (VMState == 0) { VMState = 1; - if (hooksList != null) { for (int i = 0; i < hooksList.size(); i++) { ((Thread)hooksList.elementAt(i)).start(); @@ -126,7 +126,7 @@ hooksList.removeAllElements(); } } - + } catch (Throwable e) {} // skip any exceptions in shutdown sequence } // #2: Index: vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java (revision 430048) +++ vm/vmcore/src/kernel_classes/javasrc/java/lang/ThreadGroup.java (working copy) @@ -100,7 +100,7 @@ */ ThreadGroup() { this.parent = null; - this.name = "main"; + this.name = "System"; this.daemon = false; } @@ -119,11 +119,13 @@ threadsCopy = copyThreads(); groupsListCopy = (List)groups.clone(); } + for (int i = 0; i < threadsCopy.length; i++) { if (((Thread) threadsCopy[i]).isAlive()) { count++; } } + for (Iterator it = groupsListCopy.iterator(); it.hasNext();) { count += ((ThreadGroup)it.next()).activeCount(); } Index: vm/vmcore/src/exception/exceptions.cpp =================================================================== --- vm/vmcore/src/exception/exceptions.cpp (revision 430048) +++ vm/vmcore/src/exception/exceptions.cpp (working copy) @@ -29,8 +29,8 @@ #include "m2n.h" #include "object_handles.h" #include "vm_strings.h" -#include "open/thread.h" + // internal declaration of functions void __stdcall set_current_thread_exception_internal(ManagedObject * exn); @@ -48,7 +48,7 @@ void exn_throw_only(jthrowable exc) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // Temporary fix of incorrect using of throw_by name in the interpreter if (interpreter_enabled()) { exn_raise_only(exc); @@ -140,7 +140,7 @@ static jthrowable create_exception(const char *exception_name) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *exc_clss = get_class(exception_name); if (exc_clss == NULL) { assert(exn_raised()); @@ -165,7 +165,7 @@ static jthrowable create_exception(const char *exception_name, jthrowable cause) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *exc_clss = get_class(exception_name); if (exc_clss == NULL) { assert(exn_raised()); @@ -202,7 +202,7 @@ jthrowable cause, const char *message) { // XXX salikh: change to unconditional thread_disable_suspend() - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *exc_clss = get_class(exception_name); if (exc_clss == NULL) { @@ -293,7 +293,7 @@ void exn_throw_by_name(const char *exception_name) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jthrowable exc = create_exception(exception_name); tmn_suspend_disable(); exn_throw_only(exc); @@ -303,7 +303,7 @@ void exn_throw_by_name(const char *exception_name, const char *message) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jthrowable exc = create_exception(exception_name, NULL, message); tmn_suspend_disable(); exn_throw_only(exc); @@ -484,7 +484,7 @@ void __stdcall set_current_thread_exception_internal(ManagedObject * exn) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); p_TLS_vmthread->p_exception_object = (volatile ManagedObject *) exn; p_TLS_vmthread->ti_exception_callback_pending = true; } @@ -508,7 +508,7 @@ // function should be only called from suspend disabled mode // it changes enumeratable reference to zero which is not // gc safe operation. - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); p_TLS_vmthread->p_exception_object = NULL; if (p_TLS_vmthread->restore_guard_page) { @@ -563,7 +563,7 @@ // prints stackTrace via jni inline void exn_jni_print_stack_trace(FILE * f, jthrowable exc) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // finds java environment JNIEnv_Internal *jenv = jni_native_intf; @@ -698,7 +698,7 @@ } } - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); } inline void exn_native_print_stack_trace(FILE * f, ManagedObject * exn) @@ -738,7 +738,7 @@ // prints stack trace using 3 ways: via java, via jni, and native void exn_print_stack_trace(FILE * f, ManagedObject * exn) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // saves curent thread exception and clear to allow java to work Java_java_lang_Throwable *cte = get_current_thread_exception(); jthrowable j = oh_allocate_local_handle(); @@ -798,7 +798,7 @@ void print_uncaught_exception_message(FILE * f, char *context_message, ManagedObject * exn) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); fprintf(f, "** During %s uncaught exception: %s\n", context_message, exn->vt()->clss->name->bytes); exn_print_stack_trace(f, exn); @@ -811,9 +811,9 @@ static ManagedObject *create_lazy_exception(StackIterator * UNREF throw_si, Class_Handle exn_class, Method_Handle exn_constr, uint8 * exn_constr_args) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); volatile ManagedObject *exn_obj = 0; - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); exn_obj = class_alloc_new_object_and_run_constructor((Class *) exn_class, (Method *) exn_constr, exn_constr_args); @@ -839,7 +839,7 @@ ManagedObject ** exn_obj, Class_Handle exn_class, Method_Handle exn_constr, uint8 * exn_constr_args) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); ASSERT_NO_INTERPRETER assert(*exn_obj || exn_class); // Save the throw context @@ -940,7 +940,8 @@ // No appropriate handler found, undo synchronization if (method->is_synchronized()) { if (method->is_static()) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); + TRACE2("tm.locks", ("unlock staic sync methods... %x", exn_obj)); vm_monitor_exit(struct_Class_to_java_lang_Class(method-> get_class())); } @@ -948,6 +949,7 @@ void **p_this = (void **) jit->get_address_of_this(method, si_get_jit_context(si)); + TRACE2("tm.locks", ("unlock sync methods...%x" , *p_this)); vm_monitor_exit((ManagedObject *) * p_this); } } @@ -969,7 +971,7 @@ create_lazy_exception(throw_si, exn_class, exn_constr, exn_constr_args); } - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); CodeChunkInfo *catch_cci = si_get_code_chunk_info(si); Method *catch_method = NULL; @@ -1025,7 +1027,7 @@ * !!!! RELEASE BUILD WILL BE BROKEN !!! * !!!! NO TRACE2, INFO, WARN, ECHO, ASSERT, ... */ - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); //TRACE2("exn","exn_athrow"); ASSERT_NO_INTERPRETER if ((exn_obj == NULL) && (exn_class == NULL)) { Global_Env *env = VM_Global_State::loader_env; @@ -1240,7 +1242,7 @@ // Return the type of negative array size exception Class_Handle exn_get_negative_array_size_exception_type() { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *exn_clss; @@ -1277,6 +1279,45 @@ } //exn_get_rth_throw_negative_array_size +// Return the type of illegal state exception +Class_Handle exn_get_illegal_state_exception_type() +{ + assert(hythread_is_suspend_enabled()); + Class *exn_clss; + + + Global_Env *env = VM_Global_State::loader_env; + String *exc_str = + env->string_pool.lookup("java/lang/IllegalMonitorStateException"); + exn_clss = + env->bootstrap_class_loader->LoadVerifyAndPrepareClass(env, exc_str); + assert(exn_clss); + + return exn_clss; +} + +// rth_throw_negative_array_size throws a negative array size exception (lazily) +NativeCodePtr exn_get_rth_throw_illegal_state_exception() +{ + static NativeCodePtr addr = NULL; + if (addr) { + return addr; + } + + LilCodeStub *cs = lil_parse_code_stub("entry 0:managed::void;" + "std_places 1;" "sp0=%0i;" "tailcall %1i;", + exn_get_illegal_state_exception_type(), + lil_npc_to_fp(exn_get_rth_throw_lazy_trampoline())); + assert(lil_is_valid(cs)); + addr = + LilCodeGenerator::get_platform()->compile(cs, + "rth_throw_illegal_state_exception", dump_stubs); + lil_free_code_stub(cs); + + return addr; +} //exn_get_rth_throw_illegal_state_exception + + // rth_throw_array_store throws an array store exception (lazily) NativeCodePtr exn_get_rth_throw_array_store() { @@ -1326,7 +1367,7 @@ // Return the type of class cast exception Class_Handle exn_get_class_cast_exception_type() { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *exn_clss; Global_Env *env = VM_Global_State::loader_env; @@ -1362,7 +1403,7 @@ // Return the type of incompatible class change exception Class_Handle exn_get_incompatible_class_change_exception_type() { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *exn_clss; Global_Env *env = VM_Global_State::loader_env; Index: vm/vmcore/src/class_support/Prepare.cpp =================================================================== --- vm/vmcore/src/class_support/Prepare.cpp (revision 430048) +++ vm/vmcore/src/class_support/Prepare.cpp (working copy) @@ -36,7 +36,6 @@ #include "compile.h" #include "interpreter_exports.h" #include "interpreter.h" -#include "open/thread.h" #include "lil.h" #include "lil_code_generator.h" @@ -1393,7 +1392,7 @@ if(!env->InBootstrap()) { autoUnlocker.ForceUnlock(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (init_fields) { jvmti_send_class_prepare_event(clss); } @@ -1607,7 +1606,7 @@ if (!assign_values_to_class_static_final_fields(clss)) { //OOME happened - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return false; } @@ -1640,7 +1639,7 @@ if(!env->InBootstrap()) { autoUnlocker.ForceUnlock(); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jvmti_send_class_prepare_event(clss); } TRACE2("classloader.prepare", "END class prepare, class name = " << clss->name->bytes); Index: vm/vmcore/src/class_support/String_Pool.cpp =================================================================== --- vm/vmcore/src/class_support/String_Pool.cpp (revision 430048) +++ vm/vmcore/src/class_support/String_Pool.cpp (working copy) @@ -46,7 +46,7 @@ // Spin until lock is m_free. while (apr_atomic_casptr( (volatile void **)&string_pool_lock, (void *)1, (void *)0) != 0) { - Sleep (0); + hythread_yield(); } } Index: vm/vmcore/src/class_support/Initialize.cpp =================================================================== --- vm/vmcore/src/class_support/Initialize.cpp (revision 430048) +++ vm/vmcore/src/class_support/Initialize.cpp (working copy) @@ -22,22 +22,21 @@ #include "cxxlog.h" #include "Class.h" -#include "open/thread.h" -#include "mon_enter_exit.h" +#include "open/jthread.h" #include "exceptions.h" #include "thread_manager.h" #include "Verifier_stub.h" #include "vm_strings.h" #include "classloader.h" #include "ini.h" +#include "vm_threads.h" - // Initializes a class. static void class_initialize1(Class *clss) { assert(!exn_raised()); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // the following code implements the 11-step class initialization program // described in page 226, section 12.4.2 of Java Language Spec, 1996 @@ -47,38 +46,21 @@ // --- step 1 ---------------------------------------------------------- - assert(!tmn_is_suspend_enabled()); - vm_monitor_enter_slow(struct_Class_to_java_lang_Class(clss)); + assert(!hythread_is_suspend_enabled()); + jobject jlc = struct_Class_to_java_lang_Class_Handle(clss); + jthread_monitor_enter(jlc); -#ifdef _DEBUG - if (clss->p_initializing_thread){ - tmn_suspend_enable(); - tm_iterator_t * iterator = tm_iterator_create(); - tmn_suspend_disable(); - volatile VM_thread *p_scan = tm_iterator_next(iterator); - while (p_scan) { - if (p_scan == (VM_thread *)clss->p_initializing_thread) break; - p_scan = tm_iterator_next(iterator); - } - tm_iterator_release(iterator); - assert(p_scan); // make sure p_initializer_thread is legit - } -#endif - // --- step 2 ---------------------------------------------------------- TRACE2("class.init", "initializing class " << clss->name->bytes << " STEP 2" ); - jobject jlc = struct_Class_to_java_lang_Class_Handle(clss); while(((VM_thread *)(clss->p_initializing_thread) != p_TLS_vmthread) && (clss->state == ST_Initializing) ) { // thread_object_wait had been expecting the only unsafe reference // to be its parameter, so enable_gc() should be safe here -salikh - tmn_suspend_enable(); - thread_object_wait(jlc, 0); - tmn_suspend_disable(); + jthread_monitor_wait(jlc); jthrowable exc = exn_get(); if (exc) { - vm_monitor_exit(struct_Class_to_java_lang_Class(clss)); + jthread_monitor_exit(jlc); return; } } @@ -86,26 +68,27 @@ // --- step 3 ---------------------------------------------------------- if ( (VM_thread *)(clss->p_initializing_thread) == p_TLS_vmthread) { - vm_monitor_exit(struct_Class_to_java_lang_Class(clss)); + jthread_monitor_exit(jlc); return; } // --- step 4 ---------------------------------------------------------- if (clss->state == ST_Initialized) { - vm_monitor_exit(struct_Class_to_java_lang_Class(clss)); + jthread_monitor_exit(jlc); return; } // --- step 5 ---------------------------------------------------------- if (clss->state == ST_Error) { - vm_monitor_exit(struct_Class_to_java_lang_Class(clss)); + jthread_monitor_exit(jlc); tmn_suspend_enable(); jthrowable exn = exn_create("java/lang/NoClassDefFoundError", clss->name->bytes); tmn_suspend_disable(); exn_raise_only(exn); + return; } @@ -116,7 +99,7 @@ clss->state = ST_Initializing; assert(clss->p_initializing_thread == 0); clss->p_initializing_thread = (void *)p_TLS_vmthread; - vm_monitor_exit(struct_Class_to_java_lang_Class(clss)); + jthread_monitor_exit(jlc); // --- step 7 ------------------------------------------------------------ @@ -124,15 +107,16 @@ class_initialize_ex(clss->super_class); if (clss->super_class->state == ST_Error) { - vm_monitor_enter_slow(struct_Class_to_java_lang_Class(clss)); + jthread_monitor_enter(jlc); tmn_suspend_enable(); REPORT_FAILED_CLASS_CLASS_EXN(clss->class_loader, clss, class_get_error_cause(clss->super_class)); tmn_suspend_disable(); clss->p_initializing_thread = 0; - assert(!tmn_is_suspend_enabled()); - thread_object_notify_all(struct_Class_to_java_lang_Class_Handle(clss)); - vm_monitor_exit(struct_Class_to_java_lang_Class(clss)); + clss->state = ST_Error; + assert(!hythread_is_suspend_enabled()); + jthread_monitor_notify_all(jlc); + jthread_monitor_exit(jlc); return; } } @@ -183,22 +167,20 @@ Method *meth = clss->static_initializer; if (meth == NULL) { - vm_monitor_enter_slow(struct_Class_to_java_lang_Class(clss)); + jthread_monitor_enter(jlc); clss->state = ST_Initialized; TRACE2("classloader", "class " << clss->name->bytes << " initialized"); clss->p_initializing_thread = 0; - assert(!tmn_is_suspend_enabled()); - thread_object_notify_all (struct_Class_to_java_lang_Class_Handle(clss)); - vm_monitor_exit(struct_Class_to_java_lang_Class(clss)); + assert(!hythread_is_suspend_enabled()); + jthread_monitor_notify_all(jlc); + jthread_monitor_exit(jlc); return; } TRACE2("class.init", "initializing class " << clss->name->bytes << " STEP 8" ); jthrowable p_error_object; - int tmn_suspend_disable_count(); - assert(tmn_suspend_disable_count()==1); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); vm_execute_java_method_array((jmethodID) meth, 0, 0); p_error_object = exn_get(); @@ -206,30 +188,30 @@ TRACE2("class.init", "initializing class " << clss->name->bytes << " STEP 9" ); if(!p_error_object) { - vm_monitor_enter_slow(struct_Class_to_java_lang_Class(clss)); + jthread_monitor_enter(jlc); clss->state = ST_Initialized; TRACE2("classloader", "class " << clss->name->bytes << " initialized"); clss->p_initializing_thread = 0; assert(clss->p_error == 0); - assert(!tmn_is_suspend_enabled()); - thread_object_notify_all (struct_Class_to_java_lang_Class_Handle(clss)); - vm_monitor_exit(struct_Class_to_java_lang_Class(clss)); + assert(!hythread_is_suspend_enabled()); + jthread_monitor_notify_all(jlc); + jthread_monitor_exit(jlc); return; } // --- step 10 ---------------------------------------------------------- if(p_error_object) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); clear_current_thread_exception(); Class *p_error_class = p_error_object->object->vt()->clss; Class *jle = VM_Global_State::loader_env->java_lang_Error_Class; while(p_error_class && p_error_class != jle) { p_error_class = p_error_class->super_class; } - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); if((!p_error_class) || (p_error_class != jle) ) { -#ifdef _DEBUG +#ifdef _DEBUG_REMOVED Class* eiie = VM_Global_State::loader_env->java_lang_ExceptionInInitializerError_Class; assert(eiie); #endif @@ -245,13 +227,13 @@ tmn_suspend_disable(); // --- step 11 ---------------------------------------------------------- - assert(!tmn_is_suspend_enabled()); - vm_monitor_enter_slow(struct_Class_to_java_lang_Class(clss)); + assert(!hythread_is_suspend_enabled()); + jthread_monitor_enter(jlc); clss->state = ST_Error; clss->p_initializing_thread = 0; - assert(!tmn_is_suspend_enabled()); - thread_object_notify_all(struct_Class_to_java_lang_Class_Handle(clss)); - vm_monitor_exit(struct_Class_to_java_lang_Class(clss)); + assert(!hythread_is_suspend_enabled()); + jthread_monitor_notify_all(jlc); + jthread_monitor_exit(jlc); exn_raise_only(p_error_object); } // end of 11 step class initialization program @@ -265,7 +247,7 @@ #endif void class_initialize_from_jni(Class *clss) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // check verifier constraints if(!class_verify_constraints(VM_Global_State::loader_env, clss)) { @@ -297,7 +279,7 @@ void class_initialize_ex(Class *clss) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // check verifier constraints tmn_suspend_enable(); Index: vm/vmcore/src/class_support/C_Interface.cpp =================================================================== --- vm/vmcore/src/class_support/C_Interface.cpp (revision 430048) +++ vm/vmcore/src/class_support/C_Interface.cpp (working copy) @@ -28,7 +28,8 @@ #include "vm_arrays.h" #include "vm_strings.h" #include "properties.h" -#include "open/thread.h" + +#include "open/hythread_ext.h" #include "thread_manager.h" #include "Verifier_stub.h" @@ -995,7 +996,7 @@ Class_Handle class_find_class_from_loader(ClassLoaderHandle loader, const char* n, Boolean init) { - assert(tmn_is_suspend_enabled()); // -salikh + assert(hythread_is_suspend_enabled()); // -salikh char *new_name = strdup(n); char *p = new_name; while (*p) { @@ -1009,7 +1010,7 @@ ch = class_load_verify_prepare_by_loader_jni( VM_Global_State::loader_env, name, loader); } else { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); ch = class_load_verify_prepare_from_jni(VM_Global_State::loader_env, name); } if (!ch) return NULL; @@ -1181,7 +1182,7 @@ Class_Handle method_get_throws(Method_Handle mh, unsigned idx) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(mh); Method* m = (Method*)mh; String* exn_name = m->get_exception_name(idx); @@ -1758,7 +1759,7 @@ // -gc magic needs this to do the recursive load. Class_Handle field_get_class_of_field_value(Field_Handle fh) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(fh); Class_Handle ch = class_load_class_by_descriptor(field_get_descriptor(fh), field_get_class(fh)); @@ -2291,7 +2292,7 @@ void vm_gc_lock_enum() { tmn_suspend_enable(); - tm_acquire_tm_lock(); + hythread_global_lock(); tmn_suspend_disable(); } // vm_gc_lock_enum @@ -2299,7 +2300,7 @@ void vm_gc_unlock_enum() { - tm_release_tm_lock(); + hythread_global_unlock(); } // vm_gc_unlock_enum @@ -2481,40 +2482,12 @@ // patches done by JIT on IPF: it replaces the branch offset in a single bundle containing // a branch long. Note that this function does not synchronize the I- or D-caches. - bool gc_enabled = false; - if ((p_TLS_vmthread != NULL) && !tmn_is_suspend_enabled()) { - tmn_suspend_enable(); - gc_enabled = true; - } - tm_acquire_tm_lock(); - if (gc_enabled) { - tmn_suspend_disable(); - } - // Run through list of active threads and suspend the other ones. - tm_iterator_t * iterator = tm_iterator_create(); - VM_thread *thread = tm_iterator_next(iterator); - while (thread != NULL) { - if (thread != p_TLS_vmthread) { - SUSPEND_THREAD(thread); - } - thread = tm_iterator_next(iterator); - } - + hythread_suspend_all(NULL, NULL); patch_code_with_threads_suspended(code_block, new_code, size); - // Resume each of the other threads. - tm_iterator_reset(iterator); - thread = tm_iterator_next(iterator); - while (thread != NULL) { - if (thread != p_TLS_vmthread) { - RESUME_THREAD(thread); - } - thread = tm_iterator_next(iterator); - } - tm_iterator_release(iterator); + hythread_resume_all(NULL); - tm_release_tm_lock(); } //vm_patch_code_block @@ -2663,5 +2636,7 @@ } //vm_managed_calling_convention unsigned thread_get_suspend_request_offset() { - return APR_OFFSETOF(VM_thread, suspend_request); + //FIXME: + //return APR_OFFSETOF(VM_thread, suspend_request); + return 0; } Index: vm/vmcore/src/class_support/Environment.cpp =================================================================== --- vm/vmcore/src/class_support/Environment.cpp (revision 430048) +++ vm/vmcore/src/class_support/Environment.cpp (working copy) @@ -22,11 +22,12 @@ #include "cxxlog.h" #include "environment.h" +#include "Package.h" #include "String_Pool.h" #include "Class.h" #include "nogc.h" #include "GlobalClassLoaderIterator.h" -#include "open/thread.h" + #include "verifier.h" #include "native_overrides.h" @@ -151,6 +152,7 @@ tmn_suspend_disable(); GlobalClassLoaderIterator ClIterator; ClassLoader *cl = ClIterator.first(); + while(cl) { ClassLoader* cltmp = cl; cl = ClIterator.next(); Index: vm/vmcore/src/class_support/Class.cpp =================================================================== --- vm/vmcore/src/class_support/Class.cpp (revision 430048) +++ vm/vmcore/src/class_support/Class.cpp (working copy) @@ -316,7 +316,7 @@ // ManagedObject *struct_Class_to_java_lang_Class(Class *clss) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(clss); ManagedObject** hjlc = clss->class_handle; assert(hjlc); @@ -369,7 +369,7 @@ */ jclass struct_Class_to_jclass(Class *c) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); // ------------------------vvv ObjectHandle h = oh_allocate_local_handle(); h->object = struct_Class_to_java_lang_Class(c); @@ -400,7 +400,7 @@ // Given a class instance, find its corresponding struct Class. Class *java_lang_Class_to_struct_Class(ManagedObject *jlc) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(jlc != NULL); assert(jlc->vt()); assert(jlc->vt()->clss == VM_Global_State::loader_env->JavaLangClass_Class); @@ -432,7 +432,7 @@ void class_report_failure(Class* target, uint16 cp_index, jthrowable exn) { assert(cp_index > 0 && cp_index < target->cp_size); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if (exn_raised()) { TRACE2("classloader.error", "runtime exception in classloading"); return; Index: vm/vmcore/src/class_support/Resolve.cpp =================================================================== --- vm/vmcore/src/class_support/Resolve.cpp (revision 430048) +++ vm/vmcore/src/class_support/Resolve.cpp (working copy) @@ -104,8 +104,8 @@ #include "open/bytecodes.h" #include "open/vm_util.h" -#include "open/thread.h" + #define CLASS_REPORT_FAILURE(target, cp_index, exnclass, exnmsg) \ { \ std::stringstream ss; \ @@ -132,7 +132,7 @@ Class *clss, unsigned cp_index) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Const_Pool *cp = clss->const_pool; clss->m_lock->_lock(); Index: vm/vmcore/src/class_support/method.cpp =================================================================== --- vm/vmcore/src/class_support/method.cpp (revision 430048) +++ vm/vmcore/src/class_support/method.cpp (working copy) @@ -21,7 +21,7 @@ #define LOG_DOMAIN "vm.core" #include "cxxlog.h" -#include "open/thread.h" + #include "Class.h" #include "classloader.h" #include "environment.h" @@ -118,7 +118,7 @@ Class_Handle method_get_return_type_class(Method_Handle m) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Method *method = (Method *)m; Global_Env *env = VM_Global_State::loader_env; Java_Type UNUSED t = method->get_return_java_type(); Index: vm/vmcore/src/class_support/Class_File_Loader.cpp =================================================================== --- vm/vmcore/src/class_support/Class_File_Loader.cpp (revision 430048) +++ vm/vmcore/src/class_support/Class_File_Loader.cpp (working copy) @@ -30,7 +30,6 @@ #include "Class.h" #include "vm_strings.h" #include "open/vm_util.h" -#include "open/thread.h" #include "bytereader.h" #include "compile.h" #include "jit_intf_cpp.h" @@ -2175,7 +2174,7 @@ const String* classname, ClassLoader* cl) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); // if no class loader passed, re-route to bootstrap if(!cl) cl = env->bootstrap_class_loader; Class* clss = cl->LoadVerifyAndPrepareClass(env, classname); @@ -2185,7 +2184,7 @@ Class *class_load_verify_prepare_from_jni(Global_Env *env, const String *classname) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class *clss = env->bootstrap_class_loader->LoadVerifyAndPrepareClass(env, classname); return clss; } Index: vm/vmcore/src/class_support/classloader.cpp =================================================================== --- vm/vmcore/src/class_support/classloader.cpp (revision 430048) +++ vm/vmcore/src/class_support/classloader.cpp (working copy) @@ -38,7 +38,7 @@ #include "jvmti_internal.h" #include "ini.h" #include "open/gc.h" -#include "open/thread.h" +#include "open/hythread_ext.h" #include "open/vm_util.h" #include "suspend_checker.h" #include "verifier.h" @@ -157,18 +157,6 @@ delete m_package_table; } -bool ClassLoader::LoadingClass::CreateWaitingEvent(const String* className) -{ - if(m_loadWaitEvent == 0) - m_loadWaitEvent = vm_create_event(NULL, TRUE, FALSE, NULL); - if(m_loadWaitEvent == 0) { - DIE2("classloader", "Event creation failed for class " << className->bytes - << ", which is loaded concurrently"); - return false; - } - return true; -} - void ClassLoader::LoadingClass::EnqueueInitiator(VM_thread* new_definer, ClassLoader* cl, const String* clsname) { if(!IsInitiator(new_definer)) { @@ -392,7 +380,7 @@ Class* ClassLoader::LoadVerifyAndPrepareClass(Global_Env* env, const String* name) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class* clss = LoadClass(env, name); if(!clss) return NULL; @@ -804,11 +792,6 @@ // avoid preliminary removal of LoadingClass loading->AddWaitingThread(cur_thread, this, className); // lazy wait event creation - if(!loading->CreateWaitingEvent(className)) { - // should never get here - DIE("Event creation failure was not reported: should never get here!"); - return NULL; - } aulock.ForceUnlock(); // only wait for class loading if we are in bootstrap class loader loading->WaitLoading(); @@ -894,12 +877,6 @@ // defining thread should not get here assert(!loading->IsDefiner(cur_thread)); assert(loading->AlreadyWaiting(cur_thread)); - // lazy wait event creation - if(!loading->CreateWaitingEvent(className)) { - // should never get here - DIE("Event creation failure was not reported: should never get here!"); - return NULL; - } m_lock._unlock(); TRACE2("classloader.collisions", this << " " << cur_thread << " WAITING " << className->bytes); // wait class loading @@ -1663,7 +1640,7 @@ // wgs's comment here: // * (Ljava/lang/String;Z) is not abstract in current JDK version // * Generally (Ljava/lang/String;) are overloaded - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert(!exn_raised()); tmn_suspend_disable(); @@ -1932,7 +1909,7 @@ VMEXPORT GenericFunctionPointer classloader_find_native(const Method_Handle method) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); assert( !exn_raised() ); // get class and class loader of a given method Index: vm/vmcore/src/init/finalize.cpp =================================================================== --- vm/vmcore/src/init/finalize.cpp (revision 430048) +++ vm/vmcore/src/init/finalize.cpp (working copy) @@ -36,8 +36,8 @@ #include "jit_runtime_support.h" #include "vm_synch.h" #include "finalize.h" -#include "open/thread.h" + #define LOG_DOMAIN "vm.object_queue" #include "classloader.h" #undef LOG_DOMAIN @@ -75,7 +75,7 @@ // weak/soft/phantom references. // -VmEventHandle begin_run_finalizer; +hylatch_t begin_run_finalizer; class Object_Queue { @@ -149,6 +149,7 @@ * Allocates array to save objects. Should be called from synchronized block. * Now it's called from add_object only. */ + void Object_Queue::reallocate(unsigned new_capacity) { ManagedObject **new_table = @@ -261,7 +262,7 @@ // workaround method to ignore classes java.nio.charset.CharsetEncoder // java.io.FileDescriptor & java.io.FileOutputStream during finalization on exit bool Objects_To_Finalize::is_class_ignored(Class* test) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); if (!classes_cached) { @@ -299,7 +300,7 @@ void Objects_To_Finalize::run_finalizers() { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); Class* finalizer_thread = VM_Global_State::loader_env->finalizer_thread; @@ -468,13 +469,13 @@ void vm_run_pending_finalizers() { NativeObjectHandles nhs; - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); objects_to_finalize.run_finalizers(); } //vm_run_pending_finalizers int vm_do_finalization(int quantity) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); return objects_to_finalize.do_finalization(quantity); } //vm_run_pending_finalizers Index: vm/vmcore/src/init/vm.cpp =================================================================== --- vm/vmcore/src/init/vm.cpp (revision 430048) +++ vm/vmcore/src/init/vm.cpp (working copy) @@ -46,7 +46,9 @@ #include "nogc.h" #include "object_generic.h" -#include "open/thread.h" + +#include "open/hythread_ext.h" +#include "open/jthread.h" #include "component_manager.h" #include "lock_manager.h" #include "root_set_enum_internal.h" @@ -207,10 +209,8 @@ { // Send VM_Death event and switch phase to VM_Death jvmti_send_vm_death_event(); -void terminate_all_threads(); if (vm_get_boolean_property_value_with_default("vm.cleanupOnExit")) - terminate_all_threads(); - + jthread_cancel_all(); /* FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME * * gregory - JVMTI shutdown should be part of DestroyVM after current VM shutdown * * problems are fixed * Index: vm/vmcore/src/init/vm_init.cpp =================================================================== --- vm/vmcore/src/init/vm_init.cpp (revision 430048) +++ vm/vmcore/src/init/vm_init.cpp (working copy) @@ -39,8 +39,7 @@ p_jit_a_method_lock = new Lock_Manager(); p_vtable_patch_lock = new Lock_Manager(); p_meth_addr_table_lock = new Lock_Manager(); - p_thread_lock = new Lock_Manager(); - p_tm_lock = new Lock_Manager(); + p_handle_lock = new Lock_Manager(); // 20040224 Support for recording which methods (actually, CodeChunkInfo's) call which other methods. p_method_call_lock = new Lock_Manager(); @@ -51,8 +50,7 @@ delete p_jit_a_method_lock; delete p_vtable_patch_lock; delete p_meth_addr_table_lock; - delete p_thread_lock; - delete p_tm_lock; + delete p_handle_lock; delete p_method_call_lock; } //vm_uninitialize_critical_sections @@ -127,7 +125,7 @@ static void bootstrap_initial_java_classes(Global_Env *env) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); TRACE2("init", "bootstrapping initial java classes"); /* @@ -203,21 +201,19 @@ return true; } //initialize_system_class_loader +static bool init_thread_object(JNIEnv *); bool vm_init(Global_Env *env) { if(vm_is_initialized) return false; - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); vm_is_initialized = true; TRACE2("init","Initializing VM"); vm_monitor_init(); - vm_thread_init(env); - active_thread_count = 1; - env->bootstrap_class_loader = new BootstrapClassLoader(env); // !!! use proper MM env->bootstrap_class_loader->Initialize(); @@ -326,7 +322,7 @@ Method *m = class_lookup_method(env->java_lang_Throwable_Class, env->Init_String, env->VoidVoidDescriptor_String); assert(m); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); m->set_side_effects(MSE_False); m = class_lookup_method(env->java_lang_Throwable_Class, @@ -354,13 +350,12 @@ env->ReadyForExceptions(); TRACE2("init", "initializing thread group"); - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); - bool init_threadgroup(); - if (! init_threadgroup()) + JNIEnv *jni_env = (JNIEnv *)jni_native_intf; + if (! init_thread_object(jni_env)) return false; - JNIEnv *jni_env = (JNIEnv *)jni_native_intf; TRACE2("init", "Invoking the java.lang.Class constructor"); Class *jlc = env->JavaLangClass_Class; @@ -442,3 +437,42 @@ return true; } //vm_init + +static bool init_thread_object(JNIEnv *jenv) +{ + Global_Env *env = VM_Global_State::loader_env; + + assert(hythread_is_suspend_enabled()); + + // Load, prepare and initialize the "Thread class" + String *ss = env->string_pool.lookup("java/lang/VMStart"); + Class *thread_clss = env->bootstrap_class_loader->LoadVerifyAndPrepareClass(env, ss); + assert(thread_clss); + assert(hythread_is_suspend_enabled()); + tmn_suspend_disable(); + class_initialize(thread_clss); + assert(!hythread_is_suspend_enabled()); + + ObjectHandle jThreadClass = oh_allocate_local_handle(); + jThreadClass->object = struct_Class_to_java_lang_Class(thread_clss); + tmn_suspend_enable(); + + jmethodID main_method = jenv->GetStaticMethodID(jThreadClass, "mainThreadInit", "()V"); + if (ExceptionOccurred(jenv) || !main_method) { + WARN("*** Error: exception occured in main Thread constructor."); + ExceptionDescribe(jenv); + ExceptionClear(jenv); + return false; + } + + jenv->CallStaticVoidMethod(jThreadClass, main_method); + + if (ExceptionOccurred(jenv)) { + WARN("*** Error: exception occured in main Thread constructor."); + ExceptionDescribe(jenv); + ExceptionClear(jenv); + return false; + } + + return true; +} //init_thread_object Index: vm/vmcore/src/init/vm_main.cpp =================================================================== --- vm/vmcore/src/init/vm_main.cpp (revision 430048) +++ vm/vmcore/src/init/vm_main.cpp (working copy) @@ -23,6 +23,7 @@ #include "thread_generic.h" #include "open/vm_util.h" +#include "open/hythread_ext.h" #include "properties.h" #include #include "vm_synch.h" @@ -76,14 +77,19 @@ bool parallel_jit = true; +static bool begin_shutdown_hooks = false; + static M2nFrame* p_m2n = NULL; typedef union { ObjectHandlesOld old; ObjectHandlesNew nw; } HandlesUnion; + static HandlesUnion* p_handles = NULL; +hythread_library_t hythread_lib; + static void initialize_javahome(Global_Env* p_env) { PropertiesHandle ph = (PropertiesHandle)&p_env->properties; @@ -198,7 +204,7 @@ static int run_java_main(char *class_name, char **java_args, int java_args_num) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); JNIEnv* jenv = (JNIEnv*) jni_native_intf; @@ -241,7 +247,7 @@ static int run_java_init() { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); JNIEnv* jenv = (JNIEnv*) jni_native_intf; @@ -262,7 +268,7 @@ static int run_java_shutdown() { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); JNIEnv* jenv = (JNIEnv*) jni_native_intf; @@ -293,9 +299,8 @@ void create_vm(Global_Env *p_env, JavaVMInitArgs* vm_arguments) { -#ifdef PLATFORM_POSIX - init_linux_thread_system(); -#elif defined(PLATFORM_NT) + +#if defined(PLATFORM_NT) OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); BOOL ok = GetVersionEx(&osvi); @@ -312,24 +317,18 @@ exit(1); } #endif + hythread_init(hythread_lib); + vm_thread_init(&env); - - non_daemon_threads_dead_handle = vm_create_event( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - NULL // pointer to event-object name - ); - assert(non_daemon_threads_dead_handle); - VM_Global_State::loader_env = &env; - - tmn_thread_attach(); + hythread_attach(NULL); + // should be removed + vm_thread_attach(); MARK_STACK_END p_env->TI = new DebugUtilsTI; - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); vm_initialize_critical_sections(); initialize_vm_cmd_state(p_env, vm_arguments); //PASS vm_arguments to p_env->vm_arguments and free vm_arguments @@ -392,7 +391,7 @@ // Initialize memory allocation vm_init_mem_alloc(); gc_init(); - gc_thread_init(&p_TLS_vmthread->_gc_private_information); + // gc_thread_init(&p_TLS_vmthread->_gc_private_information); // Prepares to load natives bool UNREF status = natives_init(); @@ -456,10 +455,8 @@ } } - assert(p_TLS_vmthread->app_status == thread_is_birthing); - // create first m2n frame - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); p_m2n = (M2nFrame*) p_env->mem_pool.alloc(sizeof(M2nFrame)); p_handles = (HandlesUnion*) p_env->mem_pool.alloc(sizeof(HandlesUnion)); @@ -481,16 +478,7 @@ // Send VM init event jvmti_send_vm_init_event(p_env); - // Signal the GC that the VM is now completely - // initialized. Hence GC stop-the-world events - // can occur at any time, since the VM is now - // ready to enumerate live references when asked. - gc_vm_initialized(); - assert(p_TLS_vmthread->app_status == thread_is_birthing); - // Now, we set it to "running" just before entering user code. - p_TLS_vmthread->app_status = thread_is_running; - int result = run_java_init(); if (result != 0) @@ -553,7 +541,6 @@ void destroy_vm(Global_Env *p_env) { - assert(p_TLS_vmthread->app_status == thread_is_running); run_java_shutdown(); @@ -593,13 +580,14 @@ static inline void dump_all_java_stacks() { - tm_iterator_t * iterator = tm_iterator_create(); - VM_thread *thread = tm_iterator_next(iterator); + hythread_iterator_t iterator; + hythread_suspend_all(&iterator, NULL); + VM_thread *thread = get_vm_thread (hythread_iterator_next(&iterator)); while(thread) { interpreter.stack_dump(thread); - thread = tm_iterator_next(iterator); + thread = get_vm_thread (hythread_iterator_next(&iterator)); } - tm_iterator_release(iterator); + hythread_resume_all( NULL); INFO("****** END OF JAVA STACKS *****\n"); } @@ -618,7 +606,8 @@ } } -void interrupt_handler(int UNREF x) { +void interrupt_handler(int UNREF x) +{ if (VM_Global_State::loader_env->shutting_down != 0) { // too late for quit handler // required infrastructure can be missing. @@ -626,10 +615,10 @@ return; } - static bool begin_shutdown_hooks = false; if(!begin_shutdown_hooks){ begin_shutdown_hooks = true; - vm_set_event(non_daemon_threads_dead_handle); + //FIXME: integration should do int another way. + //vm_set_event(non_daemon_threads_dead_handle); }else exit(1); //vm_exit(1); } Index: vm/vmcore/src/stack/stack_trace.cpp =================================================================== --- vm/vmcore/src/stack/stack_trace.cpp (revision 430048) +++ vm/vmcore/src/stack/stack_trace.cpp (working copy) @@ -24,7 +24,7 @@ #include "stack_trace.h" #include "interpreter.h" #include "jit_intf_cpp.h" -#include "open/thread.h" + #include "method_lookup.h" Method_Handle get_method(StackIterator* si) Index: vm/vmcore/src/object/vm_arrays.cpp =================================================================== --- vm/vmcore/src/object/vm_arrays.cpp (revision 430048) +++ vm/vmcore/src/object/vm_arrays.cpp (working copy) @@ -33,7 +33,7 @@ #include "vm_arrays.h" #include "vm_synch.h" #include "open/vm_util.h" -#include "open/thread.h" + #include "vm_stats.h" @@ -78,7 +78,7 @@ #ifdef VM_STATS vm_stats_total.num_anewarray++; #endif - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(!arr_clss->is_array_of_primitives); if (length < 0) { @@ -128,7 +128,7 @@ VMEXPORT // temporary solution for interpreter unplug Vector_Handle vm_new_vector_primitive(Class *vector_class, int length) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // VM does not support arrays of length >= MAXINT>>2 if (length & TWO_HIGHEST_BITS_SET_MASK) { tmn_suspend_enable(); @@ -202,7 +202,7 @@ Vector_Handle vm_new_vector_using_vtable_and_thread_pointer(Allocation_Handle vector_handle, int length, void *tp) { - assert( ! tmn_is_suspend_enabled()); + assert( ! hythread_is_suspend_enabled()); // VM does not support arrays of length >= MAXINT>>2 if (length & TWO_HIGHEST_BITS_SET_MASK) { tmn_suspend_enable(); @@ -222,9 +222,9 @@ vector_vtable->clss->num_allocations++; vector_vtable->clss->num_bytes_allocated += sz; #endif //VM_STATS - assert( ! tmn_is_suspend_enabled()); + assert( ! hythread_is_suspend_enabled()); Vector_Handle vector = (Vector_Handle)gc_alloc(sz, vector_handle, tp); - assert( ! tmn_is_suspend_enabled()); + assert( ! hythread_is_suspend_enabled()); if (NULL == vector) { exn_throw( @@ -275,7 +275,7 @@ int *dims_array, unsigned dims) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Global_Env *global_env = VM_Global_State::loader_env; int length = *dims_array; assert(length >= 0); @@ -289,7 +289,7 @@ // Allocate an array of arrays. volatile Vector_Handle object_array = (Vector_Handle) vm_new_vector(c, length); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // Alexei // Since this function is called from a managed code // generated by JIT and this is a native code, @@ -353,7 +353,7 @@ #ifdef VM_STATS vm_stats_total.num_multianewarray++; #endif - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); const unsigned max_dims = 100; int dims_array[max_dims]; Index: vm/vmcore/src/object/object_handles.cpp =================================================================== --- vm/vmcore/src/object/object_handles.cpp (revision 430048) +++ vm/vmcore/src/object/object_handles.cpp (working copy) @@ -32,7 +32,7 @@ #include "object_handles.h" #include "vm_stats.h" #include "vm_threads.h" -#include "open/thread.h" + #include "thread_manager.h" #include "open/types.h" #include "open/vm_util.h" @@ -66,7 +66,7 @@ GcFrame::GcFrame(unsigned size_hint) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); if (size_hint>0) nodes = gc_frame_node_new(size_hint); @@ -78,7 +78,7 @@ GcFrame::~GcFrame() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(p_TLS_vmthread->gc_frames==this); p_TLS_vmthread->gc_frames = next; @@ -97,7 +97,7 @@ assert(p); assert(NULL == *p || (*p >= vm_heap_base_address() && *p < vm_heap_ceiling_address())); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); ensure_capacity(); nodes->elements[nodes->obj_size+nodes->mp_size] = nodes->elements[nodes->obj_size]; @@ -107,7 +107,7 @@ void GcFrame::add_managed_pointer(ManagedPointer* p) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); ensure_capacity(); nodes->elements[nodes->obj_size+nodes->mp_size] = (void**)p; @@ -156,13 +156,13 @@ bool managed_object_is_java_lang_class(ManagedObject* p_obj) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return managed_object_is_java_lang_class_unsafe(p_obj); } bool object_is_java_lang_class(ObjectHandle oh) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); bool res = managed_object_is_java_lang_class_unsafe(oh->object); tmn_suspend_enable(); @@ -178,13 +178,13 @@ bool managed_object_is_valid(ManagedObject* p_obj) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return managed_object_object_is_valid_unsafe(p_obj); } bool object_is_valid(ObjectHandle oh) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); bool res = managed_object_object_is_valid_unsafe(oh->object); tmn_suspend_enable(); @@ -199,25 +199,22 @@ ObjectHandle oh_allocate_global_handle() { - assert(tmn_is_suspend_enabled()); // Allocate and init handle ObjectHandlesOld* h = oh_allocate_object_handle(); //(ObjectHandlesOld*)m_malloc(sizeof(ObjectHandlesOld)); h->handle.object = NULL; h->allocated_on_the_stack = false; - tm_acquire_tm_lock(); - tmn_suspend_disable(); // ----------------vvv + p_handle_lock->_lock(); // Insert at beginning of globals list h->prev = NULL; h->next = global_object_handles; global_object_handles = h; if(h->next) h->next->prev = h; + p_handle_lock->_unlock(); tmn_suspend_enable(); //--------------------------------------------^^^ - tm_release_tm_lock(); - return &h->handle; } //vm_create_global_object_handle @@ -230,10 +227,8 @@ void oh_deallocate_global_handle(ObjectHandle handle) { - assert(tmn_is_suspend_enabled()); - - tm_acquire_tm_lock(); tmn_suspend_disable(); // ----------vvv + p_handle_lock->_lock(); assert(is_global_handle(handle)); handle->object = NULL; @@ -242,9 +237,8 @@ if (h->prev) h->prev->next = h->next; if (h==global_object_handles) global_object_handles = h->next; + p_handle_lock->_unlock(); tmn_suspend_enable(); // -------------------------------------^^^ - tm_release_tm_lock(); - STD_FREE(h); } //vm_delete_global_object_handle @@ -289,7 +283,7 @@ { // the function should be called only from suspend disabled mode // as it is not gc safe. - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); ObjectHandlesNew* cur = (ObjectHandlesNew*)*hs; if (!cur || cur->size>=cur->capacity) cur = oh_add_new_handles((ObjectHandlesNew**)hs); @@ -356,9 +350,9 @@ VMEXPORT // temporary solution for interpreter unplug ObjectHandle oh_allocate_local_handle() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // FIXME: it looks like this should be uncoment or suspend_disable added - //assert(!tmn_is_suspend_enabled()); + //assert(!hythread_is_suspend_enabled()); // ? 20021202 There are really 3 cases to check: @@ -385,7 +379,7 @@ } ObjectHandle oh_convert_to_local_handle(ManagedObject* pointer) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); ObjectHandle jobj = oh_allocate_local_handle(); TRACE2("oh", "oh_convert_to_local_handle() pointer = " << pointer << ", handle = " << jobj); jobj->object = pointer; Index: vm/vmcore/src/thread/atomics.cpp =================================================================== --- vm/vmcore/src/thread/atomics.cpp (revision 430048) +++ vm/vmcore/src/thread/atomics.cpp (working copy) @@ -27,8 +27,8 @@ #include "atomics.h" #include "vm_arrays.h" #include "port_atomic.h" -#include "open/thread.h" + /* * Common atomic functions. * Platform dependent atomic functions are in corresponding arch/ subfolders. @@ -79,7 +79,7 @@ (JNIEnv * env, jobject UNREF accesor, jobject obj, jobject fieldID, jobject expected, jobject value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jlong offset = getFieldOffset(env, fieldID); ObjectHandle h = (ObjectHandle)obj; @@ -118,7 +118,7 @@ JNIEXPORT jboolean compareAndSetBooleanField (JNIEnv * env, jobject UNREF accesor, jobject obj, jobject fieldID, jboolean expected, jboolean value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jlong offset = getFieldOffset(env, fieldID); ObjectHandle h = (ObjectHandle)obj; @@ -138,7 +138,7 @@ (JNIEnv * env, jobject UNREF accesor, jobject obj, jobject fieldID, jint expected, jint value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jlong offset = getFieldOffset(env, fieldID); ObjectHandle h = (ObjectHandle)obj; @@ -157,7 +157,7 @@ JNIEXPORT jboolean compareAndSetLongField (JNIEnv * env, jobject UNREF accesor, jobject obj, jobject fieldID, jlong expected, jlong value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jlong offset = getFieldOffset(env, fieldID); ObjectHandle h = (ObjectHandle)obj; @@ -177,7 +177,7 @@ JNIEXPORT jboolean compareAndSetObjectArray (JNIEnv * UNREF env, jobject UNREF self, jobjectArray array, jint index, jobject expected, jobject value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); @@ -213,7 +213,7 @@ JNIEXPORT jboolean compareAndSetBooleanArray (JNIEnv * UNREF env, jobject UNREF self, jbooleanArray array, jint index, jboolean expected, jboolean value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); @@ -232,7 +232,7 @@ JNIEXPORT jboolean compareAndSetIntArray (JNIEnv * UNREF env, jobject UNREF self, jintArray array, jint index, jint expected, jint value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); @@ -251,7 +251,7 @@ JNIEXPORT jboolean compareAndSetLongArray (JNIEnv * UNREF env, jobject UNREF self, jlongArray array, jint index, jlong expected, jlong value) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); Index: vm/vmcore/src/thread/mon_enter_exit.cpp =================================================================== --- vm/vmcore/src/thread/mon_enter_exit.cpp (revision 430048) +++ vm/vmcore/src/thread/mon_enter_exit.cpp (working copy) @@ -27,351 +27,44 @@ #include "thread_generic.h" #include "vm_synch.h" #include "port_atomic.h" +#include "open/jthread.h" static void vm_monitor_exit_default(ManagedObject *p_obj); -static void vm_monitor_exit_default_handle(jobject jobj); +static void vm_monitor_enter_default(ManagedObject *p_obj); + void (*vm_monitor_enter)(ManagedObject *p_obj) = 0; void (*vm_monitor_exit)(ManagedObject *p_obj) = 0; -void (*vm_monitor_exit_handle)(jobject jobj) = 0; -volatile int active_thread_count; -mon_enter_fields mon_enter_array[MAX_VM_THREADS]; - -static void jvmti_push_monitor(jobject jobj); -static void jvmti_pop_monitor(jobject jobj); - -#if defined(USE_TLS_API) || !defined(STACK_BASE_AS_TID) -uint16 get_self_stack_key() -{ - return p_TLS_vmthread->stack_key; -} -#endif //#ifdef USE_TLS_API || !STACK_BASE_AS_TID - -void block_on_mon_enter(jobject obj) -{ - assert(!tmn_is_suspend_enabled()); - ManagedObject *p_obj = obj->object; - VM_thread *p_thr = get_thread_ptr(); - - assert(mon_enter_array[p_thr->thread_index].p_obj == 0); - - // set thread state to BLOCKED on monitor - // RUNNING will be set back before return - enum java_state old_state = p_thr->app_status; - p_thr->app_status = thread_is_blocked; - -#ifdef _DEBUG - int loop_count = 0; -#endif - - //since p_obj may be moved by GC in the below loop, we need to reload after gc_enable/disable - volatile ManagedObject *volatile_p_obj = (ManagedObject *)p_obj; - - while (1) { - - mon_enter_array[p_thr->thread_index].p_obj = (ManagedObject *)volatile_p_obj; - -#ifdef _DEBUG - loop_count++; - if (loop_count > max_block_on_mon_enter_loops) - max_block_on_mon_enter_loops = loop_count; -#endif - if ( STACK_KEY(volatile_p_obj) == FREE_MONITOR) - { - mon_enter_array[p_thr->thread_index].p_obj = 0; - - Boolean retval = vm_try_monitor_enter( (ManagedObject *)volatile_p_obj); - if (retval){ - assert(p_thr->app_status == thread_is_blocked); - p_thr->app_status = old_state; - return; - } - else continue; - } - - tmn_suspend_enable(); - p_thr -> is_suspended = true; - - // no one sends this event - // DWORD stat = vm_wait_for_single_object(p_thr->event_handle_monitor, 1); - vm_yield(); - - p_thr -> is_suspended = false; - tmn_suspend_disable(); - - // by convention, *only* mon_enter_array and mon_wait_array will be enumerated to the GC - // thus reload from mon_enter_array[] after the waitforsingleobject returns - ManagedObject* p_obj = (ManagedObject *) - mon_enter_array[p_thr->thread_index].p_obj; - assert(managed_object_is_valid(p_obj)); - volatile_p_obj = p_obj; - - } //while(1) -} - - -void find_an_interested_thread(ManagedObject *p_obj) -{ - assert(!tmn_is_suspend_enabled()); - if ( ( HASH_CONTENTION(p_obj) & CONTENTION_MASK) == 0) - return; // nobody wants this object - - DWORD stat; - int xx; - - for (xx = 1; xx < next_thread_index; xx++) - { - if (mon_enter_array[xx].p_obj == p_obj) - { - stat = vm_set_event(mon_enter_array[xx].p_thr->event_handle_monitor); - assert(stat); - - return; - } - } -} - - void vm_enumerate_root_set_mon_arrays() { - TRACE2("enumeration", "enumerating root set monitor arrays"); - int xx; - - for (xx = 1; xx < next_thread_index; xx++) - { - if (mon_enter_array[xx].p_obj){ - assert( (STACK_KEY( mon_enter_array[xx].p_obj)) != mon_enter_array[xx].p_thr->stack_key ); - vm_enumerate_root_reference((void **)&(mon_enter_array[xx].p_obj), FALSE); - } - - if (mon_wait_array[xx].p_obj){ - assert( mon_wait_array[xx].p_thr->app_status == thread_is_waiting || mon_wait_array[xx].p_thr->app_status == thread_is_timed_waiting); - vm_enumerate_root_reference((void **)&(mon_wait_array[xx].p_obj), FALSE); - } - } } -void mon_enter_recursion_overflowed(ManagedObject * UNREF p_obj) -{ - ABORT("Not implemented"); //TODO: add the backup algorithm for recursion overflow - -} - void vm_monitor_init() { - vm_monitor_enter = vm_monitor_enter_slow; + vm_monitor_enter = vm_monitor_enter_default; vm_monitor_exit = vm_monitor_exit_default; - vm_monitor_exit_handle = vm_monitor_exit_default_handle; -} - -inline void pause_inst(void){ -#if defined(PLATFORM_POSIX) && !defined(_IPF_) - __asm__( -#if !((__GLIBC__ == 2) && (__GLIBC_MINOR__ <= 1)) - "pause" -#else - "nop;nop;nop" -#endif - : : : "memory" - ); - -#else -#ifdef _IPF_ - // WE WILL DO NOTHING HERE FOR THE TIME BEING...until we can find a suitable & profitable IPF instruction... -#else // !_IPF_ - _asm{ - pause } -#endif // !_IPF_ -#endif - -} - - -//return the old monitor stack key, so that 0 means success, otherwise failure; -Boolean vm_try_monitor_enter(ManagedObject *p_obj) +static void vm_monitor_enter_default(ManagedObject *p_obj) { - - uint16 current_stack_key = get_self_stack_key(); - uint16 *p_monitor_stack_key = P_STACK_KEY(p_obj); - uint16 old_stack_key = FREE_MONITOR; - old_stack_key = port_atomic_cas16(p_monitor_stack_key, current_stack_key, FREE_MONITOR); - if( old_stack_key == FREE_MONITOR ){ - - return TRUE; - - } else if (old_stack_key == current_stack_key) { //recursed - ++RECURSION(p_obj); - if (0 == RECURSION(p_obj)) { - mon_enter_recursion_overflowed(p_obj); - } - return TRUE; - } - - //hold by other thread - return FALSE; -} - -static inline uint8 get_recursion(jobject jobj) { - assert(tmn_is_suspend_enabled()); - tmn_suspend_disable(); // ----------- vv - uint8 recursion = RECURSION(jobj->object); - tmn_suspend_enable(); // ------------ ^^ - return recursion; -} - -static inline uint16 get_stack_key(jobject jobj) { - assert(object_is_valid(jobj)); - tmn_suspend_disable(); // ----------vv - uint16 *p_stack_key = P_STACK_KEY(jobj->object); - uint16 result = *p_stack_key; - tmn_suspend_enable(); // -----------^^ - return result; -} - -static inline uint16 compare_swap_stack_key(jobject jobj, uint16 value, uint16 expected) { - assert(object_is_valid(jobj)); - tmn_suspend_disable(); // ----------vv - uint16 *p_stack_key = P_STACK_KEY(jobj->object); - uint16 old = port_atomic_cas16(p_stack_key, value, expected); - tmn_suspend_enable(); // -----------^^ - return old; -} - -// this is a first step of a bigger refactoring -// of VM code to run with gc enabled. -// -// this function should be called instead of vm_monitor_enter_slow -// NOTE, that only ia32 stubs were modified so. -// -// -salikh 2005-05-11 -VMEXPORT void vm_monitor_enter_slow_handle (jobject jobj) { - TRACE2("oh", "vm_monitor_enter_slow_handle()"); - assert(tmn_is_suspend_enabled()); - assert(object_is_valid(jobj)); - - uint16 current_stack_key = get_self_stack_key(); - uint16 old_stack_key = get_stack_key(jobj); - - if (old_stack_key == FREE_MONITOR) { //common case, fastest - old_stack_key = compare_swap_stack_key(jobj, current_stack_key, FREE_MONITOR); - if (old_stack_key == FREE_MONITOR) { //ok, got it - jvmti_push_monitor(jobj); - return; - } - // failed to grab the lock, fall through to contended case - } else if (old_stack_key == current_stack_key) { //recursed - tmn_suspend_disable(); // ---------------vv - ++RECURSION(jobj->object); - int recursion = RECURSION(jobj->object); - tmn_suspend_enable(); // ----------------^^ - if (0 == recursion) { - tmn_suspend_disable(); // -----------vv - mon_enter_recursion_overflowed(jobj->object); - tmn_suspend_enable(); // ------------^^ - } - return; - } - - //hold by other thread, let's spin look for a short while - - unsigned int i = SPIN_LOOP_COUNT; - while (i--) { - pause_inst(); - if (0 == get_stack_key(jobj)) { //monitor is free now, try to get it - old_stack_key = compare_swap_stack_key(jobj, current_stack_key, FREE_MONITOR); - if (old_stack_key == FREE_MONITOR) { //ok, got it - jvmti_push_monitor(jobj); - return; - } - } - } - - bool isEnter = true; - jvmti_send_contended_enter_or_entered_monitor_event(jobj, isEnter); - - // we have no way to get the lock, then sleep; - tmn_suspend_disable(); - block_on_mon_enter(jobj); - tmn_suspend_enable(); - - assert(object_is_valid(jobj)); - if (get_stack_key(jobj) != current_stack_key) { - DIE("Wrong monitor states after GC: " << jobj << ")"); - } - - return; -} - -void vm_monitor_enter_slow(ManagedObject *p_obj) -{ - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(p_obj); jobject jobj = oh_allocate_local_handle(); jobj->object = p_obj; - tmn_suspend_enable(); // we've protected the argument - vm_monitor_enter_slow_handle(jobj); - tmn_suspend_disable(); // restore suspend enabled state + jthread_monitor_enter(jobj); } -static void vm_monitor_exit_default_handle(jobject jobj) { - assert(object_is_valid(jobj)); - - uint16 current_stack_key = get_self_stack_key(); - - uint16 monitor_stack_key = get_stack_key(jobj); - if (monitor_stack_key == current_stack_key) { //common case, fastest path - if (!get_recursion(jobj)) { //no recursion - tmn_suspend_disable(); // ----------------------vv - STACK_KEY(jobj->object) = FREE_MONITOR; //release the lock - if (HASH_CONTENTION(jobj->object) & CONTENTION_MASK) { //contented - find_an_interested_thread(jobj->object); - } - tmn_suspend_enable(); // -----------------------^^ - jvmti_pop_monitor(jobj); - } else { //recursed - tmn_suspend_disable(); // ----------------------vv - RECURSION(jobj->object)--; - tmn_suspend_enable(); // -----------------------^^ - } - - } else { //illegal monitor state - exn_throw_by_name("java/lang/IllegalMonitorStateException"); - } - - assert(tmn_is_suspend_enabled()); -} - - - static void vm_monitor_exit_default(ManagedObject *p_obj) { assert(managed_object_is_valid(p_obj)); jobject jobj = oh_allocate_local_handle(); jobj->object = p_obj; - tmn_suspend_enable(); - vm_monitor_exit_default_handle(jobj); - tmn_suspend_disable(); + jthread_monitor_exit(jobj); } -//#endif // !_IPF_ -void set_hash_bits(ManagedObject *p_obj) -{ - uint8 hb = (uint8) (((POINTER_SIZE_INT)p_obj >> 3) & HASH_MASK) ; - // lowest 3 bits are not random enough so get rid of them - - if (hb == 0) - hb = (23 & HASH_MASK); // NO hash = zero allowed, thus hard map hb = 0 to a fixed prime number - - // don't care if the cmpxchg fails -- just means someone else already set the hash - port_atomic_cas8(P_HASH_CONTENTION(p_obj),hb, 0); -} - - // returns true if the object has its monitor taken... // asserts if the object header is ill-formed. // returns false if object's monitor is free. @@ -382,72 +75,5 @@ Boolean verify_object_header(void *ptr) { - ManagedObject *p_obj = (ManagedObject *) ptr; - if (p_obj->get_obj_info() == 0) { - // ZERO header is valid. return FALSE; } - - uint16 stack_key = STACK_KEY(p_obj); - // Recursion can be any 8-bit value...no way to check integrity. - // Contention bit can remain ON in our current implemenation at arbitrary times. - // Hash can be zero or non-zero at any given time, though it doesnt change after it goes non-zero - - // Not much I can check here....can I???? - - // So I will check only if the monitor lock is held and if so by a valid thread. - - if (stack_key == 0) { - // No thread owns the object lock - return FALSE; - } - - // Object monitor is held. - - Boolean res = TRUE; - tmn_suspend_enable(); - tm_iterator_t * iterator = tm_iterator_create(); - tmn_suspend_disable(); - VM_thread *thread = tm_iterator_next(iterator); - assert(thread); - - while (thread) { - if (thread->thread_index == stack_key) { - res = TRUE; - break; - } - thread = tm_iterator_next(iterator); - } - tm_iterator_release(iterator); - // What should the return value be? - return res; -} - -static void jvmti_push_monitor(jobject jobj) -{ - assert(tmn_is_suspend_enabled()); - if (VM_Global_State::loader_env->TI->isEnabled()) { - VM_thread *thread = p_TLS_vmthread; - assert(thread -> jvmti_owned_monitor_count < MAX_OWNED_MONITORS); - ObjectHandle oh = oh_allocate_global_handle(); - tmn_suspend_disable(); // ----------- vv - oh -> object = jobj -> object; - tmn_suspend_enable(); // ------------ ^^ - thread -> jvmti_owned_monitors[thread -> jvmti_owned_monitor_count++] = (jobject) oh; - } -} - -static void jvmti_pop_monitor(jobject UNREF jobj) -{ - assert(tmn_is_suspend_enabled()); - if (VM_Global_State::loader_env->TI->isEnabled()) { - VM_thread *thread = p_TLS_vmthread; - if (thread -> jvmti_owned_monitor_count <= 0) return; - assert(thread -> jvmti_owned_monitor_count > 0); - - ObjectHandle oh = (ObjectHandle) - thread -> jvmti_owned_monitors[--thread -> jvmti_owned_monitor_count]; - oh_deallocate_global_handle(oh); - } -} - Index: vm/vmcore/src/thread/verify_stack_enumeration.cpp =================================================================== --- vm/vmcore/src/thread/verify_stack_enumeration.cpp (revision 430048) +++ vm/vmcore/src/thread/verify_stack_enumeration.cpp (working copy) @@ -114,7 +114,7 @@ if (NULL == heap_ceiling) { heap_ceiling = gc_heap_ceiling_address(); } // GC must be prevented from happening while we hijack the GC functions - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // save away the GC function pointer add_root_set_entry_func gc_add_root_set_entry_saved Index: vm/vmcore/src/thread/suspend.cpp =================================================================== --- vm/vmcore/src/thread/suspend.cpp (revision 430048) +++ vm/vmcore/src/thread/suspend.cpp (working copy) @@ -1,542 +0,0 @@ -/* - * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * @author Artem Aliev - * @version $Revision: 1.1.2.3.4.4 $ - */ - - -#include "platform_lowlevel.h" -#ifdef PLATFORM_POSIX -#endif // PLATFORM_POSIX - -#include "open/gc.h" -#include "jit_intf_cpp.h" -#include "method_lookup.h" -#include "vm_stats.h" -#include "vm_threads.h" -#include "thread_generic.h" -#include "open/thread.h" -#include "atomics.h" -#include "root_set_enum_internal.h" -#include "lock_manager.h" -#include "verify_stack_enumeration.h" - -#include "open/vm_util.h" -#include "vm_process.h" -#include "cxxlog.h" - -#define REDUCE_RWBARRIER 1 - -#if defined (PLATFORM_POSIX) && defined (_IPF_) -extern "C" void get_rnat_and_bspstore(uint64* res); -extern "C" void do_flushrs(); -#endif - -#ifdef REDUCE_RWBARRIER -#if defined (PLATFORM_POSIX) -#include -#endif -static void thread_yield_other(VM_thread*); -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - -// The rules for when something can and can't be enabled or disabled: -// -// 1. Only the current thread (p_TLS_vmthread) can disable and enable GC. -// 2. You cannot enable GC from within JITTED code. -// 3. You can only enable if you are disabled. - -// tmn_suspend_disable interface() assumes we are in enabled state (otherwise -// tmn_suspend_disable_and_return_old_value() should be used) -// so it would be better to rename thread_enable_suspend() to vm_try_enabling_gc() -// to break incorrectly intuitive pair -// -// New interface: -// tmn_suspend_enable(); -// tmn_suspend_disable(); -// the thread_safe_point(); - - -// this is internal function -// thread param should always be self thread (p_TLS_vmthread). - -inline void thread_safe_point_impl(VM_thread *thread) { - // must be either suspend enabled (status == 0) or in managed code (status == 1) - assert(thread->suspend_enabled_status <= 1); - debug_stack_enumeration(); - if(thread->suspend_request >0) { - int old_status = thread->suspend_enabled_status; - do { - thread->suspend_enabled_status = 0; - MemoryReadWriteBarrier(); - // code for Ipf that support StackIterator and immmediate suspend - // notify suspender - vm_set_event(thread->suspended_event); - TRACE2("suspend", "suspended event... " << thread->thread_id); - - // wait for resume event - vm_wait_for_single_object(thread->resume_event, INFINITE); - - TRACE2("suspend", "resuming after gc resume event" << thread->thread_id); - thread->suspend_enabled_status = old_status; - MemoryReadWriteBarrier(); - } while (thread->suspend_request >0); - } -} // thread_safe_point_impl - - -void tmn_suspend_enable() -{ - assert(p_TLS_vmthread->suspend_enabled_status == 1); - tmn_suspend_enable_recursive(); -} - -void tmn_suspend_enable_recursive() -{ - VM_thread *thread = p_TLS_vmthread; - //TRACE2("suspend", "enable" << thread->suspend_enabled_status); - assert(!tmn_is_suspend_enabled()); - debug_stack_enumeration(); - thread->suspend_enabled_status--; - //assert(tmn_is_suspend_enabled()); - -// MemoryReadWriteBarrier(); - if ((thread->suspend_request > 0) - && (0 == thread->suspend_enabled_status)) { - // notify suspender - vm_set_event(thread->suspended_event); - TRACE2("suspend", "suspended " << thread->thread_id); - } -} - -int suspend_count = 0; -void tmn_suspend_disable() -{ -// if (!tmn_is_suspend_enabled()) { -// printf("asserted\n"); -// // the following lines allow MSVC++ "Debug->>>Break" to work -// while (1) { -// DWORD stat = vm_wait_for_single_object(NULL, 2000); -//// if (stat == WAIT_OBJECT_0) break; -//// assert(stat != WAIT_FAILED); -// Sleep(2000); -// } -// } - - assert(tmn_is_suspend_enabled()); - tmn_suspend_disable_recursive(); -} - -void tmn_suspend_disable_recursive() -{ -#ifdef _DEBUG - suspend_count++; - if(suspend_count % 100000 == 0) - TRACE2("suspend", "suspend disable count: " << suspend_count); -#endif - VM_thread *thread = p_TLS_vmthread; - //TRACE2("suspend", "disable: " << thread->suspend_enabled_status); - thread->suspend_enabled_status++; - debug_stack_enumeration(); -#ifndef REDUCE_RWBARRIER - MemoryReadWriteBarrier(); -#endif - if (1 == thread->suspend_enabled_status) - thread_safe_point_impl(thread); -} - - -//FIXME replace through the code to tmn_suspend_disable(); -bool tmn_suspend_disable_and_return_old_value() { - /*if(tmn_is_suspend_enabled()) { - tmn_suspend_disable(); - return true; - } - return false;*/ - //TRACE2("suspend", "disable if enable: " << p_TLS_vmthread->suspend_enabled_status); - - p_TLS_vmthread->suspend_enabled_status++; - return true; -} - -VMEXPORT bool tmn_is_suspend_enabled() { - assert(p_TLS_vmthread->suspend_enabled_status >=0); - return (p_TLS_vmthread->suspend_enabled_status == 0); -} - -// temporary for debug purpose -VMEXPORT int tmn_suspend_disable_count() { - return (p_TLS_vmthread->suspend_enabled_status); -} - -void tmn_safe_point() { - thread_safe_point_impl(p_TLS_vmthread); -} - -void rse_thread_resume(VM_thread *thread) -{ - if(thread == p_TLS_vmthread) { - return; - } - - if(thread->suspend_request <=0) { - LOG2("suspend", "resume allived thread: " << thread->thread_id); - return; - } - - //decrement suspend_request - if(--thread->suspend_request > 0) { - return; - } - - vm_set_event(thread->resume_event); - - TRACE2("suspend", "resume " << thread->thread_id); - thread -> jvmti_thread_state ^= JVMTI_THREAD_STATE_SUSPENDED; - -} // rse_thread_resume - -// the function start suspension. -// call wait_supend_respose() should be called to wait for safe region or safe point. -// the function do not suspend self. -static void send_suspend_request(VM_thread *t) { - - assert(t->suspend_request >=0); - // already suspended? - if(t->suspend_request > 0) { - t->suspend_request++; - return; - } - - //we realy need to suspend thread. - - vm_reset_event(t->resume_event); - - t->suspend_request++; - MemoryReadWriteBarrier(); -#ifdef REDUCE_RWBARRIER - // ping other thread to do MemoryReadWriteBarrier() - // this is done by sending signal on linux - // or by SuspendThread();ResumeThread() on windows - thread_yield_other(t); -#endif - TRACE2("suspend", "suspend request " << t->thread_id); -} - - -// the second part of suspention -// blocked in case was selfsuspended. -static void wait_supend_respose(VM_thread *t) { - if(t->suspend_request > 1) { - return; - } - if(t == p_TLS_vmthread) { - TRACE2("suspend", "suspend self... skiped"); - return; - } - - // we need to wait for notification only in case the thread is in the unsafe/disable region - while (t->suspend_enabled_status != 0) { - // wait for the notification - TRACE2("suspend", "wait for suspended_event " << t->thread_id); - vm_wait_for_single_object(t->suspended_event, 50); - // this is auto reset event - //vm_reset_event(t->suspended_event); - } - TRACE2("suspend", "suspended " << t->thread_id); - t -> jvmti_thread_state |= JVMTI_THREAD_STATE_SUSPENDED; -} - - -// GC suspend function -void suspend_all_threads_except_current() { - VM_thread *self = p_TLS_vmthread; - TRACE2("suspend", "suspend_all_threads_except_current() in thread: " << p_TLS_vmthread->thread_id); - tm_acquire_tm_lock(); - // unlock mutex in case self was suspended by other thread - // this will prevent us from cyclic dead-lock - if(self != NULL) { - while (self ->suspend_request > 0) { - tm_release_tm_lock(); - TRACE2("suspend", "generic suspend safe_point " << self->thread_id); - thread_safe_point_impl(self); - tm_acquire_tm_lock(); - } - } - // Run through list of active threads and suspend each one of them. - // We can do this safely because we hold the global thread lock - VM_thread *t = p_active_threads_list; - assert(t); - - for (;t;t = t->p_active) { - if(t == self) { - TRACE2("suspend", "skip enumerate self"); - continue; - } - send_suspend_request(t); - } - - for (t = p_active_threads_list;t;t = t->p_active) { - if(t == self) { - TRACE2("suspend", "skip enumerate self"); - continue; - } - wait_supend_respose(t); - t->gc_status = gc_at_safepoint; - - } - tm_release_tm_lock(); - - TRACE2("suspend", "suspend_all_threads_except_current() complete"); -} - -void suspend_all_threads_except_current_generic() { - TRACE2("suspend", "suspend_all_threads_except_current() in thread: " << p_TLS_vmthread->thread_id); - p_thread_lock->_lock_enum(); - // unlock mutex in case self was suspended by other thread - // this will prevent us from cyclic dead-lock - while (p_TLS_vmthread ->suspend_request > 0) { - p_thread_lock->_unlock_enum(); - TRACE2("suspend", "generic suspend safe_point " << p_TLS_vmthread->thread_id); - thread_safe_point_impl(p_TLS_vmthread); - p_thread_lock->_lock_enum(); - } - // Run through list of active threads and suspend each one of them. - // We can do this safely because we hold the global thread lock - VM_thread *t = p_active_threads_list; - assert(t); - - for (;t;t = t->p_active) { - if(t == p_TLS_vmthread) { - TRACE2("suspend", "skip enumerate self"); - continue; - } - send_suspend_request(t); - } - - for (t = p_active_threads_list;t;t = t->p_active) { - if(t == p_TLS_vmthread) { - TRACE2("suspend", "skip enumerate self"); - continue; - } - wait_supend_respose(t); - - } - p_thread_lock->_unlock_enum(); - - TRACE2("suspend", "suspend_all_threads_except_current() complete"); -} - -// GC resume function -void resume_all_threads() { - VM_thread *self = p_TLS_vmthread; - tm_acquire_tm_lock(); - TRACE2("suspend", " ====== resume all threads ==========" ); - - VM_thread *t = p_active_threads_list; - assert(t); - - - for (;t;t = t->p_active) { - if(t == self) { - assert(t->gc_status == gc_enumeration_done); - t->gc_status = zero; - continue; - } - rse_thread_resume(t); - assert(t->gc_status == gc_enumeration_done); - t->gc_status = zero; - - } - tm_release_tm_lock(); - -} - -void resume_all_threads_generic() { - p_thread_lock->_lock_enum(); - TRACE2("suspend", " ====== resume all threads ==========" ); - - VM_thread *t = p_active_threads_list; - assert(t); - - - for (;t;t = t->p_active) { - if(t == p_TLS_vmthread) { - continue; - } - - if ((t->suspend_request == 1 && t->gc_status != zero) // do no resume stoped by GC thread - || t->suspend_request <=0) { // do not resume working thread - - TRACE2("suspend", "generic resume failed " << t->thread_id << " gc " <gc_status - << " suspend_request " << t->suspend_request ); - continue; - } - - rse_thread_resume(t); - } - p_thread_lock->_unlock_enum(); -} - -void -thread_suspend_self() { - TRACE2("suspend", "suspend_self called" ); - VM_thread *thread = p_TLS_vmthread; - assert(thread); - tm_acquire_tm_lock(); - send_suspend_request(thread); - tm_release_tm_lock(); - - assert(tmn_is_suspend_enabled()); - assert(thread->suspend_request > 0); - thread_safe_point_impl(thread); -} - -bool -thread_suspend_generic(VM_thread *thread) -{ - VM_thread *self = p_TLS_vmthread; - // suspend self - if(thread == NULL || thread == self) { - TRACE2("suspend", "suspend self " << (thread == NULL?0:thread->thread_id)); - thread_suspend_self(); - return true; - } - - assert(tmn_is_suspend_enabled()); - tm_acquire_tm_lock(); - - // unlock mutex in case self was suspended by other thread - // this will prevent us from cyclic dead-lock - if(self != NULL) { - while (self ->suspend_request > 0) { - tm_release_tm_lock(); - TRACE2("suspend", "generic suspend safe_point " << self->thread_id); - thread_safe_point_impl(self); - tm_acquire_tm_lock(); - } - } - TRACE2("suspend", "generic suspend " << thread->thread_id); - - send_suspend_request(thread); - wait_supend_respose(thread); - tm_release_tm_lock(); - return true; -} // thread_suspend_generic - - -bool -thread_resume_generic(VM_thread *t) -{ - if(t == NULL || t == p_TLS_vmthread) { - TRACE2("suspend", "generic resume self failed "); - return false; - } - assert(tmn_is_suspend_enabled()); - TRACE2("suspend", "generic resume " << t->thread_id); - - tm_acquire_tm_lock(); - assert(t); - assert(t->suspend_request >=0); - if ((t->suspend_request == 1 && t->gc_status != zero) // do no resume stoped by GC thread - || t->suspend_request <=0) { // do not resume working thread - - TRACE2("suspend", "generic resume failed " << t->thread_id << " gc " <gc_status - << " suspend_request " << t->suspend_request ); - tm_release_tm_lock(); - return false; - } - - rse_thread_resume(t); - tm_release_tm_lock(); - return true; -} // thread_resume_generic - -void jvmti_thread_resume(VM_thread *thread) -{ - thread_resume_generic(thread); -} // jvmti_thread_resume - - -#ifdef REDUCE_RWBARRIER -// touch thread to flash memory -static void thread_yield_other(VM_thread* thread) { - assert(thread); - TRACE2("suspend", "yield from thread: " << p_TLS_vmthread->thread_id << "to: " << thread->thread_id); - // use signals on linux - #ifdef PLATFORM_POSIX - // IPF compiler generate st4.rel ld4.acq for valatile variables - // so nothing need to do. - #ifndef _IPF_ - assert(thread->thread_id); - pthread_kill(thread->thread_id, SIGUSR2); - sem_wait(&thread->yield_other_sem); - #endif - // use SuspendThread on windows - #else - SuspendThread(thread->thread_handle); - ResumeThread(thread->thread_handle); - #endif -} -#endif - -// depricated functions -uint32 thread_gc_number_of_threads() -{ - uint32 xx = 0; - - tmn_suspend_enable(); // to make tm_iterator_create()happy: it uses assert(tmn_is_suspend_enabled()); - tm_iterator_t * iterator = tm_iterator_create(); - tmn_suspend_disable(); - - VM_thread *thread = tm_iterator_next(iterator); - while (thread != NULL) { - xx++; - thread = tm_iterator_next(iterator); - } - tm_iterator_release(iterator); - - // do NOT enumerate the current thread thus its - // return xx - 1; instead of return xx; - // setup iterator for thread_gc_enumerate_one(); - p_threads_iterator = p_active_threads_list; - - return xx - 1; -} - -//TODO change to iterator -VM_thread *thread_gc_enumerate_one() -{ - //depricated - - assert(p_threads_iterator); - - // skip over the current thread which is already at - // a gc safepoint. Also, doing a Get/SetThreadContext() - // on the current thread will cause a crash (for good reason) - - if(p_TLS_vmthread == p_threads_iterator) - p_threads_iterator = p_threads_iterator->p_active; - - VM_thread *p_cookie = p_threads_iterator; - if(p_threads_iterator) - p_threads_iterator = p_threads_iterator->p_active; - - return p_cookie; -} Index: vm/vmcore/src/thread/thread_manager.cpp =================================================================== --- vm/vmcore/src/thread/thread_manager.cpp (revision 430048) +++ vm/vmcore/src/thread/thread_manager.cpp (working copy) @@ -19,6 +19,8 @@ */ +#include "open/thread_externals.h" + #include "platform_lowlevel.h" #include @@ -31,7 +33,15 @@ #include "vm_process.h" #endif +#include "object_layout.h" #include "open/vm_util.h" +#include "object_handles.h" +//FIXME remove this code +#include "exceptions.h" +#include "Class.h" +#include "environment.h" + +#include "open/vm_util.h" #include "nogc.h" #include "sync_bits.h" #include "vm_synch.h" @@ -39,6 +49,9 @@ #include "lock_manager.h" #include "thread_manager.h" #include "thread_generic.h" +#include "open/thread_helpers.h" +#include "open/jthread.h" + #include "vm_threads.h" #define LOG_DOMAIN "thread" #include "cxxlog.h" @@ -61,61 +74,24 @@ static tl::MemoryPool thr_pool; -VM_thread *p_threads_iterator; -VM_thread *p_free_thread_blocks; -VM_thread *p_active_threads_list; +hythread_tls_key_t TLS_key_pvmthread; -#ifdef USE_TLS_API -#ifdef PLATFORM_POSIX -__thread VM_thread *p_TLS_vmthread = NULL; -VM_thread *get_thread_ptr() -{ - return p_TLS_vmthread; -} - -#else //PLATFORM_POSIX -__declspec( thread ) VM_thread *p_TLS_vmthread; -#endif //PLATFORM_POSIX else -#endif //USE_TLS_API - #ifdef __cplusplus extern "C" { #endif volatile VM_thread *p_the_safepoint_control_thread = 0; // only set when a gc is happening volatile safepoint_state global_safepoint_status = nill; -// Incremented at the start and at the end of each GC. The total number -// of GC is this number * 2. This is done so that when a lot of application -// threads discover that they need a GC only on is done. -unsigned non_daemon_thread_count = 0; - -VmEventHandle non_daemon_threads_dead_handle = 0; -VmEventHandle new_thread_started_handle = 0; - -VmEventHandle non_daemon_threads_are_all_dead; - -thread_array quick_thread_id[MAX_VM_THREADS]; -POINTER_SIZE_INT hint_free_quick_thread_id; - #ifdef __cplusplus } #endif -#ifdef _DEBUG -////////////Object_Handle vm_create_global_object_handle(); // bugbug -- where does this go? -#include "jni.h" -#endif +void init_TLS_data(); - void vm_thread_init(Global_Env * UNREF p_env___not_used) { - new_thread_started_handle = vm_create_event( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - N_T_S_H // pointer to event-object name - ); + init_TLS_data(); } @@ -128,323 +104,118 @@ VM_thread * get_a_thread_block() { VM_thread *p_vmthread; - int thread_index; - for( thread_index=1; thread_index < MAX_VM_THREADS; thread_index++ ){ - if (quick_thread_id[thread_index].p_vmthread == NULL ) - break; + p_vmthread = p_TLS_vmthread; + if (!p_vmthread) { + p_vmthread = (VM_thread *)thr_pool.alloc(sizeof(VM_thread)); + memset(p_vmthread, 0, sizeof(VM_thread) ); } - if (thread_index == MAX_VM_THREADS){ - WARN("Out of java threads, maximum is " << MAX_VM_THREADS); - return NULL; + return p_vmthread; } - next_thread_index = (thread_index == next_thread_index)? ++next_thread_index : next_thread_index; - - if (p_free_thread_blocks) { - p_vmthread = p_free_thread_blocks; - p_free_thread_blocks = p_free_thread_blocks->p_free; - p_vmthread->p_free = 0; - p_vmthread->app_status = thread_is_birthing; - TRACE2("thread", "Reusing old thread block " << p_vmthread << " for a new thread"); +void free_this_thread_block(VM_thread *p_vmthread) +{ } - else { - p_vmthread = (VM_thread *)thr_pool.alloc(sizeof(VM_thread)); - memset(p_vmthread, 0, sizeof(VM_thread) ); - TRACE2("thread", "Creating new thread block " << p_vmthread); - //park semaphore initialization - p_vmthread->park_event = CreateEvent( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - NULL // pointer to event-object name - ); - - // If new thread block is being created, set app_status to "birthing" here too. - p_vmthread->app_status = thread_is_birthing; - - p_vmthread->event_handle_monitor = vm_create_event( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - E_H_M // pointer to event-object name - ); - assert(p_vmthread->event_handle_monitor); - - p_vmthread->event_handle_sleep = vm_create_event( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - E_H_S // pointer to event-object name - ); - assert(p_vmthread->event_handle_sleep); - - p_vmthread->event_handle_notify_or_interrupt = vm_create_event( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - E_H_I // pointer to event-object name - ); - assert(p_vmthread->event_handle_notify_or_interrupt); - - p_vmthread->jvmti_resume_event_handle = vm_create_event( - NULL, // pointer to security attributes - TRUE, // flag for manual-reset event -- manual mode - TRUE, // flag for initial state - J_V_M_T_I_E_H // pointer to event-object name - ); - assert(p_vmthread->jvmti_resume_event_handle); - - // ============== new SUSPEND related variables setup ===================== - p_vmthread->suspend_request = 0; - p_vmthread->suspended_event = vm_create_event( - NULL, // pointer to security attributes - TRUE, // flag for manual-reset event -- manual mode - FALSE, // flag for initial state - E_H_S0 // pointer to event-object name - ); // set when thread is suspended - - assert(p_vmthread->suspended_event); - - p_vmthread->resume_event = vm_create_event( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- manual mode - TRUE, // flag for initial state - NULL // pointer to event-object name - ); // set when thread is suspended - assert(p_vmthread->resume_event); +void vm_thread_attach() +{ + VM_thread *p_vmthread; + p_vmthread = p_TLS_vmthread; + if (!p_vmthread) { + p_vmthread = (VM_thread *)thr_pool.alloc(sizeof(VM_thread)); + memset(p_vmthread, 0, sizeof(VM_thread) ); + set_TLS_data(p_vmthread); } -#ifdef PLATFORM_POSIX - sem_init(&p_vmthread->yield_other_sem,0,0); -#endif - p_vmthread->p_active = p_active_threads_list; - p_active_threads_list = p_vmthread; - p_vmthread->thread_index = thread_index; - quick_thread_id[thread_index].p_vmthread = p_vmthread; - mon_enter_array[thread_index].p_thr = p_vmthread; - mon_wait_array[thread_index].p_thr = p_vmthread; - p_vmthread->native_handles = 0; +} //init_thread_block - return p_vmthread; +VM_thread *get_vm_thread(hythread_t thr) { + if (thr == NULL) { + return NULL; } - -#ifdef RECOMP_THREAD -VM_thread* new_a_thread_block() -{ //:: - VM_thread* p_vmthread = (VM_thread *)thr_pool.alloc(sizeof(VM_thread)); - TRACE2("thread", "new_a_thread_block() created new thread block " << p_vmthread); - memset(p_vmthread, 0, sizeof(VM_thread) ); - - p_vmthread->park_event = CreateEvent( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - NULL // pointer to event-object name - ); - - // If new thread block is being created, set app_status to "birthing" here too. - p_vmthread->app_status = thread_is_birthing; - - p_vmthread->event_handle_monitor = vm_create_event( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - E_H_M // pointer to event-object name - ); - assert(p_vmthread->event_handle_monitor); - - p_vmthread->event_handle_sleep = vm_create_event( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - E_H_S // pointer to event-object name - ); - assert(p_vmthread->event_handle_sleep); - - p_vmthread->event_handle_notify_or_interrupt = vm_create_event( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- auto reset mode - FALSE, // flag for initial state - E_H_I // pointer to event-object name - ); - assert(p_vmthread->event_handle_notify_or_interrupt); - - p_vmthread->jvmti_resume_event_handle = vm_create_event( - NULL, // pointer to security attributes - TRUE, // flag for manual-reset event -- manual mode - TRUE, // flag for initial state - J_V_M_T_I_E_H // pointer to event-object name - ); - assert(p_vmthread->jvmti_resume_event_handle); - - //park semaphore initialization - - // ============== new SUSPEND related variables setup ===================== - p_vmthread->suspend_request = 0; - p_vmthread->suspended_event = vm_create_event( - NULL, // pointer to security attributes - TRUE, // flag for manual-reset event -- manual mode - FALSE, // flag for initial state - E_H_S0 // pointer to event-object name - ); // set when thread is suspended - - assert(p_vmthread->suspended_event); - - p_vmthread->resume_event = vm_create_event( - NULL, // pointer to security attributes - FALSE, // flag for manual-reset event -- manual mode - TRUE, // flag for initial state - NULL // pointer to event-object name - ); // set when thread is suspended - assert(p_vmthread->resume_event); -#ifdef PLATFORM_POSIX - sem_init(&p_vmthread->yield_other_sem,0,0); -#endif - return p_vmthread; + return (VM_thread *)hythread_tls_get(thr, TLS_key_pvmthread); } -#endif -void free_this_thread_block(VM_thread *p_vmthread) +VM_thread *get_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj) { - assert(quick_thread_id[p_vmthread->thread_index].p_vmthread == p_vmthread); + hythread_t t=jthread_get_native_thread(jThreadObj); + if(t == NULL) { + return NULL; + } + return (VM_thread *)hythread_tls_get(t, TLS_key_pvmthread); +} - VM_thread *p_thr = p_active_threads_list; - VM_thread *p_old_thr = p_active_threads_list; +VM_thread *get_thread_ptr_stub() +{ - // pull thread out of active threads list - if (p_thr == p_vmthread) - p_active_threads_list = p_thr->p_active; - - else { - while (1) { - if(p_thr == p_vmthread) break; - p_old_thr = p_thr; - p_thr = p_thr->p_active; - } - assert(p_thr); - assert(p_old_thr); - p_old_thr->p_active = p_thr->p_active; - } - - // put it back in the free threads pool - quick_thread_id[p_vmthread->thread_index].p_vmthread = 0; - mon_enter_array[p_vmthread->thread_index].p_thr = NULL; - mon_wait_array[p_vmthread->thread_index].p_thr = NULL; - - // copy the handles into a temporary place - // and put them back after zeroing whole data struct - VmEventHandle aa = p_vmthread->event_handle_monitor; - VmEventHandle bb = p_vmthread->event_handle_sleep; - VmEventHandle cc = p_vmthread->event_handle_notify_or_interrupt; - VmEventHandle ff = p_vmthread->jvmti_resume_event_handle; - VmEventHandle jj = p_vmthread->suspended_event; - VmEventHandle hh = p_vmthread->resume_event; - VmEventHandle gg = p_vmthread->park_event; - #ifdef PLATFORM_POSIX - sem_destroy(&p_vmthread->yield_other_sem); -#endif + return NULL; +} - memset(p_vmthread, 0, sizeof(VM_thread) ); +vm_thread_accessor* get_thread_ptr = get_thread_ptr_stub; +void init_TLS_data() { + hythread_tls_alloc(&TLS_key_pvmthread); + get_thread_ptr = (vm_thread_accessor*) get_tls_helper(TLS_key_pvmthread); + //printf ("init fast call %p\n", get_thread_ptr); +} - vm_reset_event(gg); - p_vmthread->park_event = gg; +void set_TLS_data(VM_thread *thread) { + hythread_tls_set(hythread_self(), TLS_key_pvmthread, thread); + //printf ("sett ls call %p %p\n", get_thread_ptr(), get_vm_thread(hythread_self())); +} - vm_reset_event(aa); - p_vmthread->event_handle_monitor = aa; - vm_reset_event(bb); - p_vmthread->event_handle_sleep = bb; - vm_reset_event(cc); - p_vmthread->event_handle_notify_or_interrupt = cc; - vm_reset_event(ff); - vm_set_event(ff); - p_vmthread->jvmti_resume_event_handle = ff; - vm_reset_event(jj); - p_vmthread->suspended_event = jj; - vm_reset_event(hh); - vm_set_event(hh); - p_vmthread->resume_event = hh; +IDATA jthread_throw_exception(char* name, char* message) { + exn_throw_by_name(name); + return 0; +} -#ifdef PLATFORM_POSIX - sem_init(&p_vmthread->yield_other_sem,0,0); -#endif +/** + * This file contains the functions which eventually should become part of vmcore. + * This localizes the dependencies of Thread Manager on vmcore component. + */ - p_vmthread->p_free = p_free_thread_blocks; - p_free_thread_blocks = p_vmthread; +void *vm_object_get_lockword_addr(jobject monitor){ + return (*(ManagedObject**)monitor)->get_obj_info_addr(); +} +extern "C" char *vm_get_object_class_name(void* ptr) { + return (char*) (((ManagedObject*)ptr)->vt()->clss->name->bytes); } -void tmn_thread_attach() +void* vm_jthread_get_tm_data(jthread thread) { - VM_thread *p_vmthread; - p_vmthread = get_a_thread_block(); - VERIFY(p_vmthread, "Thread attach failure: can't get a thread block"); -// FIXME: following code should be incapsulated into thread manager component. -#ifdef PLATFORM_POSIX - p_vmthread->thread_handle = GetCurrentThreadId(); - p_vmthread->thread_id = GetCurrentThreadId(); -#else //PLATFORM_POSIX - int UNUSED stat = - DuplicateHandle(GetCurrentProcess(), // handle to process with handle to duplicate - GetCurrentThread(), // handle to duplicate - GetCurrentProcess(), // handle to process to duplicate to - // gashiman - Duplicate handle does not do anything on linux - // so it is safe to put type convertion here - (VmEventHandle*)(&(p_vmthread->thread_handle)), // pointer to duplicate handle - 0, // access for duplicate handle - false, // handle inheritance flag - DUPLICATE_SAME_ACCESS // optional actions - ); - assert(stat); -#endif //!PLATFORM_POSIX + JNIEnv *jenv = (JNIEnv*)jni_native_intf; + jclass jThreadClass = jenv->GetObjectClass(thread); + jfieldID field_id = jenv->GetFieldID(jThreadClass, "vm_thread", "J"); + POINTER_SIZE_INT data = (POINTER_SIZE_INT)jenv->GetLongField(thread, field_id); - set_TLS_data(p_vmthread); -} //init_thread_block -void tm_acquire_tm_lock(){ - p_thread_lock->_lock(); + return (void *)data; } -void tm_release_tm_lock(){ - p_thread_lock->_unlock(); +void vm_jthread_set_tm_data(jthread jt, void* nt) { + JNIEnv *jenv = (JNIEnv*)jni_native_intf; + jclass jthreadclass = jenv->GetObjectClass(jt); + jfieldID field_id = jenv->GetFieldID(jthreadclass, "vm_thread", "J"); + jenv->SetLongField(jt, field_id, (jlong)(POINTER_SIZE_INT)nt); } -bool tm_try_acquire_tm_lock(){ - return p_thread_lock->_tryLock(); -} - -tm_iterator_t * tm_iterator_create() +JNIEnv * get_jnienv(void) { - assert(tmn_is_suspend_enabled()); - tm_acquire_tm_lock(); - tm_iterator_t * iterator = (tm_iterator_t *) malloc(sizeof(tm_iterator_t)); - assert(iterator); - iterator->current = p_active_threads_list; - iterator->init = true; - return iterator; + return (JNIEnv*)jni_native_intf; } -int tm_iterator_release(tm_iterator_t * iterator) -{ - free(iterator); - tm_release_tm_lock(); - return 0; +int vm_objects_are_equal(jobject obj1, jobject obj2){ + //ObjectHandle h1 = (ObjectHandle)obj1; + //ObjectHandle h2 = (ObjectHandle)obj2; + if (obj1 == NULL && obj2 == NULL){ + return 1; } - -int tm_iterator_reset(tm_iterator_t * iterator) -{ - iterator->current = p_active_threads_list; - iterator->init = true; + if (obj1 == NULL || obj2 == NULL){ return 0; } - -VM_thread * tm_iterator_next(tm_iterator_t * iterator) -{ - if (iterator->init) { - iterator->init = false; - } else if (iterator->current) { - iterator->current = iterator->current->p_active; + return obj1->object == obj2->object; } - return iterator->current; + +int ti_is_enabled(){ + return VM_Global_State::loader_env->TI->isEnabled(); } Index: vm/vmcore/src/thread/lock_manager.cpp =================================================================== --- vm/vmcore/src/thread/lock_manager.cpp (revision 430048) +++ vm/vmcore/src/thread/lock_manager.cpp (working copy) @@ -32,38 +32,47 @@ Lock_Manager *p_meth_addr_table_lock; Lock_Manager *p_thread_lock; Lock_Manager *p_method_call_lock; -Lock_Manager *p_tm_lock; +Lock_Manager *p_handle_lock; +extern hythread_library_t hythread_lib; +VMEXPORT void jit_lock() { + p_jit_a_method_lock->_lock(); +} +VMEXPORT void jit_unlock() { + p_jit_a_method_lock->_unlock(); +} Lock_Manager::Lock_Manager() -{ +{ // init thread menager if needed + hythread_init(hythread_lib); + UNREF IDATA stat = hymutex_create (&lock, TM_MUTEX_NESTED); + assert(stat==TM_ERROR_NONE); } Lock_Manager::~Lock_Manager() { + UNREF IDATA stat = hymutex_destroy (lock); + assert(stat==TM_ERROR_NONE); } void Lock_Manager::_lock() { - DEBUG_CONTENDS_LOCK (this); - _critical_section.lock(); - DEBUG_PUSH_LOCK (this); + UNREF IDATA stat = hymutex_lock(lock); + assert(stat==TM_ERROR_NONE); } bool Lock_Manager::_tryLock() -{ if(_critical_section.tryLock()) { - DEBUG_PUSH_LOCK (this); - return true; - } - return false; +{ + IDATA stat = hymutex_trylock(lock); + return stat==TM_ERROR_NONE; } void Lock_Manager::_unlock() { - _critical_section.unlock(); - DEBUG_POP_LOCK (this); + UNREF IDATA stat = hymutex_unlock(lock); + assert(stat==TM_ERROR_NONE); } @@ -75,8 +84,7 @@ void Lock_Manager::_unlock_enum() { - _critical_section.unlock(); - DEBUG_POP_LOCK (this); + Lock_Manager::_unlock(); } @@ -89,33 +97,23 @@ bool Lock_Manager::_lock_or_null() { - bool stat = _critical_section.tryLock(); - if (!stat) { - return false; - } - DEBUG_PUSH_LOCK (this); - return true; + return Lock_Manager::_tryLock(); } void Lock_Manager::_unlock_or_null() { - - _critical_section.unlock(); - DEBUG_POP_LOCK (this); + Lock_Manager::_unlock_enum(); } void Lock_Manager::_unlock_enum_or_null() { - _critical_section.unlock(); - DEBUG_POP_LOCK (this); + Lock_Manager::_unlock_enum(); } bool Lock_Manager::_lock_enum_or_null(bool UNREF return_null_on_fail) { - DEBUG_CONTENDS_LOCK (this); - _critical_section.lock(); - DEBUG_PUSH_LOCK (this); - return true; + IDATA stat = hymutex_lock(lock); + return stat==TM_ERROR_NONE; } Index: vm/vmcore/src/thread/object_generic.cpp =================================================================== --- vm/vmcore/src/thread/object_generic.cpp (revision 430048) +++ vm/vmcore/src/thread/object_generic.cpp (working copy) @@ -40,11 +40,13 @@ #include "vm_arrays.h" #include "thread_generic.h" -#include "open/thread.h" + +#include "open/jthread.h" #include "thread_manager.h" #include "object.h" #include "object_generic.h" #include "mon_enter_exit.h" +#include "port_atomic.h" #include "jit_runtime_support_common.h" @@ -52,272 +54,28 @@ #include "interpreter.h" #include "vm_log.h" -mon_wait_fields mon_wait_array[MAX_VM_THREADS]; - -#ifdef _DEBUG -// loose, approximate counts, full of race conditions -int max_notifyAll = 0; -int max_recursion = 0; -int total_sleep_timeouts = 0; -int total_sleep_interrupts = 0; -int total_wait_timeouts = 0; -int total_wait_interrupts = 0; -int total_illegal_mon_state_exceptions = 0; -int iterations_per_thread[MAX_VM_THREADS]; -int max_block_on_mon_enter_loops = 0; -#endif - -static inline bool object_locked_by_current_thread(jobject jobj) { - uint16 current_stack_key = get_self_stack_key(); - bool result = false; - assert(!tmn_is_suspend_enabled()); - result = (STACK_KEY(jobj->object) == current_stack_key); - TRACE2("stack_key", "self = " << current_stack_key - << ", locked by " << STACK_KEY(jobj->object) - << ", result = " << result); - return result; -} - -void notify_internal (jobject jobj, Boolean all) -{ - - tmn_suspend_disable_recursive(); - assert(jobj->object->vt()->clss->vtable->clss->vtable); - - if (!object_locked_by_current_thread(jobj)) +void set_hash_bits(ManagedObject *p_obj) { - tmn_suspend_enable_recursive(); - exn_raise_by_name("java/lang/IllegalMonitorStateException"); - return; - } + uint8 hb = (uint8) (((POINTER_SIZE_INT)p_obj >> 3) & HASH_MASK) ; + // lowest 3 bits are not random enough so get rid of them -#ifdef _DEBUG - int notifyAll_count = 0; -#endif + if (hb == 0) + hb = (23 & HASH_MASK); // NO hash = zero allowed, thus hard map hb = 0 to a fixed prime number - DWORD stat; - int xx; - - for (xx = 1; xx < next_thread_index; xx++) - { - if (mon_wait_array[xx].p_obj == jobj->object) - { - stat = vm_set_event(mon_wait_array[xx].p_thr->event_handle_notify_or_interrupt); -#ifdef _DEBUG - if(!stat) { - WARN("set notify event failed: " << IJGetLastError()); - } -#endif - if (!all) - break; - -#ifdef _DEBUG - notifyAll_count++; - if (notifyAll_count > max_notifyAll) - max_notifyAll = notifyAll_count; -#endif - } - } - tmn_suspend_enable_recursive(); + // don't care if the cmpxchg fails -- just means someone else already set the hash + port_atomic_cas8(P_HASH_CONTENTION_BYTE(p_obj),hb, 0); } -void thread_object_notify (jobject jobj) -{ - java_lang_Object_notify (jobj); -} -void java_lang_Object_notify (jobject jobj) -{ - TRACE2("notify", "Notify " << p_TLS_vmthread->thread_handle << " on " << jobj); - //assert(tmn_is_suspend_enabled()); - - notify_internal(jobj, false); - - //assert(tmn_is_suspend_enabled()); - TRACE2("notify", "Finish Notify " << p_TLS_vmthread->thread_handle << " on " << jobj); -} - -void thread_object_notify_all (jobject jobj) -{ - java_lang_Object_notifyAll (jobj); -} - -void java_lang_Object_notifyAll (jobject jobj) -{ - TRACE2("notify", "Notify all " << p_TLS_vmthread->thread_handle << " on " << jobj); - - notify_internal(jobj, true); - - TRACE2("notify", "Finish notify all " << p_TLS_vmthread->thread_handle << " on " << jobj); -} - -void thread_object_wait_nanos(jobject jobj, int64 msec, int nanosec) { - /* - * We have to do something in the case millis == 0 and nanos > 0, - * because otherwise we'll wait infinitely, also just return whould - * be incorrect because we have to relese lock for a while: - */ - msec += (msec==0 && nanosec>0)?1:0; - java_lang_Object_wait(jobj, msec); -} - -void thread_object_wait(jobject jobj, int64 msec) -{ - java_lang_Object_wait(jobj, msec); -} -int java_lang_Object_wait(jobject jobj, int64 msec) -{ - assert(tmn_is_suspend_enabled()); - - // ? 2003-06-23. The lock needs to be unreserved. - if (msec < 0) - { - exn_raise_by_name("java/lang/IllegalArgumentException"); - return -1; - } - - assert(object_is_valid(jobj)); - tmn_suspend_disable(); - - if (!object_locked_by_current_thread(jobj)) - { - tmn_suspend_enable(); - exn_raise_by_name("java/lang/IllegalMonitorStateException"); - return -1; - } - - VM_thread *p_thr = get_thread_ptr(); - DWORD stat; - // toss stale notifies - stat = vm_reset_event(p_thr->event_handle_notify_or_interrupt); - - // check prior interrupts. - if (p_thr->interrupt_a_waiting_thread) - { - p_thr->interrupt_a_waiting_thread = false; - tmn_suspend_enable(); - exn_raise_by_name("java/lang/InterruptedException"); - - return -1; - } - - tmn_suspend_enable(); - assert(tmn_is_suspend_enabled()); - tm_acquire_tm_lock(); - assert(p_thr->app_status == thread_is_running); - if(msec == 0 /*&& nanos == 0 // added for nanos support*/) { - p_thr->app_status = thread_is_waiting; - } else { - p_thr->app_status = thread_is_timed_waiting; - } - tm_release_tm_lock(); - tmn_suspend_disable(); - assert(p_thr->notify_recursion_count == 0); - assert(mon_wait_array[p_thr->thread_index].p_obj == 0); - mon_wait_array[p_thr->thread_index].p_obj = jobj->object; - p_thr->notify_recursion_count = RECURSION(jobj->object); - RECURSION(jobj->object) = 0; // leave the recursion at zero for the next lock owner - -#ifdef _DEBUG - if (p_thr->notify_recursion_count > max_recursion) - max_recursion = p_thr->notify_recursion_count; -#endif - - STACK_KEY(jobj->object) = FREE_MONITOR; // finally, give up the lock - - - find_an_interested_thread(jobj->object); - tmn_suspend_enable(); - - TRACE2("wait", "thread going to wait " << p_TLS_vmthread->thread_handle); - - assert(tmn_is_suspend_enabled()); - p_thr -> is_suspended = true; - if (msec == 0) - { - stat = vm_wait_for_single_object(p_thr->event_handle_notify_or_interrupt, INFINITE); - assert(stat == WAIT_OBJECT_0); - } - else - { -#if defined (__INTEL_COMPILER) -#pragma warning( push ) -#pragma warning (disable:1683) // to get rid of remark #1683: explicit conversion of a 64-bit integral type to a smaller integral type -#endif - stat = vm_wait_for_single_object(p_thr->event_handle_notify_or_interrupt, (int)msec); - -#if defined (__INTEL_COMPILER) -#pragma warning( pop ) -#endif - - assert( (stat == WAIT_OBJECT_0) || (stat == WAIT_TIMEOUT) ); - } - p_thr -> is_suspended = false; - - TRACE2("wait", "thread finished waiting " << p_TLS_vmthread->thread_handle); - -#ifdef _DEBUG - if (stat == WAIT_OBJECT_0) - total_wait_interrupts++; - else - total_wait_timeouts++; -#endif - - assert(object_is_valid(jobj)); - tmn_suspend_disable(); - //GC may have moved the object sitting in mon_wait_array[], thus reload it - assert(mon_wait_array[p_thr->thread_index].p_obj->vt()->clss->vtable->clss->vtable); - assert(mon_wait_array[p_thr->thread_index].p_obj == jobj->object); // jobj should have been updated too -salikh - - mon_wait_array[p_thr->thread_index].p_obj = 0; - //do we need to do a p4 sfence here? - // lock will do sfence. - tmn_suspend_enable(); - - assert(tmn_is_suspend_enabled()); - tm_acquire_tm_lock(); - - assert(p_thr->app_status == thread_is_waiting || p_thr->app_status == thread_is_timed_waiting); - p_thr->app_status = thread_is_running; - - // now we need to re-acquire the object lock - // since block_on_mon_enter() can block, reload p_obj - tm_release_tm_lock(); //with gc_disabled xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - tmn_suspend_disable(); - - block_on_mon_enter(jobj); - assert(jobj->object->vt()->clss->vtable->clss->vtable); - - assert(object_locked_by_current_thread(jobj)); - - // re-install the recursion count - assert(RECURSION(jobj->object) == 0); - RECURSION(jobj->object) = (uint8)p_thr->notify_recursion_count; - - p_thr->notify_recursion_count = 0; - - tmn_suspend_enable(); - if ( (stat == WAIT_OBJECT_0) && (p_thr->interrupt_a_waiting_thread == true) ) - { - p_thr->interrupt_a_waiting_thread = false; - exn_raise_by_name("java/lang/InterruptedException"); - } - - return stat; - - // ready to return to java code -} - - long generic_hashcode(ManagedObject * p_obj) { if (!p_obj) return 0L; - if ( HASH_CONTENTION(p_obj) & HASH_MASK) - return HASH_CONTENTION(p_obj) & HASH_MASK; + if ( *P_HASH_CONTENTION_BYTE(p_obj) & HASH_MASK) + return *P_HASH_CONTENTION_BYTE(p_obj) & HASH_MASK; set_hash_bits(p_obj); - if ( HASH_CONTENTION(p_obj) & HASH_MASK) - return HASH_CONTENTION(p_obj) & HASH_MASK; + if ( *P_HASH_CONTENTION_BYTE(p_obj) & HASH_MASK) + return *P_HASH_CONTENTION_BYTE(p_obj) & HASH_MASK; ASSERT(0, "All the possible cases are supposed to be covered before"); return 0xff; @@ -338,22 +96,10 @@ return hash; } -#define NEW_ARRAY(X) new_arr = jenv->New##X##Array(length); assert(new_arr); - -#define GET_ARRAY_ELEMENTS(X, Y) src_bytes = jenv->Get##X##ArrayElements((j##Y##Array)jobj, &is_copy); \ - dst_bytes = jenv->Get##X##ArrayElements((j##Y##Array)new_arr, &is_copy); - -#define MEMCPY(X) tmn_suspend_disable(); memcpy(dst_bytes, src_bytes, sizeof(j##X) * length); tmn_suspend_enable(); - -#define RELEASE_ARRAY_ELEMENTS(X, Y) jenv->Release##X##ArrayElements((j##Y##Array)new_arr, (j##Y *) dst_bytes, 0); \ - jenv->Release##X##ArrayElements((j##Y##Array)jobj, (j##Y *)src_bytes, JNI_ABORT); - -#define HANDLE_TYPE_COPY(A, B) NEW_ARRAY(A) GET_ARRAY_ELEMENTS(A, B) MEMCPY(B) RELEASE_ARRAY_ELEMENTS(A, B) - jobject object_clone(JNIEnv *jenv, jobject jobj) { ManagedObject *result; - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); if(!jobj) { // Throw NullPointerException. throw_exception_from_jni(jenv, "java/lang/NullPointerException", 0); Index: vm/vmcore/src/thread/thread_generic.cpp =================================================================== --- vm/vmcore/src/thread/thread_generic.cpp (revision 430048) +++ vm/vmcore/src/thread/thread_generic.cpp (working copy) @@ -41,6 +41,7 @@ #include #endif +#include "open/thread_externals.h" #include "environment.h" #include "vm_strings.h" #include "open/types.h" @@ -60,7 +61,7 @@ #include "vm_threads.h" #include "jni_utils.h" #include "object.h" -#include "open/thread.h" + #include "platform_core_natives.h" #include "heap.h" #include "verify_stack_enumeration.h" @@ -83,7 +84,7 @@ #include "thread_manager.h" #include "object_generic.h" #include "thread_generic.h" -#include "open/thread.h" + #include "mon_enter_exit.h" #include "jni_direct.h" @@ -96,845 +97,78 @@ #include "../m2n_ia32_internal.h" #endif -void __cdecl call_the_run_method2(void *p_xx); +#include "port_malloc.h" -int next_thread_index = 1; // never use zero for a thread index +#include "open/jthread.h" ///////////////////////////////////////////////////////////////////// // Native lib stuff -#if defined (__INTEL_COMPILER) -#pragma warning( push ) -#pragma warning (disable:1683) // to get rid of remark #1683: explicit conversion of a 64-bit integral type to a smaller integral type -#endif -void set_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj, jlong data) -{ - jclass jthreadclass = jenv->GetObjectClass(jThreadObj); - jfieldID field_id = jenv->GetFieldID(jthreadclass, "vm_thread", "J"); - jenv->SetLongField(jThreadObj, field_id, data); -} - -VM_thread *get_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj) -{ - jclass jThreadClass = jenv->GetObjectClass(jThreadObj); - jfieldID field_id = jenv->GetFieldID(jThreadClass, "vm_thread", "J"); - POINTER_SIZE_INT data = (POINTER_SIZE_INT)jenv->GetLongField(jThreadObj, field_id); - - return (VM_thread *)data; -} - -// ToDo: Remove this function. Use get_vm_thread_ptr_safe() instead. -static VM_thread * -my_get_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj) -{ - jclass jThreadClass = jenv->GetObjectClass(jThreadObj); - jfieldID field_id = jenv->GetFieldID(jThreadClass, "vm_thread", "J"); - POINTER_SIZE_INT eetop = (POINTER_SIZE_INT)jenv->GetLongField(jThreadObj, field_id); - return (VM_thread *)eetop; -} //my_get_vm_thread_ptr_safe - -static boolean is_daemon_thread(JNIEnv *jenv, jobject jThreadSelf) -{ - //FIXME should not use JNI here - jclass jthreadclass = jenv->GetObjectClass(jThreadSelf); - jfieldID daemon_id = jenv->GetFieldID(jthreadclass, "daemon", "Z"); - jboolean daemon = jenv->GetBooleanField(jThreadSelf, daemon_id); - return daemon ? TRUE : FALSE; -} //is_daemon_thread - -// Call default constructor for java.lang.Thread object (should be called for main thread) -static bool init_thread_object(JNIEnv *jenv, jobject jthread) -{ - // DRL uses this function to initialize main thread's java.lang.Thread object. - jclass tclazz = FindClass(jenv, "java/lang/Thread"); - assert(tclazz); - - jmethodID tconstr = GetMethodID(jenv, tclazz, "", "()V"); - assert(tconstr); - - CallVoidMethod(jenv, jthread, tconstr); - - if (ExceptionOccurred(jenv)) { - WARN("*** Error: exception occured in main Thread constructor."); - ExceptionDescribe(jenv); - ExceptionClear(jenv); - return false; +IDATA vm_attach() { + //hythread_suspend_disable(); + IDATA status; + status = hythread_global_lock(); + if(status != TM_ERROR_NONE) + return status; + VM_thread * p_vm_thread = get_a_thread_block(); + if (NULL == p_vm_thread) { + TRACE2("thread", "can't get a thread block for a new thread"); + status =hythread_global_unlock(); + assert (status == TM_ERROR_NONE); + return TM_ERROR_OUT_OF_MEMORY; } - return true; -} //init_thread_object - -void thread_sleep(jthread UNREF thread, long millis, int UNREF nanos){ - Java_java_lang_Thread_sleep_generic(jni_native_intf, get_thread_ptr(), millis); -} - -//JNI implementation of Thread.sleep() -void Java_java_lang_Thread_sleep_generic(JNIEnv *jenv, VM_thread * p_thr, int64 msec) -{ - assert(!((unsigned int)(msec >> 32))); // We currently ignore high 32 bits of msec. - - tm_acquire_tm_lock(); - - jint stat; - - stat = vm_reset_event(p_thr->event_handle_notify_or_interrupt); // throw away old vm_set_event()s - assert(stat); - - assert(p_thr->app_status == thread_is_running); - p_thr->app_status = thread_is_sleeping; - - tm_release_tm_lock(); - - assert(tmn_is_suspend_enabled()); - p_thr -> is_suspended = true; - - while (p_thr->interrupt_a_waiting_thread == false) { - stat = vm_wait_for_single_object(p_thr->event_handle_notify_or_interrupt, (int)msec); - - if (stat == WAIT_TIMEOUT) - { -#ifdef _DEBUG - total_sleep_timeouts++; -#endif - break; - } - - // the sleep did not time out and nobody sent us an interrupt - // the only other possibility is that this is a stale notify/notifyAll() - // - // if other threads did a notify()/notifyAll() and between - // the time they selected the current thread and the time they - // do the notifyAll's vm_set_event(), they get preempted for a long enough period of - // time such that the current thread gets to the above WaitForSingleEvent() - // then we ignore this unblocking and loop back to the waitforsingleevent() - // note that we re-wait for the same amount of msec. This should not cause a problem - // since pre-emptive multitasking guarantees a sleep() will be at least - // mseconds or longer. If the system is lightly loaded, the stale notify()s will - // get flushed out quickly. If the system is heavily loaded, the run queues - // are long meaning a sleep will wakeup and go onto a long run queue anyway + set_TLS_data(p_vm_thread); + M2nFrame* p_m2n = (M2nFrame*) STD_MALLOC(sizeof(M2nFrame)); + ObjectHandles* p_handles = (ObjectHandles*) STD_MALLOC (sizeof(ObjectHandlesNew)); + if ((p_m2n==NULL)||(p_handles==NULL)) + { + TRACE2("thread", "can't get a thread block for a new thread"); + status =hythread_global_unlock(); + assert (status == TM_ERROR_NONE); + return TM_ERROR_OUT_OF_MEMORY; } - p_thr -> is_suspended = false; - tmn_suspend_disable(); // to suspend thread if needed - tmn_suspend_enable(); + status =hythread_global_unlock(); + if(status != TM_ERROR_NONE) + return status; - tm_acquire_tm_lock(); - assert(p_thr->app_status == thread_is_sleeping); - p_thr->app_status = thread_is_running; + hythread_suspend_disable(); - if (p_thr->interrupt_a_waiting_thread == true) - { - // this can only happen if someone really did send us an interrupt - p_thr->interrupt_a_waiting_thread = false; -#ifdef _DEBUG - total_sleep_interrupts++; -#endif - tm_release_tm_lock(); - throw_exception_from_jni(jenv, "java/lang/InterruptedException", 0); - return; // gregory - added return here because otherwise we execute - // unlock_enum twice which results in error and failed assert on - // error code from pthread_mutex_unlock that thread doesn't own - // the mutex. The thread doesn't own mutex because it was unlocked in - // this if block - } + m2n_null_init(p_m2n); + m2n_set_last_frame(p_m2n); - tm_release_tm_lock(); -} + oh_null_init_handles(p_handles); -#if defined (__INTEL_COMPILER) -#pragma warning( pop ) -#endif - -void Java_java_lang_Thread_interrupt_generic(VM_thread *p_thr) -{ - if (!p_thr) { - printf("bad interrupt, current thread_index = %d\n", p_TLS_vmthread->thread_index); - return; - } - - p_thr->interrupt_a_waiting_thread = true; - unpark(p_thr); - - jint UNUSED stat = vm_set_event(p_thr->event_handle_notify_or_interrupt); - assert(stat); -} - -void Java_java_lang_Thread_setPriority_generic(VM_thread *p_vm_thread, int pri) -{ - - tm_acquire_tm_lock(); - tmn_suspend_disable(); - - ASSERT(0, "Is not expected to be called"); - - // NOTE: setPriority is actually called before the thread is started - // in which case, p_vm_thread is null... Thread_start will then set the priority - - if(p_vm_thread == 0) { - tmn_suspend_enable(); - tm_release_tm_lock(); - return; - } - if (p_vm_thread->app_status == zip) { - tmn_suspend_enable(); - tm_release_tm_lock(); - return; - } - - int status = p_vm_thread->setPriority(THREAD_PRIORITY_NORMAL + pri - 5); - if(status == 0) { - jint error = IJGetLastError(); - printf ("java_lang_Thread_setPriority error = 0x%x\n", error); - } - - tmn_suspend_enable(); - tm_release_tm_lock(); -} //Java_java_lang_Thread_setPriority_generic - -static void -my_clear_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj) -{ - assert(tmn_is_suspend_enabled()); - jclass jThreadClass = jenv->GetObjectClass(jThreadObj); - jfieldID field_id = jenv->GetFieldID(jThreadClass, "vm_thread", "J"); - jenv->SetLongField(jThreadObj, field_id, (jlong) NULL); - assert(tmn_is_suspend_enabled()); -} //my_clear_vm_thread_ptr_safe - -// This method should be called when Thread.run() execution ended with an exception. -static void process_uncaught_exception(VM_thread *p_vm_thread, ManagedObject *exn) { - // create handle for exception object - ObjectHandle exn_handle = oh_allocate_local_handle(); - exn_handle->object = exn; - - // create handle for java.lang.Thread object - ObjectHandle thread_handle = oh_allocate_local_handle(); - thread_handle->object = (ManagedObject*) p_vm_thread->p_java_lang_thread; - - // lookup Thread.getThreadGroup() method - String *name = VM_Global_State::loader_env->string_pool.lookup("getThreadGroup"); - String *descr = VM_Global_State::loader_env->string_pool.lookup("()Ljava/lang/ThreadGroup;"); - - VTable *p_vtable = (((ManagedObject *)thread_handle->object)->vt()); - Method *getThreadGroup_method = class_lookup_method_recursive(p_vtable->clss, name, descr); - assert(getThreadGroup_method); - - // execute Thread.getThreadGroup() method in order to get threadGroup - jvalue getThreadGroup_args[1]; - jvalue threadGroup; - //tmn_suspend_enable(); - getThreadGroup_args[0].l = (jobject) thread_handle; // this - vm_execute_java_method_array((jmethodID) getThreadGroup_method, &threadGroup, getThreadGroup_args); - //tmn_suspend_disable(); - - // check for exception - ManagedObject* cte = get_current_thread_exception(); - clear_current_thread_exception(); - if (cte || ! threadGroup.l) { - print_uncaught_exception_message(stderr, "thread execution", exn_handle->object); - return; - } - - // lookup ThreadGroup.uncaughtException() method - name = VM_Global_State::loader_env->string_pool.lookup("uncaughtException"); - descr = VM_Global_State::loader_env->string_pool.lookup("(Ljava/lang/Thread;Ljava/lang/Throwable;)V"); - - p_vtable = (((ManagedObject *)threadGroup.l->object)->vt()); - Method *uncaughtException_method = class_lookup_method_recursive(p_vtable->clss, name, descr); - assert(uncaughtException_method); - - // execute ThreadGroup.uncaughtException() method - jvalue uncaughtException_args[3]; - //tmn_suspend_enable(); - uncaughtException_args[0].l = (jobject) threadGroup.l; // this - uncaughtException_args[1].l = (jobject) thread_handle; // Thread - uncaughtException_args[2].l = (jobject) exn_handle; // Throwable - vm_execute_java_method_array((jmethodID) uncaughtException_method, NULL, uncaughtException_args); - //tmn_suspend_disable(); - - // check for exception - cte = get_current_thread_exception(); - clear_current_thread_exception(); - if (cte) { - print_uncaught_exception_message(stderr, "thread execution", exn_handle->object); - return; - } -} - -//JNI implementation -void __cdecl call_the_run_method( void * p_args ) -{ -#ifdef _IA32_ - init_stack_info(); -#ifdef PLATFORM_POSIX - set_guard_stack(); -#endif // PLATFORM_POSIX -#endif // _IA32_ - - //when a new thread created, gc is disabled, because VM thread structure - //was set 0 initially, then gc_enabled_status kept 0 till now - VM_thread *p_vm_thread=(VM_thread *)(((void **)p_args)[0]); - JNIEnv *jenv=(JNIEnv *)(((void **)p_args)[1]); - ObjectHandle jThreadSelf = ((ObjectHandle*)p_args)[2]; - - jvmtiEnv * jvmti_Env = (jvmtiEnv *)((void **)p_args)[3]; - jvmtiStartFunction jvmtiStartProc = (jvmtiStartFunction)((void **)p_args)[4]; - void* jvmtiStartProcArg = ((void **)p_args)[5]; - - set_TLS_data(p_vm_thread); - MARK_STACK_END - - tmn_suspend_disable(); - - m2n_set_last_frame(NULL); - - p_vm_thread->thread_id = GetCurrentThreadId(); - - // Invoke Thread.run() - // BUGBUG its an interface method but we cheat by looking up "run" in the instance instead of going thru interface lookup - String *name = VM_Global_State::loader_env->string_pool.lookup("run"); - String *descr = VM_Global_State::loader_env->string_pool.lookup("()V"); - - VTable *p_vtable = (((ManagedObject *)p_vm_thread->p_java_lang_thread)->vt()); - Method *start_method = class_lookup_method_recursive(p_vtable->clss, name, descr); - assert(start_method); - - SET_THREAD_DATA_MACRO(); - - int old_floating_point_state = 0; - void setup_floating_point_state(int *); - setup_floating_point_state(&old_floating_point_state); - // Set the app_status to "running" just before entering Java code. It is "birthing" till now. - - p_vm_thread->app_status = thread_is_running; - active_thread_count ++; - - // the thread that originally called java_lang_Thread_start() will wait for this event - jint UNUSED stat = vm_set_event(new_thread_started_handle); - assert(stat); - - // The scope of lhs must be very precise to make it work properly - { NativeObjectHandles lhs; - + m2n_set_local_handles(p_m2n, p_handles); + m2n_set_frame_type(p_m2n, FRAME_NON_UNWINDABLE); gc_thread_init(&p_vm_thread->_gc_private_information); - assert(!tmn_is_suspend_enabled()); - tmn_suspend_enable(); - jvmti_send_thread_start_end_event(1); - tmn_suspend_disable(); - - jvalue args[1]; - ObjectHandle h = oh_allocate_local_handle(); - h->object = (ManagedObject*) p_vm_thread->p_java_lang_thread; - args[0].l = (jobject) h; - - if (jvmtiStartProc){ - // ppervov: all JVM TI agent functions must be run with gc enabled - tmn_suspend_enable(); - jvmtiStartProc(jvmti_Env, jenv, jvmtiStartProcArg); - tmn_suspend_disable(); - } else { - //tmn_suspend_enable(); - - vm_execute_java_method_array((jmethodID) start_method, 0, args); - //tmn_suspend_disable(); + assert(!hythread_is_suspend_enabled()); + hythread_suspend_enable(); + return TM_ERROR_NONE; } - assert(!tmn_is_suspend_enabled()); +IDATA vm_detach() { + IDATA status; + VM_thread *p_vm_thread=get_thread_ptr(); - // If an exception resulted from calling the run method, call - // ThreadGroup.uncaughtException() - ManagedObject* exn = get_current_thread_exception(); - clear_current_thread_exception(); - if (exn) - process_uncaught_exception(p_vm_thread, exn); - - void cleanup_floating_point_state(int); - cleanup_floating_point_state(old_floating_point_state); - - clear_current_thread_exception(); - tmn_suspend_enable(); - jvmti_send_thread_start_end_event(0); - tmn_suspend_disable(); - - assert(p_vm_thread->app_status == thread_is_running); - - Method *kill_method = class_lookup_method_recursive(p_vtable->clss, "kill", "()V"); - assert(kill_method); - vm_execute_java_method_array((jmethodID) kill_method, 0, args); - assert(!exn_raised()); - - p_vm_thread->app_status = thread_is_dying; - + hythread_suspend_disable(); +// assert(p_vm_thread->app_status == thread_is_running); gc_thread_kill(&p_vm_thread->_gc_private_information); - - tmn_suspend_enable(); - vm_monitor_enter_slow_handle(jThreadSelf); - - thread_object_notify_all(jThreadSelf); - vm_monitor_exit_handle(jThreadSelf); - - tm_acquire_tm_lock(); - - if (! is_daemon_thread(jenv, (jobject)jThreadSelf)) { - non_daemon_thread_count--; - TRACE2("thread", "non daemon threads removed: " << non_daemon_thread_count); + hythread_suspend_enable(); - } - //--------------------------------------------------------- fix 979 - // pointer to VM_thread structure wasn't cleared and was - // wrongly used after correasponding thread was terminated and - // VM_thread structure was reused for another thread - my_clear_vm_thread_ptr_safe(jenv, (jobject)jThreadSelf); - //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fix 979 - } // end of scope for lhs - - // We should remove those useless global handles - oh_deallocate_global_handle(jThreadSelf); - tmn_suspend_disable(); - - /* - wgs: I did meet with the assertion failure here. The scenario is: - A Thread.run() begins to compile a method, but fails in loading - some exception classes which are necessary for compiling the method, - thus ClassNotFoundException is throwed. Thread.run() has a handler - for all exception, so it catches and exits, but note that the compilation - of the method never finishes. - That might prevent further compilation because we have global compile lock. - - Should we use a defensive way: - if (p_vm_thread->gc_frames != 0) - p_jit_a_method_lock->_unlock(); - */ + status = hythread_global_lock(); + if(status != TM_ERROR_NONE) + return status; assert(p_vm_thread->gc_frames == 0); free_this_thread_block( p_vm_thread ); set_TLS_data(NULL); - THREAD_CLEANUP(); - - TRACE2("thread", "non daemon threads count: " << non_daemon_thread_count); - if (!non_daemon_thread_count) { - TRACE2("thread", "non_daemon_threads_dead_handle set" ); - jint UNUSED stat = vm_set_event(non_daemon_threads_dead_handle); - assert(stat); + status =hythread_global_unlock(); + return status; } - - active_thread_count --; - tm_release_tm_lock(); - vm_endthread(); -} - -void thread_start(JNIEnv* jenv, jobject jthread) -{ - Java_java_lang_Thread_start_generic(jenv, jthread, NULL, NULL, NULL, 5); -} //thread_start - -//JNI implementation -void Java_java_lang_Thread_start_generic(JNIEnv *jenv, jobject jThreadSelf, - jvmtiEnv * jvmtiEnv, jvmtiStartFunction proc, - const void* arg, jint priority) -{ - //GC is enabled in JNI invocation of Java_java_lang_Thread_start - - // get a nursery for child thread. this invocation previously is - // by child thread itself in call_the_run_method() - - //BUGBUG this should throw IllegalThreadStateException - // because field in use means thread is already running - assert(! get_vm_thread_ptr_safe(jenv, jThreadSelf)); - - tm_acquire_tm_lock(); - TRACE2("thread", "starting a new thread"); - - VM_thread * p_vm_thread = get_a_thread_block(); - if (NULL == p_vm_thread) { - tm_release_tm_lock(); - TRACE2("thread", "can't get a thread block for a new thread"); - exn_raise_by_name("java/lang/OutOfMemoryError", - "too many threads created"); - return; - } - - p_vm_thread->p_java_lang_thread = ((ObjectHandle)jThreadSelf)->object; - - set_vm_thread_ptr_safe(jenv, jThreadSelf, (jlong) POINTER_SIZE_INT(p_vm_thread)); - - assert(get_vm_thread_ptr_safe(jenv, jThreadSelf)); - - if (! is_daemon_thread(jenv, (jobject)jThreadSelf)) { - non_daemon_thread_count++; - TRACE2("thread", "non daemon threads total: " << non_daemon_thread_count); - } - ObjectHandle hThreadSelf = oh_allocate_global_handle(); - tmn_suspend_disable(); - hThreadSelf->object = ((ObjectHandle)jThreadSelf)->object; - - void *p_args[7]={(void*)p_vm_thread, (void*)jenv, (void *)hThreadSelf, - (void*)jvmtiEnv, (void*)proc, (void*)arg, (void*)((POINTER_SIZE_INT)priority)}; - - -VmThreadHandle stat = vm_beginthread( - (void(__cdecl *)(void *))call_the_run_method2, - (unsigned)(64*1024), - (void *)p_args); - - if (!stat) { - TRACE2("thread", "thread failed to start, raising OOME"); - free_this_thread_block(p_vm_thread); - tmn_suspend_enable(); - set_vm_thread_ptr_safe(jenv, jThreadSelf, (jlong) 0); - assert(get_vm_thread_ptr_safe(jenv, jThreadSelf) == NULL); - tm_release_tm_lock(); - exn_raise_by_name("java/lang/OutOfMemoryError", - "can't start new thread"); - return; - } - - p_vm_thread->thread_handle = stat; - - Sleep(0); - - // the new thread just resumed above will set new_thread_started_handle - int status; - //FIXME we should release thread_Lock before wait. - status = vm_wait_for_single_object(new_thread_started_handle, INFINITE); - - ASSERT(status != (int)WAIT_FAILED, "Unexpected error while starting new thread: " << IJGetLastError()); - - tmn_suspend_enable(); - assert(thread_is_birthing != p_vm_thread->app_status); - tm_release_tm_lock(); -} //Java_java_lang_Thread_start_generic - - -// -// For IPF configuration this method is defined in nt_exception_filter.cpp -// - -#if !defined(_IPF_) || defined(PLATFORM_POSIX) -#ifdef __INTEL_COMPILER -#pragma optimize("", off) -#endif -void __cdecl call_the_run_method2(void *p_args) -{ - VM_thread *p_vm_thread; - p_vm_thread = (VM_thread *)(((void **)p_args)[0]); - - set_TLS_data(p_vm_thread); - - // Hyperthreading (HT) optimization. We allocate extra space on the stack - // so that each thread's stack is "misaligned" with other threads' stacks. - // The offset is 256*thead_index, capped at 16KB. - if (VM_Global_State::loader_env->is_hyperthreading_enabled) - { - STD_ALLOCA(((p_TLS_vmthread->thread_index - 1) % 64) * 256); - } - -#ifdef PLATFORM_POSIX - call_the_run_method( p_args ); -#else // !PLATFORM_POSIX - - // A temporary patch needed to support j9 class libraries. - // TODO: remove it after the needed subset of j9thread functions is implemented. - - { - static HINSTANCE hDLL; // Handle to j9thr23.dll - typedef void* (*lpFunc)(void*); // - static lpFunc func; // j9thread_attach proc address - static boolean firstAttempt = true; - - if (firstAttempt) { - hDLL = GetModuleHandle("j9thr23.dll"); - // hDLL = LoadLibrary("j9thr23"); - - if (hDLL != NULL) { - func = (lpFunc)GetProcAddress(hDLL, "j9thread_attach"); - } - } - - if (func != NULL) { - func(NULL); // Attach to j9thread - } - } - - call_the_run_method( p_args ); -#endif //#ifdef PLATFORM_POSIX - -} -#ifdef __INTEL_COMPILER -#pragma optimize("", on) -#endif -#endif // !_IPF_ - - - //////////////////////////////////////////////////////////////////////////////////////////// //////// CALLED by vm_init() to initialialize thread groups and create the main thread //// -//////////////////////////////////////////////////////////////////////////////////////////// - - -bool init_threadgroup() -{ - NativeObjectHandles lhs; // allows us to create handles in native code not called from JITed code - - Global_Env *env = VM_Global_State::loader_env; - JNIEnv *jenv = (JNIEnv *)jni_native_intf; - - assert(tmn_is_suspend_enabled()); - - // Load, prepare and initialize the "Thread class" - String *ss = env->string_pool.lookup("java/lang/Thread"); - Class *thread_clss = env->bootstrap_class_loader->LoadVerifyAndPrepareClass(env, ss); - assert(tmn_is_suspend_enabled()); - tmn_suspend_disable(); - class_initialize(thread_clss); - assert(!tmn_is_suspend_enabled()); - - ObjectHandle jThreadClass = oh_allocate_local_handle(); - ObjectHandle jname = oh_allocate_local_handle(); - ObjectHandle jMainThreadObj = oh_allocate_local_handle(); - jThreadClass->object = struct_Class_to_java_lang_Class(thread_clss); - jname->object = string_create_from_utf8("init", 4); - - // Allocate the Thread object for ... public static void main(String args[]) - // Volatile needed here since GC is enabled by JNI functions below and the use of - // "main_thread_obj" after the JNI calls shouldnt become stale. - volatile ManagedObject *main_thread_obj = class_alloc_new_object(thread_clss); - assert(main_thread_obj); - - jMainThreadObj->object = (ManagedObject *) main_thread_obj; - - p_TLS_vmthread->thread_id = GetCurrentThreadId(); - p_TLS_vmthread->p_java_lang_thread = jMainThreadObj->object; - tmn_suspend_enable(); - assert(tmn_is_suspend_enabled()); - - // Set all all attributes for "main" thread - set_vm_thread_ptr_safe(jenv, (jobject)jMainThreadObj, (jlong) POINTER_SIZE_INT(p_TLS_vmthread)); - - // Call constructor for java.lang.Thread object of "main" thread - if (! init_thread_object(jenv, (jobject) jMainThreadObj)) - return false; - - int UNUSED stat = - DuplicateHandle(GetCurrentProcess(), // handle to process with handle to duplicate - GetCurrentThread(), // handle to duplicate - GetCurrentProcess(), // handle to process to duplicate to - // gashiman - Duplicate handle does not do anything on linux - // so it is safe to put type convertion here - (VmEventHandle*)&(p_TLS_vmthread->thread_handle), // pointer to duplicate handle - 0, // access for duplicate handle - false, // handle inheritance flag - DUPLICATE_SAME_ACCESS // optional actions - ); - assert(stat); - - p_TLS_vmthread->thread_id = GetCurrentThreadId(); - -#ifdef PLATFORM_POSIX -#else - assert(p_TLS_vmthread->event_handle_monitor); -#endif - - return true; -} //init_threadgroup - -// Alexei -// migrating to C interfaces for Linux -#if (defined __cplusplus) && (defined PLATFORM_POSIX) -extern "C" { -#endif - -jobject thread_current_thread() -{ - void *thread_ptr = get_thread_ptr(); - tmn_suspend_disable(); //------------v----------- - ObjectHandle hThread = NULL; - ManagedObject* object = (struct ManagedObject *)((VM_thread*)thread_ptr)->p_java_lang_thread; - if (object) - { - hThread = oh_allocate_local_handle(); - hThread->object = object; - } - tmn_suspend_enable(); //------------^----------- - return (jobject)hThread; -} //thread_current_thread - -bool thread_is_alive(jthread thread) -{ - VM_thread *p_vmthread = my_get_vm_thread_ptr_safe(jni_native_intf, thread); - if ( !p_vmthread ) { - return 0; // don't try to isAlive() non-existant thread - } - - java_state as = p_vmthread->app_status; - - // According to JAVA spec, this method should return true, if and - // only if the thread has been started and not yet died. - switch (as) { - case thread_is_sleeping: - case thread_is_waiting: - case thread_is_timed_waiting: - case thread_is_blocked: - case thread_is_running: - case thread_is_birthing: - return 1; - //break; // exclude remark #111: statement is unreachable - case thread_is_dying: - case zip: - return 0; - //break; // exclude remark #111: statement is unreachable - default: - DIE("big problem in java_lang_Thread_isAlive(), p_vmthread->appstatus == " << ((int)as)); - return 0; - //break; // exclude remark #111: statement is unreachable - } - // must return from inside the switch statement // remark #111: statement is unreachable -} //thread_is_alive - -void thread_suspend(jobject jthread) -{ - tm_acquire_tm_lock(); - // if thread is not alived do nothing - if(!thread_is_alive(jthread)) { - tm_release_tm_lock(); - return; - } - VM_thread * vm_thread = get_vm_thread_ptr_safe(jni_native_intf, jthread); - thread_suspend_generic(vm_thread); - tm_release_tm_lock(); -} - -void thread_resume(jobject jthread) -{ - tm_acquire_tm_lock(); - // if thread is not alived do nothing - if(!thread_is_alive(jthread)) { - tm_release_tm_lock(); - return; - } - VM_thread * vm_thread = get_vm_thread_ptr_safe(jni_native_intf, jthread); - thread_resume_generic(vm_thread); - tm_release_tm_lock(); -} - -void thread_join(jthread thread, long millis, int UNREF nanos) -{ - assert(thread); - VM_thread* self = get_thread_ptr(); - - vm_monitor_enter_slow_handle(thread); - while (thread_is_alive(thread) - && WAIT_TIMEOUT != java_lang_Object_wait(thread, millis) - && false == self->interrupt_a_waiting_thread ) { - // propogate not our notify - // in any case spurious notify allowed by spec - thread_object_notify(thread); - } - vm_monitor_exit_handle(thread); -} //thread_join - -void thread_interrupt(jobject jthread) -{ - VM_thread *p_vmthread = my_get_vm_thread_ptr_safe(jni_native_intf, jthread); - //XXX this is a temporary solution - // the upcoming threading design should eliminate the cases no object - // representing a thread exists - if (p_vmthread) { - Java_java_lang_Thread_interrupt_generic(p_vmthread); - } -} - -bool thread_is_interrupted(jobject thread, bool clear) -{ - VM_thread *p_thr = my_get_vm_thread_ptr_safe(jni_native_intf, thread); - //XXX this is a temporary solution - // the upcoming threading design should eliminate the cases no object - // representing a thread exists - if (p_thr){ - jboolean res = (jboolean)(p_thr->interrupt_a_waiting_thread ? TRUE : FALSE); - if (clear) p_thr->interrupt_a_waiting_thread = false; - return res; - } - return FALSE; -} - -void* thread_get_interrupt_event() -{ - VM_thread* thr = get_thread_ptr(); - return (void*)thr->event_handle_notify_or_interrupt; -} - -#if (defined __cplusplus) && (defined PLATFORM_POSIX) -} -#endif - -int parktimed(jlong milis, jint nanos) { - assert(tmn_is_suspend_enabled()); - int ret_val; - if (milis<=0 && nanos <=0) return 0; - - ret_val = WaitForSingleObject(p_TLS_vmthread->park_event,(DWORD)milis); - - return ret_val; -} - -int parkuntil(jlong milis, jint UNREF nanos) { - assert(tmn_is_suspend_enabled()); - int ret_val; - jlong delta = milis - get_current_time(); - if (delta <= 0) return 0; - - ret_val = WaitForSingleObject(p_TLS_vmthread->park_event, (DWORD)delta); - - return ret_val; -} - -int park(void) { - assert(tmn_is_suspend_enabled()); - int ret_val; - ret_val = WaitForSingleObject(p_TLS_vmthread->park_event, INFINITE); - - return ret_val; -} - -int unpark(VM_thread *thread) { - return SetEvent(thread->park_event); -} - -void wait_until_non_daemon_threads_are_dead() { - tm_acquire_tm_lock(); - - if(!non_daemon_thread_count) { - tm_release_tm_lock(); - return; - } - tm_release_tm_lock(); - - // the following lines allow MSVC++ "Debug->>>Break" to work - while (1) { - DWORD stat = vm_wait_for_single_object(non_daemon_threads_dead_handle, 2000); - if (stat == WAIT_OBJECT_0) { - INFO("VM is signalled to shutdown"); - break; - } - assert(stat != WAIT_FAILED); - - } - -} //wait_until_non_daemon_threads_are_dead - -void terminate_all_threads() { - tm_iterator_t * iterator = tm_iterator_create(); - VM_thread *self = p_TLS_vmthread; - volatile VM_thread *p_scan = tm_iterator_next(iterator); - while (p_scan) { - if(p_scan != self) { - vm_terminate_thread (p_scan->thread_handle); - } - p_scan = tm_iterator_next(iterator); - } - tm_iterator_release(iterator); -} Index: vm/vmcore/src/thread/thread_dump.cpp =================================================================== --- vm/vmcore/src/thread/thread_dump.cpp (revision 430048) +++ vm/vmcore/src/thread/thread_dump.cpp (working copy) @@ -27,7 +27,7 @@ #include "jni_utils.h" #include "jit_intf_cpp.h" #include "dll_jit_intf.h" -#include "open/thread.h" + #include "object_generic.h" #include "root_set_enum_internal.h" #include "lock_manager.h" @@ -38,7 +38,6 @@ static std::set unique_references; -static int stack_key; enum reference_types { root_reference = 1, @@ -47,493 +46,26 @@ managed_reference_with_base }; -static void td_print_thread_dumps(FILE* f); + void td_print_thread_dumps(FILE* f); #ifdef _DEBUG -static void td_print_native_dumps(FILE* f); -#endif -static void td_attach_thread(void( *printer)(FILE *), FILE *out); - -/** - * The thread dump entry poin, this function being called from the signal handler - */ -void td_dump_all_threads(FILE *out) { -#ifdef _DEBUG - td_print_native_dumps(out); -#endif - td_attach_thread(td_print_thread_dumps, out); -} - -/** - * Attaches current thread to vm and runs the given "Thread dump" thread function. - */ -static void td_attach_thread(void( *printer)(FILE *), FILE *out) { - VM_thread *current; - current = get_a_thread_block(); - - if (NULL == current) { - WARN("Thread dump: can't get a thread block"); - return; - } - - p_thread_lock->_lock_enum(); - - set_TLS_data(current); - #ifdef PLATFORM_POSIX - current->thread_handle = getpid(); - //MVM - current->thread_id = GetCurrentThreadId(); + void td_print_native_dumps(FILE* f); #endif - tmn_suspend_enable(); - - { - NativeObjectHandles lhs; - gc_thread_init(¤t->_gc_private_information); + void td_attach_thread(void( *printer)(FILE *), FILE *out); - printer(out); - } - - free_this_thread_block(current); - set_TLS_data(NULL); - gc_thread_kill(¤t->_gc_private_information); - p_thread_lock->_unlock_enum(); -} - -/** - * Returns java.lang.Thread pointer associated with te given VM_thread - */ -static jthread get_jthread(VM_thread * thread) { - if (thread->p_java_lang_thread) { - tmn_suspend_enable(); - ObjectHandle hThread = oh_allocate_global_handle(); - tmn_suspend_disable(); - hThread->object = (struct ManagedObject *)thread->p_java_lang_thread; - - tmn_suspend_enable(); - - return (jthread)hThread; - } else { - return NULL; - } -} - -/** - * Prints monitors owned by the currently processed thread. - * During stack traversing JIT being called for live object enumeration. Object returned, - * being checked if their "lockword" contains thread key of the current thread. Those objects which - * maches being collected in the unique references set. - * - * This function prints objects collected and frees the set for the next thread; - */ -static void td_print_owned_monitors(FILE *out) { - if (unique_references.size()) { - std::set::const_iterator it; - fprintf(out, "Thread owns following monitors:\n"); - ObjectHandle jmon = oh_allocate_local_handle(); - ObjectHandle jmon_class = oh_allocate_local_handle(); - for (it = unique_references.begin(); it != unique_references.end(); it++) { - ManagedObject *p_obj = (ManagedObject *)*it; - - tmn_suspend_disable(); //---------------------------------v - jmon_class->object = struct_Class_to_java_lang_Class(p_obj->vt()->clss); - jmon->object = p_obj; - tmn_suspend_enable(); //---------------------------------^ - - - JNIEnv *jenv = (JNIEnv *)jni_native_intf; - jmethodID mon_name = jenv -> GetMethodID(jmon_class, "getName","()Ljava/lang/String;"); - jstring _mon_name = jenv -> CallObjectMethod (jmon, mon_name); - char *class_name = (char *)jenv -> GetStringUTFChars (_mon_name, false); - - fprintf(stderr, " - %s@0x%ld\n", class_name, generic_hashcode(p_obj)); - } - - unique_references.clear(); - } - -} - -/** - * Prints symbolic name for the given numeric java state. - */ -static char *print_thread_state(java_state state) { - static char *names[8] = {"zip", - "sleeping", - "waiting", - "timed_waiting", - "birthing", - "running", - "blocked", - "dying"}; - - return names[state]; -} - -/** - * checks if the thread is alive. - * Note: - * Only alive threads being processed during the thread dump. - */ -static int td_is_alive(VM_thread *thread) { - if ( !thread ) { - return 0; // don't try to isAlive() non-existant thread - } - - if (thread->app_status == zip) { - return 0; // don't try to isAlive() non-existant thread - } - java_state as = thread->app_status; - - // According to JAVA spec, this method should return true, if and - // only if the thread has been started and not yet died. - switch (as) { - case thread_is_sleeping: - case thread_is_waiting: - case thread_is_timed_waiting: - case thread_is_blocked: - case thread_is_running: - return 1; - case thread_is_dying: - case thread_is_birthing: - return 0; - default: - return 0; - } -} - -/** - * Print java.lang.Thread info in the following format: - * "" prio= id= - * ^--- - if blocked or waiting - * - * Returns true if jthread header was successfully printed; - */ -static bool td_print_java_thread_info(FILE *f, VM_thread *thread, bool *is_header_printed) { - static JNIEnv *jenv = (JNIEnv *)jni_native_intf; - static jclass cl = jenv -> FindClass("java/lang/Thread"); - static jmethodID method_name = jenv -> GetMethodID(cl, "getName","()Ljava/lang/String;"); - static jmethodID method_prio = jenv -> GetMethodID(cl, "getPriority","()I"); - - - jthread _jthread = get_jthread(thread); - if (!_jthread) { - return false; - } else { - if (!*is_header_printed) { - *is_header_printed = true; - fprintf(f,"=== FULL THREAD DUMP\n"); - } - } - - jstring name = jenv -> CallObjectMethod (_jthread, method_name); - char *_name = (char *)jenv -> GetStringUTFChars (name, false); - jint prio = jenv -> CallIntMethod(_jthread, method_prio); - java_state thread_st = thread->app_status; - - fprintf(f,"\"%s\" prio=%d id=0x%lX skey=0x%lX %s\n", - _name, prio, (long)thread->thread_id, thread->stack_key, print_thread_state(thread_st)); - - if (thread_st == 2 - || thread_st == 3 - || thread_st == 6) { - //blocked/waiting on monitor - //// - ManagedObject *p_mon = mon_enter_array[thread->thread_index].p_obj; - if (p_mon) { - ObjectHandle jmon = oh_allocate_local_handle(); - ObjectHandle jmon_class = oh_allocate_local_handle(); - tmn_suspend_disable(); //---------------------------------v - jmon_class->object= struct_Class_to_java_lang_Class(p_mon->vt()->clss); - jmon->object = p_mon; - tmn_suspend_enable(); //---------------------------------^ - - - jmethodID mon_name = jenv -> GetMethodID(jmon_class, "getName","()Ljava/lang/String;"); - jstring _mon_name = jenv -> CallObjectMethod (jmon, mon_name); - char *class_name = (char *)jenv -> GetStringUTFChars (_mon_name, false); - - fprintf(f,"^--- %s on monitor : %s@%lx\n", print_thread_state(thread_st), class_name, generic_hashcode(p_mon)); - } - } - return true; -} - -/** - * Prints stack trace entry in the following format: - * - * at .()@, - * - * where source info is on of the following: - * - : - * - Native source - * - Unknown source - */ -static void td_print_entry(FILE *f, Method_Handle m, int ip, bool is_native) { - const char *file_name; - - fprintf(f, " at %s.%s%s(", class_get_name(method_get_class(m)), method_get_name(m), method_get_descriptor(m)); - - if (is_native) { - fprintf(f,"Native Method)\n"); - } else { - file_name = class_get_source_file_name(method_get_class(m)); - - if (file_name) { - fprintf(f,"%s : %d", file_name, m->get_line_number((uint16)ip)); - } else { - fprintf(f,"Unknown Source"); - } - fprintf(f,")@0x%X\n", ip); - } -} - - -static void td_print_thread_dumps(FILE* f) { - bool print_footer = false; - suspend_all_threads_except_current_generic(); - VM_thread *thread = p_active_threads_list; - - - while(thread) { - if (!(td_is_alive(thread) && td_print_java_thread_info(f, thread, &print_footer))) { - thread = thread->p_active; - continue; - } - - stack_key = thread->stack_key; - StackIterator* si = si_create_from_native(thread); - unsigned depth = 0; - - while (!si_is_past_end(si)) { - Method_Handle m = get_method(si); - if (m) { - CodeChunkInfo* cci = si_get_code_chunk_info(si); - if ( cci != NULL ) { - cci->get_jit()->get_root_set_for_thread_dump(cci->get_method(), 0, si_get_jit_context(si)); - uint32 inlined_depth = si_get_inline_depth(si); - uint32 offset = (POINTER_SIZE_INT)si_get_ip(si) - (POINTER_SIZE_INT)cci->get_code_block_addr(); - - for (uint32 i = 0; i < inlined_depth; i++) { - Method *real_method = cci->get_jit()->get_inlined_method(cci->get_inline_info(), offset, i); - - td_print_entry(f, real_method, offset, false); - depth++; - } - } - - td_print_entry(f, m, (uint8*)si_get_ip(si) - (uint8*)((Method *)m)->get_byte_code_addr(), si_is_native(si)); - } - - depth++; - si_goto_previous(si); - } - si_free(si); - - td_print_owned_monitors(f); - - fprintf(f, "--- End Stack Trace (0x%X, depth=%d)\n\n", thread, depth); - thread = thread->p_active; - - } - - if (print_footer) fprintf(f,"=== END OF THREAD DUMP\n\n"); - resume_all_threads_generic(); -} - VMEXPORT void vm_check_if_monitor(void **reference, - void **reference_base, + void **base_reference, uint32 *compressed_reference, int slotOffset, Boolean pinned, int type) { - - ManagedObject *p_obj = NULL; - - if (!(type>0 && type<5)) return; - - switch((reference_types)type) { - case root_reference: { - if (reference) { - p_obj = (ManagedObject *)*reference; - } - break; - } - - case compresses_root_reference: { - COMPRESSED_REFERENCE cref = *compressed_reference; - ManagedObject* obj = (ManagedObject *)uncompress_compressed_reference(cref); - if (cref != 0 - && (((POINTER_SIZE_INT)Class::heap_base <= (POINTER_SIZE_INT)obj) - && ((POINTER_SIZE_INT)obj <= (POINTER_SIZE_INT)Class::heap_end)) - ) { - p_obj = obj; - } - break; - } - - case managed_reference_with_base: { - slotOffset = (int)(POINTER_SIZE_INT)(*((Byte**)reference)-*((Byte**)reference_base)); - - } - - case managed_reference: { - p_obj = (ManagedObject *)((Byte*)*reference - slotOffset); - break; - } - - default : return; - } - - if (p_obj) { - uint16 *sk = P_STACK_KEY(p_obj); - - if(stack_key == *sk) { - unique_references.insert(p_obj); - } - } } +/** + * The thread dump entry poin, this function being called from the signal handler + */ +void td_dump_all_threads(FILE *out) { #ifdef _DEBUG - -char* get_lock_name(void* lock) { - if(p_thread_lock == lock) { - return "p_thread_lock"; - } - if(p_jit_a_method_lock == lock) { - return "p_jit_a_method_lock"; - } - if(p_vtable_patch_lock == lock) { - return "p_vtable_patch_lock"; - } - if(p_meth_addr_table_lock == lock) { - return "p_meth_addr_table_lock"; - } - if(p_method_call_lock == lock) { - return "p_method_call_lock"; - } - if(p_tm_lock == lock) { - return "p_tm_lock"; - } - if (JAVA_CODE_PSEUDO_LOCK == lock) { - return "java_code"; - } - return "unknown"; -} - -int get_lock_priority(void* lock) { - if(p_thread_lock == lock) { - return 10; - } - if(p_vtable_patch_lock == lock) { - return 30; - } - if(p_meth_addr_table_lock == lock) { - return 40; - } - - if(p_method_call_lock == lock) { - return 50; - } - if(p_jit_a_method_lock == lock) { - return 55; - } - if (JAVA_CODE_PSEUDO_LOCK == lock) { - return 70; - } - return -1; -} - - -void check_lock_order(VM_thread *thread) { - if (!thread) { - INFO("Cannot check lock order without a thread block"); - return; - } - - int lock_id = thread->locks_size-1; - if(lock_id < 1) { - return; - } - void *last_lock = thread->locks[thread->locks_size-1]; - if(get_lock_priority(last_lock) == -1) { - return; - } - - int lock_priority; - void *prev_lock; - for (lock_id= lock_id-1; lock_id >=0; lock_id--) { - prev_lock = thread->locks[lock_id]; - lock_priority = get_lock_priority(prev_lock); - if(lock_priority !=-1 && get_lock_priority(last_lock) > get_lock_priority(prev_lock)) { - LOG2("deadlock", "possible deadlock (incorrect lock order):" << get_lock_name(last_lock) << " after " << get_lock_name(prev_lock) ); - } - } - -} - -void push_lock(VM_thread *thread, void* lock) -{ - if (!thread) { - INFO("Attempt to push " << get_lock_name(lock) << " without a thread block"); - return; - } - - TRACE("Thread " << thread->thread_handle << " acquired " << get_lock_name(lock) << " lock"); - //assert(thread->contendent_lock == lock); - thread->contendent_lock = NULL; - thread->locks[thread->locks_size++] = lock; - ASSERT(thread->locks_size < MAX_THREAD_LOCKS, "Debugging lock stack overflowed. Last locks: " \ - << get_lock_name(thread->locks[thread->locks_size - 1]) << ", " \ - << get_lock_name(thread->locks[thread->locks_size - 2]) << ", " \ - << get_lock_name(thread->locks[thread->locks_size - 3]) << ", " \ - << get_lock_name(thread->locks[thread->locks_size - 4])); - - check_lock_order(thread); - -} - -void pop_lock(VM_thread *thread, void* lock) { - if (!thread) { - INFO("Attempt to pop " << get_lock_name(lock) << " without a thread block"); - return; - } - TRACE("Thread " << thread->thread_handle << " released " << get_lock_name(lock) << " lock"); - ASSERT(thread->locks_size > 0, "Lock stack is empty, unexpected unlock " << get_lock_name(lock)); - - void *res = thread->locks[--thread->locks_size]; - ASSERT(res == lock, "Incorrect order, expected unlocking " << get_lock_name(res) \ - << " before unlocking " << get_lock_name(lock) << ", thread block is " << thread); -} - -void contends_lock(VM_thread *thread, void* lock) { - if (!thread) { - INFO("Attempt to contend on " << get_lock_name(lock) << " without a thread block"); - return; - } - - //assert(thread->contendent_lock == NULL); - thread->contendent_lock=lock; -} - -static void td_print_native_dumps(FILE* f) { - VM_thread *thread = p_active_threads_list; - fprintf (f, "Native thread locks dump:\n"); - while(thread) { - fprintf(f, "thread %ld locks:", thread->thread_id); - if(thread->suspend_enabled_status) { - fprintf(f, " suspend_disabled%d, ", thread->suspend_enabled_status); - if(thread->suspend_request) { - fprintf(f, " suspend_request = %d, ", thread->suspend_request); - } - } - for (int i= 0; i < thread->locks_size; i++) { - fprintf(f, "%s, ", get_lock_name(thread->locks[i])); - } - if(thread->contendent_lock) { - fprintf(f, "\n\t contends on %s\n", get_lock_name(thread->contendent_lock)); - } else { - fprintf(f, "\n"); - } - thread = thread->p_active; - } -} +// td_print_native_dumps(out); #endif + // td_attach_thread(td_print_thread_dumps, out); +} Index: vm/vmcore/src/thread/hythr/hythreads.h =================================================================== --- vm/vmcore/src/thread/hythr/hythreads.h (revision 430048) +++ vm/vmcore/src/thread/hythr/hythreads.h (working copy) @@ -1,90 +0,0 @@ -/* - * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * @author Artem Aliev - * @version $Revision: 1.1.2.1.4.4 $ - */ -#include "vm_threads.h" -#include -#include -#include -#include -#include - -#include -#include - -#define GLOBAL_MONITOR_NAME "global_monitor" -extern "C" -{ - -JNIEXPORT void __cdecl hythread_init (void* lib); -// ========================== MONITOR ================================================ -struct hymonitor { - char* name; - apr_thread_mutex_t *mutex; - apr_thread_cond_t *cond; -}; - -typedef hymonitor* hythread_monitor_t; - -JNIEXPORT int __cdecl hythread_monitor_init_with_name (hythread_monitor_t* handle, unsigned flags, char* name); -JNIEXPORT int __cdecl -hythread_monitor_destroy (hythread_monitor_t monitor); -JNIEXPORT int __cdecl -hythread_monitor_try_enter (hythread_monitor_t monitor); -JNIEXPORT int __cdecl -hythread_monitor_enter (hythread_monitor_t monitor); -JNIEXPORT int __cdecl -hythread_monitor_exit (hythread_monitor_t monitor); -JNIEXPORT int __cdecl -hythread_monitor_notify (hythread_monitor_t monitor); -JNIEXPORT int __cdecl -hythread_monitor_notify_all (hythread_monitor_t monitor); -JNIEXPORT int __cdecl -hythread_monitor_wait (hythread_monitor_t monitor); - -// ======================= ATTACH ====================================== -typedef apr_os_thread_t hythread_t; - -JNIEXPORT int __cdecl -hythread_attach (hythread_t* handle); -JNIEXPORT void __cdecl -hythread_detach (hythread_t handle); -JNIEXPORT hythread_t __cdecl hythread_self(); -JNIEXPORT int __cdecl -hythread_exit (hythread_monitor_t monitor); - -JNIEXPORT unsigned* __cdecl -hythread_global (char* name); - -// ==================== create thread ==================== -typedef int(__cdecl* hythread_entrypoint_t)(void*); -JNIEXPORT int __cdecl -hythread_create(hythread_t* handle, unsigned stacksize, unsigned priority, unsigned suspend, hythread_entrypoint_t entrypoint, void* entryarg); -// ================== TLS ======================================= -typedef apr_threadkey_t* hythread_tls_key_t; - -JNIEXPORT int __cdecl -hythread_tls_alloc (hythread_tls_key_t* handle); -JNIEXPORT int __cdecl -hythread_tls_free (hythread_tls_key_t key); -JNIEXPORT void* __cdecl -hythread_tls_get (hythread_t thread, hythread_tls_key_t key); -JNIEXPORT int __cdecl -hythread_tls_set (hythread_t thread, hythread_tls_key_t key, void* value); - -}// extern "C" Index: vm/vmcore/src/thread/hythr/hythr.exp =================================================================== --- vm/vmcore/src/thread/hythr/hythr.exp (revision 430048) +++ vm/vmcore/src/thread/hythr/hythr.exp (working copy) @@ -1,22 +0,0 @@ -HYTHR_0.1 { - global : - hythread_attach; - hythread_create; - hythread_detach; - hythread_exit; - hythread_global; - hythread_monitor_destroy; - hythread_monitor_enter; - hythread_monitor_exit; - hythread_monitor_init_with_name; - hythread_monitor_notify; - hythread_monitor_notify_all; - hythread_monitor_try_enter; - hythread_monitor_wait; - hythread_self; - hythread_tls_alloc; - hythread_tls_free; - hythread_tls_get; - hythread_tls_set; - local : *; -}; Index: vm/vmcore/src/thread/hythr/hythr.def =================================================================== --- vm/vmcore/src/thread/hythr/hythr.def (revision 430048) +++ vm/vmcore/src/thread/hythr/hythr.def (working copy) @@ -1,22 +0,0 @@ -LIBRARY HYTHR - -EXPORTS - hythread_attach - hythread_create - hythread_detach - hythread_exit - hythread_global - hythread_monitor_destroy - hythread_monitor_enter - hythread_monitor_exit - hythread_monitor_init_with_name - hythread_monitor_notify - hythread_monitor_notify_all - hythread_monitor_try_enter - hythread_monitor_wait - hythread_self - hythread_tls_alloc - hythread_tls_free - hythread_tls_get - hythread_tls_set - Index: vm/vmcore/src/thread/hythr/hythreads.cpp =================================================================== --- vm/vmcore/src/thread/hythr/hythreads.cpp (revision 430048) +++ vm/vmcore/src/thread/hythr/hythreads.cpp (working copy) @@ -1,290 +0,0 @@ -/* - * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - * @author Artem Aliev - * @version $Revision: 1.1.2.1.4.5 $ - */ -#include "hythreads.h" -#include "log_macro.h" - - -#ifdef WIN32 -#include -#endif - -#define GLOBAL_MONITOR_NAME "global_monitor" - -#define RET_ON_ERROR(stat) if(stat) { return -1; } - -extern "C" -{ - -JNIEXPORT void __cdecl hythread_init(void* lib); - -#ifdef WIN32 -BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpres) { - if (dwReason == DLL_PROCESS_ATTACH) { - hythread_init (NULL); - } - return TRUE; -} -#else -void __cdecl hythread_library_init(void) { - hythread_init(NULL); - -} -#endif - - -hythread_monitor_t p_global_monitor; -// Will do all initilalization of thread library. -// init global_monitor now. -JNIEXPORT void __cdecl hythread_init (void* lib) { - apr_initialize(); - hythread_monitor_init_with_name(&p_global_monitor, 0, "Thread Global Monitor"); - hythread_monitor_t *mon = (hythread_monitor_t*)hythread_global(GLOBAL_MONITOR_NAME); - *mon = p_global_monitor; -} - - - -// ========================== MONITOR impl ================================================ - -static apr_pool_t* get_pool() { - apr_pool_t *pool; - apr_pool_create(&pool, 0); - return pool; -} - -JNIEXPORT int __cdecl hythread_monitor_init_with_name (hythread_monitor_t* handle, unsigned flags, char* name) { - apr_status_t stat; - - apr_pool_t *pool; - apr_pool_create(&pool, 0); - *handle = (hythread_monitor_t) apr_palloc(pool, sizeof(struct hymonitor)); - if(*handle == NULL) { - return -1; - } - stat = apr_thread_mutex_create(&((*handle)->mutex), APR_THREAD_MUTEX_NESTED, pool); - RET_ON_ERROR(stat) - stat = apr_thread_cond_create(&((*handle)->cond), pool); - RET_ON_ERROR(stat) - (*handle)->name = name; - return 0; -} - -JNIEXPORT int __cdecl -hythread_monitor_destroy (hythread_monitor_t monitor){ - apr_status_t stat; - apr_pool_t *pool = apr_thread_mutex_pool_get (monitor->mutex); - if(pool == NULL) { - return -1; - } - stat = apr_thread_mutex_destroy(monitor->mutex); - RET_ON_ERROR(stat) - stat = apr_thread_cond_destroy(monitor->cond); - RET_ON_ERROR(stat) - apr_pool_destroy(pool); - return 0; -} - -JNIEXPORT int __cdecl -hythread_monitor_try_enter (hythread_monitor_t monitor){ -// TODO implement - return -1; -} -JNIEXPORT int __cdecl -hythread_monitor_enter (hythread_monitor_t monitor){ - apr_status_t stat = apr_thread_mutex_lock(monitor->mutex); - RET_ON_ERROR(stat) - return 0; -} -JNIEXPORT int __cdecl -hythread_monitor_exit (hythread_monitor_t monitor) { - apr_status_t stat = apr_thread_mutex_unlock(monitor->mutex); - RET_ON_ERROR(stat) - return 0; -} -JNIEXPORT int __cdecl -hythread_monitor_notify(hythread_monitor_t monitor){ - apr_status_t stat = apr_thread_cond_signal(monitor->cond); - RET_ON_ERROR(stat) - return 0; -} -JNIEXPORT int __cdecl -hythread_monitor_notify_all (hythread_monitor_t monitor){ - apr_status_t stat = apr_thread_cond_broadcast(monitor->cond); - RET_ON_ERROR(stat) - return 0; -} -JNIEXPORT int __cdecl -hythread_monitor_wait (hythread_monitor_t monitor){ - apr_status_t stat = apr_thread_cond_wait(monitor->cond, monitor->mutex); - RET_ON_ERROR(stat) - return 0; -} - -// ======================= ATTACH ====================================== - -JNIEXPORT int __cdecl -hythread_attach (hythread_t* handle){ - if(handle) { - *handle=hythread_self(); - } - return 0; -} -JNIEXPORT void __cdecl -hythread_detach (hythread_t handle){} -JNIEXPORT hythread_t __cdecl hythread_self() { - return apr_os_thread_current(); -} - -// very simple Map implementation -// current scenario use only one global so it works well -// need to be hashtable in the future -// TODO use hashtable - -#define TABLE_SIZE 256 -char *names [TABLE_SIZE]; -unsigned data [TABLE_SIZE]; -int size = 0; -// return index in array if found, -1 otherwise -int find_entry (char* name) { - // quick pass - int i; - for (i = 0; i < size; i++) { - if (names[i] == name) { - return i; - } - } - // strcmp pass. - for (i = 0; i < size; i++) { - if (strcmp(names[i], name) == 0) { - return i; - } - } - return -1; -} -//add entry to the end of the array -// retrun new entry index, -1 if failed. -int add_entry(char* name) { - int index = size++; - if(index >= TABLE_SIZE-1) { - return -1; - } - names[index] = name; - data[index] = 0; - return index; -} - -JNIEXPORT unsigned* __cdecl -hythread_global (char* name) { - //hythread_monitor_enter(*p_global_monitor); - int index = find_entry(name); - if(index == -1) { - index = add_entry(name); - assert(index >=0); - if (index < 0) { - //hythread_monitor_exit(*p_global_monitor); - return NULL; - } - } - //hythread_monitor_exit(*p_global_monitor); - return data+index; -} - -// ================== TLS ======================================= - - -JNIEXPORT int __cdecl -hythread_tls_alloc (hythread_tls_key_t* handle){ - apr_status_t stat = apr_threadkey_private_create(handle, NULL, get_pool()); - RET_ON_ERROR(stat) - return 0; -} - -JNIEXPORT int __cdecl -hythread_tls_free (hythread_tls_key_t key){ - - apr_status_t stat = apr_threadkey_private_delete(key); - RET_ON_ERROR(stat) - return 0; -} - -// TODO method work only for current thread -JNIEXPORT void* __cdecl -hythread_tls_get (hythread_t thread, hythread_tls_key_t key) { - void* result; - apr_status_t stat = apr_threadkey_private_get(&result, key); - if(stat != 0) { - return NULL; - } - return result; -} - -// TODO method work only for current thread -JNIEXPORT int __cdecl -hythread_tls_set (hythread_t thread, hythread_tls_key_t key, void* value){ - apr_status_t stat = apr_threadkey_private_set(value, key); - RET_ON_ERROR(stat) - return 0; -} -// ==================== create thread ========================== -//#ifndef WIN32 -static void* APR_THREAD_FUNC hystart_wrapper(apr_thread_t* t , void* args) { - hythread_entrypoint_t entrypoint = (hythread_entrypoint_t)*((void **)args); - void* hyargs = *((void**)args+1); - return (void*) entrypoint(hyargs); -} - -JNIEXPORT int __cdecl -hythread_create(hythread_t* handle, unsigned stacksize, unsigned priority, unsigned suspend, hythread_entrypoint_t entrypoint, void* entryarg) { - apr_thread_t *new_thread; - apr_pool_t *pool = get_pool(); - static void **port_args = (void**)apr_palloc(pool, sizeof(void*)*2); - port_args[0] = (void*)entrypoint; - port_args[1] = (void*)entryarg; - apr_status_t stat = apr_thread_create(&new_thread, NULL, hystart_wrapper, - port_args, pool); - RET_ON_ERROR(stat); - stat = apr_os_thread_get(&handle, new_thread); - RET_ON_ERROR(stat); - return 0; -} - - -JNIEXPORT int __cdecl -hythread_exit (hythread_monitor_t monitor) { - apr_status_t stat; - apr_os_thread_t aott; - apr_thread_t *att = NULL; - - // att = (apr_thread_t*)apr_pcalloc(get_pool(), sizeof(apr_thread_t*)); - aott = apr_os_thread_current(); - stat = apr_os_thread_put(&att, &aott, get_pool()); - RET_ON_ERROR(stat); - - if (monitor) { - hythread_monitor_exit(monitor); - } - - return apr_thread_exit(att, 0); -} - - - - -}// extern "C" Index: vm/vmcore/src/util/em64t/base/jit_generic_rt_support_ia32.cpp =================================================================== --- vm/vmcore/src/util/em64t/base/jit_generic_rt_support_ia32.cpp (revision 430048) +++ vm/vmcore/src/util/em64t/base/jit_generic_rt_support_ia32.cpp (working copy) @@ -31,7 +31,7 @@ #include "cxxlog.h" #include "jit_runtime_support.h" -#include "open/thread.h" + #include "nogc.h" // for malloc_fixed_code_for_jit() #include "encoder.h" #include "vm_stats.h" @@ -49,7 +49,7 @@ //static uint64 vm_lshl(unsigned count, uint64 n) //{ -// assert(!tmn_is_suspend_enabled()); +// assert(!hythread_is_suspend_enabled()); // return n << (count & 0x3f); //} //vm_lshl @@ -69,7 +69,7 @@ //static int64 vm_lshr(unsigned count, int64 n) //{ -// assert(!tmn_is_suspend_enabled()); +// assert(!hythread_is_suspend_enabled()); // return n >> (count & 0x3f); //} //vm_lshr @@ -89,7 +89,7 @@ //static uint64 vm_lushr(unsigned count, uint64 n) //{ -// assert(!tmn_is_suspend_enabled()); +// assert(!hythread_is_suspend_enabled()); // return n >> (count & 0x3f); //} //vm_lushr @@ -111,7 +111,7 @@ static int64 __stdcall vm_lmul(int64 m, int64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return m * n; } //vm_lmul @@ -121,7 +121,7 @@ static int64 __stdcall vm_lmul_const_multiplier(int64 m, int64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); __asm{ mov eax,dword ptr [ebp+0ch] mov ecx,dword ptr [ebp+10h] @@ -139,7 +139,7 @@ //static int64 __stdcall do_lrem(int64 m, int64 n) //{ -// assert(!tmn_is_suspend_enabled()); +// assert(!hythread_is_suspend_enabled()); // // return m % n; //} //do_lrem @@ -203,7 +203,7 @@ static int64 __stdcall vm_d2l(double d) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); #ifdef VM_STATS vm_stats_total.num_d2l++; @@ -288,7 +288,7 @@ static int64 __stdcall vm_f2l(float f) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); #ifdef VM_STATS vm_stats_total.num_f2l++; Index: vm/vmcore/src/util/em64t/base/jit_runtime_support_ia32.cpp =================================================================== --- vm/vmcore/src/util/em64t/base/jit_runtime_support_ia32.cpp (revision 430048) +++ vm/vmcore/src/util/em64t/base/jit_runtime_support_ia32.cpp (working copy) @@ -48,7 +48,7 @@ #include "nogc.h" #include "encoder.h" #include "open/vm_util.h" -#include "open/thread.h" + #include "vm_threads.h" #include "mon_enter_exit.h" #include "vm_arrays.h" @@ -88,11 +88,10 @@ ///////////////////////////////////////////////////////////////// // begin VM_Runtime_Support ///////////////////////////////////////////////////////////////// -CriticalSection cs; /* static void vm_throw_java_lang_ClassCastException() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); throw_java_exception("java/lang/ClassCastException"); } //vm_throw_java_lang_ClassCastException @@ -153,7 +152,7 @@ vm_stats_total.num_is_class_initialized++; clss->num_class_init_checks++; #endif // VM_STATS - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return clss->state == ST_Initialized; } //is_class_initialized */ @@ -394,7 +393,7 @@ /* static void vm_throw_java_lang_ArithmeticException() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); throw_java_exception("java/lang/ArithmeticException"); } //vm_throw_java_lang_ArithmeticException @@ -460,7 +459,7 @@ static int64 __stdcall vm_lrem(int64 m, int64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return m % n; } //vm_lrem */ @@ -476,7 +475,7 @@ static int64 __stdcall vm_ldiv(int64 m, int64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(n); return m / n; } //vm_ldiv Index: vm/vmcore/src/util/em64t/base/compile_IA32.cpp =================================================================== --- vm/vmcore/src/util/em64t/base/compile_IA32.cpp (revision 430048) +++ vm/vmcore/src/util/em64t/base/compile_IA32.cpp (working copy) @@ -52,7 +52,7 @@ #include "nogc.h" #include "open/gc.h" -#include "open/thread.h" + #include "open/vm_util.h" #include "vm_synch.h" @@ -95,7 +95,7 @@ void compile_protect_arguments(Method_Handle method, GcFrame* gc) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Method_Signature_Handle msh = method_get_signature(method); unsigned num_args = method_args_get_number(msh); unsigned num_arg_words = ((Method*)method)->get_num_arg_bytes()>>2; Index: vm/vmcore/src/util/em64t/base/jit_lock_rt_support_ia32.cpp =================================================================== --- vm/vmcore/src/util/em64t/base/jit_lock_rt_support_ia32.cpp (revision 430048) +++ vm/vmcore/src/util/em64t/base/jit_lock_rt_support_ia32.cpp (working copy) @@ -42,8 +42,8 @@ #include "lil_code_generator.h" #include "../m2n_em64t_internal.h" #include "object_handles.h" -#include "open/thread.h" + extern bool dump_stubs; char *gen_setup_j2n_frame(char *s); Index: vm/vmcore/src/util/linux/signals_ia32.cpp =================================================================== --- vm/vmcore/src/util/linux/signals_ia32.cpp (revision 430048) +++ vm/vmcore/src/util/linux/signals_ia32.cpp (working copy) @@ -74,9 +74,6 @@ static int sc_nest = -1; static uint32 exam_point; -bool SuspendThread(unsigned UNREF xx){ return 0; } -bool ResumeThread(unsigned UNREF xx){ return 1; } - static void linux_sigcontext_to_regs(Registers* regs, ucontext_t *uc) { regs->eax = uc->uc_mcontext.gregs[REG_EAX]; @@ -348,8 +345,8 @@ return; } else { if (is_unwindable()) { - if (tmn_is_suspend_enabled()) { - tmn_suspend_disable(); + if (hythread_is_suspend_enabled()) { + hythread_suspend_disable(); } throw_from_sigcontext( uc, env->java_lang_StackOverflowError_Class); @@ -500,10 +497,13 @@ } /* + * MOVED TO PORT, DO NOT USE USR2 * USR2 signal used to yield the thread at suspend algorithm - */ + * void yield_other_handler(int signum, siginfo_t* info, void* context) { + // FIXME: integration, should be moved to port or OpenTM + Global_Env *env = VM_Global_State::loader_env; if (env->shutting_down != 0) { // Too late for this kind of signals @@ -532,8 +532,9 @@ } DIE("Cannot find Java thread using signal context"); + } - +*/ void initialize_signals() { // First figure out how to locate the context in the @@ -545,12 +546,14 @@ //behaviour, which is different from BSD. But glibc2 in Linux //implements BSD semantics. struct sigaction sa; +/* + * MOVED TO PORT, DO NOT USE USR2 sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO | SA_RESTART; sa.sa_sigaction = yield_other_handler; sigaction(SIGUSR2, &sa, NULL); - +*/ sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO | SA_ONSTACK; sa.sa_sigaction = &null_java_reference_handler; Index: vm/vmcore/src/util/linux/signals_em64t.cpp =================================================================== --- vm/vmcore/src/util/linux/signals_em64t.cpp (revision 430048) +++ vm/vmcore/src/util/linux/signals_em64t.cpp (working copy) @@ -231,8 +231,9 @@ } /* + * MOVED TO PORT, DO NOT USE USR2 * USR2 signal used to yield the thread at suspend algorithm - */ + * void yield_other_handler(int signum, siginfo_t* info, void* context) { @@ -263,8 +264,8 @@ DIE("Cannot find Java thread using signal context"); } +*/ - /* See function initialize_signals() below first please. @@ -373,12 +374,14 @@ //behaviour, which is different from BSD. But glibc2 in Linux //implements BSD semantics. struct sigaction sa; +/* + * MOVED TO PORT, DO NOT USE USR2 sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO | SA_RESTART; sa.sa_sigaction = yield_other_handler; sigaction(SIGUSR2, &sa, NULL); - +*/ sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = &null_java_reference_handler; Index: vm/vmcore/src/util/linux/stubs.cpp =================================================================== --- vm/vmcore/src/util/linux/stubs.cpp (revision 430048) +++ vm/vmcore/src/util/linux/stubs.cpp (working copy) @@ -28,14 +28,6 @@ #include "method_lookup.h" #include "open/gc.h" -// void vm_thread_enumerate_from_native(VM_thread *thread); // unused anywhere - -BOOL port_CloseHandle(VmEventHandle UNREF hh) -{ - ABORT("Not implemented"); - return 0; -} - //wgs: I wonder if we could give it a errno #if defined (__INTEL_COMPILER) #pragma warning( push ) @@ -65,24 +57,8 @@ ABORT("Not implemented"); } -BOOL GetThreadContext(VmThreadHandle UNREF hthread, const CONTEXT * UNREF lpcontext) -{ - ABORT("Not implemented"); - return 0; -} -BOOL SetThreadContext(VmThreadHandle UNREF hh, const CONTEXT * UNREF cc) -{ - ABORT("Not implemented"); - return 0; -} -int VM_thread::setPriority(int UNREF priority) -{ - ABORT("Not implemented"); - return 0; -} - #include __uint64 GetTickCount(void) { @@ -101,33 +77,8 @@ } } -CriticalSection::CriticalSection() -{ - m_cs = (void *) new CRITICAL_SECTION; - InitializeCriticalSection((CRITICAL_SECTION *)m_cs); -} - -CriticalSection::~CriticalSection() -{ - DeleteCriticalSection((CRITICAL_SECTION *)m_cs); - delete (CRITICAL_SECTION *)m_cs; -} - -void CriticalSection::lock() -{ - EnterCriticalSection((CRITICAL_SECTION *)m_cs); -} - -void CriticalSection::unlock() -{ - LeaveCriticalSection((CRITICAL_SECTION *)m_cs); -} - -bool CriticalSection::tryLock() -{ - return TryEnterCriticalSection((CRITICAL_SECTION *)m_cs) ? true : false; -} - +/* TODO reimplement this code while implementing IPF support. + VmRegisterContext::VmRegisterContext() { CONTEXT *ctx = new CONTEXT; @@ -161,6 +112,7 @@ ((CONTEXT *)_pcontext)->ContextFlags = old; } + void VmRegisterContext::getContext(VM_thread *thread) { CONTEXT *ctx = (CONTEXT *) _pcontext; @@ -250,3 +202,4 @@ ABORT("Not supported"); // shouldn't be called under IA-32 #endif // !_IPF_ } +*/ Index: vm/vmcore/src/util/linux/os_wrapper.cpp =================================================================== --- vm/vmcore/src/util/linux/os_wrapper.cpp (revision 430048) +++ vm/vmcore/src/util/linux/os_wrapper.cpp (working copy) @@ -49,343 +49,3 @@ -- which uses SIGUSR1, SIGUSR2 (which conflicts with the java app debugger and vm) #endif #endif - - -pthread_mutexattr_t mutex_attr; -pthread_mutexattr_t mutex_attr_for_cond_wait; - -pthread_condattr_t cond_attr; - -pthread_attr_t pthread_attr; -//extern pthread_key_t TLS_key_pvmthread; -void init_linux_thread_system() -{ - static bool initialized = false; - - if (initialized) return; - initialized = true; - pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE_NP); - - int UNUSED stat = pthread_condattr_init(&cond_attr); - assert(stat == 0); - - pthread_attr_init(&pthread_attr); - pthread_attr_setdetachstate(&pthread_attr, PTHREAD_CREATE_DETACHED); - - //pthread_key_create(&TLS_key_pvmthread, 0); -} - -VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection) -{ - init_linux_thread_system(); - assert(lpCriticalSection); - int UNUSED xx = pthread_mutex_init(lpCriticalSection, &mutex_attr); - assert(xx == 0); -} - - -VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection) -{ - assert(lpCriticalSection); -} - - -VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection) -{ - assert(lpCriticalSection); - int UNUSED xx = pthread_mutex_unlock(lpCriticalSection); - assert(xx == 0); -} - - -BOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection) -{ - assert(lpCriticalSection); - int xx = pthread_mutex_trylock(lpCriticalSection); - - if (xx == 0) - return 1; - - assert(xx == EBUSY); - return 0; -} - - -BOOL EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection) -{ - assert(lpCriticalSection); - int xx = pthread_mutex_lock(lpCriticalSection); - - if (xx == 0) - return 1; - - return 0; -} - - -VmThreadHandle vm_beginthreadex( void * UNREF security, unsigned UNREF stacksize, unsigned(__stdcall *start_address)(void *), void *arglist, unsigned UNREF initflag, pthread_t *thrdaddr) -{ - pthread_t tid = 0; - - void *(*sa)(void *) = ( void *(*)(void *) )start_address; - int stat = pthread_create(&tid, &pthread_attr, sa, arglist); - *thrdaddr = tid; - if(stat !=0) { - return 0; - } - return (VmThreadHandle)tid; -} - -VmThreadHandle vm_beginthread(void (__cdecl *start_address)(void *), unsigned UNREF stacksize, void *arglist) -{ - pthread_t tid = 0; - - void *(*sa)(void *) = ( void *(*)(void *) )start_address; - int stat = pthread_create(&tid, &pthread_attr, sa, arglist); - if(stat !=0) { - return 0; - } - - return (VmThreadHandle)tid; -} - -static void init_timespec(struct timespec & ts, DWORD dwMillisec) -{ - ts.tv_sec = dwMillisec/1000; - ts.tv_nsec = (dwMillisec%1000)*1000000; - - struct timeval tv; - int UNUSED stat = gettimeofday(&tv, 0); - assert(stat == 0); - - ts.tv_sec += tv.tv_sec; - ts.tv_nsec += tv.tv_usec*1000; - - ts.tv_sec += (ts.tv_nsec/1000000000); - ts.tv_nsec = (ts.tv_nsec%1000000000); -} - -VmEventHandle vm_create_event(int * UNREF security, unsigned int man_reset_flag, - unsigned int initial_state_flag, char * UNREF p_name) -{ - event_wrapper *p_event = (event_wrapper *)STD_MALLOC( sizeof(struct event_wrapper) ); - - int stat = pthread_mutex_init(&p_event->mutex, &mutex_attr_for_cond_wait); - assert(stat == 0); - - stat = pthread_cond_init(&p_event->cond, &cond_attr); - assert(stat == 0); - - p_event->man_reset_flag = man_reset_flag; - p_event->state = initial_state_flag; - p_event->n_wait = 0; - - return (VmEventHandle)p_event; -} - -BOOL vm_destroy_event(VmEventHandle hEvent) -{ - struct timespec ts; - event_wrapper *p_event = (event_wrapper *)hEvent; - - int xx = pthread_mutex_lock(&p_event->mutex); - assert(xx == 0); - // no threads in the wait set - if (p_event->n_wait == 0) goto success; - - // no chance to release waited threads - if (p_event->state == 0) goto fail; - - if (p_event->man_reset_flag == 0) { - // event is in automatic state so not more than one thread can be released - if (p_event->n_wait > 1) goto fail; - p_event->man_reset_flag = 1; - } - - init_timespec(ts, 1000); - - do { - int stat = pthread_cond_timedwait(&p_event->cond, &p_event->mutex, &ts); - assert(stat != EINVAL); - // ensure that the stat is still signaling - if (stat == ETIMEDOUT && p_event->state == 0 && p_event->n_wait != 0) - goto fail; - } while (p_event->n_wait != 0); - -success: - xx = pthread_mutex_unlock(&p_event->mutex); - assert(xx == 0); - STD_FREE(p_event); - return 1; - -fail: - xx = pthread_mutex_unlock(&p_event->mutex); - assert(xx == 0); - return 0; -} - -BOOL vm_reset_event(VmEventHandle hEvent) -{ - event_wrapper *p_event = (event_wrapper *)hEvent; - - assert(p_event); - int xx = pthread_mutex_lock(&p_event->mutex); - assert(xx == 0); - p_event->state = 0; - xx = pthread_mutex_unlock(&p_event->mutex); - assert(xx == 0); - return 1; -} - - -BOOL vm_set_event(VmEventHandle hEvent) -{ - event_wrapper *p_event = (event_wrapper *)hEvent; - - assert(p_event); - int stat = pthread_mutex_lock(&p_event->mutex); - assert(stat == 0); - - p_event->state = 1; - - stat = pthread_cond_broadcast(&p_event->cond); - assert(stat == 0); - - stat = pthread_mutex_unlock(&p_event->mutex); - assert(stat == 0); - return 1; -} - -void vm_yield() { - sched_yield(); -} - -DWORD vm_wait_for_single_object(VmEventHandle hHandle, DWORD dwMillisec) -{ - if (dwMillisec < 10) - return WAIT_TIMEOUT; - - struct timespec ts; - init_timespec(ts, dwMillisec); - - event_wrapper *p_event = (event_wrapper *)hHandle; - assert(p_event); - - int stat = pthread_mutex_lock(&p_event->mutex); - assert(stat == 0); - - int wait_status = WAIT_OBJECT_0; - - while (1) - { - if (p_event->state != 0) - break; - - ++p_event->n_wait; - wait_status = pthread_cond_timedwait(&p_event->cond, - &p_event->mutex, - &ts ); - --p_event->n_wait; - - assert(wait_status != EINVAL); - if (wait_status == ETIMEDOUT) - break; - if (wait_status == 0) - break; - } - - if (p_event->man_reset_flag == 0) - p_event->state = 0; - - stat = pthread_mutex_unlock(&p_event->mutex); - assert(stat == 0); - - if (wait_status == ETIMEDOUT) - return WAIT_TIMEOUT; - - if (wait_status == 0) - return WAIT_OBJECT_0; - - return WAIT_TIMEOUT; -} - -DWORD vm_wait_for_multiple_objects(DWORD numobj, const VmEventHandle *hHandle, BOOL waitAll, DWORD dwMillisec) -{ - DWORD ret = 0; - assert(waitAll); - assert(dwMillisec == INFINITE); - - for(unsigned int i = 0; i < numobj; i++) { - ret = vm_wait_for_single_object((VmEventHandle)hHandle[i], dwMillisec); - if (ret != WAIT_OBJECT_0) - return ret; - } - return ret; -} - -void Sleep(DWORD msec) -{ - if (msec < 1000){ - sched_yield(); - return; - } - - unsigned int zz = msec/1000; - - sleep(zz); - -} - - -void SleepEx(DWORD time, bool UNREF bb) -{ - Sleep(time); -} - -void vm_endthreadex(int UNREF zz) -{ - // on linux, this is a nop, - // call_the_run_method() simply returns into the linux kernel -} - -void vm_endthread(void ) -{ - // on linux, this is a nop, - // call_the_run_method() simply returns into the linux kernel -} - -/**************************************** - * Moved from stubs.h - * Some function need to be implemented - ****************************************/ - -pthread_t GetCurrentThreadId (void) -{ - return pthread_self(); -} - -/* - * Need to implement (?) - */ -BOOL DuplicateHandle(VmEventHandle UNREF aa, VmEventHandle UNREF bb, - VmEventHandle UNREF cc, VmEventHandle * UNREF dd, - DWORD UNREF ee, BOOL UNREF ff, DWORD UNREF gg) -{ - return TRUE; -} - -/* - * Need to implement (?) - */ -VmEventHandle GetCurrentProcess(void) -{ - return 0; -} - -/* - * Need to implement (?) - */ -VmEventHandle GetCurrentThread(void) -{ - return 0; -} Index: vm/vmcore/src/util/linux/include/platform.h =================================================================== --- vm/vmcore/src/util/linux/include/platform.h (revision 430048) +++ vm/vmcore/src/util/linux/include/platform.h (working copy) @@ -49,12 +49,9 @@ #define WORD unsigned short #define DWORD unsigned int #define BOOL unsigned int -typedef pthread_t VmThreadHandle; #ifdef POINTER64 -#define VmEventHandle void* #define HANDLE void* #else -#define VmEventHandle unsigned int #define HANDLE unsigned int #endif @@ -109,35 +106,8 @@ #define FMT64 "ll" #endif // FMT64 -void init_linux_thread_system(); typedef struct VM_thread VM_thread; -bool suspend_thread(VM_thread *); -bool resume_thread(VM_thread *); -#define CRITICAL_SECTION pthread_mutex_t -#define LPCRITICAL_SECTION pthread_mutex_t * - -VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); - -VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection); -VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); -BOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); -BOOL EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); - -VmThreadHandle vm_beginthreadex( void * security, unsigned stack_size, unsigned(__stdcall *start_address)(void *), void *arglist, unsigned initflag, pthread_t *thrdaddr); -VmThreadHandle vm_beginthread(void (__cdecl *start_address)(void *), unsigned stack_size, void *arglist); -void vm_endthreadex(int); -void vm_endthread(void); - -#define CreateEvent vm_create_event -#define SetEvent vm_set_event -#define ResetEvent vm_reset_event -#define WaitForSingleObject vm_wait_for_single_object -#define WaitForMultipleObjects vm_wait_for_multiple_objects - -void Sleep(DWORD); -void SleepEx(DWORD, bool); - /* * There are two ways to implement Thread-Specific_Data(TSD or Thread Local * Storage:TLS) in LinuxThreads. @@ -227,13 +197,7 @@ #define G_S_R_E_H NULL #define J_V_M_T_I_E_H NULL #define E_H_RECOMP NULL -#define OS_THREAD_INIT_1() -#define OS_SYNC_SUPPORT() -#define OS_THREAD_INIT_2() p_TLS_vmthread = p_vm_thread; -#define THREAD_CLEANUP() -#define BEGINTHREADEX_SUSPENDSTATE 1 -#define SET_THREAD_DATA_MACRO() -#define CHECK_HIJACK_SUPPORT_MACRO() + #include "stdlib.h" #include @@ -247,10 +211,6 @@ void _fpreset(void); - -VmEventHandle vm_create_event(int *, unsigned int, unsigned int, char *); -BOOL vm_destroy_event( VmEventHandle ); - typedef struct event_wrapper { pthread_mutex_t mutex; pthread_cond_t cond; @@ -259,19 +219,7 @@ unsigned int n_wait; } event_wrapper; -BOOL vm_reset_event(VmEventHandle hEvent); -BOOL vm_set_event(VmEventHandle hEvent); -void vm_yield(); -DWORD vm_wait_for_single_object(VmEventHandle hHandle, DWORD dwMilliseconds); -DWORD vm_wait_for_multiple_objects(DWORD num, const VmEventHandle * handle, BOOL flag, DWORD dwMilliseconds); - - -#define WAIT_TIMEOUT 0x102 -#define WAIT_OBJECT_0 0 -#define WAIT_FAILED (DWORD)0xFFFFFFFF - - typedef struct _FLOATING_SAVE_AREA { DWORD ControlWord; DWORD StatusWord; @@ -567,23 +515,13 @@ #define CONTEXT_FLOATING_POINT 2 #define CONTEXT_INTEGER 3 #define THREAD_PRIORITY_NORMAL 4 +/* - BOOL GetThreadContext(VmThreadHandle hthread, const CONTEXT *lpcontext); BOOL SetThreadContext(VmThreadHandle hh, const CONTEXT *cc); BOOL SetThreadPriority(VmThreadHandle hh, int pp); -BOOL port_CloseHandle(VmEventHandle hh); -pthread_t GetCurrentThreadId(void); -VmEventHandle GetCurrentProcess(void); -VmEventHandle GetCurrentThread(void); - -#define DUPLICATE_SAME_ACCESS 3 - -BOOL DuplicateHandle(VmEventHandle aa, VmEventHandle bb, - VmEventHandle cc, VmEventHandle *dd, - DWORD ee, BOOL ff, DWORD gg); - +*/ #define _MAX_PATH PATH_MAX struct _finddata_t { @@ -607,12 +545,11 @@ __uint64 GetTickCount(); -void vm_endthreadex(int); typedef void * FARPROC; -inline void vm_terminate_thread(VmThreadHandle thrdaddr) { +/*inline void vm_terminate_thread(VmThreadHandle thrdaddr) { pthread_cancel(thrdaddr); -} +}*/ #ifdef __cplusplus } #endif Index: vm/vmcore/src/util/natives_support.cpp =================================================================== --- vm/vmcore/src/util/natives_support.cpp (revision 430048) +++ vm/vmcore/src/util/natives_support.cpp (working copy) @@ -33,7 +33,7 @@ #include "lock_manager.h" #include "jni_direct.h" // FIXME ???? Can we use it here ???? #include "open/vm_util.h" -#include "open/thread.h" + #include "jni_types.h" #define LOG_DOMAIN "natives" @@ -113,7 +113,7 @@ JavaVM* vm = jni_native_intf->vm; // FIXME ???? Can we use it here ???? - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); jint res = onload_func(vm, NULL); return res; @@ -150,7 +150,7 @@ JavaVM* vm = jni_native_intf->vm; // FIXME ???? Can we use it here ???? - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); onunload_func(vm, NULL); return; } Index: vm/vmcore/src/util/vm_strings.cpp =================================================================== --- vm/vmcore/src/util/vm_strings.cpp (revision 430048) +++ vm/vmcore/src/util/vm_strings.cpp (working copy) @@ -232,7 +232,7 @@ // Return: str gets the string object, buf points to buffer static void string_create(unsigned unicode_length, bool eight_bit, ManagedObject** str, StringBuffer* buf) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Global_Env *global_env = VM_Global_State::loader_env; Class *clss; @@ -256,7 +256,7 @@ VTable *jls_vtable = VM_Global_State::loader_env->JavaLangString_VTable; - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); GcFrame gc(2); gc.add_object((ManagedObject**)&array); @@ -330,7 +330,7 @@ ObjectHandle string_create_from_utf8_h(const char* buf, unsigned length) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); ObjectHandle res = oh_allocate_local_handle(); res->object = string_create_from_utf8(buf, length); @@ -340,7 +340,7 @@ ObjectHandle string_create_from_unicode_h(const uint16* buf, unsigned length) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); ObjectHandle res = oh_allocate_local_handle(); res->object = string_create_from_unicode(buf, length); @@ -355,7 +355,7 @@ // returns length in characters unsigned string_get_length(ManagedObject* str) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(str); if (f_count_offset == 0) init_fields(); @@ -366,7 +366,7 @@ // returns length in characters unsigned string_get_length_h(ObjectHandle str) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); assert(str && str->object); unsigned len = string_get_length(str->object); @@ -390,7 +390,7 @@ // returns the length of the UTF8 encoding of the string unsigned string_get_utf8_length_h(ObjectHandle str) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); assert(str && str->object); unsigned utf8_len = string_get_utf8_length(str->object); @@ -473,7 +473,7 @@ // Caller should free the result const char* string_get_utf8_chars_h(ObjectHandle string) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); assert(string && string->object); const char* res = string_get_utf8_chars(string->object); @@ -497,7 +497,7 @@ // Copy the characters offset..offset+count-1 into buf void string_get_unicode_region_h(ObjectHandle str, unsigned offset, unsigned count, uint16* buf) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); assert(str && str->object && offset+count<=string_get_length(str->object)); string_get_unicode_region(str->object, offset, count, buf); @@ -519,7 +519,7 @@ // Encode characters offset..offset+count-1 into UTF8 and place in buf void string_get_utf8_region_h(ObjectHandle str, unsigned offset, unsigned count, char* buf) { - assert(tmn_is_suspend_enabled()); + assert(hythread_is_suspend_enabled()); tmn_suspend_disable(); assert(str && str->object && offset+count<=string_get_length(str->object)); string_get_utf8_region(str->object, offset, count, buf); @@ -534,7 +534,7 @@ VMEXPORT // temporary solution for interpreter unplug Java_java_lang_String *vm_instantiate_cp_string_resolved(String *str) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Global_Env *env = VM_Global_State::loader_env; if (env->compress_references) { if (str->intern.compressed_ref != 0) { @@ -550,7 +550,7 @@ if (!lang_string) { // if OutOfMemory return NULL; } - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); // Atomically update the string structure since some other thread might be trying to make the same update. // The GC won't be able to enumerate here since GC is disabled, so there are no race conditions with GC. Index: vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp =================================================================== --- vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp (revision 430048) +++ vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp (working copy) @@ -36,9 +36,9 @@ #include "exception_filter.h" #include "thread_generic.h" -#include "open/thread.h" + // Afremov Pavel 20050117 #include "../m2n_em64t_internal.h" @@ -63,7 +63,7 @@ } // since we are now sure NPE occured in java code, gc should also have been disabled - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); volatile ManagedObject *exc = 0; Index: vm/vmcore/src/util/win/include/java_lang_thread_nt.h =================================================================== --- vm/vmcore/src/util/win/include/java_lang_thread_nt.h (revision 430048) +++ vm/vmcore/src/util/win/include/java_lang_thread_nt.h (working copy) @@ -28,23 +28,3 @@ #define J_V_M_T_I_E_H NULL #define E_H_RECOMP NULL -#define OS_THREAD_INIT_1() - -#define OS_SYNC_SUPPORT() - - -#define OS_THREAD_INIT_2() \ - p_TLS_vmthread = p_vm_thread; - - -#define THREAD_CLEANUP() - -#define BEGINTHREADEX_SUSPENDSTATE 1 - -#define SET_THREAD_DATA_MACRO() - - -#define THREAD_ACTIVE_IN_OS_MACRO() - -#define CHECK_HIJACK_SUPPORT_MACRO() - Index: vm/vmcore/src/util/win/include/platform_lowlevel.h =================================================================== --- vm/vmcore/src/util/win/include/platform_lowlevel.h (revision 430048) +++ vm/vmcore/src/util/win/include/platform_lowlevel.h (working copy) @@ -40,37 +40,6 @@ #include "platform.h" -// moved from util_log.h, there should be better place for this definition. - -typedef unsigned pthread_t; // see documentation on _beginthread -typedef CRITICAL_SECTION pthread_mutex_t; -typedef struct pthread_mutexattr_t pthread_mutexattr_t; -typedef void *sem_t; - -inline pthread_t pthread_self() { - return GetCurrentThreadId(); -} - -inline int pthread_mutex_init (pthread_mutex_t *mutex, pthread_mutexattr_t *attr) { - InitializeCriticalSection(mutex); - return 0; -} - -inline int pthread_mutex_destroy (pthread_mutex_t *mutex) { - DeleteCriticalSection(mutex); - return 0; -} - -inline int pthread_mutex_lock (pthread_mutex_t *mutex) { - EnterCriticalSection(mutex); - return 0; -} - -inline int pthread_mutex_unlock (pthread_mutex_t *mutex) { - LeaveCriticalSection(mutex); - return 0; -} - inline void disable_assert_dialogs() { _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT); @@ -95,27 +64,4 @@ long tv_nsec; }; -inline int sem_init(sem_t *semaphore, int pshared, unsigned int value) { - *semaphore = CreateSemaphore(NULL, value, INFINITE, NULL); - return 0; -} - -inline int sem_destroy(sem_t *sem) { - return CloseHandle(*sem); -} - -inline int sem_post(sem_t *semaphore) { - return ReleaseSemaphore(*semaphore, 1, NULL); -} - -inline int sem_wait(sem_t *semaphore) { - return WaitForSingleObject(*semaphore, INFINITE); -} - -inline int sem_timedwait(sem_t *semaphore, - const struct timespec *abs_timeout) { - return WaitForSingleObject(*semaphore, abs_timeout->tv_sec*1000); -} - - #endif // _platform_lowlevel_H_ Index: vm/vmcore/src/util/win/include/vm_process.h =================================================================== --- vm/vmcore/src/util/win/include/vm_process.h (revision 430048) +++ vm/vmcore/src/util/win/include/vm_process.h (working copy) @@ -35,68 +35,8 @@ #include #include -inline VmEventHandle vm_beginthreadex( void * security, unsigned stack_size, unsigned(__stdcall *start_address)(void *), void *arglist, unsigned initflag, pthread_t *thrdaddr) -{ - return (VmEventHandle) _beginthreadex(security, stack_size, start_address, arglist, initflag, thrdaddr); -} -inline void vm_endthreadex(int value) -{ - _endthreadex(value); -} - -inline VmEventHandle vm_beginthread(void(__cdecl *start_address)(void *), unsigned stack_size, void *arglist) -{ - uintptr_t result = _beginthread(start_address, stack_size, arglist); - // on windows error code is -1 !!! - if (result == -1L) - return NULL; - - return (VmEventHandle) result; -} - -inline void vm_endthread(void) -{ - _endthread(); -} - -inline VmEventHandle vm_create_event(int *lpEventAttributes, unsigned int bManualReset, unsigned int bInitialState, char *lpName) -{ - assert(lpEventAttributes == NULL); - return CreateEvent(NULL, bManualReset, bInitialState, lpName); -} - -inline BOOL vm_destroy_event( VmEventHandle handle ) -{ - assert( handle != INVALID_HANDLE_VALUE ); - return CloseHandle( handle ) == FALSE ? 0 : 1; -} - -inline BOOL vm_reset_event(VmEventHandle hEvent) -{ - return ResetEvent(hEvent); -} - -inline BOOL vm_set_event(VmEventHandle hEvent) -{ - return SetEvent(hEvent); -} - -inline void vm_yield() { - Sleep(0); -} - -inline DWORD vm_wait_for_single_object(VmEventHandle hHandle, DWORD dwMilliseconds) -{ - return WaitForSingleObject(hHandle, dwMilliseconds); -} - -inline DWORD vm_wait_for_multiple_objects(DWORD num, const VmEventHandle * handle, BOOL flag, DWORD dwMilliseconds) -{ - return WaitForMultipleObjects(num, handle, flag, dwMilliseconds); -} - -inline void vm_terminate_thread(VmThreadHandle thrdaddr) { +/*inline void vm_terminate_thread(VmThreadHandle thrdaddr) { TerminateThread(thrdaddr,0); -} +}*/ #endif Index: vm/vmcore/src/util/win/include/platform.h =================================================================== --- vm/vmcore/src/util/win/include/platform.h (revision 430048) +++ vm/vmcore/src/util/win/include/platform.h (working copy) @@ -26,8 +26,6 @@ typedef unsigned long DWORD; typedef int BOOL; -typedef void *VmEventHandle; -typedef VmEventHandle VmThreadHandle; #ifndef FMT64 #define FMT64 "I64" Index: vm/vmcore/src/util/win/nt_platform_utils.cpp =================================================================== --- vm/vmcore/src/util/win/nt_platform_utils.cpp (revision 430048) +++ vm/vmcore/src/util/win/nt_platform_utils.cpp (working copy) @@ -199,33 +199,6 @@ } -CriticalSection::CriticalSection() -{ - m_cs = (void *) new CRITICAL_SECTION; - InitializeCriticalSection((CRITICAL_SECTION *)m_cs); -} - -CriticalSection::~CriticalSection() -{ - DeleteCriticalSection((CRITICAL_SECTION *)m_cs); - delete (CRITICAL_SECTION *)m_cs; -} - -void CriticalSection::lock() -{ - EnterCriticalSection((CRITICAL_SECTION *)m_cs); -} - -void CriticalSection::unlock() -{ - LeaveCriticalSection((CRITICAL_SECTION *)m_cs); -} - -bool CriticalSection::tryLock() -{ - return TryEnterCriticalSection((CRITICAL_SECTION *)m_cs) ? true : false; -} - VmRegisterContext::VmRegisterContext() { CONTEXT *ctx = new CONTEXT; @@ -259,6 +232,7 @@ ((CONTEXT *)_pcontext)->ContextFlags = old; } +/* FIXME integration uncomment and fix void VmRegisterContext::getContext(VM_thread *thread) { CONTEXT *ctx = (CONTEXT *) _pcontext; @@ -354,4 +328,4 @@ { return SetThreadPriority(thread_handle, priority); } - +*/ Index: vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp =================================================================== --- vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp (revision 430048) +++ vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp (working copy) @@ -18,11 +18,8 @@ * @version $Revision: 1.1.2.1.4.4 $ */ - #include "cxxlog.h" #include "method_lookup.h" -#include "m2n.h" -#include "open/thread.h" #include "Environment.h" #include "exceptions.h" @@ -317,8 +314,8 @@ run_default_handler = false; } else if (code == STATUS_STACK_OVERFLOW) { if (is_unwindable()) { - if (tmn_is_suspend_enabled()) { - tmn_suspend_disable(); + if (hythread_is_suspend_enabled()) { + hythread_suspend_disable(); } run_default_handler = false; } else { @@ -385,7 +382,7 @@ } // since we are now sure HWE occured in java code, gc should also have been disabled - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Global_Env *env = VM_Global_State::loader_env; Class *exc_clss = 0; Index: vm/vmcore/src/util/win/ipf/nt_exception_filter.cpp =================================================================== --- vm/vmcore/src/util/win/ipf/nt_exception_filter.cpp (revision 430048) +++ vm/vmcore/src/util/win/ipf/nt_exception_filter.cpp (working copy) @@ -17,10 +17,6 @@ * @author Intel, Evgueni Brevnov * @version $Revision: 1.1.2.1.4.3 $ */ - -#define LOG_DOMAIN "vm.exn_filter" -#include "cxxlog.h" - #include "platform_lowlevel.h" #include "Class.h" @@ -33,8 +29,8 @@ #include "open/vm_util.h" #include "compile.h" #include "../../../arch/ipf/include/vm_ipf.h" -#include "open/thread.h" + #include "exception_filter.h" // Afremov Pavel 20050117 Index: vm/vmcore/src/util/ia32/base/jit_generic_rt_support_ia32.cpp =================================================================== --- vm/vmcore/src/util/ia32/base/jit_generic_rt_support_ia32.cpp (revision 430048) +++ vm/vmcore/src/util/ia32/base/jit_generic_rt_support_ia32.cpp (working copy) @@ -31,7 +31,7 @@ #include "cxxlog.h" #include "jit_runtime_support.h" -#include "open/thread.h" + #include "nogc.h" // for malloc_fixed_code_for_jit() #include "encoder.h" #include "vm_stats.h" @@ -52,7 +52,7 @@ static uint64 vm_lshl(unsigned count, uint64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return n << (count & 0x3f); } //vm_lshl @@ -108,7 +108,7 @@ static int64 vm_lshr(unsigned count, int64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return n >> (count & 0x3f); } //vm_lshr @@ -162,7 +162,7 @@ static uint64 vm_lushr(unsigned count, uint64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return n >> (count & 0x3f); } //vm_lushr @@ -218,7 +218,7 @@ static int64 __stdcall vm_lmul(int64 m, int64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return m * n; } //vm_lmul @@ -228,7 +228,7 @@ static int64 __stdcall vm_lmul_const_multiplier(int64 m, int64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); __asm{ mov eax,dword ptr [ebp+0ch] mov ecx,dword ptr [ebp+10h] @@ -246,7 +246,7 @@ static int64 __stdcall do_lrem(int64 m, int64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return m % n; } //do_lrem @@ -701,7 +701,7 @@ static int64 __stdcall vm_d2l(double d) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); #ifdef VM_STATS vm_stats_total.num_d2l++; @@ -883,7 +883,7 @@ static int64 __stdcall vm_f2l(float f) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); #ifdef VM_STATS vm_stats_total.num_f2l++; Index: vm/vmcore/src/util/ia32/base/jit_runtime_support_ia32.cpp =================================================================== --- vm/vmcore/src/util/ia32/base/jit_runtime_support_ia32.cpp (revision 430048) +++ vm/vmcore/src/util/ia32/base/jit_runtime_support_ia32.cpp (working copy) @@ -43,7 +43,9 @@ #include "nogc.h" #include "encoder.h" #include "open/vm_util.h" -#include "open/thread.h" + +#include "open/thread_helpers.h" + #include "vm_threads.h" #include "mon_enter_exit.h" #include "vm_arrays.h" @@ -77,22 +79,16 @@ #define SIZE(Struct, Field) \ (sizeof(((Struct *) NULL)->Field)) - -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 * get_generic_rt_support_addr_ia32(VM_RT_SUPPORT f); ///////////////////////////////////////////////////////////////// // begin VM_Runtime_Support ///////////////////////////////////////////////////////////////// -CriticalSection cs; static void vm_throw_java_lang_ClassCastException() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); throw_java_exception("java/lang/ClassCastException"); ABORT("The last called function should not return"); } //vm_throw_java_lang_ClassCastException @@ -225,7 +221,7 @@ vm_stats_total.num_is_class_initialized++; clss->num_class_init_checks++; #endif // VM_STATS - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return clss->state == ST_Initialized; } //is_class_initialized @@ -393,10 +389,10 @@ memset(stub, 0xcc /*int 3*/, stub_size); #endif char *ss = stub; - -#ifdef PLATFORM_POSIX +// openTM integration +//#ifdef PLATFORM_POSIX ss = call(ss, (char *)vm_get_gc_thread_local); -#else // !PLATFORM_POSIX +/*#else // !PLATFORM_POSIX *ss++ = (char)0x64; *ss++ = (char)0xa1; *ss++ = (char)0x14; @@ -405,6 +401,7 @@ *ss++ = (char)0x00; ss = alu(ss, add_opc, eax_opnd, Imm_Opnd((uint32)&((VM_thread *)0)->_gc_private_information)); #endif // !PLATFORM_POSIX +*/ ss = push(ss, eax_opnd); ss = push(ss, M_Base_Opnd(esp_reg, 12)); @@ -423,9 +420,10 @@ *backpatch_address__fast_alloc_failed = (char)offset; ss = gen_setup_j2n_frame(ss); -#ifdef PLATFORM_POSIX +// openTM integration +//#ifdef PLATFORM_POSIX ss = call(ss, (char *)vm_get_gc_thread_local); -#else // !PLATFORM_POSIX +/*#else // !PLATFORM_POSIX *ss++ = (char)0x64; *ss++ = (char)0xa1; *ss++ = (char)0x14; @@ -434,6 +432,7 @@ *ss++ = (char)0x00; ss = alu(ss, add_opc, eax_opnd, Imm_Opnd((uint32)&((VM_thread *)0)->_gc_private_information)); #endif // !PLATFORM_POSIX +*/ ss = push(ss, eax_opnd); ss = push(ss, M_Base_Opnd(esp_reg, 8+m2n_sizeof_m2n_frame)); ss = push(ss, M_Base_Opnd(esp_reg, 8+m2n_sizeof_m2n_frame)); @@ -926,7 +925,7 @@ static void vm_throw_java_lang_ArithmeticException() { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); throw_java_exception("java/lang/ArithmeticException"); ABORT("The last called function should not return"); } //vm_throw_java_lang_ArithmeticException @@ -1125,7 +1124,7 @@ static int64 __stdcall vm_lrem(int64 m, int64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); return m % n; } //vm_lrem @@ -1176,7 +1175,7 @@ static int64 __stdcall vm_ldiv(int64 m, int64 n) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(n); return m / n; } //vm_ldiv @@ -1236,7 +1235,14 @@ #endif //VM_STATS +void * getaddress__vm_monitor_enter_naked(); +void * getaddress__vm_monitor_enter_static_naked(); +void * getaddress__vm_monitor_exit_naked(); +/** + * Returns fast monitor exit static function. + */ +void * getaddress__vm_monitor_exit_static_naked(); void *vm_get_rt_support_addr(VM_RT_SUPPORT f) { #ifdef VM_STATS Index: vm/vmcore/src/util/ia32/base/compile_IA32.cpp =================================================================== --- vm/vmcore/src/util/ia32/base/compile_IA32.cpp (revision 430048) +++ vm/vmcore/src/util/ia32/base/compile_IA32.cpp (working copy) @@ -36,7 +36,7 @@ #include "lock_manager.h" #include "open/types.h" -#include "open/thread.h" + #include "Class.h" #include "environment.h" #include "method_lookup.h" @@ -97,7 +97,7 @@ void compile_protect_arguments(Method_Handle method, GcFrame* gc) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); Method_Signature_Handle msh = method_get_signature(method); unsigned num_args = method_args_get_number(msh); unsigned num_arg_words = ((Method*)method)->get_num_arg_bytes()>>2; @@ -262,13 +262,13 @@ // pop args, leaving stack pointer pointing at return address ss = alu(ss, add_opc, esp_opnd, ecx_opnd); ss = ret(ss); - break; } + break; case CNP_JmpToRetAddrFinalAction: { // Continue execution in, e.g., the newly compiled method. ss = jump(ss, eax_opnd); - break; } + break; default: ABORT("Wrong final action"); } @@ -484,7 +484,6 @@ // // return addr; //} // compile_gen_compile_me_exc_throw - void gen_native_hashcode(Emitter_Handle h, Method *m); unsigned native_hashcode_fastpath_size(Method *m); Index: vm/vmcore/src/util/ia32/base/ini_iA32.cpp =================================================================== --- vm/vmcore/src/util/ia32/base/ini_iA32.cpp (revision 430048) +++ vm/vmcore/src/util/ia32/base/ini_iA32.cpp (working copy) @@ -32,7 +32,7 @@ #include "Class.h" #include "exceptions.h" #include "vm_threads.h" -#include "open/thread.h" + #include "compile.h" #include "nogc.h" #include "encoder.h" @@ -128,7 +128,7 @@ int argId = sz; int pos = 0; - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); if (!method->is_static()) { ObjectHandle handle = (ObjectHandle) args[pos++].l; assert(handle); Index: vm/vmcore/src/util/ia32/base/jit_lock_rt_support_ia32.cpp =================================================================== --- vm/vmcore/src/util/ia32/base/jit_lock_rt_support_ia32.cpp (revision 430048) +++ vm/vmcore/src/util/ia32/base/jit_lock_rt_support_ia32.cpp (working copy) @@ -18,6 +18,8 @@ * @version $Revision: 1.1.2.2.4.3 $ */ +#include +#include #include "platform_lowlevel.h" @@ -40,7 +42,6 @@ #include "lil_code_generator.h" #include "../m2n_ia32_internal.h" #include "object_handles.h" -#include "open/thread.h" #include "Class.h" #ifdef VM_STATS @@ -51,7 +52,7 @@ #include "dump.h" extern bool dump_stubs; #endif - +#define INPUT_ARG_OFFSET 4 char *gen_setup_j2n_frame(char *s); char *gen_pop_j2n_frame(char *s); @@ -77,72 +78,53 @@ } //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 ss = inc(ss, M_Opnd((unsigned)&(vm_stats_total.num_monitor_enter))); #endif - -#ifdef USE_TLS_API - ss = call(ss, (char *)get_self_stack_key); - ss = mov(ss, edx_opnd, eax_opnd); -#else //USE_TLS_API - *ss++ = (char)0x64; - *ss++ = (char)0xa1; - *ss++ = (char)0x14; - *ss++ = (char)0x00; - *ss++ = (char)0x00; - *ss++ = (char)0x00; - ss = mov(ss, edx_opnd, M_Base_Opnd(eax_reg, (uint32)&((VM_thread *)0)->stack_key) ); -#endif //!USE_TLS_API - - ss = alu(ss, xor_opc, eax_opnd, eax_opnd); ss = mov(ss, ecx_opnd, M_Base_Opnd(esp_reg, INPUT_ARG_OFFSET)); ss = test(ss, ecx_opnd, ecx_opnd); ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); char *backpatch_address__null_pointer = ((char *)ss) - 1; - ss = prefix(ss, lock_prefix); - ss = cmpxchg(ss, M_Base_Opnd(ecx_reg, header_offset + STACK_KEY_OFFSET), edx_opnd, size_16); + ss = alu(ss, add_opc, ecx_opnd, Imm_Opnd(header_offset)); // pop parameters + ss = gen_monitorenter_fast_path_helper(ss, ecx_opnd); + ss = test(ss, eax_opnd, eax_opnd); ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); char *backpatch_address__fast_monitor_failed = ((char *)ss) - 1; - ss = ret(ss, Imm_Opnd(4)); - signed offset = (signed)ss - (signed)backpatch_address__fast_monitor_failed - 1; + // Slow path: happens when the monitor is busy (contention case) + offset = (signed)ss - (signed)backpatch_address__fast_monitor_failed - 1; *backpatch_address__fast_monitor_failed = (char)offset; ss = gen_setup_j2n_frame(ss); ss = push(ss, M_Base_Opnd(esp_reg, m2n_sizeof_m2n_frame)); -/* - // packing heap pointer to handle -salikh ss = call(ss, (char *)oh_convert_to_local_handle); ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters - ss = push(ss, eax_opnd); // push the address of the handle - ss = call(ss, (char *)tmn_suspend_enable); // enable gc - // -salikh - ss = call(ss, (char *)vm_monitor_enter_slow_handle); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters - - // disable gc afterwards -salikh - ss = call(ss, (char *)tmn_suspend_disable); // disable gc - // -salikh -*/ - ss = call(ss, (char *)vm_monitor_enter_slow); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); + ss = gen_monitorenter_slow_path_helper(ss, eax_opnd); ss = gen_pop_j2n_frame(ss); ss = ret(ss, Imm_Opnd(4)); - offset = (signed)ss - (signed)backpatch_address__null_pointer - 1; - *backpatch_address__null_pointer = (char)offset; + // Handle NPE here + signed npe_offset = (signed)ss - (signed)backpatch_address__null_pointer - 1; + *backpatch_address__null_pointer = (char)npe_offset; if (patch_addr_null_arg != NULL) { - offset = (signed)ss - (signed)patch_addr_null_arg - 1; - *patch_addr_null_arg = (char)offset; + npe_offset = (signed)ss - (signed)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()); @@ -197,127 +179,40 @@ static char * gen_restore_monitor_exit(char *ss, char *patch_addr_null_arg) { + const unsigned header_offset = ManagedObject::header_offset(); #ifdef VM_STATS - ss = inc(ss, M_Opnd((unsigned)&(vm_stats_total.num_monitor_exit))); + ss = inc(ss, M_Opnd((unsigned)&(vm_stats_total.num_monitor_enter))); #endif -#define CHECK_FOR_ILLEGAL_MONITOR_STATE_EXCEPTION -#ifdef CHECK_FOR_ILLEGAL_MONITOR_STATE_EXCEPTION -#ifdef USE_TLS_API - ss = call(ss, (char *)get_self_stack_key); - ss = shift(ss, shl_opc, eax_opnd, Imm_Opnd(16)); -#else -//#error This code has not been tested. - ss = mov(ss, eax_opnd, esp_opnd); - ss = alu(ss, and_opc, eax_opnd, Imm_Opnd(0xffff0000)); -#endif //#ifdef USE_TLS_API else ss = mov(ss, ecx_opnd, M_Base_Opnd(esp_reg, INPUT_ARG_OFFSET)); - ss = alu(ss, xor_opc, eax_opnd, M_Base_Opnd(ecx_reg, header_offset)); - ss = test(ss, eax_opnd, Imm_Opnd(0xffffff80)); - ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); - char *backpatch_address__slow_path = ((char *)ss) - 1; - ss = alu(ss, and_opc, M_Base_Opnd(ecx_reg, header_offset), Imm_Opnd(0x0000ffff)); - ss = ret(ss, Imm_Opnd(4)); - signed offset1 = (signed)ss-(signed)backpatch_address__slow_path - 1; - *backpatch_address__slow_path = (char)offset1; -#else // !CHECK_FOR_ILLEGAL_MONITOR_STATE_EXCEPTION - ss = mov(ss, ecx_opnd, M_Base_Opnd(esp_reg, INPUT_ARG_OFFSET)); - // The current ia32.cpp doesn't support a 16-bit test instruction, so - // we hack it here. - *ss = 0x66; ss++; // prefix 0x66 means use the 16-bit form instead of the 32-bit form - ss = test(ss, M_Base_Opnd(ecx_reg, header_offset), Imm_Opnd(0xff80)); - ss -= 2; // Adjust for a 16-bit immediate instead of a 32-bit immediate. - ss = branch8(ss, cc_ne, Imm_Opnd(size_8, 0), 0); - char *backpatch_address__slow_path = ((char *)ss) - 1; - ss = mov(ss, M_Base_Opnd(ecx_reg, header_offset + STACK_KEY_OFFSET), Imm_Opnd(0), opnd_16); - ss = ret(ss, Imm_Opnd(4)); - signed offset1 = (signed)ss-(signed)backpatch_address__slow_path - 1; - *backpatch_address__slow_path = offset1; -#endif // !CHECK_FOR_ILLEGAL_MONITOR_STATE_EXCEPTION + ss = test(ss, ecx_opnd, ecx_opnd); + ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); + char *backpatch_address__null_pointer = ((char *)ss) - 1; -#ifdef USE_TLS_API - ss = call(ss, (char *)get_self_stack_key); - ss = mov(ss, edx_opnd, eax_opnd); -#else //USE_TLS_API - *ss++ = (char)0x64; - *ss++ = (char)0xa1; - *ss++ = (char)0x14; - *ss++ = (char)0x00; - *ss++ = (char)0x00; - *ss++ = (char)0x00; - ss = mov(ss, edx_opnd, M_Base_Opnd(eax_reg, (uint32)&((VM_thread *)0)->stack_key) ); -#endif //!USE_TLS_API - - ss = mov(ss, ecx_opnd, M_Base_Opnd(esp_reg, INPUT_ARG_OFFSET)); - ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, header_offset + STACK_KEY_OFFSET ), size_16); - ss = alu(ss, cmp_opc, eax_opnd, edx_opnd, size_16); + ss = alu(ss, add_opc, ecx_opnd, Imm_Opnd(header_offset)); + ss = gen_monitor_exit_helper(ss, ecx_opnd); + ss = test(ss, eax_opnd, eax_opnd); ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); - char *backpatch_address__illegal_monitor_failed = ((char *)ss) - 1; - - ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg,header_offset + HASH_CONTENTION_AND_RECURSION_OFFSET), size_16); - - // need to code AH: ESP & size_8 -> AH - ss = alu(ss, cmp_opc, esp_opnd, Imm_Opnd(size_8, 0), size_8); - - ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); - char *backpatch_address__recursed_monitor_failed = ((char *)ss) - 1; - - //release the lock - - ss = mov(ss, edx_opnd, Imm_Opnd(0)); - ss = mov(ss, M_Base_Opnd(ecx_reg, header_offset + STACK_KEY_OFFSET), edx_opnd, size_16); - - ss = mov(ss, edx_opnd, eax_opnd); - ss = alu(ss, and_opc, edx_opnd, Imm_Opnd(0x80)); - - ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); - char *backpatch_address__contended_monitor_failed = ((char *)ss) - 1; + char *backpatch_address__fast_monitor_failed = ((char *)ss) - 1; ss = ret(ss, Imm_Opnd(4)); - signed - offset = (signed)ss-(signed)backpatch_address__contended_monitor_failed - 1; - *backpatch_address__contended_monitor_failed = (char)offset; - ss = push(ss, M_Base_Opnd(esp_reg, INPUT_ARG_OFFSET)); - ss = call(ss, (char *)find_an_interested_thread); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); - ss = ret(ss, Imm_Opnd(4)); + signed offset = (signed)ss - (signed)backpatch_address__fast_monitor_failed - 1; + *backpatch_address__fast_monitor_failed = (char)offset; + // illegal state happend + ss = jump(ss, (char*)exn_get_rth_throw_illegal_state_exception()); - offset = (signed)ss-(signed)backpatch_address__recursed_monitor_failed - 1; - *backpatch_address__recursed_monitor_failed = (char)offset; - // esp_opnd & size_8 translates to AH - ss = dec(ss, esp_opnd, size_8); - ss = mov(ss, M_Base_Opnd(ecx_reg, header_offset + RECURSION_OFFSET), esp_opnd, size_8); - ss = ret(ss, Imm_Opnd(4)); - - offset = (signed)ss-(signed)backpatch_address__illegal_monitor_failed - 1; - *backpatch_address__illegal_monitor_failed = (char)offset; + 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; } - ss = gen_setup_j2n_frame(ss); - ss = push(ss, M_Base_Opnd(esp_reg, m2n_sizeof_m2n_frame)); - - /* - // packing heap pointer to handle -salikh - ss = call(ss, (char *)oh_convert_to_local_handle); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters - ss = push(ss, eax_opnd); // push the address of the handle - ss = call(ss, (char *)tmn_suspend_enable); // enable gc - // -salikh - - ss = call(ss, (char *)vm_monitor_exit_handle); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); - - // disable gc afterwards -salikh - ss = call(ss, (char *)tmn_suspend_disable); // disable gc - // -salikh -*/ - ss = call(ss, (char *)vm_monitor_exit); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); + // 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 @@ -372,7 +267,7 @@ return addr; } - const int stub_size = 126; + const int stub_size = 226; 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); @@ -411,7 +306,7 @@ return addr; } - const int stub_size = 150; + const int stub_size = 250; 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); Index: vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp =================================================================== --- vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp (revision 430048) +++ vm/vmcore/src/util/ipf/base/jit_runtime_support_ipf.cpp (working copy) @@ -50,7 +50,7 @@ #include "open/vm_util.h" #include "vm_strings.h" #include "vm_threads.h" -#include "open/thread.h" + #include "vm_stats.h" #include "merced.h" #include "Code_Emitter.h" @@ -167,7 +167,7 @@ extern "C" ManagedObject *vm_rt_new_resolved(Class *c) { - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); assert(strcmp(c->name->bytes, "java/lang/Class")); #ifdef VM_STATS vm_stats_total.num_class_alloc_new_object++; @@ -1250,7 +1250,7 @@ emitter.set_target(nonnull_target); } - // If the cmpxchg failed, we fall through and execute the slow monitor enter path by calling vm_monitor_enter_slow. + // If the cmpxchg failed, we fall through and execute the slow monitor enter path by calling vm_monitor_enter. } //gen_vm_rt_monitorenter_fast_path @@ -1427,9 +1427,9 @@ if (addr) { return addr; } - void (*p_vm_monitor_enter_slow)(ManagedObject *p_obj); - p_vm_monitor_enter_slow = vm_monitor_enter_slow; - addr = gen_vm_rt_monitor_wrapper((void **)p_vm_monitor_enter_slow, gen_vm_rt_monitorenter_fast_path, + void (*p_vm_monitor_enter)(ManagedObject *p_obj); + p_vm_monitor_enter = vm_monitor_enter; + addr = gen_vm_rt_monitor_wrapper((void **)p_vm_monitor_enter, gen_vm_rt_monitorenter_fast_path, check_null, /*static_operation*/ false, "rt_monitor_enter_slowpath", "rt_monitor_enter_fastpath"); return addr; @@ -1460,9 +1460,9 @@ return addr; } // 20030220 The "static" monitor enter function is only called with a struct Class pointer, which can't be NULL. - void (*p_vm_monitor_enter_slow)(ManagedObject *p_obj); - p_vm_monitor_enter_slow = vm_monitor_enter_slow; - addr = gen_vm_rt_monitor_wrapper((void **)p_vm_monitor_enter_slow, gen_vm_rt_monitorenter_fast_path, + void (*p_vm_monitor_enter)(ManagedObject *p_obj); + p_vm_monitor_enter = vm_monitor_enter; + addr = gen_vm_rt_monitor_wrapper((void **)p_vm_monitor_enter, gen_vm_rt_monitorenter_fast_path, /*check_null*/ false, /*static_operation*/ true, "rt_monitor_enter_static_slowpath", "rt_monitor_enter_static_fastpath"); return addr; Index: vm/vmcore/src/util/ipf/base/compile_ipf.cpp =================================================================== --- vm/vmcore/src/util/ipf/base/compile_ipf.cpp (revision 430048) +++ vm/vmcore/src/util/ipf/base/compile_ipf.cpp (working copy) @@ -58,7 +58,7 @@ #include "open/vm_util.h" #include "vm_synch.h" #include "vm_threads.h" -#include "open/thread.h" + #include "ini.h" #define METHOD_NAME_BUF_SIZE 512 @@ -363,7 +363,7 @@ static void protect_value_type(Class_Handle c, uint64* start, GcFrame* gc) { ABORT("It is supposed that the function is never called"); - assert(!tmn_is_suspend_enabled()); + assert(!hythread_is_suspend_enabled()); unsigned num_fields = class_num_instance_fields_recursive(c); for(unsigned i=0; iget_code_addr(); int nargs = meth->get_num_args(); uint64 arg_words[255]; Index: vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp (revision 430048) +++ vm/jitrino/src/codegenerator/ia32/Ia32BBPolling.cpp (working copy) @@ -50,13 +50,14 @@ RegName_EDI); // Basic Block for flag address calculating. (To be inserted before the loopHeaders) BasicBlock * bbpFlagAddrBlock = irManager.newBasicBlock(); -#ifdef PLATFORM_POSIX +//#ifdef PLATFORM_POSIX // TLS base can be obtained by calling get_thread_ptr() (from vm_threads.h) Opnd * target=irManager.newImmOpnd( irManager.getTypeManager().getIntPtrType(), Opnd::RuntimeInfo::Kind_HelperAddress, (void*)CompilationInterface::Helper_GetSuspReqFlag ); bbpFlagAddrBlock->appendInsts(irManager.newCallInst(target, &CallingConvention_STDCALL, 0, NULL, tlsBaseReg)); +/* #else // PLATFORM_POSIX // TLS base can be obtained from [fs:0x14] Opnd* tlsBase = irManager.newMemOpnd(typeInt32, MemOpndKind_Any, NULL, 0x14, RegName_FS); @@ -67,7 +68,7 @@ bbpFlagAddrBlock->appendInsts(irManager.newInst(Mnemonic_MOV, tlsBaseReg, tlsBase)); } #endif // PLATFORM_POSIX - +*/ // inserting bbpFlagAddrBlock before the given loopHeader uint32 startIndex = otherStartNdx[id]; Index: vm/jitrino/src/jet/cg_ia32.cpp =================================================================== --- vm/jitrino/src/jet/cg_ia32.cpp (revision 430048) +++ vm/jitrino/src/jet/cg_ia32.cpp (working copy) @@ -1260,9 +1260,10 @@ m_curr_bb_state->seen_gcpt = true; veax(); -#ifdef PLATFORM_POSIX +//#ifdef PLATFORM_POSIX gen_call_vm(rt_helper_get_thread_suspend_ptr, 0); voper(Mnemonic_CMP, MK_MEM32(RegName_EAX, 0), Imm32_0); +/* #else // This is a bit quicker, but tricky way - VM uses TIB to store // thread-specific info, and the offset of suspend request flag is @@ -1276,6 +1277,7 @@ MK_MEM32(RegName_EAX, rt_suspend_req_flag_offset)); voper(Mnemonic_TEST, RegName_EAX, RegName_EAX); #endif +*/ unsigned patch_id = vjcc(ConditionMnemonic_E, InstPrefix_HintTaken); // gen_mem(MEM_TO_MEM|MEM_VARS|MEM_STACK|MEM_NO_UPDATE);