diff options
-rw-r--r-- | src/interp/interp-inl.h | 14 | ||||
-rw-r--r-- | src/interp/interp.cc | 32 | ||||
-rw-r--r-- | src/interp/interp.h | 22 | ||||
-rw-r--r-- | src/test-interp.cc | 4 |
4 files changed, 35 insertions, 37 deletions
diff --git a/src/interp/interp-inl.h b/src/interp/interp-inl.h index 1237d811..49d85662 100644 --- a/src/interp/interp-inl.h +++ b/src/interp/interp-inl.h @@ -467,6 +467,10 @@ inline const Features& Store::features() const { return features_; } +inline std::set<Thread*>& Store::threads() { + return threads_; +} + //// Object //// // static inline bool Object::classof(const Object* obj) { @@ -938,16 +942,6 @@ inline std::vector<DataSegment>& Instance::datas() { } //// Thread //// -// static -inline bool Thread::classof(const Object* obj) { - return obj->kind() == skind; -} - -// static -inline Thread::Ptr Thread::New(Store& store, const Options& options) { - return store.Alloc<Thread>(store, options); -} - inline Store& Thread::store() { return store_; } diff --git a/src/interp/interp.cc b/src/interp/interp.cc index bba27c9b..bd9fbb2c 100644 --- a/src/interp/interp.cc +++ b/src/interp/interp.cc @@ -256,6 +256,10 @@ void Store::Collect() { } } + for (auto thread : threads_) { + thread->Mark(); + } + // TODO: better GC algo. // Loop through all newly marked objects and mark their referents. std::vector<bool> all_marked(object_count, false); @@ -366,10 +370,8 @@ Result Func::Call(Store& store, Values& results, Trap::Ptr* out_trap, Stream* trace_stream) { - Thread::Options options; - options.trace_stream = trace_stream; - Thread::Ptr thread = Thread::New(store, options); - return DoCall(*thread, params, results, out_trap); + Thread thread(store, trace_stream); + return DoCall(thread, params, results, out_trap); } Result Func::Call(Thread& thread, @@ -934,24 +936,30 @@ void Instance::Mark(Store& store) { } //// Thread //// -Thread::Thread(Store& store, const Options& options) - : Object(skind), store_(store) { +Thread::Thread(Store& store, Stream* trace_stream) + : store_(store), trace_stream_(trace_stream) { + store.threads().insert(this); + + Thread::Options options; frames_.reserve(options.call_stack_size); values_.reserve(options.value_stack_size); - trace_stream_ = options.trace_stream; - if (options.trace_stream) { + if (trace_stream) { trace_source_ = MakeUnique<TraceSource>(this); } } -void Thread::Mark(Store& store) { +Thread::~Thread() { + store_.threads().erase(this); +} + +void Thread::Mark() { for (auto&& frame : frames_) { - frame.Mark(store); + frame.Mark(store_); } for (auto index : refs_) { - store.Mark(values_[index].Get<Ref>()); + store_.Mark(values_[index].Get<Ref>()); } - store.Mark(exceptions_); + store_.Mark(exceptions_); } void Thread::PushValues(const ValueTypes& types, const Values& values) { diff --git a/src/interp/interp.h b/src/interp/interp.h index 5c7dd8d3..270228f5 100644 --- a/src/interp/interp.h +++ b/src/interp/interp.h @@ -20,6 +20,7 @@ #include <cstdint> #include <functional> #include <memory> +#include <set> #include <string> #include <type_traits> #include <vector> @@ -90,7 +91,6 @@ enum class ObjectKind { Tag, Module, Instance, - Thread, }; const char* GetName(Mutability); @@ -500,11 +500,15 @@ class Store { const Features& features() const; void setFeatures(const Features& features) { features_ = features; } + std::set<Thread*>& threads(); + private: template <typename T> friend class RefPtr; Features features_; + // This set contains the currently active Thread objects. + std::set<Thread*> threads_; ObjectList objects_; RootList roots_; std::vector<bool> marks_; @@ -1086,15 +1090,8 @@ enum class RunResult { Exception, }; -// TODO: Kinda weird to have a thread as an object, but it makes reference -// marking simpler. -class Thread : public Object { +class Thread { public: - static bool classof(const Object* obj); - static const ObjectKind skind = ObjectKind::Thread; - static const char* GetTypeName() { return "Thread"; } - using Ptr = RefPtr<Thread>; - struct Options { static const u32 kDefaultValueStackSize = 64 * 1024 / sizeof(Value); static const u32 kDefaultCallStackSize = 64 * 1024 / sizeof(Frame); @@ -1104,13 +1101,15 @@ class Thread : public Object { Stream* trace_stream = nullptr; }; - static Thread::Ptr New(Store&, const Options&); + Thread(Store& store, Stream* trace_stream = nullptr); + ~Thread(); RunResult Run(Trap::Ptr* out_trap); RunResult Run(int num_instructions, Trap::Ptr* out_trap); RunResult Step(Trap::Ptr* out_trap); Store& store(); + void Mark(); Instance* GetCallerInstance(); @@ -1120,9 +1119,6 @@ class Thread : public Object { struct TraceSource; - explicit Thread(Store&, const Options&); - void Mark(Store&) override; - RunResult PushCall(Ref func, u32 offset, Trap::Ptr* out_trap); RunResult PushCall(const DefinedFunc&, Trap::Ptr* out_trap); RunResult PushCall(const HostFunc&, Trap::Ptr* out_trap); diff --git a/src/test-interp.cc b/src/test-interp.cc index d7461209..1ba6b0b1 100644 --- a/src/test-interp.cc +++ b/src/test-interp.cc @@ -346,7 +346,7 @@ TEST_F(InterpTest, HostFunc_PingPong_SameThread) { 0x0b, 0x01, 0x09, 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x10, 0x00, 0x0b, }); - auto thread = Thread::New(store_, {}); + Thread thread(store_); auto host_func = HostFunc::New(store_, FuncType{{ValueType::I32}, {ValueType::I32}}, @@ -369,7 +369,7 @@ TEST_F(InterpTest, HostFunc_PingPong_SameThread) { Values results; Trap::Ptr trap; Result result = - GetFuncExport(0)->Call(*thread, {Value::Make(1)}, results, &trap); + GetFuncExport(0)->Call(thread, {Value::Make(1)}, results, &trap); ASSERT_EQ(Result::Ok, result); EXPECT_EQ(1u, results.size()); |