Closed Bug 683694 Opened 13 years ago Closed 12 years ago

Fuse js_IteratorMore with js_IteratorNext and remove the JSOP_MOREITER opcode

Categories

(Core :: JavaScript Engine, defect)

Other Branch
x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 777596

People

(Reporter: jorendorff, Unassigned)

References

Details

Currently, |for (V in EXPR) STMT| compiles to bytecode like this:

      EXPR
      iter 1
      goto L2
  L1: trace
      iternext 2
      setlocal V    ;; or other set instruction(s)
      pop
      STMT
  L2: moreiter
      ifne L1
      enditer

There is duplication of work between moreiter and iternext. This means at least one extra conditional branch (guarding the iterator class).

To eliminate that, there should be a single instruction that computes the new value and puts it on the stack. There are two ways to do it.

Option 1: Keep JSOP_ITERNEXT, turning it into a conditional branch, and eliminate JSOP_ITERMORE. The bytecode would look like this:

      EXPR
      iter 1
  L1: trace
      iternext L2
      setlocal V    ;; or other set instruction(s)
      pop
      STMT
      goto L1
  L2: enditer

Destructuring cases require a JSOP_PICK, but it isn't that bad.

Option 2: Keep moreiter and remove nextiter:

      EXPR
      iter 1
      push
      goto L2
  L1: trace
      setlocal V    ;; or other set instruction(s)
      pop
      STMT
      push
  L2: moreiter
      ifne L1
      enditer

I think those JSOP_PUSH opcodes are necessary because my understanding is that the operand stack depth must be unchanged from a JSOP_GOTO to the subsequent instruction, even though control can't flow that way.

I like option 1.
This is what i thought of, too. Option 1++
BTW, a perk of changing this: we can remove JSContext::iterValue.
Summary: Fuse js_IteratorMore with js_IteratorNext and remove the JSOP_ITERMORE opcode → Fuse js_IteratorMore with js_IteratorNext and remove the JSOP_MOREITER opcode
Assignee: general → evilpies
Depends on: 677957
Stealing.

I think I want the code to look like this:

    EXPR                       obj
    enterfor 1 L2              iter
L1: setlocal V                 iter val
    pop                        iter
    STMT                       iter
L2: next L1                    iter val
    leavefor                   

The operand stack depth thing is a silly constraint; I'll push through that.
Assignee: evilpies → jorendorff
Untaking again. Can't get around to it.
Assignee: jorendorff → general
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.