Files
mercury/runtime/mercury_stack_trace.h
Tyson Dowd 376f2c69af An initial implementation of the accurate garbage collector.
Estimated hours taken: 90

An initial implementation of the accurate garbage collector.

WORK_IN_PROGRESS:
	Add an entry for the accurate garbage collector.

library/builtin.m:
library/mercury_builtin.m:
library/std_util.m:
runtime/mercury_tabling.h:
	Deep copy terms using the address of the value instead of
	just the value.

library/io.m:
	Initialize the garbage collector's rootset with the globals.

runtime/Mmakefile:
	Add new files to the Mmakefile.

runtime/mercury_accurate_gc.h:
runtime/mercury_accurate_gc.c:
	The new garbage collector.

runtime/mercury_agc_debug.c:
runtime/mercury_agc_debug.h:
	Debugging utilities for the new garbage collector.

runtime/mercury_deep_copy.c:
runtime/mercury_deep_copy.h:
runtime/mercury_deep_copy_body.h:
	Put the deep copy code in mercury_deep_copy_body.h, and #include
	it with appropriate #defines in order to get a variant for
	deep_copy(), and one for agc_deep_copy().

	agc_deep_copy() forwards pointers as it copies.

	Also, deep_copy (all variants) have been modified to take
	a pointer to the data to be copied, because some variants
	need to be able to modify it.

runtime/mercury_engine.c:
runtime/mercury_engine.h:
	Add a second heap_zone which is the to-space of
	the copying collector.
	Add a debug_heap_zone, which is used as a scratch
	heap for debugging.

runtime/mercury_label.c:
	Instead of
		realloc(entry_table, ....)
	do
		entry_table = realloc(entry_table, ....)
	to avoid horrible bugs.

	Also, make sure the tables get initialized before looking up
	an entry label.

runtime/mercury_imp.h:
	Include mercury_debug.h before most of the modules.
	(mercury_engine.h adds a new MemoryZone only if we are
	debugging accurate GC).

runtime/mercury_memory.c:
	Setup the debug_memory_zone sizes.
	Remove an unnecessary prototype.

runtime/mercury_memory_handlers.c:
	Add code to get the program counter and the stack pointer
	from the signal context.

	Call MR_schedule_agc() from default_handler() if doing accurate gc.

runtime/mercury_memory_zones.c:
	Setup the hardzone regardless of whether redzones are used.

	Add some more debugging information.

runtime/mercury_regorder.h:
runtime/machdeps/alpha_regs.h:
runtime/machdeps/i386_regs.h:
	Add definitions to make the real machine registers name/number
	for MR_sp available.

runtime/mercury_trace_internal.c:
runtime/mercury_trace_util.c:
runtime/mercury_trace_util.h:
	Add MR_trace_write_variable(), which writes terms given their
	value and type_info.

runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
	Change the size of the heap redzone when doing accurate GC.
	Use a small heap when debugging agc.

runtime/mercury_debug.h:
runtime/mercury_conf_param.h:
	Add new debugging macros and document them.

runtime/mercury_type_info.c:
	Add const to the pointer arguments of MR_make_type_info.
1998-07-22 07:55:19 +00:00

136 lines
4.9 KiB
C

/*
** Copyright (C) 1998 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
#ifndef MERCURY_STACK_TRACE_H
#define MERCURY_STACK_TRACE_H
#include "mercury_stack_layout.h"
/*
** mercury_stack_trace.h -
** Definitions for use by the stack tracing.
*/
/*---------------------------------------------------------------------------*/
/*
** MR_dump_stack:
** Given the succip, det stack pointer and current frame, generate a
** stack dump showing the name of each active procedure on the
** stack.
** NOTE: MR_dump_stack will assume that the succip is for the
** topmost stack frame. If you call MR_dump_stack from some
** pragma c_code, that may not be the case.
** Due to some optimizations (or lack thereof) the MR_dump_stack call
** may end up inside code that has a stack frame allocated, but
** that has a succip for the previous stack frame.
** Don't call MR_dump_stack from Mercury pragma c_code (calling
** from other C code in the runtime is probably ok, provided the
** succip corresponds to the topmost stack frame).
** (See library/require.m for a technique for calling MR_dump_stack
** from Mercury).
** If you need a more convenient way of calling from Mercury code,
** it would probably be best to make an impure predicate defined
** using `:- external'.
*/
extern void MR_dump_stack(Code *success_pointer,
Word *det_stack_pointer,
Word *current_frame);
/*
** MR_dump_stack_from_layout:
** This function does the same job and makes the same assumptions
** as MR_dump_stack, but instead of the succip, it takes the entry
** layout of the current procedure as input. It also takes a parameter
** that tells it where to put the stack dump. If the entire stack
** was printed successfully, the return value is NULL; otherwise,
** it is a string indicating why the dump was cut short.
*/
extern const char *MR_dump_stack_from_layout(FILE *fp,
const MR_Stack_Layout_Entry *entry_layout,
Word *det_stack_pointer, Word *current_frame);
/*
** MR_dump_nondet_stack_from_layout:
** This function dumps the control control slots of the nondet stack.
** The output format is not meant to be intelligible to non-implementors.
** The value of maxfr should be in *base_maxfr.
*/
extern void MR_dump_nondet_stack_from_layout(FILE *fp,
Word *base_maxfr);
/*
** MR_find_nth_ancestor:
** Return the layout structure of the return label of the call
** ancestor_level levels above the current call. Label_layout
** tells us how to decipher the stack of the current call, while
** *stack_trace_sp and *stack_trace_curfr tell us where it is.
** On return, *stack_trace_sp and *stack_trace_curfr will be
** set up to match the specified ancestor.
**
** If the required stack walk is not possible (e.g. because some
** stack frames have no layout information, or because the stack
** does not have the required depth), the return value will be NULL,
** and problem will point to an error message.
*/
extern const MR_Stack_Layout_Label *MR_find_nth_ancestor(
const MR_Stack_Layout_Label *label_layout,
int ancestor_level, Word **stack_trace_sp,
Word **stack_trace_curfr, const char **problem);
/*
** MR_stack_trace_bottom should be set to the address of global_success,
** the label main/2 goes to on success. Stack dumps terminate when they
** reach a stack frame whose saved succip slot contains this address.
*/
Code *MR_stack_trace_bottom;
/*
** MR_nondet_stack_trace_bottom should be set to the address of the buffer
** nondet stack frame created before calling main. Nondet stack dumps terminate
** when they reach a stack frame whose redoip contains this address. Note that
** the redoip and redofr slots of this frame may be hijacked.
*/
Word *MR_nondet_stack_trace_bottom;
typedef enum {
STEP_ERROR_BEFORE, /* the current entry_layout has no valid info */
STEP_ERROR_AFTER, /* the current entry_layout has valid info,
but the next one does not */
STEP_OK /* both have valid info */
} MR_Stack_Walk_Step_Result;
/*
** MR_stack_walk_step:
** This function takes the entry_layout for the current stack
** frame (which is the topmost stack frame from the two stack
** pointers given), and moves down one stack frame, setting the
** stack pointers to their new levels.
**
** return_label_layout will be set to the stack_layout of the
** continuation label, or NULL if the bottom of the stack has
** been reached.
**
** The meaning of the return value for MR_stack_walk_step is
** described in its type definiton above. If an error is
** encountered, problem_ptr will be set to a string representation
** of the error.
*/
extern MR_Stack_Walk_Step_Result
MR_stack_walk_step(const MR_Stack_Layout_Entry *entry_layout,
const MR_Stack_Layout_Label **return_label_layout,
Word **stack_trace_sp_ptr, Word **stack_trace_curfr_ptr,
const char **problem_ptr);
#endif /* MERCURY_STACK_TRACE_H */