Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions programs/bpf_loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,6 @@ fn create_vm<'a, 'b>(
.touch(index_in_transaction as IndexOfAccount)
.map_err(|_| ())?;

if account.is_shared() {
// See BorrowedAccount::make_data_mut() as to why we reserve extra
// MAX_PERMITTED_DATA_INCREASE bytes here.
account.reserve(MAX_PERMITTED_DATA_INCREASE);
}
Ok(account.data_as_mut_slice().as_mut_ptr() as u64)
})),
)?;
Expand Down
7 changes: 7 additions & 0 deletions programs/bpf_loader/src/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,13 @@ fn deserialize_parameters_aligned<I: IntoIterator<Item = usize>>(
borrowed_account.set_data_length(post_len)?;
let allocated_bytes = post_len.saturating_sub(pre_len);
if allocated_bytes > 0 {
// Just in time resize of data field within the internal AccountSharedData
//
// NOTE: this is an optimization for CoW account mappings, where the account's
// data is not immediately resized with an extra MAX_PERMITTED_DATA_INCREASE,
// but if the realloc did occur (and this branch was taken) then we need to reserve
// max permitted amount of extra space so the subsequent code will work correctly
borrowed_account.reserve(MAX_PERMITTED_DATA_INCREASE)?;
borrowed_account
.get_data_mut()?
.get_mut(pre_len..pre_len.saturating_add(allocated_bytes))
Expand Down
10 changes: 6 additions & 4 deletions sdk/transaction-context/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,7 +974,12 @@ impl BorrowedAccount<'_> {
// memory that holds the account but it doesn't actually change content
// nor length of the account.
self.make_data_mut();
self.account.reserve(additional);
// NOTE: we don't call reserve unnecessarily, as the first call to make_data_mut
// has already resized the data to an extra MAX_PERMITTED_DATA_INCREASE bytes
if additional > MAX_PERMITTED_DATA_INCREASE {
self.account
.reserve(additional.saturating_sub(MAX_PERMITTED_DATA_INCREASE));
}
Comment on lines +979 to +982
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I know it was previously already the case and this condition just makes it better but the double reallocation does feel like a big waste. Especially in such case where the data size is know to be pretty big already.
I wonder if the introduction of a "make mut with additional size" or something of the sort would be acceptable.

Also i'm unsure if it is actually possible for additional to be > MAX_PERMITTED_DATA_INCREASE but since its been renamed from MAX_PERMITTED_DATA_LENGTH it may now/soon be the case.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

But overall feels like a very positive change - everything that can speed up execution is more than welcomed...


Ok(())
}
Expand Down Expand Up @@ -1004,9 +1009,6 @@ impl BorrowedAccount<'_> {
// buffer with MAX_PERMITTED_DATA_INCREASE capacity so that if the
// transaction reallocs, we don't have to copy the whole account data a
// second time to fullfill the realloc.
//
// NOTE: The account memory region CoW code in bpf_loader::create_vm() implements the same
// logic and must be kept in sync.
if self.account.is_shared() {
self.account.reserve(MAX_PERMITTED_DATA_INCREASE);
}
Expand Down