Skip to content

Commit 52b328e

Browse files
committed
Add object monitor to Jvm with object_wait, object_listen and object_notify
1 parent 303f581 commit 52b328e

File tree

4 files changed

+38
-3
lines changed

4 files changed

+38
-3
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

java_runtime/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ tracing = { workspace = true }
1414

1515
chrono = { version = "^0.4", default-features = false }
1616
encoding_rs = { version = "^0.8", features = ["alloc"], default-features = false }
17-
event-listener = { version = "^5.4", default-features = false }
1817
zip = { version = "^6.0", features = ["deflate"], default-features = false }
1918
url = { version = "^2.5", default-features = false }
2019

jvm/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ nom = { workspace = true }
1616
parking_lot = { workspace = true }
1717
tracing = { workspace = true }
1818

19+
event-listener = { version = "^5.4", default-features = false }
20+
1921
java_constants = { workspace = true }
2022

2123
[dev-dependencies]

jvm/src/jvm.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33
use alloc::{borrow::ToOwned, boxed::Box, collections::BTreeMap, format, string::String, sync::Arc, vec::Vec};
44
use core::{
55
fmt::Debug,
6+
hash::BuildHasher,
67
iter,
78
mem::{forget, size_of_val},
89
sync::atomic::{AtomicBool, Ordering},
910
};
1011

1112
use bytemuck::cast_slice;
1213
use dyn_clone::clone_box;
13-
use hashbrown::HashSet;
14+
use event_listener::{Event, EventListener};
15+
use hashbrown::{DefaultHashBuilder, HashSet};
1416
use parking_lot::RwLock;
1517

1618
use java_constants::{ClassAccessFlags, MethodAccessFlags};
@@ -36,6 +38,8 @@ struct JvmInner {
3638
classes: RwLock<BTreeMap<String, Class>>,
3739
threads: RwLock<BTreeMap<u64, JvmThread>>,
3840
all_objects: RwLock<HashSet<Box<dyn ClassInstance>>>,
41+
monitors: RwLock<BTreeMap<u64, Arc<Event>>>,
42+
monitor_hasher: DefaultHashBuilder,
3943
get_current_thread_id: Box<dyn Fn() -> u64 + Sync + Send>,
4044
bootstrap_class_loader: Box<dyn BootstrapClassLoader>,
4145
bootstrapping: AtomicBool,
@@ -57,6 +61,8 @@ impl Jvm {
5761
classes: RwLock::new(BTreeMap::new()),
5862
threads: RwLock::new(BTreeMap::new()),
5963
all_objects: RwLock::new(HashSet::new()),
64+
monitors: RwLock::new(BTreeMap::new()),
65+
monitor_hasher: DefaultHashBuilder::default(),
6066
get_current_thread_id: Box::new(get_current_thread_id),
6167
bootstrap_class_loader: Box::new(bootstrap_class_loader),
6268
bootstrapping: AtomicBool::new(true),
@@ -464,6 +470,21 @@ impl Jvm {
464470
self.inner.classes.read().get(class_name).cloned()
465471
}
466472

473+
pub fn object_listen(&self, obj: &Box<dyn ClassInstance>) -> EventListener {
474+
self.get_or_create_monitor(obj).listen()
475+
}
476+
477+
pub async fn object_wait(&self, obj: &Box<dyn ClassInstance>) -> Result<()> {
478+
self.object_listen(obj).await;
479+
480+
Ok(())
481+
}
482+
483+
pub fn object_notify(&self, obj: &Box<dyn ClassInstance>, count: usize) {
484+
let monitor = self.get_or_create_monitor(obj);
485+
monitor.notify(count);
486+
}
487+
467488
#[async_recursion::async_recursion]
468489
pub async fn resolve_class(&self, class_name: &str) -> Result<Class> {
469490
self.resolve_class_internal(class_name, None).await
@@ -720,6 +741,19 @@ impl Jvm {
720741
}
721742
}
722743

744+
fn get_or_create_monitor(&self, obj: &Box<dyn ClassInstance>) -> Arc<Event> {
745+
let key = self.inner.monitor_hasher.hash_one(obj);
746+
747+
let monitors = self.inner.monitors.read();
748+
if let Some(monitor) = monitors.get(&key) {
749+
return monitor.clone();
750+
}
751+
drop(monitors);
752+
753+
let mut monitors = self.inner.monitors.write();
754+
monitors.entry(key).or_insert_with(|| Arc::new(Event::new())).clone()
755+
}
756+
723757
pub(crate) fn find_field(&self, class: &dyn ClassDefinition, name: &str, descriptor: &str) -> Result<Option<Box<dyn Field>>> {
724758
let field = class.field(name, descriptor, false);
725759

0 commit comments

Comments
 (0)