diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-03-15 11:23:35 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-03-15 11:23:35 -0300 |
commit | ba710603811c68fe3a69b3bb98e9038d37489a79 (patch) | |
tree | c960f80517482d4baa33f92dd7f9b9002b24f365 | |
parent | 3823fc6c814d20f2b2a0a1e3be8782084440040f (diff) | |
download | lua-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.c | 36 | ||||
-rw-r--r-- | ltable.c | 17 | ||||
-rw-r--r-- | ltable.h | 18 |
3 files changed, 14 insertions, 57 deletions
@@ -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 | */ | ||
473 | static 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 | */ |
489 | static int traversearray (global_State *g, Table *h) { | 471 | static 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 |
@@ -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 | */ |
681 | static void clearNewSlice (Table *t, unsigned oldasize, unsigned newasize) { | 679 | static 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 | ||
@@ -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 | |||
105 | struct ArrayCell { | 96 | struct 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]) |