summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/disassembler/Disassembler.cpp
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2016-08-25 19:20:41 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-02-02 12:30:55 +0000
commit6882a04fb36642862b11efe514251d32070c3d65 (patch)
treeb7959826000b061fd5ccc7512035c7478742f7b0 /Source/JavaScriptCore/disassembler/Disassembler.cpp
parentab6df191029eeeb0b0f16f127d553265659f739e (diff)
downloadqtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/JavaScriptCore/disassembler/Disassembler.cpp')
-rw-r--r--Source/JavaScriptCore/disassembler/Disassembler.cpp110
1 files changed, 109 insertions, 1 deletions
diff --git a/Source/JavaScriptCore/disassembler/Disassembler.cpp b/Source/JavaScriptCore/disassembler/Disassembler.cpp
index 3fed2cdab..788a6c362 100644
--- a/Source/JavaScriptCore/disassembler/Disassembler.cpp
+++ b/Source/JavaScriptCore/disassembler/Disassembler.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,7 +27,13 @@
#include "Disassembler.h"
#include "MacroAssemblerCodeRef.h"
+#include <wtf/Condition.h>
#include <wtf/DataLog.h>
+#include <wtf/Deque.h>
+#include <wtf/Lock.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/StringPrintStream.h>
+#include <wtf/Threading.h>
namespace JSC {
@@ -39,5 +45,107 @@ void disassemble(const MacroAssemblerCodePtr& codePtr, size_t size, const char*
out.printf("%sdisassembly not available for range %p...%p\n", prefix, codePtr.executableAddress(), static_cast<char*>(codePtr.executableAddress()) + size);
}
+namespace {
+
+// This is really a struct, except that it should be a class because that's what the WTF_* macros
+// expect.
+class DisassemblyTask {
+ WTF_MAKE_NONCOPYABLE(DisassemblyTask);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ DisassemblyTask()
+ {
+ }
+
+ ~DisassemblyTask()
+ {
+ if (header)
+ free(header); // free() because it would have been copied by strdup.
+ }
+
+ char* header { nullptr };
+ MacroAssemblerCodeRef codeRef;
+ size_t size { 0 };
+ const char* prefix { nullptr };
+};
+
+class AsynchronousDisassembler {
+public:
+ AsynchronousDisassembler()
+ {
+ createThread("Asynchronous Disassembler", [&] () { run(); });
+ }
+
+ void enqueue(std::unique_ptr<DisassemblyTask> task)
+ {
+ LockHolder locker(m_lock);
+ m_queue.append(WTFMove(task));
+ m_condition.notifyAll();
+ }
+
+ void waitUntilEmpty()
+ {
+ LockHolder locker(m_lock);
+ while (!m_queue.isEmpty() || m_working)
+ m_condition.wait(m_lock);
+ }
+
+private:
+ NO_RETURN void run()
+ {
+ for (;;) {
+ std::unique_ptr<DisassemblyTask> task;
+ {
+ LockHolder locker(m_lock);
+ m_working = false;
+ m_condition.notifyAll();
+ while (m_queue.isEmpty())
+ m_condition.wait(m_lock);
+ task = m_queue.takeFirst();
+ m_working = true;
+ }
+
+ dataLog(task->header);
+ disassemble(task->codeRef.code(), task->size, task->prefix, WTF::dataFile());
+ }
+ }
+
+ Lock m_lock;
+ Condition m_condition;
+ Deque<std::unique_ptr<DisassemblyTask>> m_queue;
+ bool m_working { false };
+};
+
+bool hadAnyAsynchronousDisassembly = false;
+
+AsynchronousDisassembler& asynchronousDisassembler()
+{
+ static NeverDestroyed<AsynchronousDisassembler> disassembler;
+ hadAnyAsynchronousDisassembly = true;
+ return disassembler.get();
+}
+
+} // anonymous namespace
+
+void disassembleAsynchronously(
+ const CString& header, const MacroAssemblerCodeRef& codeRef, size_t size, const char* prefix)
+{
+ std::unique_ptr<DisassemblyTask> task = std::make_unique<DisassemblyTask>();
+ task->header = strdup(header.data()); // Yuck! We need this because CString does racy refcounting.
+ task->codeRef = codeRef;
+ task->size = size;
+ task->prefix = prefix;
+
+ asynchronousDisassembler().enqueue(WTFMove(task));
+}
+
+void waitForAsynchronousDisassembly()
+{
+ if (!hadAnyAsynchronousDisassembly)
+ return;
+
+ asynchronousDisassembler().waitUntilEmpty();
+}
+
} // namespace JSC