diff --git a/runtime/src/globals/field_offsets.rs b/runtime/src/globals/field_offsets.rs index 6c97f34..20c5fb4 100644 --- a/runtime/src/globals/field_offsets.rs +++ b/runtime/src/globals/field_offsets.rs @@ -94,3 +94,18 @@ pub fn field_holder_thread_status_field_offset() -> usize { pub unsafe fn set_field_holder_thread_status_field_offset(value: usize) { FIELDHOLDER_THREAD_STATUS_FIELD_OFFSET = value; } + +static mut THREAD_EETOP_FIELD_OFFSET: usize = 0; + +/// `java.lang.Thread#eetop` field offset +/// +/// This will not change for the lifetime of the program. +/// +/// Expected type: `jlong` +pub fn thread_eetop_field_offset() -> usize { + unsafe { THREAD_EETOP_FIELD_OFFSET } +} + +pub unsafe fn set_thread_eetop_field_offset(value: usize) { + THREAD_EETOP_FIELD_OFFSET = value; +} diff --git a/runtime/src/initialization.rs b/runtime/src/initialization.rs index a260cc6..b4a3f84 100644 --- a/runtime/src/initialization.rs +++ b/runtime/src/initialization.rs @@ -58,7 +58,7 @@ fn initialize_thread(thread: &JavaThread) { } // Grab the java.lang.Thread field offsets - JavaThread::set_field_holder_offsets(); + JavaThread::set_field_offsets(); // Init some important classes initialize_global_classes(thread); diff --git a/runtime/src/native/jdk/internal/misc/Unsafe.rs b/runtime/src/native/jdk/internal/misc/Unsafe.rs index d70e029..3b46772 100644 --- a/runtime/src/native/jdk/internal/misc/Unsafe.rs +++ b/runtime/src/native/jdk/internal/misc/Unsafe.rs @@ -127,8 +127,12 @@ where } #[doc(hidden)] - unsafe fn __put_raw(&self, _value: T) { - unimplemented!("put at raw pointer offsets"); + unsafe fn __put_raw(&self, value: T) { + let offset = self.offset; + let ptr = offset as *mut T; + unsafe { + *ptr = value; + } } #[doc(hidden)] diff --git a/runtime/src/native/mod.rs b/runtime/src/native/mod.rs index 819970b..e23ad05 100644 --- a/runtime/src/native/mod.rs +++ b/runtime/src/native/mod.rs @@ -84,6 +84,27 @@ pub(self) fn insert_method((def, ptr): (NativeMethodDef, NativeMethodPtr)) { // Module marker, do not remove +pub(crate) mod jdk { + pub(crate) mod internal { + pub(crate) mod misc { + pub(crate) mod ScopedMemoryAccess; + pub(crate) mod CDS; + pub(crate) mod VM; + pub(crate) mod Unsafe; + pub(crate) mod Signal; + } + pub(crate) mod util { + pub(crate) mod SystemProps; + } + pub(crate) mod loader { + pub(crate) mod NativeLibraries; + } + pub(crate) mod reflect { + pub(crate) mod Reflection; + } + } +} + pub(crate) mod java { pub(crate) mod io { pub(crate) mod FileInputStream; @@ -111,24 +132,3 @@ pub(crate) mod java { } } -pub(crate) mod jdk { - pub(crate) mod internal { - pub(crate) mod misc { - pub(crate) mod ScopedMemoryAccess; - pub(crate) mod CDS; - pub(crate) mod VM; - pub(crate) mod Unsafe; - pub(crate) mod Signal; - } - pub(crate) mod util { - pub(crate) mod SystemProps; - } - pub(crate) mod loader { - pub(crate) mod NativeLibraries; - } - pub(crate) mod reflect { - pub(crate) mod Reflection; - } - } -} - diff --git a/runtime/src/thread.rs b/runtime/src/thread.rs index ca240c1..8f82a39 100644 --- a/runtime/src/thread.rs +++ b/runtime/src/thread.rs @@ -223,57 +223,70 @@ pub enum ThreadStatus { /// `java.lang.Thread$FieldHolder` accessors impl JavaThread { - pub fn set_field_holder_offsets() { - // java.lang.Thread#holder + pub fn set_field_offsets() { + // java.lang.Thread fields { let class = crate::globals::classes::java_lang_Thread(); - for (index, field) in class - .fields() - .filter(|field| !field.is_static()) - .enumerate() - { + + let mut field_set = 0; + for (index, field) in class.instance_fields().enumerate() { if field.name == sym!(holder) { unsafe { crate::globals::field_offsets::set_thread_holder_field_offset(index); } - break; + field_set |= 1; + continue; } - } - } - // java.lang.Thread$FieldHolder fields - { - let class = crate::globals::classes::java_lang_Thread_FieldHolder(); + if field.name == sym!(eetop) { + unsafe { + crate::globals::field_offsets::set_thread_eetop_field_offset(index); + } - let mut field_set = 0; - for (index, field) in class.fields().enumerate() { - match field.name.as_str() { - "priority" => unsafe { - crate::globals::field_offsets::set_field_holder_priority_field_offset( - index, - ); - field_set |= 1; - }, - "daemon" => unsafe { - crate::globals::field_offsets::set_field_holder_daemon_field_offset(index); - field_set |= 1 << 1; - }, - "threadStatus" => unsafe { - crate::globals::field_offsets::set_field_holder_thread_status_field_offset( - index, - ); - field_set |= 1 << 2; - }, - _ => {}, + field_set |= 1 << 1; + continue; } } assert_eq!( - field_set, 0b111, - "Not all fields were found in java/lang/Thread$FieldHolder" + field_set, 0b11, + "Not all fields were found in java/lang/Thread" ); } + + Self::set_field_holder_offsets(); + } + + // java.lang.Thread$FieldHolder fields + fn set_field_holder_offsets() { + let class = crate::globals::classes::java_lang_Thread_FieldHolder(); + + let mut field_set = 0; + for (index, field) in class.fields().enumerate() { + match field.name.as_str() { + "priority" => unsafe { + crate::globals::field_offsets::set_field_holder_priority_field_offset(index); + field_set |= 1; + }, + "daemon" => unsafe { + crate::globals::field_offsets::set_field_holder_daemon_field_offset(index); + field_set |= 1 << 1; + }, + "threadStatus" => unsafe { + crate::globals::field_offsets::set_field_holder_thread_status_field_offset( + index, + ); + field_set |= 1 << 2; + }, + _ => {}, + } + } + + assert_eq!( + field_set, 0b111, + "Not all fields were found in java/lang/Thread$FieldHolder" + ); } fn set_field_holder_field(&self, offset: usize, value: Operand) { @@ -367,6 +380,7 @@ impl JavaThread { // Set the obj early, since the java.lang.Thread constructor calls Thread#current. self.set_obj(Reference::class(ClassInstanceRef::clone(&thread_instance))); + self.set_eetop(); let init_method = thread_class .vtable() @@ -409,6 +423,16 @@ impl JavaThread { let obj_opt = unsafe { &*obj_ptr }; obj_opt.as_ref().map(Reference::clone) } + + fn set_eetop(&self) { + let offset = crate::globals::field_offsets::thread_eetop_field_offset(); + + let obj = self.obj().unwrap(); + obj.extract_class().get_mut().put_field_value0( + offset, + Operand::Long(JavaThread::current_ptr() as jni::sys::jlong), + ); + } } impl JavaThread { diff --git a/symbols/src/lib.rs b/symbols/src/lib.rs index e9e32e8..1f41961 100644 --- a/symbols/src/lib.rs +++ b/symbols/src/lib.rs @@ -202,6 +202,7 @@ vm_symbols::define_symbols! { // Fields holder: "holder", + eetop: "eetop", value: "value", coder: "coder", fd: "fd",