Some complications:
When you input a line to be interpreted like
100 if X then gosub 5000
But 5000 does not exist yet, you are spaghetti coding...
Maybe x does not have any assigned value or data type yet.
If we don't index now, are we going wait till someone
types "run" or executes a line directly from the prompt?
if we do index now to speed things up later, how will we
know the last instance of "100" or "X" or "5000" gets
removed?
What entry do we make in the master index of "things"?
Assuming these things may include lines of basic code,
strings, and other variables we want to handle by name
or line number.
We want to find quickly, and use to strategically identify
garbage collection potential when the need for collection
arises.
How much static space do we burn on the index of things
that may change in size? Which details besides label,
location, and length are useful enough to justify indexing?
Should we attempt to index empty space when a variable
shrinks? Or just index the variable's largest historical
size along with its current size? How do we identify those
variables that change in size most frequently, and should
we avoid cleaning them, or even deliberately pad them?
When do we clean up the entire mess? or is it better to
defrag only enough free space to squeeze in something that
cannot be otherwise jammed sideways into an existing hole?
Purposeful delays and waiting for "input" seem good targets
that we might exploit to proactively clean up some of the
mess. There is no assurance any basic program will have such
deadtime.
Sorry this is not an answer, but the original question seems
to invite some brainstorming towards a better scheme. We need
a clear strategy that requires defining the entire problem.