Skip to content

Commit 4fe4091

Browse files
committed
Made memory improvements
1 parent dcd80d5 commit 4fe4091

File tree

1 file changed

+99
-15
lines changed

1 file changed

+99
-15
lines changed

src/diamond/DiamondUpgradeFacet.sol

Lines changed: 99 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ contract DiamondUpgradeFacet {
198198
* We store it at ptr to reuse that memory immediately.
199199
*/
200200
mstore(ptr, 0x3e62267c00000000000000000000000000000000000000000000000000000000)
201-
mstore(add(ptr, 0x04), _facet)
202201
/**
203202
* 3. Perform the staticcall.
204203
* We pass 0 for out and outSize to keep the return data in the
@@ -209,7 +208,7 @@ contract DiamondUpgradeFacet {
209208
gas(), // pass all available gas
210209
_facet, // target address
211210
ptr, // pointer to start of input
212-
0x24, // input length (4 bytes for selector and 32 bytes for address)
211+
0x4, // input length (4 bytes for selector)
213212
0, // output pointer, not used
214213
0 // output length, not used
215214
)
@@ -250,15 +249,13 @@ contract DiamondUpgradeFacet {
250249
*/
251250
size := sub(size, 0x20) // Adjust size to account for the 32-byte offset word
252251
returndatacopy(ptr, 0x20, size)
253-
254252
selectors := ptr
255-
256253
/**
257254
* 6. Update Free Memory Pointer
258255
* New Free Memory Pointer is after the copied selectors.
259256
* Solidity requires the Free Memory Pointer to be aligned to 32 bytes.
260257
* 1. add(ptr, size) - end of copied selectors
261-
* 2. add(..., 0x1f) - round up to next 32-byte boundary
258+
* 2. add(..., 0x1f) - round up to next 32-byte boundary (0x1f is 31)
262259
* 3. and(..., not(0x1f)) - clear lower 5 bits to align to 32 bytes
263260
*/
264261
mstore(
@@ -286,6 +283,93 @@ contract DiamondUpgradeFacet {
286283
}
287284

288285
function addFacets(address[] calldata _facets) internal {
286+
DiamondStorage storage s = getDiamondStorage();
287+
uint256 facetLength = _facets.length;
288+
if (facetLength == 0) {
289+
return;
290+
}
291+
FacetList memory facetList = s.facetList;
292+
/*
293+
* Store current Free Memory Pointer to restore later.
294+
* This is use to reuse memory in each loop iteration.
295+
*/
296+
uint256 freeMemPtr;
297+
assembly ("memory-safe") {
298+
freeMemPtr := mload(0x40)
299+
}
300+
bytes4 prevFacetNodeId = facetList.lastFacetNodeId;
301+
address facet = _facets[0];
302+
bytes memory selectors = packedSelectors(facet);
303+
uint256 selectorsLength = selectors.length / 4;
304+
facetList.selectorCount += uint32(selectorsLength);
305+
bytes4 currentFacetNodeId = at(selectors, 0);
306+
if (facetList.facetCount == 0) {
307+
facetList.firstFacetNodeId = currentFacetNodeId;
308+
} else {
309+
s.facetNodes[prevFacetNodeId].nextFacetNodeId = currentFacetNodeId;
310+
}
311+
if (facetLength == 1) {
312+
if (s.facetNodes[currentFacetNodeId].facet != address(0)) {
313+
revert CannotAddFunctionToDiamondThatAlreadyExists(currentFacetNodeId);
314+
}
315+
s.facetNodes[currentFacetNodeId] = FacetNode(facet, prevFacetNodeId, bytes4(0));
316+
}
317+
emit DiamondFunctionAdded(currentFacetNodeId, facet);
318+
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
319+
bytes4 selector = at(selectors, selectorIndex);
320+
if (s.facetNodes[selector].facet != address(0)) {
321+
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
322+
}
323+
s.facetNodes[selector] = FacetNode(facet, bytes4(0), bytes4(0));
324+
emit DiamondFunctionAdded(selector, facet);
325+
}
326+
/*
327+
* Restore Free Memory Pointer to reuse memory from packedSelectors() calls.
328+
*/
329+
assembly ("memory-safe") {
330+
mstore(0x40, freeMemPtr)
331+
}
332+
for (uint256 i = 1; i < facetLength; i++) {
333+
if (s.facetNodes[currentFacetNodeId].facet != address(0)) {
334+
revert CannotAddFunctionToDiamondThatAlreadyExists(currentFacetNodeId);
335+
}
336+
address nextFacet = _facets[i];
337+
selectors = packedSelectors(nextFacet);
338+
selectorsLength = selectors.length / 4;
339+
facetList.selectorCount += uint32(selectorsLength);
340+
bytes4 nextFacetNodeId = at(selectors, 0);
341+
s.facetNodes[currentFacetNodeId] = FacetNode(facet, prevFacetNodeId, nextFacetNodeId);
342+
facet = nextFacet;
343+
prevFacetNodeId = currentFacetNodeId;
344+
currentFacetNodeId = nextFacetNodeId;
345+
emit DiamondFunctionAdded(currentFacetNodeId, facet);
346+
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
347+
bytes4 selector = at(selectors, selectorIndex);
348+
if (s.facetNodes[selector].facet != address(0)) {
349+
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
350+
}
351+
s.facetNodes[selector] = FacetNode(facet, bytes4(0), bytes4(0));
352+
emit DiamondFunctionAdded(selector, facet);
353+
}
354+
/*
355+
* Restore Free Memory Pointer to reuse memory from packedSelectors() calls.
356+
*/
357+
assembly ("memory-safe") {
358+
mstore(0x40, freeMemPtr)
359+
}
360+
}
361+
if (s.facetNodes[currentFacetNodeId].facet != address(0)) {
362+
revert CannotAddFunctionToDiamondThatAlreadyExists(currentFacetNodeId);
363+
}
364+
s.facetNodes[currentFacetNodeId] = FacetNode(facet, prevFacetNodeId, bytes4(0));
365+
unchecked {
366+
facetList.facetCount += uint32(facetLength);
367+
}
368+
facetList.lastFacetNodeId = currentFacetNodeId;
369+
s.facetList = facetList;
370+
}
371+
372+
function addFacetsOld(address[] calldata _facets) internal {
289373
DiamondStorage storage s = getDiamondStorage();
290374
if (_facets.length == 0) {
291375
return;
@@ -295,9 +379,9 @@ contract DiamondUpgradeFacet {
295379
* Store current Free Memory Pointer to restore later.
296380
* This is use to reuse memory in each loop iteration.
297381
*/
298-
uint256 freeMemoryPointerLocation;
382+
uint256 freeMemPtr;
299383
assembly ("memory-safe") {
300-
freeMemoryPointerLocation := mload(0x40)
384+
freeMemPtr := mload(0x40)
301385
}
302386
bytes4 prevFacetNodeId = facetList.lastFacetNodeId;
303387
bytes memory selectors = packedSelectors(_facets[0]);
@@ -323,9 +407,10 @@ contract DiamondUpgradeFacet {
323407
}
324408
/*
325409
* Restore Free Memory Pointer to reuse memory from packedSelectors() calls.
410+
* // have to fix this.
326411
*/
327412
assembly ("memory-safe") {
328-
mstore(0x40, freeMemoryPointerLocation)
413+
mstore(0x40, freeMemPtr)
329414
}
330415
address oldFacet = s.facetNodes[currentFacetNodeId].facet;
331416
if (oldFacet != address(0)) {
@@ -370,9 +455,9 @@ contract DiamondUpgradeFacet {
370455
* Store current Free Memory Pointer to restore later.
371456
* This is use to reuse memory in each loop iteration.
372457
*/
373-
uint256 freeMemoryPointerLocation;
458+
uint256 freeMemPtr;
374459
assembly ("memory-safe") {
375-
freeMemoryPointerLocation := mload(0x40)
460+
freeMemPtr := mload(0x40)
376461
}
377462
for (uint256 i; i < _replaceFacets.length; i++) {
378463
address oldFacet = _replaceFacets[i].oldFacet;
@@ -396,9 +481,8 @@ contract DiamondUpgradeFacet {
396481
* Restore Free Memory Pointer to reuse memory.
397482
*/
398483
assembly ("memory-safe") {
399-
mstore(0x40, freeMemoryPointerLocation)
484+
mstore(0x40, freeMemPtr)
400485
}
401-
402486
if (oldCurrentFacetNodeId != newCurrentFacetNodeId) {
403487
/**
404488
* Write first selector with linking info, then process remaining.
@@ -505,9 +589,9 @@ contract DiamondUpgradeFacet {
505589
* Store current Free Memory Pointer to restore later.
506590
* This is use to reuse memory in each loop iteration.
507591
*/
508-
uint256 freeMemoryPointerLocation;
592+
uint256 freeMemPtr;
509593
assembly ("memory-safe") {
510-
freeMemoryPointerLocation := mload(0x40)
594+
freeMemPtr := mload(0x40)
511595
}
512596
for (uint256 i = 0; i < _facets.length; i++) {
513597
address facet = _facets[i];
@@ -526,7 +610,7 @@ contract DiamondUpgradeFacet {
526610
* Restore Free Memory Pointer to reuse memory.
527611
*/
528612
assembly ("memory-safe") {
529-
mstore(0x40, freeMemoryPointerLocation)
613+
mstore(0x40, freeMemPtr)
530614
}
531615
/**
532616
* Remove the facet from the linked list.

0 commit comments

Comments
 (0)