mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-08 18:34:00 +00:00
Discussion of these changes can be found on the Mercury developers
mailing list archives from June 2018.
COPYING.LIB:
Add a special linking exception to the LGPL.
*:
Update references to COPYING.LIB.
Clean up some minor errors that have accumulated in copyright
messages.
127 lines
5.3 KiB
C
127 lines
5.3 KiB
C
// vim: ts=4 sw=4 expandtab ft=c
|
|
|
|
// Copyright (C) 1997-2000, 2002-2003, 2007 The University of Melbourne.
|
|
// Copyright (C) 2016, 2018 The Mercury team.
|
|
// This file is distributed under the terms specified in COPYING.LIB.
|
|
|
|
// deepcopy.h - declares the MR_deep_copy() function.
|
|
|
|
#ifndef MERCURY_DEEP_COPY_H
|
|
#define MERCURY_DEEP_COPY_H
|
|
|
|
#include "mercury_types.h" // for `MR_Word'
|
|
#include "mercury_bitmap.h"
|
|
#include "mercury_type_info.h" // for `MR_TypeInfo'
|
|
#include "mercury_conf.h" // for `MR_MIGHT_RECLAIM_HP_ON_FAILURE'
|
|
|
|
// MR_deep_copy:
|
|
//
|
|
// Copy a data item, completely.
|
|
//
|
|
// The copying is done depth first. Any part of the data structure that is
|
|
// outside the given upper and lower bounds not be copied, instead a reference
|
|
// to the original data will be used. For conservative gc grades, the entire
|
|
// data structure will be copied, as there is no heap.
|
|
//
|
|
// The caller must provide the type_info describing the type of this
|
|
// data structure. It must also provide the upper and lower limits;
|
|
// if no limits are desired, pass NULL as the lower_limit.
|
|
//
|
|
// Deep copy returns the actual data that it copied, which may need to be
|
|
// stored on the heap, or put in a register or stack slot (depending on
|
|
// what you are using deep copy for). This may be a tagged pointer, or,
|
|
// if the data is just a simple type like a constant or integer,
|
|
// it will be the constant or integer itself.
|
|
//
|
|
// Please note - MR_deep_copy increments the heap pointer, however on
|
|
// some platforms (notably, SPARCs) the register-windows mean the transient
|
|
// Mercury registers may be lost. So before calling MR_deep_copy, call
|
|
// MR_save_transient_hp();
|
|
//
|
|
// MR_deep_copy will use MR_restore_transient_hp() to restore and modify
|
|
// the heap pointer, and then call MR_save_transient_hp() to save it again.
|
|
// (This may also restore/save other registers in the process.)
|
|
//
|
|
// After calling MR_deep_copy, be sure to do a MR_restore_transient_hp();
|
|
// so that the registers are restored.
|
|
//
|
|
// If writing a C function that calls MR_deep_copy, make sure you document that
|
|
// around your function, MR_save_transient_hp()/MR_restore_transient_hp()
|
|
// need to be used.
|
|
//
|
|
// Deep copy does not preserve sharing of subterms. Each subterm is copied
|
|
// in full, except for data items that are stored outside the heap limits.
|
|
// XXX For some applications, sharing is useful. For others we want a copy
|
|
// that is completely unique. We should modify MR_deep_copy to do both.
|
|
|
|
extern MR_Word MR_deep_copy(MR_Word data, MR_TypeInfo type_info,
|
|
const MR_Word *lower_limit, const MR_Word *upper_limit);
|
|
|
|
// MR_agc_deep_copy:
|
|
//
|
|
// Just like MR_deep_copy(), but it will leave forwarding pointers
|
|
// in the old data (destructively). lower_limit and upper_limit give
|
|
// the boundaries for copying data, and the boundaries for leaving
|
|
// forwarding pointers.
|
|
//
|
|
// Data will be copied to wherever the heap pointer is pointing.
|
|
//
|
|
// A forwarding pointer will be left simply by copying the new value
|
|
// of the data into the old location. If the data was a tagged pointer,
|
|
// the pointer will now refer to the rest of the data on the new heap.
|
|
// (If the data wasn't a tagged pointer, it will be a constant anyway).
|
|
//
|
|
// The upper and lower limits allow forwarding pointers to be detected
|
|
// and treated just as if they were pointers off the heap (say to a constant
|
|
// data structure in the data segment of the program).
|
|
//
|
|
// Note: You cannot pass NULL as the lower_limit to MR_agc_deep_copy
|
|
// (which is possible with normal MR_deep_copy).
|
|
|
|
extern MR_Word MR_agc_deep_copy(MR_Word data, MR_TypeInfo type_info,
|
|
const MR_Word *lower_limit, const MR_Word *upper_limit);
|
|
|
|
// This holds a bitmap used by MR_agc_deep_copy() to record which objects
|
|
// have already been copied and hence contain forwarding pointers.
|
|
// It gets initialized by MR_garbage_collect().
|
|
|
|
extern MR_Word *MR_has_forwarding_pointer;
|
|
|
|
// MR_make_permanent:
|
|
//
|
|
// Returns a copy of term that can be accessed safely even after Mercury
|
|
// execution has backtracked past the point at which the term was allocated.
|
|
//
|
|
// Note that if we are never going to reclaim heap on failure (e.g. in
|
|
// conservative GC grades) then nothing needs to be done, and hence the term
|
|
// is just returned.
|
|
//
|
|
// When not using a conservative GC grade, MR_save_transient_hp() and
|
|
// MR_restore_transient_hp() need to be used around this function.
|
|
// (When using a conservative GC grade, these macros are harmless,
|
|
// so they can be used then too.)
|
|
|
|
#define MR_make_permanent(term, type_info) \
|
|
MR_make_long_lived((term), (type_info), NULL)
|
|
|
|
// MR_make_long_lived:
|
|
//
|
|
// This is the same as MR_make_permanent, except that if limit is an
|
|
// address on the heap, parts of term that are "older" than limit will
|
|
// not be copied. This is useful when you know that the permanent copy
|
|
// of term will not be accessed after the heap pointer has backtracked
|
|
// beyond limit. Naturally, this always occurs when the permanent term
|
|
// is to be stored in *limit.
|
|
//
|
|
// I'd like to describe the limit argument without referring to the "heap,"
|
|
// but don't see how to.
|
|
|
|
#ifndef MR_MIGHT_RECLAIM_HP_ON_FAILURE
|
|
#define MR_make_long_lived(term, type_info, lower_limit) (term)
|
|
#else
|
|
extern MR_Word MR_make_long_lived(MR_Word term, MR_TypeInfo type_info,
|
|
MR_Word *lower_limit);
|
|
#endif
|
|
|
|
#endif // not MERCURY_DEEP_COPY_H
|