With JSVALUE64 (i.e. 64-bit platforms), JSValue boxes integers, pointers, doubles and a handful of special values using the NaN space. This requires adding or subtracting 2^49 to the encoded double to put things in convenient ranges.
I don't know what the overheads of boxing actually are, but when JSValue holds a capability, this boxing should be unnecessary. We should investigate adding a JSVALUECAP or similar, and implementing a simpler scheme. This would allow a more realistic performance comparison with purecap mode.
Note that this could be quite a big (if not difficult) task; the JSVALUE32_64-or-JSVALUE64 assumption is widespread, and probably also affects JIT code.