1/* 2 * Copyright (C) 2013 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#ifndef ConcurrentJITLock_h 27#define ConcurrentJITLock_h 28 29#include "DeferGC.h" 30#include <wtf/ByteSpinLock.h> 31#include <wtf/NoLock.h> 32 33namespace JSC { 34 35#if ENABLE(CONCURRENT_JIT) 36typedef ByteSpinLock ConcurrentJITLock; 37typedef ByteSpinLocker ConcurrentJITLockerImpl; 38#else 39typedef NoLock ConcurrentJITLock; 40typedef NoLockLocker ConcurrentJITLockerImpl; 41#endif 42 43class ConcurrentJITLockerBase { 44 WTF_MAKE_NONCOPYABLE(ConcurrentJITLockerBase); 45public: 46 explicit ConcurrentJITLockerBase(ConcurrentJITLock& lockable) 47 : m_locker(&lockable) 48 { 49 } 50 explicit ConcurrentJITLockerBase(ConcurrentJITLock* lockable) 51 : m_locker(lockable) 52 { 53 } 54 55 ~ConcurrentJITLockerBase() 56 { 57 } 58 59 void unlockEarly() 60 { 61 m_locker.unlockEarly(); 62 } 63 64private: 65 ConcurrentJITLockerImpl m_locker; 66}; 67 68class GCSafeConcurrentJITLocker : public ConcurrentJITLockerBase { 69public: 70 GCSafeConcurrentJITLocker(ConcurrentJITLock& lockable, Heap& heap) 71 : ConcurrentJITLockerBase(lockable) 72 , m_deferGC(heap) 73 { 74 } 75 76 GCSafeConcurrentJITLocker(ConcurrentJITLock* lockable, Heap& heap) 77 : ConcurrentJITLockerBase(lockable) 78 , m_deferGC(heap) 79 { 80 } 81 82 ~GCSafeConcurrentJITLocker() 83 { 84 // We have to unlock early due to the destruction order of base 85 // vs. derived classes. If we didn't, then we would destroy the 86 // DeferGC object before unlocking the lock which could cause a GC 87 // and resulting deadlock. 88 unlockEarly(); 89 } 90 91private: 92#if ENABLE(CONCURRENT_JIT) 93 DeferGC m_deferGC; 94#else 95 struct NoDefer { 96 NoDefer(Heap& heap) : m_heap(heap) { } 97 Heap& m_heap; 98 }; 99 NoDefer m_deferGC; 100#endif 101}; 102 103class ConcurrentJITLocker : public ConcurrentJITLockerBase { 104public: 105 ConcurrentJITLocker(ConcurrentJITLock& lockable) 106 : ConcurrentJITLockerBase(lockable) 107 { 108 } 109 110 ConcurrentJITLocker(ConcurrentJITLock* lockable) 111 : ConcurrentJITLockerBase(lockable) 112 { 113 } 114 115#if ENABLE(CONCURRENT_JIT) && !defined(NDEBUG) 116private: 117 DisallowGC m_disallowGC; 118#endif 119}; 120 121} // namespace JSC 122 123#endif // ConcurrentJITLock_h 124