26 void VM::reportStackUse()
28 static intptr_t p = 0;
29 intptr_t q = intptr_t(&q);
31 cerr <<
"STACK: " << p <<
" - " << q <<
" = " << (p - q) << endl;
35 std::array<InstructionMetric, 256> VM::c_metrics;
36 void VM::initMetrics()
38 static bool done=
false;
41 for (
unsigned i = 0; i < 256; ++i)
45 c_metrics[i].args = op.
args;
46 c_metrics[i].ret = op.
ret;
52 void VM::copyCode(
int _extraBytes)
57 auto extendedSize = m_ext->code.size() + _extraBytes;
58 m_codeSpace.reserve(extendedSize);
59 m_codeSpace = m_ext->code;
60 m_codeSpace.resize(extendedSize);
61 m_code = m_codeSpace.data();
68 size_t const nBytes = m_ext->code.size();
73 for (
size_t pc = 0; pc < nBytes; ++pc)
80 op == Instruction::PUSHC ||
81 op == Instruction::JUMPC ||
82 op == Instruction::JUMPCI
86 m_code[pc] = (
byte)Instruction::BAD;
89 if (op == Instruction::JUMPDEST)
91 m_jumpDests.push_back(pc);
94 (
byte)Instruction::PUSH1 <= (
byte)op &&
95 (
byte)op <= (
byte)Instruction::PUSH32
98 pc += (
byte)op - (
byte)Instruction::PUSH1 + 1;
100 #if EVM_JUMPS_AND_SUBS 102 op == Instruction::JUMPTO ||
103 op == Instruction::JUMPIF ||
104 op == Instruction::JUMPSUB)
109 else if (op == Instruction::JUMPV || op == Instruction::JUMPSUBV)
112 pc += 4 * m_code[pc];
114 else if (op == Instruction::BEGINSUB)
116 m_beginSubs.push_back(pc);
118 else if (op == Instruction::BEGINDATA)
125 #ifdef EVM_DO_FIRST_PASS_OPTIMIZATION 127 #ifdef EVM_USE_CONSTANT_POOL 133 const uint32_t FNV_PRIME1 = 2166136261;
134 const uint32_t FNV_PRIME2 = 16777619;
135 uint32_t hash = FNV_PRIME1;
142 for (
int i = 0; i < 256; ++i)
149 void hashInit() { hash = FNV_PRIME1; }
152 void hashByte(
byte b) { hash ^= (
b), hash *= FNV_PRIME2; }
155 byte getHash() {
return ((hash >> 8) ^ hash) & 0xff; }
158 bool insertVal(
byte hash,
u256& val)
166 return table[hash] == val;
168 } constantPool(m_pool);
169 #define CONST_POOL_HASH_INIT() constantPool.hashInit() 170 #define CONST_POOL_HASH_BYTE(b) constantPool.hashByte(b) 171 #define CONST_POOL_GET_HASH() constantPool.getHash() 172 #define CONST_POOL_INSERT_VAL(hash, val) constantPool.insertVal((hash), (val)) 174 #define CONST_POOL_HASH_INIT() 175 #define CONST_POOL_HASH_BYTE(b) 176 #define CONST_POOL_GET_HASH() 0 177 #define CONST_POOL_INSERT_VAL(hash, val) false 180 TRACE_STR(1,
"Do first pass optimizations")
181 for (
size_t pc = 0; pc < nBytes; ++pc)
186 if ((
byte)Instruction::PUSH1 <= (
byte)op && (
byte)op <= (
byte)Instruction::PUSH32)
192 CONST_POOL_HASH_INIT();
194 for (uint64_t i = pc+2, n = nPush; --n; ++i) {
195 val = (val << 8) | m_code[i];
196 CONST_POOL_HASH_BYTE(m_code[i]);
199 #ifdef EVM_USE_CONSTANT_POOL 205 byte hash = CONST_POOL_GET_HASH();
206 if (CONST_POOL_INSERT_VAL(hash, val))
208 m_code[pc] = (
byte)Instruction::PUSHC;
210 m_code[pc+2] = nPush - 1;
217 #ifdef EVM_REPLACE_CONST_JUMP 222 size_t i = pc + nPush + 1;
224 if (op == Instruction::JUMP)
229 if (0 <= verifyJumpDest(val,
false))
230 m_code[i] =
byte(op = Instruction::JUMPC);
234 else if (op == Instruction::JUMPI)
239 if (0 <= verifyJumpDest(val,
false))
240 m_code[i] =
byte(op = Instruction::JUMPCI);
260 m_bounce = &VM::interpretCases;
275 using boost::multiprecision::limb_type;
279 if (static_cast<limb_type>(_exponent) & 1)
#define TRACE_STR(level, str)
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
#define TRACE_OP(level, pc, op)
int args
Number of items required on the stack for this instruction (and, for the purposes of ret...
#define TRACE_PRE_OPT(level, pc, op)
void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2)
#define TRACE_POST_OPT(level, pc, op)
std::hash for asio::adress
Instruction
Virtual machine bytecode instruction.
InstructionInfo instructionInfo(Instruction _inst)
Information on all the instructions.
int ret
Number of items placed (back) on the stack by this instruction, assuming args items were removed...
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Instruction
Virtual machine bytecode instruction.
Information structure for a particular instruction.
bool optimize(llvm::Module &_module)
Tier gasPriceTier
Tier for gas pricing.
#define TRACE_VAL(level, name, val)