Add thread operations and improve thread initialization logic
This commit is contained in:
parent
1ed50300c4
commit
94f43066f9
@ -522,4 +522,54 @@ impl ObjectManager {
|
||||
}
|
||||
constructor_object
|
||||
}
|
||||
|
||||
pub fn new_thread_group(
|
||||
&mut self,
|
||||
thread_group_class: Arc<RuntimeClass>,
|
||||
name: ObjectReference,
|
||||
max_priority: jint,
|
||||
) -> ObjectReference {
|
||||
let tg_object = self.new_object(thread_group_class);
|
||||
{
|
||||
let obj = tg_object.lock();
|
||||
obj.set_field("name", name.into());
|
||||
obj.set_field("maxPriority", max_priority.into());
|
||||
}
|
||||
tg_object
|
||||
}
|
||||
pub fn new_holder(
|
||||
&mut self,
|
||||
holder_class: Arc<RuntimeClass>,
|
||||
group: ObjectReference,
|
||||
priority: jint,
|
||||
status: jint,
|
||||
) -> ObjectReference {
|
||||
let holder_object = self.new_object(holder_class);
|
||||
{
|
||||
let obj = holder_object.lock();
|
||||
obj.set_field("group", group.into());
|
||||
obj.set_field("priority", priority.into());
|
||||
obj.set_field("threadStatus", status.into());
|
||||
}
|
||||
holder_object
|
||||
}
|
||||
|
||||
pub fn new_thread(
|
||||
&mut self,
|
||||
thread_class: Arc<RuntimeClass>,
|
||||
eetop: jlong,
|
||||
tid: jlong,
|
||||
name: ObjectReference,
|
||||
holder: ObjectReference,
|
||||
) -> ObjectReference {
|
||||
let tg_object = self.new_object(thread_class);
|
||||
{
|
||||
let obj = tg_object.lock();
|
||||
obj.set_field("eetop", eetop.into());
|
||||
obj.set_field("tid", tid.into());
|
||||
obj.set_field("name", name.into());
|
||||
obj.set_field("holder", holder.into());
|
||||
}
|
||||
tg_object
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,8 +22,8 @@ use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::ops::{Add, Deref};
|
||||
use std::ptr::null_mut;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::sync::{Arc, OnceLock};
|
||||
|
||||
use std::thread;
|
||||
use std::vec::IntoIter;
|
||||
@ -46,12 +46,12 @@ pub struct VmThread {
|
||||
pub frame_stack: Mutex<Vec<Frame>>,
|
||||
pub gc: Arc<RwLock<ObjectManager>>,
|
||||
pub jni_env: JNIEnv,
|
||||
pub mirror: OnceLock<u32>,
|
||||
}
|
||||
|
||||
impl VmThread {
|
||||
pub fn new(vm: Arc<Vm>, loader: Option<LoaderRef>) -> Arc<Self> {
|
||||
static NEXT_ID: AtomicU64 = AtomicU64::new(0);
|
||||
let id = ThreadId(NEXT_ID.fetch_add(1, Ordering::SeqCst));
|
||||
let id = ThreadId(vm.NEXT_ID.fetch_add(1, Ordering::SeqCst));
|
||||
|
||||
let loader = loader.unwrap_or(vm.loader.clone());
|
||||
let gc = vm.gc.clone();
|
||||
@ -64,6 +64,7 @@ impl VmThread {
|
||||
frame_stack: Default::default(),
|
||||
gc,
|
||||
jni_env,
|
||||
mirror: Default::default(),
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -286,7 +287,7 @@ impl VmThread {
|
||||
}
|
||||
|
||||
pub fn invoke(&self, method_reference: MethodRef, args: Vec<Value>) -> MethodCallResult {
|
||||
if self.gc.read().objects.len() > 2230 {
|
||||
if self.gc.read().objects.len() > 2235 {
|
||||
INIT_LOGGER.call_once(|| {
|
||||
env_logger::Builder::from_default_env()
|
||||
.filter_level(LevelFilter::Trace)
|
||||
@ -320,9 +321,9 @@ impl VmThread {
|
||||
pub fn invoke_native(&self, method: &MethodRef, mut args: Vec<Value>) -> MethodCallResult {
|
||||
let symbol_name = generate_jni_method_name(method, false);
|
||||
|
||||
if symbol_name.contains("Java_jdk_internal_misc_Signal_handle0") {
|
||||
if symbol_name.contains("Java_jdk_internal_misc_Unsafe_getLongVolatile") {
|
||||
return Err(VmError::Debug(
|
||||
"RoastVM specific implementation required for Java_jdk_internal_misc_Signal_handle0",
|
||||
"RoastVM specific implementation required for Java_jdk_internal_misc_Unsafe_getLongVolatile",
|
||||
));
|
||||
}
|
||||
|
||||
@ -601,4 +602,26 @@ impl VmThread {
|
||||
gc.get_interned_string(utf)
|
||||
.unwrap_or_else(|| gc.new_string(byte_array_class, string_class, utf))
|
||||
}
|
||||
|
||||
pub fn bootstrap_mirror(&self) {
|
||||
let thread_id = self.id.0 as jlong;
|
||||
let main = self.intern_string("main");
|
||||
let system = self.intern_string("system");
|
||||
let thread_klass = self.get_class("java/lang/Thread").unwrap();
|
||||
let thread_group_klass = self.get_class("java/lang/ThreadGroup").unwrap();
|
||||
let field_holder_klass = self.get_class("java/lang/Thread$FieldHolder").unwrap();
|
||||
let group = self
|
||||
.gc
|
||||
.write()
|
||||
.new_thread_group(thread_group_klass, system, 10 as jint);
|
||||
let holder = self
|
||||
.gc
|
||||
.write()
|
||||
.new_holder(field_holder_klass, group, 5 as jint, 5 as jint);
|
||||
let thread = self
|
||||
.gc
|
||||
.write()
|
||||
.new_thread(thread_klass, thread_id, thread_id, main, holder);
|
||||
self.mirror.set(thread.lock().id).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ use imp::Library;
|
||||
use log::trace;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicU64;
|
||||
|
||||
type NativeLibraries = Arc<RwLock<Vec<(String, Library)>>>;
|
||||
|
||||
@ -34,6 +35,7 @@ pub struct Vm {
|
||||
pub native_libraries: NativeLibraries,
|
||||
pub gc: Arc<RwLock<ObjectManager>>,
|
||||
pub safent: RwLock<UnsafeSupport>,
|
||||
pub NEXT_ID: AtomicU64,
|
||||
}
|
||||
|
||||
impl Vm {
|
||||
@ -47,6 +49,7 @@ impl Vm {
|
||||
native_libraries: Arc::new(RwLock::new(Vec::new())),
|
||||
gc: Default::default(),
|
||||
safent: Default::default(),
|
||||
NEXT_ID: AtomicU64::new(0),
|
||||
});
|
||||
|
||||
// Create main thread
|
||||
@ -160,6 +163,10 @@ impl Vm {
|
||||
name: "initPhase1".to_string(),
|
||||
desc: MethodDescriptor::void(),
|
||||
};
|
||||
self.threads
|
||||
.get(&self.main_thread_id)
|
||||
.unwrap()
|
||||
.bootstrap_mirror();
|
||||
thread.invoke(phase1ref, Vec::new())?;
|
||||
panic!("HOLY FUCKING SHIT, DID WE PHASE 1!?");
|
||||
Ok(())
|
||||
|
||||
@ -2,12 +2,14 @@
|
||||
|
||||
mod CDS;
|
||||
mod class;
|
||||
mod memaccess;
|
||||
mod misc_unsafe;
|
||||
mod object;
|
||||
mod reflection;
|
||||
mod runtime;
|
||||
mod scoped_memory_access;
|
||||
mod signal;
|
||||
mod system;
|
||||
mod thread;
|
||||
|
||||
use jni::objects::{JClass, JObject, JString};
|
||||
use jni::strings::JNIString;
|
||||
|
||||
@ -571,3 +571,42 @@ pub unsafe extern "system" fn Java_jdk_internal_misc_Unsafe_fullFence(
|
||||
) {
|
||||
std::sync::atomic::fence(std::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "system" fn Java_jdk_internal_misc_Unsafe_getLongVolatile(
|
||||
env: *mut JNIEnv,
|
||||
_unsafe_obj: jobject,
|
||||
obj: jobject,
|
||||
offset: jlong,
|
||||
) -> jlong {
|
||||
let thread = &*get_thread(env);
|
||||
let reference = thread.gc.read().get(obj as u32);
|
||||
|
||||
match reference {
|
||||
ReferenceKind::ArrayReference(array_ref) => {
|
||||
if let ArrayReference::Long(arr) = array_ref {
|
||||
let guard = arr.lock();
|
||||
let index = (offset / 8) as usize;
|
||||
guard.backing[index]
|
||||
} else {
|
||||
panic!("getLongVolatile on non-long array")
|
||||
}
|
||||
}
|
||||
ReferenceKind::ObjectReference(obj_ref) => {
|
||||
let key = thread
|
||||
.vm
|
||||
.safent
|
||||
.read()
|
||||
.resolve_field(offset)
|
||||
.expect("unregistered field offset");
|
||||
let guard = obj_ref.lock();
|
||||
guard
|
||||
.fields
|
||||
.get(&key.field_name)
|
||||
.unwrap()
|
||||
.clone()
|
||||
.try_into_jlong()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
crates/roast-vm-sys/src/signal.rs
Normal file
11
crates/roast-vm-sys/src/signal.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use jni::sys::{JNIEnv, jclass, jint, jlong};
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "system" fn Java_jdk_internal_misc_Signal_handle0(
|
||||
_env: *mut JNIEnv,
|
||||
_cls: jclass,
|
||||
_sig: jint,
|
||||
_handler: jlong,
|
||||
) -> jlong {
|
||||
// Return 0 (SIG_DFL) - pretend no previous handler existed
|
||||
0
|
||||
}
|
||||
22
crates/roast-vm-sys/src/thread.rs
Normal file
22
crates/roast-vm-sys/src/thread.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::get_thread;
|
||||
use jni::sys::{JNIEnv, jclass, jint, jlong, jobject};
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "system" fn Java_java_lang_Thread_currentThread(
|
||||
env: *mut JNIEnv,
|
||||
_cls: jclass,
|
||||
) -> jobject {
|
||||
let thread = &*get_thread(env);
|
||||
let thread_id_obj = thread.mirror.get().unwrap();
|
||||
*thread_id_obj as jobject
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
unsafe extern "system" fn Java_java_lang_Thread_getNextThreadIdOffset(
|
||||
env: *mut JNIEnv,
|
||||
_cls: jclass,
|
||||
) -> jlong {
|
||||
let thread = &*get_thread(env);
|
||||
thread.vm.NEXT_ID.fetch_add(1, Ordering::Relaxed) as jlong
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user