Currently it can happen so that two blocks with handle scope data in HandleScopeImplementer::blocks_ can be allocated so the end of the first one is with the same address as the start of the second.
If this happens in a situation when the thus aligned blocks are the last used block and the one before it, the following situation can happen:
- You close a HandleScope that is the only one kept in the last block and starts at the beginning of the last block
- CloseScope calls DeleteExtensions
- DeleteExtensions checks whether the last open scope after the current closed one is in the last block, or the last block should be freed
- If the end of the remaining open scope is at the end of the next to last block, DeleteExtensions decides that the handle scope is in the beginning of the last block as well and doesn't free it
Which results at least in an error in the invariant of HandleScope::Extend, which causes DCHECK_LT(limit - current->next, kHandleBlockSize)) to fail in debug and causes a crash in release.
I was able to fix this by changing the check inside DeleteExtensions from
if (reinterpret_cast<Address>(block_start) <= reinterpret_cast<Address>(prev_limit) && reinterpret_cast<Address>(prev_limit) <= reinterpret_cast<Address>(block_limit)) {
to
if (reinterpret_cast<Address>(block_start) < reinterpret_cast<Address>(prev_limit) && reinterpret_cast<Address>(prev_limit) <= reinterpret_cast<Address>(block_limit)) {
However, is it expected two blocks to be able to be aligned this way?
If yes, then this error should be fixed. If not - then maybe the allocation of blocks for handle scope data should be reiterated and modified.
I caught this on Linux, x64 arch.