More comprehensive recursion guard.

This changes the behaviour of `Thread#recursion_guard` and adds `Thread#recursion_guard_outer` in order to allow more flexibility in how recursion is handled in Ruby code. In addition, recursion detection is now based on a function identifier rather being global to prevent nested guards from different functions interfering with each other.