-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Increase wasm (smart contract) max memory to 33MiB #1459
Conversation
Change sbrk() to return -1 on failure. This has 2 benefits: 1) wasm doesn’t need to know the memory ceiling (neither hardcoded nor by adding a new native call), and 2) the wasm runtime will now honor the maximum memory growth defined in the contract. That could be beneficial to force the current malloc implementation to reuse freed memory vs unbounded growth.
Two recently fixed unit tests have a problem with new sbrk behavior. One simply needs modification to look for a -1 indicating failure. The other one, where sbrk and malloc is mixed, is more troublesome. When I adjusted the malloc behavior to only create heaps on wasm page boundaries it breaks that unit test. However, I prefer to keep the heaps on the wasm boundaries. So I’m going to disable that unit test for now,
Change the maximum memory a wasm smart contract can consume to 33MiB. Update a couple of the unit tests to accommodate any max memory size. A number of the “legacy” unit tests assume a 1MiB maximum so add a way in our cmakes to bound certain wasms to a particular runtime limit.
constexpr unsigned maximum_mutable_globals = 1024; //bytes | ||
constexpr unsigned maximum_table_elements = 1024; //elements | ||
constexpr unsigned maximum_linear_memory_init = 64*1024; //bytes | ||
constexpr unsigned maximum_linear_memory = 33*1024*1024;//bytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
under wasm_eosio_constraints
, it increase the memory size to 33MIB
(mebibyte)
@@ -34,31 +34,39 @@ namespace eosio { | |||
|
|||
memory* next_active_heap() | |||
{ | |||
constexpr uint32_t wasm_page_size = 64*1024; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
define the wasm_page_size
to 64 Kibibyte
@@ -461,7 +469,6 @@ namespace eosio { | |||
static const uint32_t _mem_block = 8; | |||
static const uint32_t _rem_mem_block_mask = _mem_block - 1; | |||
static const uint32_t _initial_heap_size = 8192;//32768; | |||
static const uint32_t _new_heap_size = 65536; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_new_heap_size
has been re-specified as wasm_page_size
in the new commit
// sbrk should only allow for memory to grow | ||
if (num_bytes < 0) | ||
throw eosio::chain::page_memory_error(); | ||
// TODO: omitted checktime function from previous version of sbrk, may need to be put back in at some point | ||
constexpr uint32_t NBPPL2 = IR::numBytesPerPageLog2; | ||
constexpr uint32_t MAX_MEM = 1024 * 1024; | ||
constexpr uint32_t MAX_MEM = wasm_constraints::maximum_linear_memory; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
increase the MAX_MEM
from 1 Mib
to 33Mib
@@ -1030,17 +1030,17 @@ class memory_api : public context_aware_api { | |||
return (char *)::memset( dest, value, length ); | |||
} | |||
|
|||
uint32_t sbrk(int num_bytes) { | |||
int sbrk(int num_bytes) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: the return variable prev_num_bytes
is uint32_t
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the return type of sbrk
should still be uint32_t
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it to int to be a more clear indicator that sbrk()
can now return a negative value. While I realize it could stay uint32_t
and still return -1 or even 0xFFFFFFFF that doesn't seem as explicit.
@@ -1,5 +1,8 @@ | |||
#set the MAX_MEMORY to 1MB for these tests; there were lots of memory unit tests that assume such |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1048576 = 1024*1024 = 2^20, the comment should be 1MIB
instead of 1MB
to avoid confusion
same for /test_api/CMakeLists.txt
@@ -165,7 +165,7 @@ macro(add_wast_library) | |||
endmacro(add_wast_library) | |||
|
|||
macro(add_wast_executable) | |||
cmake_parse_arguments(ARG "NOWARNINGS" "TARGET;DESTINATION_FOLDER" "SOURCE_FILES;INCLUDE_FOLDERS;SYSTEM_INCLUDE_FOLDERS;LIBRARIES" ${ARGN}) | |||
cmake_parse_arguments(ARG "NOWARNINGS" "TARGET;DESTINATION_FOLDER;MAX_MEMORY" "SOURCE_FILES;INCLUDE_FOLDERS;SYSTEM_INCLUDE_FOLDERS;LIBRARIES" ${ARGN}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MAX_MEMORY
is assigned value on test_api/CMakeLists.txt
and test_api_mem/CMakeLists.txt
Just occurred to me that all of tests/wasm_tests have been disabled on the large test PR that recently went in (and was included in the sync to master on this branch). Recommending to delay this PR until the tests are reenabled as I think some of those tests may fail and need proper modifications. |
There is a requirement to support a 32MiB dataset in wasm memory. Make the maximum memory allowed 33MiB. 33 was chosen via fair dice roll; if we feel 32.064 is the most we want to push we can easily change it.
See each individual commit for a better description of changes. Most notable is that I had to disable the unit test that mixes sbrk() and malloc() because I modified malloc's heap growth to always create heaps on wasm page boundaries.