See discussion in parent task. Briefly: ParserOutput uses JsonCodec for serialization. If you use ParserOutput::setExtensionData('my-key-here', (object)...) to store a stdClass object, then ParserOutput::getExtensionData('my-key-here) will return a stdClass` *only if this was a fresh parse*, but when the ParserOutput is fetched from ParserCache (subsequent page visits) the value will be unserialized as an array instead of a class and so the return type of ParserOutput::getExtensionData('my-key-here') will be different (an array) and client code will likely crash.
When investigating, some FIXMEs regarding detecting cyclic structures in the serialized objects were also rediscovered, and the order of operations for custom unserializers was found to be quite fragile, putting the responsibility on the implementer of the unserializer to correctly invoke ::newFromJsonArray() on every possibly-object-valued component value. This was altered to make coding unserializers more robust.