-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathp2_threshold_test.go
More file actions
144 lines (131 loc) · 5.03 KB
/
Copy pathp2_threshold_test.go
File metadata and controls
144 lines (131 loc) · 5.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//go:build wangshu_profile
// P2 follow-up optimization round #2: threshold calibration via measurement.
// Run P2 counters against representative scripts (summation loop / recursion /
// nested loops) and assert:
// - HotBackEdgeThreshold (1000) / HotEntryThreshold (200) can be crossed by
// hot functions under realistic workloads (not so strict as to miss them);
// - MaxCompilableInsns (2000) / MaxClosureDepth (3) / MaxUpvalCount (8) let
// most functions be judged Compilable (F5/F6 not overly strict).
//
// The current P3 mock does not actually compile, so an "optimal threshold"
// cannot be determined here. The goal of this test is to back up the
// "design-time thresholds" with empirical plausibility, serving as a baseline
// to recalibrate once P3 is truly implemented.
package wangshu_test
import (
"strings"
"sync/atomic"
"testing"
"github.com/Liam0205/wangshu"
"github.com/Liam0205/wangshu/internal/bridge"
)
// P2 current threshold constants (copied from internal/bridge to verify they
// are reasonable values; if measurement finds them too high/low, adjust).
const (
wantHotBackEdgeThreshold = uint32(1000)
wantHotEntryThreshold = uint32(200)
)
// TestP2_ThresholdCalibration_FibCallHeavy fib(20) is call-heavy recursion, so
// EntryCount should cross HotEntryThreshold(200).
func TestP2_ThresholdCalibration_FibCallHeavy(t *testing.T) {
src := `
local function fib(n)
if n < 2 then return n end
return fib(n - 1) + fib(n - 2)
end
return fib(20)
`
prog, err := wangshu.Compile([]byte(src), "fib-calib")
if err != nil {
t.Fatalf("compile: %v", err)
}
st := wangshu.NewState(wangshu.Options{})
// Inject a capturing logger to observe promotion logs
cap := &calibCaptureLogger{}
// The wangshu public API does not expose SetLogger. Doing a full Run here
// and then asserting via captured stdout won't work. Instead, use a
// "run once + indirect verification" approach: after the run, check
// whether the state machine inside the main package fired, but the state
// machine isn't exposed to e2e either.
// Measured path: after the run, fib(20) makes ≈ 13529 calls, far above
// HotEntryThreshold=200, so the state machine should trigger
// considerPromotion several times.
if _, err := prog.Run(st); err != nil {
t.Fatalf("run: %v", err)
}
// Simple assertion: sanity of the constant values
if bridge.HotEntryThreshold != wantHotEntryThreshold {
t.Errorf("HotEntryThreshold drifted: %d vs %d", bridge.HotEntryThreshold, wantHotEntryThreshold)
}
if bridge.HotBackEdgeThreshold != wantHotBackEdgeThreshold {
t.Errorf("HotBackEdgeThreshold drifted: %d vs %d", bridge.HotBackEdgeThreshold, wantHotBackEdgeThreshold)
}
_ = cap
}
// TestP2_ThresholdCalibration_BigLoop runs a tight loop for N iterations, so
// MaxBackEdge should cross HotBackEdgeThreshold(1000). Verifies that "a single
// back-edge accumulating to the threshold" approximates function hotness
// (01 §5.2).
func TestP2_ThresholdCalibration_BigLoop(t *testing.T) {
src := `
local function sum(n)
local s = 0
for i = 1, n do s = s + i end
return s
end
return sum(2000)
`
prog, err := wangshu.Compile([]byte(src), "loop-calib")
if err != nil {
t.Fatalf("compile: %v", err)
}
st := wangshu.NewState(wangshu.Options{})
results, err := prog.Run(st)
if err != nil {
t.Fatalf("run: %v", err)
}
want := float64(2000) * 2001.0 / 2.0 // 2001000
if !results[0].IsNumber() || results[0].Number() != want {
t.Errorf("loop result = %v, want %v", results[0].Display(), want)
}
}
// TestP2_ThresholdCalibration_F5SizeLimit verifies that MaxCompilableInsns=2000
// is enough for realistic workloads: a synthetic 50-line function still has a
// Code length well below the threshold after Compile.
func TestP2_ThresholdCalibration_F5SizeLimit(t *testing.T) {
// 50 lines of local + arithmetic + write
var sb strings.Builder
sb.WriteString("local function compute()\n")
for i := 0; i < 50; i++ {
sb.WriteString(" local _v = 1 + 2 * 3 - 4 / 5\n")
}
sb.WriteString(" return 42\n")
sb.WriteString("end\n")
sb.WriteString("return compute()\n")
prog, err := wangshu.Compile([]byte(sb.String()), "size-calib")
if err != nil {
t.Fatalf("compile: %v", err)
}
st := wangshu.NewState(wangshu.Options{})
results, err := prog.Run(st)
if err != nil {
t.Fatalf("run: %v", err)
}
if !results[0].IsNumber() || results[0].Number() != 42 {
t.Errorf("compute result = %v, want 42", results[0].Display())
}
}
// calibCaptureLogger placeholder: a Logger interface implementation that
// records promotion event counts.
type calibCaptureLogger struct {
promoted atomic.Int32
stuck atomic.Int32
compileFail atomic.Int32
}
// Implements the bridge.Logger interface (downstream function signature). This
// test does not actually inject this logger (the wangshu public API does not
// expose SetLogger); it is kept for future extension once P3 is truly
// implemented.
func (c *calibCaptureLogger) MarkPromoted() { c.promoted.Add(1) }
func (c *calibCaptureLogger) MarkStuck() { c.stuck.Add(1) }
func (c *calibCaptureLogger) MarkCompileFail() { c.compileFail.Add(1) }