diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-12-20 16:25:20 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-12-20 16:25:20 -0300 |
| commit | ad0ea7813b39e76b377983138ca995189e22054f (patch) | |
| tree | 087e3585a4b4bf5ae65f56b9599bbff9c361a123 /lobject.c | |
| parent | 666e95a66d1a2ceb98bdf320980b3f655264a9c9 (diff) | |
| download | lua-ad0ea7813b39e76b377983138ca995189e22054f.tar.gz lua-ad0ea7813b39e76b377983138ca995189e22054f.tar.bz2 lua-ad0ea7813b39e76b377983138ca995189e22054f.zip | |
GC parameters encoded as floating-point bytes
This encoding brings more precision and a larger range for these
parameters.
Diffstat (limited to 'lobject.c')
| -rw-r--r-- | lobject.c | 53 |
1 files changed, 52 insertions, 1 deletions
| @@ -33,7 +33,7 @@ | |||
| 33 | ** Computes ceil(log2(x)) | 33 | ** Computes ceil(log2(x)) |
| 34 | */ | 34 | */ |
| 35 | int luaO_ceillog2 (unsigned int x) { | 35 | int luaO_ceillog2 (unsigned int x) { |
| 36 | static const lu_byte log_2[256] = { /* log_2[i] = ceil(log2(i - 1)) */ | 36 | static const lu_byte log_2[256] = { /* log_2[i - 1] = ceil(log2(i)) */ |
| 37 | 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, | 37 | 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, |
| 38 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, | 38 | 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, |
| 39 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, | 39 | 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, |
| @@ -49,6 +49,57 @@ int luaO_ceillog2 (unsigned int x) { | |||
| 49 | return l + log_2[x]; | 49 | return l + log_2[x]; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | /* | ||
| 53 | ** Encodes 'p'% as a floating-point byte, represented as (eeeeexxx). | ||
| 54 | ** The exponent is represented using excess-7. Mimicking IEEE 754, the | ||
| 55 | ** representation normalizes the number when possible, assuming an extra | ||
| 56 | ** 1 before the mantissa (xxx) and adding one to the exponent (eeeeexxx) | ||
| 57 | ** to signal that. So, the real value is (1xxx) * 2^(eeeee - 8) if | ||
| 58 | ** eeeee != 0, and (xxx) * 2^-7 otherwise. | ||
| 59 | */ | ||
| 60 | unsigned int luaO_codeparam (unsigned int p) { | ||
| 61 | if (p >= (cast(lu_mem, 0xF) << 0xF) / 128 * 100) /* overflow? */ | ||
| 62 | return 0xFF; /* return maximum value */ | ||
| 63 | else { | ||
| 64 | p = (p * 128u) / 100; | ||
| 65 | if (p <= 0xF) | ||
| 66 | return p; | ||
| 67 | else { | ||
| 68 | int log = luaO_ceillog2(p + 1) - 5; | ||
| 69 | return ((p >> log) - 0x10) | ((log + 1) << 4); | ||
| 70 | } | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | |||
| 75 | /* | ||
| 76 | ** Computes 'p' times 'x', where 'p' is a floating-point byte. | ||
| 77 | */ | ||
| 78 | l_obj luaO_applyparam (unsigned int p, l_obj x) { | ||
| 79 | unsigned int m = p & 0xF; /* mantissa */ | ||
| 80 | int e = (p >> 4); /* exponent */ | ||
| 81 | if (e > 0) { /* normalized? */ | ||
| 82 | e--; | ||
| 83 | m += 0x10; /* maximum 'm' is 0x1F */ | ||
| 84 | } | ||
| 85 | e -= 7; /* correct excess-7 */ | ||
| 86 | if (e < 0) { | ||
| 87 | e = -e; | ||
| 88 | if (x < MAX_LOBJ / 0x1F) /* multiplication cannot overflow? */ | ||
| 89 | return (x * m) >> e; /* multiplying first gives more precision */ | ||
| 90 | else if ((x >> e) < MAX_LOBJ / 0x1F) /* cannot overflow after shift? */ | ||
| 91 | return (x >> e) * m; | ||
| 92 | else /* real overflow */ | ||
| 93 | return MAX_LOBJ; | ||
| 94 | } | ||
| 95 | else { | ||
| 96 | if (x < (MAX_LOBJ / 0x1F) >> e) /* no overflow? */ | ||
| 97 | return (x * m) << e; /* order doesn't matter here */ | ||
| 98 | else /* real overflow */ | ||
| 99 | return MAX_LOBJ; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 52 | 103 | ||
| 53 | static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, | 104 | static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, |
| 54 | lua_Integer v2) { | 105 | lua_Integer v2) { |
