|
3 | 3 | # Tests for extending the MoarVM specializer to guard on new kinds of things
|
4 | 4 | # from NQP.
|
5 | 5 |
|
6 |
| -plan(53); |
| 6 | +plan(57); |
7 | 7 |
|
8 | 8 | {
|
9 | 9 | # Minimal test case: under no threaded contention, should run the resolve just
|
@@ -264,6 +264,54 @@ plan(53);
|
264 | 264 | ok($times-run == 1, 'Ran the plugin another time if we had to deopt due to type object guard failure');
|
265 | 265 | }
|
266 | 266 |
|
| 267 | +# Deopt by attribute guard. |
| 268 | +{ |
| 269 | + my class TestWithAttr { |
| 270 | + has $!attr; |
| 271 | + method new($attr) { |
| 272 | + my $self := nqp::create(self); |
| 273 | + nqp::bindattr($self, TestWithAttr, '$!attr', $attr); |
| 274 | + $self |
| 275 | + } |
| 276 | + } |
| 277 | + my $times-run := 0; |
| 278 | + nqp::speshreg('nqp', 'attr-type-and-definedness-counter-spesh', -> $obj { |
| 279 | + nqp::speshguardtype($obj, TestWithAttr); |
| 280 | + nqp::speshguardconcrete($obj); |
| 281 | + my $attr := nqp::speshguardgetattr($obj, TestWithAttr, '$!attr'); |
| 282 | + nqp::speshguardtype($attr, $attr.WHAT); |
| 283 | + nqp::isconcrete($attr) |
| 284 | + ?? nqp::speshguardconcrete($attr) |
| 285 | + !! nqp::speshguardtypeobj($attr); |
| 286 | + ++$times-run |
| 287 | + }); |
| 288 | + my @obj; |
| 289 | + sub test() { |
| 290 | + nqp::speshresolve('attr-type-and-definedness-counter-spesh', |
| 291 | + TestWithAttr.new(nqp::atpos(@obj, 0))) |
| 292 | + } |
| 293 | + |
| 294 | + my class A { } |
| 295 | + sub hot-loop() { |
| 296 | + my int $i := 0; |
| 297 | + my int $total := 0; |
| 298 | + while $i++ < 1_000_000 { |
| 299 | + $total := $total + test(); |
| 300 | + } |
| 301 | + return $total; |
| 302 | + } |
| 303 | + @obj[0] := A; |
| 304 | + my $result := hot-loop(); |
| 305 | + ok($times-run == 1, 'Only ran the attribute type-based plugin once in hot code'); |
| 306 | + ok($result == 1_000_000, 'Correct result from hot code'); |
| 307 | + |
| 308 | + my class B { } |
| 309 | + @obj[0] := B; |
| 310 | + ok(test() == 2, 'Correct result when we trigger attr type deopt'); |
| 311 | + ok($times-run == 2, |
| 312 | + 'Ran the plugin another time if we had to deopt due to attr type guard failure'); |
| 313 | +} |
| 314 | + |
267 | 315 | # Recursive spesh plugin setup
|
268 | 316 | {
|
269 | 317 | nqp::speshreg('nqp', 'rec-a', -> $code {
|
|
0 commit comments