Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor interpreter flow module #14

Closed
wants to merge 5 commits into from
Closed

Conversation

vlopes11
Copy link
Contributor

Instruction calls are to return Result instead of bool, except for ALU

Memory ownership checks should be centralized in its module

@vlopes11 vlopes11 self-assigned this Aug 20, 2021
@vlopes11 vlopes11 requested review from adlerjohn and Voxelot August 20, 2021 14:36
If an attempt to increase the stack space results in memory intersection
with the heap, then `ExecuteError::StackHeapCollision` should be
returned

Resolves #19
Instruction calls are to return `Result` instead of bool, except for ALU

Memory ownership checks should be centralized in its module
@vlopes11 vlopes11 force-pushed the vlopes11/flow-refactor branch from bcfe406 to eed8833 Compare August 23, 2021 23:11
self.registers[REG_SP] = result;
true
pub(crate) fn extend_call_frame(&mut self, imm: Word) -> Result<(), ExecuteError> {
if self.registers[REG_SP] > VM_MAX_RAM - imm {
Copy link
Contributor

@adlerjohn adlerjohn Aug 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if imm is 2^24-1? That's 16 MB, but VM_MAX_RAM might be less than that. This question applies to other unsafe arithmetic as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is true, I was under the wrong assumption that the VM ram is 32M when it is 1.

However, this brings up a new question: how can the MEM_MAX_ACCESS_SIZE (currently 32M) be bigger than VM_MAX_RAM? Should I reduce the MEM_MAX_ACCESS_SIZE to VM_MAX_RAM?
https://github.com/FuelLabs/fuel-vm/blob/master/src/consts.rs#L9-L10

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't be bigger, no. It should be reduced. But back to this specific issue: these subtractions are actually unsafe and shouldn't be optimized away. This PR should instead focus on refactoring the flow module to return result, and leave optimizations to future PRs if needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is correct. Without the assumption that VM_MAX_RAM == 32m, that calculation is unsafe.

That can be trivially solved by prepending one of these two:

  • imm > VM_MAX_RAM || self.registers[REG_SP] > VM_MAX_RAM - imm
  • imm > MEM_MAX_ACCESS_SIZE || self.registers[REG_SP] > VM_MAX_RAM - imm

I'll replicate this into the other verifications, ok?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While those checks seem to solve the issue, I think it would be more idiomatic to use checked_sub, no?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know enough about the vm memory model to verify all this unsafe code, but I wonder do we really need all this performance right now? Shouldn't we focus on being as correct as possible first, benchmark, then optimize?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @Voxelot. There will absolutely be time for optimizations later, but for now the priority should be functionality and correctness.

Copy link
Contributor Author

@vlopes11 vlopes11 Aug 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Voxelot the $sp can't ever be 0 or smaller than $ssp/$fp; otherwise its a severe violation of the initialization routine. There is a nit in the example code but it applies to both functions (if_add and checked_add): it should be >= VM_MAX_RAM, and not >.

As for the approach, all clear, but this is not hard optimization. My goal for now is to achieve a final form of the API, and these changes reflect on how the data backend should interact with the VM (e.g. last change to use references in the data trait).

If we achieve the final form of the API, then any further optimization will be done internally and/or incrementally.

A next step is to add some serious test coverage to catch all little edge cases.

Copy link
Member

@Voxelot Voxelot Aug 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given these are just opcode implementation details I don't see how these relate to holding up the design of the public api interface? This seems purely like premature optimization to me.

Copy link
Contributor Author

@vlopes11 vlopes11 Aug 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will know if these optimizations won't reflect anything into the API/sway/client/core after we have the full integration tests done.

Also, if you check, the signature of the functions changed. Instead of returning bool, they are returning Result. As much as that is not expected to impact sway/client, it is important to achieve consistency with these functions internally.

When I'm done migrating all of them to results (including the other PRs of the other modules), I'll then update the execute function. In that function, I'm (for the moment) using is_ok while I don't have all of them migrated

self.registers[ra] = self.block_height() as Word
Opcode::BHEI(ra) if Self::is_register_writable(ra) && self.gas_charge(&op).is_ok() => {
self.registers[ra] = self.block_height() as Word;
self.inc_pc();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These calls to inc_pc seems redundant and inconsistent. In some cases they are in the root opcode impl, and sometimes performed in lower methods.

Couldn't we just check the result of the opcode match and then do inc_pc in a single location?

Copy link
Contributor Author

@vlopes11 vlopes11 Aug 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These refactorings aim (also) to move all of them into the functions. Some opcodes increment the PC while some others doesn't

There is a lot of small nits like that I'm fixing with these PRs. When I'm finished with them, I'll change the way execute is implemented and create the constants for the gas cost

@vlopes11 vlopes11 marked this pull request as draft August 26, 2021 09:22
@adlerjohn adlerjohn linked an issue Aug 26, 2021 that may be closed by this pull request
@vlopes11
Copy link
Contributor Author

vlopes11 commented Nov 2, 2021

N/A

@vlopes11 vlopes11 closed this Nov 2, 2021
@vlopes11 vlopes11 deleted the vlopes11/flow-refactor branch August 1, 2022 17:36
ControlCplusControlV pushed a commit that referenced this pull request Nov 24, 2022
* Add script data offset function to tx

Script data offset will need to be accessible to users of the
transaction API in order to create data for scripts

* Update transaction script offset to return Option

The API must be consistent and when a function that is directed to a
specifc variant of transaction is called over a script or vice-versa, it
should be protected by either a result or an option.
ControlCplusControlV pushed a commit that referenced this pull request Nov 24, 2022
* Add serde-types feature

* Add iterator to bytes capability for Opcode
ControlCplusControlV pushed a commit that referenced this pull request Nov 24, 2022
ControlCplusControlV pushed a commit that referenced this pull request Nov 24, 2022
* Reintroduce auto_impl

* cargo sort
ControlCplusControlV pushed a commit that referenced this pull request Nov 29, 2022
* Reintroduce auto_impl

* cargo sort
ControlCplusControlV pushed a commit that referenced this pull request Dec 1, 2022
* Add script data offset function to tx

Script data offset will need to be accessible to users of the
transaction API in order to create data for scripts

* Update transaction script offset to return Option

The API must be consistent and when a function that is directed to a
specifc variant of transaction is called over a script or vice-versa, it
should be protected by either a result or an option.
ControlCplusControlV pushed a commit that referenced this pull request Dec 1, 2022
* Add serde-types feature

* Add iterator to bytes capability for Opcode
ControlCplusControlV pushed a commit that referenced this pull request Dec 1, 2022
mitchmindtree pushed a commit that referenced this pull request Dec 5, 2022
@mitchmindtree mitchmindtree added the fuel-vm Related to the `fuel-vm` crate. label Dec 9, 2022
xgreenx pushed a commit that referenced this pull request Dec 20, 2022
* Reintroduce auto_impl

* cargo sort
xgreenx pushed a commit that referenced this pull request Dec 20, 2022
* Add script data offset function to tx

Script data offset will need to be accessible to users of the
transaction API in order to create data for scripts

* Update transaction script offset to return Option

The API must be consistent and when a function that is directed to a
specifc variant of transaction is called over a script or vice-versa, it
should be protected by either a result or an option.
xgreenx pushed a commit that referenced this pull request Dec 20, 2022
xgreenx pushed a commit that referenced this pull request Dec 20, 2022
* Add serde-types feature

* Add iterator to bytes capability for Opcode
xgreenx pushed a commit that referenced this pull request Dec 20, 2022
xgreenx pushed a commit that referenced this pull request Dec 20, 2022
* Reintroduce auto_impl

* cargo sort
xgreenx pushed a commit that referenced this pull request Dec 20, 2022
* Add script data offset function to tx

Script data offset will need to be accessible to users of the
transaction API in order to create data for scripts

* Update transaction script offset to return Option

The API must be consistent and when a function that is directed to a
specifc variant of transaction is called over a script or vice-versa, it
should be protected by either a result or an option.
xgreenx pushed a commit that referenced this pull request Dec 20, 2022
xgreenx pushed a commit that referenced this pull request Dec 20, 2022
* Add serde-types feature

* Add iterator to bytes capability for Opcode
xgreenx pushed a commit that referenced this pull request Dec 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fuel-vm Related to the `fuel-vm` crate.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Stack increase should emit StackCollision
4 participants