diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-11-24 14:41:07 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-11-24 14:41:07 -0300 |
commit | 52b899d60d8c61b8affe0206014173912de94940 (patch) | |
tree | 5e6f9116b2c70a5ebd4c1bdea49f283cca5cb3fb /ltable.c | |
parent | 25cd3d377ec13176a6701d9d21a278ba8f2bc3d6 (diff) | |
download | lua-52b899d60d8c61b8affe0206014173912de94940.tar.gz lua-52b899d60d8c61b8affe0206014173912de94940.tar.bz2 lua-52b899d60d8c61b8affe0206014173912de94940.zip |
Simpler coding for new representation for arrays
With the tags comming first in a cell, we can define the whole cell
as a C type and let C do part of the address computations.
Diffstat (limited to 'ltable.c')
-rw-r--r-- | ltable.c | 46 |
1 files changed, 27 insertions, 19 deletions
@@ -541,29 +541,28 @@ static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) { | |||
541 | 541 | ||
542 | 542 | ||
543 | /* | 543 | /* |
544 | ** Convert an "abstract size" (number of values in an array) to | 544 | ** Convert an "abstract size" (number of slots in an array) to |
545 | ** "concrete size" (number of cell elements in the array). Cells | 545 | ** "concrete size" (number of bytes in the array). |
546 | ** do not need to be full; we only must make sure it has the values | 546 | ** If the abstract size is not a multiple of NM, the last cell is |
547 | ** needed and its 'tag' element. So, we compute the concrete tag index | 547 | ** incomplete, so we don't need to allocate memory for the whole cell. |
548 | ** and the concrete value index of the last element, get their maximum | 548 | ** 'extra' computes how many values are not needed in that last cell. |
549 | ** and adds 1. | 549 | ** It will be zero when 'size' is a multiple of NM, and from there it |
550 | ** increases as 'size' decreases, up to (NM - 1). | ||
550 | */ | 551 | */ |
551 | static unsigned int concretesize (unsigned int size) { | 552 | static size_t concretesize (unsigned int size) { |
552 | if (size == 0) return 0; | 553 | unsigned int numcells = (size + NM - 1) / NM; /* (size / NM) rounded up */ |
553 | else { | 554 | unsigned int extra = NM - 1 - ((size + NM - 1) % NM); |
554 | unsigned int ts = TagIndex(size - 1); | 555 | return numcells * sizeof(ArrayCell) - extra * sizeof(Value); |
555 | unsigned int vs = ValueIndex(size - 1); | ||
556 | return ((ts >= vs) ? ts : vs) + 1; | ||
557 | } | ||
558 | } | 556 | } |
559 | 557 | ||
560 | 558 | ||
561 | static ArrayCell *resizearray (lua_State *L , Table *t, | 559 | static ArrayCell *resizearray (lua_State *L , Table *t, |
562 | unsigned int oldasize, | 560 | unsigned int oldasize, |
563 | unsigned int newasize) { | 561 | unsigned int newasize) { |
564 | oldasize = concretesize(oldasize); | 562 | size_t oldasizeb = concretesize(oldasize); |
565 | newasize = concretesize(newasize); | 563 | size_t newasizeb = concretesize(newasize); |
566 | return luaM_reallocvector(L, t->array, oldasize, newasize, ArrayCell); | 564 | void *a = luaM_reallocvector(L, t->array, oldasizeb, newasizeb, lu_byte); |
565 | return cast(ArrayCell*, a); | ||
567 | } | 566 | } |
568 | 567 | ||
569 | 568 | ||
@@ -747,10 +746,19 @@ Table *luaH_new (lua_State *L) { | |||
747 | } | 746 | } |
748 | 747 | ||
749 | 748 | ||
749 | /* | ||
750 | ** Frees a table. The assert ensures the correctness of 'concretesize', | ||
751 | ** checking its result against the address of the last element in the | ||
752 | ** array part of the table, computed abstractly. | ||
753 | */ | ||
750 | void luaH_free (lua_State *L, Table *t) { | 754 | void luaH_free (lua_State *L, Table *t) { |
751 | unsigned ps = concretesize(luaH_realasize(t)); | 755 | unsigned int realsize = luaH_realasize(t); |
756 | size_t sizeb = concretesize(realsize); | ||
757 | lua_assert((sizeb == 0 && realsize == 0) || | ||
758 | cast_charp(t->array) + sizeb - sizeof(Value) == | ||
759 | cast_charp(getArrVal(t, realsize - 1))); | ||
752 | freehash(L, t); | 760 | freehash(L, t); |
753 | luaM_freearray(L, t->array, ps); | 761 | luaM_freemem(L, t->array, sizeb); |
754 | luaM_free(L, t); | 762 | luaM_free(L, t); |
755 | } | 763 | } |
756 | 764 | ||
@@ -944,7 +952,7 @@ TString *luaH_getstrkey (Table *t, TString *key) { | |||
944 | ** main search function | 952 | ** main search function |
945 | */ | 953 | */ |
946 | int luaH_get (Table *t, const TValue *key, TValue *res) { | 954 | int luaH_get (Table *t, const TValue *key, TValue *res) { |
947 | const TValue *slot; | 955 | const TValue *slot; |
948 | switch (ttypetag(key)) { | 956 | switch (ttypetag(key)) { |
949 | case LUA_VSHRSTR: | 957 | case LUA_VSHRSTR: |
950 | slot = luaH_Hgetshortstr(t, tsvalue(key)); | 958 | slot = luaH_Hgetshortstr(t, tsvalue(key)); |