Skip to content

Commit fd49d41

Browse files
committed
[stack-switching] Code jump error in fast-int
1 parent c3c8eb2 commit fd49d41

2 files changed

Lines changed: 26 additions & 10 deletions

File tree

src/engine/x86-64/X86_64Stack.v3

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,13 @@ class X86_64FrameAccessor(stack: X86_64Stack, sp: Pointer, decl: FuncDecl) exten
10541054
var vfp = (sp + X86_64InterpreterFrame.vfp.offset).load<Pointer>();
10551055
return stack.readValue(vfp, i);
10561056
}
1057+
// Get the value at {vfp + i}.
1058+
// XXX: refactor
1059+
def getValue(i: int) -> Value {
1060+
checkNotUnwound();
1061+
var vfp = (sp + X86_64InterpreterFrame.vfp.offset).load<Pointer>();
1062+
return stack.readValue(vfp, i);
1063+
}
10571064
// Get the value of frame variable {i}.
10581065
def getFrameVar(i: int) -> Value {
10591066
checkNotUnwound();

src/engine/x86-64/X86_64StackCompression.v3

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright 2025 Wizard authors. All rights reserved.
22
// See LICENSE for details of Apache 2.0 license.
33

4+
def valuerep = Target.tagging;
5+
46
// Represents a compressed frame.
57
// {ret_addr} is a pointer into the code of {func}.
68
// TODO: make it more compact
@@ -40,7 +42,13 @@ component X86_64Compression {
4042
collector.reset();
4143
builder.reset();
4244
stack.walk<void>(collector.visitFrame, void, stack.rsp, false);
43-
for (i = collector.frames.length - 1; i >= 0; i--) builder.addFrame(collector.frames[i]);
45+
for (i = collector.frames.length - 1; i >= 0; i--) {
46+
var next_vfp = stack.vsp;
47+
if (i != 0) {
48+
next_vfp = collector.frames[i-1].getFrameAccessor().vfp();
49+
}
50+
builder.addFrame(collector.frames[i], next_vfp);
51+
}
4452

4553
var compressed = X86_64CompressedStack.new();
4654
builder.build(compressed);
@@ -152,27 +160,28 @@ class CompressedStackBuilder {
152160
def values = Vector<Value>.new();
153161

154162
def reset() { frames.clear(); values.clear(); }
155-
def addFrame(frame: TargetFrame) {
163+
def addFrame(frame: TargetFrame, next_vfp: Pointer) {
156164
var accessor = frame.getFrameAccessor();
157165
var func = accessor.func();
158166
var pc = accessor.pc();
159167

160-
var n_locals = accessor.numLocals();
161-
var n_operands = accessor.numOperands();
162-
var n_vals = n_locals + n_operands;
163-
164168
// XXX: a neater way to access ret_addr pointer?
165169
var ret_addr = (frame.sp + (-Pointer.SIZE)).load<Pointer>();
166170

167-
frames.put(CompressedFrame(func, pc, n_vals, ret_addr));
168-
169171
if (Debug.compression) {
170172
var vfp_ptr = accessor.sp + X86_64InterpreterFrame.vfp.offset - Pointer.NULL;
171173
var vfp_val = accessor.vfp() - Pointer.NULL;
172174
Trace.OUT.put2("vfp (at compression) *(0x%x) = 0x%x", vfp_ptr, vfp_val).ln();
173175
}
174-
for (i < n_locals) values.put(accessor.getLocal(i));
175-
for (i < n_operands) values.put(accessor.getOperand(i - n_operands + 1));
176+
177+
var offset = 0;
178+
for (this_vfp = accessor.vfp(); this_vfp < next_vfp; this_vfp += valuerep.slot_size) {
179+
var value = accessor.getValue(offset);
180+
values.put(value);
181+
offset++;
182+
}
183+
184+
frames.put(CompressedFrame(func, pc, offset, ret_addr));
176185
}
177186

178187
def build(to: X86_64CompressedStack) {

0 commit comments

Comments
 (0)