use crate::class::RuntimeClass; use crate::class_file::ClassFlags; use crate::class_file::attributes::ArrayType; use crate::error::VmError; use crate::objects::array::{Array, ArrayReference}; use crate::objects::object::{ Object, ObjectReference, Reference, ReferenceKind, string_from_bytes, }; use crate::value::Value; use crate::{BaseType, ThreadId, VmSymbols}; use dashmap::DashMap; use jni::sys::{jint, jlong}; use parking_lot::{Condvar, Mutex}; use std::collections::HashMap; use std::sync::Arc; use std::sync::atomic::{AtomicU32, Ordering}; #[derive(Default)] pub struct ObjectManager { pub objects: HashMap, strings: HashMap, monitors: DashMap>, max_memory: usize, next_id: AtomicU32, } impl ObjectManager { pub fn max_memory(&self) -> usize { self.max_memory } fn next_id(&self) -> u32 { self.next_id.fetch_add(1, Ordering::Relaxed) } /// Returns the total bytes in use by all managed objects and arrays pub fn bytes_in_use(&self) -> usize { self.objects .values() .map(|kind| match kind { ReferenceKind::ObjectReference(r) => { let guard = r.lock(); guard .fields .iter() .map(|entry| entry.value().size_bytes()) .sum() } ReferenceKind::ArrayReference(a) => a.size_bytes(), }) .sum() } pub fn new_object(&mut self, class: Arc) -> ObjectReference { let id = self.next_id(); if self.objects.contains_key(&id) { let next = self.next_id(); let key_pairs = self .objects .iter() .map(|(id, obj)| format!("id: {id} obj: {}", obj.class().this_class)) .collect::>(); eprintln!("next: {} all: \n{:#?}", next, key_pairs) } assert!( !self.objects.contains_key(&id), "Generated ID already exists!" ); let object = Arc::new(Mutex::new(Object { id, class: class.clone(), fields: Default::default(), })); self.objects.insert(id, ReferenceKind::from(object.clone())); object } pub fn new_primitive_array(&mut self, class: Arc, count: i32) -> ArrayReference { let id = self.next_id(); assert!( !self.objects.contains_key(&id), "Generated ID already exists!" ); let symbol = class .this_class .strip_prefix("[") .unwrap() .chars() .next() .unwrap(); let array_type = symbol.into(); let array_ref = match array_type { BaseType::Int => { ArrayReference::Int(Arc::new(Mutex::new(Array::new(id, class, count)))) } BaseType::Byte => { ArrayReference::Byte(Arc::new(Mutex::new(Array::new(id, class, count)))) } BaseType::Short => { ArrayReference::Short(Arc::new(Mutex::new(Array::new(id, class, count)))) } BaseType::Long => { ArrayReference::Long(Arc::new(Mutex::new(Array::new(id, class, count)))) } BaseType::Float => { ArrayReference::Float(Arc::new(Mutex::new(Array::new(id, class, count)))) } BaseType::Double => { ArrayReference::Double(Arc::new(Mutex::new(Array::new(id, class, count)))) } BaseType::Char => { ArrayReference::Char(Arc::new(Mutex::new(Array::new(id, class, count)))) } BaseType::Boolean => { ArrayReference::Boolean(Arc::new(Mutex::new(Array::new(id, class, count)))) } }; self.objects .insert(id, ReferenceKind::ArrayReference(array_ref.clone())); array_ref } pub fn new_object_array(&mut self, class: Arc, count: i32) -> ArrayReference { let id = self.next_id(); assert!( !self.objects.contains_key(&id), "Generated ID already exists!" ); let array_ref = ArrayReference::Object(Arc::new(Mutex::new(Array::new(id, class, count)))); self.objects .insert(id, ReferenceKind::ArrayReference(array_ref.clone())); array_ref } pub fn new_object_array_from( &mut self, class: Arc, values: Box<[Reference]>, ) -> ArrayReference { let id = self.next_id(); assert!( !self.objects.contains_key(&id), "Generated ID already exists!" ); let array_ref = ArrayReference::Object(Arc::new(Mutex::new(Array::from((id, class, values))))); self.objects .insert(id, ReferenceKind::ArrayReference(array_ref.clone())); array_ref } pub fn new_byte_array( &mut self, class: Arc, vector: Box<[i8]>, ) -> ArrayReference { let id = self.next_id(); assert!( !self.objects.contains_key(&id), "Generated ID already exists!" ); let array_ref = ArrayReference::Byte(Arc::new(Mutex::new(Array::from((id, class, vector))))); self.objects .insert(id, ReferenceKind::ArrayReference(array_ref.clone())); array_ref } pub fn get(&self, id: u32) -> ReferenceKind { self.objects .get(&id) .unwrap_or_else(|| { let objs = self .objects .iter() .map(|(x, y)| format!("{x} : {y}")) .collect::>(); panic!("Object must be present id: {id}\n{objs:#?}") }) .clone() } pub fn get_interned_string(&self, utf: &str) -> Option { self.strings .get(utf) .and_then(|e| self.get(*e).try_into_object_reference().ok()) } pub fn new_string( &mut self, byte_array_class: Arc, string_class: Arc, utf8: &str, ) -> ObjectReference { let key = utf8.to_owned(); let jstr = self.new_object(string_class); let byte_vec = utf8 .encode_utf16() .flat_map(|e| e.to_le_bytes()) .map(|e| e as i8) .collect::>(); let barray = self.new_byte_array(byte_array_class, byte_vec.into_boxed_slice()); jstr.lock().fields.insert( "value".to_string(), Value::from(Some(ReferenceKind::ArrayReference(barray))), ); jstr.lock() .fields .insert("coder".to_string(), Value::from(1i8)); jstr.lock() .fields .insert("hash".to_string(), Value::from(0i32)); jstr.lock() .fields .insert("hashIsZero".to_string(), Value::from(false)); let id = jstr.lock().id; debug_assert!(!self.strings.contains_key(&key), "String already interned"); self.strings.insert(key, id); jstr } pub fn intern_existing_string(&mut self, utf: String, obj_id: u32) -> u32 { *self.strings.entry(utf).or_insert(obj_id) } pub fn new_class( &mut self, class_class: Arc, name: Reference, module: Reference, modifiers: ClassFlags, primitive: bool, component_type: Reference, ) -> ObjectReference { let string = self .transmute_string(name.clone().unwrap().try_into_object_reference().unwrap()) .unwrap(); if string.contains("byte") { println!("!!!!!"); } let module = None; let modifiers = 17u16; let class_redefined_count = 0i32; let clazz = self.new_object(class_class); { let clakz = clazz.lock(); clakz.set_field("name", Value::from(name)); clakz.set_field("module", Value::from(module)); clakz.set_field("modifiers", Value::from(modifiers)); clakz.set_field("primitive", Value::from(primitive)); clakz.set_field("classRedefinedCount", Value::from(class_redefined_count)); clakz.set_field("componentType", Value::from(component_type)) } clazz } /// using pure wizardry, transmute a string object into a rust string pub fn transmute_string(&self, string: ObjectReference) -> Result { let guard = string.lock(); let value_field = guard .fields .get("value") .ok_or_else(|| VmError::InvariantError("String must have value field".to_string()))?; let array_ref = match *value_field { Value::Reference(Some(ReferenceKind::ArrayReference(ref arr))) => arr.clone(), _ => { return Err(VmError::InvariantError( "String value field must be a byte array".to_string(), )); } }; let bytes = match array_ref { ArrayReference::Byte(byte_arr) => { let arr_guard = byte_arr.lock(); arr_guard.backing.clone() } _ => { return Err(VmError::InvariantError( "String value must be a byte array".to_string(), )); } }; Ok(string_from_bytes(&bytes)) } pub fn monitor_enter(&self, thread_id: ThreadId, obj_id: u32) { let monitor = self .monitors .entry(obj_id) .or_insert_with(|| Arc::new(Monitor::new())) .clone(); // DashMap entry guard dropped here, map unlocked let mut inner = monitor.inner.lock(); while inner.owner.is_some() && inner.owner != Some(thread_id) { monitor.condvar.wait(&mut inner); } inner.owner = Some(thread_id); inner.entry_count += 1; } pub fn monitor_exit(&self, thread_id: ThreadId, obj_id: u32) -> Result<(), VmError> { let monitor = self .monitors .get(&obj_id) .ok_or_else(|| VmError::InvariantError("Monitor not found for object".to_string()))? .clone(); let mut inner = monitor.inner.lock(); if inner.owner != Some(thread_id) { return Err(VmError::InvariantError( "Thread does not own monitor".to_string(), )); } inner.entry_count -= 1; if inner.entry_count == 0 { inner.owner = None; monitor.condvar.notify_one(); } Ok(()) } pub fn wait( &self, thread_id: ThreadId, obj_id: u32, timeout_millis: jlong, ) -> Result<(), VmError> { let monitor = self .monitors .get(&obj_id) .ok_or_else(|| VmError::InvariantError("Monitor not found".into()))? .clone(); let mut inner = monitor.inner.lock(); if inner.owner != Some(thread_id) { return Err(VmError::InvariantError( "IllegalMonitorStateException".into(), )); } // Save entry count, release monitor let saved_count = inner.entry_count; inner.entry_count = 0; inner.owner = None; inner.wait_count += 1; // Wake a thread waiting to enter monitor.condvar.notify_one(); // Wait for notify if timeout_millis > 0 { monitor.wait_condvar.wait_for( &mut inner, std::time::Duration::from_millis(timeout_millis as u64), ); } else { monitor.wait_condvar.wait(&mut inner); } inner.wait_count -= 1; // Reacquire monitor while inner.owner.is_some() { monitor.condvar.wait(&mut inner); } inner.owner = Some(thread_id); inner.entry_count = saved_count; Ok(()) } pub fn notify_one(&self, obj_id: u32) { if let Some(monitor) = self.monitors.get(&obj_id) { monitor.wait_condvar.notify_one(); } } pub fn notify_all(&self, obj_id: u32) { if let Some(monitor) = self.monitors.get(&obj_id) { monitor.wait_condvar.notify_all(); } } pub fn clone_object(&mut self, source: &ReferenceKind) -> Result { match source { ReferenceKind::ArrayReference(arr) => self.clone_array(arr), ReferenceKind::ObjectReference(obj) => { let class = obj.lock().class.clone(); if !class.implements(VmSymbols::CLONEABLE) { return Err(VmError::InvariantError("CloneNotSupported".to_string())); } self.clone_instance(obj) } } } fn clone_array(&mut self, arr: &ArrayReference) -> Result { let new_arr = match arr { ArrayReference::Int(a) => { let guard = a.lock(); let new_id = self.next_id(); ArrayReference::Int(Arc::new(Mutex::new(Array { id: new_id, class: guard.class.clone(), backing: guard.backing.clone(), }))) } ArrayReference::Byte(a) => { let guard = a.lock(); let new_id = self.next_id(); ArrayReference::Byte(Arc::new(Mutex::new(Array { id: new_id, class: guard.class.clone(), backing: guard.backing.clone(), }))) } ArrayReference::Short(a) => { let guard = a.lock(); let new_id = self.next_id(); ArrayReference::Short(Arc::new(Mutex::new(Array { id: new_id, class: guard.class.clone(), backing: guard.backing.clone(), }))) } ArrayReference::Long(a) => { let guard = a.lock(); let new_id = self.next_id(); ArrayReference::Long(Arc::new(Mutex::new(Array { id: new_id, class: guard.class.clone(), backing: guard.backing.clone(), }))) } ArrayReference::Float(a) => { let guard = a.lock(); let new_id = self.next_id(); ArrayReference::Float(Arc::new(Mutex::new(Array { id: new_id, class: guard.class.clone(), backing: guard.backing.clone(), }))) } ArrayReference::Double(a) => { let guard = a.lock(); let new_id = self.next_id(); ArrayReference::Double(Arc::new(Mutex::new(Array { id: new_id, class: guard.class.clone(), backing: guard.backing.clone(), }))) } ArrayReference::Char(a) => { let guard = a.lock(); let new_id = self.next_id(); ArrayReference::Char(Arc::new(Mutex::new(Array { id: new_id, class: guard.class.clone(), backing: guard.backing.clone(), }))) } ArrayReference::Boolean(a) => { let guard = a.lock(); let new_id = self.next_id(); ArrayReference::Boolean(Arc::new(Mutex::new(Array { id: new_id, class: guard.class.clone(), backing: guard.backing.clone(), }))) } ArrayReference::Object(a) => { let guard = a.lock(); let new_id = self.next_id(); ArrayReference::Object(Arc::new(Mutex::new(Array { id: new_id, class: guard.class.clone(), backing: guard.backing.clone(), // shallow clone - copies references, not objects }))) } }; let id = new_arr.id(); self.objects .insert(id, ReferenceKind::ArrayReference(new_arr.clone())); Ok(ReferenceKind::ArrayReference(new_arr)) } fn clone_instance(&mut self, obj: &ObjectReference) -> Result { let guard = obj.lock(); let class = guard.class.clone(); // Create a new object with the same class let new_obj = self.new_object(class); // Copy all fields (shallow copy) { let new_guard = new_obj.lock(); for entry in guard.fields.iter() { new_guard .fields .insert(entry.key().clone(), entry.value().clone()); } } Ok(ReferenceKind::ObjectReference(new_obj)) } } pub struct Monitor { inner: Mutex, condvar: Condvar, wait_condvar: Condvar, } struct MonitorInner { owner: Option, entry_count: u32, wait_count: u32, } impl Monitor { fn new() -> Self { Self { inner: Mutex::new(MonitorInner { owner: None, entry_count: 0, wait_count: 0, }), condvar: Condvar::new(), wait_condvar: Condvar::new(), } } } //reflection impl ObjectManager { fn get_from_klass(&self, klass: Arc) -> ReferenceKind { self.get(klass.mirror()) } pub fn new_constructor( &mut self, index: jint, modifiers: jint, parameters: Box<[Arc]>, exceptions: Box<[Arc]>, class_array_class: Arc, declaring_class: Arc, constructor_class: Arc, ) -> ObjectReference { let parameters = parameters .iter() .map(|c| { let mirror_id = c.mirror.get().unwrap(); Some(self.get(*mirror_id)) }) .collect::>(); let exceptions = exceptions .iter() .map(|c| { let mirror_id = c.mirror.get().unwrap(); Some(self.get(*mirror_id)) }) .collect::>(); let constructor_object = self.new_object(constructor_class); let parameter_types = self.new_object_array_from(class_array_class.clone(), parameters); let exception_types = self.new_object_array_from(class_array_class, exceptions); let signature = Value::NULL; let annotations = Value::NULL; let parameter_annotations = Value::NULL; { let obj = constructor_object.lock(); obj.set_field("clazz", Value::from(self.get_from_klass(declaring_class))); obj.set_field("slot", Value::from(index)); obj.set_field("parameterTypes", Value::from(parameter_types)); obj.set_field("exceptionTypes", Value::from(exception_types)); obj.set_field("modifiers", Value::from(modifiers)); obj.set_field("override", Value::from(false)); obj.set_field("signature", signature); obj.set_field("annotations", annotations); obj.set_field("parameterAnnotations", parameter_annotations); } constructor_object } pub fn new_thread_group( &mut self, thread_group_class: Arc, 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, 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, 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 } pub fn new_method_type( &mut self, method_type_class: Arc, class_array_class: Arc, rtype: ReferenceKind, // Class mirror for return type ptypes: Vec, // Class mirrors for param types ) -> ObjectReference { let ptypes_array = self.new_object_array_from(class_array_class, ptypes.into_iter().map(Some).collect()); let mt = self.new_object(method_type_class); { let obj = mt.lock(); obj.set_field("rtype", Value::from(Some(rtype))); obj.set_field("ptypes", Value::from(ptypes_array)); } mt } pub fn new_member_name( &mut self, member_name_class: Arc, clazz: ReferenceKind, // declaring class mirror name: ObjectReference, // method/field name as String method_type: ObjectReference, flags: jint, // REF_invokeStatic, etc encoded ) -> ObjectReference { let mn = self.new_object(member_name_class); { let obj = mn.lock(); obj.set_field("clazz", Value::from(Some(clazz))); obj.set_field("name", Value::from(name)); obj.set_field("type", Value::from(method_type)); obj.set_field("flags", Value::from(flags)); } mn } pub fn new_direct_method_handle( &mut self, dmh_class: Arc, member: ObjectReference, method_type: ObjectReference, ) -> ObjectReference { let mh = self.new_object(dmh_class); { let obj = mh.lock(); obj.set_field("type", Value::from(method_type)); obj.set_field("member", Value::from(member)); } mh } }