|
| 1 | +(* TEST |
| 2 | + reference = "${test_source_directory}/immediates.reference" |
| 3 | + * flambda2 |
| 4 | + ** native |
| 5 | + flags = "-extension layouts_alpha" |
| 6 | + ** bytecode |
| 7 | + flags = "-extension layouts_alpha" |
| 8 | + ** native |
| 9 | + flags = "-extension layouts_beta" |
| 10 | + ** bytecode |
| 11 | + flags = "-extension layouts_beta" |
| 12 | + ** native |
| 13 | + flags = "-extension layouts" |
| 14 | + ** bytecode |
| 15 | + flags = "-extension layouts" |
| 16 | + ** setup-ocamlc.byte-build-env |
| 17 | + ocamlc_byte_exit_status = "2" |
| 18 | + *** ocamlc.byte |
| 19 | + compiler_reference = "${test_source_directory}/immediates_disabled.compilers.reference" |
| 20 | + **** check-ocamlc.byte-output |
| 21 | +
|
| 22 | +
|
| 23 | +*) |
| 24 | + |
| 25 | +(* This tests some example uses of immediates in both native and bytecode. *) |
| 26 | + |
| 27 | +(*****************************************) |
| 28 | +(* Prelude: Some immediate types. *) |
| 29 | + |
| 30 | +type a : immediate = A | B | C |
| 31 | + |
| 32 | +(*********************************) |
| 33 | +(* Test 1: higher-order function *) |
| 34 | + |
| 35 | +let[@inline never] test1 (f : ('a : immediate). 'a -> 'a) = |
| 36 | + match f 4 + f 5, f A with |
| 37 | + | x, A -> Printf.printf "Test 1: %d\n" (x + 1) |
| 38 | + | _, (B | C) -> assert false |
| 39 | + |
| 40 | +let () = test1 (fun x -> x) |
| 41 | + |
| 42 | +(****************************************) |
| 43 | +(* Test 2: exercising the write barrier *) |
| 44 | + |
| 45 | +type 'a mut = |
| 46 | + { mutable x : 'a } |
| 47 | + |
| 48 | +type ('a : immediate) mut_imm = |
| 49 | + { mutable x_imm : 'a } |
| 50 | + |
| 51 | +type ('a : immediate64) mut_imm64 = |
| 52 | + { mutable x_imm64 : 'a } |
| 53 | + |
| 54 | +let[@inline never] update_with_write_barrier (type a) (m : a mut) (x : a) = |
| 55 | + m.x <- x |
| 56 | +;; |
| 57 | + |
| 58 | +let[@inline never] update_1 (type (a : immediate)) (m : a mut) (x : a) = |
| 59 | + m.x <- x |
| 60 | +;; |
| 61 | + |
| 62 | +let[@inline never] update_2 (type (a : immediate64)) (m : a mut) (x : a) = |
| 63 | + m.x <- x |
| 64 | +;; |
| 65 | + |
| 66 | +let[@inline never] update_imm (type (a : immediate)) (m : a mut_imm) (x : a) = |
| 67 | + m.x_imm <- x |
| 68 | +;; |
| 69 | + |
| 70 | +let[@inline never] update_imm64 (type (a : immediate64)) (m : a mut_imm64) (x : a) = |
| 71 | + m.x_imm64 <- x |
| 72 | +;; |
| 73 | + |
| 74 | +let[@inline never] test2 x = |
| 75 | + Printf.printf "Test 2: original value: %d\n" x; |
| 76 | + let mut_non_imm = { x = [||] } in |
| 77 | + let mut = { x } in |
| 78 | + let mut_imm = { x_imm = x } in |
| 79 | + let mut_imm64 = { x_imm64 = x } in |
| 80 | + Gc.full_major (); |
| 81 | + (* Exercise the write barrier by making something on the major heap point |
| 82 | + back to the minor heap. |
| 83 | + *) |
| 84 | + update_with_write_barrier mut_non_imm [| x |]; |
| 85 | + Printf.printf " 1. mut_non_imm.x.(0): %d\n" mut_non_imm.x.(0); |
| 86 | + update_with_write_barrier mut x; |
| 87 | + Printf.printf " 2. mut.x: %d\n" mut.x; |
| 88 | + update_1 mut x; |
| 89 | + Printf.printf " 3. mut.x: %d\n" mut.x; |
| 90 | + update_2 mut (x+1); |
| 91 | + update_imm mut_imm (x+2); |
| 92 | + update_imm64 mut_imm64 (x+3); |
| 93 | + Gc.full_major (); |
| 94 | + Printf.printf " 4. mut_non_imm.x.(0): %d\n" mut_non_imm.x.(0); |
| 95 | + Printf.printf " 5. mut.x: %d\n" mut.x; |
| 96 | + Printf.printf " 6. mut_imm.x_imm: %d\n" mut_imm.x_imm; |
| 97 | + Printf.printf " 7. mut_imm64.x_imm64: %d\n" mut_imm64.x_imm64; |
| 98 | +;; |
| 99 | + |
| 100 | +let () = test2 123_456_789_000 |
0 commit comments