profiling opcodes
This commit is contained in:
parent
ab64d31271
commit
5b23d27c0a
|
@ -632,7 +632,7 @@ proc parseFunct(comp: Compiler) =
|
|||
dec comp.stackIndex # the previous end scope did not put anything on the stack, it is jumped over
|
||||
|
||||
# get konvalue functions:
|
||||
let konFunct = newKonFunction(comp.chunk.name, functII, params.len)
|
||||
let konFunct = newKonFunction(functII, params.len)
|
||||
|
||||
# end of function declaration:
|
||||
comp.patchJump(jumpOverBody)
|
||||
|
|
|
@ -10,6 +10,7 @@ const debugCompiler* = false
|
|||
const debugDumpChunk* = false
|
||||
const assertionsVM* = false # sanity checks in the VM, such as the stack being empty at the end
|
||||
const assertionsCompiler* = false # sanity checks in the compiler
|
||||
const profileInstructions* = false # if true, the time spent on every opcode is measured
|
||||
|
||||
# choose a line editor for the repl
|
||||
const lineEditor = leRdstdin
|
||||
|
|
7
main.nim
7
main.nim
|
@ -37,8 +37,13 @@ proc runFile(path: string) =
|
|||
of rsOK:
|
||||
quit 0
|
||||
|
||||
const hardcodedPath* = ""
|
||||
|
||||
if paramCount() == 0:
|
||||
repl()
|
||||
if hardcodedPath == "":
|
||||
repl()
|
||||
else:
|
||||
runFile(hardcodedPath)
|
||||
elif paramCount() == 1:
|
||||
runFile(paramStr(1))
|
||||
else:
|
||||
|
|
|
@ -20,7 +20,6 @@ type
|
|||
of ktString:
|
||||
stringValue*: string
|
||||
of ktFunct:
|
||||
module*: string # which chunk the function is compiled in
|
||||
entryII*: int # entry instruction index
|
||||
arity*: int # number of arguments
|
||||
of errorTypes:
|
||||
|
@ -39,7 +38,7 @@ proc `$`*(val: KonValue): string =
|
|||
of ktString:
|
||||
return val.stringValue
|
||||
of ktFunct:
|
||||
return &"Function object: {val.module}/{val.entryII}"
|
||||
return &"Function object: {val.entryII}"
|
||||
of errorTypes:
|
||||
let ename = $val.konType
|
||||
return &"{ename[2..^1]}: {val.message}"
|
||||
|
@ -67,7 +66,7 @@ proc equal*(val, right: KonValue): bool =
|
|||
of ktString:
|
||||
val.stringValue == right.stringValue
|
||||
of ktFunct:
|
||||
val.module == right.module and val.entryII == right.entryII
|
||||
val.entryII == right.entryII
|
||||
# same entry II/module but diff arity is a bug
|
||||
of errorTypes:
|
||||
false # error comparison is undefined
|
||||
|
@ -83,8 +82,8 @@ proc toKonValue*(val: bool): KonValue =
|
|||
proc toKonValue*(val: string): KonValue =
|
||||
KonValue(konType: ktString, stringValue: val)
|
||||
|
||||
proc newKonFunction*(module: string, ii: int, arity: int): KonValue =
|
||||
KonValue(konType: ktFunct, module: module, entryII: ii, arity: arity)
|
||||
proc newKonFunction*(ii: int, arity: int): KonValue =
|
||||
KonValue(konType: ktFunct, entryII: ii, arity: arity)
|
||||
|
||||
proc toKonValue*: KonValue =
|
||||
KonValue(konType: ktNil)
|
||||
|
|
22
vm.nim
22
vm.nim
|
@ -5,6 +5,9 @@ import value
|
|||
import chunk
|
||||
import config
|
||||
import pointerutils
|
||||
when profileInstructions:
|
||||
import times
|
||||
import std/monotimes
|
||||
|
||||
type
|
||||
Frame = object
|
||||
|
@ -78,6 +81,12 @@ proc binary(op: OpCode, left: KonValue, right: KonValue): KonValue =
|
|||
else:
|
||||
discard #unreachable
|
||||
|
||||
when profileInstructions:
|
||||
# not a perfect profiling approach, doing random stacktrace dumps
|
||||
# x amount of times per second to get the current source line
|
||||
# would be better
|
||||
var durations: array[OpCode, Duration]
|
||||
|
||||
proc run*(vm: VM): InterpretResult =
|
||||
|
||||
template frameBottom: int = vm.frames[vm.frames.high].stackBottom
|
||||
|
@ -98,6 +107,10 @@ proc run*(vm: VM): InterpretResult =
|
|||
msg &= &"{e} "
|
||||
msg &= "]"
|
||||
echo msg
|
||||
|
||||
when profileInstructions:
|
||||
let startTime = getMonoTime()
|
||||
|
||||
case ins:
|
||||
of opPop:
|
||||
discard vm.pop()
|
||||
|
@ -200,9 +213,18 @@ proc run*(vm: VM): InterpretResult =
|
|||
|
||||
vm.ip = vm.chunk.code[0].unsafeAddr.padd(funct.entryII) # jump to the entry point
|
||||
|
||||
when profileInstructions:
|
||||
durations[ins] += getMonoTime() - startTime
|
||||
|
||||
when assertionsVM:
|
||||
if not vm.hadError and vm.stack.len > 0:
|
||||
vm.runtimeError(&"VM Assertion failed: stack is of non-zero length {vm.stack.len} after execution has finished.")
|
||||
|
||||
when profileInstructions:
|
||||
for op in OpCode:
|
||||
let dur = durations[op].inMilliseconds
|
||||
echo &"OpCode: {op} total duration {dur} ms"
|
||||
|
||||
if vm.hadError:
|
||||
irRuntimeError
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue