-
-
Notifications
You must be signed in to change notification settings - Fork 761
Description
This manifests as something like:
Assert fail: jsvLockAgain jsvar.c ... (jsvGetLocks(var) < JSV_LOCK_MAX)
When an object is used from the interpreter loads of times and it's being run in a non-release build (so there are asserts)
a = {};
function recurse(n,z) {
if (n<20) recurse(n+1,z,z,z,z,z,z);
}
recurse(0,a);
As seen in #2615 - I thought we had an issue open for this already, but it seems not.
Background
We count the number of locks per var (the max number depends on how many variables we want to be able to reference as per https://www.espruino.com/Internals#variable-storage ) - if you do something like referencing the same object 80 times then the lock counter overflows and wraps over. In reality it's not that big a deal - as long as the lock counter is nonzero you're fine - and it's very unlikely that you'll reference something just enough times to make the lock count overflow and be zero and also have that variable with no references.
It's not ideal, but it's worked pretty well so far. The alternative would be keeping the lock counter static at the maximum allowed value if it hit it, which would avoid issues but would introduce a variable that then couldn't ever be freed.
Fix
In retrospect for the small amount of times this happens I think it's probably worth having the memory leak and small speed impact of keeping the lock counter as max if it ever gets there. It shouldn't be massive.
We already do this for references, but it's not such a big deal there as GC can free things even if the references are nonzero. It can't free locked vars though as it has no way of checking the actual interpreter code to see where a pointer is used.