They're not negligible in the overall count.
This decreases the performance of scripts which use objects with many
properties because the GC threshold remains the same (10K) but it's
reached quicker due to counting more allocations, so GC is more
frequent and wastes more overall time.
Good example of the performance impact is the splay.js v8 bench test,
where this commit reduces its score by a factor of 5.
We're not changing the threshold because it's arbitrary anyway, but the
next commit will change it in a way which allows more proportional
control of the GC overhead.
Only create an iterator for coercible types in OP_ITERATOR, and then
detect the lack of a real iterator in OP_NEXTITER.
Thus we don't need to allocate and push an empty iterator object for
these cases.
Reduce memory use per property by not keeping the properties in two
parallel data structures. Maintaining the order of insertion is not
required by the spec, and is not a very useful feature.
Separate literal/interned and garbage collected string types in js_Value.
js_pushintern/js_tointern are convenience functions to push/pop strings and
automatically intern them (so that the string pointers are guaranteed to be
stable).
js_pushliteral should push stable strings (either interned or actual literals).
js_pushstring will copy the string into garbage collected memory.
The pointer returned by js_tostring is guaranteed to be stable only for as long as
the stack slot it came from remains untouched.
Some uses will always cause a string to be interned:
* Using it as a property name.
* Wrapping it in a new String() object.
* Strings returned by toString().
ToPrimitive must not clobber the stack, so the result has to be unrooted.
* Numbers converted to strings (by js_tostring)
Likewise, we have nowhere to store the temporary string here.
Passing in a scratch buffer to js_tostring could help this problem.
Mostly an issue with array accesses (OP_GETPROP, etc) so an auxiliary
function and we don't have to clutter the API needlessly.
The tail pointer in the linked list head was mismanaged, leading
to using free memory when properties are inserted after deleting
a property such that the tail points to the deleted node.
Only trigger between function calls, during bytecode interpretation,
to allow for intra-function race conditions where an object has been
created but not yet inserted into the stack or environment scope chain.