mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-14 15:41:04 +00:00
a07968205b
- Add the revive runtime function interface to minimize boiler plate code. - Outline heavily repeated code into dedicated functions to bring down code size. - The code size tests builds optimized for size. - Function attributes are passed as slices. This significantly brings down the code size for all OpenZeppelin wizard contracts (using all possible features) compiled against OpenZeppelin `v5.0.0` with size optimizations. |contract|| `-Oz` main | `-Oz` PR || `-O3` main | `-O3` PR | |-|-|-|-|-|-|-| |erc1155.sol||100K|67K||114K|147K| |erc20.sol||120K|90K||160K|191K| |erc721.sol||128K|101K||178K|214K| |governor.sol||226K|165K||293K|349K| |rwa.sol||116K|85K||154K|185K| |stable.sol||116K|86K||155K|192K| On the flip side this introduces a heavy penalty for cycle optimized builds. Setting the no-inline attributes for cycle optimized builds helps a lot but heavily penalizes runtime speed (LLVM does not yet inline everything properly - to be investigated later on). Next steps: - Modularize more functions - Refactor the YUL function arguments to use pointers instead of values - Afterwards check if LLVM still has trouble inline-ing properly on O3 or set the no-inline attribute if it does not penalize runtime performance too bad.
128 lines
3.1 KiB
C
128 lines
3.1 KiB
C
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include "polkavm_guest.h"
|
|
|
|
// Missing builtins
|
|
|
|
#define EVM_WORD_SIZE 32
|
|
#define ALIGN(size) ((size + EVM_WORD_SIZE - 1) & ~(EVM_WORD_SIZE - 1))
|
|
#define MAX_MEMORY_SIZE (64 * 1024)
|
|
char __memory[MAX_MEMORY_SIZE];
|
|
uint32_t __memory_size = 0;
|
|
|
|
void * __sbrk_internal(uint32_t offset, uint32_t size) {
|
|
if (offset >= MAX_MEMORY_SIZE || size > MAX_MEMORY_SIZE) {
|
|
POLKAVM_TRAP();
|
|
}
|
|
|
|
uint32_t new_size = ALIGN(offset + size);
|
|
if (new_size > MAX_MEMORY_SIZE) {
|
|
POLKAVM_TRAP();
|
|
}
|
|
if (new_size > __memory_size) {
|
|
__memory_size = new_size;
|
|
}
|
|
|
|
return (void *)&__memory[offset];
|
|
}
|
|
|
|
void * memset(void *b, int c, size_t len) {
|
|
uint8_t *dest = b;
|
|
while (len-- > 0) *dest++ = c;
|
|
return b;
|
|
}
|
|
|
|
void * memcpy(void *dst, const void *_src, size_t len) {
|
|
uint8_t *dest = dst;
|
|
const uint8_t *src = _src;
|
|
|
|
while (len--) *dest++ = *src++;
|
|
|
|
return dst;
|
|
}
|
|
|
|
void * memmove(void *dst, const void *src, size_t n) {
|
|
char *d = dst;
|
|
const char *s = src;
|
|
|
|
if (d==s) return d;
|
|
if ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return memcpy(d, s, n);
|
|
|
|
if (d<s) {
|
|
for (; n; n--) *d++ = *s++;
|
|
} else {
|
|
while (n) n--, d[n] = s[n];
|
|
}
|
|
|
|
return dst;
|
|
}
|
|
|
|
// Imports
|
|
|
|
POLKAVM_IMPORT(void, address, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, balance, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, balance_of, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, base_fee, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, block_author, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, block_hash, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, block_number, uint32_t)
|
|
|
|
POLKAVM_IMPORT(uint64_t, call, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t)
|
|
|
|
POLKAVM_IMPORT(uint64_t, call_data_copy, uint32_t, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(uint64_t, call_data_load, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(uint64_t, call_data_size)
|
|
|
|
POLKAVM_IMPORT(void, caller, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, chain_id, uint32_t)
|
|
|
|
POLKAVM_IMPORT(uint64_t, code_size, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, code_hash, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(uint64_t, delegate_call, uint64_t, uint64_t, uint64_t, uint32_t, uint64_t, uint64_t)
|
|
|
|
POLKAVM_IMPORT(void, deposit_event, uint32_t, uint32_t, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(uint64_t, gas_limit);
|
|
|
|
POLKAVM_IMPORT(uint64_t, gas_price);
|
|
|
|
POLKAVM_IMPORT(void, get_immutable_data, uint32_t, uint32_t);
|
|
|
|
POLKAVM_IMPORT(uint64_t, get_storage, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, hash_keccak_256, uint32_t, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(uint64_t, instantiate, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t)
|
|
|
|
POLKAVM_IMPORT(void, now, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, origin, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, seal_return, uint32_t, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(uint64_t, ref_time_left)
|
|
|
|
POLKAVM_IMPORT(void, return_data_copy, uint32_t, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(uint64_t, return_data_size)
|
|
|
|
POLKAVM_IMPORT(void, set_immutable_data, uint32_t, uint32_t);
|
|
|
|
POLKAVM_IMPORT(uint64_t, set_storage, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, value_transferred, uint32_t)
|
|
|
|
POLKAVM_IMPORT(void, weight_to_fee, uint64_t, uint64_t, uint32_t);
|