1 ///////////////////////////////////////////////////////////////////////////////
3 // This file implements the garbage collection interface generation
5 ///////////////////////////////////////////////////////////////////////////////
11 ///////////////////////////////////////////////////////////////////////////////
13 // This method generates the interface method declarations
14 // for the garbage collector.
16 ///////////////////////////////////////////////////////////////////////////////
17 void DatatypeClass::generate_gc_interface(CodeGen& C)
21 "%^// Method for garbage collection tracing"
25 "%^virtual void trace(GC *);"
30 ///////////////////////////////////////////////////////////////////////////////
32 // This method generates an implementation for the trace method
34 ///////////////////////////////////////////////////////////////////////////////
35 void DatatypeClass::generate_gc_implementation(CodeGen& C, Tys tys, DefKind k)
37 // Unit constructors do not need gc methods
38 if (root->arg_constructors == 0) return;
40 if (k == INTERFACE_DEFINITION)
41 { C.pr("%^extern void %s%P::trace(GC *);", class_name, tys);
45 C.pr("%^void %s%P::trace(GC * gc__)"
46 "%^{%+", class_name, tys);
48 // Invoke base class tracing methods
49 gen_super_class_tracing_methods(C,tys,k);
51 // Invoke tracing functions for each collectable fields.
53 { Ty arg_ty = cons_arg_ty;
54 if (is_array) arg_ty = mkarrayty(arg_ty,IDexp("len_"));
55 gen_field_tracing_methods(C,DEREFexp(IDexp(#"this")),
62 ///////////////////////////////////////////////////////////////////////////////
64 // This method generates a tracing method for each base class
65 // that is collectable.
67 ///////////////////////////////////////////////////////////////////////////////
68 void DatatypeClass::gen_super_class_tracing_methods
69 (CodeGen& C, Tys tys, DefKind k)
71 // Generate a call to the superclass
74 if (root->use_gc_base)
75 C.pr("%^%s%P::trace(gc__);", root->class_name, tys);
77 C.pr("%^// call to method %s%P::trace() has been optimized out",
78 root->class_name, tys);
81 for_each(Inherit, inh, inherited_classes)
82 { if((inh->qualifiers & QUALcollectable) || is_gc_ty(inh->super_class))
83 { C.pr("%^%t::trace(gc__);",
84 apply_ty(mkpolyty(inh->super_class,parameters),tys), "");
85 if (this == root) root->use_gc_base = true;
90 ///////////////////////////////////////////////////////////////////////////////
92 // This method generates a tracing method for each field
93 // that is collectable.
95 ///////////////////////////////////////////////////////////////////////////////
96 void DatatypeClass::gen_field_tracing_methods
97 (CodeGen& C, Exp exp, Ty ty, Tys tys, DefKind k, Bool toplevel)
102 for_each(Ty, ty, types)
103 gen_field_tracing_methods(C,DOTexp(exp,index_of(i++)),ty,tys,k);
107 for_each(Ty, ty, types)
108 gen_field_tracing_methods(C,DOTexp(exp,index_of(i++)),ty,tys,k);
110 | RECORDty (labels, _, types):
112 for(ls = labels, ts = types; ls && ts; ls = ls->#2, ts = ts->#2)
113 gen_field_tracing_methods(C,DOTexp(exp,ls->#1),ts->#1,tys,k);
115 | ARRAYty (ty,bound):
117 "%^for (int i__ = 0; i__ < %e; i__++)"
120 gen_field_tracing_methods(C,INDEXexp(exp,IDexp(#"i__")),ty,tys,k);
126 { if (toplevel) exp = DOTexp(exp,mangle(cons->name));
127 if (is_pointer_ty(ty))
128 C.pr("%^%e = (%t)gc__->trace(%e);",exp,ty,"",exp);
130 C.pr("%^gc__->trace(%e);",exp);
133 { C.pr("%^// omitted %T", ty); }