From ce75b6a61cbeda05dfc5afa99ef00ec5d9948a5d Mon Sep 17 00:00:00 2001 From: Oleg Pliss Date: Sun, 2 Jul 2023 02:01:18 -0700 Subject: [PATCH 01/14] Introduce stanza debug command --- compiler/main.stanza | 60 ++++++++++++++++++++++++++++++++++++++++- compiler/repl.stanza | 46 ++++++++++++++++++++++--------- stanza.proj | 1 + tests/dev-linker.stanza | 7 ++--- 4 files changed, 97 insertions(+), 17 deletions(-) diff --git a/compiler/main.stanza b/compiler/main.stanza index 427c43687..8b213f455 100644 --- a/compiler/main.stanza +++ b/compiler/main.stanza @@ -271,7 +271,7 @@ defn ensure-proper-verbose-level! (cmd-args:CommandArgs) : val setting:Maybe = cmd-args["verbose"] if not empty?(setting) : match(to-int(value!(setting))) : - (v:Int) : + (v:Int) : if v < 1 or v > 10 : throw(ArgParseError("The '-verbose' flag requires an integer between 1 and 10.")) (f:False) : @@ -921,6 +921,63 @@ defn run-test-command () : flags, run-tests-msg, intercept-no-match-exceptions(run-tests)) +;============================================================ +;====================== Debug Command ======================= +;============================================================ + +defn debug-command () : + ;Flags + val flags = [ + Flag("pkg", ZeroOrMoreFlag, OptionalFlag, + "The set of additional directories to look in for .pkg files.") + Flag("flags", ZeroOrMoreFlag, OptionalFlag, + "The set of compile-time flags to be set before beginning execution.") + common-stanza-flag("pkg-cache") + common-stanza-flag("verbose") + common-stanza-flag("macros") + Flag("-", AllRemainingFlag, OptionalFlag, + "If provided, the remaining arguments after this flag will be set as the command line arguments for the REPL session.")] + + ;Verify that the passed options are good. + defn verify-args (cmd-args:CommandArgs) : + ensure-proper-verbose-level!(cmd-args) + + ;Main action for command + val launch-msg = "Debug Stanza files directly using the Stanza virtual machine." + defn launch-run (cmd-args:CommandArgs) : + within run-with-verbose-flag(cmd-args) : + read-config-file() + + ;Add pkg directories to pkg-dirs + for dir in get?(cmd-args, "pkg", []) do : + STANZA-PKG-DIRS = cons(dir, STANZA-PKG-DIRS) + + ;Add flags + for flag in get?(cmd-args, "flags", []) do : + add-flag(to-symbol(flag)) + + ;Add platform flag + add-flag(platform-flag(OUTPUT-PLATFORM)) + + ;Setup command line arguments. + val new-cmd-args = to-tuple $ cat(["run"], get?(cmd-args, "-", [])) + set-command-line-arguments(new-cmd-args) + + ;Run in REPL + debug-in-repl(args(cmd-args), + get?(cmd-args, "macros", []), + get?(cmd-args, "pkg-cache", false)) + + ;Command definition + Command( + name = "debug", + argtype = AtLeastOneArg, + arg-description = "the .stanza/.proj input files or Stanza package names to execute in the virtual machine.", + flags = flags, + description = launch-msg, + verify = verify-args, + action = intercept-no-match-exceptions(launch-run)) + ;============================================================ ;================= Dependency Analysis Command ============== ;============================================================ @@ -1181,6 +1238,7 @@ add-stanza-command(install-command()) add-stanza-command(compile-command()) add-stanza-command(repl-command()) add-stanza-command(run-command()) +add-stanza-command(debug-command()) add-stanza-command(compile-test-command()) add-stanza-command(compile-macros-command()) add-stanza-command(run-test-command()) diff --git a/compiler/repl.stanza b/compiler/repl.stanza index 4ffe08a21..99145bd1a 100644 --- a/compiler/repl.stanza +++ b/compiler/repl.stanza @@ -252,7 +252,7 @@ public defn register-initial-repl-syntax (name:Symbol) : ;============================================================ ;==================== REPL Initial Load ===================== ;============================================================ -public val REPL-INITIAL-LOAD-PACKAGES = Vector() +public val REPL-INITIAL-LOAD-PACKAGES = to-vector([`core]) public defn register-initial-repl-package (name:Symbol|String) : add(REPL-INITIAL-LOAD-PACKAGES, name) @@ -280,7 +280,8 @@ defmulti use-syntax (repl:REPL, inputs:Tuple, add-to-existing?:True|Fals defmulti shutdown (repl:REPL) -> False public defn REPL (macro-plugins:Tuple, - pkg-cache-dir:String|False) : + pkg-cache-dir:String|False, + debug?:True|False) : ;============================================================ ;===================== REPL State =========================== ;============================================================ @@ -352,7 +353,7 @@ public defn REPL (macro-plugins:Tuple, if not empty?(inputs*) : within intercept-errors() : val vmpackages = within log-time(REPL-COMPILE-TO-VMPACKAGES) : - compile-to-vmpackages(to-tuple(inputs*), live-recs, false) + compile-to-vmpackages(to-tuple(inputs*), live-recs, false, debug?) load-dynamic-libraries(dylibs, proj-manager(), vmpackages) within log-time(REPL-LOAD-INTO-VM) : load(vm, vmpackages, false) @@ -384,7 +385,7 @@ public defn REPL (macro-plugins:Tuple, defn update-files () : within intercept-errors() : val inputs = changed-files(file-env) - val vmpackages = compile-to-vmpackages(inputs, live-recs, false) + val vmpackages = compile-to-vmpackages(inputs, live-recs, false, debug?) load-dynamic-libraries(dylibs, proj-manager(), vmpackages) load(vm, vmpackages, false) init-packages(vmpackages) @@ -394,7 +395,7 @@ public defn REPL (macro-plugins:Tuple, within log-time(REPL-RELOAD) : within intercept-errors() : val inputs = changed-files(file-env) - val vmpackages = compile-to-vmpackages(inputs, {[]}, false) + val vmpackages = compile-to-vmpackages(inputs, {[]}, false, debug?) load-dynamic-libraries(dylibs, proj-manager(), vmpackages) load(vm, vmpackages, false) @@ -417,7 +418,7 @@ public defn REPL (macro-plugins:Tuple, defn load-repl (form) : within intercept-errors() : val ipackage = to-ipackage(form) - val vmpackages = compile-to-vmpackages([ipackage], live-recs, name(ipackage)) + val vmpackages = compile-to-vmpackages([ipackage], live-recs, name(ipackage), debug?) load-dynamic-libraries(dylibs, proj-manager(), vmpackages) load(vm, vmpackages, false) register-repl(repl-env, name(ipackage)) @@ -442,7 +443,8 @@ public defn REPL (macro-plugins:Tuple, defn compile-to-vmpackages (inputs:Tuple, live-recs: Tuple -> Tuple, - repl-package?:Symbol|False) -> Tuple : + repl-package?:Symbol|False, + debug?:True|False) -> Tuple : ;Compile to epackages val proj-manager = proj-manager() set-proj-manager(macroexpander, proj-manager) @@ -466,6 +468,8 @@ public defn REPL (macro-plugins:Tuple, false defmethod macroexpander (this) : macroexpander + defmethod debug? (this) : + debug? ;Register file associations with file environment. do(register{file-env, _}, pkgstamps(result)) @@ -496,7 +500,7 @@ public defn REPL (macro-plugins:Tuple, val lowered = within log-time(REPL-LOWER-TO-UNOPTIMIZED) : lower-unoptimized(p) within log-time(REPL-COMPILE-LOWERED) : - compile(lowered, false) + compile(lowered, debug?) vprintln("REPL: Done Compiling EPackage %_ to VMPackage." % [name(p)]) if name(p) != repl-package? : save-when-appropriate(pkgsaver, StdPkg(vmp, false, false)) @@ -534,7 +538,6 @@ public defn REPL (macro-plugins:Tuple, ;============================================================ ;===================== REPL Structure ======================= ;============================================================ - load-files([`core]) load-files(to-tuple(REPL-INITIAL-LOAD-PACKAGES)) new REPL : defmethod load-files (this, inputs:Tuple, go-inside?:True|False) : @@ -1007,7 +1010,7 @@ public defn repl (args:Tuple, style:TerminalStyle, macro-plugins:Tuple, pkg-cache-dir:String|False) : - val repl = REPL(macro-plugins, pkg-cache-dir) + val repl = REPL(macro-plugins, pkg-cache-dir, false) ;Create a LoadExp expression out of the command line ;arguments. And execute them in the REPL. @@ -1068,7 +1071,7 @@ public defn run-in-repl (args:Tuple, macro-plugins:Tuple, pkg-cache-dir:String|False) : val repl = within log-time(REPL-CREATION) : - REPL(macro-plugins, pkg-cache-dir) + REPL(macro-plugins, pkg-cache-dir, false) try: within log-time(REPL-EXP-EVALUATION) : eval-exp(repl, make-load-exp(args, false)) @@ -1076,7 +1079,24 @@ public defn run-in-repl (args:Tuple, shutdown(repl) defn make-load-exp (args:Tuple, go-inside?:True|False) : - val inputs = for a in args map : + Load(make-inputs(args), go-inside?) + +defn make-inputs (args:Tuple) : + for a in args map : if index-of-char(a, '.') is Int : a else : to-symbol(a) - Load(inputs, go-inside?) \ No newline at end of file + +;============================================================ +;=================== Debug Immediately ====================== +;============================================================ + +;Debug the given arguments in the virtual +;machine. Implements the 'stanza debug' command. +public defn debug-in-repl (args:Tuple, + macro-plugins:Tuple, + pkg-cache-dir:String|False) : + val repl = REPL(macro-plugins, pkg-cache-dir, true) + try: + load-files(repl, make-inputs(args), false) + finally: + shutdown(repl) diff --git a/stanza.proj b/stanza.proj index 1804eca53..3a6c8dfe3 100644 --- a/stanza.proj +++ b/stanza.proj @@ -1,4 +1,5 @@ include "examples/stanza.proj" +include "build-stanza.proj" package stz/line-noise-prompter requires : ccfiles: diff --git a/tests/dev-linker.stanza b/tests/dev-linker.stanza index 646f72b84..40e544e34 100644 --- a/tests/dev-linker.stanza +++ b/tests/dev-linker.stanza @@ -67,7 +67,7 @@ defn conan-vars (platform:Symbol, val system-dir = to-string("%_/system" % [build-dir]) val conan-root = to-string("%_/.conan" % [projdir(stmt)]) [`conan-system-includes => system-dir - `conan-root => conan-root] + `conan-root => conan-root] ;Retrieve a bunch of dummy package managers for testing. defn manager-infos (names:Tuple) -> Tuple : @@ -88,7 +88,7 @@ defn read-example-proj (filenames:Tuple) -> ProjFile : ;manager-infos(get?(cmdargs, "package-managers", [])) defmethod package-manager-variables (this, params:ForeignPackageParamsStmt, platform:Symbol) : switch(package-manager(params)) : - `conan : conan-vars(platform, params) + `conan : conan-vars(platform, params) read-proj-files(filenames, platform, env) defn LinkEnv () : @@ -172,13 +172,14 @@ defn try-link (cmdargs:CommandArgs) : val proj-files = cmdargs["proj"] val build-settings = BuildSettings( BuildPackages(packages, false), ;inputs - [], ;vm-packages + [], ;vm-packages `os-x, ;platform AsmFile("myprog.s", false) ;assembly "myprog", ;output false, ;external-dependencies false, ;pkg-dir false, ;optimize? + false, ;debug? [], ;ccfiles [], ;ccflags [], ;flags From 08c5fcd947ff476992a6fa6fb4ba94ca09a84e8c Mon Sep 17 00:00:00 2001 From: Oleg Pliss Date: Fri, 7 Jul 2023 10:40:53 -0700 Subject: [PATCH 02/14] Force debug mode, add scratch/print-safepoints.stanza --- scratch/print-safepoints.stanza | 155 ++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 scratch/print-safepoints.stanza diff --git a/scratch/print-safepoints.stanza b/scratch/print-safepoints.stanza new file mode 100644 index 000000000..e0842286e --- /dev/null +++ b/scratch/print-safepoints.stanza @@ -0,0 +1,155 @@ +; Agenda: +;- run an app under debugger +;- set breakpoints at source lines +;- view stack trace +;- view global and local variables +;- view locals in selected stack frame +;- structural inspection of variables +;- application output redirection +;- step in and over global variable initializations +;- step in, over and out function calls and coroutines +;- step over loops +;- pause and continue infinite loop +;- restart debugging session + +defpackage print-safepoints : + import core + import collections + +;Expand 'Globals' and step over the initializations. +;Pay attention to value changes. +val GLOBAL-A = "Hello world" +var GLOBAL-B:Int = 23 +val GLOBAL-C = [23, "Hello"] +val GLOBAL-D = CharArray(3, 'A') +val GLOBAL-E = ByteArray(3, 5Y) +val GLOBAL-F = IntArray(3, 1) +val GLOBAL-G = Array(3, 1) +var GLOBAL-H:List = List(42, "Timon") +val GLOBAL-I = `core +val GLOBAL-J = to-char(0x07Y) +val GLOBAL-K = CharArray(3, to-char(0x0AY)) + +defn test (i:Int) : + println("=== test started %_ ===" % [i]) + for j in 0 to 10 do : + println("=== test iteration %_ ===" % [j]) + println("=== test finished %_ ===" % [i]) + +defn f0 (a:Int) : + println("f0(%_)" % [a]) + f1(a + a) + f1(a + a) + println(a) + +defn f1 (b:Int) : + println("f1(%_)" % [b]) + f2(b + b) + f2(b + b) + println(b) + +defn f2 (c:Int) : + ;Select caller's frames in stack trace to see their locals in 'Locals' view + println("f2(%_)" % [c]) + println(c) + +defn my-process (co:Coroutine, a:Int) -> String : + ;Step in or over suspends + println("Came in a = %_" % [a]) + println("Passing out Timon") + val b = suspend(co, "Timon") + + println("Came in b = %_" % [b]) + println("Passing out and") + val c = suspend(co, "and") + + println("Came in c = %_" % [c]) + println("Passing out Pumbaa") + val d = suspend(co, "Pumbaa") + + println("Came in d = %_" % [d]) + println("Coroutine is done") + "Done" + +defn coroutine-test () : + println("Create coroutine") + val co = Coroutine(my-process) + + ;Step in or over resumes + println("\nResume with 42") + val x = resume(co, 42) + println("Got back x = %_" % [x]) + + println("\nResume with 43") + val y = resume(co, 43) + println("Got back y = %_" % [y]) + + println("\nResume with 44") + val z = resume(co, 44) + println("Got back z = %_" % [z]) + + println("\nResume with 45") + val w = resume(co, 45) + println("Got back w = %_" % [w]) + +defn random-selection-test () : + ;Step in or over here. Pay attention to locals. + val items = ["Hello", 0, 'X'] + val x = items[rand(3)] + val y = items[rand(3)] + match(x, y) : + (x:Int, y:Int) : + println("Both integers") + (x:String, y:String) : + println("Both strings") + (x:Char, y:Char) : + println("Both chars") + (x:Int, y:String) : + println("Int and String") + (x:Char, y:Int) : + println("Char and Int") + (x:String, y:Char) : + println("String and Char") + (x:Int, y:Char) : + println("Int and Char") + (x, y) : + println("Default case") + println("x is %_" % [object-type(x)]) + println("y is %_" % [object-type(y)]) + +defn infinite-loop () -> False : + println("=== Infinite loop ===") + for i in 0 to false do : + println("=== Infinite Loop Iteration %_ ===" % [i]) + false + +defn main () : + ;Step over these to lines to show stdout and stderr redirection + println("=== Hello world ===") + println(STANDARD-ERROR-STREAM, "Hello from error stream"); + + ;Step in this function call + f0(10) + ;Step over this function call + f0(11) + + ;Step over this line to skip the loop + for i in 0 to 5 do : + println("=== Iteration %_ ===" % [i]) + test(i) + GLOBAL-B = GLOBAL-B * 10 + GLOBAL-H = cons(GLOBAL-B, GLOBAL-H) + ;Inspect GLOBAL-H linked list here + + ;Step in this coroutine test + coroutine-test() + + ;Set a breakpoint at 'match' and continue + for i in 0 to 20 do : + random-selection-test() + + ;Continue, let this loop run for a while, then pause. + infinite-loop() + println("=== FINISHED ===") + +main() From 8e0c7fa90e7fa32226bf9b49aca56b72bb1bfd38 Mon Sep 17 00:00:00 2001 From: Patrick Li Date: Fri, 7 Jul 2023 14:07:05 -0700 Subject: [PATCH 03/14] Safepoint table for VM --- compiler/asmjit.stanza | 7 +- compiler/code-table.stanza | 15 +- compiler/cvm-code-table.stanza | 6 +- compiler/cvm-encoder.stanza | 6 +- compiler/jit-code-table.stanza | 10 +- compiler/jit-encoder.stanza | 253 ++++++++++++++---------- compiler/packed-safepoint-table.stanza | 16 +- compiler/vm-ids.stanza | 130 ++++++++++-- compiler/vm-ir.stanza | 10 +- compiler/vm-load-unit.stanza | 4 +- compiler/vm-table.stanza | 30 +-- compiler/vm.stanza | 182 +++++++++++++++-- libs/asmjit/src/bindings/stz-asmjit.cpp | 3 + libs/asmjit/src/bindings/stz-asmjit.h | 3 +- 14 files changed, 487 insertions(+), 188 deletions(-) diff --git a/compiler/asmjit.stanza b/compiler/asmjit.stanza index 2c382c43b..124162690 100644 --- a/compiler/asmjit.stanza +++ b/compiler/asmjit.stanza @@ -61,6 +61,7 @@ extern assembler_div_reg: (ptr, ptr) -> int extern assembler_mod_reg: (ptr, ptr) -> int extern assembler_cqo_reg: (ptr) -> int extern assembler_cdq_reg: (ptr) -> int +extern assembler_nop: (ptr) -> int extern assembler_and_reg: (ptr, ptr, ptr) -> int extern assembler_and_int: (ptr, ptr, int) -> int extern assembler_or_reg: (ptr, ptr, ptr) -> int @@ -186,7 +187,7 @@ public lostanza deftype MemPtr : ;------------------------------------------------------------ defmethod equal? (a:Gp, b:Gp) -> True|False : id(a) == id(b) - + defmethod equal? (a:Xmm, b:Xmm) -> True|False : id(a) == id(b) @@ -697,6 +698,9 @@ public lostanza defn btr (a:ref, dst:ref, src:ref) -> ref public lostanza defn btr (a:ref, ptr:ref, src:ref) -> ref : call-c assembler_btr_ptr_reg(a.value, ptr.value, src.value) return src +public lostanza defn nop (a:ref) -> ref : + call-c assembler_nop(a.value) + return false ;------------------------------------------------------------ ;-------------------- Comparisons and Jumps ----------------- @@ -912,4 +916,3 @@ public lostanza defn ucomiss (a:ref, x:ref, y:ref) -> ref, x:ref, y:ref) -> ref : call-c assembler_ucomisd(a.value, x.value, y.value) return false - diff --git a/compiler/code-table.stanza b/compiler/code-table.stanza index c40f628d4..0232ec5b4 100644 --- a/compiler/code-table.stanza +++ b/compiler/code-table.stanza @@ -12,7 +12,7 @@ defpackage stz/code-table : ;============================================================ ;This contains all the generated code for the functions ;loaded into the virtual machine, as well as any additional -;tables for performing the code encoding. +;tables for performing the code encoding. public deftype CodeTable @@ -37,6 +37,7 @@ public defmulti load-function (t:CodeTable, public defstruct LoadedFunction : address:Long trace-entries:Vector + safepoint-entries:Vector ;Represents the entry for use during backtraces. public defstruct TraceTableEntry : @@ -45,6 +46,12 @@ public defstruct TraceTableEntry : with: printer => true +public defstruct SafepointTableEntry : + pc: Long + id: Int +with: + printer => true + ;============================================================ ;================== Launch ================================== ;============================================================ @@ -80,7 +87,7 @@ public deftype EncodingResolver ;- live: The set of locals that are live at the moment. public defmulti liveness-map (r:EncodingResolver, live:Seqable, num-locals:Int) -> Int -;Return the number of bytes used for the tag word of each object. +;Return the number of bytes used for the tag word of each object. public defmulti object-header-size (r:EncodingResolver) -> Int ;Return the number of bytes used to store an object on the heap. @@ -120,10 +127,10 @@ public defmulti marker? (r:EncodingResolver, n:Int) -> True|False public defmulti tagbits (r:EncodingResolver, typeid:Int) -> Int ;Return the address of the given extern address. -public defmulti extern-address (r:EncodingResolver, id:Int) -> Long +public defmulti extern-address (r:EncodingResolver, id:Int) -> Long ;Return the address of the given extern defn address. -public defmulti extern-defn-address (r:EncodingResolver, id:Int) -> Long +public defmulti extern-defn-address (r:EncodingResolver, id:Int) -> Long ;------------------------------------------------------------ ;----------------------- Convenience ------------------------ diff --git a/compiler/cvm-code-table.stanza b/compiler/cvm-code-table.stanza index 0577b180b..07d1f6a4e 100644 --- a/compiler/cvm-code-table.stanza +++ b/compiler/cvm-code-table.stanza @@ -46,15 +46,19 @@ lostanza defmethod load-function (table:ref, ;Add the offset to the trace entries so that we know their absolute position. val relocated-trace-entries = add-offset(trace-entries(encoded-function), new Long{offset}) + val relocated-safepoint-entries = add-offset(safepoint-entries(encoded-function), new Long{offset}) ;Return the new loaded function - return LoadedFunction(new Long{offset}, relocated-trace-entries) + return LoadedFunction(new Long{offset}, relocated-trace-entries, relocated-safepoint-entries) ;Add 'offset' to the 'pc' of every entry in 'trace-entries' and return ;the result. defn add-offset (trace-entries:Seqable, offset:Long) -> Vector : to-vector $ for e in trace-entries seq : TraceTableEntry(pc(e) + offset, entry(e)) +defn add-offset (safepoint-entries:Seqable, offset:Long) -> Vector : + to-vector $ for e in safepoint-entries seq : + SafepointTableEntry(pc(e) + offset, id(e)) ;============================================================ ;================== Launch ================================== diff --git a/compiler/cvm-encoder.stanza b/compiler/cvm-encoder.stanza index 0d96d72e8..f0e180434 100644 --- a/compiler/cvm-encoder.stanza +++ b/compiler/cvm-encoder.stanza @@ -18,13 +18,14 @@ defpackage stz/cvm-encoder : public defstruct EncodedFunction : buffer: ByteBuffer trace-entries: Vector + safepoint-entries: Vector public defn encode (func:VMFunction, resolver:EncodingResolver, backend:Backend) -> EncodedFunction : ;Encode instructions into this byte buffer val buffer = ByteBuffer() - + ;All instructions are sized to be multiples of 4 bytes, and thus ;we use address / 4 as a "position" in the instruction stream. defn buffer-pos () : write-position(buffer) / 4 @@ -32,6 +33,7 @@ public defn encode (func:VMFunction, ;Accumulate file information entries for implementing ;stack traces. val trace-entry-table = Vector() + val safepoint-entry-table = Vector() defn record-trace-entry (entry:StackTraceInfo|False) : match(entry:StackTraceInfo) : add(trace-entry-table, TraceTableEntry(to-long(write-position(buffer)), entry)) @@ -698,7 +700,7 @@ public defn encode (func:VMFunction, ;Use delayed actions and encode instructions within delay-actions() : encode(func as VMMultifn|VMFunc) - EncodedFunction(buffer, trace-entry-table) + EncodedFunction(buffer, trace-entry-table, safepoint-entry-table) ;============================================================ ;====================== Utilities =========================== diff --git a/compiler/jit-code-table.stanza b/compiler/jit-code-table.stanza index 981dfba63..b3665cf64 100644 --- a/compiler/jit-code-table.stanza +++ b/compiler/jit-code-table.stanza @@ -31,7 +31,7 @@ public defstruct JITStubs : public defn JITCodeTable (resolver:EncodingResolver, backend:Backend) -> JITCodeTable : val runtime = jit-runtime-new() - val stubs = make-jit-stubs(runtime, resolver, backend) + val stubs = make-jit-stubs(runtime, resolver, backend) #JITCodeTable(runtime, stubs) ;============================================================ @@ -52,12 +52,12 @@ defmethod load-function (table:JITCodeTable, val oldf = get?(funcs(table), fid) match(oldf:Func) : release(runtime(table), oldf) - + ;Add the function into the table so that we can release them later. put(funcs(table), fid, func(encoded-function)) ;Return the loaded function - LoadedFunction(value(func(encoded-function)), trace-entries(encoded-function)) + LoadedFunction(value(func(encoded-function)), trace-entries(encoded-function), safepoint-entries(encoded-function)) ;============================================================ ;================== Launch ================================== @@ -68,7 +68,7 @@ lostanza defmethod launch (vmstate-address:ref, table:ref, f val fptr = launch as ptr<( (ptr, long, long) -> int )> val vmstate = vmstate-address.value as ptr call-c [fptr](vmstate, call-prim crsp() as long, func-id.value) - return false + return false ;============================================================ ;===================== Free ================================= @@ -96,6 +96,6 @@ defn put (xs:Vector, k:Int, v:T) : if k >= length(xs) : lengthen(xs, k + 1, false) xs[k] = v - + defn get? (xs:Vector, k:Int) -> T|False : if k < length(xs) : xs[k] diff --git a/compiler/jit-encoder.stanza b/compiler/jit-encoder.stanza index 2a97291b1..7bb805c46 100644 --- a/compiler/jit-encoder.stanza +++ b/compiler/jit-encoder.stanza @@ -51,6 +51,7 @@ val COMPUTE-ABSOLUTE-ADDRESSES = TimerLabel(JIT-ENCODER, suffix("Compute absolut public defstruct EncodedFunction : func: Func trace-entries: Vector + safepoint-entries: Vector ;============================================================ ;=================== Configuration ========================== @@ -89,7 +90,7 @@ lostanza defn call-collect-stack-trace-addr () -> ref : ;================== Register Conventions ==================== ;============================================================ ;Decide on which x86 registers to use for all our virtual machine -;quantities. This is backend-specific. +;quantities. This is backend-specific. ; ;# Notes about Assignment # ;- X86 div and shl instructions uses RAX, RDX, RCX as special registers. @@ -330,7 +331,7 @@ defn branch-is-final? (resolver:EncodingResolver, b:VMBranch) : ; ;- vmstate.current_stack.stack_pointer.locals[0 to n]: Locali ; JIT code for single function assumes cached in register. -; Needs to be written to in-memory structure when current stack frame changes. +; Needs to be written to in-memory structure when current stack frame changes. ; ;- vmstate.registers[0 to n]: VMRegi ; JIT code assumes cached in register. @@ -367,6 +368,7 @@ defn AsmGen (code:CodeHolder, resolver:EncodingResolver, func-info:FuncInfo|False, trace-entry-table:Vector|False, + safepoint-entry-table:Vector|False, backend:Backend) : ;========================================================= @@ -403,7 +405,7 @@ defn AsmGen (code:CodeHolder, ;Call slot if x is a Local otherwise return dummy value 0. ;The dummy value is fine because in this case the instruction - ;doesn't have a return value anyway. + ;doesn't have a return value anyway. defn slot? (x:Local|False) -> Int : match(x:Local) : slot(x) else : 0 @@ -444,7 +446,7 @@ defn AsmGen (code:CodeHolder, ;========================================================= val label-table = IntTable