History

Add support for traps in VM Add instruction trap to enable single step scenario in debugger Remote get_state() function from thread

arr committed 9 years ago

Commit cb408a11 parent eb570d98 files · +120 −40Browse files

Showing the changes to src/vm/thread.cpp (1 of 8 files). Show all

Unified · Split

src/vm/thread.cpp+23−12
@@ -12,6 +12,7 @@ · 11 unmodified lines
12#include <exceptions.h>12#include <exceptions.h>
13#include <vm_memory.h>13#include <vm_memory.h>
14#include <debug.h>14#include <debug.h>
15#include <utils.h>
15#include "execution_table.h"16#include "execution_table.h"
16#include "tool_dispatch.h"17#include "tool_dispatch.h"
17 18
@@ -51,10 +52,11 @@ namespace · 33 unmodified lines
51}52}
52 53
53vm_registers_t::vm_registers_t(54vm_registers_t::vm_registers_t(
54 const vm_thread_t &thread,55 vm_thread_t &thread,
55 vm_module_ref_t &entry)56 vm_module_ref_t &entry)
56 : current_thread_state{ vm_thread_state_t::ready }57 : current_thread_state{ vm_thread_state_t::ready }
57 , current_thread_quanta{ 0 }58 , current_thread_quanta{ 0 }
59 , trap_flags{ vm_trap_flags_t::none }
58 , module_ref{ &entry }60 , module_ref{ &entry }
59 , mp_base{ entry.mp_base }61 , mp_base{ entry.mp_base }
60 , thread{ thread }62 , thread{ thread }
@@ -174,25 +176,37 @@ namespace · 113 unmodified lines
174{176{
175 struct execute_with_tool_t final177 struct execute_with_tool_t final
176 {178 {
177 static void begin_exec_loop(vm_registers_t &registers, vm_t &)179 static void begin_exec_loop(vm_registers_t &r, vm_t &)
178 {180 {
179 auto tool_dispatch = registers.tool_dispatch.load();181 auto tool_dispatch = r.tool_dispatch.load();
180 assert(tool_dispatch != nullptr);182 assert(tool_dispatch != nullptr);
181 183
182 tool_dispatch->block_if_thread_suspended(registers.thread.get_thread_id());184 tool_dispatch->block_if_thread_suspended(r.thread.get_thread_id());
185 }
186
187 static void after_exec(vm_registers_t &r, vm_t &)
188 {
189 if (r.trap_flags == vm_trap_flags_t::none
190 || !util::has_flag(r.trap_flags, vm_trap_flags_t::instruction))
191 return;
192
193 auto tool_dispatch = r.tool_dispatch.load();
194 assert(tool_dispatch != nullptr);
195
196 tool_dispatch->on_trap(r, vm_trap_flags_t::instruction);
183 }197 }
184 };198 };
185 199
186 struct execute_normal_t final200 struct execute_normal_t final
187 {201 {
188 static void begin_exec_loop(vm_registers_t &, vm_t &) { }202 static void begin_exec_loop(vm_registers_t &, vm_t &) { }
203 static void after_exec(vm_registers_t &, vm_t &) { }
189 };204 };
190 205
191 template<typename EXEC_DETOUR>206 template<typename EXEC_DETOUR>
192 void execute_impl(vm_registers_t &r, vm_t &vm)207 void execute_impl(vm_registers_t &r, vm_t &vm)
193 {208 {
194 auto &execution_duration = r.current_thread_quanta;209 for (; 0 != r.current_thread_quanta; --r.current_thread_quanta)
195 for (; 0 != execution_duration; --execution_duration)
196 {210 {
197 EXEC_DETOUR::begin_exec_loop(r, vm);211 EXEC_DETOUR::begin_exec_loop(r, vm);
198 assert(r.stack.peek_frame() != nullptr && "Thread state should not be running with empty stack");212 assert(r.stack.peek_frame() != nullptr && "Thread state should not be running with empty stack");
@@ -212,6 +226,8 @@ namespace · 13 unmodified lines
212 vm_exec_table[opcode](r, vm);226 vm_exec_table[opcode](r, vm);
213 r.pc = r.next_pc;227 r.pc = r.next_pc;
214 228
229 EXEC_DETOUR::after_exec(r, vm);
230
215 if (r.current_thread_state != vm_thread_state_t::running)231 if (r.current_thread_state != vm_thread_state_t::running)
216 break;232 break;
217 }233 }
@@ -306,11 +322,6 @@ void vm_thread_t::set_tool_dispatch(vm_tool_dispatch_t *dispatch) · 88 unmodified lines
306 _registers.tool_dispatch = dispatch;322 _registers.tool_dispatch = dispatch;
307}323}
308 324
309vm_thread_state_t vm_thread_t::get_state() const
310{
311 return _registers.current_thread_state;
312}
313
314const char *vm_thread_t::get_error_message() const325const char *vm_thread_t::get_error_message() const
315{326{
316 return _error_message;327 return _error_message;
@@ -329,4 +340,4 @@ uint32_t vm_thread_t::get_parent_thread_id() const · 12 unmodified lines
329const vm_registers_t& vm_thread_t::get_registers() const340const vm_registers_t& vm_thread_t::get_registers() const
330{341{
331 return _registers;342 return _registers;
332}343}