provide experimental op handler switch -d:lowmem:1 for low memory C compiler

why:
  on 32bit windows 7, there seems to be a 64k memory ceiling for the gcc
  compiler which was exceeded on some test platform.

details:
  compiling VM2 for low memory C compiler can be triggered with
  "make ENABLE_VM2LOWMEM". this comes with a ~24% longer execution time
  of the test suite against old VM and optimised VM2.
This commit is contained in:
Jordan Hrycaj 2021-04-23 08:50:48 +01:00 committed by zah
parent 1b3117edbd
commit bca6e791aa
3 changed files with 88 additions and 33 deletions

View File

@ -80,10 +80,15 @@ ifneq ($(ENABLE_EVMC), 0)
NIM_PARAMS := $(NIM_PARAMS) -d:evmc_enabled
endif
# disabled by default, enable with ENABLE_VM2SLOW=1
ifneq ($(if $(ENABLE_VM2LOWMEM),$(ENABLE_VM2LOWMEM),0),0)
NIM_PARAMS := $(NIM_PARAMS) -d:vm2_enabled -d:lowmem:1
else
# disabled by default, enable with ENABLE_VM2=1
ifneq ($(if $(ENABLE_VM2),$(ENABLE_VM2),0),0)
NIM_PARAMS := $(NIM_PARAMS) -d:vm2_enabled
endif
endif
deps: | deps-common nat-libs nimbus.nims
ifneq ($(USE_LIBBACKTRACE), 0)

View File

@ -67,7 +67,7 @@ nix-shell default.nix
make nimbus
# See available command line options
build/nimbus -- help
build/nimbus --help
# Start syncing with mainnet
build/nimbus
@ -190,8 +190,29 @@ make nimbus
build/nimbus
```
### <a name="make-xvars"></a>Experimental make variables
### Development tips
Apart from standard make flags (see link in the next [chapter](#devel-tips)),
the following make variables can be set to control which version of a virtual
engine is compiled. The variables are listed with decreasing priority (in
case of doubt, the lower prioritised variable is ignored when the higher on is
available.)
* ENABLE_EVMC=1<br>
Enable mostly EVMC compliant wrapper around the native nim VM
* ENABLE_VM2LOWMEM=1<br>
Enable new re-factored version of the native nim VM. This version is not
optimised and coded in a way so that low memory compilers can handle it
(observed on 32 bit windows 7.)
* ENABLE_VM2=1<br>
Enable new re-factored version of the native nim VM.
For these variables, using &lt;variable&gt;=0 is ignored and &lt;variable&gt;=2
has the same effect as &lt;variable&gt;=1 (ditto for other numbers.)
### <a name="devel-tips"></a>Development tips
Interesting Make variables and targets are documented in the [nimbus-build-system](https://github.com/status-im/nimbus-build-system) repo.

View File

@ -9,6 +9,10 @@
# according to those terms.
const
# help with low memory when compiling
lowmem {.intdefine.}: int = 0
lowMemoryCompileTime {.used.} = lowmem > 0
# debugging flag
kludge {.intdefine.}: int = 0
breakCircularDependency {.used.} = kludge > 0
@ -99,7 +103,7 @@ proc toCaseStmt(forkArg, opArg, k: NimNode): NimNode =
of Create, Create2, Call, CallCode, DelegateCall, StaticCall:
quote do:
`forkCaseSubExpr`
if not c.continuation.isNil:
if not `k`.cpt.continuation.isNil:
break
of Stop, Return, Revert, SelfDestruct:
quote do:
@ -117,9 +121,29 @@ proc toCaseStmt(forkArg, opArg, k: NimNode): NimNode =
echo ">>> ", result.repr
macro genDispatchMatrix(fork: Fork; op: Op; k: Vm2Ctx): untyped =
macro genDispatchMatrix(fork: Fork; op: Op; k: Vm2Ctx): untyped {.used.} =
result = fork.toCaseStmt(op, k)
template genLowMemDispatcher(fork: Fork; op: Op; k: Vm2Ctx) {.used.} =
if op == Stop:
handleStopDirective(k)
break
if BaseGasCosts[op].kind == GckFixed:
handleFixedGasCostsDirective(fork, op, k)
else:
handleOtherDirective(fork, op, k)
case c.instr
of Create, Create2, Call, CallCode, DelegateCall, StaticCall:
if not k.cpt.continuation.isNil:
break
of Return, Revert, SelfDestruct:
break
else:
discard
# ------------------------------------------------------------------------------
# Public functions
# ------------------------------------------------------------------------------
@ -144,40 +168,45 @@ proc selectVM*(c: Computation, fork: Fork) {.gcsafe.} =
# # we could use manual jump table instead
# # TODO lots of macro magic here to unravel, with chronicles...
# # `c`.logger.log($`c`.stack & "\n\n", fgGreen)
when not lowMemoryCompileTime:
when defined(release):
#
# FIXME: OS case list below needs to be adjusted
#
when defined(windows):
when defined(cpu64):
{.warning: "*** Win64/VM2 handler switch => computedGoto".}
{.computedGoto, optimization: speed.}
else:
# computedGoto not compiling on github/ci (out of memory) -- jordan
{.warning: "*** Win32/VM2 handler switch => optimisation disabled".}
# {.computedGoto, optimization: speed.}
elif defined(linux):
when defined(cpu64):
{.warning: "*** Linux64/VM2 handler switch => computedGoto".}
{.computedGoto, optimization: speed.}
else:
{.warning: "*** Linux32/VM2 handler switch => computedGoto".}
{.computedGoto, optimization: speed.}
elif defined(macosx):
when defined(cpu64):
{.warning: "*** MacOs64/VM2 handler switch => computedGoto".}
{.computedGoto, optimization: speed.}
else:
{.warning: "*** MacOs32/VM2 handler switch => computedGoto".}
{.computedGoto, optimization: speed.}
when defined(release):
#
# FIXME: OS case list below needs to be adjusted
#
when defined(windows):
when defined(cpu64):
{.warning: "*** Win64/VM2 handler switch => computedGoto".}
{.computedGoto, optimization: speed.}
else:
# computedGoto is not compiling on github/ci (out of memory) -- jordan
{.warning: "*** Win32/VM2 handler switch => optimisation disabled".}
# {.computedGoto, optimization: speed.}
{.warning: "*** Unsupported OS => no handler switch optimisation".}
elif defined(linux):
when defined(cpu64):
{.warning: "*** Linux64/VM2 handler switch => computedGoto".}
{.computedGoto, optimization: speed.}
else:
{.warning: "*** Linux32/VM2 handler switch => computedGoto".}
{.computedGoto, optimization: speed.}
genDispatchMatrix(fork, c.instr, desc)
elif defined(macosx):
when defined(cpu64):
{.warning: "*** MacOs64/VM2 handler switch => computedGoto".}
{.computedGoto, optimization: speed.}
else:
{.warning: "*** MacOs32/VM2 handler switch => computedGoto".}
{.computedGoto, optimization: speed.}
else:
{.warning: "*** low memory compiler mode => program will be slow".}
else:
{.warning: "*** Unsupported OS => no handler switch optimisation".}
genDispatchMatrix(fork, c.instr, desc)
genLowMemDispatcher(fork, c.instr, desc)
# ------------------------------------------------------------------------------
# End