1/* 2 * Copyright (C) 2012, 2014 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 GCAwareJITStubRoutine_h 27#define GCAwareJITStubRoutine_h 28 29#if ENABLE(JIT) 30 31#include "JITStubRoutine.h" 32#include "JSObject.h" 33#include "JSString.h" 34#include "WriteBarrier.h" 35#include <wtf/RefCounted.h> 36#include <wtf/Vector.h> 37 38namespace JSC { 39 40class JITStubRoutineSet; 41 42// Use this stub routine if you know that your code might be on stack when 43// either GC or other kinds of stub deletion happen. Basicaly, if your stub 44// routine makes calls (either to JS code or to C++ code) then you should 45// assume that it's possible for that JS or C++ code to do something that 46// causes the system to try to delete your routine. Using this routine type 47// ensures that the actual deletion is delayed until the GC proves that the 48// routine is no longer running. You can also subclass this routine if you 49// want to mark additional objects during GC in those cases where the 50// routine is known to be executing, or if you want to force this routine to 51// keep other routines alive (for example due to the use of a slow-path 52// list which does not get reclaimed all at once). 53class GCAwareJITStubRoutine : public JITStubRoutine { 54public: 55 GCAwareJITStubRoutine(const MacroAssemblerCodeRef&, VM&); 56 virtual ~GCAwareJITStubRoutine(); 57 58 void markRequiredObjects(SlotVisitor& visitor) 59 { 60 markRequiredObjectsInternal(visitor); 61 } 62 63 void deleteFromGC(); 64 65protected: 66 virtual void observeZeroRefCount() override; 67 68 virtual void markRequiredObjectsInternal(SlotVisitor&); 69 70private: 71 friend class JITStubRoutineSet; 72 73 bool m_mayBeExecuting; 74 bool m_isJettisoned; 75}; 76 77// Use this if you want to mark one additional object during GC if your stub 78// routine is known to be executing. 79class MarkingGCAwareJITStubRoutineWithOneObject : public GCAwareJITStubRoutine { 80public: 81 MarkingGCAwareJITStubRoutineWithOneObject( 82 const MacroAssemblerCodeRef&, VM&, const JSCell* owner, JSCell*); 83 virtual ~MarkingGCAwareJITStubRoutineWithOneObject(); 84 85protected: 86 virtual void markRequiredObjectsInternal(SlotVisitor&) override; 87 88private: 89 WriteBarrier<JSCell> m_object; 90}; 91 92// Helper for easily creating a GC-aware JIT stub routine. For the varargs, 93// pass zero or more JSCell*'s. This will either create a JITStubRoutine, a 94// GCAwareJITStubRoutine, or an ObjectMarkingGCAwareJITStubRoutine as 95// appropriate. Generally you only need to pass pointers that will be used 96// after the first call to C++ or JS. 97// 98// PassRefPtr<JITStubRoutine> createJITStubRoutine( 99// const MacroAssemblerCodeRef& code, 100// VM& vm, 101// const JSCell* owner, 102// bool makesCalls, 103// ...); 104// 105// Note that we don't actually use C-style varargs because that leads to 106// strange type-related problems. For example it would preclude us from using 107// our custom of passing '0' as NULL pointer. Besides, when I did try to write 108// this function using varargs, I ended up with more code than this simple 109// way. 110 111PassRefPtr<JITStubRoutine> createJITStubRoutine( 112 const MacroAssemblerCodeRef&, VM&, const JSCell* owner, bool makesCalls, 113 JSCell* = nullptr); 114 115// Helper for the creation of simple stub routines that need no help from the GC. Note 116// that codeBlock gets "executed" more than once. 117#define FINALIZE_CODE_FOR_GC_AWARE_STUB(codeBlock, patchBuffer, makesCalls, cell, dataLogFArguments) \ 118 (createJITStubRoutine(FINALIZE_CODE_FOR((codeBlock), (patchBuffer), dataLogFArguments), *(codeBlock)->vm(), (codeBlock)->ownerExecutable(), (makesCalls), (cell))) 119 120} // namespace JSC 121 122#endif // ENABLE(JIT) 123 124#endif // GCAwareJITStubRoutine_h 125 126