From 846f34f78b5f76233655d0cf3611706e99f2efe2 Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Fri, 17 Jul 2015 23:09:36 +0200 Subject: core/vm, tests: implemented semi-jit vm * changed stack and removed stack ptr. Let go decide on slice reuse. --- tests/state_test.go | 17 +++++++++++ tests/state_test_util.go | 56 ++++++++++++++++++++++++++++++++++++ tests/vm_test.go | 14 +++++++++ tests/vm_test_util.go | 74 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 160 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/state_test.go b/tests/state_test.go index 1684614df..eb1900e1b 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -20,8 +20,25 @@ import ( "os" "path/filepath" "testing" + + "github.com/ethereum/go-ethereum/core/vm" ) +func init() { + if os.Getenv("JITVM") == "true" { + vm.ForceJit = true + } else { + vm.DisableJit = true + } +} + +func BenchmarkStateCall1024(b *testing.B) { + fn := filepath.Join(stateTestDir, "stCallCreateCallCodeTest.json") + if err := BenchVmTest(fn, bconf{"Call1024BalanceTooLow", true, false}, b); err != nil { + b.Error(err) + } +} + func TestStateSystemOperations(t *testing.T) { fn := filepath.Join(stateTestDir, "stSystemOperationsTest.json") if err := RunStateTest(fn, StateSkipTests); err != nil { diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 7086de389..695e50852 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -23,6 +23,7 @@ import ( "io" "math/big" "strconv" + "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -60,6 +61,61 @@ func RunStateTest(p string, skipTests []string) error { } +func BenchStateTest(p string, conf bconf, b *testing.B) error { + tests := make(map[string]VmTest) + if err := readJsonFile(p, &tests); err != nil { + return err + } + test, ok := tests[conf.name] + if !ok { + return fmt.Errorf("test not found: %s", conf.name) + } + + pNoJit := vm.DisableJit + vm.DisableJit = conf.nojit + pForceJit := vm.ForceJit + vm.ForceJit = conf.precomp + + // XXX Yeah, yeah... + env := make(map[string]string) + env["currentCoinbase"] = test.Env.CurrentCoinbase + env["currentDifficulty"] = test.Env.CurrentDifficulty + env["currentGasLimit"] = test.Env.CurrentGasLimit + env["currentNumber"] = test.Env.CurrentNumber + env["previousHash"] = test.Env.PreviousHash + if n, ok := test.Env.CurrentTimestamp.(float64); ok { + env["currentTimestamp"] = strconv.Itoa(int(n)) + } else { + env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchStateTest(test, env, b) + } + + vm.DisableJit = pNoJit + vm.ForceJit = pForceJit + + return nil +} + +func benchStateTest(test VmTest, env map[string]string, b *testing.B) { + b.StopTimer() + db, _ := ethdb.NewMemDatabase() + statedb := state.New(common.Hash{}, db) + for addr, account := range test.Pre { + obj := StateObjectFromAccount(db, addr, account) + statedb.SetStateObject(obj) + for a, v := range account.Storage { + obj.SetState(common.HexToHash(a), common.HexToHash(v)) + } + } + b.StartTimer() + + RunState(statedb, env, test.Exec) +} + func runStateTests(tests map[string]VmTest, skipTests []string) error { skipTest := make(map[string]bool, len(skipTests)) for _, name := range skipTests { diff --git a/tests/vm_test.go b/tests/vm_test.go index 3674ed440..6b6b179fd 100644 --- a/tests/vm_test.go +++ b/tests/vm_test.go @@ -21,6 +21,20 @@ import ( "testing" ) +func BenchmarkVmAckermann32Tests(b *testing.B) { + fn := filepath.Join(vmTestDir, "vmPerformanceTest.json") + if err := BenchVmTest(fn, bconf{"ackermann32", true, false}, b); err != nil { + b.Error(err) + } +} + +func BenchmarkVmFibonacci16Tests(b *testing.B) { + fn := filepath.Join(vmTestDir, "vmPerformanceTest.json") + if err := BenchVmTest(fn, bconf{"fibonacci16", true, true}, b); err != nil { + b.Error(err) + } +} + // I've created a new function for each tests so it's easier to identify where the problem lies if any of them fail. func TestVMArithmetic(t *testing.T) { fn := filepath.Join(vmTestDir, "vmArithmeticTest.json") diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index e63a92558..b29dcd20f 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -22,6 +22,7 @@ import ( "io" "math/big" "strconv" + "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" @@ -48,8 +49,79 @@ func RunVmTestWithReader(r io.Reader, skipTests []string) error { return nil } -func RunVmTest(p string, skipTests []string) error { +type bconf struct { + name string + precomp bool + nojit bool +} + +func BenchVmTest(p string, conf bconf, b *testing.B) error { + tests := make(map[string]VmTest) + err := readJsonFile(p, &tests) + if err != nil { + return err + } + + test, ok := tests[conf.name] + if !ok { + return fmt.Errorf("test not found: %s", conf.name) + } + + pNoJit := vm.DisableJit + vm.DisableJit = conf.nojit + pForceJit := vm.ForceJit + vm.ForceJit = conf.precomp + + env := make(map[string]string) + env["currentCoinbase"] = test.Env.CurrentCoinbase + env["currentDifficulty"] = test.Env.CurrentDifficulty + env["currentGasLimit"] = test.Env.CurrentGasLimit + env["currentNumber"] = test.Env.CurrentNumber + env["previousHash"] = test.Env.PreviousHash + if n, ok := test.Env.CurrentTimestamp.(float64); ok { + env["currentTimestamp"] = strconv.Itoa(int(n)) + } else { + env["currentTimestamp"] = test.Env.CurrentTimestamp.(string) + } + /* + if conf.precomp { + program := vm.NewProgram(test.code) + err := vm.AttachProgram(program) + if err != nil { + return err + } + } + */ + + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchVmTest(test, env, b) + } + + vm.DisableJit = pNoJit + vm.ForceJit = pForceJit + + return nil +} + +func benchVmTest(test VmTest, env map[string]string, b *testing.B) { + b.StopTimer() + db, _ := ethdb.NewMemDatabase() + statedb := state.New(common.Hash{}, db) + for addr, account := range test.Pre { + obj := StateObjectFromAccount(db, addr, account) + statedb.SetStateObject(obj) + for a, v := range account.Storage { + obj.SetState(common.HexToHash(a), common.HexToHash(v)) + } + } + b.StartTimer() + + RunVm(statedb, env, test.Exec) +} + +func RunVmTest(p string, skipTests []string) error { tests := make(map[string]VmTest) err := readJsonFile(p, &tests) if err != nil { -- cgit v1.2.3