Skip to content

Introduce interpreter V2 infrastructure.#2438

Merged
gbrail merged 3 commits into
mozilla:masterfrom
aardvark179:aardvark179-interpreterv2-infra-1
Jun 28, 2026
Merged

Introduce interpreter V2 infrastructure.#2438
gbrail merged 3 commits into
mozilla:masterfrom
aardvark179:aardvark179-interpreterv2-infra-1

Conversation

@aardvark179

Copy link
Copy Markdown
Contributor

This is the first chunk of Interpreter V2 work. It introduces the call frame, interpreter data, instructions, operand and other associated classes, but I cut the actual interpreter out of this PR to make it a more manageable size, that will come in the next chunk.

The InstructionSimplification and KnownType classes allow the compiler to replace general instructions such as Add with specialised versions when the typee are known.

I've extracted this from #2426 with some additional tidy up.

@aardvark179 aardvark179 force-pushed the aardvark179-interpreterv2-infra-1 branch 2 times, most recently from ff19dc2 to f609c4b Compare June 22, 2026 21:38

@gbrail gbrail left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks -- I have a bunch of questions but most are stylistic. No way to tell whether this is correct yet ;-)

I COULD suggest a few of the abstractions here like the line number table are great candidates for unit tests and if I were working on this I would insist on it (and let my AI get me started)

Finally, I think we should either bite the bullet and start using something like SLF4J in here like every other Java project on earth, or stick with "System.out" logging like other parts of Rhino.

import org.mozilla.javascript.interpreterv2.InstructionSimplification;
import org.mozilla.javascript.interpreterv2.KnownType;

public abstract class Instruction {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a good reason to make this an abstract class rather than an interface with some default methods? I'm not sure there's a big difference but an interface might unlock some future flexibility.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Invoke virtual has a measurable performance difference from invoke interface because even if the receiver is not known the offset of the method is. This makes for an almost 10% improvement in some benchmarks.

import org.mozilla.javascript.interpreterv2.InstructionSimplification;
import org.mozilla.javascript.interpreterv2.KnownType;

public abstract class Operand {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general I'd love a little bit of Javadoc on some of these generic abstractions that are going to serve us for years in the future. (Which is funny because I've noticed that AI loves to put comments on everything when I DON'T want them!) If people are going to use them to implement new things in the future they or their AI helpers might need some guidance.

I get why this one is abstract and not an interface.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally reasonable, I'll add some java docs.


// Function header with metadata
String functionName = desc.name != null ? desc.name : "<anonymous>";
out.printf(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I see what's going on here. But in general do we want to introduce java.util.Logging now or stickwith our existing "System.out" logging approach? I feel like we should pick one or the other.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this should simply be the same style we use everywhere else. I think this was done here to capture stuff to our logs during development.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, specialising this in the operands makes a small positive difference. I'll get those changes rolled into the appropriate commits.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


static boolean shouldDumpInstructions = RhinoConfig.get("rhino.printICodeV2", false);

public static final int EXCEPTION_TRY_START_SLOT = 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be an enum?

Also we've had trouble with a few of these numeric constants that grow forever and we have started to use a convention like:

int FOO = 1;
int BAR = FOO + 1;
int BAZ = BAR + 1;

The reason is that when we add constants and merge conflicting PRs all the time then the renumbering gets out of hand. Not a big deal here but something to keep in mind for future PRs.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's quite a few things I'd like to turn into enums. I'd thought I'd do this as part of an overall change to clean up our exception handling, but since this is really a duplicate of similar constants in Interpreter, it might be worth trying to do some of that now.

public class LineNumberTable {
private static final Logger LOG = Logger.getLogger(LineNumberTable.class.getName());

private final short[] pcs;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure that each set of offsets will never grow beyond 64k? (And I can help find a few corpuses of JavaScript to test if you'd like.) Or what happens if they do?

If this thing is one per interpreter I'd suggest that there's no advantage to using short here versus int.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Large version and test introduced.


int lineIdx = 0;
for (int i = 0; i < numPcs; i++) {
pcs[i] = (short) (pcsList.get(i) & 0xFFFF);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we trying to avoid overflow here or something with all the bitmasking?

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be the first use of java.util.logging in Rhino. Is it worth it? Or should we stick with System.out like in other parts of the codebase?

Either way, I don't recall in this PR how we're enabling or disabling logging but elsewhere we have used out existing "config" mechanism for this and I think we should use that here too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed,

@aardvark179

Copy link
Copy Markdown
Contributor Author

There should definitely be a unit test for the line number table, and there's one on our fork, but it looks like it's way later on my branch. Let me see about pulling that back to here.

Please do bring up any stylistic stuff. I've been doing some tidy as I've gone, but there's definitely room for more cleanup. Some things I want to tidy up, but want to wait to do properly, e.g. exception handling can definitely be unified and made simpler, but I'd like to do that after we've got v2 in because that will affect v1, v2, and class compilation.

@aardvark179 aardvark179 force-pushed the aardvark179-interpreterv2-infra-1 branch from f609c4b to 5256354 Compare June 23, 2026 11:24
@aardvark179

Copy link
Copy Markdown
Contributor Author

I've done some more clean up on this, and on #2426, still need to put some more tests on there at the right points.

@aardvark179

Copy link
Copy Markdown
Contributor Author

@gbrail I've sent you a message on Slack.

@aardvark179

Copy link
Copy Markdown
Contributor Author

I've pushed a large line number table implementation that can be used if we see anything that doesn't fit in a short during the build process. @andreabergia I'd appreciate your review on this as well.

@aardvark179 aardvark179 force-pushed the aardvark179-interpreterv2-infra-1 branch 2 times, most recently from 36b7eaf to 47beb79 Compare June 24, 2026 13:28
aardvark179 and others added 3 commits June 24, 2026 14:42
Co-authored-by: Jimmy Miller <jimmy.miller@servicenow.com>
Co-authored-by: Cam Walter <cam.n.walter@gmail.com>
@aardvark179 aardvark179 force-pushed the aardvark179-interpreterv2-infra-1 branch from 47beb79 to f10ab31 Compare June 24, 2026 14:04
* <p>Lookup uses binary search on pcs[] with O(log n) performance. Memory usage is approximately 12
* bytes per PC + 4 bytes per line number (no object overhead).
*/
public abstract class LineNumberTable {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this looks reasonable to me. There's a bit of duplication, but I can't think of any way to solve this better sadly.

import java.util.List;
import org.junit.jupiter.api.Test;

class LineNumberTableTest {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be evolved to support both the short and int line number table versions.

@gbrail

gbrail commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

This looks OK to me now -- I'd still like to make sure we're clear going forward on enums versus integers and on Javadoc, but I'm also OK doing that later.

@gbrail

gbrail commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator

Let's merge this now and keep going. Thanks!

@gbrail gbrail merged commit 0de2a42 into mozilla:master Jun 28, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants