Removed "bulk operations"

Negligible performance gains don't justify extra complexity.
This commit is contained in:
Roberto Ierusalimschy
2024-03-15 11:23:35 -03:00
parent 3823fc6c81
commit ba71060381
3 changed files with 14 additions and 57 deletions

36
lgc.c
View File

@@ -465,46 +465,24 @@ static void traverseweakvalue (global_State *g, Table *h) {
} }
#define BK2(x) cast(lua_Unsigned, ((x) << 8) | BIT_ISCOLLECTABLE)
/* /*
** Check whether some value in the cell starting at index 'i' ** Traverse the array part of a table.
** is collectable
*/
static int checkBulkCollectable (Table *h, unsigned i) {
const lua_Unsigned bitscoll = BK2(BK2(BK2(BK2(BK2(BK2(BK2(BK2(~0u))))))));
int j;
i /= NM;
for (j = 0; j < BKSZ; j++) {
if (h->array[i].u.bulk[j] & bitscoll)
return 1;
}
return 0;
}
/*
** Traverse the array part of a table. The traversal is made by cells,
** only traversing a cell if it has some collectable tag among its tags.
*/ */
static int traversearray (global_State *g, Table *h) { static int traversearray (global_State *g, Table *h) {
unsigned asize = luaH_realasize(h); unsigned asize = luaH_realasize(h);
int marked = 0; /* true if some object is marked in this traversal */ int marked = 0; /* true if some object is marked in this traversal */
unsigned i; unsigned i;
for (i = 0; i < asize; i += NM) { /* traverse array in cells */ for (i = 0; i < asize; i++) {
if (checkBulkCollectable(h, i)) { /* something to mark in this cell? */ GCObject *o = gcvalarr(h, i);
unsigned j; if (o != NULL && iswhite(o)) {
for (j = 0; j < NM && i + j < asize; j++) { marked = 1;
GCObject *o = gcvalarr(h, i + j); reallymarkobject(g, o);
if (o != NULL && iswhite(o)) {
marked = 1;
reallymarkobject(g, o);
}
}
} }
} }
return marked; return marked;
} }
/* /*
** Traverse an ephemeron table and link it to proper list. Returns true ** Traverse an ephemeron table and link it to proper list. Returns true
** iff any object was marked during this traversal (which implies that ** iff any object was marked during this traversal (which implies that

View File

@@ -665,7 +665,7 @@ static void reinsertOldSlice (lua_State *L, Table *t, unsigned oldasize,
int tag = *getArrTag(t, i); int tag = *getArrTag(t, i);
if (!tagisempty(tag)) { /* a non-empty entry? */ if (!tagisempty(tag)) { /* a non-empty entry? */
TValue aux; TValue aux;
farr2val(t, i + 1, tag, &aux); farr2val(t, i + 1, tag, &aux); /* copy entry into 'aux' */
luaH_setint(L, t, i + 1, &aux); /* re-insert it into the table */ luaH_setint(L, t, i + 1, &aux); /* re-insert it into the table */
} }
} }
@@ -673,21 +673,12 @@ static void reinsertOldSlice (lua_State *L, Table *t, unsigned oldasize,
} }
#define BK1(x) cast(lua_Unsigned, ((x) << 8) | LUA_VEMPTY)
/* /*
** Clear new slice of the array, in bulk. ** Clear new slice of the array.
*/ */
static void clearNewSlice (Table *t, unsigned oldasize, unsigned newasize) { static void clearNewSlice (Table *t, unsigned oldasize, unsigned newasize) {
int i, j; for (; oldasize < newasize; oldasize++)
int firstcell = (oldasize + NM - 1) / NM; *getArrTag(t, oldasize) = LUA_VEMPTY;
int lastcell = cast_int((newasize + NM - 1) / NM) - 1;
for (i = firstcell; i <= lastcell; i++) {
/* empty tag repeated for all tags in a word */
const lua_Unsigned empty = BK1(BK1(BK1(BK1(BK1(BK1(BK1(BK1(0))))))));
for (j = 0; j < BKSZ; j++)
t->array[i].u.bulk[j] = empty;
}
} }

View File

@@ -87,32 +87,20 @@
/* /*
** The array part of a table is represented by an array of *cells*. ** The array part of a table is represented by an array of cells.
** Each cell is composed of NM tags followed by NM values, so that ** Each cell is composed of NM tags followed by NM values, so that
** no space is wasted in padding. ** no space is wasted in padding.
*/ */
#define NM cast_uint(sizeof(Value)) #define NM cast_uint(sizeof(Value))
/*
** A few operations on arrays can be performed "in bulk", treating all
** tags of a cell as a simple (or a few) word(s). The next constant is
** the number of words to cover the tags of a cell. (In conventional
** architectures that will be 1 or 2.)
*/
#define BKSZ cast_int((NM - 1) / sizeof(lua_Unsigned) + 1)
struct ArrayCell { struct ArrayCell {
union { lu_byte tag[NM];
lua_Unsigned bulk[BKSZ]; /* for "bulk" operations */
lu_byte tag[NM];
} u;
Value value[NM]; Value value[NM];
}; };
/* Computes the address of the tag for the abstract index 'k' */ /* Computes the address of the tag for the abstract index 'k' */
#define getArrTag(t,k) (&(t)->array[(k)/NM].u.tag[(k)%NM]) #define getArrTag(t,k) (&(t)->array[(k)/NM].tag[(k)%NM])
/* Computes the address of the value for the abstract index 'k' */ /* Computes the address of the value for the abstract index 'k' */
#define getArrVal(t,k) (&(t)->array[(k)/NM].value[(k)%NM]) #define getArrVal(t,k) (&(t)->array[(k)/NM].value[(k)%NM])