mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10341 from ethereum/optimizeAllocation
Do not allocate memory objects if they will be assigned directly.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
uint[] memory x;
|
||||
uint y;
|
||||
assembly {
|
||||
y := x
|
||||
}
|
||||
// The value of an uninitialized dynamic array is not zero but rather
|
||||
// an address of a location in memory that has the value of zero.
|
||||
assert(y != 0);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() ->
|
||||
@@ -0,0 +1,30 @@
|
||||
contract C {
|
||||
function memorySize() internal pure returns (uint s) {
|
||||
assembly { s := mload(0x40) }
|
||||
}
|
||||
function f() public returns (uint, uint, uint) {
|
||||
uint a = memorySize();
|
||||
g();
|
||||
uint b = memorySize();
|
||||
h();
|
||||
uint c = memorySize();
|
||||
i();
|
||||
uint d = memorySize();
|
||||
return (b - a, c - b, d - c);
|
||||
}
|
||||
// In these functions, we do allocate memory in both cases.
|
||||
// In `i()`, this could be avoided but we would have to check
|
||||
// that all code paths return explicitly and provide a value.
|
||||
function g() internal returns (uint[40] memory) {
|
||||
}
|
||||
function h() internal returns (uint[40] memory t) {
|
||||
}
|
||||
function i() internal returns (uint[40] memory) {
|
||||
uint[40] memory x;
|
||||
return x;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 0x0500, 0x0500, 0x0a00
|
||||
@@ -0,0 +1,24 @@
|
||||
contract C {
|
||||
function memorySize() internal pure returns (uint s) {
|
||||
assembly { s := mload(0x40) }
|
||||
}
|
||||
function withValue() public pure returns (uint) {
|
||||
uint[20] memory x;
|
||||
uint memorySizeBefore = memorySize();
|
||||
uint[20] memory t = x;
|
||||
uint memorySizeAfter = memorySize();
|
||||
return memorySizeAfter - memorySizeBefore;
|
||||
}
|
||||
function withoutValue() public pure returns (uint) {
|
||||
uint[20] memory x;
|
||||
uint memorySizeBefore = memorySize();
|
||||
uint[20] memory t;
|
||||
uint memorySizeAfter = memorySize();
|
||||
return memorySizeAfter - memorySizeBefore;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// withValue() -> 0x00
|
||||
// withoutValue() -> 0x0280
|
||||
@@ -0,0 +1,24 @@
|
||||
contract C {
|
||||
struct S { uint x; uint y; uint z; }
|
||||
function memorySize() internal pure returns (uint s) {
|
||||
assembly { s := mload(0x40) }
|
||||
}
|
||||
function withValue() public pure returns (uint) {
|
||||
S memory x = S(1, 2, 3);
|
||||
uint memorySizeBefore = memorySize();
|
||||
S memory t = x;
|
||||
uint memorySizeAfter = memorySize();
|
||||
return memorySizeAfter - memorySizeBefore;
|
||||
}
|
||||
function withoutValue() public pure returns (uint) {
|
||||
uint memorySizeBefore = memorySize();
|
||||
S memory t;
|
||||
uint memorySizeAfter = memorySize();
|
||||
return memorySizeAfter - memorySizeBefore;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// withValue() -> 0x00
|
||||
// withoutValue() -> 0x60
|
||||
@@ -0,0 +1,7 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
uint[] memory x = x[0];
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 7576: (70-71): Undeclared identifier. "x" is not (or not yet) visible at this point.
|
||||
@@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
struct S { uint y; }
|
||||
function f() public pure {
|
||||
S memory x = x.y;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 7576: (90-91): Undeclared identifier. "x" is not (or not yet) visible at this point.
|
||||
Reference in New Issue
Block a user