| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
Optimize type casting by using `__transmute` instead of `asm` blocks (#7675) ## Description This PR improves gas costs and bytecode sizes by consistently replacing `asm`-based conversions of _reference types_ in `std` with `__transmute`. Note that **copy-types are still converted using `asm` blocks**, because currently we didn't extend `__transmute` to handle copy-types without demoting transmuted values to stack and actually casting pointers. This gives a performance penalty when transmuting copy-types which we don't want to have. As expected, removing `asm` blocks unlocked existing IR performance optimizations and resulted in performance improvements given in the comment below. Note that we might think of temporarily forbidding using `__transmute` with copy-types until it is properly supported. But we have code in `ops.sw` where `__transmute` must be used to convert between copy-types, because the operator trait methods must be const-evaluable and if they use `asm` for conversion, they cannot be. Historically, making them const-evaluable was the reason for adding `__transmute` in the first place. Note that in the future, we plan to improve IR optimizations by letting them be aware of "safe `asm` blocks". Pure conversion blocks will be considered safe. That improvement would likely bring the same performance benefits as rolling out `__transmute`, but: - it will take some time before we get it implemented, - regardless, `__transmute` is the expected way to convert types and we should use it consistentlty across the codebase. Note that the PR changes snapshot files in the `sway-ir` tests. These changes are not related to this PR, but likely to the snapshots not being updated because of the `insta` checks being silent. For more info see https://github.com/FuelLabs/sway/pull/7666#pullrequestreview-4589675640. ## Checklist - [x] I have linked to any relevant issues. - [ ] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [ ] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Implement dynamic storage based `StorageVec` (#7614) ## Description This PR is an additional step in implementing #7560. It implements `StorageVec<V>` for dynamic storage. Additionally the PR: - adds comprehensive test coverage for `StorageVec` in the form of in-language tests. Existing SDK harness tests are deleted in favor of new in-language tests. This is aligned with the agreed strategy to migrate SDK harness tests to in-language tests. - closes #6040 by properly documenting the semantics of zero-sized types in relation to storage. Every `StorageVec<V>` methods that does not work with zero-sized types, which are assumed to be nested storage types, is now documented for limitations. - fixes #7618 by accepting non-aligned types of any size in `store_vec` and `load_vec` and padding them accordingly. - fixes existing issue of over-allocating memory and having larger amount of slot writes than needed in the quads-based implementation of `store_vec`. - consistently add reverts to all existing `StorageVec<V>` methods in the quads-based implementation that cannot be used with nested storage types. For more details see Breaking Changes below. When running in-language tests using `forc test` on the whole workspace two blocking issues occur: - #7612 - #7613 Workarounds for those issues are commented in code and linked to the issues. Additional in-language tests for other storage types will be added in a separate PR. ## Breaking Changes Existing `StorageVec<V>` methods in the quads-based implementation that cannot be used with nested storage types, e.g., `swap` now consistently reverts if `V` is a nested storage type. Previously, those methods: - sometimes always reverted, - sometimes reverted in specific paths, - sometimes executed with undefined behavior. Consistently reverting can be a breaking change if some existing code called these methods and they were not reverting. Note that such calls represent invalid usage of the storage API (although it was up to now not clearly documented as such) and reverting will actually point to bugs in existing callers code. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 4 个月前 | |
Optimize dynamic `std` types (#7683) ## Description This PR optimizes several aspects of dynamic `std` types: - Hashing of string arrays, by properly accommodating initial `Hasher` buffer capacity for the string length prefix. - `Bytes::clear`, by reusing the already allocated buffer, the same way `Vec` is doing it. - Removing expensive double-allocation and memory-copy in the `Bytes::append_raw_slice`. - Adding `from_moved_...` constructors to types that own their buffers, for supporting taking ownership of the content without copying it. - Adding `from_ascii_str_array` constructor to `String` to create a string directly from string array without a need to first copy it to `str` via `from_str_array`. Additionally, the PR: - fixes invalid doc-comment examples on `String` methods, that were using a non-existing `String::push` method. ## Performance Improvements Performance improvements are given in the comment below. Although the PR obviously only removes runtime overhead, we still have some smaller numbers of regressions. Regressions are analyzed and have the same root-cause, the one we already encountered before. The leaner `Bytes::append_raw_slice` now leads to more inlining in hashing code like `sha256` that brings `CastPtr` to caller scope suppressing potential optimizations in the caller. The regressions on real-life o2 code are small and in contract methods that are not frequently used while improvements are bigger and in often use contract methods. Improving this particular issue will be done in #7492. Also, analysis of regressions in `sha256` and `keccak256` calls revealed another potentially high future performance improvement. E.g., hashing a `b256` using `s256` opcode directly costs ~60 gas units, while using `sha256` function will cost ~250 gas units. Similar values for are for `u8`, .., `u256` and even worse for larger structured types. One way to improve our hashing abstractions is to introduce a concept of "trivially hashable types", similar to trivially encodeable and decodeable. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Implement dynamic storage for `storage` declaration and `std` (#7598) ## Description This PR is a part of #7560 implementation and implements: - `storage` fields access compilation for dynamic storage. - dynamic storage for all the types and functions in the `std::storage` module, except the `StorageVec`. In the `storage_api`, support for dynamic storage is added as the extension to the existing API based on quads. The reason is that we will need to support quad-based storage for backwards compatibility, for contracts that cannot migrate all the data, but still want to use, in parallel, the benefits of dynamic storage. The existing API is marked as deprecated in favor of the new API in which the function suffix, either `quads` or `slot(s)`, clearly indicates what kind of storage access the function performs. Additionally, the existing `clear` API that returned boolean information about slot occupancy is split into two distinctive APIs: `clear` that only clears and doesn't return occupancy information, and `clear_existed` that returns boolean information about slot occupancy. Introducing two variants for clearing is done for performance reasons. Returning the occupancy information in dynamic storage case requires more gas, and in many of the cases that information is not needed. Having two distinctive function allows developers to opt-in for the cost. Additionally, the PR: - fixes bug in `ir_generation::purity::check_function_purity` where `StateUpdateSlot` IR instruction and `supd/supi` opcodes were still be considered as reading and writing operations instead of only writing. - closes #6829 by properly documenting the semantic of zero-sized types in relation to storage. Planned next steps are: - Adding additional comprehensive test coverage. Some of the existing tests are adapted to test the new API and dynamic storage in this PR. Considering the impact of the change, unlike for other experimental feature, we want dynamic storage test to be included in all the tests that are currently testing storage. - Further optimizing writing to storage by supporting `__state_store_slot` in the `StorageKey`. `__state_store_slot` intrinsic is used in storage types, e.g. when storing slices or inserting into a `StorageMap`, but currently not in the `StorageKey` in general. There, `__state_update_slot` is always used. Supporting `__state_store_slot` in the `StorageKey` requires introduction of an additional abstraction that will allow us to express that a `StorageKey` points to a value that is guaranteed to be the only value in the slot. - Enabling SDK tests for `StorageVec`s that are temporarily disabled. This will be done when dynamic storage version of `StorageVec` is implemented. - Emitting `<project>-storage_slots.json` for dynamic storage and properly consuming them in the SDK. Until then, some of the tests are disabled and marked as `TODO: (INIT-STORAGE)`. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 4 个月前 | |
Implement dynamic storage for `storage` declaration and `std` (#7598) ## Description This PR is a part of #7560 implementation and implements: - `storage` fields access compilation for dynamic storage. - dynamic storage for all the types and functions in the `std::storage` module, except the `StorageVec`. In the `storage_api`, support for dynamic storage is added as the extension to the existing API based on quads. The reason is that we will need to support quad-based storage for backwards compatibility, for contracts that cannot migrate all the data, but still want to use, in parallel, the benefits of dynamic storage. The existing API is marked as deprecated in favor of the new API in which the function suffix, either `quads` or `slot(s)`, clearly indicates what kind of storage access the function performs. Additionally, the existing `clear` API that returned boolean information about slot occupancy is split into two distinctive APIs: `clear` that only clears and doesn't return occupancy information, and `clear_existed` that returns boolean information about slot occupancy. Introducing two variants for clearing is done for performance reasons. Returning the occupancy information in dynamic storage case requires more gas, and in many of the cases that information is not needed. Having two distinctive function allows developers to opt-in for the cost. Additionally, the PR: - fixes bug in `ir_generation::purity::check_function_purity` where `StateUpdateSlot` IR instruction and `supd/supi` opcodes were still be considered as reading and writing operations instead of only writing. - closes #6829 by properly documenting the semantic of zero-sized types in relation to storage. Planned next steps are: - Adding additional comprehensive test coverage. Some of the existing tests are adapted to test the new API and dynamic storage in this PR. Considering the impact of the change, unlike for other experimental feature, we want dynamic storage test to be included in all the tests that are currently testing storage. - Further optimizing writing to storage by supporting `__state_store_slot` in the `StorageKey`. `__state_store_slot` intrinsic is used in storage types, e.g. when storing slices or inserting into a `StorageMap`, but currently not in the `StorageKey` in general. There, `__state_update_slot` is always used. Supporting `__state_store_slot` in the `StorageKey` requires introduction of an additional abstraction that will allow us to express that a `StorageKey` points to a value that is guaranteed to be the only value in the slot. - Enabling SDK tests for `StorageVec`s that are temporarily disabled. This will be done when dynamic storage version of `StorageVec` is implemented. - Emitting `<project>-storage_slots.json` for dynamic storage and properly consuming them in the SDK. Until then, some of the tests are disabled and marked as `TODO: (INIT-STORAGE)`. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 4 个月前 | |
Optimize dynamic `std` types (#7683) ## Description This PR optimizes several aspects of dynamic `std` types: - Hashing of string arrays, by properly accommodating initial `Hasher` buffer capacity for the string length prefix. - `Bytes::clear`, by reusing the already allocated buffer, the same way `Vec` is doing it. - Removing expensive double-allocation and memory-copy in the `Bytes::append_raw_slice`. - Adding `from_moved_...` constructors to types that own their buffers, for supporting taking ownership of the content without copying it. - Adding `from_ascii_str_array` constructor to `String` to create a string directly from string array without a need to first copy it to `str` via `from_str_array`. Additionally, the PR: - fixes invalid doc-comment examples on `String` methods, that were using a non-existing `String::push` method. ## Performance Improvements Performance improvements are given in the comment below. Although the PR obviously only removes runtime overhead, we still have some smaller numbers of regressions. Regressions are analyzed and have the same root-cause, the one we already encountered before. The leaner `Bytes::append_raw_slice` now leads to more inlining in hashing code like `sha256` that brings `CastPtr` to caller scope suppressing potential optimizations in the caller. The regressions on real-life o2 code are small and in contract methods that are not frequently used while improvements are bigger and in often use contract methods. Improving this particular issue will be done in #7492. Also, analysis of regressions in `sha256` and `keccak256` calls revealed another potentially high future performance improvement. E.g., hashing a `b256` using `s256` opcode directly costs ~60 gas units, while using `sha256` function will cost ~250 gas units. Similar values for are for `u8`, .., `u256` and even worse for larger structured types. One way to improve our hashing abstractions is to introduce a concept of "trivially hashable types", similar to trivially encodeable and decodeable. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 | |
Optimize dynamic `std` types (#7683) ## Description This PR optimizes several aspects of dynamic `std` types: - Hashing of string arrays, by properly accommodating initial `Hasher` buffer capacity for the string length prefix. - `Bytes::clear`, by reusing the already allocated buffer, the same way `Vec` is doing it. - Removing expensive double-allocation and memory-copy in the `Bytes::append_raw_slice`. - Adding `from_moved_...` constructors to types that own their buffers, for supporting taking ownership of the content without copying it. - Adding `from_ascii_str_array` constructor to `String` to create a string directly from string array without a need to first copy it to `str` via `from_str_array`. Additionally, the PR: - fixes invalid doc-comment examples on `String` methods, that were using a non-existing `String::push` method. ## Performance Improvements Performance improvements are given in the comment below. Although the PR obviously only removes runtime overhead, we still have some smaller numbers of regressions. Regressions are analyzed and have the same root-cause, the one we already encountered before. The leaner `Bytes::append_raw_slice` now leads to more inlining in hashing code like `sha256` that brings `CastPtr` to caller scope suppressing potential optimizations in the caller. The regressions on real-life o2 code are small and in contract methods that are not frequently used while improvements are bigger and in often use contract methods. Improving this particular issue will be done in #7492. Also, analysis of regressions in `sha256` and `keccak256` calls revealed another potentially high future performance improvement. E.g., hashing a `b256` using `s256` opcode directly costs ~60 gas units, while using `sha256` function will cost ~250 gas units. Similar values for are for `u8`, .., `u256` and even worse for larger structured types. One way to improve our hashing abstractions is to introduce a concept of "trivially hashable types", similar to trivially encodeable and decodeable. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. | 2 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 2 个月前 | ||
| 4 个月前 | ||
| 2 个月前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 2 个月前 | ||
| 2 个月前 |