diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-08-26 10:13:48 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-08-26 10:13:48 -0700 |
commit | 801baed1ca81d87380d56298289fe8cc0b4f1e1a (patch) | |
tree | 683c8535f4e6072e41eda4fcda08e00da42b6626 | |
parent | 2cb8b275caf090bf56cc78424aaa97766cd02fb6 (diff) | |
parent | a008d4fd7af3b04a3d351a03d56df7c28998690e (diff) | |
download | binaryen-801baed1ca81d87380d56298289fe8cc0b4f1e1a.tar.gz binaryen-801baed1ca81d87380d56298289fe8cc0b4f1e1a.tar.bz2 binaryen-801baed1ca81d87380d56298289fe8cc0b4f1e1a.zip |
Merge pull request #682 from loganchien/fix-empty-deadlock
Fix asm2wasm dead lock caused by empty module
-rw-r--r-- | src/asm2wasm.h | 2 | ||||
-rw-r--r-- | src/cfg/Relooper.cpp | 2 | ||||
-rw-r--r-- | src/passes/LowerIfElse.cpp | 2 | ||||
-rw-r--r-- | src/passes/LowerInt64.cpp | 2 | ||||
-rw-r--r-- | src/support/threads.cpp | 7 | ||||
-rw-r--r-- | src/wasm-module-building.h | 15 | ||||
-rw-r--r-- | test/empty.asm.js | 4 | ||||
-rw-r--r-- | test/empty.fromasm | 4 | ||||
-rw-r--r-- | test/empty.fromasm.imprecise | 4 | ||||
-rw-r--r-- | test/empty.fromasm.imprecise.no-opts | 4 | ||||
-rw-r--r-- | test/empty.fromasm.no-opts | 4 |
11 files changed, 39 insertions, 11 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index a5754f725..ce3c0749d 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -537,7 +537,7 @@ void Asm2WasmBuilder::processAsm(Ref ast) { for (unsigned i = 1; i < body->size(); i++) { if (body[i][0] == DEFUN) numFunctions++; } - optimizingBuilder = std::unique_ptr<OptimizingIncrementalModuleBuilder>(new OptimizingIncrementalModuleBuilder(&wasm, numFunctions)); + optimizingBuilder = make_unique<OptimizingIncrementalModuleBuilder>(&wasm, numFunctions); } // first pass - do almost everything, but function imports and indirect calls diff --git a/src/cfg/Relooper.cpp b/src/cfg/Relooper.cpp index cde61df0b..e75adbce5 100644 --- a/src/cfg/Relooper.cpp +++ b/src/cfg/Relooper.cpp @@ -98,7 +98,7 @@ Branch::Branch(wasm::Expression* ConditionInit, wasm::Expression* CodeInit) : An Branch::Branch(std::vector<wasm::Index>&& ValuesInit, wasm::Expression* CodeInit) : Ancestor(nullptr), Code(CodeInit) { if (ValuesInit.size() > 0) { - SwitchValues = std::unique_ptr<std::vector<wasm::Index>>(new std::vector<wasm::Index>(ValuesInit)); + SwitchValues = wasm::make_unique<std::vector<wasm::Index>>(ValuesInit); } // otherwise, it is the default } diff --git a/src/passes/LowerIfElse.cpp b/src/passes/LowerIfElse.cpp index 7bdb2f419..b566e8207 100644 --- a/src/passes/LowerIfElse.cpp +++ b/src/passes/LowerIfElse.cpp @@ -38,7 +38,7 @@ struct LowerIfElse : public WalkerPass<PostWalker<LowerIfElse, Visitor<LowerIfEl void prepare(PassRunner* runner, Module *module) override { allocator = runner->allocator; - namer = std::unique_ptr<NameManager>(new NameManager()); + namer = make_unique<NameManager>(); namer->run(runner, module); } diff --git a/src/passes/LowerInt64.cpp b/src/passes/LowerInt64.cpp index b59b1d5fc..69f6d5ae9 100644 --- a/src/passes/LowerInt64.cpp +++ b/src/passes/LowerInt64.cpp @@ -35,7 +35,7 @@ struct LowerInt64 : public Pass { void prepare(PassRunner* runner, Module *module) override { allocator = runner->allocator; - namer = std::unique_ptr<NameManager>(new NameManager()); + namer = make_unique<NameManager>(); namer->run(runner, module); } diff --git a/src/support/threads.cpp b/src/support/threads.cpp index d9e8f8bf2..18f99d5ca 100644 --- a/src/support/threads.cpp +++ b/src/support/threads.cpp @@ -22,6 +22,7 @@ #include "threads.h" #include "compiler-support.h" +#include "utilities.h" // debugging tools @@ -47,7 +48,7 @@ static std::unique_ptr<ThreadPool> pool; Thread::Thread() { assert(!ThreadPool::get()->isRunning()); - thread = std::unique_ptr<std::thread>(new std::thread(mainLoop, this)); + thread = make_unique<std::thread>(mainLoop, this); } Thread::~Thread() { @@ -110,7 +111,7 @@ void ThreadPool::initialize(size_t num) { ready.store(threads.size()); // initial state before first resetThreadsAreReady() resetThreadsAreReady(); for (size_t i = 0; i < num; i++) { - threads.emplace_back(std::unique_ptr<Thread>(new Thread())); + threads.emplace_back(make_unique<Thread>()); } DEBUG_POOL("initialize() waiting\n"); condition.wait(lock, [this]() { return areThreadsReady(); }); @@ -127,7 +128,7 @@ size_t ThreadPool::getNumCores() { ThreadPool* ThreadPool::get() { if (!pool) { - pool = std::unique_ptr<ThreadPool>(new ThreadPool()); + pool = make_unique<ThreadPool>(); pool->initialize(getNumCores()); } return pool.get(); diff --git a/src/wasm-module-building.h b/src/wasm-module-building.h index 3cdebc558..ead074991 100644 --- a/src/wasm-module-building.h +++ b/src/wasm-module-building.h @@ -86,7 +86,15 @@ class OptimizingIncrementalModuleBuilder { public: // numFunctions must be equal to the number of functions allocated, or higher. Knowing // this bounds helps avoid locking. - OptimizingIncrementalModuleBuilder(Module* wasm, Index numFunctions) : wasm(wasm), numFunctions(numFunctions), nextFunction(0), finishing(false) { + OptimizingIncrementalModuleBuilder(Module* wasm, Index numFunctions) + : wasm(wasm), numFunctions(numFunctions), endMarker(nullptr), list(nullptr), nextFunction(0), + numWorkers(0), liveWorkers(0), activeWorkers(0), availableFuncs(0), finishedFuncs(0), + finishing(false) { + if (numFunctions == 0) { + // special case: no functions to be optimized. Don't create any threads. + return; + } + // prepare work list endMarker = new Function(); list = new std::atomic<Function*>[numFunctions]; @@ -139,7 +147,7 @@ public: private: void createWorker() { DEBUG_THREAD("create a worker"); - threads.emplace_back(std::unique_ptr<std::thread>(new std::thread(workerMain, this))); + threads.emplace_back(make_unique<std::thread>(workerMain, this)); } void wakeWorker() { @@ -197,9 +205,8 @@ private: passRunner.runFunction(func); } - static void workerMain(void* param) { + static void workerMain(OptimizingIncrementalModuleBuilder* self) { DEBUG_THREAD("workerMain"); - OptimizingIncrementalModuleBuilder* self = (OptimizingIncrementalModuleBuilder*)param; { std::lock_guard<std::mutex> lock(self->mutex); self->liveWorkers++; diff --git a/test/empty.asm.js b/test/empty.asm.js new file mode 100644 index 000000000..94fa6bb38 --- /dev/null +++ b/test/empty.asm.js @@ -0,0 +1,4 @@ +function EmptyModule() { + 'use asm'; + return {}; +} diff --git a/test/empty.fromasm b/test/empty.fromasm new file mode 100644 index 000000000..939cbb87c --- /dev/null +++ b/test/empty.fromasm @@ -0,0 +1,4 @@ +(module + (memory 256 256) + (export "memory" memory) +) diff --git a/test/empty.fromasm.imprecise b/test/empty.fromasm.imprecise new file mode 100644 index 000000000..939cbb87c --- /dev/null +++ b/test/empty.fromasm.imprecise @@ -0,0 +1,4 @@ +(module + (memory 256 256) + (export "memory" memory) +) diff --git a/test/empty.fromasm.imprecise.no-opts b/test/empty.fromasm.imprecise.no-opts new file mode 100644 index 000000000..939cbb87c --- /dev/null +++ b/test/empty.fromasm.imprecise.no-opts @@ -0,0 +1,4 @@ +(module + (memory 256 256) + (export "memory" memory) +) diff --git a/test/empty.fromasm.no-opts b/test/empty.fromasm.no-opts new file mode 100644 index 000000000..939cbb87c --- /dev/null +++ b/test/empty.fromasm.no-opts @@ -0,0 +1,4 @@ +(module + (memory 256 256) + (export "memory" memory) +) |