core/vm/evmjit: Do not use full env context if not needed

This commit is contained in:
Paweł Bylica 2017-01-26 00:45:34 +01:00
parent fae74919b1
commit c030867ccf
No known key found for this signature in database
GPG key ID: 7A0C037434FE77EF

View file

@ -108,10 +108,14 @@ func unpinCtx(id uintptr) {
contextMapMu.Unlock() contextMapMu.Unlock()
} }
func getCtx(id uintptr) *EVMCContext { func getCtx(idx uintptr) *EVMCContext {
contextMapMu.Lock() contextMapMu.Lock()
defer contextMapMu.Unlock() defer contextMapMu.Unlock()
return contextMap[id] return contextMap[idx]
}
func getEnv(idx uintptr) *EVM {
return getCtx(idx).env
} }
func HashToEvmc(hash common.Hash) C.struct_evm_uint256be { func HashToEvmc(hash common.Hash) C.struct_evm_uint256be {
@ -147,27 +151,27 @@ func GoByteSlice(data unsafe.Pointer, size C.size_t) []byte {
//export getTxCtx //export getTxCtx
func getTxCtx(pResult unsafe.Pointer, ctxIdx uintptr) { func getTxCtx(pResult unsafe.Pointer, ctxIdx uintptr) {
ctx := getCtx(ctxIdx) env := getEnv(ctxIdx)
txCtx := (*C.struct_evm_tx_context)(pResult) txCtx := (*C.struct_evm_tx_context)(pResult)
txCtx.tx_gas_price = BigToEvmc(ctx.env.GasPrice) txCtx.tx_gas_price = BigToEvmc(env.GasPrice)
txCtx.tx_origin = AddressToEvmc(ctx.env.Origin) txCtx.tx_origin = AddressToEvmc(env.Origin)
txCtx.block_coinbase = AddressToEvmc(ctx.env.Coinbase) txCtx.block_coinbase = AddressToEvmc(env.Coinbase)
txCtx.block_number = C.int64_t(ctx.env.BlockNumber.Int64()) txCtx.block_number = C.int64_t(env.BlockNumber.Int64())
txCtx.block_timestamp = C.int64_t(ctx.env.Time.Int64()) txCtx.block_timestamp = C.int64_t(env.Time.Int64())
txCtx.block_gas_limit = C.int64_t(ctx.env.GasLimit.Int64()) txCtx.block_gas_limit = C.int64_t(env.GasLimit.Int64())
txCtx.block_difficulty = BigToEvmc(ctx.env.Difficulty) txCtx.block_difficulty = BigToEvmc(env.Difficulty)
} }
//export getBlockHash //export getBlockHash
func getBlockHash(pResult unsafe.Pointer, ctxIdx uintptr, number int64) { func getBlockHash(pResult unsafe.Pointer, ctxIdx uintptr, number int64) {
// Represent the result memory as Go slice of 32 bytes. // Represent the result memory as Go slice of 32 bytes.
result := GoByteSlice(pResult, 32) result := GoByteSlice(pResult, 32)
ctx := getCtx(ctxIdx) env := getEnv(ctxIdx)
b := ctx.env.BlockNumber.Int64() b := env.BlockNumber.Int64()
a := b - 256 a := b - 256
var hash common.Hash var hash common.Hash
if number >= a && number < b { if number >= a && number < b {
hash = ctx.env.GetHash(uint64(number)) hash = env.GetHash(uint64(number))
} }
copy(result, hash[:]) copy(result, hash[:])
} }
@ -180,7 +184,7 @@ func queryState(pResult unsafe.Pointer, ctxIdx uintptr, key int32, pAddr unsafe.
pInt64Result := (*int64)(pResult) pInt64Result := (*int64)(pResult)
// Get the execution context. // Get the execution context.
ctx := getCtx(ctxIdx) env := getEnv(ctxIdx)
var addr common.Address var addr common.Address
copy(addr[:], GoByteSlice(pAddr, 20)) copy(addr[:], GoByteSlice(pAddr, 20))
@ -188,30 +192,30 @@ func queryState(pResult unsafe.Pointer, ctxIdx uintptr, key int32, pAddr unsafe.
switch key { switch key {
case C.EVM_SLOAD: case C.EVM_SLOAD:
arg := *(*[32]byte)(pArg) arg := *(*[32]byte)(pArg)
val := ctx.env.StateDB.GetState(ctx.contract.Address(), arg) val := env.StateDB.GetState(addr, arg)
copy(result, val[:]) copy(result, val[:])
case C.EVM_CODE_BY_ADDRESS: case C.EVM_CODE_BY_ADDRESS:
code := ctx.env.StateDB.GetCode(addr) code := env.StateDB.GetCode(addr)
pResAsMemRef := (*MemoryRef)(pResult) pResAsMemRef := (*MemoryRef)(pResult)
pResAsMemRef.ptr = ptr(code) pResAsMemRef.ptr = ptr(code)
pResAsMemRef.len = len(code) pResAsMemRef.len = len(code)
// fmt.Printf("EXTCODE %x : %d\n", addr, pResAsMemRef.len) // fmt.Printf("EXTCODE %x : %d\n", addr, pResAsMemRef.len)
case C.EVM_CODE_SIZE: case C.EVM_CODE_SIZE:
pInt64Result := (*int64)(pResult) pInt64Result := (*int64)(pResult)
*pInt64Result = int64(ctx.env.StateDB.GetCodeSize(addr)) *pInt64Result = int64(env.StateDB.GetCodeSize(addr))
// fmt.Printf("EXTCODESIZE %x : %d\n", addr, *pInt64Result) // fmt.Printf("EXTCODESIZE %x : %d\n", addr, *pInt64Result)
case C.EVM_BALANCE: case C.EVM_BALANCE:
balance := ctx.env.StateDB.GetBalance(addr) balance := env.StateDB.GetBalance(addr)
val := common.BigToHash(balance) val := common.BigToHash(balance)
copy(result, val[:]) copy(result, val[:])
case C.EVM_ACCOUNT_EXISTS: case C.EVM_ACCOUNT_EXISTS:
eip158 := ctx.env.ChainConfig().IsEIP158(ctx.env.BlockNumber) eip158 := env.ChainConfig().IsEIP158(env.BlockNumber)
var exist int64 var exist int64
if eip158 { if eip158 {
if !ctx.env.StateDB.Empty(addr) { if !env.StateDB.Empty(addr) {
exist = 1 exist = 1
} }
} else if ctx.env.StateDB.Exist(addr) { } else if env.StateDB.Exist(addr) {
exist = 1 exist = 1
} }
*pInt64Result = exist *pInt64Result = exist
@ -222,16 +226,19 @@ func queryState(pResult unsafe.Pointer, ctxIdx uintptr, key int32, pAddr unsafe.
//export updateState //export updateState
func updateState(ctxIdx uintptr, key int32, pAddr unsafe.Pointer, pArg1 unsafe.Pointer, pArg2 unsafe.Pointer) { func updateState(ctxIdx uintptr, key int32, pAddr unsafe.Pointer, pArg1 unsafe.Pointer, pArg2 unsafe.Pointer) {
ctx := getCtx(ctxIdx) env := getEnv(ctxIdx)
var addr common.Address
copy(addr[:], GoByteSlice(pAddr, 20))
switch key { switch key {
case C.EVM_SSTORE: case C.EVM_SSTORE:
key := *(*[32]byte)(pArg1) key := *(*[32]byte)(pArg1)
newVal := *(*[32]byte)(pArg2) newVal := *(*[32]byte)(pArg2)
oldVal := ctx.env.StateDB.GetState(ctx.contract.Address(), key) oldVal := env.StateDB.GetState(addr, key)
ctx.env.StateDB.SetState(ctx.contract.Address(), key, newVal) env.StateDB.SetState(addr, key, newVal)
if !common.EmptyHash(oldVal) && common.EmptyHash(newVal) { if !common.EmptyHash(oldVal) && common.EmptyHash(newVal) {
ctx.env.StateDB.AddRefund(params.SstoreRefundGas) env.StateDB.AddRefund(params.SstoreRefundGas)
} }
// fmt.Printf("EVMJIT STORE %x : %x [%x, %d]\n", arg1, arg2, ctx.contract.Address(), int(uintptr(pEnv))) // fmt.Printf("EVMJIT STORE %x : %x [%x, %d]\n", arg1, arg2, ctx.contract.Address(), int(uintptr(pEnv)))
case C.EVM_LOG: case C.EVM_LOG:
@ -245,16 +252,15 @@ func updateState(ctxIdx uintptr, key int32, pAddr unsafe.Pointer, pArg1 unsafe.P
for i := 0; i < nTopics; i++ { for i := 0; i < nTopics; i++ {
copy(topics[i][:], tData[i*32:(i+1)*32]) copy(topics[i][:], tData[i*32:(i+1)*32])
} }
ctx.env.StateDB.AddLog(&types.Log{ env.StateDB.AddLog(&types.Log{
Address: ctx.contract.Address(), Address: addr,
Topics: topics, Topics: topics,
Data: data, Data: data,
BlockNumber: ctx.env.BlockNumber.Uint64(), BlockNumber: env.BlockNumber.Uint64(),
}) })
case C.EVM_SELFDESTRUCT: case C.EVM_SELFDESTRUCT:
arg := GoByteSlice(pArg1, 32) arg := GoByteSlice(pArg1, 32)
db := ctx.env.StateDB db := env.StateDB
addr := ctx.contract.Address()
if !db.HasSuicided(addr) { if !db.HasSuicided(addr) {
db.AddRefund(params.SuicideRefundGas) db.AddRefund(params.SuicideRefundGas)
} }