/* * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef DFGWorklist_h #define DFGWorklist_h #if ENABLE(DFG_JIT) #include "DFGPlan.h" #include "DFGThreadData.h" #include #include #include #include #include namespace JSC { class SlotVisitor; namespace DFG { class Worklist : public RefCounted { public: enum State { NotKnown, Compiling, Compiled }; ~Worklist(); static Ref create(CString worklistName, unsigned numberOfThreads, int relativePriority = 0); void enqueue(PassRefPtr); // This is equivalent to: // worklist->waitUntilAllPlansForVMAreReady(vm); // worklist->completeAllReadyPlansForVM(vm); void completeAllPlansForVM(VM&); void rememberCodeBlocks(VM&); void waitUntilAllPlansForVMAreReady(VM&); State completeAllReadyPlansForVM(VM&, CompilationKey = CompilationKey()); void removeAllReadyPlansForVM(VM&); State compilationState(CompilationKey); size_t queueLength(); void suspendAllThreads(); void resumeAllThreads(); bool isActiveForVM(VM&) const; // Only called on the main thread after suspending all threads. void visitWeakReferences(SlotVisitor&); void removeDeadPlans(VM&); void dump(PrintStream&) const; private: Worklist(CString worklistName); void finishCreation(unsigned numberOfThreads, int); void runThread(ThreadData*); static void threadFunction(void* argument); void removeAllReadyPlansForVM(VM&, Vector, 8>&); void dump(const LockHolder&, PrintStream&) const; CString m_threadName; // Used to inform the thread about what work there is left to do. Deque> m_queue; // Used to answer questions about the current state of a code block. This // is particularly great for the cti_optimize OSR slow path, which wants // to know: did I get here because a better version of me just got // compiled? typedef HashMap> PlanMap; PlanMap m_plans; // Used to quickly find which plans have been compiled and are ready to // be completed. Vector, 16> m_readyPlans; Lock m_suspensionLock; mutable Lock m_lock; Condition m_planEnqueued; Condition m_planCompiled; Vector> m_threads; unsigned m_numberOfActiveThreads; }; // For DFGMode compilations. Worklist* ensureGlobalDFGWorklist(); Worklist* existingGlobalDFGWorklistOrNull(); // For FTLMode and FTLForOSREntryMode compilations. Worklist* ensureGlobalFTLWorklist(); Worklist* existingGlobalFTLWorklistOrNull(); Worklist* ensureGlobalWorklistFor(CompilationMode); // Simplify doing things for all worklists. inline unsigned numberOfWorklists() { return 2; } inline Worklist* worklistForIndexOrNull(unsigned index) { switch (index) { case 0: return existingGlobalDFGWorklistOrNull(); case 1: return existingGlobalFTLWorklistOrNull(); default: RELEASE_ASSERT_NOT_REACHED(); return 0; } } void completeAllPlansForVM(VM&); void rememberCodeBlocks(VM&); } } // namespace JSC::DFG #endif // ENABLE(DFG_JIT) #endif // DFGWorklist_h