Do you have some ideas to tackle this problem?
What's wrong with my earlier suggestion? During GC_TRAVERSE, you could traverse weak ref entry both when traversing the object itself and the weak map. On the first visit, just mark the entry as visited. On the second visit, continue visiting the value. It means that if any of them are missing, value will not be marked as alive. All of that may happen during regular GC steps, so no extra passes are needed.
And again, jsdisp_t memory overhead is avoidable.