There's a case that was missing in this optimization. We install invalidation
points on a block's dominance frontiers when the block contains som
invalidation instructions. However, if a block is an entry to exception
handler, state is always invalidated. This should be done
since exception handler may recover and proceed with some code that
follows try/catch block. Without this change code after try/catch inherits
state of `try` block, which is invalid, since `catch` is another
source from where we can get there. We can't rely on regular instruction
analysis in `catch` blocks, since we get into `catch` from an unpredictable
point.
When one TeaVM program calls `eval` and code passed to eval is itself generated
with TeaVM, the inner code can throw uncaught Java exception. The outer code could
try to catch this exception as a native JavaScript exception, but this is not possible,
since the exception is marked as Java exception, and inner scripts's Java class
does not inherit java.lang.Throwable of outer script. The solution for each script
to generate own tag (Symbol) and only treat JS exception as Java exception when
this exception has this tag.
When performing young GC, we can encounter some WeakReferences which get into
corresponding ReferenceQueue. In this case queue internal state will be updated.
After it defragmentation phase runs which updates references to relocated objects.
For performance reason, defragmentation phase scans only regions either
marked with write barriers or regions that contain surviving objects in
young generation. However, sometimes a queue can be in neither of these sets,
so we additionally mark regions containing all affected queues.
Add write replace method to lambdas that implement java.io.Serializable
* Peripheral java library classes added as part of the toString method
of SerializedLambda to align functionality with the standard library.
* Test added that checks the SerializedLambda can be returned and that
it is populated with the correct values including it's toString method.