33use alloc:: { borrow:: ToOwned , boxed:: Box , collections:: BTreeMap , format, string:: String , sync:: Arc , vec:: Vec } ;
44use core:: {
55 fmt:: Debug ,
6+ hash:: BuildHasher ,
67 iter,
78 mem:: { forget, size_of_val} ,
89 sync:: atomic:: { AtomicBool , Ordering } ,
910} ;
1011
1112use bytemuck:: cast_slice;
1213use dyn_clone:: clone_box;
13- use hashbrown:: HashSet ;
14+ use event_listener:: { Event , EventListener } ;
15+ use hashbrown:: { DefaultHashBuilder , HashSet } ;
1416use parking_lot:: RwLock ;
1517
1618use 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