Skip to content

Commit

Permalink
Remove workaround with the HP pointer (FuelLabs#4643)
Browse files Browse the repository at this point in the history
## Description

Fixes FuelLabs#4246

## 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).
- [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.

---------

Co-authored-by: Joshua Batty <[email protected]>
Co-authored-by: Brandon Kite <[email protected]>
  • Loading branch information
3 people authored Jun 9, 2023
1 parent b38ea0a commit 2d23078
Show file tree
Hide file tree
Showing 8 changed files with 19 additions and 31 deletions.
34 changes: 12 additions & 22 deletions sway-lib-std/src/alloc.sw
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,33 @@ library;

/// Allocates zeroed memory on the heap.
///
/// In the FuelVM, the heap begins at `VM_MAX_RAM - 1` and grows downward.
/// The heap pointer, `$hp`, will always point to unallocated space.
/// In the FuelVM, the heap begins at `VM_MAX_RAM` and grows downward.
/// The heap pointer(`$hp`) always points to the first allocated byte.
///
/// Initially the heap will look like this:
/// ```
/// ▾$hp
/// ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
/// $hp^ ^VM_MAX_RAM
/// VM_MAX_RAM
/// ```
/// After allocating with `let ptr = alloc::<u64>(1)`:
/// ```
/// ▾$hp
/// ... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
/// $hp^ ^ptr ^VM_MAX_RAM
/// ptr VM_MAX_RAM
/// ```
/// After writing with `sw(ptr, u64::max())`:
/// ```
/// ▾$hp
/// ... 00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF |
/// $hp^ ^ptr ^VM_MAX_RAM
/// ptr VM_MAX_RAM
/// ```
/// For more information, see the Fuel Spec for [VM Initialization](https://fuellabs.github.io/fuel-specs/master/vm#vm-initialization)
/// and the VM Instruction Set for [Memory Allocation](https://fuellabs.github.io/fuel-specs/master/vm/instruction_set.html#aloc-allocate-memory).
///
/// NOTE: See https://github.com/FuelLabs/fuel-specs/pull/464 and related PRs. There is an upcoming
/// breaking change to the VM which 'corrects' the above behaviour to be more intuitive. Instead of
/// `$hp` pointing to the last byte of free memory it will instead point to the bottom of allocated
/// memory. So it will be initialized to `VM_MAX_RAM` and after an `ALOC` it will point directly to
/// the new buffer.
///
/// To avoid the need to synchronize the behaviours between this library and the two allocation
/// modes, i.e., before and after the breaking change, we allocate 1 extra byte here and still
/// return `$hp + 1`. So prior to the VM change every allocation will have an unused byte _after_
/// the buffer and after the change every allocation will have an unused byte _before_ the buffer.
pub fn alloc<T>(count: u64) -> raw_ptr {
asm(size: __size_of::<T>() * count + 1, ptr) {
asm(size: __size_of::<T>() * count, ptr) {
aloc size;
// `$hp` points to unallocated space and heap grows downward so
// our newly allocated space will be right after it.
addi ptr hp i1;
move ptr hp;
ptr: raw_ptr
}
}
Expand All @@ -59,9 +49,9 @@ pub fn realloc<T>(ptr: raw_ptr, count: u64, new_count: u64) -> raw_ptr {

/// Allocates zeroed memory on the heap in individual bytes.
pub fn alloc_bytes(count: u64) -> raw_ptr {
asm(size: count + 1, ptr) {
asm(size: count, ptr) {
aloc size;
addi ptr hp i1;
move ptr hp;
ptr: raw_ptr
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
category = "run"
expected_result = { action = "return", value = 67108855 }
expected_result = { action = "return", value = 67108856 }
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
category = "run"
expected_result = { action = "return_data", value = "0000000003ffffc500000000000000040000000000000003" }
expected_result = { action = "return_data", value = "0000000003ffffc800000000000000040000000000000003" }
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ script;
use basic_storage_abi::{BasicStorage, Quad};

fn main() -> u64 {
let addr = abi(BasicStorage, 0x30a664b11896792cc65021bc1253260a7b6f4c110e5e79a5cb0bd11f72adc59c);
let addr = abi(BasicStorage, 0x653cdcadb583d948a54d530166d558671fd6e4947018d3411afd0c207430ec15);
let key = 0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
let value = 4242;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ script;
use increment_abi::Incrementor;

fn main() -> bool {
let the_abi = abi(Incrementor, 0x29e6359ab1febd63fe10e78c9f40003335374b0a788b12d4c6e4c61fbe26788e);
let the_abi = abi(Incrementor, 0xb1e5d89c93b868694aa3cb65a7d69912ed08ae6a318b099cc86d2f8e1f8212ef);
the_abi.increment(5);
the_abi.increment(5);
let result = the_abi.get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use storage_access_abi::*;
use std::hash::sha256;

fn main() -> bool {
let contract_id = 0x563e287ad3b5a44355fbb7ed0d9f530462e46627a82617abf7047c76b0f0eb63;
let contract_id = 0x97b6be38b9ecbc3352ecffe46d162d776dbf121670ad7da93c4415a649624a14;
let caller = abi(StorageAccess, contract_id);

// Test initializers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn sw(ptr: raw_ptr, val: u64) {

fn heap_ptr() -> raw_ptr {
asm(ptr) {
addi ptr hp i1;
move ptr hp;
ptr: raw_ptr
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# This test is making assumptions about how `$hp` is used with allocations. It needs to be
# re-enabled after the VM introduces the new `ALOC` behaviour.
category = "disabled"
category = "run"
expected_result = { action = "return", value = 1 }
validate_abi = true

0 comments on commit 2d23078

Please sign in to comment.