diff --git a/src/codegen/compile.ml b/src/codegen/compile.ml index 68db1f394c6..68041a72bd2 100644 --- a/src/codegen/compile.ml +++ b/src/codegen/compile.ml @@ -6583,7 +6583,7 @@ module MakeSerialization (Strm : Stream) = struct (* interval for checking instruction counter *) let idl_limit_interval = 32l (* TUNE *) - let idl_limit = 50_000_000L (* TUNE *) + let idl_limit_factor = 200L (* TUNE *) let idl_pseudo_cost = 100L (* TUNE *) let idl_instruction_counter env = @@ -6604,11 +6604,15 @@ module MakeSerialization (Strm : Stream) = struct G.i (Binary (Wasm.Values.I64 I64Op.Add)) ^^ set_pseudo_instruction_counter env - let reset_instruction_limit env get_rel_buf_opt = + let reset_instruction_limit env get_blob get_rel_buf_opt = get_rel_buf_opt ^^ G.if0 begin (* Candid deserialization *) idl_instruction_counter env ^^ - compile_const_64 idl_limit ^^ + get_blob ^^ + Blob.len env ^^ + G.i (Convert (Wasm.Values.I64 I64Op.ExtendUI32)) ^^ + compile_const_64 idl_limit_factor^^ + G.i (Binary (Wasm.Values.I64 I64Op.Mul)) ^^ G.i (Binary (Wasm.Values.I64 I64Op.Add)) ^^ set_instruction_limit env end @@ -8079,7 +8083,7 @@ module MakeSerialization (Strm : Stream) = struct get_typtbl_ptr ^^ load_unskewed_ptr ^^ Registers.set_typtbl env ^^ get_maintyps_ptr ^^ load_unskewed_ptr ^^ Registers.set_typtbl_end env ^^ get_typtbl_size_ptr ^^ load_unskewed_ptr ^^ Registers.set_typtbl_size env ^^ - Registers.reset_instruction_limit env get_rel_buf_opt + Registers.reset_instruction_limit env get_blob get_rel_buf_opt end ^^ (* set up a dedicated read buffer for the list of main types *) diff --git a/test/bench/ok/bignum.drun-run-opt.ok b/test/bench/ok/bignum.drun-run-opt.ok index 275dce6b630..789680e4738 100644 --- a/test/bench/ok/bignum.drun-run-opt.ok +++ b/test/bench/ok/bignum.drun-run-opt.ok @@ -2,5 +2,5 @@ ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a000000000000000001 ingress Completed: Reply: 0x4449444c0000 debug.print: {cycles = 2_512_723; size = +59_652} ingress Completed: Reply: 0x4449444c0000 -debug.print: {cycles = 107_695_540; size = +1_817_872} +debug.print: {cycles = 107_695_543; size = +1_817_872} ingress Completed: Reply: 0x4449444c0000 diff --git a/test/bench/ok/bignum.drun-run.ok b/test/bench/ok/bignum.drun-run.ok index 964db58e9dd..4179f01800a 100644 --- a/test/bench/ok/bignum.drun-run.ok +++ b/test/bench/ok/bignum.drun-run.ok @@ -2,5 +2,5 @@ ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a000000000000000001 ingress Completed: Reply: 0x4449444c0000 debug.print: {cycles = 2_619_856; size = +59_652} ingress Completed: Reply: 0x4449444c0000 -debug.print: {cycles = 107_890_493; size = +1_817_872} +debug.print: {cycles = 107_890_497; size = +1_817_872} ingress Completed: Reply: 0x4449444c0000 diff --git a/test/run-drun/idl-limits-fine.mo b/test/run-drun/idl-limits-fine.mo new file mode 100644 index 00000000000..30287a2d086 --- /dev/null +++ b/test/run-drun/idl-limits-fine.mo @@ -0,0 +1,39 @@ +import Region "stable-region/Region"; +import Prim "mo:prim"; + +// shows that we can decode up to 15MB of coarse grained data before +// exceeding the candid decoding limit +actor { + + let page : [Nat16] = + Prim.Array_tabulate(65536/4, func i { + Prim.natToNat16(i)}); + + var cnt = 0; + label l while (cnt < 64) { + let a = Prim.Array_tabulate<[Nat16]>(cnt*16, func i {page}); + let b = to_candid (a); + if (b.size() > 10_000_000) break l; + Prim.debugPrint(debug_show {bytes=b.size()}); + let c1 = Prim.performanceCounter(0); + let ?_ = from_candid b : ?[[Nat16]]; + let c2 = Prim.performanceCounter(0); + let diff = c2 - c1; + Prim.debugPrint(debug_show { + bytes = b.size(); + MB = cnt; + instrs = diff; + instr_per_byte = Prim.nat64ToNat diff / b.size() + }); + cnt += 1; + }; + +} + +//SKIP run-low +//SKIP run-ir +//SKIP run +//SKIP ic-ref + + + diff --git a/test/run-drun/idl-limits.mo b/test/run-drun/idl-limits.mo index a1c0eeb19a5..83f7f58a545 100644 --- a/test/run-drun/idl-limits.mo +++ b/test/run-drun/idl-limits.mo @@ -11,11 +11,21 @@ actor { let page = Region.loadBlob(r, 0, Prim.nat64ToNat(pages*65536-1)); var cnt = 0; - while (cnt < 32) { + label l while (cnt < 256) { let a = Prim.Array_tabulate(cnt*16, func i {page}); let b = to_candid (a); + if (b.size() > 10_000_000) break l; + Prim.debugPrint(debug_show {bytes=b.size()}); + let c1 = Prim.performanceCounter(0); let ?_ = from_candid b : ?[Blob]; - Prim.debugPrint(debug_show {MB=cnt}); + let c2 = Prim.performanceCounter(0); + let diff = c2 - c1; + Prim.debugPrint(debug_show { + bytes = b.size(); + MB = cnt; + instrs = diff ; + instr_per_byte = Prim.nat64ToNat diff / b.size() + }); cnt += 1; }; diff --git a/test/run-drun/ok/idl-limits-fine.drun-run.ok b/test/run-drun/ok/idl-limits-fine.drun-run.ok new file mode 100644 index 00000000000..38bed358d0d --- /dev/null +++ b/test/run-drun/ok/idl-limits-fine.drun-run.ok @@ -0,0 +1,42 @@ +ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 +debug.print: {bytes = 12} +debug.print: {MB = 0; bytes = 12; instr_per_byte = 194; instrs = 2_331} +debug.print: {bytes = 524_348} +debug.print: {MB = 1; bytes = 524_348; instr_per_byte = 86; instrs = 45_447_595} +debug.print: {bytes = 1_048_684} +debug.print: {MB = 2; bytes = 1_048_684; instr_per_byte = 86; instrs = 90_892_859} +debug.print: {bytes = 1_573_020} +debug.print: {MB = 3; bytes = 1_573_020; instr_per_byte = 86; instrs = 136_338_331} +debug.print: {bytes = 2_097_356} +debug.print: {MB = 4; bytes = 2_097_356; instr_per_byte = 86; instrs = 181_783_595} +debug.print: {bytes = 2_621_692} +debug.print: {MB = 5; bytes = 2_621_692; instr_per_byte = 86; instrs = 227_228_859} +debug.print: {bytes = 3_146_028} +debug.print: {MB = 6; bytes = 3_146_028; instr_per_byte = 86; instrs = 272_674_331} +debug.print: {bytes = 3_670_364} +debug.print: {MB = 7; bytes = 3_670_364; instr_per_byte = 86; instrs = 318_119_595} +debug.print: {bytes = 4_194_701} +debug.print: {MB = 8; bytes = 4_194_701; instr_per_byte = 86; instrs = 363_564_898} +debug.print: {bytes = 4_719_037} +debug.print: {MB = 9; bytes = 4_719_037; instr_per_byte = 86; instrs = 409_010_162} +debug.print: {bytes = 5_243_373} +debug.print: {MB = 10; bytes = 5_243_373; instr_per_byte = 86; instrs = 454_455_426} +debug.print: {bytes = 5_767_709} +debug.print: {MB = 11; bytes = 5_767_709; instr_per_byte = 86; instrs = 499_900_898} +debug.print: {bytes = 6_292_045} +debug.print: {MB = 12; bytes = 6_292_045; instr_per_byte = 86; instrs = 545_346_162} +debug.print: {bytes = 6_816_381} +debug.print: {MB = 13; bytes = 6_816_381; instr_per_byte = 86; instrs = 590_791_426} +debug.print: {bytes = 7_340_717} +debug.print: {MB = 14; bytes = 7_340_717; instr_per_byte = 86; instrs = 636_236_690} +debug.print: {bytes = 7_865_053} +debug.print: {MB = 15; bytes = 7_865_053; instr_per_byte = 86; instrs = 681_682_162} +debug.print: {bytes = 8_389_389} +debug.print: {MB = 16; bytes = 8_389_389; instr_per_byte = 86; instrs = 727_127_426} +debug.print: {bytes = 8_913_725} +debug.print: {MB = 17; bytes = 8_913_725; instr_per_byte = 86; instrs = 772_572_690} +debug.print: {bytes = 9_438_061} +debug.print: {MB = 18; bytes = 9_438_061; instr_per_byte = 86; instrs = 818_018_162} +debug.print: {bytes = 9_962_397} +debug.print: {MB = 19; bytes = 9_962_397; instr_per_byte = 86; instrs = 863_463_218} +ingress Completed: Reply: 0x4449444c0000 diff --git a/test/run-drun/ok/idl-limits-fine.tc.ok b/test/run-drun/ok/idl-limits-fine.tc.ok new file mode 100644 index 00000000000..50d12e41c25 --- /dev/null +++ b/test/run-drun/ok/idl-limits-fine.tc.ok @@ -0,0 +1,5 @@ +idl-limits-fine.mo:19.10-19.12: warning [M0145], this pattern of type + ?[[Nat16]] +does not cover value + null +idl-limits-fine.mo:1.8-1.14: warning [M0194], unused identifier Region (delete or rename to wildcard `_` or `_Region`) diff --git a/test/run-drun/ok/idl-spacebomb.drun-run.ok b/test/run-drun/ok/idl-spacebomb.drun-run.ok index 2f5d216cca3..ca8b2fee94c 100644 --- a/test/run-drun/ok/idl-spacebomb.drun-run.ok +++ b/test/run-drun/ok/idl-spacebomb.drun-run.ok @@ -47,8 +47,7 @@ debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: ID debug.print: {function = "vec_null_subtyping"; hex = "4449444C016D7F0100FFFF3F"} debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: IDL error: exceeded instruction limit debug.print: {function = "vec_null_subtyping"; hex = "4449444C016D7F010080BF18"} -debug.print: 40_775_934 -debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: assertion failed at idl-spacebomb.mo:40.5-40.41 +debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: IDL error: exceeded instruction limit debug.print: {function = "vec_reserved_subtyping"; hex = "4449444C016D7001008094EBDC03"} debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: IDL error: exceeded instruction limit debug.print: {function = "vec_reserved_subtyping"; hex = "4449444C016D70010080ADE204"} @@ -56,8 +55,7 @@ debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: ID debug.print: {function = "vec_reserved_subtyping"; hex = "4449444C016D700100FFFF3F"} debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: IDL error: exceeded instruction limit debug.print: {function = "vec_reserved_subtyping"; hex = "4449444C016D70010080BF18"} -debug.print: 40_775_934 -debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: assertion failed at idl-spacebomb.mo:40.5-40.41 +debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: IDL error: exceeded instruction limit debug.print: {function = "zero_sized_record_subtyping"; hex = "4449444C046C03007F010102026C0100706C006D0001038094EBDC03"} debug.print: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: IDL error: exceeded instruction limit debug.print: {function = "zero_sized_record_subtyping"; hex = "4449444C046C03007F010102026C0100706C006D00010380ADE204"}