Skip to content
New issue

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

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

Already on GitHub? # to your account

Conditional jumps only check for address validity if the condition is true #469

Merged
merged 1 commit into from
Mar 17, 2023

Conversation

Dentosal
Copy link
Member

@Dentosal Dentosal commented Mar 13, 2023

This is the current VM bevior

@Dentosal Dentosal added documentation Improvements or additions to documentation comp:FVM Component: FuelVM labels Mar 13, 2023
@Dentosal Dentosal requested a review from a team March 13, 2023 19:06
@Dentosal Dentosal self-assigned this Mar 13, 2023
@Voxelot
Copy link
Member

Voxelot commented Mar 13, 2023

Is this for optimization purposes? Should we update the VM to always check the JMP args just for consistency?

@Dentosal
Copy link
Member Author

Is this for optimization purposes? Should we update the VM to always check the JMP args just for consistency?

It's faster to not check, but I'm not sure if this decision was done for optimization reasons. It's essentially saving us a couple of multiplications and maybe four local branches per each jump instruction where the branch is not selected. CPUs should be able to speculatively execute these anyway, so the performance penalty here is tiny.

However, I can imagine situations where not doing the check would allow the Sway compiler to produce smaller code. On the other hand, the possible gains are again minimal, since our instruction set is so inefficient anyway.

Still, one use case for not checking is combining a niche optimization with a jump table. Imagine that we have a counter that's Option<u64>, but we know that the max value will never be reached, so we reuse u64::MAX to encode None, so the whole value fits into a 8-byte register. Then when we want to do a jump table lookup using that value, we could do something like this:

/// Assume the $a register is of the above `Option<u64>` type
not $tmp, $zero                         // Set $tmp to u64::MAX
jnef $tmp, $a, $a, offset_to(.table)    // Do jump table jump only if we have Some(x)

// Here is the processing for None
rvrt

// This is the jump table
.table:
jmp foo
jmp bar
jmp baz

In this case, the check would fail since the jump target address is u64::MAX which is way above vm ram limit, but the jump is never performed with that value.

@Dentosal Dentosal merged commit 8257ff4 into master Mar 17, 2023
@Dentosal Dentosal deleted the conditional-jump-panic branch March 17, 2023 16:11
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
comp:FVM Component: FuelVM documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants