wasm_memory.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_runtime_common.h"
  6. #include "../interpreter/wasm_runtime.h"
  7. #include "bh_platform.h"
  8. #include "mem_alloc.h"
  9. typedef enum Memory_Mode {
  10. MEMORY_MODE_UNKNOWN = 0,
  11. MEMORY_MODE_POOL,
  12. MEMORY_MODE_ALLOCATOR,
  13. MEMORY_MODE_SYSTEM_ALLOCATOR
  14. } Memory_Mode;
  15. static Memory_Mode memory_mode = MEMORY_MODE_UNKNOWN;
  16. static mem_allocator_t pool_allocator = NULL;
  17. #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
  18. static void *allocator_user_data = NULL;
  19. static void *(*malloc_func)(void *user_data, unsigned int size) = NULL;
  20. static void *(*realloc_func)(void *user_data, void *ptr,
  21. unsigned int size) = NULL;
  22. static void (*free_func)(void *user_data, void *ptr) = NULL;
  23. #else
  24. static void *(*malloc_func)(unsigned int size) = NULL;
  25. static void *(*realloc_func)(void *ptr, unsigned int size) = NULL;
  26. static void (*free_func)(void *ptr) = NULL;
  27. #endif
  28. static unsigned int global_pool_size;
  29. static bool
  30. wasm_memory_init_with_pool(void *mem, unsigned int bytes)
  31. {
  32. mem_allocator_t _allocator = mem_allocator_create(mem, bytes);
  33. if (_allocator) {
  34. memory_mode = MEMORY_MODE_POOL;
  35. pool_allocator = _allocator;
  36. global_pool_size = bytes;
  37. return true;
  38. }
  39. LOG_ERROR("Init memory with pool (%p, %u) failed.\n", mem, bytes);
  40. return false;
  41. }
  42. #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
  43. static bool
  44. wasm_memory_init_with_allocator(void *_user_data, void *_malloc_func,
  45. void *_realloc_func, void *_free_func)
  46. {
  47. if (_malloc_func && _free_func && _malloc_func != _free_func) {
  48. memory_mode = MEMORY_MODE_ALLOCATOR;
  49. allocator_user_data = _user_data;
  50. malloc_func = _malloc_func;
  51. realloc_func = _realloc_func;
  52. free_func = _free_func;
  53. return true;
  54. }
  55. LOG_ERROR("Init memory with allocator (%p, %p, %p, %p) failed.\n",
  56. _user_data, _malloc_func, _realloc_func, _free_func);
  57. return false;
  58. }
  59. #else
  60. static bool
  61. wasm_memory_init_with_allocator(void *_malloc_func, void *_realloc_func,
  62. void *_free_func)
  63. {
  64. if (_malloc_func && _free_func && _malloc_func != _free_func) {
  65. memory_mode = MEMORY_MODE_ALLOCATOR;
  66. malloc_func = _malloc_func;
  67. realloc_func = _realloc_func;
  68. free_func = _free_func;
  69. return true;
  70. }
  71. LOG_ERROR("Init memory with allocator (%p, %p, %p) failed.\n", _malloc_func,
  72. _realloc_func, _free_func);
  73. return false;
  74. }
  75. #endif
  76. bool
  77. wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
  78. const MemAllocOption *alloc_option)
  79. {
  80. if (mem_alloc_type == Alloc_With_Pool) {
  81. return wasm_memory_init_with_pool(alloc_option->pool.heap_buf,
  82. alloc_option->pool.heap_size);
  83. }
  84. else if (mem_alloc_type == Alloc_With_Allocator) {
  85. #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
  86. return wasm_memory_init_with_allocator(
  87. alloc_option->allocator.user_data,
  88. alloc_option->allocator.malloc_func,
  89. alloc_option->allocator.realloc_func,
  90. alloc_option->allocator.free_func);
  91. #else
  92. return wasm_memory_init_with_allocator(
  93. alloc_option->allocator.malloc_func,
  94. alloc_option->allocator.realloc_func,
  95. alloc_option->allocator.free_func);
  96. #endif
  97. }
  98. else if (mem_alloc_type == Alloc_With_System_Allocator) {
  99. memory_mode = MEMORY_MODE_SYSTEM_ALLOCATOR;
  100. return true;
  101. }
  102. else {
  103. return false;
  104. }
  105. }
  106. void
  107. wasm_runtime_memory_destroy()
  108. {
  109. if (memory_mode == MEMORY_MODE_POOL) {
  110. #if BH_ENABLE_GC_VERIFY == 0
  111. (void)mem_allocator_destroy(pool_allocator);
  112. #else
  113. int ret = mem_allocator_destroy(pool_allocator);
  114. if (ret != 0) {
  115. /* Memory leak detected */
  116. exit(-1);
  117. }
  118. #endif
  119. }
  120. memory_mode = MEMORY_MODE_UNKNOWN;
  121. }
  122. unsigned
  123. wasm_runtime_memory_pool_size()
  124. {
  125. if (memory_mode == MEMORY_MODE_POOL)
  126. return global_pool_size;
  127. else
  128. return UINT32_MAX;
  129. }
  130. static inline void *
  131. wasm_runtime_malloc_internal(unsigned int size)
  132. {
  133. if (memory_mode == MEMORY_MODE_UNKNOWN) {
  134. LOG_WARNING(
  135. "wasm_runtime_malloc failed: memory hasn't been initialize.\n");
  136. return NULL;
  137. }
  138. else if (memory_mode == MEMORY_MODE_POOL) {
  139. return mem_allocator_malloc(pool_allocator, size);
  140. }
  141. else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
  142. #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
  143. return malloc_func(allocator_user_data, size);
  144. #else
  145. return malloc_func(size);
  146. #endif
  147. }
  148. else {
  149. return os_malloc(size);
  150. }
  151. }
  152. static inline void *
  153. wasm_runtime_realloc_internal(void *ptr, unsigned int size)
  154. {
  155. if (memory_mode == MEMORY_MODE_UNKNOWN) {
  156. LOG_WARNING(
  157. "wasm_runtime_realloc failed: memory hasn't been initialize.\n");
  158. return NULL;
  159. }
  160. else if (memory_mode == MEMORY_MODE_POOL) {
  161. return mem_allocator_realloc(pool_allocator, ptr, size);
  162. }
  163. else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
  164. if (realloc_func)
  165. #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
  166. return realloc_func(allocator_user_data, ptr, size);
  167. #else
  168. return realloc_func(ptr, size);
  169. #endif
  170. else
  171. return NULL;
  172. }
  173. else {
  174. return os_realloc(ptr, size);
  175. }
  176. }
  177. static inline void
  178. wasm_runtime_free_internal(void *ptr)
  179. {
  180. if (!ptr) {
  181. LOG_WARNING("warning: wasm_runtime_free with NULL pointer\n");
  182. #if BH_ENABLE_GC_VERIFY != 0
  183. exit(-1);
  184. #endif
  185. return;
  186. }
  187. if (memory_mode == MEMORY_MODE_UNKNOWN) {
  188. LOG_WARNING("warning: wasm_runtime_free failed: "
  189. "memory hasn't been initialize.\n");
  190. }
  191. else if (memory_mode == MEMORY_MODE_POOL) {
  192. mem_allocator_free(pool_allocator, ptr);
  193. }
  194. else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
  195. #if WASM_MEM_ALLOC_WITH_USER_DATA != 0
  196. free_func(allocator_user_data, ptr);
  197. #else
  198. free_func(ptr);
  199. #endif
  200. }
  201. else {
  202. os_free(ptr);
  203. }
  204. }
  205. void *
  206. wasm_runtime_malloc(unsigned int size)
  207. {
  208. if (size == 0) {
  209. LOG_WARNING("warning: wasm_runtime_malloc with size zero\n");
  210. /* At lease alloc 1 byte to avoid malloc failed */
  211. size = 1;
  212. #if BH_ENABLE_GC_VERIFY != 0
  213. exit(-1);
  214. #endif
  215. }
  216. return wasm_runtime_malloc_internal(size);
  217. }
  218. void *
  219. wasm_runtime_realloc(void *ptr, unsigned int size)
  220. {
  221. return wasm_runtime_realloc_internal(ptr, size);
  222. }
  223. void
  224. wasm_runtime_free(void *ptr)
  225. {
  226. wasm_runtime_free_internal(ptr);
  227. }
  228. bool
  229. wasm_runtime_get_mem_alloc_info(mem_alloc_info_t *mem_alloc_info)
  230. {
  231. if (memory_mode == MEMORY_MODE_POOL) {
  232. return mem_allocator_get_alloc_info(pool_allocator, mem_alloc_info);
  233. }
  234. return false;
  235. }
  236. bool
  237. wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst_comm,
  238. uint32 app_offset, uint32 size)
  239. {
  240. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  241. WASMMemoryInstance *memory_inst;
  242. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  243. || module_inst_comm->module_type == Wasm_Module_AoT);
  244. memory_inst = wasm_get_default_memory(module_inst);
  245. if (!memory_inst) {
  246. goto fail;
  247. }
  248. /* integer overflow check */
  249. if (app_offset > UINT32_MAX - size) {
  250. goto fail;
  251. }
  252. if (app_offset + size <= memory_inst->memory_data_size) {
  253. return true;
  254. }
  255. fail:
  256. wasm_set_exception(module_inst, "out of bounds memory access");
  257. return false;
  258. }
  259. bool
  260. wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst_comm,
  261. uint32 app_str_offset)
  262. {
  263. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  264. uint32 app_end_offset;
  265. char *str, *str_end;
  266. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  267. || module_inst_comm->module_type == Wasm_Module_AoT);
  268. if (!wasm_runtime_get_app_addr_range(module_inst_comm, app_str_offset, NULL,
  269. &app_end_offset))
  270. goto fail;
  271. str = wasm_runtime_addr_app_to_native(module_inst_comm, app_str_offset);
  272. str_end = str + (app_end_offset - app_str_offset);
  273. while (str < str_end && *str != '\0')
  274. str++;
  275. if (str == str_end)
  276. goto fail;
  277. return true;
  278. fail:
  279. wasm_set_exception(module_inst, "out of bounds memory access");
  280. return false;
  281. }
  282. bool
  283. wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst_comm,
  284. void *native_ptr, uint32 size)
  285. {
  286. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  287. WASMMemoryInstance *memory_inst;
  288. uint8 *addr = (uint8 *)native_ptr;
  289. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  290. || module_inst_comm->module_type == Wasm_Module_AoT);
  291. memory_inst = wasm_get_default_memory(module_inst);
  292. if (!memory_inst) {
  293. goto fail;
  294. }
  295. /* integer overflow check */
  296. if ((uintptr_t)addr > UINTPTR_MAX - size) {
  297. goto fail;
  298. }
  299. if (memory_inst->memory_data <= addr
  300. && addr + size <= memory_inst->memory_data_end) {
  301. return true;
  302. }
  303. fail:
  304. wasm_set_exception(module_inst, "out of bounds memory access");
  305. return false;
  306. }
  307. void *
  308. wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst_comm,
  309. uint32 app_offset)
  310. {
  311. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  312. WASMMemoryInstance *memory_inst;
  313. uint8 *addr;
  314. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  315. || module_inst_comm->module_type == Wasm_Module_AoT);
  316. memory_inst = wasm_get_default_memory(module_inst);
  317. if (!memory_inst) {
  318. return NULL;
  319. }
  320. addr = memory_inst->memory_data + app_offset;
  321. if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end)
  322. return addr;
  323. return NULL;
  324. }
  325. uint32
  326. wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst_comm,
  327. void *native_ptr)
  328. {
  329. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  330. WASMMemoryInstance *memory_inst;
  331. uint8 *addr = (uint8 *)native_ptr;
  332. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  333. || module_inst_comm->module_type == Wasm_Module_AoT);
  334. memory_inst = wasm_get_default_memory(module_inst);
  335. if (!memory_inst) {
  336. return 0;
  337. }
  338. if (memory_inst->memory_data <= addr && addr < memory_inst->memory_data_end)
  339. return (uint32)(addr - memory_inst->memory_data);
  340. return 0;
  341. }
  342. bool
  343. wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst_comm,
  344. uint32 app_offset, uint32 *p_app_start_offset,
  345. uint32 *p_app_end_offset)
  346. {
  347. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  348. WASMMemoryInstance *memory_inst;
  349. uint32 memory_data_size;
  350. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  351. || module_inst_comm->module_type == Wasm_Module_AoT);
  352. memory_inst = wasm_get_default_memory(module_inst);
  353. if (!memory_inst) {
  354. return false;
  355. }
  356. memory_data_size = memory_inst->memory_data_size;
  357. if (app_offset < memory_data_size) {
  358. if (p_app_start_offset)
  359. *p_app_start_offset = 0;
  360. if (p_app_end_offset)
  361. *p_app_end_offset = memory_data_size;
  362. return true;
  363. }
  364. return false;
  365. }
  366. bool
  367. wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst_comm,
  368. uint8 *native_ptr,
  369. uint8 **p_native_start_addr,
  370. uint8 **p_native_end_addr)
  371. {
  372. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  373. WASMMemoryInstance *memory_inst;
  374. uint8 *addr = (uint8 *)native_ptr;
  375. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  376. || module_inst_comm->module_type == Wasm_Module_AoT);
  377. memory_inst = wasm_get_default_memory(module_inst);
  378. if (!memory_inst) {
  379. return false;
  380. }
  381. if (memory_inst->memory_data <= addr
  382. && addr < memory_inst->memory_data_end) {
  383. if (p_native_start_addr)
  384. *p_native_start_addr = memory_inst->memory_data;
  385. if (p_native_end_addr)
  386. *p_native_end_addr = memory_inst->memory_data_end;
  387. return true;
  388. }
  389. return false;
  390. }
  391. bool
  392. wasm_check_app_addr_and_convert(WASMModuleInstance *module_inst, bool is_str,
  393. uint32 app_buf_addr, uint32 app_buf_size,
  394. void **p_native_addr)
  395. {
  396. WASMMemoryInstance *memory_inst = wasm_get_default_memory(module_inst);
  397. uint8 *native_addr;
  398. if (!memory_inst) {
  399. goto fail;
  400. }
  401. native_addr = memory_inst->memory_data + app_buf_addr;
  402. /* No need to check the app_offset and buf_size if memory access
  403. boundary check with hardware trap is enabled */
  404. #ifndef OS_ENABLE_HW_BOUND_CHECK
  405. if (app_buf_addr >= memory_inst->memory_data_size) {
  406. goto fail;
  407. }
  408. if (!is_str) {
  409. if (app_buf_size > memory_inst->memory_data_size - app_buf_addr) {
  410. goto fail;
  411. }
  412. }
  413. else {
  414. const char *str, *str_end;
  415. /* The whole string must be in the linear memory */
  416. str = (const char *)native_addr;
  417. str_end = (const char *)memory_inst->memory_data_end;
  418. while (str < str_end && *str != '\0')
  419. str++;
  420. if (str == str_end)
  421. goto fail;
  422. }
  423. #endif
  424. *p_native_addr = (void *)native_addr;
  425. return true;
  426. fail:
  427. wasm_set_exception(module_inst, "out of bounds memory access");
  428. return false;
  429. }
  430. WASMMemoryInstance *
  431. wasm_get_default_memory(WASMModuleInstance *module_inst)
  432. {
  433. if (module_inst->memories)
  434. return module_inst->memories[0];
  435. else
  436. return NULL;
  437. }
  438. #ifndef OS_ENABLE_HW_BOUND_CHECK
  439. bool
  440. wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
  441. {
  442. WASMMemoryInstance *memory = wasm_get_default_memory(module);
  443. uint8 *memory_data_old, *memory_data_new, *heap_data_old;
  444. uint32 num_bytes_per_page, heap_size, total_size_old;
  445. uint32 cur_page_count, max_page_count, total_page_count;
  446. uint64 total_size_new;
  447. bool ret = true;
  448. if (!memory)
  449. return false;
  450. heap_data_old = memory->heap_data;
  451. heap_size = (uint32)(memory->heap_data_end - memory->heap_data);
  452. memory_data_old = memory->memory_data;
  453. total_size_old = memory->memory_data_size;
  454. num_bytes_per_page = memory->num_bytes_per_page;
  455. cur_page_count = memory->cur_page_count;
  456. max_page_count = memory->max_page_count;
  457. total_page_count = inc_page_count + cur_page_count;
  458. total_size_new = num_bytes_per_page * (uint64)total_page_count;
  459. if (inc_page_count <= 0)
  460. /* No need to enlarge memory */
  461. return true;
  462. if (total_page_count < cur_page_count /* integer overflow */
  463. || total_page_count > max_page_count) {
  464. return false;
  465. }
  466. bh_assert(total_size_new <= 4 * (uint64)BH_GB);
  467. if (total_size_new > UINT32_MAX) {
  468. /* Resize to 1 page with size 4G-1 */
  469. num_bytes_per_page = UINT32_MAX;
  470. total_page_count = max_page_count = 1;
  471. total_size_new = UINT32_MAX;
  472. }
  473. #if WASM_ENABLE_SHARED_MEMORY != 0
  474. if (memory->is_shared) {
  475. memory->num_bytes_per_page = num_bytes_per_page;
  476. memory->cur_page_count = total_page_count;
  477. memory->max_page_count = max_page_count;
  478. /* No need to update memory->memory_data_size as it is
  479. initialized with the maximum memory data size for
  480. shared memory */
  481. return true;
  482. }
  483. #endif
  484. if (heap_size > 0) {
  485. if (mem_allocator_is_heap_corrupted(memory->heap_handle)) {
  486. wasm_runtime_show_app_heap_corrupted_prompt();
  487. return false;
  488. }
  489. }
  490. if (!(memory_data_new =
  491. wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) {
  492. if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) {
  493. return false;
  494. }
  495. if (memory_data_old) {
  496. bh_memcpy_s(memory_data_new, (uint32)total_size_new,
  497. memory_data_old, total_size_old);
  498. wasm_runtime_free(memory_data_old);
  499. }
  500. }
  501. memset(memory_data_new + total_size_old, 0,
  502. (uint32)total_size_new - total_size_old);
  503. if (heap_size > 0) {
  504. if (mem_allocator_migrate(memory->heap_handle,
  505. (char *)heap_data_old
  506. + (memory_data_new - memory_data_old),
  507. heap_size)
  508. != 0) {
  509. /* Don't return here as memory->memory_data is obsolete and
  510. must be updated to be correctly used later. */
  511. ret = false;
  512. }
  513. }
  514. memory->heap_data = memory_data_new + (heap_data_old - memory_data_old);
  515. memory->heap_data_end = memory->heap_data + heap_size;
  516. memory->num_bytes_per_page = num_bytes_per_page;
  517. memory->cur_page_count = total_page_count;
  518. memory->max_page_count = max_page_count;
  519. memory->memory_data_size = (uint32)total_size_new;
  520. memory->memory_data = memory_data_new;
  521. memory->memory_data_end = memory_data_new + (uint32)total_size_new;
  522. #if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
  523. #if UINTPTR_MAX == UINT64_MAX
  524. memory->mem_bound_check_1byte.u64 = total_size_new - 1;
  525. memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
  526. memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
  527. memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
  528. memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
  529. #else
  530. memory->mem_bound_check_1byte.u32[0] = (uint32)total_size_new - 1;
  531. memory->mem_bound_check_2bytes.u32[0] = (uint32)total_size_new - 2;
  532. memory->mem_bound_check_4bytes.u32[0] = (uint32)total_size_new - 4;
  533. memory->mem_bound_check_8bytes.u32[0] = (uint32)total_size_new - 8;
  534. memory->mem_bound_check_16bytes.u32[0] = (uint32)total_size_new - 16;
  535. #endif
  536. #endif
  537. return ret;
  538. }
  539. #else
  540. bool
  541. wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
  542. {
  543. WASMMemoryInstance *memory = wasm_get_default_memory(module);
  544. uint32 num_bytes_per_page, total_size_old;
  545. uint32 cur_page_count, max_page_count, total_page_count;
  546. uint64 total_size_new;
  547. if (!memory)
  548. return false;
  549. num_bytes_per_page = memory->num_bytes_per_page;
  550. cur_page_count = memory->cur_page_count;
  551. max_page_count = memory->max_page_count;
  552. total_size_old = num_bytes_per_page * cur_page_count;
  553. total_page_count = inc_page_count + cur_page_count;
  554. total_size_new = num_bytes_per_page * (uint64)total_page_count;
  555. if (inc_page_count <= 0)
  556. /* No need to enlarge memory */
  557. return true;
  558. if (total_page_count < cur_page_count /* integer overflow */
  559. || total_page_count > max_page_count) {
  560. return false;
  561. }
  562. bh_assert(total_size_new <= 4 * (uint64)BH_GB);
  563. if (total_size_new > UINT32_MAX) {
  564. /* Resize to 1 page with size 4G-1 */
  565. num_bytes_per_page = UINT32_MAX;
  566. total_page_count = max_page_count = 1;
  567. total_size_new = UINT32_MAX;
  568. }
  569. #ifdef BH_PLATFORM_WINDOWS
  570. if (!os_mem_commit(memory->memory_data_end,
  571. (uint32)total_size_new - total_size_old,
  572. MMAP_PROT_READ | MMAP_PROT_WRITE)) {
  573. return false;
  574. }
  575. #endif
  576. if (os_mprotect(memory->memory_data_end,
  577. (uint32)total_size_new - total_size_old,
  578. MMAP_PROT_READ | MMAP_PROT_WRITE)
  579. != 0) {
  580. #ifdef BH_PLATFORM_WINDOWS
  581. os_mem_decommit(memory->memory_data_end,
  582. (uint32)total_size_new - total_size_old);
  583. #endif
  584. return false;
  585. }
  586. /* The increased pages are filled with zero by the OS when os_mmap,
  587. no need to memset it again here */
  588. memory->num_bytes_per_page = num_bytes_per_page;
  589. memory->cur_page_count = total_page_count;
  590. memory->max_page_count = max_page_count;
  591. memory->memory_data_size = (uint32)total_size_new;
  592. memory->memory_data_end = memory->memory_data + (uint32)total_size_new;
  593. #if WASM_ENABLE_FAST_JIT != 0 || WASM_ENABLE_JIT != 0 || WASM_ENABLE_AOT != 0
  594. memory->mem_bound_check_1byte.u64 = total_size_new - 1;
  595. memory->mem_bound_check_2bytes.u64 = total_size_new - 2;
  596. memory->mem_bound_check_4bytes.u64 = total_size_new - 4;
  597. memory->mem_bound_check_8bytes.u64 = total_size_new - 8;
  598. memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
  599. #endif
  600. return true;
  601. }
  602. #endif /* end of OS_ENABLE_HW_BOUND_CHECK */