Bill Coffman <[EMAIL PROTECTED]> wrote: > Hello, > * I have the below failed tests.
> t/library/dumper.t 13 3328 13 13 100.00% 1-13 These are fixed (assignment collisions in pcc.c) > t/op/gc.t 1 256 18 1 5.56% 13 Is very similar to the case below - gc_14 (you might read that one first, it's a bit simpler). The variable C<arr2> is assigned to P17. In gc_13.imc:80 the temp C<$P0> is also getting this register. Now when the algorithm backtracks over "y = choose(arr2)" arr2 in P17 is clobbered and we get "shift_pmc() not implemented in class 'Closure'". (You can turn on these print statements to see the flow of operations) There is no sign in the source code, that the control flow from calling choose() the second time to calling the "fail" closure might be a branch target. We basically have a loop (due to the continuation usage), which the register allocator can't be aware of. Inserting a label e.g. lp: y = choose(arr2) and a "branch lp" after the call to the "fail" closure hides the problem, because with that loop, C<arr2> is preserved. (arr1 is still clobbered, but the algorithm doesn't bactrack there again). > t/pmc/sub.t 1 256 78 1 1.28% 78 tb_loop: set P17, P16[K16] ^^^^^ Somewhere a SymReg with set 'K' has slipped into the register allocator. Excluding r->set != 'K' in build_reglist():405 fixes that. Now failing too is t/op/gc_14 (and an exception test, which is the same). These 2 are a bit tricky and I don't know, which result is correct - or better there is probably no answer. We have this recursive method: sub b11 method .param int n .local int n1 n1 = n + 1 newsub $P0, .Exception_Handler, catch set_eh $P0 n = self."b11"(n1) clear_eh catch: .pcc_begin_return .return n .pcc_end_return .end C<n1> is going into the recursive call, C<n> is the return result. Now it depends on the register allocator which register C<n1> and C<n> have. When the allocator isn't really clever then it assigns different registers. So C<n> is preserved when the exception is fired as the recursion limit is hit. The new allocator assigns both C<n1> and C<n> to the same Parrot register. This is technically correct, as the life-span of C<n> ends on the line where it's used as a return result of the recursive method call. Therefore we have a piece of code that in the presence of exceptions may behave differently depending on some implementation details. This is AFAIK very the same, as the gcc warning we had until a few days about a possibly clobbered variable used around setjmp (s. src/inter_run.c:55, and the variable offset. (It's a volatile now) This is totally the same variable usage like above's C<n> and the result depends on register allocation details. > ~Bill leo