Setup proper copy constructor for VMException

The tests depended on a properly working copy constructor, so we create
a proper one that also duplicates the reason and backtrace vector as
needed.
Also mark data as freed when no data pointer is associated

We should mark this data as freed anyway for this case so we don't crash
if we encounter double free's due to issues such as this:

https://github.com/sparklemotion/nokogiri/pull/895

Fixes #2340
Use faster handle validation mechanism

The handle allocator already has a faster way of validating whether a
handle is valid, so we should use that instead of iterating all handles.

This improves performance for JSON entries, since they use
rb_gc_mark_maybe extensively. In a Sidekiq demo app, this validation
took around 3% of the total runtime, with this change it was reduced to
almost nothing.
Track fiber data in a set instead of list

When deleting an item, having a list was having bad performance effects
since the whole list needs to be walked. Since this data structure is
only used to add and remove entries a set is a much better data
structure than a list for this purpose.