aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-03-15 11:23:35 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-03-15 11:23:35 -0300
commitba710603811c68fe3a69b3bb98e9038d37489a79 (patch)
treec960f80517482d4baa33f92dd7f9b9002b24f365
parent3823fc6c814d20f2b2a0a1e3be8782084440040f (diff)
downloadlua-ba710603811c68fe3a69b3bb98e9038d37489a79.tar.gz
lua-ba710603811c68fe3a69b3bb98e9038d37489a79.tar.bz2
lua-ba710603811c68fe3a69b3bb98e9038d37489a79.zip
Removed "bulk operations"
Negligible performance gains don't justify extra complexity.
Diffstat (limited to '')
-rw-r--r--lgc.c36
-rw-r--r--ltable.c17
-rw-r--r--ltable.h18
3 files changed, 14 insertions, 57 deletions
diff --git a/lgc.c b/lgc.c
index f76e851e..d1f5590e 100644
--- a/lgc.c
+++ b/lgc.c
@@ -465,46 +465,24 @@ static void traverseweakvalue (global_State *g, Table *h) {
465} 465}
466 466
467 467
468#define BK2(x) cast(lua_Unsigned, ((x) << 8) | BIT_ISCOLLECTABLE)
469/*
470** Check whether some value in the cell starting at index 'i'
471** is collectable
472*/
473static int checkBulkCollectable (Table *h, unsigned i) {
474 const lua_Unsigned bitscoll = BK2(BK2(BK2(BK2(BK2(BK2(BK2(BK2(~0u))))))));
475 int j;
476 i /= NM;
477 for (j = 0; j < BKSZ; j++) {
478 if (h->array[i].u.bulk[j] & bitscoll)
479 return 1;
480 }
481 return 0;
482}
483
484
485/* 468/*
486** Traverse the array part of a table. The traversal is made by cells, 469** Traverse the array part of a table.
487** only traversing a cell if it has some collectable tag among its tags.
488*/ 470*/
489static int traversearray (global_State *g, Table *h) { 471static int traversearray (global_State *g, Table *h) {
490 unsigned asize = luaH_realasize(h); 472 unsigned asize = luaH_realasize(h);
491 int marked = 0; /* true if some object is marked in this traversal */ 473 int marked = 0; /* true if some object is marked in this traversal */
492 unsigned i; 474 unsigned i;
493 for (i = 0; i < asize; i += NM) { /* traverse array in cells */ 475 for (i = 0; i < asize; i++) {
494 if (checkBulkCollectable(h, i)) { /* something to mark in this cell? */ 476 GCObject *o = gcvalarr(h, i);
495 unsigned j; 477 if (o != NULL && iswhite(o)) {
496 for (j = 0; j < NM && i + j < asize; j++) { 478 marked = 1;
497 GCObject *o = gcvalarr(h, i + j); 479 reallymarkobject(g, o);
498 if (o != NULL && iswhite(o)) {
499 marked = 1;
500 reallymarkobject(g, o);
501 }
502 }
503 } 480 }
504 } 481 }
505 return marked; 482 return marked;
506} 483}
507 484
485
508/* 486/*
509** Traverse an ephemeron table and link it to proper list. Returns true 487** Traverse an ephemeron table and link it to proper list. Returns true
510** iff any object was marked during this traversal (which implies that 488** iff any object was marked during this traversal (which implies that
diff --git a/ltable.c b/ltable.c
index 6eb5f3e3..c5f48716 100644
--- a/ltable.c
+++ b/ltable.c
@@ -665,7 +665,7 @@ static void reinsertOldSlice (lua_State *L, Table *t, unsigned oldasize,
665 int tag = *getArrTag(t, i); 665 int tag = *getArrTag(t, i);
666 if (!tagisempty(tag)) { /* a non-empty entry? */ 666 if (!tagisempty(tag)) { /* a non-empty entry? */
667 TValue aux; 667 TValue aux;
668 farr2val(t, i + 1, tag, &aux); 668 farr2val(t, i + 1, tag, &aux); /* copy entry into 'aux' */
669 luaH_setint(L, t, i + 1, &aux); /* re-insert it into the table */ 669 luaH_setint(L, t, i + 1, &aux); /* re-insert it into the table */
670 } 670 }
671 } 671 }
@@ -673,21 +673,12 @@ static void reinsertOldSlice (lua_State *L, Table *t, unsigned oldasize,
673} 673}
674 674
675 675
676#define BK1(x) cast(lua_Unsigned, ((x) << 8) | LUA_VEMPTY)
677
678/* 676/*
679** Clear new slice of the array, in bulk. 677** Clear new slice of the array.
680*/ 678*/
681static void clearNewSlice (Table *t, unsigned oldasize, unsigned newasize) { 679static void clearNewSlice (Table *t, unsigned oldasize, unsigned newasize) {
682 int i, j; 680 for (; oldasize < newasize; oldasize++)
683 int firstcell = (oldasize + NM - 1) / NM; 681 *getArrTag(t, oldasize) = LUA_VEMPTY;
684 int lastcell = cast_int((newasize + NM - 1) / NM) - 1;
685 for (i = firstcell; i <= lastcell; i++) {
686 /* empty tag repeated for all tags in a word */
687 const lua_Unsigned empty = BK1(BK1(BK1(BK1(BK1(BK1(BK1(BK1(0))))))));
688 for (j = 0; j < BKSZ; j++)
689 t->array[i].u.bulk[j] = empty;
690 }
691} 682}
692 683
693 684
diff --git a/ltable.h b/ltable.h
index 8688264c..8b0340b5 100644
--- a/ltable.h
+++ b/ltable.h
@@ -87,32 +87,20 @@
87 87
88 88
89/* 89/*
90** The array part of a table is represented by an array of *cells*. 90** The array part of a table is represented by an array of cells.
91** Each cell is composed of NM tags followed by NM values, so that 91** Each cell is composed of NM tags followed by NM values, so that
92** no space is wasted in padding. 92** no space is wasted in padding.
93*/ 93*/
94#define NM cast_uint(sizeof(Value)) 94#define NM cast_uint(sizeof(Value))
95 95
96
97/*
98** A few operations on arrays can be performed "in bulk", treating all
99** tags of a cell as a simple (or a few) word(s). The next constant is
100** the number of words to cover the tags of a cell. (In conventional
101** architectures that will be 1 or 2.)
102*/
103#define BKSZ cast_int((NM - 1) / sizeof(lua_Unsigned) + 1)
104
105struct ArrayCell { 96struct ArrayCell {
106 union { 97 lu_byte tag[NM];
107 lua_Unsigned bulk[BKSZ]; /* for "bulk" operations */
108 lu_byte tag[NM];
109 } u;
110 Value value[NM]; 98 Value value[NM];
111}; 99};
112 100
113 101
114/* Computes the address of the tag for the abstract index 'k' */ 102/* Computes the address of the tag for the abstract index 'k' */
115#define getArrTag(t,k) (&(t)->array[(k)/NM].u.tag[(k)%NM]) 103#define getArrTag(t,k) (&(t)->array[(k)/NM].tag[(k)%NM])
116 104
117/* Computes the address of the value for the abstract index 'k' */ 105/* Computes the address of the value for the abstract index 'k' */
118#define getArrVal(t,k) (&(t)->array[(k)/NM].value[(k)%NM]) 106#define getArrVal(t,k) (&(t)->array[(k)/NM].value[(k)%NM])