Closed
Bug 885183
Opened 13 years ago
Closed 13 years ago
Use Push/Pop instead of explicitly manipulating the stack
Categories
(Core :: JavaScript Engine, enhancement)
Tracking
()
RESOLVED
FIXED
mozilla25
People
(Reporter: sunfish, Unassigned)
References
Details
Attachments
(1 file, 1 obsolete file)
|
12.60 KB,
patch
|
sstangl
:
review+
|
Details | Diff | Splinter Review |
Several places in the code explicitly reserve stack space and use it in a manner equivalent to a Push or Pop. Using Push and Pop allows targets like x86/x64 to optimize them to more efficient code.
| Reporter | ||
Comment 1•13 years ago
|
||
This patch also makes Pop more consistent with Push and adds Push and Pop methods for ARM to match their x86 counterparts.
Attachment #765179 -
Flags: review?(sstangl)
Comment 2•13 years ago
|
||
Comment on attachment 765179 [details] [diff] [review]
a proposed fix
Review of attachment 765179 [details] [diff] [review]:
-----------------------------------------------------------------
::: js/src/ion/x64/Assembler-x64.h
@@ +357,5 @@
> return label;
> }
>
> + void pop(const FloatRegister &src) {
> + addq(Imm32(sizeof(void*)), StackPointer);
This should be sizeof(double). The matching call to push() also needs sizeof(double) instead of (sizeof(void*)).
@@ +358,5 @@
> }
>
> + void pop(const FloatRegister &src) {
> + addq(Imm32(sizeof(void*)), StackPointer);
> + movsd(Operand(StackPointer, 0), src);
This doesn't appear to match the semantics of a pop(). Shouldn't the load be from the top of the stack, and only then the stack pointer modified?
The equivalent push(const FloatRegister &src) code does appear to be written as expected.
::: js/src/ion/x86/Assembler-x86.h
@@ +284,5 @@
> }
>
> + void pop(const FloatRegister &src) {
> + addl(Imm32(sizeof(double)), StackPointer);
> + movsd(Operand(StackPointer, 0), src);
Same issue here.
Attachment #765179 -
Flags: review?(sstangl)
| Reporter | ||
Comment 3•13 years ago
|
||
(In reply to Sean Stangl [:sstangl] from comment #2)
> ::: js/src/ion/x64/Assembler-x64.h
> @@ +357,5 @@
> > return label;
> > }
> >
> > + void pop(const FloatRegister &src) {
> > + addq(Imm32(sizeof(void*)), StackPointer);
>
> This should be sizeof(double). The matching call to push() also needs
> sizeof(double) instead of (sizeof(void*)).
Makes sense.
> @@ +358,5 @@
> > }
> >
> > + void pop(const FloatRegister &src) {
> > + addq(Imm32(sizeof(void*)), StackPointer);
> > + movsd(Operand(StackPointer, 0), src);
>
> This doesn't appear to match the semantics of a pop(). Shouldn't the load be
> from the top of the stack, and only then the stack pointer modified?
Yes, good catch! I'll look into why this isn't causing trouble.
| Reporter | ||
Comment 4•13 years ago
|
||
(In reply to Dan Gohman from comment #3)
> (In reply to Sean Stangl [:sstangl] from comment #2)
> > ::: js/src/ion/x64/Assembler-x64.h
> > @@ +358,5 @@
> > > }
> > >
> > > + void pop(const FloatRegister &src) {
> > > + addq(Imm32(sizeof(void*)), StackPointer);
> > > + movsd(Operand(StackPointer, 0), src);
> >
> > This doesn't appear to match the semantics of a pop(). Shouldn't the load be
> > from the top of the stack, and only then the stack pointer modified?
>
> Yes, good catch! I'll look into why this isn't causing trouble.
It turns out this isn't ever called. I needed it because I needed the generic Pop method for other purposes, and doing that while being consistent with the generic Push entailed having this.
Attached is a new patch which fixes this bug (as well as the sizeof(void *) thing). I left the pop method in, even though it's unused, as it's nice to keep Pop consistent with Push, but I'm happy to implement any fix you like.
Attachment #765179 -
Attachment is obsolete: true
Attachment #766695 -
Flags: review?(sstangl)
Updated•13 years ago
|
Attachment #766695 -
Flags: review?(sstangl) → review+
| Reporter | ||
Comment 5•13 years ago
|
||
Comment 6•13 years ago
|
||
Status: UNCONFIRMED → RESOLVED
Closed: 13 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla25
Comment 7•13 years ago
|
||
(In reply to Dan Gohman from comment #0)
> Several places in the code explicitly reserve stack space and use it in a
> manner equivalent to a Push or Pop. Using Push and Pop allows targets like
> x86/x64 to optimize them to more efficient code.
Is this only for single pushes/pops? Or does this trick also applies for pushing more values. E.g. for saving the registers before calling?
| Reporter | ||
Comment 8•13 years ago
|
||
Yes, push/pop are good for multiple values. Modern processors have stack engines to optimize pushes and pops. Also, they are single-byte instructions, so they're good for code size.
The main downsides are that an explicit stack pointer increment or decrement after a sequence of pushes/pops costs an extra micro-op, and pushing with a memory operand from the stack also incurs an extra micro-op (source: Agner's micro-architecture manual, "Stack engine" sections). Also there is no push/pop for xmm registers.
See also bugs 871811 and 868027.
You need to log in
before you can comment on or make changes to this bug.
Description
•