Smash calls/jumps to point at resumeHelperNoTranslate when TC fills
Summary:
Building upon the previous diffs, if getting a translation fails, and
we know that all future attempts will fail for the process lifetime,
we will call the resumeHelperNoTranslate stub. This behaves like
resumeHelper, but does not bother calling getTranslation and just
checks for existing translations. Now go one step further. We can
smash calls and jumps to call the stub directly, rather than always
going through handleServiceRequest and family.
This is pretty straight-forward for calls. We can just smash the call
instruction with a version of the fcallHelperThunk. For jumps and
retranslate fallthroughs with a translation, it's a little bit more
tricky because vmsp and vmpc aren't synced (and they need to be when
we reach resumeHelperNoTranslate). For these situations, we emit a
tiny stub which syncs the data, then jumps to resumeHelperNoTranslate.
This leaves one extra complication. Usually we can't generate any new
translations because the TC is full. We need to generate these stubs
into the TC, so there might not be space. We emit the stubs into
frozen, which usually has plenty of space even when the others are
full. If frozen happens to be full, we just refrain from generating
the stub and smashing. A lot of the machinery for generating stubs
simply assumed there was enough space and failed oddly if it did
not. Namely, we could throw DataBlockFull from the VAuto dtor, which
terminates the process. Add some machinery to (optionally) detect the
full case and handle it gracefully.
Differential Revision:
D25771143
fbshipit-source-id:
df4b51f85a4a7ef1084550bde8c7feaa925f92b5