blob: 00c63e1b26ed5b8dad634b1076f11479b69b4193 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef THREAD_MANAGER_HEADER
#define THREAD_MANAGER_HEADER
#include "open/hythread.h"
#include "jthread.h"
#include "exceptions_type.h"
#define GC_BYTES_IN_THREAD_LOCAL (20 * sizeof(void *))
#define CONVERT_ERROR(stat) (stat)
#define TM_JVMTI_MAX_BUFFER_SIZE 500
#define TM_INITIAL_OWNED_MONITOR_SIZE 32
#ifdef __cplusplus
extern "C"
{
#endif
struct jvmti_frame_pop_listener;
struct JVMTISingleStepState;
struct NCAISingleStepState;
struct ClassLoader;
struct Registers;
/**
* Java-specific context that is attached to tm_thread control structure by Java layer
*/
struct JVMTIThread
{
/**
* Blocked on monitor times count
*/
jlong blocked_count;
/**
* Blocked on monitor time in nanoseconds
*/
jlong blocked_time;
/**
* Waited on monitor times count
*/
jlong waited_count;
/**
* Waited on monitor time in nanoseconds
*/
jlong waited_time;
/**
* JVM TI local storage
*/
JVMTILocalStorage jvmti_local_storage;
/**
* Monitor this thread is blocked on.
*/
jobject contended_monitor;
/**
* Monitor this thread waits on.
*/
jobject wait_monitor;
/**
* Monitors for which this thread is owner.
*/
jobject *owned_monitors;
/**
* owned monitors count.
*/
int owned_monitors_nmb;
/**
* owned monitors array size.
*/
int owned_monitors_size;
/**
* For support of JVMTI events: EXCEPTION, EXCEPTION_CATCH
* If p_exception_object is set and p_exception_object_ti is not
* - EXCEPTION event should be generated
* If p_exception_object_ti is set and p_exception_object is not
* - EXCEPTION_CATCH even should be generated
*/
volatile struct ManagedObject *p_exception_object_ti;
/**
* Buffer used to create instructions instead of original instruction
* to transfer execution control back to the code after breakpoint
* has been processed
*/
jbyte *jvmti_jit_breakpoints_handling_buffer;
struct jvmti_frame_pop_listener *frame_pop_listener;
struct JVMTISingleStepState *ss_state;
struct Registers *jvmti_saved_exception_registers;
// Flag and restart address for memory access violation detection
int violation_flag;
void* violation_restart_address;
// Storage for NCAI Single Step data
struct NCAISingleStepState* ncai_ss;
// Is set when current thread is in NCAI handler
jboolean flag_ncai_handler;
};
struct VM_thread
{
/**
* Native thread which is associated with <code>VM_thread</code>
* The fields of <code>HyThread</code> sub-structure should not be used in VM directly
* An address of <code>hy_thread</code> field should be used instead
* as an argument for <code>hythread*</code> functions.
*/
struct HyThread hy_thread;
/**
* Thread reference object to corresponding java.lang.ThreadWeakRef instance
*/
jobject weak_ref;
/**
* Java thread object to corresponding java.lang.Thread instance
*/
jobject java_thread;
/**
* Exception that has to be thrown in stopped thread
*/
jthrowable stop_exception;
/**
* Memory pool where this structure is allocated.
* This pool should be used by current thread for memory allocations.
*/
apr_pool_t *pool;
/**
* JNI environment associated with this thread.
*/
JNIEnv *jni_env;
/**
* Class loader which loads native library and calls to its JNI_OnLoad
*/
struct ClassLoader *onload_caller;
/**
* Flag to detect if a class is not found on bootclasspath,
* as opposed to linkage errors.
* Used for implementing default delegation model.
*/
unsigned char class_not_found;
/**
* Flag to detect if a thread is suspend.
* Used for serialization Java suspend.
*/
unsigned char suspend_flag;
// In case exception is thrown, Exception object is put here
volatile struct Exception thread_exception;
// flag which indicate that guard page on the stack should be restored
unsigned char restore_guard_page;
// thread stack address
void *stack_addr;
// thread stack size
UDATA stack_size;
int finalize_thread_flags;
// CPU registers.
struct Registers *regs;
// This field is private the to M2nFrame module, init code should set it to NULL
// Informational frame - created when native is called from Java,
// used to store local handles (jobjects) + registers.
// =0 if there is no m2n frame.
void *last_m2n_frame;
// GC Information
unsigned char _gc_private_information[GC_BYTES_IN_THREAD_LOCAL];
void *native_handles;
void *gc_frames;
#if defined(PLATFORM_POSIX) && defined(_IPF_)
// Linux/IPF
hysem_t suspend_self; // To suspend current thread for signal handler
uint64 suspended_state; // Flag to indicate how the one thread is suspended
// Possible values:
// NOT_SUSPENDED,
// SUSPENDED_IN_SIGNAL_HANDLER,
// SUSPENDED_IN_DISABLE_GC_FOR_THREAD
uint64 t[2]; // t[0] <= rnat, t[1] <= bspstore for current thread context
// t[0] <= rnat, t[1] <= bsp for other thread context
#endif
void *lastFrame;
void *firstFrame;
int interpreter_state;
/**
* The upper boundary of the stack to scan when verifying stack enumeration
*/
void **stack_end;
/**
* Is this thread daemon?
*/
IDATA daemon;
/**
* JVMTI support in thread structure
*/
struct JVMTIThread jvmti_thread;
};
/**
* Java thread creation attributes.
*/
struct jthread_start_proc_data
{
/**
* Native thread
*/
hythread_t native_thread;
/**
* Pointer to Java VM.
*/
JavaVM *java_vm;
/**
* Thread scheduling priority.
*/
jint priority;
/**
* Thread stack size.
*/
UDATA stacksize;
/**
* Denotes whether Java thread is daemon.
* JVM exits when the only threads running are daemon threads.
*/
jboolean daemon;
/**
* JVMTI environment.
*/
jvmtiEnv *jvmti_env;
/**
* JVMTI start function to be executed in this thread.
*/
jvmtiStartFunction proc;
/**
* Start function argument to the start function. Is passed as an array.
*/
const void *arg;
};
/**
* Registrates current thread in VM, so it could execute Java.
*
* @param[in] java_vm - current thread will be attached to the specified VM
* @param[out] p_jni_env - will point to JNI environment assocciated with the thread
*/
VMEXPORT jint vm_attach(JavaVM * java_vm, JNIEnv ** p_jni_env);
/**
* Frees java related resources before thread exit.
*/
VMEXPORT jint vm_detach(jobject java_thread);
/**
* Stores a pointer to TM-specific data in the <code>java.lang.Thread</code> object.
*
* A typical implementation may store a pointer within a private
* non-static field of Thread.
*
* @param[in] thread - a <code>java.lang.Thread</code> object those private field
* is going to be used for data storage
* @param[in] data_ptr - a pointer to data to be stored
*/
VMEXPORT void jthread_set_tm_data(jobject thread, void *data_ptr);
/**
* Retrieves TM-specific data from the <code>java.lang.Thread</code> object.
*
* @param[in] thread - a thread
*
* @return TM-specific data previously stored, or <code>NULL</code>,
* if there are none.
*/
VMEXPORT void* jthread_get_tm_data(jobject thread);
/**
* <code>vm_objects_are_equal<br>
* obj1 jobject<br>
* obj2 jobject</code>
*
* @return <code>int</code>
*/
VMEXPORT int vm_objects_are_equal(jobject obj1, jobject obj2);
/**
* Gets VM_thread from native thread
*/
hy_inline vm_thread_t jthread_self_vm_thread()
{
register hythread_t self = hythread_self();
return (self && self->java_status == TM_STATUS_INITIALIZED)
? ((vm_thread_t)self) : NULL;
} // jthread_self_vm_thread
/**
* Gets VM_thread from a given native thread
*/
hy_inline vm_thread_t jthread_get_vm_thread(hythread_t native)
{
return (native && native->java_status == TM_STATUS_INITIALIZED)
? ((vm_thread_t)native) : NULL;
} // jthread_get_vm_thread
/**
* Gets unsafe VM_thread from native thread.
* VM_thread could be not initialized.
*/
hy_inline vm_thread_t jthread_self_vm_thread_unsafe()
{
register hythread_t self = hythread_self();
return (self && self->java_status != TM_STATUS_WITHOUT_JAVA)
? ((vm_thread_t)self) : NULL;
} // jthread_self_vm_thread_unsafe
/**
* Gets unsafe VM_thread from a given native thread.
* VM_thread could be not initialized.
*/
hy_inline vm_thread_t jthread_get_vm_thread_unsafe(hythread_t native)
{
return (native && native->java_status != TM_STATUS_WITHOUT_JAVA)
? ((vm_thread_t)native) : NULL;
} // jthread_get_vm_thread_unsafe
/**
* Gets native thread associated with a given Java thread.
* @return native thread
*/
hy_inline hythread_t jthread_get_native_thread(jobject java_thread)
{
assert(java_thread);
return (hythread_t)jthread_get_tm_data(java_thread);
} // jthread_get_native_thread
/**
* Gets VM_thread associated with a given Java thread.
* @return pointer to VM_thread or NULL
*/
hy_inline vm_thread_t jthread_get_vm_thread_from_java(jobject java_thread)
{
vm_thread_t vm_thread;
assert(java_thread);
vm_thread = (vm_thread_t)jthread_get_tm_data(java_thread);
return (vm_thread && ((hythread_t)vm_thread)->java_status == TM_STATUS_INITIALIZED)
? vm_thread : NULL;
} // jthread_get_vm_thread_from_java
#ifdef __cplusplus
}
#endif
#endif // THREAD_MANAGER_HEADER