Round up allocations to multiples of 32.

This commit is contained in:
chriseth 2021-01-14 19:42:07 +01:00 committed by Alex Beregszaszi
parent 31ee06d945
commit db4b39e09e
20 changed files with 86 additions and 58 deletions

View File

@ -2805,7 +2805,7 @@ string YulUtilFunctions::allocationFunction()
return Whiskers(R"(
function <functionName>(size) -> memPtr {
memPtr := mload(<freeMemoryPointer>)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, <roundUp>(size))
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { <panic>() }
mstore(<freeMemoryPointer>, newFreePtr)
@ -2813,6 +2813,7 @@ string YulUtilFunctions::allocationFunction()
)")
("functionName", functionName)
("freeMemoryPointer", to_string(CompilerUtils::freeMemoryPointer))
("roundUp", roundUpFunction())
("panic", panicFunction(PanicCode::ResourceError))
.render();
});

View File

@ -110,7 +110,7 @@ object "C_81" {
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
@ -295,6 +295,10 @@ object "C_81" {
revert(0, 0x24)
}
function round_up_to_mul_of_32(value) -> result {
result := and(add(value, 31), not(31))
}
function shift_right_224_unsigned(value) -> newValue {
newValue :=

View File

@ -72,7 +72,7 @@ object "D_16" {
function allocateMemory(size) -> memPtr
{
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, and(add(size, 31), not(31)))
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
}

View File

@ -19,44 +19,40 @@ object "C_59" {
object "C_59_deployed" {
code {
{
let _1 := 64
mstore(_1, 128)
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let _2 := 0
if eq(0xf8eddcc6, shr(224, calldataload(_2)))
let _1 := 0
if eq(0xf8eddcc6, shr(224, calldataload(_1)))
{
if callvalue() { revert(_2, _2) }
let _3 := 32
if slt(add(calldatasize(), not(3)), _3) { revert(_2, _2) }
if callvalue() { revert(_1, _1) }
let _2 := 32
if slt(add(calldatasize(), not(3)), _2) { revert(_1, _1) }
let offset := calldataload(4)
let _4 := 0xffffffffffffffff
if gt(offset, _4) { revert(_2, _2) }
if iszero(slt(add(offset, 35), calldatasize())) { revert(_2, _2) }
let _5 := calldataload(add(4, offset))
if gt(_5, _4) { panic_error_0x41() }
let _6 := mul(_5, _3)
let dst := allocateMemory(add(_6, _3))
let _3 := 0xffffffffffffffff
if gt(offset, _3) { revert(_1, _1) }
if iszero(slt(add(offset, 35), calldatasize())) { revert(_1, _1) }
let _4 := calldataload(add(4, offset))
if gt(_4, _3) { panic_error_0x41() }
let _5 := mul(_4, _2)
let dst := allocateMemory(add(_5, _2))
let dst_1 := dst
mstore(dst, _5)
dst := add(dst, _3)
mstore(dst, _4)
dst := add(dst, _2)
let src := add(offset, 36)
if gt(add(add(offset, _6), 36), calldatasize()) { revert(_2, _2) }
let i := _2
for { } lt(i, _5) { i := add(i, 1) }
if gt(add(add(offset, _5), 36), calldatasize()) { revert(_1, _1) }
let i := _1
for { } lt(i, _4) { i := add(i, 1) }
{
if slt(sub(calldatasize(), src), _3) { revert(_2, _2) }
let memPtr := mload(_1)
let newFreePtr := add(memPtr, _3)
if or(gt(newFreePtr, _4), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(_1, newFreePtr)
mstore(memPtr, calldataload(src))
mstore(dst, memPtr)
dst := add(dst, _3)
src := add(src, _3)
if slt(sub(calldatasize(), src), _2) { revert(_1, _1) }
let value := allocateMemory(_2)
mstore(value, calldataload(src))
mstore(dst, value)
dst := add(dst, _2)
src := add(src, _2)
}
let ret, ret_1 := fun_sumArray_58(dst_1)
let memPos := allocateMemory(_2)
let memPos := allocateMemory(_1)
return(memPos, sub(abi_encode_uint256_t_string(memPos, ret, ret_1), memPos))
}
}
@ -83,16 +79,13 @@ object "C_59" {
function allocateMemory(size) -> memPtr
{
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, and(add(size, 31), not(31)))
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
}
function copy_literal_to_memory_64902fd228f7ef267f3b474dd6ef84bae434cf5546eee948e7ca26df3eda1927() -> memPtr
{
let memPtr_1 := mload(64)
let newFreePtr := add(memPtr_1, 160)
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr_1)) { panic_error_0x41() }
mstore(64, newFreePtr)
let memPtr_1 := allocateMemory(160)
mstore(memPtr_1, 100)
memPtr := memPtr_1
mstore(add(memPtr_1, 0x20), "longstringlongstringlongstringlo")

View File

@ -54,7 +54,7 @@ object "Arraysum_34" {
function allocateMemory(size) -> memPtr
{
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, and(add(size, 31), not(31)))
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr))
{
mstore(0, shl(224, 0x4e487b71))

File diff suppressed because one or more lines are too long

View File

@ -43,7 +43,7 @@ object \"C_7\" {
function allocateMemory(size) -> memPtr
{
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
}
@ -55,6 +55,10 @@ object \"C_7\" {
mstore(4, 0x41)
revert(0, 0x24)
}
function round_up_to_mul_of_32(value) -> result
{
result := and(add(value, 31), not(31))
}
function shift_right_224_unsigned(value) -> newValue
{ newValue := shr(224, value) }
}

View File

@ -60,7 +60,7 @@ object \"C_7\" {
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
@ -76,6 +76,10 @@ object \"C_7\" {
revert(0, 0x24)
}
function round_up_to_mul_of_32(value) -> result {
result := and(add(value, 31), not(31))
}
function shift_right_224_unsigned(value) -> newValue {
newValue :=

File diff suppressed because one or more lines are too long

View File

@ -111,7 +111,7 @@ object \"D_16\" {
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
@ -152,6 +152,10 @@ object \"D_16\" {
revert(0, returndatasize())
}
function round_up_to_mul_of_32(value) -> result {
result := and(add(value, 31), not(31))
}
function shift_right_224_unsigned(value) -> newValue {
newValue :=

View File

@ -67,7 +67,7 @@ object "test_11" {
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
@ -93,6 +93,10 @@ object "test_11" {
revert(0, 0x24)
}
function round_up_to_mul_of_32(value) -> result {
result := and(add(value, 31), not(31))
}
function shift_right_224_unsigned(value) -> newValue {
newValue :=

View File

@ -35,9 +35,9 @@ object "C_3" {
======= viair_subobjects/input.sol:D =======
Binary:
608060405234156100105760006000fd5b61010680610021600039806000f350fe6080604052600436101515610088576000803560e01c6326121ff0141561008657341561002a578081fd5b806003193601121561003a578081fd5b6028806080016080811067ffffffffffffffff8211171561005e5761005d6100c4565b5b50806100de60803980608083f01515610079573d82833e3d82fd5b508061008482610092565bf35b505b60006000fd6100dc565b6000604051905081810181811067ffffffffffffffff821117156100b9576100b86100c4565b5b80604052505b919050565b634e487b7160e01b600052604160045260246000fd5b565bfe60806040523415600f5760006000fd5b600a80601e600039806000f350fe608060405260006000fd
608060405234156100105760006000fd5b61010d80610021600039806000f350fe6080604052600436101515610088576000803560e01c6326121ff0141561008657341561002a578081fd5b806003193601121561003a578081fd5b6028806080016080811067ffffffffffffffff8211171561005e5761005d6100cb565b5b50806100e560803980608083f01515610079573d82833e3d82fd5b508061008482610092565bf35b505b60006000fd6100e3565b60006040519050601f19601f830116810181811067ffffffffffffffff821117156100c0576100bf6100cb565b5b80604052505b919050565b634e487b7160e01b600052604160045260246000fd5b565bfe60806040523415600f5760006000fd5b600a80601e600039806000f350fe608060405260006000fd
Binary of the runtime part:
6080604052600436101515610088576000803560e01c6326121ff0141561008657341561002a578081fd5b806003193601121561003a578081fd5b6028806080016080811067ffffffffffffffff8211171561005e5761005d6100c4565b5b50806100de60803980608083f01515610079573d82833e3d82fd5b508061008482610092565bf35b505b60006000fd6100dc565b6000604051905081810181811067ffffffffffffffff821117156100b9576100b86100c4565b5b80604052505b919050565b634e487b7160e01b600052604160045260246000fd5b565bfe60806040523415600f5760006000fd5b600a80601e600039806000f350fe608060405260006000fd
6080604052600436101515610088576000803560e01c6326121ff0141561008657341561002a578081fd5b806003193601121561003a578081fd5b6028806080016080811067ffffffffffffffff8211171561005e5761005d6100cb565b5b50806100e560803980608083f01515610079573d82833e3d82fd5b508061008482610092565bf35b505b60006000fd6100e3565b60006040519050601f19601f830116810181811067ffffffffffffffff821117156100c0576100bf6100cb565b5b80604052505b919050565b634e487b7160e01b600052604160045260246000fd5b565bfe60806040523415600f5760006000fd5b600a80601e600039806000f350fe608060405260006000fd
Optimized IR:
/*******************************************************
* WARNING *
@ -84,7 +84,7 @@ object "D_16" {
function allocateMemory(size) -> memPtr
{
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, and(add(size, 31), not(31)))
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
}

View File

@ -70,7 +70,7 @@ object \"C_11\" {
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)

View File

@ -66,7 +66,7 @@ object \"C_11\" {
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
@ -95,6 +95,10 @@ object \"C_11\" {
revert(0, 0x24)
}
function round_up_to_mul_of_32(value) -> result {
result := and(add(value, 31), not(31))
}
function shift_right_224_unsigned(value) -> newValue {
newValue :=

View File

@ -66,7 +66,7 @@ object \"C_11\" {
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
@ -100,6 +100,10 @@ object \"C_11\" {
revert(0, 0x24)
}
function round_up_to_mul_of_32(value) -> result {
result := and(add(value, 31), not(31))
}
function shift_left_224(value) -> newValue {
newValue :=

View File

@ -70,7 +70,7 @@ object \"C_11\" {
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)

View File

@ -66,7 +66,7 @@ object \"C_11\" {
function allocateMemory(size) -> memPtr {
memPtr := mload(64)
let newFreePtr := add(memPtr, size)
let newFreePtr := add(memPtr, round_up_to_mul_of_32(size))
// protect against overflow
if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() }
mstore(64, newFreePtr)
@ -100,6 +100,10 @@ object \"C_11\" {
revert(0, 0x24)
}
function round_up_to_mul_of_32(value) -> result {
result := and(add(value, 31), not(31))
}
function shift_left_224(value) -> newValue {
newValue :=

View File

@ -14,9 +14,9 @@ contract C {
}
// ----
// creation:
// codeDepositCost: 1174000
// codeDepositCost: 1175600
// executionCost: 1221
// totalCost: 1175221
// totalCost: 1176821
// external:
// a(): 1130
// b(uint256): infinite

View File

@ -17,9 +17,9 @@ contract C {
// optimize-yul: true
// ----
// creation:
// codeDepositCost: 587400
// codeDepositCost: 588800
// executionCost: 619
// totalCost: 588019
// totalCost: 589419
// external:
// a(): 1029
// b(uint256): 2084

View File

@ -15,5 +15,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes #