Skip to content

Commit 3cfb37d

Browse files
branch hints (#81)
* branch hints * add documentation for hint function Co-authored-by: Fernando Otero <[email protected]> * doc for likely Co-authored-by: Fernando Otero <[email protected]> * doc for unlikely Co-authored-by: Fernando Otero <[email protected]> * linter * rename unlikely_branch to match core --------- Co-authored-by: Fernando Otero <[email protected]>
1 parent cf136e7 commit 3cfb37d

File tree

4 files changed

+42
-6
lines changed

4 files changed

+42
-6
lines changed

p-interface/src/lib.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,35 @@ pub mod state;
88
pub mod program {
99
pinocchio_pubkey::declare_id!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
1010
}
11+
12+
/// A "dummy" function with a hint to the compiler that it is unlikely to be
13+
/// called.
14+
///
15+
/// This function is used as a hint to the compiler to optimize other code paths
16+
/// instead of the one where the function is used.
17+
#[cold]
18+
pub const fn cold_path() {}
19+
20+
/// Return the given `bool` value with a hint to the compiler that `true` is the
21+
/// likely case.
22+
#[inline(always)]
23+
pub const fn likely(b: bool) -> bool {
24+
if b {
25+
true
26+
} else {
27+
cold_path();
28+
false
29+
}
30+
}
31+
32+
/// Return a given `bool` value with a hint to the compiler that `false` is the
33+
/// likely case.
34+
#[inline(always)]
35+
pub const fn unlikely(b: bool) -> bool {
36+
if b {
37+
cold_path();
38+
true
39+
} else {
40+
false
41+
}
42+
}

p-interface/src/state/account.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use {
22
super::{account_state::AccountState, COption, Initializable, Transmutable},
3+
crate::likely,
34
pinocchio::{program_error::ProgramError, pubkey::Pubkey},
45
};
56

@@ -158,6 +159,6 @@ unsafe impl Transmutable for Account {
158159
impl Initializable for Account {
159160
#[inline(always)]
160161
fn is_initialized(&self) -> Result<bool, ProgramError> {
161-
AccountState::try_from(self.state).map(|state| state != AccountState::Uninitialized)
162+
AccountState::try_from(self.state).map(|state| likely(state != AccountState::Uninitialized))
162163
}
163164
}

p-token/src/processor/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use {
1212
multisig::{Multisig, MAX_SIGNERS},
1313
Transmutable,
1414
},
15+
unlikely,
1516
},
1617
};
1718

@@ -103,9 +104,10 @@ unsafe fn validate_owner(
103104
return Err(TokenError::OwnerMismatch.into());
104105
}
105106

106-
if owner_account_info.data_len() == Multisig::LEN
107-
&& owner_account_info.is_owned_by(&TOKEN_PROGRAM_ID)
108-
{
107+
if unlikely(
108+
owner_account_info.data_len() == Multisig::LEN
109+
&& owner_account_info.is_owned_by(&TOKEN_PROGRAM_ID),
110+
) {
109111
// SAFETY: the caller guarantees that there are no mutable borrows of
110112
// `owner_account_info` account data and the `load` validates that the
111113
// account is initialized; additionally, `Multisig` accounts are only
@@ -130,7 +132,7 @@ unsafe fn validate_owner(
130132
if num_signers < multisig.m {
131133
return Err(ProgramError::MissingRequiredSignature);
132134
}
133-
} else if !owner_account_info.is_signer() {
135+
} else if unlikely(!owner_account_info.is_signer()) {
134136
return Err(ProgramError::MissingRequiredSignature);
135137
}
136138

p-token/src/processor/shared/transfer.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use {
44
pinocchio_token_interface::{
55
error::TokenError,
66
state::{account::Account, load, load_mut, load_mut_unchecked, mint::Mint},
7+
unlikely,
78
},
89
};
910

@@ -76,7 +77,7 @@ pub fn process_transfer(
7677
// - transfers to different accounts: we need to check that the source and
7778
// destination accounts are not frozen, have the same mint, and the source
7879
// account has enough tokens.
79-
let remaining_amount = if self_transfer {
80+
let remaining_amount = if unlikely(self_transfer) {
8081
if source_account.is_frozen()? {
8182
return Err(TokenError::AccountFrozen.into());
8283
}

0 commit comments

Comments
 (0)