mkList: Scrub better
Clearing v.app.right was not enough, because the length field of a list only takes 32 bits, so the most significant 32 bits of v.app.left (a.k.a. v.thunk.env) would remain. This could cause Boehm GC to interpret it as a valid pointer. This change reduces maximum RSS for evaluating the ‘tested’ job in nixos/release-small.nix from 1.33 GiB to 0.80 GiB, and runtime by about 8%.
This commit is contained in:
parent
986fbd6fab
commit
6bb4c0b712
|
@ -455,6 +455,7 @@ Bindings * EvalState::allocBindings(Bindings::size_t capacity)
|
||||||
|
|
||||||
void EvalState::mkList(Value & v, unsigned int length)
|
void EvalState::mkList(Value & v, unsigned int length)
|
||||||
{
|
{
|
||||||
|
clearValue(v);
|
||||||
v.type = tList;
|
v.type = tList;
|
||||||
v.list.length = length;
|
v.list.length = length;
|
||||||
v.list.elems = length ? (Value * *) GC_MALLOC(length * sizeof(Value *)) : 0;
|
v.list.elems = length ? (Value * *) GC_MALLOC(length * sizeof(Value *)) : 0;
|
||||||
|
|
|
@ -96,7 +96,7 @@ struct Value
|
||||||
Value to ensure that the target isn't kept alive unnecessarily. */
|
Value to ensure that the target isn't kept alive unnecessarily. */
|
||||||
static inline void clearValue(Value & v)
|
static inline void clearValue(Value & v)
|
||||||
{
|
{
|
||||||
v.app.right = 0;
|
v.app.left = v.app.right = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,8 +118,8 @@ static inline void mkBool(Value & v, bool b)
|
||||||
|
|
||||||
static inline void mkNull(Value & v)
|
static inline void mkNull(Value & v)
|
||||||
{
|
{
|
||||||
|
clearValue(v);
|
||||||
v.type = tNull;
|
v.type = tNull;
|
||||||
v.app.left = v.app.right = 0; // scrub
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue