summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interp/interp-inl.h14
-rw-r--r--src/interp/interp.cc32
-rw-r--r--src/interp/interp.h22
-rw-r--r--src/test-interp.cc4
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());