aboutsummaryrefslogtreecommitdiff
path: root/lobject.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-12-20 16:25:20 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2023-12-20 16:25:20 -0300
commitad0ea7813b39e76b377983138ca995189e22054f (patch)
tree087e3585a4b4bf5ae65f56b9599bbff9c361a123 /lobject.c
parent666e95a66d1a2ceb98bdf320980b3f655264a9c9 (diff)
downloadlua-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.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/lobject.c b/lobject.c
index 9cfa5227..4091b9d7 100644
--- a/lobject.c
+++ b/lobject.c
@@ -33,7 +33,7 @@
33** Computes ceil(log2(x)) 33** Computes ceil(log2(x))
34*/ 34*/
35int luaO_ceillog2 (unsigned int x) { 35int 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*/
60unsigned 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*/
78l_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
53static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, 104static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
54 lua_Integer v2) { 105 lua_Integer v2) {