Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: handle stack frames in the correct order #1762

Merged
merged 1 commit into from
Dec 24, 2024

Conversation

andreabergia
Copy link
Contributor

Commit f3c64ee removed ObjArray and replaced its usage with standard JDK classes. In Interpreter, in particular, an ArrayDeque is now used to store
cx.previousInterpreterInvocations, which is used to generate the stack frame information. However, there is one place where toArray is done, and the behavior for ObjArray and ArrayDeque are different (swapped).
Unfortunately no tests actually ends up exercising this difference due to the interpreter function peeling optimization done in #1510.

We have discovered this problem because, in ServiceNow's fork, we currently need to disable the function peeling optimization.

I cannot figure out how to write an unit test for this problem, though. Any ideas?


To verify that the behavior are different, I've written this code:

class ObjArrayTest {
	public static void main(String[] args) {
		var objArray = new ObjArray();
		objArray.push(1);
		objArray.push(2);
		objArray.push(3);
		System.out.println("objArray: " + Arrays.toString(objArray.toArray()));
	
		var deque = new ArrayDeque<Integer>();
		deque.push(1);
		deque.push(2);
		deque.push(3);
		System.out.println("ArrayDeque: " + Arrays.toString(deque.toArray()));
	}
}

It prints:

objArray: [1, 2, 3]
ArrayDeque: [3, 2, 1]

Commit f3c64ee removed `ObjArray` and
replaced its usage with standard JDK classes. In `Interpreter`, in
particular, an `ArrayDeque` is now used to store
`cx.previousInterpreterInvocations`, which is used to generate the
stack frame information. However, there is one place where `toArray`
is done, and the behavior for `ObjArray` and `ArrayDeque` are different
(swapped).
Unfortunately no tests actually ends up exercising this difference due
to the interpreter function peeling optimization done in
mozilla#1510.

We have discovered this problem because, in ServiceNow's fork, we
currently need to disable the function peeling optimization.
@gbrail
Copy link
Collaborator

gbrail commented Dec 20, 2024

I could see how this would be a problem! I think this is a fine solution.

As for testing, is there a way to verify the stack traces in interpreted mode? I'm not totally sure where this stuff happens but I figure that we'd get backwards stack traces in this case, would we not?

@gbrail
Copy link
Collaborator

gbrail commented Dec 23, 2024

This is a low-risk enough change that I'm happy to merge it unless someone here has a great testing idea.

@gbrail gbrail added this to the Release 1.8.0 milestone Dec 23, 2024
@andreabergia
Copy link
Contributor Author

As for testing, is there a way to verify the stack traces in interpreted mode? I'm not totally sure where this stuff happens but I figure that we'd get backwards stack traces in this case, would we not?

If we have three recursive call of interpreterLoop, then yeah, we would see them in an incorrect order. However, given the function peeling optimization done in #1510, in most situations we will just have one call of interpreterLoop, with multiple frames stored - and those frames are in the correct order.

So... I am not really sure how to make this explicitly happen in a test.

@gbrail gbrail merged commit d9f7210 into mozilla:master Dec 24, 2024
3 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.

2 participants