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)); |
