Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file owee_marker.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235type'resultservice=..type_service+=|Name:stringservice|Traverse:((Obj.t->'acc->'acc)->'acc->'acc)service|Locate:Owee_location.tlistservicetype'aservice_result=|Successof'a|Unsupported_service|Unmanaged_objectletmagic_potion=Obj.repr(ref())type'amarker={magic_potion:Obj.t;service:'result.'a->'resultservice->'resultservice_result;}letsize_marker=2type'acycle_marker={magic_potion:Obj.t;original:'amarker;unique_id:int;mutableusers:int;}letsize_cycle_marker=4letunique_ids=ref0letfresh_name()=incrunique_ids;!unique_idsletmake_cycle_marker(marker:_marker)={magic_potion;original=marker;unique_id=fresh_name();users=0}letis_markerobj=ifObj.tagobj=0&&Obj.sizeobj>=2&&Obj.fieldobj0==magic_potionthenifObj.sizeobj=size_markerthen`MarkerelseifObj.sizeobj=size_cycle_markerthen`Cycle_markerelse`Noelse`Noletfind_markert=letrecaux(obj:'a)ij=ifi>=jthen`Noelseletobj'=Obj.field(Obj.reprobj)iinmatchis_markerobj'with|`Marker->`Marker(i,(Obj.objobj':'amarker))|`Cycle_marker->`Cycle_marker(i,(Obj.objobj':'acycle_marker))|`No->auxobj(i+1)jinletobj=Obj.reprtinifObj.tagobj<Obj.lazy_tagthenauxt0(Obj.sizeobj)else`Noletquery_servicetservice=matchfind_markertwith|`No->Unmanaged_object|`Marker(_,marker)|`Cycle_marker(_,{original=marker;_})->marker.servicetservicemoduletypeT0=sigtypetvalservice:t->'resultservice->'resultservice_resultendmoduleUnsafe0(M:T0):sigvalmarker:M.tmarkerend=structletmarker=M.({magic_potion;service})endtype'amarked={cell:'a;marker:'amarkedmarker;}letmake_markedcellmarker={cell;marker}letgett=t.cellmoduleSafe0(M:T0):sigvalmark:M.t->M.tmarkedend=structincludeUnsafe0(structtypet=M.tmarkedletserviceobj(typea)(request:aservice):aservice_result=M.serviceobj.cellrequestend)letmarkcell=make_markedcellmarkerend(******)moduletypeT1=sigtype'xtvalservice:'xt->'resultservice->'resultservice_resultendmoduleUnsafe1(M:T1):sigvalmarker:'xM.tmarkerend=structletmarker=M.({magic_potion;service})endmoduleSafe1(M:T1):sigvalmark:'aM.t->'aM.tmarkedend=structincludeUnsafe1(structtype'at='aM.tmarkedletserviceobj(typea)(request:aservice):aservice_result=M.serviceobj.cellrequestend)letmarkcell=make_markedcellmarkerendmoduletypeT2=sigtype('x,'y)tvalservice:('x,'y)t->'resultservice->'resultservice_resultendmoduleUnsafe2(M:T2):sigvalmarker:('x,'y)M.tmarkerend=structletmarker=M.({magic_potion;service})endmoduleSafe2(M:T2):sigvalmark:('a,'b)M.t->('a,'b)M.tmarkedend=structincludeUnsafe2(structtype('a,'b)t=('a,'b)M.tmarkedletserviceobj(typea)(request:aservice):aservice_result=M.serviceobj.cellrequestend)letmarkcell=make_markedcellmarkerendmoduletypeT3=sigtype('x,'y,'z)tvalservice:('x,'y,'z)t->'resultservice->'resultservice_resultendmoduleUnsafe3(M:T3):sigvalmarker:('x,'y,'z)M.tmarkerend=structletmarker=M.({magic_potion;service})endmoduleSafe3(M:T3):sigvalmark:('a,'b,'c)M.t->('a,'b,'c)M.tmarkedend=structincludeUnsafe3(structtype('a,'b,'c)t=('a,'b,'c)M.tmarkedletserviceobj(typea)(request:aservice):aservice_result=M.serviceobj.cellrequestend)letmarkcell=make_markedcellmarkerend(* Cycle detection *)typecycle={(* FIXME: someday, find better than an hashtable, or maybe just drop cycle
detection to some library like Phystable? *)seen_ids:(int,unit)Hashtbl.t;(* Cause uncessary retention, switch to weak array?*)mutableseen_objs:Obj.tlist;}letseencycleobj=matchfind_markerobjwith|`No->`Unmanaged|`Marker_->`Not_seen|`Cycle_marker(_,marker)->ifHashtbl.memcycle.seen_idsmarker.unique_idthen`Seenmarker.unique_idelse`Not_seenletadd_to_cyclecycle(obj:'a)(marker:'acycle_marker)=marker.users<-marker.users+1;Hashtbl.addcycle.seen_idsmarker.unique_id();cycle.seen_objs<-Obj.reprobj::cycle.seen_objs;`Now_seenmarker.unique_idletupdate_marker(obj:'a)(field:int)(marker:'amarker)=Obj.set_field(Obj.reprobj)field(Obj.reprmarker)letupdate_cycle_marker(obj:'a)(field:int)(marker:'acycle_marker)=Obj.set_field(Obj.reprobj)field(Obj.reprmarker)letmark_seencycleobj=matchfind_markerobjwith|`No->`Unmanaged|`Marker(i,marker)->letmarker=make_cycle_markermarkerinupdate_cycle_markerobjimarker;add_to_cyclecycleobjmarker|`Cycle_marker(_,marker)->ifHashtbl.memcycle.seen_idsmarker.unique_idthen`Already_seenmarker.unique_idelseadd_to_cyclecycleobjmarkerletunmark_seenobj=matchfind_markerobjwith|`Cycle_marker(i,marker)->marker.users<-marker.users-1;ifmarker.users=0thenupdate_markerobjimarker.original|`Marker_->prerr_endline"UNEXPECTED MARKER";assertfalse|`No->prerr_endline"UNEXPECTED UNMANAGED";assertfalseletend_cyclecycle=Hashtbl.resetcycle.seen_ids;letseen_objs=cycle.seen_objsincycle.seen_objs<-[];List.iterunmark_seenseen_objsletstart_cycle()=letcycle={seen_ids=Hashtbl.create7;seen_objs=[]}inGc.finaliseend_cyclecycle;cycle