Closed Bug 818138 Opened 7 years ago Closed 7 years ago

enterFakeExitFrame can do a better job with the assembly it generates

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set

Tracking

()

RESOLVED FIXED
mozilla20

People

(Reporter: bzbarsky, Assigned: evilpie)

References

(Blocks 1 open bug)

Details

(Whiteboard: [js:t])

Attachments

(1 file)

Right now, for something like enterFakeExitFrame(ION_FRAME_DOMGETTER) we get codegen like so on x86-84:

> movabsq    $0x1, %r11                   #bz Stick 1 in %r11
> push       %r11                         #bz Push 1
> movabsq    $0x0, %r11                   #bz Stick 0 in %r11
> push       %r11                         #bz Push 0

The problem is that it's not clear to me that the codeVal argument is always something that can be pushed as an immediate...  But null sure is.
Blocks: 817937
Assignee: general → evilpies
So what buildFakeExitFrame (which ends up with a pushl) does is this:

364         Push(Imm32(descriptor));

while enterFakeExitFrame does this:

        Push(ImmWord(uintptr_t(codeVal)));
        Push(ImmWord(uintptr_t(NULL)));

The problem is that presumably fake and real exit frames need to match size, and real exit frames have:

        exitCodePatch_ = PushWithPatch(ImmWord(-1));
        // Push VMFunction pointer, to mark arguments.
        Push(ImmWord(f));

which is in fact pushing two pointer-sized values.
Pushing pointer-sized values is fine; Push (or similar) just needs to be taught about the sign-extension semantics when pushing immediates.

Wonder what the codegen looks like on x86.
Looks like pushl on x86-64 will in fact sign-extend 32-bit immediates to a 64-bit value.

I'm building a 32-bit build at the moment to answer that last question.  ;)
In a 32-bit build, this bit of asm looks like so:

pushl      $0x1
pushl      $0x0
Attachment #688363 - Flags: review?(jdemooij)
Comment on attachment 688363 [details] [diff] [review]
optimize push(immword) to push(imm32) sometimes

Review of attachment 688363 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/ion/IonMacroAssembler.h
@@ +491,5 @@
>          exitCodePatch_ = PushWithPatch(ImmWord(-1));
>          // Push VMFunction pointer, to mark arguments.
>          Push(ImmWord(f));
>      }
> +    void enterFakeExitFrame(IonCode *codeVal = NULL) {

Pre-existing, but can you add a comment to this method like this:

// Note: use ImmWord, not ImmGCPtr, since codeVal is not a valid IonCode
// pointer but a magic value like ION_FRAME_DOMGETTER.
Attachment #688363 - Flags: review?(jdemooij) → review+
Comment on attachment 688363 [details] [diff] [review]
optimize push(immword) to push(imm32) sometimes

Review of attachment 688363 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/ion/x64/Assembler-x64.h
@@ +290,5 @@
>      }
>      void push(const ImmWord ptr) {
> +        // We often end up with ImmWords that actually fit into int32.
> +        // Be aware of the sign extension behavior.
> +        if (ptr.value <= INT32_MAX) {

This needs to check for ptr.value >= INT32_MIN as well, otherwise pointers whose numeric values are < INT32_MIN will be corrupted.  Or is the pointer guaranteed to fit into a 32-bit address space?  (Probably not a bad idea to check anyway.)
Whiteboard: [js:t]
ptr.value is an uintptr_t, so it can never be negative. So this should result in an unsigned compare.
https://hg.mozilla.org/mozilla-central/rev/d148382e074c
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla20
You need to log in before you can comment on or make changes to this bug.