Open Bug 1167445 Opened 9 years ago Updated 1 year ago

Improve register allocation on large interpreter loops.


(Core :: JavaScript Engine: JIT, defect, P3)

40 Branch




(Reporter: mbx, Unassigned)


(Blocks 1 open bug)



(1 file)

Attached file bug.tar.gz

Unpack bug.tar.gz and run "js jsshell.js Time".

This test executes the following Java source file in the j2me.js bytecode interpreter.

public static void main(String[] args) {
  long start = JVM.monotonicTimeMillis();
  int s = 0;
  for (int i = 0; i < 1024; i++) {
    for (int j = 0; j < 1024; j++) {
      for (int k = 0; k < 16; k++) {
  System.out.println("Done: " + (JVM.monotonicTimeMillis() - start));

The j2me.js interpreter loop is implemented in the |interpret| function in the bld/j2me.js file. This is a fairly straight forward switch based interpreter. The interpreter state is cached in local variables within the interpreter function and there are only a handful of locals that flow back to the top of the interpreter loop, in most cases it's just |pc| and |sp|. Most other locals live only for the duration of a particular Java bytecode case block.

The generated ION code has a significant number of memory moves (12-14) after each bytecode case block, and I don't understand why that is. There aren't a lot of overlapping live ranges here.
Ccing bhackett since I heard from sunfish that he's currently looking into register allocation.
Blocks: jsperf
Priority: -- → P5
Removing from the jsperf list, since this is listed as P5. The jsperf list is for P1-P3 items.
No longer blocks: jsperf

I'm interested in having a look at this because this affects an interpreter I'm writing in WebAssembly. I could use some help though.

It seems the info at isn't really up to date w.r.t. register allocators since GreedyAllocator and LinearScan no longer exist. I have found js/src/jit/{StupidAllocator,BacktrackingAllocator}; are these all and should I then be looking at the BacktrackingAllocator or are there cases in which it bails out and the StupidAllocator is still used? I'm asking because the code generated for my interpreter is really inefficient (it does not reserve registers for program counter and heap and stack pointers, for instance).

Or is it not really worth the effort at the moment considering IonMonkey will be replaced by cranelift eventually (I don't know the timepath)?

I'm also wondering about the priority assigned here by jonco. I would expect at least P3/P4, especially since WebAssembly is also affected and the code going through the JIT becomes increasingly complex.

Flags: needinfo?(jcoppeard)

(In reply to Camil Staps from comment #3)
Jan will be able to answer your question about register allocation. Yes, our documentation is probably out of date.

I'm also wondering about the priority assigned here by jonco.

I don't remember what criteria I was using to determine this but we can change it if necessary. Again, Jan would be a better judge of this though.

Flags: needinfo?(jcoppeard) → needinfo?(jdemooij)

Ion uses the BacktrackingAllocator for all code nowadays.

It's probably worth downloading the latest Nightly and testing with Cranelift (go to about:config, search for cranelift, toggle the pref, restart). The plan is to use Cranelift as WebAssembly backend and eventually for all Ion code.

Flags: needinfo?(jdemooij)
Priority: P5 → P3

Thanks for the quick responses, both. Cranelift produces similar code, I'll have a look at what I can do there then.

If you plan to do any regalloc work on cranelift pls try to sync with me, since I'll be doing that as well. Bug 1539399 is the root of the bug tree that will eventually be evolving for this and related work.

Blocks: sm-regalloc
Severity: normal → S4
You need to log in before you can comment on or make changes to this bug.