wasm_exec_env.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_exec_env.h"
  6. #include "wasm_runtime_common.h"
  7. #if WASM_ENABLE_INTERP != 0
  8. #include "../interpreter/wasm_runtime.h"
  9. #endif
  10. #if WASM_ENABLE_AOT != 0
  11. #include "../aot/aot_runtime.h"
  12. #endif
  13. #if WASM_ENABLE_AOT != 0
  14. #include "aot_runtime.h"
  15. #endif
  16. #if WASM_ENABLE_THREAD_MGR != 0
  17. #include "../libraries/thread-mgr/thread_manager.h"
  18. #if WASM_ENABLE_DEBUG_INTERP != 0
  19. #include "../libraries/debug-engine/debug_engine.h"
  20. #endif
  21. #endif
  22. WASMExecEnv *
  23. wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
  24. uint32 stack_size)
  25. {
  26. uint64 total_size =
  27. offsetof(WASMExecEnv, wasm_stack.s.bottom) + (uint64)stack_size;
  28. WASMExecEnv *exec_env;
  29. if (total_size >= UINT32_MAX
  30. || !(exec_env = wasm_runtime_malloc((uint32)total_size)))
  31. return NULL;
  32. memset(exec_env, 0, (uint32)total_size);
  33. #if WASM_ENABLE_AOT != 0
  34. if (!(exec_env->argv_buf = wasm_runtime_malloc(sizeof(uint32) * 64))) {
  35. goto fail1;
  36. }
  37. #endif
  38. #if WASM_ENABLE_THREAD_MGR != 0
  39. if (os_mutex_init(&exec_env->wait_lock) != 0)
  40. goto fail2;
  41. if (os_cond_init(&exec_env->wait_cond) != 0)
  42. goto fail3;
  43. #if WASM_ENABLE_DEBUG_INTERP != 0
  44. if (!(exec_env->current_status = wasm_cluster_create_exenv_status()))
  45. goto fail4;
  46. #endif
  47. #endif
  48. #ifdef OS_ENABLE_HW_BOUND_CHECK
  49. if (!(exec_env->exce_check_guard_page =
  50. os_mmap(NULL, os_getpagesize(), MMAP_PROT_NONE, MMAP_MAP_NONE)))
  51. goto fail5;
  52. #endif
  53. exec_env->module_inst = module_inst;
  54. exec_env->wasm_stack_size = stack_size;
  55. exec_env->wasm_stack.s.top_boundary =
  56. exec_env->wasm_stack.s.bottom + stack_size;
  57. exec_env->wasm_stack.s.top = exec_env->wasm_stack.s.bottom;
  58. #if WASM_ENABLE_AOT != 0
  59. if (module_inst->module_type == Wasm_Module_AoT) {
  60. AOTModuleInstance *i = (AOTModuleInstance *)module_inst;
  61. AOTModule *m = (AOTModule *)i->module;
  62. exec_env->native_symbol = m->native_symbol_list;
  63. }
  64. #endif
  65. #if WASM_ENABLE_MEMORY_TRACING != 0
  66. wasm_runtime_dump_exec_env_mem_consumption(exec_env);
  67. #endif
  68. return exec_env;
  69. #ifdef OS_ENABLE_HW_BOUND_CHECK
  70. fail5:
  71. #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
  72. wasm_cluster_destroy_exenv_status(exec_env->current_status);
  73. #endif
  74. #endif
  75. #if WASM_ENABLE_THREAD_MGR != 0
  76. #if WASM_ENABLE_DEBUG_INTERP != 0
  77. fail4:
  78. os_cond_destroy(&exec_env->wait_cond);
  79. #endif
  80. fail3:
  81. os_mutex_destroy(&exec_env->wait_lock);
  82. fail2:
  83. #endif
  84. #if WASM_ENABLE_AOT != 0
  85. wasm_runtime_free(exec_env->argv_buf);
  86. fail1:
  87. #endif
  88. wasm_runtime_free(exec_env);
  89. return NULL;
  90. }
  91. void
  92. wasm_exec_env_destroy_internal(WASMExecEnv *exec_env)
  93. {
  94. #ifdef OS_ENABLE_HW_BOUND_CHECK
  95. os_munmap(exec_env->exce_check_guard_page, os_getpagesize());
  96. #endif
  97. #if WASM_ENABLE_THREAD_MGR != 0
  98. os_mutex_destroy(&exec_env->wait_lock);
  99. os_cond_destroy(&exec_env->wait_cond);
  100. #if WASM_ENABLE_DEBUG_INTERP != 0
  101. wasm_cluster_destroy_exenv_status(exec_env->current_status);
  102. #endif
  103. #endif
  104. #if WASM_ENABLE_AOT != 0
  105. wasm_runtime_free(exec_env->argv_buf);
  106. #endif
  107. wasm_runtime_free(exec_env);
  108. }
  109. WASMExecEnv *
  110. wasm_exec_env_create(struct WASMModuleInstanceCommon *module_inst,
  111. uint32 stack_size)
  112. {
  113. #if WASM_ENABLE_THREAD_MGR != 0
  114. WASMCluster *cluster;
  115. #endif
  116. WASMExecEnv *exec_env =
  117. wasm_exec_env_create_internal(module_inst, stack_size);
  118. if (!exec_env)
  119. return NULL;
  120. #if WASM_ENABLE_INTERP != 0
  121. /* Set the aux_stack_boundary and aux_stack_bottom */
  122. if (module_inst->module_type == Wasm_Module_Bytecode) {
  123. WASMModule *module = ((WASMModuleInstance *)module_inst)->module;
  124. exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
  125. exec_env->aux_stack_boundary.boundary =
  126. module->aux_stack_bottom - module->aux_stack_size;
  127. }
  128. #endif
  129. #if WASM_ENABLE_AOT != 0
  130. /* Set the aux_stack_boundary and aux_stack_bottom */
  131. if (module_inst->module_type == Wasm_Module_AoT) {
  132. AOTModule *module =
  133. (AOTModule *)((AOTModuleInstance *)module_inst)->module;
  134. exec_env->aux_stack_bottom.bottom = module->aux_stack_bottom;
  135. exec_env->aux_stack_boundary.boundary =
  136. module->aux_stack_bottom - module->aux_stack_size;
  137. }
  138. #endif
  139. #if WASM_ENABLE_THREAD_MGR != 0
  140. /* Create a new cluster for this exec_env */
  141. if (!(cluster = wasm_cluster_create(exec_env))) {
  142. wasm_exec_env_destroy_internal(exec_env);
  143. return NULL;
  144. }
  145. #endif /* end of WASM_ENABLE_THREAD_MGR */
  146. return exec_env;
  147. }
  148. void
  149. wasm_exec_env_destroy(WASMExecEnv *exec_env)
  150. {
  151. #if WASM_ENABLE_THREAD_MGR != 0
  152. /* Wait for all sub-threads */
  153. WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
  154. if (cluster) {
  155. wasm_cluster_wait_for_all_except_self(cluster, exec_env);
  156. #if WASM_ENABLE_DEBUG_INTERP != 0
  157. /* Must fire exit event after other threads exits, otherwise
  158. the stopped thread will be overrided by other threads */
  159. wasm_cluster_thread_exited(exec_env);
  160. #endif
  161. /* We have waited for other threads, this is the only alive thread, so
  162. * we don't acquire cluster->lock because the cluster will be destroyed
  163. * inside this function */
  164. wasm_cluster_del_exec_env(cluster, exec_env);
  165. }
  166. #endif /* end of WASM_ENABLE_THREAD_MGR */
  167. wasm_exec_env_destroy_internal(exec_env);
  168. }
  169. WASMModuleInstanceCommon *
  170. wasm_exec_env_get_module_inst(WASMExecEnv *exec_env)
  171. {
  172. return exec_env->module_inst;
  173. }
  174. void
  175. wasm_exec_env_set_module_inst(WASMExecEnv *exec_env,
  176. WASMModuleInstanceCommon *const module_inst)
  177. {
  178. exec_env->module_inst = module_inst;
  179. }
  180. void
  181. wasm_exec_env_set_thread_info(WASMExecEnv *exec_env)
  182. {
  183. uint8 *stack_boundary = os_thread_get_stack_boundary();
  184. #if WASM_ENABLE_THREAD_MGR != 0
  185. os_mutex_lock(&exec_env->wait_lock);
  186. #endif
  187. exec_env->handle = os_self_thread();
  188. exec_env->native_stack_boundary =
  189. stack_boundary ? stack_boundary + WASM_STACK_GUARD_SIZE : NULL;
  190. exec_env->native_stack_top_min = (void *)UINTPTR_MAX;
  191. #if WASM_ENABLE_THREAD_MGR != 0
  192. os_mutex_unlock(&exec_env->wait_lock);
  193. #endif
  194. }
  195. #if WASM_ENABLE_THREAD_MGR != 0
  196. void *
  197. wasm_exec_env_get_thread_arg(WASMExecEnv *exec_env)
  198. {
  199. return exec_env->thread_arg;
  200. }
  201. void
  202. wasm_exec_env_set_thread_arg(WASMExecEnv *exec_env, void *thread_arg)
  203. {
  204. exec_env->thread_arg = thread_arg;
  205. }
  206. #endif
  207. #if defined(OS_ENABLE_HW_BOUND_CHECK) || defined(OS_ENABLE_INTERRUPT_BLOCK_INSN)
  208. void
  209. wasm_exec_env_push_jmpbuf(WASMExecEnv *exec_env, WASMJmpBuf *jmpbuf)
  210. {
  211. jmpbuf->prev = exec_env->jmpbuf_stack_top;
  212. exec_env->jmpbuf_stack_top = jmpbuf;
  213. }
  214. WASMJmpBuf *
  215. wasm_exec_env_pop_jmpbuf(WASMExecEnv *exec_env)
  216. {
  217. WASMJmpBuf *stack_top = exec_env->jmpbuf_stack_top;
  218. if (stack_top) {
  219. exec_env->jmpbuf_stack_top = stack_top->prev;
  220. return stack_top;
  221. }
  222. return NULL;
  223. }
  224. #endif