# emit-treecode-heapcleaner-calls.api
#
# This is an alternative module for generating
# heapcleaner ("garbage collector") invocation code.
# There are a few improvements.
#
# All code to invoke heapcleaner is generated once at the end of the
# compilation unit---with one exception. For each cluster, a
# call to heapcleaner is a jump to the end of the cluster where there
# is another jump.
#
# Code to invoke heapcleaner for known functions is generated at the end of
# the cluster. This is important as there may be spilling across
# heapcleaner invocation calls.
# Compiled by:
#
src/lib/compiler/core.sublibstipulate
package ncf = nextcode_form; # nextcode_form is from
src/lib/compiler/back/top/nextcode/nextcode-form.pkgherein
# This api is implemented in:
#
#
src/lib/compiler/back/low/main/nextcode/emit-treecode-heapcleaner-calls-g.pkg #
api Emit_Treecode_Heapcleaner_Calls {
#
package tcs: Treecode_Codebuffer; # Treecode_Codebuffer is from
src/lib/compiler/back/low/treecode/treecode-codebuffer.api package mcg: Machcode_Controlflow_Graph # Machcode_Controlflow_Graph is from
src/lib/compiler/back/low/mcg/machcode-controlflow-graph.api where
pop == tcs::cst::pop; # "pop" == "pseudo_op".
Fun_Info
=
{ max_possible_heapbytes_allocated_before_next_heaplimit_check: Int,
#
live_registers: List( tcs::tcf::Expression ),
live_register_types: List( ncf::Type ),
return: tcs::tcf::Void_Expression
};
Stream
=
tcs::Treecode_Codebuffer (
tcs::tcf::Void_Expression,
List( tcs::tcf::Expression ),
mcg::Machcode_Controlflow_Graph
);
# List of registers which are used
# as roots for the heapcleaner:
#
heapcleaner_arg_registers
:
List( tcs::tcf::Int_Expression ); # Float registers don't contain pointers, so heapcleaner can ignore them.
# Initialize the state before compiling a package:
#
clear__public_fn_heapcleaner_call_specs__private_fn_heapcleaner_call_specs__and__longjumps_to_heapcleaner_calls
:
Void -> Void;
# These are called as part of emitting
# code for a package cccomponent:
#
put_heaplimit_check_and_push_heapcleaner_call_spec_for_public_fn : Stream -> Fun_Info -> Void;
put_heaplimit_check_and_push_heapcleaner_call_spec_for_unoptimized_private_fn: Stream -> Fun_Info -> Void;
put_heaplimit_check_and_push_heapcleaner_call_spec_for_optimized_private_fn : Stream -> Fun_Info -> Void;
#
# These all basically emit code equivalent to
#
# if (heap_allocation_pointer > heap_allocation_limit) goto foo;
#
# and then push code address 'foo' on a list. Later we do
# a pass generating all the call-heapcleaner blocks 'foo' --
# the Fun_Info stuff is saved for this pass.
# This is called when done emitting code
# for a given package cccomponent:
#
put_all_publicfn_heapcleaner_longjumps_and_all_privatefn_heapcleaner_calls_for_cccomponent
:
Stream -> Void;
# This is called when done emitting all
# cccomponents for a package:
#
put_all_publicfn_heapcleaner_calls_for_package
:
Stream -> Void;
# Generate the actual heapcleaner invocation code:
#
# put_heapcleaner_call # Commented out 2011-08-05 CrT because it is never called.
# :
# Stream
# ->
# { live_registers: List( tcs::tcf::Expression ), # Formal parameters.
# live_register_types: List( ncf::Type ), # Formal paramter types.
# return: tcs::tcf::Void_Expression
# }
# ->
# Void;
};
end;
## Changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.