Reentrant code is typically not used on PICs, it is generally incompatible with the Overlay memory allocation commonly used.
Basically say you have a task which uses a variable. For some reason you think you have a need for the task to call itself- like the task adds a+b and you think it'll be nifty if you have a carry for the adder task to call itself, but this time with the carry digits as arguments to add. Maybe that'll result in a carry too and thus that instance may have to call itself again.
Well that's often unnecessarily stressful on the calling stack. We only have so much space for return addresses. But what about that variable we used? Do we want the second instance to use the same memory location for its variable? If not we have to give up fixed memory locations for these variables (part of Overlay) and have some sort of memory stack to dynamically allocate memory for these variables.
The C compilers just won't let you do this reentrant stuff. The problems are significant and people almost never need it.
The core will not jump to the ISR while it's executing the ISR. It's already doing it. The user could make code in the ISR that called the ISR but it would be complete nonsense. Thus reentrancy is a non-issue.