@@ -10,6 +10,7 @@ use core::{
1010
1111use bytemuck:: cast_slice;
1212use dyn_clone:: clone_box;
13+ use hashbrown:: HashSet ;
1314use parking_lot:: RwLock ;
1415
1516use java_constants:: MethodAccessFlags ;
@@ -33,6 +34,7 @@ use crate::{
3334struct JvmInner {
3435 classes : RwLock < BTreeMap < String , Class > > ,
3536 threads : RwLock < BTreeMap < u64 , JvmThread > > ,
37+ all_objects : RwLock < HashSet < Box < dyn ClassInstance > > > ,
3638 get_current_thread_id : Box < dyn Fn ( ) -> u64 + Sync + Send > ,
3739 bootstrap_class_loader : Box < dyn BootstrapClassLoader > ,
3840 bootstrapping : AtomicBool ,
@@ -53,6 +55,7 @@ impl Jvm {
5355 inner : Arc :: new ( JvmInner {
5456 classes : RwLock :: new ( BTreeMap :: new ( ) ) ,
5557 threads : RwLock :: new ( BTreeMap :: new ( ) ) ,
58+ all_objects : RwLock :: new ( HashSet :: new ( ) ) ,
5659 get_current_thread_id : Box :: new ( get_current_thread_id) ,
5760 bootstrap_class_loader : Box :: new ( bootstrap_class_loader) ,
5861 bootstrapping : AtomicBool :: new ( true ) ,
@@ -108,6 +111,13 @@ impl Jvm {
108111
109112 let instance = class. definition . instantiate ( ) ?;
110113
114+ let thread_id = ( self . inner . get_current_thread_id ) ( ) ;
115+ let mut threads = self . inner . threads . write ( ) ;
116+ let thread = threads. get_mut ( & thread_id) . unwrap ( ) ;
117+
118+ thread. top_frame_mut ( ) . local_variables ( ) . push ( instance. clone ( ) ) ;
119+ self . inner . all_objects . write ( ) . insert ( instance. clone ( ) ) ;
120+
111121 Ok ( instance)
112122 }
113123
@@ -131,6 +141,14 @@ impl Jvm {
131141 let array_class = class. as_array_class_definition ( ) . unwrap ( ) ;
132142
133143 let instance = array_class. instantiate_array ( length) ?;
144+
145+ let thread_id = ( self . inner . get_current_thread_id ) ( ) ;
146+ let mut threads = self . inner . threads . write ( ) ;
147+ let thread = threads. get_mut ( & thread_id) . unwrap ( ) ;
148+
149+ thread. top_frame_mut ( ) . local_variables ( ) . push ( instance. clone ( ) ) ;
150+ self . inner . all_objects . write ( ) . insert ( instance. clone ( ) ) ;
151+
134152 Ok ( instance)
135153 }
136154
@@ -423,10 +441,10 @@ impl Jvm {
423441 }
424442 }
425443
426- // temporary until we have working gc
427444 pub fn destroy ( & self , instance : Box < dyn ClassInstance > ) -> Result < ( ) > {
428445 tracing:: debug!( "Destroy {}" , instance. class_definition( ) . name( ) ) ;
429446
447+ self . inner . all_objects . write ( ) . remove ( & instance) ;
430448 instance. destroy ( ) ;
431449
432450 Ok ( ( ) )
@@ -496,7 +514,7 @@ impl Jvm {
496514 let threads = self . inner . threads . read ( ) ;
497515 let thread = threads. get ( & thread_id) . unwrap ( ) ;
498516
499- Ok ( thread. top_frame ( ) . map ( |x| ( x. class . clone ( ) , x. class_instance . clone ( ) ) ) )
517+ Ok ( thread. top_java_frame ( ) . map ( |x| ( x. class . clone ( ) , x. class_instance . clone ( ) ) ) )
500518 }
501519
502520 pub async fn register_class (
@@ -553,18 +571,18 @@ impl Jvm {
553571 let threads = self . inner . threads . read ( ) ;
554572 let thread = threads. get ( & thread_id) . unwrap ( ) ;
555573
556- let mut result = Vec :: with_capacity ( thread. stack . len ( ) ) ;
557-
558- for item in thread . stack . iter ( ) . rev ( ) {
559- // skip exception classes
560- if self . is_inherited_from ( & * item . class . definition , "java/lang/Throwable" ) {
561- continue ;
562- }
563-
564- result . push ( format ! ( "{}.{}" , item . class. definition. name( ) , item . method) ) ;
565- }
566-
567- result
574+ thread
575+ . iter_java_frame ( )
576+ . rev ( )
577+ . filter_map ( |x| {
578+ // skip exception classes
579+ if self . is_inherited_from ( & * x . class . definition , "java/lang/Throwable" ) {
580+ None
581+ } else {
582+ Some ( format ! ( "{}.{}" , x . class. definition. name( ) , x . method) )
583+ }
584+ } )
585+ . collect ( )
568586 }
569587
570588 async fn register_class_internal ( & self , class : Class , class_loader_wrapper : Option < & dyn ClassLoaderWrapper > ) -> Result < ( ) > {
@@ -624,6 +642,7 @@ impl Jvm {
624642 pub fn attach_thread ( & self ) -> Result < ( ) > {
625643 let thread_id = ( self . inner . get_current_thread_id ) ( ) ;
626644 self . inner . threads . write ( ) . insert ( thread_id, JvmThread :: new ( ) ) ;
645+ self . push_native_frame ( ) ;
627646
628647 Ok ( ( ) )
629648 }
@@ -635,6 +654,17 @@ impl Jvm {
635654 Ok ( ( ) )
636655 }
637656
657+ // TODO we need safe, ergonomic api..
658+ pub fn push_native_frame ( & self ) {
659+ let thread_id = ( self . inner . get_current_thread_id ) ( ) ;
660+ self . inner . threads . write ( ) . get_mut ( & thread_id) . unwrap ( ) . push_native_frame ( ) ;
661+ }
662+
663+ pub fn pop_frame ( & self ) {
664+ let thread_id = ( self . inner . get_current_thread_id ) ( ) ;
665+ self . inner . threads . write ( ) . get_mut ( & thread_id) . unwrap ( ) . pop_frame ( ) ;
666+ }
667+
638668 pub async fn current_class_loader ( & self ) -> Result < Box < dyn ClassInstance > > {
639669 let calling_class = self . find_calling_class ( ) ?;
640670
@@ -703,7 +733,7 @@ impl Jvm {
703733 . write ( )
704734 . get_mut ( & thread_id)
705735 . unwrap ( )
706- . push_frame ( class, class_instance, & method_str) ;
736+ . push_java_frame ( class, class_instance, & method_str) ;
707737
708738 let result = method. run ( self , args) . await ;
709739
0 commit comments