1/*
2 * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "DFGPlan.h"
29#include "DFGThreadData.h"
30#include <wtf/AutomaticThread.h>
31#include <wtf/Condition.h>
32#include <wtf/Deque.h>
33#include <wtf/HashMap.h>
34#include <wtf/Lock.h>
35
36namespace JSC {
37
38class SlotVisitor;
39
40namespace DFG {
41
42#if ENABLE(DFG_JIT)
43
44class Worklist : public RefCounted<Worklist> {
45public:
46 enum State { NotKnown, Compiling, Compiled };
47
48 ~Worklist();
49
50 static Ref<Worklist> create(CString&& tierName, unsigned numberOfThreads, int relativePriority = 0);
51
52 void enqueue(Ref<Plan>&&);
53
54 // This is equivalent to:
55 // worklist->waitUntilAllPlansForVMAreReady(vm);
56 // worklist->completeAllReadyPlansForVM(vm);
57 void completeAllPlansForVM(VM&);
58
59 template<typename Func>
60 void iterateCodeBlocksForGC(VM&, const Func&);
61
62 void waitUntilAllPlansForVMAreReady(VM&);
63 State completeAllReadyPlansForVM(VM&, CompilationKey = CompilationKey());
64 void removeAllReadyPlansForVM(VM&);
65
66 State compilationState(CompilationKey);
67
68 size_t queueLength();
69
70 void suspendAllThreads();
71 void resumeAllThreads();
72
73 bool isActiveForVM(VM&) const;
74
75 // Only called on the main thread after suspending all threads.
76 void visitWeakReferences(SlotVisitor&);
77 void removeDeadPlans(VM&);
78
79 void removeNonCompilingPlansForVM(VM&);
80
81 void dump(PrintStream&) const;
82 unsigned setNumberOfThreads(unsigned, int);
83
84private:
85 Worklist(CString&& tierName);
86 void finishCreation(unsigned numberOfThreads, int);
87 void createNewThread(const AbstractLocker&, int);
88
89 class ThreadBody;
90 friend class ThreadBody;
91
92 void runThread(ThreadData*);
93 static void threadFunction(void* argument);
94
95 void removeAllReadyPlansForVM(VM&, Vector<RefPtr<Plan>, 8>&);
96
97 void dump(const AbstractLocker&, PrintStream&) const;
98
99 unsigned m_numberOfActiveThreads { 0 };
100 CString m_threadName;
101 Vector<std::unique_ptr<ThreadData>> m_threads;
102
103 // Used to inform the thread about what work there is left to do.
104 Deque<RefPtr<Plan>> m_queue;
105
106 // Used to answer questions about the current state of a code block. This
107 // is particularly great for the cti_optimize OSR slow path, which wants
108 // to know: did I get here because a better version of me just got
109 // compiled?
110 typedef HashMap<CompilationKey, RefPtr<Plan>> PlanMap;
111 PlanMap m_plans;
112
113 // Used to quickly find which plans have been compiled and are ready to
114 // be completed.
115 Vector<RefPtr<Plan>, 16> m_readyPlans;
116 Ref<AutomaticThreadCondition> m_planEnqueued;
117 Condition m_planCompiled;
118
119 Lock m_suspensionLock;
120 Box<Lock> m_lock;
121};
122
123JS_EXPORT_PRIVATE unsigned setNumberOfDFGCompilerThreads(unsigned);
124JS_EXPORT_PRIVATE unsigned setNumberOfFTLCompilerThreads(unsigned);
125
126// For DFGMode compilations.
127JS_EXPORT_PRIVATE Worklist& ensureGlobalDFGWorklist();
128JS_EXPORT_PRIVATE Worklist* existingGlobalDFGWorklistOrNull();
129
130// For FTLMode and FTLForOSREntryMode compilations.
131JS_EXPORT_PRIVATE Worklist& ensureGlobalFTLWorklist();
132JS_EXPORT_PRIVATE Worklist* existingGlobalFTLWorklistOrNull();
133
134Worklist& ensureGlobalWorklistFor(CompilationMode);
135
136// Simplify doing things for all worklists.
137unsigned numberOfWorklists();
138Worklist& ensureWorklistForIndex(unsigned index);
139Worklist* existingWorklistForIndexOrNull(unsigned index);
140Worklist& existingWorklistForIndex(unsigned index);
141
142#endif // ENABLE(DFG_JIT)
143
144void completeAllPlansForVM(VM&);
145
146template<typename Func>
147void iterateCodeBlocksForGC(VM&, const Func&);
148
149} } // namespace JSC::DFG
150
151