Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor src/hpc/traverse.c #2102

Merged
merged 6 commits into from
Jan 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions src/hpc/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,6 @@ void RunThreadedMain(int (*mainFunction)(int, char **, char **),
RunThreadedMain2(mainFunction, argc, argv, environ);
}

extern void InitTraversalModule();

static void RunThreadedMain2(int (*mainFunction)(int, char **, char **),
int argc,
char ** argv,
Expand Down Expand Up @@ -266,9 +264,6 @@ static void RunThreadedMain2(int (*mainFunction)(int, char **, char **),
InitSignals();
if (sySetjmp(TLS(threadExit)))
exit(0);
/* Traversal functionality may be needed during the initialization
* of some modules, so we set it up now. */
InitTraversalModule();
exit((*mainFunction)(argc, argv, environ));
}

Expand Down
222 changes: 44 additions & 178 deletions src/hpc/traverse.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,12 @@
#include <src/bool.h>
#include <src/fibhash.h>
#include <src/gap.h>
#include <src/objset.h>
#include <src/gaputils.h>
#include <src/plist.h>
#include <src/precord.h>

#include <src/hpc/guards.h>
#include <src/hpc/thread.h>

#ifdef BOEHM_GC
# ifdef HPCGAP
# define GC_THREADS
# endif
# include <gc/gc.h>
#endif

#ifndef WARD_ENABLED

typedef struct TraversalState {
Expand Down Expand Up @@ -52,52 +44,13 @@ static Obj NewList(UInt size)
}


void QueueForTraversal(Obj obj);

typedef enum {
TRAVERSE_BY_FUNCTION,
TRAVERSE_NONE,
TRAVERSE_ALL,
TRAVERSE_ALL_BUT_FIRST,
} TraversalMethodEnum;

typedef void (*TraversalCopyFunction)(Obj copy, Obj original);

TraversalFunction TraversalFunc[LAST_REAL_TNUM + 1];
TraversalCopyFunction TraversalCopyFunc[LAST_REAL_TNUM + 1];
TraversalMethodEnum TraversalMethod[LAST_REAL_TNUM + 1];

void TraversePList(Obj obj)
{
UInt len = LEN_PLIST(obj);
const Obj * ptr = CONST_ADDR_OBJ(obj) + 1;
while (len) {
QueueForTraversal(*ptr++);
len--;
}
}

void TraverseWPObj(Obj obj)
{
/* This is a hack, we rely on weak pointer objects
* having the same layout as plain lists, so we don't
* have to replicate the macro here.
*/
UInt len = LEN_PLIST(obj);
const Obj * ptr = CONST_ADDR_OBJ(obj) + 1;
while (len) {
volatile Obj tmp = *ptr;
MEMBAR_READ();
if (tmp && *ptr)
QueueForTraversal(*ptr);
ptr++;
len--;
}
}

static UInt FindTraversedObj(Obj);

static inline Obj ReplaceByCopy(Obj obj)
inline Obj ReplaceByCopy(Obj obj)
{
TraversalState * traversal = currentTraversal();
UInt found = FindTraversedObj(obj);
Expand All @@ -114,136 +67,15 @@ static inline Obj ReplaceByCopy(Obj obj)
return obj;
}

void CopyPList(Obj copy, Obj original)
void SetTraversalMethod(UInt tnum,
TraversalMethodEnum meth,
TraversalFunction tf,
TraversalCopyFunction cf)
{
UInt len = LEN_PLIST(original);
const Obj * ptr = CONST_ADDR_OBJ(original) + 1;
Obj * copyptr = ADDR_OBJ(copy) + 1;
while (len) {
*copyptr++ = ReplaceByCopy(*ptr++);
len--;
}
}

void CopyWPObj(Obj copy, Obj original)
{
/* This is a hack, we rely on weak pointer objects
* having the same layout as plain lists, so we don't
* have to replicate the macro here.
*/
UInt len = LEN_PLIST(original);
const Obj * ptr = CONST_ADDR_OBJ(original) + 1;
Obj * copyptr = ADDR_OBJ(copy) + 1;
while (len) {
volatile Obj tmp = *ptr;
MEMBAR_READ();
if (tmp && *ptr)
*copyptr = ReplaceByCopy(tmp);
REGISTER_WP(copyptr, tmp);
ptr++;
copyptr++;
}
}

void TraversePRecord(Obj obj)
{
UInt i, len = LEN_PREC(obj);
for (i = 1; i <= len; i++)
QueueForTraversal((Obj)GET_ELM_PREC(obj, i));
}

void CopyPRecord(Obj copy, Obj original)
{
UInt i, len = LEN_PREC(original);
for (i = 1; i <= len; i++)
SET_ELM_PREC(copy, i, ReplaceByCopy(GET_ELM_PREC(original, i)));
}

void TraverseObjSet(Obj obj)
{
UInt i, len = *(UInt *)(CONST_ADDR_OBJ(obj) + OBJSET_SIZE);
for (i = 0; i < len; i++) {
Obj item = CONST_ADDR_OBJ(obj)[OBJSET_HDRSIZE + i];
if (item && item != Undefined)
QueueForTraversal(item);
}
}

void CopyObjSet(Obj copy, Obj original)
{
UInt i, len = *(UInt *)(CONST_ADDR_OBJ(original) + OBJSET_SIZE);
for (i = 0; i < len; i++) {
Obj item = CONST_ADDR_OBJ(original)[OBJSET_HDRSIZE + i];
ADDR_OBJ(copy)[OBJSET_HDRSIZE + i] = ReplaceByCopy(item);
}
}

void TraverseObjMap(Obj obj)
{
UInt i, len = *(UInt *)(CONST_ADDR_OBJ(obj) + OBJSET_SIZE);
for (i = 0; i < len; i++) {
Obj key = CONST_ADDR_OBJ(obj)[OBJSET_HDRSIZE + 2 * i];
Obj val = CONST_ADDR_OBJ(obj)[OBJSET_HDRSIZE + 2 * i + 1];
if (key && key != Undefined) {
QueueForTraversal(key);
QueueForTraversal(val);
}
}
}

void CopyObjMap(Obj copy, Obj original)
{
UInt i, len = *(UInt *)(CONST_ADDR_OBJ(original) + OBJSET_SIZE);
for (i = 0; i < len; i++) {
Obj key = CONST_ADDR_OBJ(original)[OBJSET_HDRSIZE + 2 * i];
Obj val = CONST_ADDR_OBJ(original)[OBJSET_HDRSIZE + 2 * i + 1];
ADDR_OBJ(copy)[OBJSET_HDRSIZE + 2 * i] = ReplaceByCopy(key);
ADDR_OBJ(copy)[OBJSET_HDRSIZE + 2 * i + 1] = ReplaceByCopy(val);
}
}

void InitTraversalModule(void)
{
int i;
for (i = FIRST_REAL_TNUM; i <= LAST_REAL_TNUM; i++) {
assert(TraversalMethod[i] == 0);
TraversalMethod[i] = TRAVERSE_NONE;
}
TraversalMethod[T_PREC ] = TRAVERSE_BY_FUNCTION;
TraversalMethod[T_PREC +IMMUTABLE] = TRAVERSE_BY_FUNCTION;
TraversalFunc[T_PREC ] = TraversePRecord;
TraversalFunc[T_PREC +IMMUTABLE] = TraversePRecord;
TraversalCopyFunc[T_PREC ] = CopyPRecord;
TraversalCopyFunc[T_PREC +IMMUTABLE] = CopyPRecord;
for (i = FIRST_PLIST_TNUM; i <= LAST_PLIST_TNUM; i++) {
TraversalMethod[i] = TRAVERSE_BY_FUNCTION;
TraversalFunc[i] = TraversePList;
TraversalCopyFunc[i] = CopyPList;
}
TraversalMethod[T_PLIST_CYC] = TRAVERSE_NONE;
TraversalMethod[T_PLIST_CYC_NSORT] = TRAVERSE_NONE;
TraversalMethod[T_PLIST_CYC_SSORT] = TRAVERSE_NONE;
TraversalMethod[T_PLIST_FFE] = TRAVERSE_NONE;

TraversalMethod[T_POSOBJ] = TRAVERSE_ALL_BUT_FIRST;

TraversalMethod[T_COMOBJ] = TRAVERSE_BY_FUNCTION;
TraversalFunc[T_COMOBJ] = TraversePRecord;
TraversalCopyFunc[T_COMOBJ] = CopyPRecord;

// FIXME: no TraversalMethod for T_WPOBJ ?!
TraversalFunc[T_WPOBJ] = TraverseWPObj;
TraversalCopyFunc[T_WPOBJ] = CopyWPObj;

TraversalMethod[T_DATOBJ] = TRAVERSE_NONE;

TraversalMethod[T_OBJSET] = TRAVERSE_BY_FUNCTION;
TraversalFunc[T_OBJSET] = TraverseObjSet;
TraversalCopyFunc[T_OBJSET] = CopyObjSet;

TraversalMethod[T_OBJMAP] = TRAVERSE_BY_FUNCTION;
TraversalFunc[T_OBJMAP] = TraverseObjMap;
TraversalCopyFunc[T_OBJMAP] = CopyObjMap;
GAP_ASSERT(tnum < ARRAY_SIZE(TraversalMethod));
TraversalMethod[tnum] = meth;
TraversalFunc[tnum] = tf;
TraversalCopyFunc[tnum] = cf;
}

static void BeginTraversal(TraversalState * traversal)
Expand Down Expand Up @@ -576,4 +408,38 @@ Obj CopyTraversed(Obj traversedList)
return copies[1];
}


/****************************************************************************
**
*F InitKernel( <module> ) . . . . . . . . initialise kernel data structures
*/
static Int InitKernel ( StructInitInfo * module )
{
int i;
for (i = FIRST_REAL_TNUM; i <= LAST_REAL_TNUM; i++) {
assert(TraversalMethod[i] == 0);
TraversalMethod[i] = TRAVERSE_NONE;
}

return 0;
}


/****************************************************************************
**
*F InitInfoGVars() . . . . . . . . . . . . . . . . . table of init functions
*/
static StructInitInfo module = {
// init struct using C99 designated initializers; for a full list of
// fields, please refer to the definition of StructInitInfo
.type = MODULE_BUILTIN,
.name = "traverse",
.initKernel = InitKernel,
};

StructInitInfo * InitInfoTraverse ( void )
{
return &module;
}

#endif
37 changes: 36 additions & 1 deletion src/hpc/traverse.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,47 @@
*/

typedef void (*TraversalFunction)(Obj);
typedef void (*TraversalCopyFunction)(Obj copy, Obj original);

typedef enum {
TRAVERSE_NONE,
TRAVERSE_BY_FUNCTION,
TRAVERSE_ALL,
TRAVERSE_ALL_BUT_FIRST,
} TraversalMethodEnum;

// set the traversal method (and optionally, helper functions)
// for all objects with the specified tnum.
extern void SetTraversalMethod(UInt tnum,
TraversalMethodEnum meth,
TraversalFunction tf,
TraversalCopyFunction cf);


// helper to be called from traverse functions
extern void QueueForTraversal(Obj obj);

// helper to be called from copy functions
extern Obj ReplaceByCopy(Obj obj);

extern TraversalFunction TraversalFunc[];

Obj ReachableObjectsFrom(Obj obj);
Obj CopyReachableObjectsFrom(Obj obj, int delimited, int asList, int imm);
Obj CopyTraversed(Obj traversed);
int PreMakeImmutableCheck(Obj obj);


/****************************************************************************
**
*F * * * * * * * * * * * * * initialize package * * * * * * * * * * * * * * *
*/


/****************************************************************************
**
*F InitInfoTraverse() . . . . . . . . . . . . . . . table of init functions
*/
StructInitInfo * InitInfoTraverse( void );


#endif // GAP_TRAVERSE_H
7 changes: 7 additions & 0 deletions src/modules-builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <src/hpc/aobjects.h>
#include <src/hpc/serialize.h>
#include <src/hpc/threadapi.h>
#include <src/hpc/traverse.h>
#endif

extern StructInitInfo * InitInfoGap ( void );
Expand All @@ -24,6 +25,12 @@ extern StructInitInfo * InitInfoGap ( void );
*/
const InitInfoFunc InitFuncsBuiltinModules[] = {

#ifdef HPCGAP
// Traversal functionality may be needed during the initialization
// of some modules, so set it up as early as possible
InitInfoTraverse,
#endif

/* global variables */
InitInfoGVars,

Expand Down
7 changes: 6 additions & 1 deletion src/objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <src/hpc/aobjects.h>
#include <src/hpc/guards.h>
#include <src/hpc/thread.h>
#include <src/hpc/traverse.h>
#endif

#if defined(USE_THREADSAFE_COPYING)
Expand Down Expand Up @@ -2077,8 +2078,12 @@ static Int InitKernel (
for ( t = FIRST_EXTERNAL_TNUM; t <= LAST_EXTERNAL_TNUM; t++ )
ShallowCopyObjFuncs[ t ] = ShallowCopyObjObject;

#ifdef USE_THREADSAFE_COPYING
SetTraversalMethod(T_POSOBJ, TRAVERSE_ALL_BUT_FIRST, 0, 0);
SetTraversalMethod(T_COMOBJ, TRAVERSE_BY_FUNCTION, TraversePRecord, CopyPRecord);
SetTraversalMethod(T_DATOBJ, TRAVERSE_NONE, 0, 0);
#else
/* make and install the 'COPY_OBJ' function */
#if !defined(USE_THREADSAFE_COPYING)
for ( t = FIRST_REAL_TNUM; t <= LAST_REAL_TNUM; t++ ) {
assert(CopyObjFuncs [ t ] == 0);
CopyObjFuncs [ t ] = CopyObjError;
Expand Down
Loading