diff --git a/Cargo.lock b/Cargo.lock index b9ba753b..eb003914 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1530,6 +1530,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + [[package]] name = "parking_lot_core" version = "0.9.11" @@ -2042,6 +2052,7 @@ dependencies = [ "flate2", "indexmap", "indoc", + "parking_lot", "reqwest", "ristretto_classfile", "ristretto_gc", @@ -2119,6 +2130,7 @@ dependencies = [ "getrandom 0.3.3", "indexmap", "os_info", + "parking_lot", "phf", "phf_codegen", "rayon", diff --git a/Cargo.toml b/Cargo.toml index d474954d..f161c557 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ getrandom = "0.3.3" indoc = "2.0.6" indexmap = "2.10.0" os_info = "3.12.0" +parking_lot = "0.12.4" phf = "0.12.1" phf_codegen = "0.12.1" proc-macro2 = "1.0.95" diff --git a/ristretto_classloader/Cargo.toml b/ristretto_classloader/Cargo.toml index 95d4b03f..faf2e715 100644 --- a/ristretto_classloader/Cargo.toml +++ b/ristretto_classloader/Cargo.toml @@ -13,6 +13,7 @@ version.workspace = true [dependencies] flate2 = { workspace = true } indexmap = { workspace = true } +parking_lot = { workspace = true } reqwest = { workspace = true, features = ["json"] } ristretto_classfile = { path = "../ristretto_classfile", version = "0.25.0" } ristretto_gc = { path = "../ristretto_gc", version = "0.25.0" } diff --git a/ristretto_classloader/src/object.rs b/ristretto_classloader/src/object.rs index a2e58487..786fa970 100644 --- a/ristretto_classloader/src/object.rs +++ b/ristretto_classloader/src/object.rs @@ -1,4 +1,4 @@ -use crate::Error::{FieldNotFound, InvalidValueType, ParseError, PoisonedLock}; +use crate::Error::{FieldNotFound, InvalidValueType, ParseError}; use crate::Reference::{ByteArray, CharArray}; use crate::field::FieldKey; use crate::{Class, Field, Reference, Result, Value}; @@ -283,14 +283,8 @@ impl Object { Value::Object(Some(Reference::Object(self_object))), Value::Object(Some(Reference::Object(other_object))), ) => { - let self_object = self_object - .read() - .map_err(|error| PoisonedLock(error.to_string())) - .expect("poisoned lock"); - let other_object = other_object - .read() - .map_err(|error| PoisonedLock(error.to_string())) - .expect("poisoned lock"); + let self_object = self_object.read(); + let other_object = other_object.read(); if !self_object.equal_with_visited(&other_object, visited) { return false; } @@ -522,17 +516,13 @@ impl Object { let coder = self.value("coder")?.as_i32()?; if coder == 0 { // Latin-1 encoded string - let bytes = bytes - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let bytes = bytes.read(); #[expect(clippy::cast_sign_loss)] let value = bytes.iter().map(|&byte| char::from(byte as u8)).collect(); Ok(value) } else { // UTF-16 encoded string - let bytes = bytes - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let bytes = bytes.read(); #[expect(clippy::cast_sign_loss)] let code_units = bytes .chunks(2) @@ -544,9 +534,7 @@ impl Object { } } CharArray(bytes) => { - let bytes = bytes - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let bytes = bytes.read(); let value = String::from_utf16(&bytes).map_err(|error| ParseError(error.to_string()))?; Ok(value) diff --git a/ristretto_classloader/src/reference.rs b/ristretto_classloader/src/reference.rs index c188dcf9..2a8a8b4f 100644 --- a/ristretto_classloader/src/reference.rs +++ b/ristretto_classloader/src/reference.rs @@ -1,10 +1,11 @@ -use crate::Error::{InvalidValueType, PoisonedLock}; +use crate::Error::InvalidValueType; use crate::{Class, Object, Result, Value}; +use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; use ristretto_gc::{GarbageCollector, Gc, Trace}; use std::fmt; use std::fmt::{Debug, Display}; use std::hash::{Hash, Hasher}; -use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}; +use std::sync::Arc; use zerocopy::transmute_ref; /// Represents an array of objects in the Ristretto VM. @@ -57,9 +58,7 @@ impl Reference { Reference::DoubleArray(_) => "[D".to_string(), Reference::Array(object_array) => object_array.class.name().to_string(), Reference::Object(object) => { - let object = object - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let object = object.read(); object.class().name().to_string() } }; @@ -73,9 +72,7 @@ impl Reference { /// if the value is not a `ByteArray`. pub fn as_byte_vec_ref(&self) -> Result>> { match self { - Reference::ByteArray(array) => array - .read() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::ByteArray(array) => Ok(array.read()), _ => Err(InvalidValueType("Expected byte array".to_string())), } } @@ -87,9 +84,7 @@ impl Reference { /// if the value is not a `ByteArray`. pub fn as_byte_vec_mut(&self) -> Result>> { match self { - Reference::ByteArray(array) => array - .write() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::ByteArray(array) => Ok(array.write()), _ => Err(InvalidValueType("Expected byte array".to_string())), } } @@ -101,9 +96,7 @@ impl Reference { /// if the value is not a `CharArray`. pub fn as_char_vec_ref(&self) -> Result>> { match self { - Reference::CharArray(array) => array - .read() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::CharArray(array) => Ok(array.read()), _ => Err(InvalidValueType("Expected char array".to_string())), } } @@ -115,9 +108,7 @@ impl Reference { /// if the value is not a `CharArray`. pub fn as_char_vec_mut(&self) -> Result>> { match self { - Reference::CharArray(array) => array - .write() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::CharArray(array) => Ok(array.write()), _ => Err(InvalidValueType("Expected char array".to_string())), } } @@ -129,9 +120,7 @@ impl Reference { /// if the value is not a `ShortArray`. pub fn as_short_vec_ref(&self) -> Result>> { match self { - Reference::ShortArray(array) => array - .read() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::ShortArray(array) => Ok(array.read()), _ => Err(InvalidValueType("Expected short array".to_string())), } } @@ -143,9 +132,7 @@ impl Reference { /// if the value is not a `ShortArray`. pub fn as_short_vec_mut(&self) -> Result>> { match self { - Reference::ShortArray(array) => array - .write() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::ShortArray(array) => Ok(array.write()), _ => Err(InvalidValueType("Expected short array".to_string())), } } @@ -157,9 +144,7 @@ impl Reference { /// if the value is not a `IntArray`. pub fn as_int_vec_ref(&self) -> Result>> { match self { - Reference::IntArray(array) => array - .read() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::IntArray(array) => Ok(array.read()), _ => Err(InvalidValueType("Expected int array".to_string())), } } @@ -171,9 +156,7 @@ impl Reference { /// if the value is not a `IntArray`. pub fn as_int_vec_mut(&self) -> Result>> { match self { - Reference::IntArray(array) => array - .write() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::IntArray(array) => Ok(array.write()), _ => Err(InvalidValueType("Expected int array".to_string())), } } @@ -185,9 +168,7 @@ impl Reference { /// if the value is not a `LongArray`. pub fn as_long_vec_ref(&self) -> Result>> { match self { - Reference::LongArray(array) => array - .read() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::LongArray(array) => Ok(array.read()), _ => Err(InvalidValueType("Expected long array".to_string())), } } @@ -199,9 +180,7 @@ impl Reference { /// if the value is not a `LongArray`. pub fn as_long_vec_mut(&self) -> Result>> { match self { - Reference::LongArray(array) => array - .write() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::LongArray(array) => Ok(array.write()), _ => Err(InvalidValueType("Expected long array".to_string())), } } @@ -213,9 +192,7 @@ impl Reference { /// if the value is not a `FloatArray`. pub fn as_float_vec_ref(&self) -> Result>> { match self { - Reference::FloatArray(array) => array - .read() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::FloatArray(array) => Ok(array.read()), _ => Err(InvalidValueType("Expected float array".to_string())), } } @@ -227,9 +204,7 @@ impl Reference { /// if the value is not a `FloatArray`. pub fn as_float_vec_mut(&self) -> Result>> { match self { - Reference::FloatArray(array) => array - .write() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::FloatArray(array) => Ok(array.write()), _ => Err(InvalidValueType("Expected float array".to_string())), } } @@ -241,9 +216,7 @@ impl Reference { /// if the value is not a `DoubleArray`. pub fn as_double_vec_ref(&self) -> Result>> { match self { - Reference::DoubleArray(array) => array - .read() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::DoubleArray(array) => Ok(array.read()), _ => Err(InvalidValueType("Expected double array".to_string())), } } @@ -255,9 +228,7 @@ impl Reference { /// if the value is not a `DoubleArray`. pub fn as_double_vec_mut(&self) -> Result>> { match self { - Reference::DoubleArray(array) => array - .write() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::DoubleArray(array) => Ok(array.write()), _ => Err(InvalidValueType("Expected double array".to_string())), } } @@ -273,10 +244,7 @@ impl Reference { ) -> Result<(&Arc, RwLockReadGuard<'_, Vec>>)> { match self { Reference::Array(object_array) => { - let array = object_array - .elements - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = object_array.elements.read(); Ok((&object_array.class, array)) } _ => Err(InvalidValueType("Expected array".to_string())), @@ -294,10 +262,7 @@ impl Reference { ) -> Result<(&Arc, RwLockWriteGuard<'_, Vec>>)> { match self { Reference::Array(object_array) => { - let array = object_array - .elements - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = object_array.elements.write(); Ok((&object_array.class, array)) } _ => Err(InvalidValueType("Expected array".to_string())), @@ -311,9 +276,7 @@ impl Reference { /// if the value is not an Object. pub fn as_object_ref(&self) -> Result> { match self { - Reference::Object(object) => object - .read() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::Object(object) => Ok(object.read()), _ => Err(InvalidValueType("Expected object".to_string())), } } @@ -325,9 +288,7 @@ impl Reference { /// if the value is not an `Object`. pub fn as_object_mut(&self) -> Result> { match self { - Reference::Object(object) => object - .write() - .map_err(|error| PoisonedLock(error.to_string())), + Reference::Object(object) => Ok(object.write()), _ => Err(InvalidValueType("Expected object".to_string())), } } @@ -378,52 +339,35 @@ impl Reference { pub fn deep_clone(&self) -> Result { let value = match self { Reference::ByteArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); Reference::ByteArray(Gc::new(RwLock::new(array.clone()))) } Reference::CharArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); Reference::CharArray(Gc::new(RwLock::new(array.to_vec()))) } Reference::ShortArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); Reference::ShortArray(Gc::new(RwLock::new(array.to_vec()))) } Reference::IntArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); Reference::IntArray(Gc::new(RwLock::new(array.to_vec()))) } Reference::LongArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); Reference::LongArray(Gc::new(RwLock::new(array.to_vec()))) } Reference::FloatArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); Reference::FloatArray(Gc::new(RwLock::new(array.to_vec()))) } Reference::DoubleArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); Reference::DoubleArray(Gc::new(RwLock::new(array.to_vec()))) } Reference::Array(object_array) => { - let array = object_array - .elements - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = object_array.elements.read(); let array = array.to_vec(); let mut cloned_values = Vec::with_capacity(array.len()); for value in array { @@ -439,9 +383,7 @@ impl Reference { Reference::Array(object_array) } Reference::Object(object) => { - let object = object - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let object = object.read(); if object.class().name() == "java/lang/Class" { // Special case for Class objects, which should not be deep cloned. self.clone() @@ -639,7 +581,7 @@ impl Display for Reference { name: &str, value: &Gc>>, ) -> fmt::Result { - let guard = value.read().map_err(|_| fmt::Error)?; + let guard = value.read(); let slice = guard.as_slice(); let mut values = Vec::with_capacity(slice.len()); for value in slice { @@ -662,7 +604,7 @@ impl Display for Reference { Reference::FloatArray(array) => fmt_vec(f, "float", array), Reference::DoubleArray(array) => fmt_vec(f, "double", array), Reference::Array(object_array) => { - let guard = object_array.elements.read().map_err(|_| fmt::Error)?; + let guard = object_array.elements.read(); write!( f, "{}[{}]", @@ -670,14 +612,10 @@ impl Display for Reference { guard.len() ) } - Reference::Object(object) => match object.read() { - Ok(object) => { - write!(f, "{object}") - } - Err(error) => { - write!(f, "{error:?}") - } - }, + Reference::Object(object) => { + let guard = object.read(); + write!(f, "{guard}") + } } } } @@ -699,44 +637,44 @@ impl Hash for Reference { fn hash(&self, state: &mut H) { match self { Reference::ByteArray(array) => { - let array = array.read().expect("poisoned lock"); + let array = array.read(); array.hash(state); } Reference::CharArray(array) => { - let array = array.read().expect("poisoned lock"); + let array = array.read(); array.hash(state); } Reference::ShortArray(array) => { - let array = array.read().expect("poisoned lock"); + let array = array.read(); array.hash(state); } Reference::IntArray(array) => { - let array = array.read().expect("poisoned lock"); + let array = array.read(); array.hash(state); } Reference::LongArray(array) => { - let array = array.read().expect("poisoned lock"); + let array = array.read(); array.hash(state); } Reference::FloatArray(array) => { - let array = array.read().expect("poisoned lock"); + let array = array.read(); for value in array.iter() { value.to_bits().hash(state); } } Reference::DoubleArray(array) => { - let array = array.read().expect("poisoned lock"); + let array = array.read(); for value in array.iter() { value.to_bits().hash(state); } } Reference::Array(object_array) => { object_array.class.name().hash(state); - let array = object_array.elements.read().expect("poisoned lock"); + let array = object_array.elements.read(); array.hash(state); } Reference::Object(object) => { - let object = object.read().expect("poisoned lock"); + let object = object.read(); object.hash(state); } } @@ -749,14 +687,9 @@ impl PartialEq for Reference { if Gc::ptr_eq(a, b) { return true; } - // Use try_read to avoid blocking if locks are contended - if let (Ok(a_guard), Ok(b_guard)) = (a.try_read(), b.try_read()) { - *a_guard == *b_guard - } else { - let a_guard = a.read().expect("poisoned lock"); - let b_guard = b.read().expect("poisoned lock"); - *a_guard == *b_guard - } + let a_guard = a.read(); + let b_guard = b.read(); + *a_guard == *b_guard } match (self, other) { @@ -769,14 +702,8 @@ impl PartialEq for Reference { if Gc::ptr_eq(a, b) { return true; } - // Use try_read to avoid blocking if locks are contended - let (a, b) = if let (Ok(a_guard), Ok(b_guard)) = (a.try_read(), b.try_read()) { - (a_guard, b_guard) - } else { - let a_guard = a.read().expect("poisoned lock"); - let b_guard = b.read().expect("poisoned lock"); - (a_guard, b_guard) - }; + let a = a.read(); + let b = b.read(); if a.len() != b.len() { return false; @@ -789,14 +716,9 @@ impl PartialEq for Reference { if Gc::ptr_eq(a, b) { return true; } - // Use try_read to avoid blocking if locks are contended - let (a, b) = if let (Ok(a_guard), Ok(b_guard)) = (a.try_read(), b.try_read()) { - (a_guard, b_guard) - } else { - let a_guard = a.read().expect("poisoned lock"); - let b_guard = b.read().expect("poisoned lock"); - (a_guard, b_guard) - }; + + let a = a.read(); + let b = b.read(); if a.len() != b.len() { return false; @@ -812,9 +734,8 @@ impl PartialEq for Reference { if Gc::ptr_eq(a, b) { return true; } - // Use try_read to avoid blocking if locks are contended - let a_guard = a.try_read().expect("poisoned lock"); - let b_guard = b.try_read().expect("poisoned lock"); + let a_guard = a.read(); + let b_guard = b.read(); *a_guard == *b_guard } _ => false, @@ -826,12 +747,12 @@ impl Trace for Reference { fn trace(&self, collector: &GarbageCollector) { match self { Reference::Array(object_array) => { - let references = object_array.elements.read().expect("object_array.elements"); + let references = object_array.elements.read(); for reference in references.iter().flatten() { reference.trace(collector); } } - Reference::Object(object) => object.trace(collector), + Reference::Object(object) => object.read().trace(collector), _ => {} } } diff --git a/ristretto_classloader/src/value.rs b/ristretto_classloader/src/value.rs index 1e30ba03..5ffb459f 100644 --- a/ristretto_classloader/src/value.rs +++ b/ristretto_classloader/src/value.rs @@ -1,10 +1,11 @@ use crate::Error::InvalidValueType; use crate::reference::Reference; use crate::{Class, Object, Result}; +use parking_lot::{RwLockReadGuard, RwLockWriteGuard}; use std::fmt; use std::fmt::Display; use std::hash::{Hash, Hasher}; -use std::sync::{Arc, RwLockReadGuard, RwLockWriteGuard}; +use std::sync::Arc; /// Represents a value in the Ristretto VM. #[derive(Clone, Debug)] diff --git a/ristretto_vm/Cargo.toml b/ristretto_vm/Cargo.toml index 6a340215..e4440914 100644 --- a/ristretto_vm/Cargo.toml +++ b/ristretto_vm/Cargo.toml @@ -33,6 +33,7 @@ dirs = { workspace = true } filetime = { workspace = true } indexmap = { workspace = true } os_info = { workspace = true } +parking_lot = { workspace = true } phf = { workspace = true } rayon = { workspace = true } ristretto_classfile = { path = "../ristretto_classfile", version = "0.25.0" } diff --git a/ristretto_vm/src/instruction/array.rs b/ristretto_vm/src/instruction/array.rs index 7639354f..4e5e782d 100644 --- a/ristretto_vm/src/instruction/array.rs +++ b/ristretto_vm/src/instruction/array.rs @@ -1,4 +1,4 @@ -use crate::Error::{InvalidStackValue, PoisonedLock}; +use crate::Error::InvalidStackValue; use crate::JavaError::NullPointerException; use crate::Result; use crate::frame::ExecutionResult::Continue; @@ -55,52 +55,35 @@ pub(crate) fn arraylength(stack: &mut OperandStack) -> Result { let length = match stack.pop_object()? { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ByteArray(array)) => { - let guard = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let guard = array.read(); guard.len() } Some(Reference::CharArray(array)) => { - let guard = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let guard = array.read(); guard.len() } Some(Reference::FloatArray(array)) => { - let guard = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let guard = array.read(); guard.len() } Some(Reference::DoubleArray(array)) => { - let guard = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let guard = array.read(); guard.len() } Some(Reference::ShortArray(array)) => { - let guard = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let guard = array.read(); guard.len() } Some(Reference::IntArray(array)) => { - let guard = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let guard = array.read(); guard.len() } Some(Reference::LongArray(array)) => { - let guard = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let guard = array.read(); guard.len() } Some(Reference::Array(object_array)) => { - let guard = object_array - .elements - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let guard = object_array.elements.read(); guard.len() } Some(object) => { diff --git a/ristretto_vm/src/instruction/byte.rs b/ristretto_vm/src/instruction/byte.rs index db863194..a0584d1c 100644 --- a/ristretto_vm/src/instruction/byte.rs +++ b/ristretto_vm/src/instruction/byte.rs @@ -1,4 +1,4 @@ -use crate::Error::{InvalidStackValue, PoisonedLock}; +use crate::Error::InvalidStackValue; use crate::JavaError::{ArrayIndexOutOfBoundsException, NullPointerException}; use crate::Result; use crate::frame::ExecutionResult; @@ -13,9 +13,7 @@ pub(crate) fn baload(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ByteArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let original_index = index; let length = array.len(); let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { @@ -47,9 +45,7 @@ pub(crate) fn bastore(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ByteArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); let length = array.capacity(); let original_index = index; let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { diff --git a/ristretto_vm/src/instruction/char.rs b/ristretto_vm/src/instruction/char.rs index cd957e23..fc72fa19 100644 --- a/ristretto_vm/src/instruction/char.rs +++ b/ristretto_vm/src/instruction/char.rs @@ -1,4 +1,4 @@ -use crate::Error::{InvalidStackValue, PoisonedLock}; +use crate::Error::InvalidStackValue; use crate::JavaError::{ArrayIndexOutOfBoundsException, NullPointerException}; use crate::Result; use crate::frame::ExecutionResult; @@ -13,9 +13,7 @@ pub(crate) fn caload(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::CharArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let original_index = index; let length = array.len(); let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { @@ -47,9 +45,7 @@ pub(crate) fn castore(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::CharArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); let length = array.capacity(); let original_index = index; let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { diff --git a/ristretto_vm/src/instruction/double.rs b/ristretto_vm/src/instruction/double.rs index b791372b..84e458bb 100644 --- a/ristretto_vm/src/instruction/double.rs +++ b/ristretto_vm/src/instruction/double.rs @@ -1,4 +1,4 @@ -use crate::Error::{InvalidStackValue, PoisonedLock}; +use crate::Error::InvalidStackValue; use crate::JavaError::{ArrayIndexOutOfBoundsException, NullPointerException}; use crate::frame::ExecutionResult::Return; use crate::frame::{ExecutionResult, ExecutionResult::Continue}; @@ -166,9 +166,7 @@ pub(crate) fn daload(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::DoubleArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let original_index = index; let length = array.len(); let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { @@ -200,9 +198,7 @@ pub(crate) fn dastore(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::DoubleArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); let length = array.capacity(); let original_index = index; let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { diff --git a/ristretto_vm/src/instruction/float.rs b/ristretto_vm/src/instruction/float.rs index abfdd4cd..c5d40018 100644 --- a/ristretto_vm/src/instruction/float.rs +++ b/ristretto_vm/src/instruction/float.rs @@ -1,4 +1,4 @@ -use crate::Error::{InvalidStackValue, PoisonedLock}; +use crate::Error::InvalidStackValue; use crate::JavaError::{ArrayIndexOutOfBoundsException, NullPointerException}; use crate::frame::ExecutionResult::Return; use crate::frame::{ExecutionResult, ExecutionResult::Continue}; @@ -173,9 +173,7 @@ pub(crate) fn faload(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::FloatArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let original_index = index; let length = array.len(); let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { @@ -207,9 +205,7 @@ pub(crate) fn fastore(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::FloatArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); let length = array.capacity(); let original_index = index; let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { diff --git a/ristretto_vm/src/instruction/integer.rs b/ristretto_vm/src/instruction/integer.rs index 80d29b6e..a3b1ec6a 100644 --- a/ristretto_vm/src/instruction/integer.rs +++ b/ristretto_vm/src/instruction/integer.rs @@ -1,4 +1,4 @@ -use crate::Error::{InvalidStackValue, PoisonedLock}; +use crate::Error::InvalidStackValue; use crate::JavaError::{ArrayIndexOutOfBoundsException, NullPointerException}; use crate::frame::ExecutionResult::Return; use crate::frame::{ExecutionResult, ExecutionResult::Continue}; @@ -202,9 +202,7 @@ pub(crate) fn iaload(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::IntArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let original_index = index; let length = array.len(); let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { @@ -236,9 +234,7 @@ pub(crate) fn iastore(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::IntArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); let length = array.capacity(); let original_index = index; let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { diff --git a/ristretto_vm/src/instruction/long.rs b/ristretto_vm/src/instruction/long.rs index 4ae3e77d..df974f86 100644 --- a/ristretto_vm/src/instruction/long.rs +++ b/ristretto_vm/src/instruction/long.rs @@ -1,4 +1,4 @@ -use crate::Error::{InvalidStackValue, PoisonedLock}; +use crate::Error::InvalidStackValue; use crate::JavaError::{ArrayIndexOutOfBoundsException, NullPointerException}; use crate::frame::ExecutionResult::Return; use crate::frame::{ExecutionResult, ExecutionResult::Continue}; @@ -168,9 +168,7 @@ pub(crate) fn laload(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::LongArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let original_index = index; let length = array.len(); let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { @@ -202,9 +200,7 @@ pub(crate) fn lastore(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::LongArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); let length = array.capacity(); let original_index = index; let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { diff --git a/ristretto_vm/src/instruction/object.rs b/ristretto_vm/src/instruction/object.rs index f05239ba..18490c4d 100644 --- a/ristretto_vm/src/instruction/object.rs +++ b/ristretto_vm/src/instruction/object.rs @@ -1,4 +1,4 @@ -use crate::Error::{InternalError, InvalidStackValue, PoisonedLock}; +use crate::Error::{InternalError, InvalidStackValue}; use crate::JavaError::{ArrayIndexOutOfBoundsException, ClassCastException, NullPointerException}; use crate::assignable::Assignable; use crate::frame::ExecutionResult::Return; @@ -162,10 +162,7 @@ pub(crate) fn aaload(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::Array(object_array)) => { - let array = object_array - .elements - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = object_array.elements.read(); let original_index = index; let length = array.len(); let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { @@ -197,10 +194,7 @@ pub(crate) fn aastore(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::Array(object_array)) => { - let mut array = object_array - .elements - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = object_array.elements.write(); let length = array.capacity(); let original_index = index; let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { @@ -327,9 +321,7 @@ async fn is_instance_of(thread: &Thread, object: &Reference, class: &Arc) .await?), Reference::Object(object) => { let object_class = { - let object = object - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let object = object.read(); object.class().clone() }; Ok(class.is_assignable_from(thread, &object_class).await?) diff --git a/ristretto_vm/src/instruction/short.rs b/ristretto_vm/src/instruction/short.rs index 900cf872..5236de51 100644 --- a/ristretto_vm/src/instruction/short.rs +++ b/ristretto_vm/src/instruction/short.rs @@ -1,4 +1,4 @@ -use crate::Error::{InvalidStackValue, PoisonedLock}; +use crate::Error::InvalidStackValue; use crate::JavaError::{ArrayIndexOutOfBoundsException, NullPointerException}; use crate::Result; use crate::frame::ExecutionResult; @@ -13,9 +13,7 @@ pub(crate) fn saload(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ShortArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let original_index = index; let length = array.len(); let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { @@ -47,9 +45,7 @@ pub(crate) fn sastore(stack: &mut OperandStack) -> Result { match stack.pop_object()? { None => Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ShortArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); let length = array.capacity(); let original_index = index; let index = usize::try_from(index).map_err(|_| ArrayIndexOutOfBoundsException { diff --git a/ristretto_vm/src/intrinsic_methods/java/io/fileinputstream.rs b/ristretto_vm/src/intrinsic_methods/java/io/fileinputstream.rs index 83efdf88..b677f3a6 100644 --- a/ristretto_vm/src/intrinsic_methods/java/io/fileinputstream.rs +++ b/ristretto_vm/src/intrinsic_methods/java/io/fileinputstream.rs @@ -1,4 +1,3 @@ -use crate::Error::PoisonedLock; #[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] use crate::JavaError::{AccessControlException, IllegalArgumentException}; use crate::JavaError::{FileNotFoundException, IoException}; @@ -343,9 +342,7 @@ pub(crate) async fn read_bytes( let bytes_read = if bytes_read == 0 && length > 0 { -1 } else { - let mut bytes = bytes - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut bytes = bytes.write(); let buffer: &[i8] = transmute_ref!(buffer.as_slice()); if bytes_read > 0 { bytes[offset..offset + bytes_read].copy_from_slice(&buffer[..bytes_read]); diff --git a/ristretto_vm/src/intrinsic_methods/java/io/randomaccessfile.rs b/ristretto_vm/src/intrinsic_methods/java/io/randomaccessfile.rs index 55364d94..977639e9 100644 --- a/ristretto_vm/src/intrinsic_methods/java/io/randomaccessfile.rs +++ b/ristretto_vm/src/intrinsic_methods/java/io/randomaccessfile.rs @@ -1,4 +1,3 @@ -use crate::Error::PoisonedLock; #[cfg(not(all(target_family = "wasm", not(target_os = "wasi"))))] use crate::JavaError::{AccessControlException, IllegalArgumentException}; use crate::JavaError::{FileNotFoundException, IoException}; @@ -357,9 +356,7 @@ pub(crate) async fn read_bytes_0( let bytes_read = if bytes_read == 0 && length > 0 { -1 } else { - let mut bytes = bytes - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut bytes = bytes.write(); let buffer: &[i8] = transmute_ref!(buffer.as_slice()); if bytes_read > 0 { bytes[offset..offset + bytes_read].copy_from_slice(&buffer[..bytes_read]); diff --git a/ristretto_vm/src/intrinsic_methods/java/lang/processhandleimpl.rs b/ristretto_vm/src/intrinsic_methods/java/lang/processhandleimpl.rs index 63ed92d7..ce0b6346 100644 --- a/ristretto_vm/src/intrinsic_methods/java/lang/processhandleimpl.rs +++ b/ristretto_vm/src/intrinsic_methods/java/lang/processhandleimpl.rs @@ -1,4 +1,3 @@ -use crate::Error::PoisonedLock; use crate::Result; use crate::parameters::Parameters; use crate::thread::Thread; @@ -71,15 +70,9 @@ pub(crate) async fn get_process_pids_0( let Some(Reference::LongArray(pids)) = parameters.pop_reference()? else { return Ok(Some(Value::Int(-1))); }; - let mut start_times = start_times - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; - let mut ppids = ppids - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; - let mut pids = pids - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut start_times = start_times.write(); + let mut ppids = ppids.write(); + let mut pids = pids.write(); let pid = parameters.pop_long()?; let mut system = System::new_all(); diff --git a/ristretto_vm/src/intrinsic_methods/java/lang/reflect/array.rs b/ristretto_vm/src/intrinsic_methods/java/lang/reflect/array.rs index 49a51918..e4fdd1ad 100644 --- a/ristretto_vm/src/intrinsic_methods/java/lang/reflect/array.rs +++ b/ristretto_vm/src/intrinsic_methods/java/lang/reflect/array.rs @@ -1,4 +1,4 @@ -use crate::Error::{InvalidOperand, InvalidStackValue, PoisonedLock}; +use crate::Error::{InvalidOperand, InvalidStackValue}; use crate::JavaError::{IndexOutOfBoundsException, NullPointerException}; use crate::Result; use crate::intrinsic_methods::java::lang::class::get_class; @@ -27,9 +27,7 @@ pub(crate) async fn get(_thread: Arc, mut parameters: Parameters) -> Res let value = match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ByteArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -37,9 +35,7 @@ pub(crate) async fn get(_thread: Arc, mut parameters: Parameters) -> Res Value::from(*value) } Some(Reference::CharArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -47,9 +43,7 @@ pub(crate) async fn get(_thread: Arc, mut parameters: Parameters) -> Res Value::from(*value) } Some(Reference::FloatArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -57,9 +51,7 @@ pub(crate) async fn get(_thread: Arc, mut parameters: Parameters) -> Res Value::from(*value) } Some(Reference::DoubleArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -67,9 +59,7 @@ pub(crate) async fn get(_thread: Arc, mut parameters: Parameters) -> Res Value::from(*value) } Some(Reference::ShortArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -77,9 +67,7 @@ pub(crate) async fn get(_thread: Arc, mut parameters: Parameters) -> Res Value::from(*value) } Some(Reference::IntArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -87,9 +75,7 @@ pub(crate) async fn get(_thread: Arc, mut parameters: Parameters) -> Res Value::from(*value) } Some(Reference::LongArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -97,10 +83,7 @@ pub(crate) async fn get(_thread: Arc, mut parameters: Parameters) -> Res Value::from(*value) } Some(Reference::Array(object_array)) => { - let array = object_array - .elements - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = object_array.elements.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -137,9 +120,7 @@ pub(crate) async fn get_byte( let value = match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ByteArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -167,9 +148,7 @@ pub(crate) async fn get_char( let value = match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::CharArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -197,9 +176,7 @@ pub(crate) async fn get_double( let value = match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::DoubleArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -227,9 +204,7 @@ pub(crate) async fn get_float( let value = match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::FloatArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -257,9 +232,7 @@ pub(crate) async fn get_int( let value = match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::IntArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -286,52 +259,35 @@ pub(crate) async fn get_length( let length = match array { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ByteArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); array.len() } Some(Reference::CharArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); array.len() } Some(Reference::FloatArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); array.len() } Some(Reference::DoubleArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); array.len() } Some(Reference::ShortArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); array.len() } Some(Reference::IntArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); array.len() } Some(Reference::LongArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); array.len() } Some(Reference::Array(object_array)) => { - let array = object_array - .elements - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = object_array.elements.read(); array.len() } Some(object) => { @@ -356,9 +312,7 @@ pub(crate) async fn get_long( let value = match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::LongArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -386,9 +340,7 @@ pub(crate) async fn get_short( let value = match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ShortArray(array)) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let Some(value) = array.get(usize::try_from(index)?) else { let size = i32::try_from(array.len())?; return Err(IndexOutOfBoundsException { index, size }.into()); @@ -538,9 +490,7 @@ pub(crate) async fn set(_thread: Arc, mut parameters: Parameters) -> Res None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ByteArray(array)) => { let value = value.as_i8()?; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -550,9 +500,7 @@ pub(crate) async fn set(_thread: Arc, mut parameters: Parameters) -> Res } Some(Reference::CharArray(array)) => { let value = value.as_u16()?; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -562,9 +510,7 @@ pub(crate) async fn set(_thread: Arc, mut parameters: Parameters) -> Res } Some(Reference::FloatArray(array)) => { let value = value.as_f32()?; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -574,9 +520,7 @@ pub(crate) async fn set(_thread: Arc, mut parameters: Parameters) -> Res } Some(Reference::DoubleArray(array)) => { let value = value.as_f64()?; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -586,9 +530,7 @@ pub(crate) async fn set(_thread: Arc, mut parameters: Parameters) -> Res } Some(Reference::ShortArray(array)) => { let value = value.as_i16()?; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -598,9 +540,7 @@ pub(crate) async fn set(_thread: Arc, mut parameters: Parameters) -> Res } Some(Reference::IntArray(array)) => { let value = value.as_i32()?; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -610,9 +550,7 @@ pub(crate) async fn set(_thread: Arc, mut parameters: Parameters) -> Res } Some(Reference::LongArray(array)) => { let value = value.as_i64()?; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -627,10 +565,7 @@ pub(crate) async fn set(_thread: Arc, mut parameters: Parameters) -> Res actual: format!("{value:?}"), }); }; - let mut array = object_array - .elements - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = object_array.elements.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -669,9 +604,7 @@ pub(crate) async fn set_byte( match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ByteArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -701,9 +634,7 @@ pub(crate) async fn set_char( match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::CharArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -733,9 +664,7 @@ pub(crate) async fn set_double( match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::DoubleArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -765,9 +694,7 @@ pub(crate) async fn set_float( match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::FloatArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -797,9 +724,7 @@ pub(crate) async fn set_int( match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::IntArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -829,9 +754,7 @@ pub(crate) async fn set_long( match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::LongArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -861,9 +784,7 @@ pub(crate) async fn set_short( match reference { None => return Err(NullPointerException("array cannot be null".to_string()).into()), Some(Reference::ShortArray(array)) => { - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(usize::try_from(index)?) { *element = value; } else { @@ -1089,9 +1010,7 @@ mod tests { for i in 0..3 { let inner_array = outer_array.get(i).expect("inner array"); if let Some(Reference::IntArray(inner_array)) = inner_array { - let inner_array = inner_array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let inner_array = inner_array.read(); assert_eq!(inner_array.len(), 4); for j in 0..4 { assert_eq!(inner_array.get(j), Some(&0i32)); diff --git a/ristretto_vm/src/intrinsic_methods/java/lang/stacktraceelement.rs b/ristretto_vm/src/intrinsic_methods/java/lang/stacktraceelement.rs index dbb3260b..20d44a60 100644 --- a/ristretto_vm/src/intrinsic_methods/java/lang/stacktraceelement.rs +++ b/ristretto_vm/src/intrinsic_methods/java/lang/stacktraceelement.rs @@ -1,4 +1,4 @@ -use crate::Error::{InternalError, PoisonedLock}; +use crate::Error::InternalError; use crate::JavaError::ArrayIndexOutOfBoundsException; use crate::Result; use crate::parameters::Parameters; @@ -55,20 +55,14 @@ pub(crate) async fn init_stack_trace_elements_1( for index in 0..depth { // Limit the scope of the read lock on the back_trace_array let value = { - let back_trace_array = back_trace_array - .elements - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let back_trace_array = back_trace_array.elements.read(); let Some(value) = back_trace_array.get(index) else { return Err(InternalError("No back trace element found".to_string())); }; value.clone() }; - let mut stack_trace_array = stack_trace_array - .elements - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut stack_trace_array = stack_trace_array.elements.write(); if let Some(element) = stack_trace_array.get_mut(index) { *element = value; } else { diff --git a/ristretto_vm/src/intrinsic_methods/java/lang/system.rs b/ristretto_vm/src/intrinsic_methods/java/lang/system.rs index 81b353c2..66eaebac 100644 --- a/ristretto_vm/src/intrinsic_methods/java/lang/system.rs +++ b/ristretto_vm/src/intrinsic_methods/java/lang/system.rs @@ -1,4 +1,4 @@ -use crate::Error::{InternalError, PoisonedLock}; +use crate::Error::InternalError; use crate::JavaError::IllegalArgumentException; use crate::Result; use crate::intrinsic_methods::java::lang::object::hash_code; @@ -7,6 +7,7 @@ use crate::java_object::JavaObject; use crate::parameters::Parameters; use crate::thread::Thread; use async_recursion::async_recursion; +use parking_lot::RwLock; use ristretto_classfile::VersionSpecification::{Any, LessThanOrEqual}; use ristretto_classfile::attributes::{Attribute, Instruction}; use ristretto_classfile::{ @@ -17,7 +18,7 @@ use ristretto_gc::Gc; use ristretto_macros::intrinsic_method; use std::env::consts::OS; use std::fmt::Debug; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; use std::time::{SystemTime, UNIX_EPOCH}; fn arraycopy_vec( @@ -34,15 +35,11 @@ fn arraycopy_vec( // Validate bounds before copying; get lengths once to avoid multiple lock acquisitions let source_len = { - let source = source - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let source = source.read(); source.len() }; let destination_len = { - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); destination.len() }; @@ -60,9 +57,7 @@ fn arraycopy_vec( // Check if source and destination are the same array if source.ptr_eq(destination) { // Same array; need to handle overlapping regions - let mut array = destination - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = destination.write(); // Handle overlapping regions correctly let regions_overlap = (source_position < destination_position @@ -93,12 +88,8 @@ fn arraycopy_vec( } } else { // Different arrays; can optimize with bulk operations - let source = source - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; - let mut destination = destination - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let source = source.read(); + let mut destination = destination.write(); // Use slice operations for maximum efficiency let source_slice = &source[source_position..source_position + length]; @@ -499,9 +490,7 @@ mod tests { let destination = Gc::new(RwLock::new(vec![0, 0, 0, 0, 0])); arraycopy_vec(&source, 0, &destination, 0, 3)?; - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); assert_eq!(destination.first(), Some(&1)); assert_eq!(destination.get(1), Some(&2)); @@ -518,9 +507,7 @@ mod tests { // Copy from source[1..3] to destination[2..4] arraycopy_vec(&source, 1, &destination, 2, 2)?; - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); assert_eq!(destination.first(), Some(&0)); // Unchanged assert_eq!(destination.get(1), Some(&0)); // Unchanged @@ -536,9 +523,7 @@ mod tests { let destination = Gc::new(RwLock::new(vec![0, 0, 0])); arraycopy_vec(&source, 0, &destination, 0, 3)?; - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); assert_eq!(destination.first(), Some(&10)); assert_eq!(destination.get(1), Some(&20)); @@ -552,9 +537,7 @@ mod tests { let destination = Gc::new(RwLock::new(vec![0, 0, 0])); arraycopy_vec(&source, 0, &destination, 0, 0)?; - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); // Nothing should be copied assert_eq!(destination.first(), Some(&0)); @@ -569,9 +552,7 @@ mod tests { let destination = Gc::new(RwLock::new(vec![0])); arraycopy_vec(&source, 0, &destination, 0, 1)?; - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); assert_eq!(destination.first(), Some(&42)); Ok(()) @@ -584,9 +565,7 @@ mod tests { // Copy last 2 elements of source to last 2 positions of destination arraycopy_vec(&source, 3, &destination, 3, 2)?; - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); assert_eq!(destination.first(), Some(&0)); // Unchanged assert_eq!(destination.get(1), Some(&0)); // Unchanged @@ -603,9 +582,7 @@ mod tests { // This should work fine since they're different arrays arraycopy_vec(&source, 1, &destination, 0, 3)?; - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); assert_eq!(destination.first(), Some(&2)); // source[1] assert_eq!(destination.get(1), Some(&3)); // source[2] @@ -677,9 +654,7 @@ mod tests { // Copy exactly to the boundary - should work arraycopy_vec(&source, 0, &destination, 0, 3)?; - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); assert_eq!(destination.first(), Some(&1)); assert_eq!(destination.get(1), Some(&2)); @@ -737,9 +712,7 @@ mod tests { ])); arraycopy_vec(&source, 0, &destination, 0, 2)?; - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); assert_eq!(destination.first(), Some(&"hello".to_string())); assert_eq!(destination.get(1), Some(&"world".to_string())); @@ -756,9 +729,7 @@ mod tests { let destination = Gc::new(RwLock::new(dest_data)); arraycopy_vec(&source, 100, &destination, 200, 500)?; - let destination = destination - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let destination = destination.read(); // Verify first few and last few elements assert_eq!(destination.get(200), Some(&100)); @@ -814,9 +785,7 @@ mod tests { // Shift "cdef" to the right by 2 positions to make room for insertion // This simulates what StringBuilder does when inserting text arraycopy_vec(&array, 2, &array, 4, 4)?; - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); assert_eq!(array.first(), Some(&'a')); // Unchanged assert_eq!(array.get(1), Some(&'b')); // Unchanged @@ -838,9 +807,7 @@ mod tests { // Shift "cdefgh" to the left by 1 position arraycopy_vec(&array, 2, &array, 1, 6)?; - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); assert_eq!(array.first(), Some(&'a')); // Unchanged assert_eq!(array.get(1), Some(&'c')); // Shifted from position 2 @@ -860,9 +827,7 @@ mod tests { // Copy first 3 elements to positions 5-7 (no overlap) arraycopy_vec(&array, 0, &array, 5, 3)?; - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); assert_eq!(array.first(), Some(&1)); // Unchanged assert_eq!(array.get(1), Some(&2)); // Unchanged diff --git a/ristretto_vm/src/intrinsic_methods/jdk/internal/misc/unsafe.rs b/ristretto_vm/src/intrinsic_methods/jdk/internal/misc/unsafe.rs index 9bd794a7..7e353d75 100644 --- a/ristretto_vm/src/intrinsic_methods/jdk/internal/misc/unsafe.rs +++ b/ristretto_vm/src/intrinsic_methods/jdk/internal/misc/unsafe.rs @@ -1,4 +1,4 @@ -use crate::Error::{InternalError, InvalidOperand, PoisonedLock}; +use crate::Error::{InternalError, InvalidOperand}; use crate::JavaError::ArrayIndexOutOfBoundsException; use crate::Result; use crate::intrinsic_methods::java::lang::class::get_class; @@ -272,10 +272,7 @@ pub(crate) async fn compare_and_set_reference( let result = match reference { Reference::Array(object_array) => { let offset = offset / REFERENCE_SIZE; - let mut elements = object_array - .elements - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut elements = object_array.elements.write(); let Some(reference) = elements.get(offset) else { return Err(InternalError( "compareAndSetReference: Invalid reference index".to_string(), @@ -302,9 +299,7 @@ pub(crate) async fn compare_and_set_reference( } } Reference::Object(object) => { - let mut object = object - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut object = object.write(); let field_name = object.class().field_name(offset)?; let value = object.value(&field_name)?; if value == expected { @@ -452,9 +447,7 @@ fn get_reference_type( let offset = usize::try_from(offset)?; let value = match &reference { Reference::ByteArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let array: &[u8] = transmute_ref!(array.as_slice()); let Some(base_type) = base_type else { return Err(InternalError( @@ -524,9 +517,7 @@ fn get_reference_type( } } Reference::CharArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let offset = offset / CHAR_SIZE; let Some(char) = array.get(offset) else { return Err(ArrayIndexOutOfBoundsException { @@ -538,9 +529,7 @@ fn get_reference_type( Value::Int(i32::from(*char)) } Reference::ShortArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let offset = offset / SHORT_SIZE; let Some(short) = array.get(offset) else { return Err(ArrayIndexOutOfBoundsException { @@ -552,9 +541,7 @@ fn get_reference_type( Value::Int(i32::from(*short)) } Reference::IntArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let offset = offset / INT_SIZE; let Some(int) = array.get(offset) else { return Err(ArrayIndexOutOfBoundsException { @@ -566,9 +553,7 @@ fn get_reference_type( Value::Int(*int) } Reference::LongArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let offset = offset / LONG_SIZE; let Some(long) = array.get(offset) else { return Err(ArrayIndexOutOfBoundsException { @@ -580,9 +565,7 @@ fn get_reference_type( Value::Long(*long) } Reference::FloatArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let offset = offset / FLOAT_SIZE; let Some(float) = array.get(offset) else { return Err(ArrayIndexOutOfBoundsException { @@ -594,9 +577,7 @@ fn get_reference_type( Value::Float(*float) } Reference::DoubleArray(array) => { - let array = array - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = array.read(); let offset = offset / DOUBLE_SIZE; let Some(double) = array.get(offset) else { return Err(ArrayIndexOutOfBoundsException { @@ -608,10 +589,7 @@ fn get_reference_type( Value::Double(*double) } Reference::Array(object_array) => { - let array = object_array - .elements - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let array = object_array.elements.read(); let offset = offset / REFERENCE_SIZE; let Some(reference) = array.get(offset) else { return Err(ArrayIndexOutOfBoundsException { @@ -623,9 +601,7 @@ fn get_reference_type( Value::Object(reference.clone()) } Reference::Object(object) => { - let object = object - .read() - .map_err(|error| PoisonedLock(error.to_string()))?; + let object = object.read(); let class = object.class(); let field_name = class.field_name(offset)?; let field = class.declared_field(&field_name)?; @@ -687,9 +663,7 @@ fn put_reference_type( )); } }; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(offset) { *element = byte_value; } else { @@ -710,9 +684,7 @@ fn put_reference_type( } }; let offset = offset / CHAR_SIZE; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(offset) { *element = char_value; } else { @@ -733,9 +705,7 @@ fn put_reference_type( } }; let offset = offset / SHORT_SIZE; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(offset) { *element = short_value; } else { @@ -753,9 +723,7 @@ fn put_reference_type( )); }; let offset = offset / INT_SIZE; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(offset) { *element = int_value; } else { @@ -773,9 +741,7 @@ fn put_reference_type( )); }; let offset = offset / LONG_SIZE; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(offset) { *element = long_value; } else { @@ -793,9 +759,7 @@ fn put_reference_type( )); }; let offset = offset / FLOAT_SIZE; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(offset) { *element = float_value; } else { @@ -813,9 +777,7 @@ fn put_reference_type( )); }; let offset = offset / DOUBLE_SIZE; - let mut array = array - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = array.write(); if let Some(element) = array.get_mut(offset) { *element = double_value; } else { @@ -833,10 +795,7 @@ fn put_reference_type( )); }; let offset = offset / REFERENCE_SIZE; - let mut array = object_array - .elements - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut array = object_array.elements.write(); if let Some(element) = array.get_mut(offset) { *element = object_value; } else { @@ -848,9 +807,7 @@ fn put_reference_type( } } Reference::Object(object) => { - let mut object = object - .write() - .map_err(|error| PoisonedLock(error.to_string()))?; + let mut object = object.write(); let class = object.class(); let field_name = class.field_name(offset)?; let field = class.declared_field(&field_name)?; diff --git a/ristretto_vm/src/java_object.rs b/ristretto_vm/src/java_object.rs index 6a0ebc3a..fdcbb925 100644 --- a/ristretto_vm/src/java_object.rs +++ b/ristretto_vm/src/java_object.rs @@ -1,10 +1,11 @@ use crate::Error::InternalError; use crate::Result; use crate::thread::Thread; +use parking_lot::RwLock; use ristretto_classfile::{JAVA_8, JAVA_17}; use ristretto_classloader::{Class, ClassLoader, Object, Reference, Value}; use ristretto_gc::Gc; -use std::sync::{Arc, RwLock}; +use std::sync::Arc; /// Trait for converting a Rust value to a Java object. Converts to objects of the primitive /// wrapper, classes, and strings.