Tracing vs. partial evaluation: comparing meta-compilation approaches for self-optimizing interpreters